1. 程式人生 > >【OpenGL】openGL學習筆記

【OpenGL】openGL學習筆記

函式1:glutInitDisplayMode(unsigned int mode)--------設定初始顯示模式

mode引數設定

#鍵盤控制

函式2:void glutKeyboardFunc(void(*func)(unsigned char key,int x,int y));
引數:
func: 處理普通按鍵訊息的函式的名稱。如果傳遞NULL,則表示GLUT忽略普通按鍵訊息。
這個作為glutKeyboardFunc函式引數的函式需要有三個形參。第一個表示按下的鍵的ASCII碼,其餘兩個提供了,當鍵按下時當前的滑鼠位置。滑鼠位置是相對於當前客戶視窗的左上角而言的。 

一些時候我們想知道要是一個組合鍵(modifier key)也就是CTRL,ALT或者SHIFT被按下該如何處理。GLUT提供了一個函式來檢測是否有組合鍵被按下。這個函式僅僅只能在處理按鍵訊息或者滑鼠訊息函式裡被呼叫。函式原型如下:
int glutGetModifiers(void);
這個函式的返回值是三個glut.h裡預定義的常量裡的一個,或它們的或組合。這三個常量是:
1:GLUT_ACTIVE_SHIFT: 返回它,當按下SHIFT鍵或按下CAPS LOCK,注意兩者同時按下時,不會返回這個值。
2:GLUT_ACTIVE_CTRL: 返回它,當按下CTRL鍵。
3:GLUT_ACTIVE_ATL:返回它,當按下ATL鍵。
注意,視窗系統可能會擷取一些組合鍵(modifiers),這是就沒有回調發生。現在讓我們擴充processNormalKeys,處理組合鍵。按下r鍵時red變數被設定為0.0,當按下ATL+r時red被設定為1.0。程式碼如下:
void processNormalKeys(unsigned char key, int x, int y) {
 
         if (key == 27) 
                 exit(0);
         else if (key=='r') {
                 int mod = glutGetModifiers();
                 if (mod == GLUT_ACTIVE_ALT)
                          red = 0.0;
                 else
                          red = 1.0;
         }
}
注意如果我們按下R鍵,將不會有什麼發生,因為R與r鍵的ASCII碼不同。即這是兩個不同的鍵。最後就是如何檢測按鍵CTRL+ALT+F1?。這種情況下,我們必須同時檢測兩個組合鍵,為了完成操作我們需要使用或操作符。下面的程式碼段,使你按下CTRL+ALT+F1時顏色改變為紅色。
void processSpecialKeys(int key, int x, int y) {
 
         int mod;
         switch(key) {
                 case GLUT_KEY_F1 : 
                    mod = glutGetModifiers();
                    if (mod == (GLUT_ACTIVE_CTRL|GLUT_ACTIVE_ALT)) {
                          red = 1.0; green = 0.0; blue = 0.0;
                    }
                    break;
                 case GLUT_KEY_F2 : 
                    red = 0.0; 
                    green = 1.0; 
                    blue = 0.0; break;
                 case GLUT_KEY_F3 : 
                    red = 0.0; 
                    green = 0.0; 
                    blue = 1.0; break;
         }
}

#openGL處理光照時

OpenGL在處理光照時把光照系統分為三部分,分別是光源、材質和光照模型。

光源、材質和光照模式都有各自的屬性,儘管屬性種類繁多,但這些屬性都只用很少的幾個函式來設定。

使用glLight*函式可設定光源的屬性,

使用glMaterial*函式可設定材質的屬性,

使用glLightModel*函式可設定光照模式。

1.啟用光源。使用GL_LIGHT0表示第0號光源,GL_LIGHT1表示第1號光源,依次類推,OpenGL至少會支援8個光源,即GL_LIGHT0到GL_LIGHT7。使用glEnable函式可以開啟它們。例如,glEnable(GL_LIGHT0);可以開啟第0號光源。使用glDisable函式則可以關閉光源。一些OpenGL實現可能支援更多數量的光源,但總的來說,開啟過多的光源將會導致程式執行速度的嚴重下降,

光源GL_LIGHT0與其他幾個光源不同,

