<h3>什么是颜色</h3> <p>颜色只是某种波长的光。现实中我们看到几乎都是由许多不同类型的光组合而成的。波长是光波相邻的波峰或相邻的波谷之间的距离。</p> <p><a href="http://static.oschina.net/uploads/img/201309/26224830_sPUw.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://static.oschina.net/uploads/img/201309/26224830_ChIK.png" width="564" height="142"></a></p> <p>人肉眼可见的光波的波长位于390nm(紫色光)到720nm(红色光)之间。紫外线和红外线都是人肉眼不可见的光。</p> <p><a href="http://static.oschina.net/uploads/img/201309/26224831_ZaSi.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://static.oschina.net/uploads/img/201309/26224832_tn4W.png" width="557" height="161"></a></p> <p>事实上白色和黑色并不是一种颜色。黑色是没有颜色,因为可见光都被材料吸收了。而白色则是材料均匀的反射各种波长的光。</p> <p>光即是波也是粒子(波粒二象性)。人之所以看到颜色,是因为光子刺激视网膜上数以百万计的锥细胞,导致神经能量传递到大脑中,大脑把把这种信息解释为光和颜色,光的亮度越大,撞击锥细胞的光子就越多。物体会反射一些光子并吸收一些光子。人眼看到纯蓝色的物体,是因为该物体反射了蓝色波长的光,吸收了其他颜色其他波长的光。如果人眼接受到的光的波长是均匀分布的,相当于看到了白色。</p> <p><a href="http://static.oschina.net/uploads/img/201309/26224833_6Yi7.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://static.oschina.net/uploads/img/201309/26224836_yIzE.png" width="546" height="307"></a></p> <h4>计算机如何产生颜色</h4> <p>计算机监视器在设计时就用来产生三种颜色的光,每种光的强度在一个可变的范围内。计算机监视器(CRT)的后面,有一个电子枪在屏幕后面发射电子,屏幕上含有磷,当电子撞击屏幕时,能够发射红、绿、蓝光。这三种颜色的磷紧密包装在一起作为屏幕上的一个物理点(像素)。它所发射的光的强度因电子束的强度而异。</p> <p><a href="http://static.oschina.net/uploads/img/201309/26224837_Ikqx.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://static.oschina.net/uploads/img/201309/26224838_Hogc.png" width="545" height="307"></a></p> <h3>在OpenGL中使用颜色</h3> <p>在OpenGL中我们分别指定红、绿、蓝成分的强度来确定一个颜色。</p> <h4>颜色立方体</h4> <p>由于一种颜色是通过三个非负的颜色值指定的,我们可以对所有颜色进行建模,形成一个RGB颜色空间。颜色空间以红、绿、蓝为轴,红、绿、蓝的坐标就像x、y、z的坐标。在坐标(0,0,0)处就代表所红、绿、蓝颜色的强度都为0,即黑色。在坐标(255,255,255)红、绿、蓝颜色的强度达到最大值,为白色。不同的灰色值,就分布在(0,0,0)到(255,255,255)这条立方体的对角线上。</p> <p><a href="http://static.oschina.net/uploads/img/201309/26224839_Z3VJ.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://static.oschina.net/uploads/img/201309/26224839_tbMJ.png" width="578" height="255"></a></p> <p><a href="http://static.oschina.net/uploads/img/201309/26224846_6tj6.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://static.oschina.net/uploads/img/201309/26224849_BnJG.png" width="345" height="361"></a></p> <h4>设置颜色</h4> <p>在OpenGL中设置颜色的函数原型如下:</p> <p>void glColor<x><t>(red, green, blue, alpha);</p> <p>其中x代表参数个数,可以是3个值代表rgb颜色,或者使4个值分别代表rgba。alpha成分用来代表透明度。t代表参数的类型,可以是b,d,f,i,s,ub,ui,us对应的类型是byte,double,float,integer,short,unsigned byte, unsigned integer,unsigned short。glColor3f指定各个颜色成分的强度值的范围为0.0到1.0之间。glColor3ub则可以指定各个颜色成分的强度值的范围在0-255之间。</p> <h4>着色</h4> <p>glColor函数设置了一个颜色值,之后的图元都使用这个颜色值着色。如果我们为图元的顶点指定了不同的颜色值,那么这个图元用什么颜色来着色呢?</p> <p>如果图元是点,那么每个点可以使用其指定的颜色来着色。如果图元是有两个不同颜色的顶点指定的一条线,线的颜色要根据着色的模式来着色,如果是使用GL_FLAT模式,则使用最后一个顶点的颜色来着色。如果使用的是GL_SMOOTH平滑着色的模式,则进行平滑插值。在RGB颜色空间中的任意两个点,都能连成一条直线。平滑着色即是使用这条线上的颜色来对图元内的点进行填着色。无论你的多边形有多复杂,OpenGL都能够正确地为每个点着色。OpenGL已经帮我们实现了这种算法,我们不需要关心。<a href="http://static.oschina.net/uploads/img/201309/26224850_VgxT.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://static.oschina.net/uploads/img/201309/26224851_xCxz.png" width="581" height="391"></a></p> <p><a href="http://static.oschina.net/uploads/img/201309/26224852_63al.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://static.oschina.net/uploads/img/201309/26224853_BUDf.png" width="585" height="321"></a></p> <p>示例:画一个平滑着色的三角形</p> <div id="codeSnippetWrapper"><pre id="codeSnippet" class="csharpcode"><span class="kwrd">static</span> <span class="kwrd">void</span> RenderScene()<br>{<br> glClear(GL_COLOR_BUFFER_BIT);<br><br> glShadeModel(GL_SMOOTH);<br> <span class="rem">// Draw the triangle</span><br> glBegin(GL_TRIANGLES);<br> <span class="rem">// Red Apex</span><br> glColor3ub((GLubyte)255,(GLubyte)0,(GLubyte)0);<br> glVertex3f(0.0f,200.0f,0.0f);<br> <span class="rem">// Green on the right bottom corner</span><br> glColor3ub((GLubyte)0,(GLubyte)255,(GLubyte)0);<br> glVertex3f(200.0f,-70.0f,0.0f);<br> <span class="rem">// Blue on the left bottom corner</span><br> glColor3ub((GLubyte)0,(GLubyte)0,(GLubyte)255);<br> glVertex3f(-200.0f, -70.0f, 0.0f);<br> glEnd();<br><br> glutSwapBuffers();<br>}</pre><a href="http://static.oschina.net/uploads/img/201309/26224857_XOUu.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://static.oschina.net/uploads/img/201309/26224859_xQxT.png" width="382" height="313"></a><br></div>