<h3>添加光照</h3> <p>glEnable(GL_LIGHTING);</p> <p>这个函数调用告诉OpenGL使用材料属性和光照参数去决定每一个顶点的颜色值。若是没有开启这个函数,则看到的物体是昏暗的。开启光照后会根据你的材料属性和光照参数计算顶点的颜色值。下图对比未开启光照和开启光照的效果。</p> <p><a href="http://static.oschina.net/uploads/img/201310/07213646_TTBF.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://static.oschina.net/uploads/img/201310/07213647_E9ZV.png" width="218" height="217" /></a>(未开启光照)</p> <p><a href="http://static.oschina.net/uploads/img/201310/07213648_pWop.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://static.oschina.net/uploads/img/201310/07213649_ZT30.png" width="216" height="244" /></a>(开启光照)</p> <h3>设置全局环境光</h3> <p>OpenGL提供了一种全局的环境光。这种光是一种向全部方向均匀发射的光源。它能够照明没有被光源直接照射的物体的背面。</p> <p>在OpenGL中经过glLightModel这个函数来设置全局环境光。第一个参数是GL_LIGHT_MODEL_AMBIETN。</p> <div> <pre id="codeSnippet" class="csharpcode"><span class="rem">//明亮的白光</span><br />GLfloat ambientLight[] = {1.0f, 1.0f, 1.0f, 1.0f};<br /><span class="rem">//开启光照</span><br />glEnable(GL_LIGHTING);<br /><span class="rem">//设置全局环境光为白光</span><br />glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);</pre> </div>数组
<div>全局环境光照的默认RGBA值是(0.2, 0.2, 0.2, 1.0),这个值是比较昏暗的。</div>app
<div> </div>ide
<h3>设置材料属性</h3>函数
<p>设置好了全局环境光源后,咱们须要为设置材料属性。有两种设置材料属性的方式,第一种是在指定多边形以前调用glMaterial函数。例子:</p>oop
<div id="codeSnippetWrapper"> <pre id="codeSnippet" class="csharpcode"><span class="rem">//灰色的材料属性</span><br />GLfloat gray[] = {0.75f, 0.75f, 0.75f, 1.0f};<br /><br />glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, gray);<br />glBegin(GL_TRIANGLES);<br /> glVertex3f(-15.0f, 0.0f, 30.0f);<br /> glVertex3f(0.0f, 15.0f, 30.0f);<br /> glVertex3f(0.0f, 0.0f, -56.0f);<br />glEnd();</pre> glMaterialfv的第一个参数是指定正面, 反面, 正面和反面。第二个参数是告诉Opengl设置哪一个属性。GL_AMBIENT_AND_DIFFUSE指定环境光反射属性和漫反射属性为同一个值。最后一个参数是一个RGBA值的数组。spa
<br /></div>.net
<div>在绝大多数状况下,环境光和漫反射光的成分是相同的,除非须要特殊的镜面光的效果。在多边形顶点以前须要调用glMaterial函数,并设置一个包含各类颜色成分的数组。这个操做仍是至关繁琐的。下面介绍一种更简单的方式</div>code
<div> </div>ip
<div>第二种方法颜色追踪较为简单。使用颜色追踪,能够经过glColor来设置材料属性。第一步启用颜色追踪</div>ci
<div>glEnable(GL_COLOR_MATERIAL);</div>
<div>而后经过glColorMaterial指定须要颜色追踪的材料属性。下面的例子的设置 追踪多边形正面的环境光和漫反射的材料属性。</div>
<div>glColorMaterial(GL_FRONT, GL_AMBIENT_ANDDIFFUSE);</div>
<div> </div>
<div>下面的例子使用颜色追踪的方式重写上面的例子:</div>
<div> <pre id="codeSnippet" class="csharpcode"><span class="rem">//开启颜色追踪</span><br />glEnable(GL_COLOR_MATERIAL);<br /><span class="rem">//设置颜色追踪的材料属性以及多边形的面</span><br />glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);<br /><br /><span class="rem">//设置颜色</span><br />glColor3f(0.75f, 0.75f, 0.75f);<br />glBegin(GL_TRIANGLES);<br /> glVertex3f(-15.0f, 0.0f, 30.0f);<br /> glVertex3f(0.0f, 15.0f, 30.0f);<br /> glVertex3f(0.0f, 0.0f, -56.0f);<br />glEnd();<br /></pre> </div>
<div>设置环境的例子:</div>
<div id="codeSnippetWrapper"> <pre id="codeSnippet" class="csharpcode"><span class="kwrd">void</span> SetupRC()<br />{<br /> GLfloat ambientLight[] = {1.0f, 1.0f, 1.0f, 1.0f};<br /> glEnable(GL_DEPTH_TEST); <br /> glEnable(GL_CULL_FACE); <br /> glFrontFace(GL_CCW); <br /><br /> glEnable(GL_COLOR_MATERIAL);<br /> glEnable(GL_LIGHTING);<br /> //设置光照模型<br /> glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);<br /> //设置材料追踪<br /> glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);<br /><br /> <br /> glClearColor(0.0f, 0.0f, 05.f,1.0f);<br />}<br /></pre> 开启明亮的环境光效果:</div>
<div> <br /></div>
<div><a href="http://static.oschina.net/uploads/img/201310/07213649_KZTV.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://static.oschina.net/uploads/img/201310/07213650_XMfk.png" width="232" height="244" /></a></div>
<div>把环境光调成原来的一半的效果:</div>
<div>GLfloat ambientLight[] = {0.5f, 0.5f, 0.5f, 1.0f};</div>
<p><a href="http://static.oschina.net/uploads/img/201310/07213652_QEEH.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://static.oschina.net/uploads/img/201310/07213653_cIfd.png" width="244" height="216" /></a></p>
<p> </p>
<div id="codeSnippetWrapper"> <pre id="codeSnippet" class="csharpcode"><font face="微软雅黑">完整的例子:</font><br /><span class="preproc">#include</span> <span class="str">"gltools.h"</span> <span class="rem">// System and OpenGL Stuff</span><br /><br /><br /><span class="rem">// Rotation amounts</span><br /><span class="kwrd">static</span> GLfloat xRot = 0.0f;<br /><span class="kwrd">static</span> GLfloat yRot = 0.0f;<br /><br /><br /><span class="rem">// Called to draw scene</span><br /><span class="kwrd">void</span> RenderScene(<span class="kwrd">void</span>)<br />{<br /> <span class="rem">// Clear the window with current clearing color</span><br /> glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);<br /><br /> <span class="rem">// Save matrix state and do the rotation</span><br /> glPushMatrix();<br /> glRotatef(xRot, 1.0f, 0.0f, 0.0f);<br /> glRotatef(yRot, 0.0f, 1.0f, 0.0f);<br /><br /> glColor3f(1.0f, 1.0f, 1.0f);<br /> glBegin(GL_TRIANGLES);<br /> <span class="rem">//机头</span><br /> glVertex3f(-15.0f, 0.0f, 30.0f);<br /> glVertex3f(15.0f, 0.0f, 30.0f);<br /> glVertex3f(0.0f, 0.0f, 60.0f);<br /><br /> glColor3f(0.0f, 0.0f, 0.0f);<br /> glVertex3f(-15.0f, 0.0f, 30.0f);<br /> glVertex3f(0.0f, 0.0f, 60.0f);<br /> glVertex3f(0.0f, 15.0f, 30.0f);<br /><br /> glColor3f(1.0f, 0.0f, 0.0f);<br /> glVertex3f(0.0f, 0.0f, 60.0f);<br /> glVertex3f(15.0f, 0.0f, 30.0f);<br /> glVertex3f(0.0f, 15.0f, 30.0f);<br /> <span class="rem">//机身</span><br /> glColor3f(0.0f, 1.0f, 0.0f);<br /> glVertex3f(-15.0f, 0.0f, 30.0f);<br /> glVertex3f(0.0f, 15.0f, 30.0f);<br /> glVertex3f(0.0f, 0.0f, -53.0f);<br /><br /> glColor3f(1.0f, 1.0f, 0.0f);<br /> glVertex3f(0.0f, 15.0f, 30.0f);<br /> glVertex3f(15.0f, 0.0f, 30.0f);<br /> glVertex3f(0.0f, 0.0f, -53.0f);<br /><br /> glColor3f(0.5f, 0.5f, 0.3f);<br /> glVertex3f(15.0f, 0.0f, 30.0f);<br /> glVertex3f(-15.0f, 0.0f, 30.0f);<br /> glVertex3f(0.0f, 0.0f, -53.0f);<br /><br /> <span class="rem">//机尾巴</span><br /> glColor3f(0.3f, 1.0f, 0.2f);<br /> glVertex3f(0.0f, 0.0f, -53.0f);<br /> glVertex3f(0.0f, 0.0f, -70.0f);<br /> glVertex3f(0.0f, 15.0f, -70.0f);<br /><br /> glColor3f(0.7f, 0.5f, 0.3f);<br /> glVertex3f(-15.0f, 0.0f, -70.0f);<br /> glVertex3f(0.0f, 0.0f, -53.0f);<br /> glVertex3f(0.0f, 0.0f, -70.0f);<br /><br /> glColor3f(0.2f, 0.2f, 0.8f);<br /> glVertex3f(15.0f, 0.0f, -70.0f);<br /> glVertex3f(0.0f, 0.0f, -70.0f);<br /> glVertex3f(0.0f, 0.0f, -53.0f);<br /><br /> <span class="rem">//因为背面被消除,背面再画一次</span><br /> glColor3f(0.3f, 1.0f, 0.2f);<br /> glVertex3f(0.0f, 0.0f, -70.0f);<br /> glVertex3f(0.0f, 0.0f, -53.0f);<br /> glVertex3f(0.0f, 15.0f, -70.0f);<br /><br /> <br /> glColor3f(0.7f, 0.5f, 0.3f);<br /> glVertex3f(0.0f, 0.0f, -53.0f);<br /> glVertex3f(-15.0f, 0.0f, -70.0f);<br /> glVertex3f(0.0f, 0.0f, -70.0f);<br /><br /> glColor3f(0.2f, 0.2f, 0.8f);<br /> glVertex3f(0.0f, 0.0f, -70.0f);<br /> glVertex3f(15.0f, 0.0f, -70.0f);<br /> glVertex3f(0.0f, 0.0f, -53.0f);<br /><br /> <span class="rem">// 左翼 </span><br /> glColor3ub(128,128,128);<br /> glVertex3f(0.0f,2.0f,27.0f);<br /> glVertex3f(-60.0f, 2.0f, -8.0f);<br /> glVertex3f(60.0f, 2.0f, -8.0f);<br /><br /> glColor3ub(64,64,64);<br /> glVertex3f(60.0f, 2.0f, -8.0f);<br /> glVertex3f(0.0f, 7.0f, -8.0f);<br /> glVertex3f(0.0f,2.0f,27.0f);<br /><br /> glColor3ub(192,192,192);<br /> glVertex3f(60.0f, 2.0f, -8.0f);<br /> glVertex3f(-60.0f, 2.0f, -8.0f);<br /> glVertex3f(0.0f,7.0f,-8.0f);<br /><br /> <span class="rem">//右翼 </span><br /> glColor3ub(64,64,64);<br /> glVertex3f(0.0f,2.0f,27.0f);<br /> glVertex3f(0.0f, 7.0f, -8.0f);<br /> glVertex3f(-60.0f, 2.0f, -8.0f);<br /> glEnd();<br /> glPopMatrix();<br /><br /> <span class="rem">// Display the results</span><br /> glutSwapBuffers();<br />}<br /><br /><span class="rem">// This function does any needed initialization on the rendering</span><br /><span class="rem">// context. </span><br /><span class="kwrd">void</span> SetupRC()<br />{<br /> GLfloat ambientLight[] = {0.5f, 0.5f, 0.5f, 1.0f};<br /> glEnable(GL_DEPTH_TEST); <span class="rem">// Hidden surface removal</span><br /> glEnable(GL_CULL_FACE); <span class="rem">// Do not calculate inside of jet</span><br /> glFrontFace(GL_CCW); <span class="rem">// Counter clock-wise polygons face out</span><br /><br /> glEnable(GL_COLOR_MATERIAL);<br /> glEnable(GL_LIGHTING);<br /> <br /> glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);<br /> <br /> glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);<br /><br /> <span class="rem">// Nice light blue</span><br /> glClearColor(0.0f, 0.0f, 05.f,1.0f);<br />}<br /><br /><span class="kwrd">void</span> SpecialKeys(<span class="kwrd">int</span> key, <span class="kwrd">int</span> x, <span class="kwrd">int</span> y)<br />{<br /> <span class="kwrd">if</span>(key == GLUT_KEY_UP)<br /> xRot-= 5.0f;<br /><br /> <span class="kwrd">if</span>(key == GLUT_KEY_DOWN)<br /> xRot += 5.0f;<br /><br /> <span class="kwrd">if</span>(key == GLUT_KEY_LEFT)<br /> yRot -= 5.0f;<br /><br /> <span class="kwrd">if</span>(key == GLUT_KEY_RIGHT)<br /> yRot += 5.0f;<br /><br /> <span class="kwrd">if</span>(key > 356.0f)<br /> xRot = 0.0f;<br /><br /> <span class="kwrd">if</span>(key < -1.0f)<br /> xRot = 355.0f;<br /><br /> <span class="kwrd">if</span>(key > 356.0f)<br /> yRot = 0.0f;<br /><br /> <span class="kwrd">if</span>(key < -1.0f)<br /> yRot = 355.0f;<br /><br /> <span class="rem">// Refresh the Window</span><br /> glutPostRedisplay();<br />}<br /><br /><br /><span class="kwrd">void</span> ChangeSize(<span class="kwrd">int</span> w, <span class="kwrd">int</span> h)<br />{<br /> GLfloat nRange = 80.0f;<br /> <span class="rem">// Prevent a divide by zero</span><br /> <span class="kwrd">if</span>(h == 0)<br /> h = 1;<br /><br /> <span class="rem">// Set Viewport to window dimensions</span><br /> glViewport(0, 0, w, h);<br /><br /> <span class="rem">// Reset coordinate system</span><br /> glMatrixMode(GL_PROJECTION);<br /> glLoadIdentity();<br /><br /> <span class="rem">// Establish clipping volume (left, right, bottom, top, near, far)</span><br /> <span class="kwrd">if</span> (w <= h) <br /> glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange);<br /> <span class="kwrd">else</span> <br /> glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange);<br /><br /> glMatrixMode(GL_MODELVIEW);<br /> glLoadIdentity();<br />}<br /><br /><span class="kwrd">int</span> main(<span class="kwrd">int</span> argc, <span class="kwrd">char</span>* argv[])<br />{<br /> glutInit(&argc, argv);<br /> glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);<br /> glutInitWindowSize(800,600);<br /> glutCreateWindow(<span class="str">"Jet"</span>);<br /> glutReshapeFunc(ChangeSize);<br /> glutSpecialFunc(SpecialKeys);<br /> glutDisplayFunc(RenderScene);<br /> SetupRC();<br /> glutMainLoop();<br /><br /> <span class="kwrd">return</span> 0;<br />}<br /></pre>
<br /></div>