在前面的基础上 加个光照,会有什么效果?
下面以博文《3D球体一个(纪念第一个opengl程序~~)》为模板,加入上一篇的代码
下面是该文效果:
加入我们的:
//显示有纹理贴图的3ds模型,+光照 +虚拟球旋转
//按a或d使...
#define name3DS "Data/3ds/boy_back.3DS" //waji building_nb //wjj1_b5 arm// //bucket1//house_back
#include "CLoad3DS.cpp"
#include "ArcBall.cpp"
const GLfloat lightPosition[] = {10.0,-10.0,10.0,0.0}; //光源所在的位置 无限远处+方向
const GLfloat whiteLight[] = {0.8,0.8,0.8,1.0};
GLfloat matSpecular [] = {0.3,0.3,0.3,1.0}; //镜面反光率(RGBA)
GLfloat matShininess [] = {20.0};
GLfloat matEmission [] = {0.3,0.3,0.3,1.0};
GLfloat spin = 0;
GLint width = 600;
GLint height = 480;
CLoad3DS *gothicLoader=new(CLoad3DS);
t3DModel gothicModel;
float gothicTrans[10] = {
0, 0 , -30 , //表示在世界矩阵的位置
0 , 0 , 0 , //表示xyz放大倍数
0 , 0 , 0 , 0 //表示旋转
};
//初始化,必须用全局变量的方式,不能用new
ArcBallT arcBall(600.0f,400.0f);
ArcBallT* ArcBall =&arcBall;// new ArcBallT(600.0f,400.0f);//&arcBall;
char * filename3ds=name3DS;
//移动
void move(int x, int y)
{
ArcBall->MousePt.s.X = x;
ArcBall->MousePt.s.Y = y;
ArcBall->upstate();
glutPostRedisplay();
}
//点击
void mouse(int button, int state, int x, int y)
{
if(button == GLUT_LEFT_BUTTON && state==GLUT_DOWN){
ArcBall->isClicked = true;
move(x,y);
}
else if(button == GLUT_LEFT_BUTTON && state==GLUT_UP)
ArcBall->isClicked = false;
else if(button == GLUT_RIGHT_BUTTON && state==GLUT_DOWN){
ArcBall->isRClicked = true;
move(x,y);
}
else if(button == GLUT_RIGHT_BUTTON && state == GLUT_UP)
ArcBall->isRClicked = false;
ArcBall->upstate();
glutPostRedisplay();
}
//计算模型外框大小
void zhong(GLvoid)
{
//遍历模型的对象,遍历对象顶点,找到x,y,z的最小,最大值,计算模型外框大小,长,宽,高
//然后计算xyz放大倍数
float xmin,xmax,ymin,ymax,zmin,zmax,t;
xmin=ymin=zmin=9999999.0;//设置一个很大的值
xmax=ymax=zmax=-9999999.0;//设置一个很小的值
printf("对象个数:%d\n",gothicModel.numOfObjects);
//printf("对象vector大小:%d\n",gothicModel.pObject.size());
//遍历模型中的所有对象
for(unsigned int i=0;i<gothicModel.pObject.size();i++)
{
//printf("第%d个对象的顶点个数:%d\n",i,gothicModel.pObject[i].numOfVerts);
NBVector3 *pVerts; // 对象的顶点
pVerts=gothicModel.pObject[i].pVerts;
//遍历对象中的所有顶点
for(int j=0;j<gothicModel.pObject[i].numOfVerts;j++)
{
//比较大小,留下最小和最大值
t=pVerts->x;
xmin=(t<xmin)?t:xmin;
xmax=(t>xmax)?t:xmax;
t=pVerts->y;
ymin=(t<ymin)?t:ymin;
ymax=(t>ymax)?t:ymax;
t=pVerts->z;
zmin=(t<zmin)?t:zmin;
zmax=(t>zmax)?t:zmax;
pVerts++;//下一个顶点
}
}
//显示最小最大值
printf("xmin:%f,xmax:%f\n",xmin,xmax);
printf("ymin:%f,ymax:%f\n",ymin,ymax);
printf("zmin:%f,xmax:%f\n",zmin,zmax);
printf("宽度(x差值):%f,\n",xmax-xmin);
printf("高度(y差值):%f,\n",ymax-ymin);
printf("深度(z差值):%f,\n",zmax-zmin);
float xm,ym,zm,b;
xm=xmax-xmin;ym=ymax-ymin;zm=zmax-zmin;
b=1.0/max(max(xm,ym),zm);
printf("放大倍数:%f,\n",b);
gothicTrans[3]=gothicTrans[4]=gothicTrans[5]=b;//设置放大倍数
//移到屏幕中央
gothicTrans[0]=-(xmin+(xmax-xmin)/2)*b;
gothicTrans[1]=-(ymin+(ymax-ymin)/2)*b;
gothicTrans[2]=-(zmin+(zmax-zmin)/2)*b-20;
}
void init()
{
gothicLoader->Import3DS(&gothicModel, filename3ds);//导入模型,第二个参数是3ds文件的路径,
zhong();
glClearColor(0.3,0.3,0.3,1.0);
glClearDepth(1.0);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING); //打开光照处理功能
glEnable(GL_LIGHT0); //使用第0号光照
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW); //对模型视景矩阵操作
glLoadIdentity(); //将坐标原点移到中心
gluPerspective(3.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);
glLightfv(GL_LIGHT0,GL_POSITION,lightPosition); //光源所在的位置。
//GL_DIFFUSE:该光源所发出的光,照射到粗糙表面时经过漫反射,所得到的光的强度(颜色)
glLightfv(GL_LIGHT0,GL_DIFFUSE,whiteLight);
//GL_SPECULAR:该光源所发出的光,照射到光滑表面时经过镜面反射,所得到的光的强度(颜色)。
glLightfv(GL_LIGHT0,GL_SPECULAR,whiteLight);
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //清空颜色和深度缓冲
glMatrixMode(GL_PROJECTION); //对投影矩阵操作
glLoadIdentity();; //将坐标原点移到中心
glMatrixMode(GL_MODELVIEW); //对模型视景矩阵操作
glPushMatrix();
glRotatef(spin,0.0,1.0,0.0);
//设置材质
glMaterialfv(GL_FRONT,GL_SPECULAR,matSpecular); //设置镜面光
glMaterialfv(GL_FRONT,GL_SHININESS,matShininess); //镜面指数
glMaterialfv(GL_FRONT,GL_EMISSION,matEmission);//自发光
changeObject( gothicTrans );
//-----轨迹球----------开始
glScalef(ArcBall->zoomRate, ArcBall->zoomRate, ArcBall->zoomRate);//2. 缩放
glMultMatrixf(ArcBall->Transform.M); //3. 旋转
//-----轨迹球----------结束
drawModel(gothicModel,true,false);
glPopMatrix();
glFlush();
}
void keyboardFunc(unsigned char key,int x,int y)
{
switch(key)
{
case 'a':
spin +=0.1;
break;
case 'd':
spin -=0.1;
break;
}
if(spin<360)
spin +=360;
else if(spin>=360)
spin -=360;
glutPostRedisplay();
}
int main(int argc,char *argv[])
{
if( argc == 2 )
filename3ds=argv[1];
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGBA|GLUT_DEPTH);
glutInitWindowSize(width,height);
glutInitWindowPosition(150,150);
glutCreateWindow("OpenGL读取3DS文件");
glutDisplayFunc(display);
glutKeyboardFunc(keyboardFunc);
init();
glutMouseFunc(mouse); //注册鼠标事件。
glutMotionFunc(move); //注册移动事件
glutMainLoop();
return EXIT_SUCCESS;
}
比较一下前后效果:
第二个是没有纹理的模型
第三个好象还不如无光照