首页 / 操作系统 / Linux / OpenGL超级宝典学习笔记——光照参数与材料属性
添加光照 glEnable(GL_LIGHTING);这个函数调用告诉OpenGL使用材料属性和光照参数去决定每个顶点的颜色值。如果没有开启这个函数,则看到的物体是昏暗的。开启光照后会根据你的材料属性和光照参数计算顶点的颜色值。下图对比未开启光照和开启光照的效果。(未开启光照)(开启光照)设置全局环境光 OpenGL提供了一种全局的环境光。这种光是一种向所有方向均匀发射的光源。它可以照明没有被光源直接照射的物体的背面。在OpenGL中通过glLightModel这个函数来设置全局环境光。第一个参数是GL_LIGHT_MODEL_AMBIETN。//明亮的白光 GLfloat ambientLight[] = {1.0f, 1.0f, 1.0f, 1.0f}; //开启光照 glEnable(GL_LIGHTING); //设置全局环境光为白光 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight); 全局环境光照的默认RGBA值是(0.2, 0.2, 0.2, 1.0),这个值是比较昏暗的。 设置材料属性 设置好了全局环境光源后,我们需要为设置材料属性。有两种设置材料属性的方式,第一种是在指定多边形之前调用glMaterial函数。例子://灰色的材料属性 GLfloat gray[] = {0.75f, 0.75f, 0.75f, 1.0f}; glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, gray); glBegin(GL_TRIANGLES); glVertex3f(-15.0f, 0.0f, 30.0f); glVertex3f(0.0f, 15.0f, 30.0f); glVertex3f(0.0f, 0.0f, -56.0f); glEnd();glMaterialfv的第一个参数是指定正面, 反面, 正面和反面。第二个参数是告诉Opengl设置哪个属性。GL_AMBIENT_AND_DIFFUSE指定环境光反射属性和漫反射属性为同一个值。最后一个参数是一个RGBA值的数组。在绝大多数情况下,环境光和漫反射光的成分是相同的,除非需要特殊的镜面光的效果。在多边形顶点之前需要调用glMaterial函数,并设置一个包含各种颜色成分的数组。这个操作还是相当繁琐的。下面介绍一种更简单的方式 第二种方法颜色追踪较为简单。使用颜色追踪,可以通过glColor来设置材料属性。第一步启用颜色追踪glEnable(GL_COLOR_MATERIAL);然后通过glColorMaterial指定需要颜色追踪的材料属性。下面的例子的设置 追踪多边形正面的环境光和漫反射的材料属性。glColorMaterial(GL_FRONT, GL_AMBIENT_ANDDIFFUSE); 下面的例子使用颜色追踪的方式重写上面的例子://开启颜色追踪 glEnable(GL_COLOR_MATERIAL); //设置颜色追踪的材料属性以及多边形的面 glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); //设置颜色 glColor3f(0.75f, 0.75f, 0.75f); glBegin(GL_TRIANGLES); glVertex3f(-15.0f, 0.0f, 30.0f); glVertex3f(0.0f, 15.0f, 30.0f); glVertex3f(0.0f, 0.0f, -56.0f); glEnd();设置环境的例子:void SetupRC() { GLfloat ambientLight[] = {1.0f, 1.0f, 1.0f, 1.0f}; glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glFrontFace(GL_CCW); glEnable(GL_COLOR_MATERIAL); glEnable(GL_LIGHTING); //设置光照模型 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight); //设置材料追踪 glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); glClearColor(0.0f, 0.0f, 05.f,1.0f); }开启明亮的环境光效果: 把环境光调成原来的一半的效果:GLfloat ambientLight[] = {0.5f, 0.5f, 0.5f, 1.0f}; 完整的例子: #include "gltools.h"// System and OpenGL Stuff // Rotation amounts static GLfloat xRot = 0.0f; static GLfloat yRot = 0.0f; // Called to draw scene void RenderScene(void) { // Clear the window with current clearing color glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Save matrix state and do the rotation glPushMatrix(); glRotatef(xRot, 1.0f, 0.0f, 0.0f); glRotatef(yRot, 0.0f, 1.0f, 0.0f); glColor3f(1.0f, 1.0f, 1.0f); glBegin(GL_TRIANGLES); //机头 glVertex3f(-15.0f, 0.0f, 30.0f); glVertex3f(15.0f, 0.0f, 30.0f); glVertex3f(0.0f, 0.0f, 60.0f); glColor3f(0.0f, 0.0f, 0.0f); glVertex3f(-15.0f, 0.0f, 30.0f); glVertex3f(0.0f, 0.0f, 60.0f); glVertex3f(0.0f, 15.0f, 30.0f); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 60.0f); glVertex3f(15.0f, 0.0f, 30.0f); glVertex3f(0.0f, 15.0f, 30.0f); //机身 glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(-15.0f, 0.0f, 30.0f); glVertex3f(0.0f, 15.0f, 30.0f); glVertex3f(0.0f, 0.0f, -53.0f); glColor3f(1.0f, 1.0f, 0.0f); glVertex3f(0.0f, 15.0f, 30.0f); glVertex3f(15.0f, 0.0f, 30.0f); glVertex3f(0.0f, 0.0f, -53.0f); glColor3f(0.5f, 0.5f, 0.3f); glVertex3f(15.0f, 0.0f, 30.0f); glVertex3f(-15.0f, 0.0f, 30.0f); glVertex3f(0.0f, 0.0f, -53.0f); //机尾巴 glColor3f(0.3f, 1.0f, 0.2f); glVertex3f(0.0f, 0.0f, -53.0f); glVertex3f(0.0f, 0.0f, -70.0f); glVertex3f(0.0f, 15.0f, -70.0f); glColor3f(0.7f, 0.5f, 0.3f); glVertex3f(-15.0f, 0.0f, -70.0f); glVertex3f(0.0f, 0.0f, -53.0f); glVertex3f(0.0f, 0.0f, -70.0f); glColor3f(0.2f, 0.2f, 0.8f); glVertex3f(15.0f, 0.0f, -70.0f); glVertex3f(0.0f, 0.0f, -70.0f); glVertex3f(0.0f, 0.0f, -53.0f); //由于背面被消除,背面再画一次 glColor3f(0.3f, 1.0f, 0.2f); glVertex3f(0.0f, 0.0f, -70.0f); glVertex3f(0.0f, 0.0f, -53.0f); glVertex3f(0.0f, 15.0f, -70.0f); glColor3f(0.7f, 0.5f, 0.3f); glVertex3f(0.0f, 0.0f, -53.0f); glVertex3f(-15.0f, 0.0f, -70.0f); glVertex3f(0.0f, 0.0f, -70.0f); glColor3f(0.2f, 0.2f, 0.8f); glVertex3f(0.0f, 0.0f, -70.0f); glVertex3f(15.0f, 0.0f, -70.0f); glVertex3f(0.0f, 0.0f, -53.0f); // 左翼 glColor3ub(128,128,128); glVertex3f(0.0f,2.0f,27.0f); glVertex3f(-60.0f, 2.0f, -8.0f); glVertex3f(60.0f, 2.0f, -8.0f); glColor3ub(64,64,64); glVertex3f(60.0f, 2.0f, -8.0f); glVertex3f(0.0f, 7.0f, -8.0f); glVertex3f(0.0f,2.0f,27.0f); glColor3ub(192,192,192); glVertex3f(60.0f, 2.0f, -8.0f); glVertex3f(-60.0f, 2.0f, -8.0f); glVertex3f(0.0f,7.0f,-8.0f); //右翼 glColor3ub(64,64,64); glVertex3f(0.0f,2.0f,27.0f); glVertex3f(0.0f, 7.0f, -8.0f); glVertex3f(-60.0f, 2.0f, -8.0f); glEnd(); glPopMatrix(); // Display the results glutSwapBuffers(); } // This function does any needed initialization on the rendering // context. void SetupRC() { GLfloat ambientLight[] = {0.5f, 0.5f, 0.5f, 1.0f}; glEnable(GL_DEPTH_TEST);// Hidden surface removal glEnable(GL_CULL_FACE);// Do not calculate inside of jet glFrontFace(GL_CCW);// Counter clock-wise polygons face out glEnable(GL_COLOR_MATERIAL); glEnable(GL_LIGHTING); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight); glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); // Nice light blue glClearColor(0.0f, 0.0f, 05.f,1.0f); } void SpecialKeys(int key, int x, int y) { if(key == GLUT_KEY_UP) xRot-= 5.0f; if(key == GLUT_KEY_DOWN) xRot += 5.0f; if(key == GLUT_KEY_LEFT) yRot -= 5.0f; if(key == GLUT_KEY_RIGHT) yRot += 5.0f; if(key > 356.0f) xRot = 0.0f; if(key < -1.0f) xRot = 355.0f; if(key > 356.0f) yRot = 0.0f; if(key < -1.0f) yRot = 355.0f; // Refresh the Window glutPostRedisplay(); } void ChangeSize(int w, int h) { GLfloat nRange = 80.0f; // Prevent a divide by zero if(h == 0) h = 1; // Set Viewport to window dimensions glViewport(0, 0, w, h); // Reset coordinate system glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Establish clipping volume (left, right, bottom, top, near, far) if (w <= h) glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange); else glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(800,600); glutCreateWindow("Jet"); glutReshapeFunc(ChangeSize); glutSpecialFunc(SpecialKeys); glutDisplayFunc(RenderScene); SetupRC(); glutMainLoop(); return 0; }OpenGL超级宝典 第4版 中文版PDF+英文版+源代码 见 http://www.linuxidc.com/Linux/2013-10/91413.htmOpenGL编程指南(原书第7版)中文扫描版PDF 下载 http://www.linuxidc.com/Linux/2012-08/67925.htmOpenGL 渲染篇 http://www.linuxidc.com/Linux/2011-10/45756.htmUbuntu 13.04 安装 OpenGL http://www.linuxidc.com/Linux/2013-05/84815.htmOpenGL三维球体数据生成与绘制【附源码】 http://www.linuxidc.com/Linux/2013-04/83235.htmUbuntu下OpenGL编程基础解析 http://www.linuxidc.com/Linux/2013-03/81675.htm如何在Ubuntu使用eclipse for c++配置OpenGL http://www.linuxidc.com/Linux/2012-11/74191.htm 更多《OpenGL超级宝典学习笔记》相关知识 见 http://www.linuxidc.com/search.aspx?where=nkey&keyword=34581本文永久更新链接地址 :http://www.linuxidc.com/Linux/2015-02/113999.htm
收藏该网址