OpenGL材質和光照(轉)
真實感圖形繪製是計算機圖形學的一個重要組成部分,它綜合利用數學、物理學、電腦科學和其它科學知識在計算機圖形裝置上生成象彩色照片那樣的具有真實感的圖形。一般說來,用計算機在圖形裝置上生成真實感圖形必須完成以下四個步驟:一是用建模,即用一定的數學方法建立所需三維場景的幾何描述,場景的幾何描述直接影響圖形的複雜性和圖形繪製的計算耗費;二是將三維幾何模型經過一定變換轉為二維平面透視投影圖;三是確定場景中所有可見面,運用隱藏面消隱演算法將視域外或被遮擋住的不可見面消去;四是計算場景中可見面的顏色,即根據基於光學物理的光照模型計算可見面投射到觀察者眼中的光亮度大小和顏色分量,並將它轉換成適合圖形裝置的顏色值,從而確定投影畫面上每一象素的顏色,最終生成圖形。
<!--[if gte vml 1]> <![endif]--> |
圖10-1 帶光影的灰色球體 |
10.2.2 OpenGL光組成 在OpenGL簡單光照模型中的幾種光分為:輻射光(Emitted Light)、環境光(Ambient Light)、漫射光(Diffuse Light)、鏡面光(Specular Light)。 輻射光是最簡單的一種光,它直接從物體發出並且不受任何光源影響。 環境光是由光源發出經環境多次散射而無法確定其方向的光,即似乎來自所有方向。一般說來,房間裡的環境光成分要多些,戶外的相反要少得多,因為大部分光按相同方向照射,而且在戶外很少有其他物體反射的光。當環境光照到曲面上時,它在各個方向上均等地發散(類似於無影燈光)。 漫射光來自一個方向,它垂直於物體時比傾斜時更明亮。一旦它照射到物體上,則在各個方向上均勻地發散出去。於是,無論視點在哪裡它都一樣亮。來自特定位置和特定方向的任何光,都可能有散射成分。 鏡面光來自特定方向並沿另一方向反射出去,一個平行鐳射束在高質量的鏡面上產生100%的鏡面反射。光亮的金屬和塑料具有很高非反射成分,而象粉筆和地毯等幾乎沒有反射成分。因此,三某種意義上講,物體的反射程度等同於其上的光強(或光亮度)。10.2.3 建立光源(Light Source) 光源有許多特性,如顏色、位置、方向等。選擇不同的特性值,則對應的光源作用在物體上的效果也不一樣,這在以後的章節中會逐步介紹的。下面詳細講述定義光源特性的函式glLight*():void glLight{if}[v](GLenum light , GLenumpname, TYPE param) 建立具有某種特性的光源。其中第一個引數light指定所建立的光源號,如GL_LIGHT0、GL_LIGHT1、...、GL_LIGHT7。第二個引數pname指定光源特性,這個引數的輔助資訊見表10-1所示。最後一個引數設定相應的光源特性值。
pname 引數名 |
預設值 |
說明 |
GL_AMBIENT |
(0.0, 0.0, 0.0, 1.0) |
RGBA模式下環境光 |
GL_DIFFUSE |
(1.0, 1.0, 1.0, 1.0) |
RGBA模式下漫反射光 |
GL_SPECULAR |
(1.0,1.0,1.0,1.0) |
RGBA模式下鏡面光 |
GL_POSITION |
(0.0,0.0,1.0,0.0) |
光源位置齊次座標(x,y,z,w) |
GL_SPOT_DIRECTION |
(0.0,0.0,-1.0) |
點光源聚光方向向量(x,y,z) |
GL_SPOT_EXPONENT |
0.0 |
點光源聚光指數 |
GL_SPOT_CUTOFF |
180.0 |
點光源聚光截止角 |
GL_CONSTANT_ATTENUATION |
1.0 |
常數衰減因子 |
GL_LINER_ATTENUATION |
0.0 |
線性衰減因子 |
GL_QUADRATIC_ATTENUATION |
0.0 |
平方衰減因子 |
表10-1 函式glLight*()引數pname說明 |
?注意:以上列出的GL_DIFFUSE和GL_SPECULAR的預設值只能用於GL_LIGHT0,其他幾個光源的GL_DIFFUSE和GL_SPECULAR預設值為(0.0,0.0,0.0,1.0)。另外,表中後六個引數的應用放在下一篇中介紹。在上面例程中,光源的建立為:GLfloat light_position[] = { 1.0, 1.0, 1.0,0.0 };glLightfv(GL_LIGHT0, GL_POSITION,light_position); 其中light_position是一個指標,指向定義的光源位置齊次座標陣列。其它幾個光源特性都為預設值。同樣,我們也可用類似的方式定義光源的其他幾個特性值,例如:GLfloat light_ambient [] = { 0.0, 0.0, 0.0,1.0 };GLfloat light_diffuse [] = { 1.0, 1.0, 1.0,1.0 };GLfloat light_specular[] = { 1.0, 1.0, 1.0,1.0 };glLightfv(GL_LIGHT0, GL_AMBIENT ,light_ambient );glLightfv(GL_LIGHT0, GL_DIFFUSE ,light_diffuse );glLightfv(GL_LIGHT0, GL_SPECULAR,light_specular);10.2.4 啟動光照 在OpenGL中,必須明確指出光照是否有效或無效。如果光照無效,則只是簡單地將當前顏色對映到當前頂點上去,不進行法向、光源、材質等複雜計算,那麼顯示的圖形就沒有真實感,如前幾章例程執行結果顯示。要使光照有效,首先得啟動光照,即:glEnable(GL_LIGHTING); 若使光照無效,則呼叫gDisable(GL_LIGHTING)可關閉當前光照。然後,必須使所定義的每個光源有效,例light0.c中只用了一個光源,即:glEnable(GL_LIGHT0); 其它光源類似,只是光源號不同而已。10.3、明暗處理 在計算機圖形學中,光滑的曲面表面常用多邊形予以逼近和表示,而每個小多邊形輪廓(或內部)就用單一的顏色或許多不同的顏色來勾畫(或填充),這種處理方式就稱為明暗處理。在OpenGL中,用單一顏色處理的稱為平面明暗處理(Flat Shading),用許多不同顏色處理的稱為光滑明暗處理(Smooth Shading),也稱為Gourand明暗處理(Gourand Shading)。設定明暗處理模式的函式為:void glShadeModel(GLenum mode); 函式引數為GL_FLAT或GL_SMOOTH,分別表示平面明暗處理和光滑明暗處理。 應用平面明暗處理模式時,多邊形內每個點的法向一致,且顏色也一致;應用光滑明暗處理模式時,多邊形所有點的法向是由內插生成的,具有一定的連續性,因此每個點的顏色也相應內插,故呈現不同色。這種模式下,插值方法採用的是雙線性插值法,如圖10-2所示。
<!--[if gte vml 1]> <![endif]--> |
圖10-2 Gouraud明暗處理 |
Gouraud明暗處理通常演算法為:先用多邊形頂點的光強線性插值出當前掃描線與多邊形邊交點處的光強,然後再用交點的光強線插值處掃描線位於多邊形內區段上每一象素處的光強值。圖中顯示出一條掃描線與多邊形相交,交線的端點是A點和B點,P點是掃描線上位於多邊形內的任一點,多邊形三個頂點的光強分別為I1、I2和I3.取A點的光強Ia為I1和I2的線性插值,B點的光強Ib為I1和I3的線性插值,P點的光強Ip則為Ia和Ib的線性插值。採用Gouraud明暗處理不但可以使用多邊形表示的曲面光強連續,而且計算量很小。這種演算法還可以以增量的形式改進,且能用硬體直接實現演算法,從而廣泛用於計算機實時圖形生成。請看下面光滑明暗處理的例程: 例10-2 明暗處理例程(Shading.c)#include "glos.h"#include <GL/gl.h>#include <GL/glu.h>#include <GL/glaux.h>void myinit(void);void object(void);void CALLBACK display(void);void CALLBACK myReshape(GLsizei w, GLsizeih);/* GL_SMOOTH is actually the defaultshading model. */void myinit (void){glShadeModel (GL_SMOOTH);}void object(void){glBegin (GL_POLYGON);glColor3f (1.0, 0.0, 0.0);glVertex2f (4.0, 4.0);glColor3f(1.0,1.0,1.0);glVertex2f (12.0, 4.0);glColor3f(0.0,0.0,1.0);glVertex2f (12.0, 12.0);glColor3f(0.0,1.0,0.0);glVertex2f (4.0, 12.0);glEnd ();}void CALLBACK display(void){glClear (GL_COLOR_BUFFER_BIT);object ();glFlush ();}void CALLBACK myReshape(GLsizei w, GLsizeih){glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();if (w <= h)gluOrtho2D (0.0, 16.0, 0.0, 16.0 *(GLfloat) h/(GLfloat) w);elsegluOrtho2D (0.0, 16.0 * (GLfloat)w/(GLfloat) h, 0.0, 16.0);glMatrixMode(GL_MODELVIEW);}void main(void){auxInitDisplayMode (AUX_SINGLE | AUX_RGBA);auxInitPosition (0, 0, 500, 500);auxInitWindow ("Smooth Shading");myinit();auxReshapeFunc (myReshape);auxMainLoop(display);} 以上程式執行結果是在螢幕上顯示一個色彩連續變化的三角形。這個程式是用的RGBA顯示模式,若改用顏色表模式,則顏色內插實際上是顏色表的內插,因此呈現的顏色可能不連續。網友不妨自己試試。 另外,若在light0.c程式中加上一句定義GL_FLAT明暗處理模式,則又會出現怎樣的情形呢?讀者可以仔細比較一下。
<!--[if gte vml 1]> <![endif]--> |
圖10-3 高氏明暗處理的正方形 |
10.4、材質10.4.1 材質顏色OpenGL用材料對光的紅、綠、藍三原色的反射率來近似定義材料的顏色。象光源一樣,材料顏色也分成環境、漫反射和鏡面反射成分,它們決定了材料對環境光、漫反射光和鏡面反射光的反射程度。在進行光照計算時,材料對環境光的反射率與每個進入光源的環境光結合,對漫反射光的反射率與每個進入光源的漫反射光結合,對鏡面光的反射率與每個進入光源的鏡面反射光結合。對環境光與漫反射光的反射程度決定了材料的顏色,並且它們很相似。對鏡面反射光的反射率通常是白色或灰色(即對鏡面反射光中紅、綠、藍的反射率相同)。鏡面反射高光最亮的地方將變成具有光源鏡面光強度的顏色。例如一個光亮的紅色塑料球,球的大部分表現為紅色,光亮的高光將是白色的。10.4.2 材質定義 材質的定義與光源的定義類似。其函式為:void glMaterial{if}[v](GLenum face,GLenumpname,TYPE param); 定義光照計算中用到的當前材質。face可以是GL_FRONT、GL_BACK、GL_FRONT_AND_BACK,它表明當前材質應該應用到物體的哪一個面上;pname說明一個特定的材質;param是材質的具體數值,若函式為向量形式,則param是一組值的指標,反之為引數值本身。非向量形式僅用於設定GL_SHINESS。pname引數值具體內容見表10-1。另外,引數GL_AMBIENT_AND_DIFFUSE表示可以用相同的RGB值設定環境光顏色和漫反射光顏色。
引數名 |
預設值 |
說明 |
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) |
材料的環境光、漫反射光和鏡面光顏色 |
表10-2 函式glMaterial*()引數pname的預設值 |
例10-3 材質定義例程(light1.c)#include "glos.h"#include <GL/gl.h>#include <GL/glaux.h>void myinit(void);void CALLBACK myReshape(GLsizei w, GLsizeih);void CALLBACK display(void); voidmyinit(void){/* 設定材質的各種光的顏色成分反射比率 */GLfloat mat_ambient[]={0.8,0.8,0.8,1.0};GLfloat mat_diffuse[]={0.8,0.0,0.8,1.0};/* 紫色 */GLfloat mat_specular[] = { 1.0, 0.0, 1.0,1.0 };/* 亮紫色 */GLfloat mat_shininess[] = { 50.0 };GLfloat light_position[] = { 1.0, 1.0, 1.0,0.0 };glMaterialfv(GL_FRONT, GL_AMBIENT,mat_ambient);glMaterialfv(GL_FRONT, GL_DIFFUSE,mat_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR,mat_specular);glMaterialfv(GL_FRONT, GL_SHININESS,mat_shininess);glLightfv(GL_LIGHT0, GL_POSITION,light_position);glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);glDepthFunc(GL_LESS);glEnable(GL_DEPTH_TEST);}void CALLBACK display(void){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);auxSolidSphere(1.0);glFlush();}void CALLBACK myReshape(GLsizei w, GLsizeih){glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();if (w <= h)glOrtho (-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w,1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);elseglOrtho (-1.5*(GLfloat)w/(GLfloat)h,1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);glMatrixMode(GL_MODELVIEW);?glLoadIdentity();}void main(void){auxInitDisplayMode (AUX_SINGLE | AUX_RGBA |AUX_DEPTH16);auxInitPosition (0, 0, 500, 500);auxInitWindow ("Lighting_1 ");myinit();auxReshapeFunc (myReshape);auxMainLoop(display);} 以上程式執行結果是一個紫色的球。在函式myinit()中定義了球的材質顏色,光源的定義仍延用light0.c中的,而light.c物體的光源定義為預設形式。從例子中明顯地看出,物體的材質顏色定義與光源顏色定義幾乎一樣,物體反射到眼中的顏色與二者都有關係,具體關係請看下一小節。10.4.3 材質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。下面一例程就說明了二者之間的關係。 例10-4 材質與光源的RGB關係例程(light2.c)#include "glos.h"#include <GL/gl.h>#include <GL/glaux.h>void myinit(void);void CALLBACK myReshape(GLsizei w, GLsizeih);void CALLBACK display(void);void myinit(void){GLfloat mat_ambient[]= { 0.8, 0.8, 0.8, 1.0};GLfloat mat_diffuse[]= { 0.8, 0.0, 0.8, 1.0};/* 紫色 */GLfloat mat_specular[] = { 1.0, 0.0, 1.0,1.0 };GLfloat mat_shininess[] = { 50.0 };GLfloat light_diffuse[]= { 0.0, 0.0, 1.0,1.0};/* 藍色 */GLfloat light_position[] = { 1.0, 1.0, 1.0,0.0 };glMaterialfv(GL_FRONT, GL_AMBIENT,mat_ambient);glMaterialfv(GL_FRONT, GL_DIFFUSE,mat_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR,mat_specular);glMaterialfv(GL_FRONT, GL_SHININESS,mat_shininess);glLightfv(GL_LIGHT0, GL_DIFFUSE,light_diffuse);glLightfv(GL_LIGHT0, GL_POSITION,light_position);glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);glDepthFunc(GL_LESS);glEnable(GL_DEPTH_TEST);}void CALLBACK display(void){glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);auxSolidSphere(1.0);glFlush();}void CALLBACK myReshape(GLsizei w, GLsizeih){glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();if (w <= h)glOrtho (-1.5, 1.5,-1.5*(GLfloat)h/(GLfloat)w, 1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);elseglOrtho (-1.5*(GLfloat)w/(GLfloat)h,1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();}void main(void){auxInitDisplayMode (AUX_SINGLE | AUX_RGBA |AUX_DEPTH16);auxInitPosition (0, 0, 500, 500);auxInitWindow ("Lighting_2 ");myinit();auxReshapeFunc (myReshape);auxMainLoop(display);} 以上程式執行結果是一個藍色的球,其中高光部分仍為上一例的亮紫色。從上可看出,球漫反射光的結果是mat_diffuse[]與light_diffuse[]中的三個顏色分量值相乘,即(0.0*1.0,0.0*1.0,0.8*1.0,1.0*1.0)=(0.0,0.0,0.8,1.0),所以球大部分呈現藍色。
<!--[if gte vml 1]> <![endif]--> |
圖10-4 光照藍色球(高光為紅色) |
10.4.4 材質改變 在實際應用的許多情況下,不同的物體或同一物體的不同部分都有可能設定不同的材質,OpenGL函式庫提供了兩種方式實現這種要求。下面一例程採用的是設定矩陣堆疊來儲存不同物體的材質資訊: 例10-5 矩陣堆疊改變材質例程(chgmat1.c)#include "glos.h"#include <GL/gl.h>#include <GL/glu.h>#include <GL/glaux.h>void myinit(void);void CALLBACK display(void);void CALLBACK myReshape(GLsizei w, GLsizeih);/* 初始化z-buffer、光源和光照模型,在此不具體定義材質。*/void myinit(void){GLfloat ambient[] = { 0.0, 0.0, 0.0, 1.0 };GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 };GLfloat specular[] = { 1.0, 1.0, 1.0, 1.0};GLfloat position[] = { 0.0, 3.0, 2.0, 0.0};GLfloat lmodel_ambient[] = { 0.4, 0.4, 0.4,1.0 };glEnable(GL_DEPTH_TEST);glDepthFunc(GL_LESS);glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);glLightfv(GL_LIGHT0, GL_POSITION,position);glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);glClearColor(0.0, 0.1, 0.1, 0.0);}void CALLBACK display(void){GLfloat no_mat[] = { 0.0, 0.0, 0.0, 1.0 };GLfloat mat_ambient[] = { 0.7, 0.7, 0.7,1.0 };GLfloat mat_ambient_color[] = { 0.8, 0.8,0.2, 1.0 };GLfloat mat_diffuse[] = { 0.1, 0.5, 0.8,1.0 };GLfloat mat_specular[] = { 1.0, 1.0, 1.0,1.0 };GLfloat no_shininess[] = { 0.0 };GLfloat low_shininess[] = { 5.0 };GLfloat high_shininess[] = { 100.0 };GLfloat mat_emission[] = {0.3, 0.2, 0.2,0.0};glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);/* 第一行第一列繪製的球僅有漫反射光而無環境光和鏡面光。*/glPushMatrix();glTranslatef (-3.75, 3.0, 0.0);glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);glMaterialfv(GL_FRONT, GL_DIFFUSE,mat_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR,no_mat);glMaterialfv(GL_FRONT, GL_SHININESS,no_shininess);glMaterialfv(GL_FRONT, GL_EMISSION,no_mat);auxSolidSphere(1.0);glPopMatrix();/* 第一行第二列繪製的球有漫反射光和鏡面光,並有低高光,而無環境光。*/glPushMatrix();glTranslatef (-1.25, 3.0, 0.0);glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);glMaterialfv(GL_FRONT, GL_DIFFUSE,mat_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR,mat_specular);glMaterialfv(GL_FRONT, GL_SHININESS,low_shininess);glMaterialfv(GL_FRONT, GL_EMISSION,no_mat);auxSolidSphere(1.0);glPopMatrix();/* 第一行第三列繪製的球有漫反射光和鏡面光,並有很亮的高光,而無環境光。*/glPushMatrix();glTranslatef (1.25, 3.0, 0.0);glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);glMaterialfv(GL_FRONT, GL_DIFFUSE,mat_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR,mat_specular);glMaterialfv(GL_FRONT, GL_SHININESS,high_shininess);glMaterialfv(GL_FRONT, GL_EMISSION,no_mat);auxSolidSphere(1.0);glPopMatrix();/* 第一行第四列繪製的球有漫反射光和輻射光,而無環境和鏡面反射光。*/glPushMatrix();glTranslatef (3.75, 3.0, 0.0);glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);glMaterialfv(GL_FRONT, GL_DIFFUSE,mat_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR,no_mat);glMaterialfv(GL_FRONT, GL_SHININESS,no_shininess);glMaterialfv(GL_FRONT, GL_EMISSION,mat_emission);auxSolidSphere(1.0);glPopMatrix();/* 第二行第一列繪製的球有漫反射光和環境光,而鏡面反射光。*/glPushMatrix();glTranslatef (-3.75, 0.0, 0.0);glMaterialfv(GL_FRONT, GL_AMBIENT,mat_ambient);glMaterialfv(GL_FRONT, GL_DIFFUSE,mat_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR,no_mat);glMaterialfv(GL_FRONT, GL_SHININESS,no_shininess);glMaterialfv(GL_FRONT, GL_EMISSION,no_mat);auxSolidSphere(1.0);glPopMatrix();/* 第二行第二列繪製的球有漫反射光、環境光和鏡面光,且有低高光。*/glPushMatrix();glTranslatef (-1.25, 0.0, 0.0);glMaterialfv(GL_FRONT, GL_AMBIENT,mat_ambient);glMaterialfv(GL_FRONT, GL_DIFFUSE,mat_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR,mat_specular);glMaterialfv(GL_FRONT, GL_SHININESS,low_shininess);glMaterialfv(GL_FRONT, GL_EMISSION,no_mat);auxSolidSphere(1.0);glPopMatrix();/* 第二行第三列繪製的球有漫反射光、環境光和鏡面光,且有很亮的高光。*/glPushMatrix();glTranslatef (1.25, 0.0, 0.0);glMaterialfv(GL_FRONT, GL_AMBIENT,mat_ambient);glMaterialfv(GL_FRONT, GL_DIFFUSE,mat_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR,mat_specular);glMaterialfv(GL_FRONT, GL_SHININESS,high_shininess);glMaterialfv(GL_FRONT, GL_EMISSION,no_mat);auxSolidSphere(1.0);glPopMatrix();/* 第二行第四列繪製的球有漫反射光、環境光和輻射光,而無鏡面光。*/glPushMatrix();glTranslatef (3.75, 0.0, 0.0);glMaterialfv(GL_FRONT, GL_AMBIENT,mat_ambient);glMaterialfv(GL_FRONT, GL_DIFFUSE,mat_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR,no_mat);glMaterialfv(GL_FRONT, GL_SHININESS,no_shininess);glMaterialfv(GL_FRONT, GL_EMISSION,mat_emission);auxSolidSphere(1.0); glPopMatrix();/* 第三行第一列繪製的球有漫反射光和有顏色的環境光,而無鏡面光。*/glPushMatrix();glTranslatef (-3.75, -3.0, 0.0);glMaterialfv(GL_FRONT, GL_AMBIENT,mat_ambient_color);glMaterialfv(GL_FRONT, GL_DIFFUSE,mat_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR,no_mat);glMaterialfv(GL_FRONT, GL_SHININESS,no_shininess);glMaterialfv(GL_FRONT, GL_EMISSION,no_mat);auxSolidSphere(1.0);glPopMatrix();/* 第三行第二列繪製的球有漫反射光和有顏色的環境光以及鏡面光,且有低高光。*/glPushMatrix();glTranslatef (-1.25, -3.0, 0.0);glMaterialfv(GL_FRONT, GL_AMBIENT,mat_ambient_color);glMaterialfv(GL_FRONT, GL_DIFFUSE,mat_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR,mat_specular);glMaterialfv(GL_FRONT, GL_SHININESS,low_shininess);glMaterialfv(GL_FRONT, GL_EMISSION,no_mat);auxSolidSphere(1.0);glPopMatrix();/* 第三行第三列繪製的球有漫反射光和有顏色的環境光以及鏡面光,且有很亮的高光。*/glPushMatrix();glTranslatef (1.25, -3.0, 0.0);glMaterialfv(GL_FRONT, GL_AMBIENT,mat_ambient_color);glMaterialfv(GL_FRONT, GL_DIFFUSE,mat_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR,mat_specular);glMaterialfv(GL_FRONT, GL_SHININESS,high_shininess);glMaterialfv(GL_FRONT, GL_EMISSION,no_mat);auxSolidSphere(1.0);glPopMatrix();/* 第三行第四列繪製的球有漫反射光和有顏色的環境光以及輻射光,而無鏡面光。*/glPushMatrix();glTranslatef (3.75, -3.0, 0.0);glMaterialfv(GL_FRONT, GL_AMBIENT,mat_ambient_color);glMaterialfv(GL_FRONT, GL_DIFFUSE,mat_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR,no_mat);glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);glMaterialfv(GL_FRONT, GL_EMISSION,mat_emission);auxSolidSphere(1.0);glPopMatrix();glFlush();}void CALLBACK myReshape(GLsizei w, GLsizeih){glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();if (w <= (h * 2))glOrtho (-6.0, 6.0,-3.0*((GLfloat)h*2)/(GLfloat)w,3.0*((GLfloat)h*2)/(GLfloat)w, -10.0,10.0);elseglOrtho (-6.0*(GLfloat)w/((GLfloat)h*2),6.0*(GLfloat)w/((GLfloat)h*2), -3.0, 3.0,-10.0, 10.0);glMatrixMode(GL_MODELVIEW);}void main(void){auxInitDisplayMode (AUX_SINGLE | AUX_RGBA);auxInitPosition (0, 0, 600, 450);auxInitWindow ("Material");myinit();auxReshapeFunc (myReshape);auxMainLoop(display);}
|