GL_DIFFUSE,GL_SPECULAR的預設值是(1.0,1.0,1.0,1.0)

而其他光源的預設值是              (0.0,0.0,0.0,1.0)

2.光源設定

設定環境光

glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight);

設定漫射光成分

glLightfv(GL_LIGHT0,GL_DIFFUSE,DiffuseLight)

設定鏡面光成分

glLightfv(GL_LIGHT0,GL_SPECULAR,SpecularLight);

光源的屬性GL_SPECULAR影響鏡面反射區域的顏色,一般物體的鏡面反射區域的顏色為入射光線的顏色,要實現真實感,應該將它的值設定成與GL_DIFFUSE相同。

設定光源的位置

glLightfv(GL_LIGHT0, GL_POSITION, sun_light_position);

GL_POSITION屬性。表示光源所在的位置。由四個值(X, Y, Z, W)表示。

方向性光源    第四個值W為零,則表示該光源位於無限遠處,前三個值表示了它所在的方向。通常,太陽可以近似的被認為是方向性光源。

位置性光源    第四個值W不為零,則X/W, Y/W, Z/W表示了光源的位置。這種光源稱為位置性光源。

定位光源需要對其發射的光進行衰減,可以設定各種衰減因子。環境光,散射光和鏡面反射光的貢獻都是衰減的,只有發射光和全域性環境光不會衰減。對於,設定其位置與設定多邊形頂點的方式相似,各種矩陣變換函式例如:glTranslate*、glRotate*等在這裡也同樣有效。方向性光源在計算時比位置性光源快了不少,

因此,在視覺效果允許的情況下,應該儘可能的使用  方向性  光源。

下面定義了一個位置在(1,1,1),沒有環境光,鏡面反射光和漫反射光都為白光的光源

GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };

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_POSITION, light_position);

glLightfv(GL_LIGHT0, GL_AMBIENT , light_ambient );

glLightfv(GL_LIGHT0, GL_DIFFUSE , light_diffuse );

glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);

建立聚光燈(這些屬性只對位置性光源有效)

glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,LightCutOff);

GL_SPOT_DIRECTION、GL_SPOT_EXPONENT、GL_SPOT_CUTOFF屬性。

表示將光源作為聚光燈使用。很多光源都是向四面八方發射光線,但有時候一些光源則是隻向某個方向發射,比如手電筒,只向一個較小的角度發射光線。

GL_SPOT_DIRECTION 屬性有三個值,表示一個向量,即光源發射的方向。光源的預設方向是(0.0,0.0,-1.0),即指向z軸負方向

GL_SPOT_EXPONENT  屬性只有一個值,表示聚光的程度,為零時表示光照範圍內向各方向發射的光線強度相同,為正數時表示光照向中央集中,正對發射方向的位置受到更多光照,其它位置受到較少光照。數值越大,聚光效果就越明顯。

GL_SPOT_CUTOFF     屬性也只有一個值,表示一個角度,它是光源發射光線所覆蓋角度的一半,其取值範圍在0到90之間,也可以取180這個特殊值。取值為180時表示光源發射光線覆蓋360度,即不使用聚光燈,向全周圍發射。即一個點光源。

3.材質屬性

設定材質對各種光的反光率

    呼叫:glMaterialfv(GL_FRONT,GL_DIFFUSE,@Diffuse);

可以指定材質對漫射光的反射率。其中,第一個引數決定該材質運用於圖元的正面還是反面。可以取GL_FRONT(正面),GL_BACK(反面),GL_FRONT_AND_BACK(正反兩面)。第2個值表示對何種光進行設定,GL_DIFFUSE表示對漫射光反射率進行設定,可以取GL_AMBIENT(環境光)、GL_DIFFUSE(漫射光)、GL_AMBIENT_AND_DIFFUSE(環境光和漫射光)、GL_SPECULAR(平行/鏡面光)。而第三個引數是一個四維陣列,這個陣列描述了反光率的RGBA值,每一項取值都為0-1之間。例如

Diffuse[4]={1,0,0,1};

glMaterialfv(GL_FRONT,GL_DIFFUSE,Diffuse);   將會使物體在有紅色成分的光照下表現為紅色。