课程实验指导光照Word格式.docx
《课程实验指导光照Word格式.docx》由会员分享,可在线阅读,更多相关《课程实验指导光照Word格式.docx(11页珍藏版)》请在冰点文库上搜索。
a)光源在无穷远处,即光线方向L为常数;
b)视点在无穷远处,即视线方向V为常数;
c)用
近似
这里H为L和V的角平分向量,
在这种简化下,由于对所有的点总共只需计算一次H的值,节省了计算时间。
结合RGB颜色模型,Phong光照明模型最终有如下的形式:
本次实验中,光源在无穷远处,光线方向为单位向量L(0.5,0.5,0.707),视点在无穷远处,视线方向V为(0,0,1)。
本次实验中增加了鼠标右键操作,相关知识见后面所附GLUT菜单知识。
4.实验代码:
//Light.cpp:
Defines theentrypointfortheconsoleapplication.
//
#include"stdafx.h"
#include <
GL/glut.h>
#include<stdio.h>
#include<
stdlib.h>
#include <
math.h>
#defineNO_LIGHT1
#defineLIGHT 2
boolbLight= false;
structVector
{
ﻩfloatfx, fy,fz;
};
structColor
ﻩfloatIr,Ig,Ib;
floatKaIa;
floatKd, n;
VectorH,light;
ColormLight, mColor;
voidInit()
{
floatmo;
Vector eye;
mLight.Ir =0;
mLight.Ig =175;
mLight.Ib= 0;
ﻩKaIa=100;
ﻩKd=0.7;
n=20;
light.fx=0.50;
light.fy=0.50;
light.fz=sqrt(1-(light.fx*light.fx)-(light.fy*light.fy));
eye.fx=0;
eye.fy=0;
eye.fz=1;
H.fx=light.fx+eye.fx;
H.fy=light.fy+eye.fy;
ﻩH.fz=light.fz+eye.fz;
mo=sqrt(H.fx*H.fx+H.fy*H.fy+H.fz*H.fz);
H.fx=(H.fx/mo);
H.fy=(H.fy/mo);
H.fz=(H.fz/mo);
ﻩH.fx=(H.fx/mo);
H.fy=(H.fy/mo);
H.fz=(H.fz/mo);
ﻩglClearColor(1.0,1.0,1.0,0.0);
glShadeModel(GL_SMOOTH);
}
ColorPhong(int x0,inty0, intr,intx,inty)
ﻩVectorN;
floatz,alpha,theta,Ks;
Ks=1.0-Kd;
ﻩz=sqrt((float)(r*r-(x-x0)*(x-x0)-(y-y0)*(y-y0)));
ﻩN.fx=(x-x0)*1.0/r;
N.fy=(y-y0)*1.0/r;
ﻩN.fz= z*1.0/r;
ﻩtheta= N.fx *light.fx +N.fy*light.fy+N.fz* light.fz;
ﻩif(theta<
0)
ﻩﻩtheta=0;
alpha=H.fx*N.fx+H.fy*N.fy+H.fx*N.fz;
if(alpha<
0)
ﻩﻩalpha=0;
ﻩmColor.Ir=KaIa+mLight.Ir*Kd*theta+mLight.Ir*Ks*pow(alpha,n);
ﻩmColor.Ig=KaIa+mLight.Ig*Kd*theta+mLight.Ig*Ks*pow(alpha,n);
ﻩmColor.Ib=KaIa+mLight.Ib*Kd*theta+mLight.Ib*Ks*pow(alpha,n);
returnmColor;
}
voidMidCircle(intx0,inty0,intr)
intx,y,deltax,deltay,d;
x = 0;
y =r;
deltax=3;
deltay =5-r-r;
ﻩd=1-r;
glColor3f(0.0f, 1.0f, 0.0f);
glBegin(GL_POINTS);
ﻩglVertex2i (x+x0,y+y0);
ﻩglVertex2i(-x+x0,y+y0);
glVertex2i(-x+x0,-y+y0);
glVertex2i(x+x0,-y+y0);
glVertex2i (y+y0,x+x0);
ﻩglVertex2i(y+y0,-x+x0);
ﻩglVertex2i(-y+y0, -x+x0);
ﻩglVertex2i (-y+y0,x+x0);
while(x<y)
{
ﻩﻩif(d<0)
ﻩ{
ﻩﻩﻩd+=deltax;
ﻩﻩdeltax +=2;
ﻩdeltay+=2;
ﻩﻩx++;
ﻩ}
ﻩelse
{
ﻩd+=deltay;
ﻩﻩdeltax+=2;
ﻩﻩdeltay+=4;
ﻩﻩx++;
ﻩy--;
}ﻩ
ﻩ
glVertex2i (x+x0,y+y0);
glVertex2i(-x+x0,y+y0);
glVertex2i(-x+x0,-y+y0);
ﻩﻩglVertex2i(x+x0,-y+y0);
ﻩ
ﻩglVertex2i(y+y0, x+x0);
ﻩﻩglVertex2i(y+y0,-x+x0);
glVertex2i(-y+y0,-x+x0);
ﻩﻩglVertex2i(-y+y0,x+x0);
ﻩ}
glEnd();
voidMidCircleLight(intx0, inty0,intr)
int x,y,deltax,deltay,d;
ﻩx=0;
y=r;
ﻩdeltax= 3;
deltay= 5-r-r;
d=1-r;
glBegin(GL_POINTS);
ﻩ{
ﻩfor(int i=-x;
i<
=x;
i++)
ﻩﻩ{
ﻩmColor=Phong(x0,y0,r,i+x0,y+y0);
ﻩﻩﻩglColor3ub (mColor.Ir,mColor.Ig,mColor.Ib);
glVertex2i (i+x0,y+y0);
ﻩﻩglColor3ub(mColor.Ir,mColor.Ig,mColor.Ib);
ﻩglVertex2i(i+x0,-y+y0);
ﻩﻩ}
ﻩfor(i=-y;
i<
=y;
ﻩ{
ﻩmColor=Phong(x0,y0,r,i+x0,x+y0);
glColor3ub(mColor.Ir,mColor.Ig,mColor.Ib);
ﻩﻩﻩglVertex2i(i+x0,x+y0);
ﻩﻩﻩglColor3ub(mColor.Ir, mColor.Ig,mColor.Ib);
ﻩﻩglVertex2i(i+x0,-x+y0);
}
while(x<
y)
if(d<
ﻩ{
ﻩﻩﻩd+=deltax;
ﻩﻩﻩﻩdeltax += 2;
ﻩdeltay+=2;
ﻩﻩﻩx++;
ﻩ}
ﻩﻩelse
ﻩ{
ﻩﻩﻩd+=deltay;
ﻩﻩdeltax+=2;
ﻩﻩdeltay+=4;
ﻩx++;
ﻩﻩy--;
ﻩﻩ}
ﻩ
ﻩﻩfor(i=-x;
=x;
ﻩ{
ﻩﻩmColor=Phong(x0,y0,r,i+x0,y+y0);
glColor3ub(mColor.Ir, mColor.Ig,mColor.Ib);
ﻩﻩﻩﻩglVertex2i(i+x0,y+y0);
ﻩﻩglColor3ub(mColor.Ir,mColor.Ig,mColor.Ib);
ﻩﻩglVertex2i(i+x0,-y+y0);
}
ﻩﻩfor(i=-y;
i<=y;
i++)
ﻩﻩ{
mColor=Phong(x0,y0,r,i+x0,x+y0);
glColor3ub (mColor.Ir,mColor.Ig, mColor.Ib);
ﻩﻩglVertex2i(i+x0,x+y0);
ﻩglColor3ub(mColor.Ir,mColor.Ig,mColor.Ib);
ﻩglVertex2i(i+x0,-x+y0);
ﻩglEnd();
void myDisplay()
ﻩglClear(GL_COLOR_BUFFER_BIT);
ﻩglColor3f (1.0f,1.0f, 1.0f);
ﻩif(bLight== false)
ﻩMidCircle(250, 250,60);
else
ﻩMidCircleLight(250,250,60);
glFlush();
voidReshape(intw, inth)
ﻩglViewport(0,0,(GLsizei)w,(GLsizei)h);
ﻩglMatrixMode(GL_PROJECTION);
ﻩglLoadIdentity();
ﻩgluOrtho2D(0.0,(GLdouble)w,0.0,(GLdouble) h);
void processMenuEvents(intoption)
{
ﻩswitch(option){
case NO_LIGHT:
bLight=false;
ﻩglutPostRedisplay();
ﻩbreak;
ﻩﻩ
ﻩcaseLIGHT:
bLight=true;
ﻩglutPostRedisplay();
ﻩbreak;
voidcreateGLUTMenus()
{ﻩ
int menu;
menu=glutCreateMenu(processMenuEvents);
ﻩglutAddMenuEntry("
NoLight"
NO_LIGHT);
ﻩglutAddMenuEntry("Light"
LIGHT);
ﻩglutAttachMenu(GLUT_RIGHT_BUTTON);
intmain(intargc,char*argv[])
glutInit(&
argc,argv);
glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);
glutInitWindowPosition(100,100);
ﻩglutInitWindowSize(640,480);
glutCreateWindow("HelloWorld!
");
Init();
ﻩglutDisplayFunc(myDisplay);
glutReshapeFunc(Reshape);
createGLUTMenus();
ﻩglutMainLoop();
ﻩreturn 0;
附GLUT菜单知识:
给一个程序增加菜单提供了一个比键盘更简单的方法来和程序交互,选择不同选项,而不用去记那些按键。
首先要做的是创建菜单,创建菜单函数glutCreateMenu的原型如下:
intglutCreateMenu(void(*func)(intvalue));
参数:
func:
为新建的菜单处理菜单事件的函数名。
这个函数的返回值是菜单的标识符(menuidentifier)。
程序中,对每个菜单要指定一个回调函数,而且可以指定相同的函数。
下面为菜单增加一些条目,使用的函数是glutAddMenuEntry:
voidglutAddMenuEntry(char *name,intvalue);
参数:
name:
菜单名称的字符串。
value:
当你选择菜单里的一项后,这个值就返回给上面的glutCreateMenu里调用的函数。
这个函数根据函数名来看,就是给菜单里添加条目的,可以一直添加,但有个顺序。
最后要把菜单和一个鼠标键连接起来(attach)。
因为我们必须指定菜单怎么出现,使用GLUT你可以在按下一个鼠标按键后让菜单显示,函数是glutAttachMenu:
voidglutAttachMenu(intbutton);
button:
一个整数,指定菜单和哪个鼠标键关联起来。
button 可以去下面的值;
GLUT_LEFT_BUTTON
GLUT_MIDDLE_BUTTON
GLUT_RIGHT_BUTTON