霧也是大自然中最常見的現象之一,有了霧的效果,場景看起來會更加真實。在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...