本文主要是介绍3DS轨迹球 + 光照,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在前面的基础上 加个光照,会有什么效果?
下面以博文《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;
}
比较一下前后效果:
第二个是没有纹理的模型
第三个好象还不如无光照
这篇关于3DS轨迹球 + 光照的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!