材質顏色 OpenGL用材料對光的紅、綠、藍三原色的反射率來近似定義材料的顏色。象光源一樣,材料顏色也分成環境、漫反射和鏡面反射成分,它們決定了材料對環境光、漫反射光和鏡面反射光的反射程度。在進行光照計算時,材料對環境光的反射率與每個進入光源的環境光結合,對漫反射光的反射率與每個進入光源的漫反射光結 ...
材質顏色
OpenGL用材料對光的紅、綠、藍三原色的反射率來近似定義材料的顏色。象光源一樣,材料顏色也分成環境、漫反射和鏡面反射成分,它們決定了材料對環境光、漫反射光和鏡面反射光的反射程度。在進行光照計算時,材料對環境光的反射率與每個進入光源的環境光結合,對漫反射光的反射率與每個進入光源的漫反射光結合,對鏡面光的反射率與每個進入光源的鏡面反射光結合。對環境光與漫反射光的反射程度決定了材料的顏色,並且它們很相似。對鏡面反射光的反射率通常是白色或灰色(即對鏡面反射光中紅、綠、藍的反射率相同)。鏡面反射高光最亮的地方將變成具有光源鏡面光強度的顏色。例如一個光亮的紅色塑料球,球的大部分表現為紅色,光亮的高光將是白色的。
在真實世界中,白色物體在綠光照射下看起來是綠色而不是白色,紅色物體在綠光照射下看起來是黑色,而有時同樣顏色的物體在同樣的光照下亮度卻不同,這都是由於物體的材質不同造成的.場景中物體的顏色取決於物體材質的反射和透射屬性.
材質RGB值與光源RGB值的關係
材質的顏色與光源的顏色有些不同。對於光源,R、G、B值等於R、G、B對其最大強度的百分比。若光源顏色的R、G、B值都是1.0,則是最強的白光;若值變為0.5,顏色仍為白色,但強度為原來的一半,於是表現為灰色;
若R=G=1.0,B=0.0,則光源為黃色。對於材質,R、G、B值為材質對光的R、G、B成分的反射率。比如,一種材質的R=1.0、G=0.5、B=0.0,則材質反射全部的紅色成分,一半的綠色成分,不反射藍色成分。也就是說,若OpenGL的光源顏色為(LR、LG、LB),材質顏色為(MR、MG、MB),那麼,在忽略所有其他反射效果的情況下,最終到達眼睛的光的顏色為(LR*MR、LG*MG、LB*MB)。
同樣,如果有兩束光,相應的值分別為(R1、G1、B1)和(R2、G2、B2),則OpenGL將各個顏色成分相加,得到(R1+R2、G1+G2、B1+B2),若任一成分的和值大於1(超出了設備所能顯示的亮度)則約簡到1.0。下麵一常式就說明瞭二者之間的關係。
材質的函數原型為:
public void Material(uint face, uint pname, float[] parameters);
face取值指明材質屬性將應用於物體的哪個面:
GL_FRONT 正面
GL_BACK 背面
GL_FRONT_AND_BACK 雙面
pnam指出要設置的哪種材質屬性,見下麵表:
參數名 |
預設值 |
說明 |
GL_AMBIENT |
(0.2, 0.2, 0.2, 1.0) |
材料的環境光顏色 |
GL_DIFFUSE |
(0.8, 0.8, 0.8, 1.0) |
材料的漫反射光顏色 |
GL_AMBIENT_AND_DIFFUSE |
? |
材料的環境光和漫反射光顏色 |
GL_SPECULAR |
(0.0, 0.0, 0.0, 1.0) |
材料的鏡面反射光顏色 |
GL_SHINESS |
0.0 |
鏡面指數(光亮度) |
GL_EMISSION |
(0.0, 0.0, 0.0, 1.0) |
材料的輻射光顏色 |
GL_COLOR_INDEXES |
(0, 1, 1) |
材料的環境光、漫反射光和鏡面光顏色 |
函數glMaterial*()參數pname的預設值 |
源代碼如下:
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 using SharpGL; 10 11 namespace SharpGLWinformsApplication1 12 { 13 //原創文章,出自"博客園, 豬悟能'S博客" : http://www.cnblogs.com/hackpig/ 14 public partial class SharpGLForm : Form 15 { 16 float[] fLightPosition = new float[4] { 0.0f, 3.0f, 2.0f, 0.0f}; //5f, 8f, -8f, 1f };// 光源位置 17 float[] fLightAmbient = new float[4] { 0f,0f, 0f, 1f };// 環境光參數 18 float[] fLightDiffuse = new float[4] { 1f,1f, 1f, 1f };// 漫射光參數 19 float[] fLightSpecular = new float[4] { 1f, 1f, 1f, 1f }; //鏡面反射 20 21 22 public SharpGLForm() 23 { 24 InitializeComponent(); 25 } 26 27 private void openGLControl_OpenGLDraw(object sender, PaintEventArgs e) 28 { 29 OpenGL gl = openGLControl.OpenGL; 30 gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT); 31 32 draw(gl); 33 } 34 35 36 private void openGLControl_OpenGLInitialized(object sender, EventArgs e) 37 { 38 OpenGL gl = openGLControl.OpenGL; 39 gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_AMBIENT, fLightAmbient);//環境光源 40 gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_DIFFUSE, fLightDiffuse);//漫射光源 41 gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_POSITION, fLightPosition);//光源位置 42 //gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_SPECULAR, fLightSpecular); 43 44 45 gl.ClearColor(0.0f, 0.2f, 0.2f, 0.0f); 46 gl.ClearDepth(1f); 47 gl.DepthFunc(OpenGL.GL_LEQUAL); 48 gl.Enable(OpenGL.GL_DEPTH_TEST); 49 gl.ShadeModel(OpenGL.GL_SMOOTH); 50 51 gl.Enable(OpenGL.GL_LIGHTING);//開啟光照 52 gl.Enable(OpenGL.GL_LIGHT0); 53 gl.Enable(OpenGL.GL_NORMALIZE); 54 } 55 56 private void openGLControl_Resized(object sender, EventArgs e) 57 { 58 OpenGL gl = openGLControl.OpenGL; 59 gl.MatrixMode(OpenGL.GL_PROJECTION); 60 gl.LoadIdentity(); 61 gl.Perspective(45f, (double)Width / (double)Height, 1, 100.0); 62 gl.MatrixMode(OpenGL.GL_MODELVIEW); 63 } 64 65 private void draw(OpenGL Gl) 66 { 67 ///定義材質屬性值 68 float[] no_mat = new float[] { 0.0f, 0.0f, 0.0f, 1.0f }; // 無材質顏色 69 float[] mat_ambient = new float[] { 0.7f, 0.7f, 0.7f, 1.0f }; // 環境顏色 70 float[] mat_ambient_color = new float[] { 0.8f, 0.6f, 0.2f, 1.0f }; 71 float[] mat_diffuse = new float[] { 0.2f, 0.5f, 0.8f, 1.0f }; // 散射顏色 72 float[] mat_specular = new float[] { 1.0f, 1.0f, 1.0f, 1.0f }; // 鏡面反射顏色 73 float[] no_shininess = new float[] { 0.0f }; // 鏡面反射指數為0 74 float[] low_shininess = new float[] { 5.0f }; // 鏡面反射指數為5.0 75 float[] high_shininess = new float[] { 100.0f }; // 鏡面反射指數為100.0 76 float[] mat_emission = new float[] { 0.3f, 0.2f, 0.3f, 0.0f }; // 發射光顏色 77 78 //清除緩存並重置單位矩陣 79 Gl.LoadIdentity(); 80 81 // 第一行第一列繪製的球僅有漫反射光而無環境光和鏡面光。 82 Gl.PushMatrix(); 83 Gl.Translate(-2.0f, 1.5f, -7.0f); 84 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_AMBIENT, no_mat); 85 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_DIFFUSE, mat_diffuse); 86 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SPECULAR, no_mat); 87 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SHININESS, no_shininess); 88 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_EMISSION, no_mat); 89 drawSphere(Gl, 0f, 0f, 0f, 0.5f, 30, 30, false); //(0.3f); 90 Gl.PopMatrix(); 91 92 // 第一行第二列繪製的球有漫反射光和鏡面光,並有低高光,而無環境光 93 Gl.PushMatrix(); 94 Gl.Translate(-0.5f, 1.5f, -7.0f); 95 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_AMBIENT, no_mat); 96 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_DIFFUSE, mat_diffuse); 97 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SPECULAR, mat_specular); 98 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SHININESS, low_shininess); 99 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_EMISSION, no_mat); 100 drawSphere(Gl, 0f, 0f, 0f, 0.5f, 30, 30, false); //(0.3f); 101 Gl.PopMatrix(); 102 103 // 第一行第三列繪製的球有漫反射光和鏡面光,並有很亮的高光,而無環境光 。*/ 104 Gl.PushMatrix(); 105 Gl.Translate(1f, 1.5f, -7.0f); 106 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_AMBIENT, no_mat); 107 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_DIFFUSE, mat_diffuse); 108 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SPECULAR, mat_specular); 109 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SHININESS, high_shininess); 110 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_EMISSION, no_mat); 111 drawSphere(Gl, 0f, 0f, 0f, 0.5f, 30, 30, false); //(0.3f); 112 Gl.PopMatrix(); 113 114 // 第一行第四列繪製的球有漫反射光和輻射光,而無環境和鏡面反射光。*/ 115 Gl.PushMatrix(); 116 Gl.Translate(2.5f, 1.5f, -7.0f); 117 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_AMBIENT, no_mat); 118 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_DIFFUSE, mat_diffuse); 119 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SPECULAR, no_mat); 120 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SHININESS, no_shininess); 121 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_EMISSION, mat_emission); 122 drawSphere(Gl, 0f, 0f, 0f, 0.5f, 30, 30, false); //(0.3f); 123 Gl.PopMatrix(); 124 125 126 127 128 // 第二行第一列繪製的球有漫反射光和環境光,而鏡面反射光。*/ 129 Gl.PushMatrix(); 130 Gl.Translate(-2.0f, 0f, -7.0f); 131 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_AMBIENT, mat_ambient); 132 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_DIFFUSE, mat_diffuse); 133 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SPECULAR, no_mat); 134 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SHININESS, no_shininess); 135 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_EMISSION, no_mat); 136 drawSphere(Gl, 0f, 0f, 0f, 0.5f, 30, 30, false); //(0.3f); 137 Gl.PopMatrix(); 138 139 // 第二行第二列繪製的球有漫反射光、環境光和鏡面光,且有低高光。*/ 140 Gl.PushMatrix(); 141 Gl.Translate(-0.5f, 0f, -7.0f); 142 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_AMBIENT, mat_ambient); 143 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_DIFFUSE, mat_diffuse); 144 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SPECULAR, mat_specular); 145 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SHININESS, low_shininess); 146 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_EMISSION, no_mat); 147 drawSphere(Gl, 0f, 0f, 0f, 0.5f, 30, 30, false); //(0.3f); 148 Gl.PopMatrix(); 149 150 // 第二行第三列繪製的球有漫反射光、環境光和鏡面光,且有很亮的高光。*/ 151 Gl.PushMatrix(); 152 Gl.Translate(1f, 0f, -7.0f); 153 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_AMBIENT, mat_ambient); 154 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_DIFFUSE, mat_diffuse); 155 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SPECULAR, mat_specular); 156 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SHININESS, high_shininess); 157 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_EMISSION, no_mat); 158 drawSphere(Gl, 0f, 0f, 0f, 0.5f, 30, 30, false); //(0.3f); 159 Gl.PopMatrix(); 160 161 // 第二行第四列繪製的球有漫反射光、環境光和輻射光,而無鏡面光。*/ 162 Gl.PushMatrix(); 163 Gl.Translate(2.5f, 0f, -7.0f); 164 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_AMBIENT, mat_ambient); 165 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_DIFFUSE, mat_diffuse); 166 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SPECULAR, no_mat); 167 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SHININESS, no_shininess); 168 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_EMISSION, mat_emission); 169 drawSphere(Gl, 0f, 0f, 0f, 0.5f, 30, 30, false); //(0.3f); 170 Gl.PopMatrix(); 171 172 173 174 175 176 // 第三行第一列繪製的球有漫反射光和有顏色的環境光,而無鏡面光。*/ 177 Gl.PushMatrix(); 178 Gl.Translate(-2.0f, -1.5f, -7.0f); 179 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_AMBIENT, mat_ambient_color); 180 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_DIFFUSE, mat_diffuse); 181 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SPECULAR, no_mat); 182 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SHININESS, no_shininess); 183 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_EMISSION, no_mat); 184 drawSphere(Gl, 0f, 0f, 0f, 0.5f, 30, 30, false); //(0.3f); 185 Gl.PopMatrix(); 186 187 // 第三行第二列繪製的球有漫反射光和有顏色的環境光以及鏡面光,且有低高光。*/ 188 Gl.PushMatrix(); 189 Gl.Translate(-0.5f, -1.5f, -7.0f); 190 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_AMBIENT, mat_ambient_color); 191 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_DIFFUSE, mat_diffuse); 192 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SPECULAR, mat_specular); 193 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SHININESS, low_shininess); 194 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_EMISSION, no_mat); 195 drawSphere(Gl, 0f, 0f, 0f, 0.5f, 30, 30, false); //(0.3f); 196 Gl.PopMatrix(); 197 198 // 第三行第三列繪製的球有漫反射光和有顏色的環境光以及鏡面光,且有很亮的高光。*/ 199 Gl.PushMatrix(); 200 Gl.Translate(1f, -1.5f, -7.0f); 201 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_AMBIENT, mat_ambient_color); 202 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_DIFFUSE, mat_diffuse); 203 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SPECULAR, mat_specular); 204 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SHININESS, high_shininess); 205 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_EMISSION, no_mat); 206 drawSphere(Gl, 0f, 0f, 0f, 0.5f, 30, 30, false); //(0.3f); 207 Gl.PopMatrix(); 208 209 // 第三行第四列繪製的球有漫反射光和有顏色的環境光以及輻射光,而無鏡面光。*/ 210 Gl.PushMatrix(); 211 Gl.Translate(2.5f, -1.5f, -7.0f); 212 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_AMBIENT, mat_ambient_color); 213 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_DIFFUSE, mat_diffuse); 214 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SPECULAR, no_mat); 215 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SHININESS, no_shininess); 216 Gl.Material(OpenGL.GL_FRONT, OpenGL.GL_EMISSION, mat_emission); 217 drawSphere(Gl, 0f, 0f, 0f, 0.5f, 30, 30, false); //(0.3f); 218 Gl.PopMatrix(); 219 220 Gl.Flush(); 221 } 222 223 private void drawBox(OpenGL gl, float xPos, float yPos, float zPos) 224 { 225 gl.PushMatrix(); 226 gl.Translate(xPos, yPos, zPos); 227 228 gl.Begin(OpenGL.GL_QUADS); 229 230 //前 231 gl.TexCoord(0, 0); gl.Vertex(0, 0, 0); 232 gl.TexCoord(1, 0); gl.Vertex(-1, 0, 0); 233 gl.TexCoord(1, 1); gl.Vertex(-1, -1, 0); 234 gl.TexCoord(0, 1); gl.Vertex(0, -1, 0); 235 236 //底 237 gl.TexCoord(0, 0); gl.Vertex(0, 0, 0); 238 gl.TexCoord(1, 0); gl.Vertex(0, 0, -1); 239 gl.TexCoord(1, 1); gl.Vertex(-1, 0, -1); 240 gl.TexCoord(0, 1); gl.Vertex(-1, 0, 0); 241 242 //左 243 gl.TexCoord(0, 0); gl.Vertex(-1, 0, 0); 244 gl.TexCoord(1, 0); gl.Vertex(-1, 0, -1); 245 gl.TexCoord(1, 1); gl.Vertex(-1, -1, -1); 246 gl.TexCoord(0, 1); gl.Vertex(-1, -1, 0); 247 248 //右 249 gl.TexCoord(0, 0); gl.Vertex(0, 0, 0); 250 gl.TexCoord(1, 0); gl.Vertex(0, 0, -1); 251 gl.TexCoord(1, 1); gl.Vertex(0, -1, -1); 252 gl.TexCoord(0, 1); gl.Vertex(0, -1, 0); 253 254 //後 255 gl.TexCoord(0, 0); gl.Vertex(0, 0, -1); 256 gl.TexCoord(1, 0); gl.Vertex(-1, 0, -1); 257 gl.TexCoord(1, 1); gl.Vertex(-1, -1, -1); 258 gl.TexCoord(0, 1); gl.Vertex(0, -1, -1); 259 260 //頂 261 gl.TexCoord(0, 0); gl.Vertex(0, -1, 0); 262 gl.TexCoord(1, 0); gl.Vertex(0, -1, -1); 263 gl.TexCoord(1, 1); gl.Vertex(-1, -1, -1); 264 gl.TexCoord(0, 1); gl.Vertex(-1, -1, 0); 265 266 267 gl.End(); 268 gl.PopMatrix(); 269 270 } 271 272 void drawSphere(OpenGL gl,float x,float y,float z, double radius, int segx, int segy, bool isLines) 273 { 274 gl.PushMatrix(); 275 gl.Translate(x, y, z); 276 var sphere = gl.NewQuadric(); 277 278 if (isLines) 279 gl.QuadricDrawStyle(sphere, OpenGL.GL_LINES); 280 else 281 gl.QuadricDrawStyle(sphere, OpenGL.GL_QUADS); 282 gl.QuadricNormals(sphere, OpenGL.GLU_SMOOTH); 283 gl.QuadricOrientation(sphere, (int)OpenGL.GLU_OUTSIDE); 284 gl.QuadricTexture(sphere, (int)OpenGL.GL_FALSE); 285 gl.Sphere(sphere, radius, segx, segy); 286 gl.DeleteQuadric(sphere); 287 gl.PopMatrix(); 288 } 289 290 void drawSphere1(OpenGL gl, float xx, float yy, float zz, float radius, float M, float N, bool isLines) 291 { 292 const float PI = 3.1415926f; 293 float step_z = (float)Math.PI / M; 294 float step_xy = 2 * PI / N; 295 float[] x = new float[4] { 0, 0, 0, 0 }; 296 float[] y = new float[4] { 0, 0, 0, 0 }; 297 float[] z = new float[4] { 0, 0, 0, 0 }; 298 299 float angle_z = 0.0f; 300 float angle_xy = 0.0f; 301 int i = 0, j = 0; 302 gl.Begin(OpenGL.GL_QUADS); 303 304 for (i = 0; i < M; i++) 305 { 306 angle_z = i * step_z; 307 for (j = 0; j < N; j++) 308 { 309 angle_xy = j * step_xy; 310 311 x[0] = (float)(radius * Math.Sin(angle_z) * Math.Cos(angle_xy)); 312 y[0] = (float)(radius * Math.Sin(angle_z) * Math.Sin(angle_xy)); 313 z[0] = (float)(radius * Math.Cos(angle_z)); 314 315 x[1] = (float)(radius * Math.Sin(angle_z + step_z) * Math.Cos(angle_xy)); 316 y[1] = (float)(radius * Math.Sin(angle_z + step_z) * Math.Sin(angle_xy)); 317 z[1] = (float)(radius * Math.Cos(angle_z + step_z)); 318 319 x[2] = (float)(radius * Math.Sin(angle_z + step_z) * Math.Cos(angle_xy + step_xy)); 320 y[2] = (float)(radius * Math.Sin(angle_z + step_z) * Math.Sin(angle_xy + step_xy)); 321 z[2] = (float)(radius * Math.Cos(angle_z + step_z)); 322 323 x[3] = (float)(radius * Math.Sin(angle_z) * Math.Cos(angle_xy + step_xy)); 324 y[3] = (float)(radius * Math.Sin(angle_z) * Math.Sin(angle_xy + step_xy)); 325 z[3] = (float)(radius * Math.Cos(angle_z)); 326 327 for (int k = 0; k < 4; k++) 328 { 329 gl.Normal(-1, -1, -1); 330 gl.Vertex(xx + x[k], yy + y[k], zz + z[k]); 331 } 332 } 333 } 334 gl.End(); 335 } 336 337 } 338 }