OpenGL超級寶典筆記——光照參數與材料屬性

<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>&#160;</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>&#160;</div>ip

<div>第二種方法顏色追蹤較爲簡單。使用顏色追蹤,能夠經過glColor來設置材料屬性。第一步啓用顏色追蹤</div>ci

<div>glEnable(GL_COLOR_MATERIAL);</div>

<div>而後經過glColorMaterial指定須要顏色追蹤的材料屬性。下面的例子的設置 追蹤多邊形正面的環境光和漫反射的材料屬性。</div>

<div>glColorMaterial(GL_FRONT, GL_AMBIENT_ANDDIFFUSE);</div>

<div>&#160;</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>&#160;</p>

<div id="codeSnippetWrapper"> <pre id="codeSnippet" class="csharpcode"><font face="微軟雅黑">完整的例子:</font><br /><span class="preproc">#include</span> <span class="str">&quot;gltools.h&quot;</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 &gt; 356.0f)<br /> xRot = 0.0f;<br /><br /> <span class="kwrd">if</span>(key &lt; -1.0f)<br /> xRot = 355.0f;<br /><br /> <span class="kwrd">if</span>(key &gt; 356.0f)<br /> yRot = 0.0f;<br /><br /> <span class="kwrd">if</span>(key &lt; -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 &lt;= 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(&amp;argc, argv);<br /> glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);<br /> glutInitWindowSize(800,600);<br /> glutCreateWindow(<span class="str">&quot;Jet&quot;</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>

相關文章
相關標籤/搜索