今天看了看opengl的融合技術,聯系前一段時間老師讓我改的一個用他自己的框架實現的3d物體透明融合的程序,感覺到老師說的思路,不可以實現。
因為三維的透明物體,簡單的使用融合功能和融合因子是不夠的,三維物體有遠近,因此三維物體的繪制過程是利用的是深度緩沖技術。這樣的話,對於繪制透明物體與不透明物體,順序是十分關鍵的。一般來說,應該先畫不透明物體,因為透明物體的繪制需要opengl的融合功能,
glEnable(GL_BLEND);
,但是融合功能一旦啟動,會影響后繼物體的着色。但是先畫不透明物體,又會產生新的問題。因為透明物體往往在不透明物體的前面,所以在深度測試中,透明物體的點會通過測試,所以會繪制新點,而把原來的不透明物體的點覆蓋掉。這是,opengl用了一個方法,當畫完不透明物體后,立即將深度緩沖進行屏蔽,即修改深度緩沖為只讀模式,不能再向深度緩沖中寫入信息。這樣就避免了不透明物體的深度信息遭到破壞。同時opengl還從深度緩沖中讀取深度信息,從而決定了不透明物體哪些點需要進行融合。
因此總結了采用融合技術繪制三維物體的步驟:
1.啟動深度測試
glEnable(GL_DEPTH_TEST)
2.繪制不透明物體
3.設置深度緩沖為只讀模式
glDepthMask(GL_FALSE)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA,GL_ONE)
4.繪制透明物體
5.恢復深度緩沖的可寫屬性
glDepthMask(GL_TRUE)
glDisable(GL_BLEND)
在運用window平台時,需要在PIXELFORMATDESCRIPTOR結構中設置雙緩沖。
static PIXELFORMATDESCRIPTOR pfd={
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
24,
0,0,0,0,0,0,
0,
0,
0,
0,0,0,0,
32,
0,
0,
PFD_MAIN_PLANE,
0,
0,0,0
};
同時利用SwapBuffer()這個函數進行緩沖的交換,在緩沖交換之前,必須進行同步操作。
opengl提供了兩個同步操作函數glFlush()和glFish()
glFlush()函數用於表明先前被送到的所有指令必須在有限時間內完成。在網絡模式下,該函數可以強制客戶端在由命令組成的網絡包還沒有填滿的情況下不等待命令而發送該包,以便繪圖工作可以繼續進行。而glFinish()則用於強制完成先前所有的指令。