OpenGL学习记录4
来源:互联网 发布:清华同方教学软件 编辑:程序博客网 时间:2024/05/20 03:37
Exercise 4:材质
要求:
1. 在练习3的基础中为每个茶壶加入不同的材质;
2. 将练习3中的点光源改为不同的颜色;
考察目的:
1. OpenGL中的材质的使用;
2. 理解光源和材质如何综合影响最终的光照结果;
by/scu xx
#include <iostream>#include <gl\glew.h>#define GLUT_DISABLE_ATEXIT_HACK//若没有这一句会出现无法解析外部符号的错误,在glut.h前加上这一句就正确了#include <glut.h>#pragma comment(lib,"glew32.lib") using namespace std; bool isRotatef[4]; // 控制要旋转的茶壶或旋转视图bool isLightOpen[3]; //定义光源是否打开的bool值 float lightRotatefSpeed = 0; //第一个光源绕三个茶壶的中心旋转的角度GLfloat LightPosition1[] = {0.0f, 0.0f, 0.0f, 1.0f}; //第一个点光源的位置GLfloat LightPosition2[] = {4.0f, 4.0f, 6.0f, 1.0f}; //第二个点光源的位置GLfloat LightPosition3[] = {-1.0f, 1.0f, 2.0f, 1.0f}; //第三个点光源的位置 static int mousePosX = 0,mousePosY = 0, tempX, tempY; bool isMosDownMove=false;//鼠标按下是否移动的判断变量 struct simpleCamera{ float camera[3]; float lookat[3]; float cam[3];}; simpleCamera camera; GLfloat no_mat[] = {0.0, 0.0, 0.0, 1.0}; //材质发射光颜色 //1号茶壶的材料属性GLfloat Ambient_Teapot1[] = {0.1, 0.1, 0.1, 1.0}; //材质的环境颜色GLfloat Diffuse_Teapot1[] = {0.9, 0.8, 0.0, 1.0}; //材质的散射颜色GLfloat Specular_Teapot1[] = {0.9, 0.8, 0.1, 1.0}; //材质的镜面反射颜色GLfloat Shininess_Teapot1[] = {110.0}; //镜面反射指数 //2号茶壶的材料属性GLfloat Ambient_Teapot2[] = {0.5, 0.0, 0.1, 1.0}; GLfloat Diffuse_Teapot2[] = {0.1, 0.5, 0.99, 1.0};GLfloat Specular_Teapot2[] = {0.2, 0.1, 0.4, 1.0};GLfloat Shininess_Teapot2[] = {10.0};GLfloat Emission_Teapot2[] = {0.5, 0.5, 0.0, 1.0}; //3号茶壶的材料属性GLfloat Ambient_Teapot3[] = {0.0, 0.0, 0.99, 1.0}; GLfloat Diffuse_Teapot3[] = {0.5, 0.99, 0.5, 1.0};GLfloat Specular_Teapot3[] = {0.0, 0.0, 0.99, 1.0};GLfloat Shininess_Teapot3[] = {110.0}; void display();void init();void keyboard(unsignedchar key, int x, int y);void motion(int x,int z);void mouse(int button,int state, int x,int z);void reshape(int w,int h);void createLight(); void init(void){ glClearColor(0.7f,0.7f, 0.7f, 0.0f); glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT); isLightOpen[0] =isLightOpen[1] = isLightOpen[2] = true; //三个光源都开启 glEnable(GL_DEPTH_TEST); if (GLEW_OK != glewInit()) { cout << "Fail to initialize GLEW!\n"; exit(1); } createLight(); isRotatef[3] = true; //默认移动鼠标旋转整个视图} void createLight(){ glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); GLfloatLightAmbient1[]= { 0.0f, 1.0f, 0.0f, 1.0f }; //环境光参数 GLfloatLightDiffuse1[]= { 0.0f, 1.0f, 0.0f, 1.0f }; //漫射光参数(由参数可知识最亮的漫射光) GLfloatLightSpecular1[]= { 0.0f, 1.0f, 0.0f, 1.0f }; //镜面光参数 //指定光源属性,个参数决定了它所指定的哪个光源的属性、具体的属性以及该属性的预想值 glLightfv(GL_LIGHT0,GL_AMBIENT, LightAmbient1); glLightfv(GL_LIGHT0,GL_DIFFUSE, LightDiffuse1); glLightfv(GL_LIGHT0,GL_SPECULAR, LightSpecular1); glEnable(GL_LIGHT1); GLfloatLightAmbient2[] = {1.0f, 0.0f, 0.0f, 1.0f}; GLfloatLightDiffuse2[] = {1.0f, 0.0f, 0.0f, 1.0f}; GLfloatLightSpecular2[]= {1.0f, 0.0f, 0.0f, 1.0f}; glLightfv(GL_LIGHT1,GL_AMBIENT, LightAmbient2); glLightfv(GL_LIGHT1,GL_DIFFUSE, LightDiffuse2); glLightfv(GL_LIGHT1,GL_SPECULAR, LightSpecular2); glEnable(GL_LIGHT2); GLfloatLightAmbient3[] = {0.0f, 0.0f, 1.0f, 1.0f}; GLfloatLightDiffuse3[] = {0.0f, 0.0f, 1.0f, 1.0f}; GLfloatLightSpecular3[]= {0.0f, 0.0f, 1.0f, 1.0f }; glLightfv(GL_LIGHT2,GL_AMBIENT, LightAmbient3); glLightfv(GL_LIGHT2,GL_DIFFUSE, LightDiffuse3); glLightfv(GL_LIGHT2,GL_SPECULAR, LightSpecular3);} void display(void){ glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT); //进行视图变换前调用下面两个函数,接下来的变换函数将影响模型变换矩阵 glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //3组参数:指定了观察点的位置,定义照相机瞄准的参考点,提示哪个方向是朝上的(个为一组) //设置照相机的位置 gluLookAt(camera.camera[0],camera.camera[1], camera.camera[2], camera.lookat[0], camera.lookat[1],camera.lookat[2], 0, 1, 0); //通过平移与旋转按照预想的方式移动观察点 glTranslatef(camera.cam[0],camera.cam[1],camera.cam[2]); /*************************************光源*****************************************************/ //处理绕三个茶壶的中心旋转的点光源 glPushMatrix(); //以下三句表示光源在z轴的.0f范围内和x轴.0f的范围内以lightRotatefSpeed的角度变化的速度移动(不知正确与否,目前这样理解) glTranslatef(0.0f,0.0f, 6.0f); glRotatef((GLfloat)lightRotatefSpeed,0.0, 1.0, 0.0); glTranslatef(6.0f,0.0f, 0.0f); glDisable(GL_LIGHTING); //使用glColor3f需要禁用光照 if (isLightOpen[0]) { glColor3f(0.0f,0.0f, 1.0f); } else { glColor3f(0.0f,0.0f, 0.0f); } //用于渲染一个球体函数原型voidglutSolidSphere(GLdouble radius , GLint slices , GLint stacks); //radius球体的半径 //slices以Z轴上线段为直径分布的圆周线的条数(将Z轴看成地球的地轴,类似于经线) //stacks围绕在Z轴周围的线的条数(类似于地球上纬线) //一般而言,后两个参数赋予较大的值,渲染花费的时间要长,效果更逼真 glutSolidSphere(0.2,10.0, 10.0); glEnable(GL_LIGHTING); glLightfv(GL_LIGHT0,GL_POSITION, LightPosition1); //光源绕中心旋转 glPopMatrix(); lightRotatefSpeed +=0.4f; //固定的一个速度 if (lightRotatefSpeed > 360) //角度大于则把角度设为 { lightRotatefSpeed = 0; } /*************************************光源*****************************************************/ //复制一份当前矩阵,并把这份复制添加到堆栈的顶部(记住自己的位置) glPushMatrix(); glTranslatef(LightPosition2[0],LightPosition2[1], LightPosition2[2]); glDisable(GL_LIGHTING); //使用glColor3f需要禁用光照 if (isLightOpen[1]) { glColor3f(0.0f,1.0f, 0.0f); //打开时颜色变亮 } else { glColor3f(0.0f,0.0f, 0.0f); //关闭时颜色变暗 } glutSolidSphere(0.2,10.0, 10.0); glEnable(GL_LIGHTING); glLightfv(GL_LIGHT1,GL_POSITION, LightPosition2); //光源设在观察坐标系 glPopMatrix(); //丢弃堆栈顶部的那个矩阵(回到原来的位置) if (isRotatef[3]) //判断是否需要旋转视图 { glRotatef((GLfloat)mousePosX, -1.0, 0.0, 0.0); glRotatef((GLfloat)mousePosY, 0.0, -1.0, 0.0); } /************************第个茶壶,光源的坐标设置在茶壶的坐标系中***************************/ glPushMatrix(); glTranslatef(-4.0f,0.0f, 4.0f); if (isRotatef[0]) //判断是否旋转 { glRotatef((GLfloat)mousePosX, -1.0, 0.0, 0.0); glRotatef((GLfloat)mousePosY, 0.0, -1.0, 0.0); } //指定用于光照计算的当前材质属性函数原型voidglMaterial{if}(GLenum face, GLenum pname, TYPE param); //参数face的取值可以是GL_FRONT、GL_BACK或GL_FRONT_AND_BACK,指出材质属性将应用于物体的哪面 //pname指出要设置的哪种材质属性,GL_AMBIENT的默认值是(.2,.2,.2,.0)表示材质的环境颜色 //param为要设置的属性值,是一个指向数组的指针(向量版本)或一个数值(非向量版本) glMaterialfv(GL_FRONT,GL_AMBIENT, Ambient_Teapot1);//GL_AMBIENT的默认值是(.2,.2,.2,.0)表示材质的环境光颜色 glMaterialfv(GL_FRONT,GL_DIFFUSE, Diffuse_Teapot1);//GL_DIFFUSE的默认值是(.8,.8,.8,.0)表示材质的散射颜色 glMaterialfv(GL_FRONT,GL_SPECULAR, Specular_Teapot1);//GL_SPECULAR的默认值是(.0,.0,.0,.0)表示材质的镜面反射颜色 glMaterialfv(GL_FRONT,GL_SHININESS, Shininess_Teapot1);//GL_SHININESS的默认值是.0表示镜面反射指数 glMaterialfv(GL_FRONT,GL_EMISSION, no_mat);//GL_EMISSION的默认值是(.0,.0,.1,.0)表示材质的发射光颜色 glutSolidTeapot(1.0);//显示一个茶壶,参数为茶壶的大小 glTranslatef(LightPosition3[0],LightPosition3[1], LightPosition3[2]); //把局部坐标系移动到需要放点光源的地方 glDisable(GL_LIGHTING); //使用glColor3f需要禁用光照 if (isLightOpen[2]) { glColor3f(1.0f,0.0f, 0.0f); } else { glColor3f(0.0f,0.0f, 0.0f); } glutSolidSphere(0.2,10.0, 10.0); glEnable(GL_LIGHTING); glLightfv(GL_LIGHT2,GL_POSITION, LightPosition3); //光源的坐标设置在茶壶的坐标系中 glPopMatrix(); /********************************茶壶************************************************/ glPushMatrix(); glTranslatef(0.0f,3.0f, 4.0f); if (isRotatef[1]) //判断是否旋转 { glRotatef((GLfloat)mousePosX, -1.0, 0.0, 0.0); glRotatef((GLfloat)mousePosY, 0.0, -1.0, 0.0); } glMaterialfv(GL_FRONT,GL_AMBIENT, Ambient_Teapot2); glMaterialfv(GL_FRONT,GL_DIFFUSE, Diffuse_Teapot2); glMaterialfv(GL_FRONT,GL_SPECULAR, Specular_Teapot2); glMaterialfv(GL_FRONT,GL_SHININESS, Shininess_Teapot2); glMaterialfv(GL_FRONT,GL_EMISSION, Emission_Teapot2); glutSolidTeapot(1.0); glPopMatrix(); /**********************************茶壶*************************************************/ glPushMatrix(); glTranslatef(4.0f,0.0f, 4.0f); if (isRotatef[2]) //判断是否需要旋转 { glRotatef((GLfloat)mousePosX, -1.0, 0.0, 0.0); glRotatef((GLfloat)mousePosY, 0.0, -1.0, 0.0); } glMaterialfv(GL_FRONT,GL_AMBIENT, Ambient_Teapot3); glMaterialfv(GL_FRONT,GL_DIFFUSE, Diffuse_Teapot3); glMaterialfv(GL_FRONT,GL_SPECULAR, Specular_Teapot3); glMaterialfv(GL_FRONT,GL_SHININESS, Shininess_Teapot3); glMaterialfv(GL_FRONT,GL_EMISSION, no_mat); glutSolidTeapot(1.0); glPopMatrix(); glutSwapBuffers();} void reshape(int w,int h){ float aspect = (float)w/((h)?h:1);//平截头体的纵横比,也就是宽度除以高度,(h)?h:1意思是若h=0,则h=1 glViewport(0,0, w,h); //进行投影变换前调用下面两个函数,接下来的变换函数将影响投影矩阵 glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f,aspect, 1.0f, 100.0f);// glViewport(0,0,w,h); glMatrixMode(GL_MODELVIEW);} void keyboard(unsignedchar key, int x, int y){ switch (key) { case 'w': camera.cam[1] +=0.1;//向上 break; case 's': camera.cam[1] -=0.1;//向下 break; case 'a': camera.cam[0] -=0.1;//向左 break; case 'd': camera.cam[0] +=0.1;//向右 break; case 'r': camera.cam[2] +=0.2;//放大视图(向外) break; case 'f': camera.cam[2] -=0.2;//缩小视图(向内) break; case 'm': lightRotatefSpeed+= 5.0f;//加快光源的速度 break; case 'n': lightRotatefSpeed-= 5.05f; break; case '4': //鼠标控制整个视图旋转(光源不会跟着旋转) isRotatef[3] = true; isRotatef[0] =isRotatef[1] = isRotatef[2] = false; break; case '5': //清除所做的任何旋转和缩放 camera.cam[0] =camera.cam[1] = camera.cam[2] = 0.0f; tempX = 0; tempY = 0; mousePosY = 0; mousePosX = 0; break; case '1': //鼠标控制茶壶旋转 (光源会跟着旋转) isRotatef[0] = true; isRotatef[1] =isRotatef[2] = isRotatef[3] =false; break; case '2': //鼠标控制茶壶旋转 isRotatef[1] = true; isRotatef[0] =isRotatef[2] = isRotatef[3] = false; break; case '3': //鼠标控制茶壶旋转 isRotatef[2] = true; isRotatef[0] =isRotatef[1] = isRotatef[3] = false; break; case 'i': //打开/关闭0号光源 isLightOpen[0] =!isLightOpen[0]; if (!isLightOpen[0]) { glDisable(GL_LIGHT0); } else { glEnable(GL_LIGHT0); } break; case 'o': //打开/关闭1号光源 isLightOpen[1] =!isLightOpen[1]; if (!isLightOpen[1]) { glDisable(GL_LIGHT1); } else { glEnable(GL_LIGHT1); } break; case 'p': //打开/关闭2号光源 isLightOpen[2] =!isLightOpen[2]; if (!isLightOpen[2]) { glDisable(GL_LIGHT2); } else { glEnable(GL_LIGHT2); } break; case 27: //退出程序 exit(0); break; }} void mouse(int button,int state, int x,int z){ switch(button) { case GLUT_LEFT_BUTTON: if (state == GLUT_DOWN) { tempX = x; tempY = z; isMosDownMove = true; //鼠标移动时需要用到的判断变量 } else { isMosDownMove = false; } break; }} void motion(int x,int z){ if(isMosDownMove) { mousePosY =(mousePosY + (x - tempX))%360; mousePosX =(mousePosX + (z - tempY))%360; tempX = x; tempY = z; glutPostRedisplay(); }} void refresh(void){ //刷新屏幕 glutPostRedisplay();} int main(int argc,char* argv[]){ //定义刚开始时观察点的位置 camera.camera[0] =0.0f; camera.camera[1] =0.0f; camera.camera[2] =20.0f; //平移观察点时的变量参数 camera.cam[0] =camera.cam[1] = camera.cam[2] = 0.0f; //相机瞄准的参考点的参数 camera.lookat[0] =0.0f-camera.camera[0]; camera.lookat[1] =0.0f-camera.camera[1]; camera.lookat[2] =20.0f-camera.camera[2]; glutInit(&argc,argv); glutInitDisplayMode(GLUT_DOUBLE| GLUT_DEPTH | GLUT_RGB); glutInitWindowSize(800,600); glutInitWindowPosition(100,100); glutCreateWindow("Teaports"); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMouseFunc(mouse); glutMotionFunc(motion); glutIdleFunc(refresh); glutMainLoop(); return 0;}
运行结果:
0 0
- OpenGL学习记录4
- OpenGL学习问题记录
- OpenGL学习记录1
- OpenGL学习记录2
- OpenGL学习记录3
- OpenGL学习记录5
- OpenGL学习记录6
- OpenGL学习记录7
- OpenGL入门学习记录
- OpenGL学习记录(1)
- 我的OpenGL学习记录1
- OpenGL学习记录——旋转矩形
- 画个三角形-----------openGL学习记录
- OPENGL记录
- Qt+openGL学习记录(4)`如何实现物体在三维坐标系中的旋转`
- OpenGL学习4
- opengl学习笔记(4)
- openGL学习笔记4
- 装了SVN,你的关联图标变了没有?
- C++第3周(春)项目3 时间类
- 黑马程序员-java集合笔记之map
- ORACLE FREELIST HWM(转)
- 关于VirtualBOX安装错误:VERR_MODULE_NOT_FOUND的解决方法。
- OpenGL学习记录4
- Multiply Strings[LeetCode]
- 使用着色器实现蒙皮动画和形变动画
- _存储一些有用的链接
- Autofac 基本例子
- <<J2SE>>Java代码自写9Path算法
- PL/SQL Developer+Oracle 连接远端数据库
- Nexus搭建私服
- 玩转html5<canvas>画图