OpenGL系統設計 霧與混合 (1)

2021-05-10 19:18:49 字數 3049 閱讀 3213

霧也是大自然中最常見的現象之一,有了霧的效果,場景看起來會更加真實。在opengl中,很容易實現霧的效果。

在opengl中,霧的工作模式有兩種:線性模式和指數模式。這兩種模式是根據霧的濃度變化來區分的。

在指數模式下,霧的濃度隨著距離的增加呈指數增長。這種模式通常用來用於煙霧、煙幕等效果。

啟用霧化的效果必須使用glenable(gl_fog),同樣,取消霧的效果就是gldisable(gl_fog)。啟用霧化後,還需要設定霧的引數才能夠真正實現霧的效果。設定霧的引數的命令是glfog,其原型如下。

void glfogf(

glenum

pname

,glfloat

param

);void glfogi(

glenum

pname

,glint

param

);void glfogfv(

glenum

pname

,const glfloat *

params

);void glfogiv(

glenum

pname

,const glint *

params

);pname 表示需要設定的霧的引數,取值及含義說明如下表9-1所示。

表9-1glfog

引數取值含義

pname

取值對應params含義

gl_fog_mode

params

引數表示霧的工作模式。可以取三個值:gl_linear, gl_exp, and gl_exp2,前者表示線性模式,後兩種表示指數模式。預設取值為gl_exp。

gl_fog_density

params

引數表示霧的密度,用於指數模式的指數。如果是負值,則被忽略,預設值為1.0。

gl_fog_start

params

引數表示霧化效果的開始距離,用於線性模式中。預設值為0.0。

gl_fog_end

params

引數表示霧化效果的結束距離,用於線性模式中,預設距離為1.0。

gl_fog_index

params

引數表示在顏色索引表的顏色模式下,顏色的索引值if,

預設的索引值為0.0。

gl_fog_color

僅用於glfogfv

和 glfogiv

函式,此時params引數表示霧的顏色c

f的向量rgba值。不論取值是浮點數還是整數,最終的顏色值都對映到[0,1]範圍。預設的值為(0,0,0,0)。

經過霧化後,從觀察者的角度來看,物體的顏色和其本身的顏色已經不同,這種差別是由混合因子來確定的,而混合因子又來自於霧的各引數。

在指數模式下有兩種情況,當pname取值為gl_fog_mode,param取值為gl_exp時,混合因子f為

當pname取值為gl_fog_mode,param取值為gl_exp2時,混合因子f為

不論採取哪種霧化模式,f 最後都會被對映到[0, 1]之間。計算出f 之後,在rgba顏色模式下,原來某畫素的顏色是

,霧的顏色為

, 則霧化後該畫素的顏色就變成

在顏色索引表模式下,原來某畫素的顏色索引為

,霧的顏色索引為

,則霧化後

該畫素的顏色索引就變成

下面我們來在場景中增加霧的效果。

//global variant

gluint fogmode=;

gluint fog=0;

//預設模式為線性模式

bool bfog = true;//

預設為啟動霧化效果

int glinit()

//啟動霧化效果

glenable(gl_fog);

//霧的顏色

float fogcolor[4] = ; //

霧化效果使用線性模式

glfogi(gl_fog_mode, gl_linear);

//rgba

模式,設定霧的顏色

glfogfv(gl_fog_color, fogcolor);

//霧的濃度,用於指數模式中

glfogf(gl_fog_density, 0.1f);

// 霧的計算精度,使用gl_dont_care或gl_fastest可以針對每個畫素

// 的霧的計算進行調整,提高計算速度。

glhint(gl_fog_hint, gl_dont_care);

// 霧化開始距離

glfogf(gl_fog_start, 0);

// 霧化結束距離

glfogf(gl_fog_end, 20.0f);

return true;

}void glmain()

angle++;

swapbuffers(g_hdc);//

交換前後緩衝區}

對於霧化模式的控制和啟動通過按鍵來實現,這一部分**放在windproc中。

lresult callback wndproc(hwnd hwnd, uint message, wparam wparam, lparam lparam)

else

return 0;

}//

監視視窗啟用訊息

case wm_size:

//通過按鍵改變霧的工作模式

case wm_keydown:

switch(wparam)

break;

case wm_destroy:

postquitmessage(0);

break;

default:

return defwindowproc(hwnd, message, wparam, lparam);

}return 0;

}程式執行後可以看到霧的效果非常明顯,距離越遠的立方體越模糊,最遠的乙個已經全然隱沒在霧中。f1鍵可以就是否進行霧化進行切換,空格鍵則在三種霧化模式間進行變換,esc鍵退出。同時也可以看到,在同樣的密度下,gl_exp2比gl_exp的霧要更加濃厚一些。執行效果如圖9-1所示。

OpenGL系統設計 OpenGL擴充套件

和微軟的direct3d directgraphics相比較,opengl的乙個最大的優點是其擴充套件機制。對於顯示卡硬體的新功能,除非微軟發布了directx的新版本,否則,程式設計師是無法使用的。但opengl就不同了,opengl給硬體廠商和程式設計師提供了擴充套件機制,讓硬體廠商增加基於顯示...

OpenGL系統設計 擴充套件建模 3

除了直線的寬度可以根據需要進行改變外,直線的線型也可以改變。gllinestipple就可以提供不同於常規的連續線段的中心線 虛線 點劃線等等。其函式原型如下 void gllinestipple glint factor glushort pattern 其中 factor factor為3 那麼...

OpenGL系統設計 擴充套件建模 6

和曲線類似,曲面也可以通過控制點來模擬。實際上在很多場合也使用多邊形來模擬平滑曲面,但使用控制點需要的計算機系統資源開銷相對要少很多。同時,控制點個數越多,就越能夠逼近真實的曲面,所以選擇好的演算法和適當的控制點個數相當重要。opengl實現曲面的方法和曲線類似,它使用二維的glmap2和gleva...