《混合、抗鋸齒、霧和多邊形偏移》
標籤(空格分隔): OpenGL編程指南第七版
6.1 混合
6.1.1 源因子與目標因子
void glBlendFunc(GLenum srcfactor GLenum destfactor);
void glBlenndFuncSeparate(GLenum srcRGB, GLenum destRBG, GLenum srcAlpha, GLenum destAlpha);
void glBlendColor(GLclampdf red, GLclampdf green, GLclampdf blue, GLclampdf alpha);
6.1.2 啓用混合
glEnable(GL_BLEND);
6.1.3 使用混合方程式組合像素
void BlendEquation(GLenum mode);
void glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
6.1.6 使用深度緩衝區進行三維混合
半透明物體繪圖順序將會極大地影響最終的結果。如果一個不透明的物體遮擋住了一個半透明的物體或者一個不透明的物體,就需要利用深度緩衝區消除這些距離更遠的物體。但是嗎,如果半透明物體更靠近觀察點,就需要把它與位於它後面的不透明物體進行混合。
這個問題的解決方案是啓用深度緩衝區。在繪製半透明物體時,讓深度緩衝區處於只讀狀態(半透明間需要注意繪圖順序,由遠及近)。
glDepthMask()傳遞GL_FALSE參數,深度緩衝區就設置爲只讀。
6.2 抗鋸齒
void glHint(GLenum target, GLenum hint);對圖像質量和渲染速度之間的權衡關係施加控制。
6.2.1 對點和直線進行抗鋸齒處理
對點和直線進行抗鋸齒處理的一種方法之一是使用glEnable()函數(GL_POINT_SMOOTH或GL_LINE_SMOOTH)啓用抗鋸齒。
RGBA模式下的抗鋸齒
在RGB模式下,需要啓用混合功能。最常用的混合因子是GL_SRC_ALPHA(源)和GL_ONE_MINUS_SRC_ALPHA(目標)。另外也可以使用GL_ONE來表示目標混合因子。
由於所執行的是混合操作(glEnable(GL_BLEND)),可能需要考慮渲染順序。但是,在大多數情況下,可以忽略渲染順序,它不會產生明顯的不良效果。
顏色索引模式下的抗鋸齒
6.2.2 使用多重採樣對幾何圖元進行抗鋸齒處理
多重採樣特別適合對多邊形的邊緣進行抗鋸齒處理,因爲此時不需要進行排序
步驟:
- 獲取支持多重採樣的窗口
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_MUTISAMPLE); - 驗證多重採樣功能是否可用
如果查詢狀態變量GL_SAMPLE_BUFFERS返回的值是1,並且查詢GL_SAMPLES返回的值大於1,就可以使用多重採樣功能。
GLint bufs,samples;
glGetIntergerv(GL_SAMPLE_BUFFERS,&bufs);
glGetIntergerv(GL_SAMPLES,&samples); - 啓用多重採樣
glEnable(GL_MULTISAMPLE);
圖片左側抗鋸齒,右側不抗鋸齒
alpha和多重採樣
在默認情況下,多重採樣計算的覆蓋值是獨立於alpha值的。但是,如果啓用了下面這些特殊的模式,那麼在計算片段的覆蓋值時,就會考慮alpha值的因素。
- GL_SAMPLE_ALPHA_TO_COVERAGE:使用片段的alpha值來計算最終的覆蓋值。
- GL_SAMPLE_ALPHA_TO_ONE:把片段的alpha值設置爲1,然後在計算覆蓋值時使用這個值。
- GL_SAMPLE_COVERAGE:使用glSampleCoverage()函數所設置的值,這個值與經過計算產生的覆蓋值進行組合(使用AND操作)。另外,也可以通過在glSampleCoverage()函數中使用invert標誌來反轉這個模式。
void glSampleCoverage(GLclampf value, GLboolean invert);
6.2.3 對多邊形進行抗鋸齒處理
6.3 霧
霧是在執行了矩陣變換、光照和紋理之後才應用的。
6.3.1 使用霧
glEnable(GL_FOG);啓用霧
GLfloat fogColor4 = { 0.5, 0.5, 0.5, 1.0 };
fogMode = GL_EXP;
glFogi(GL_FOG_MODE, fogMode);
glFogfv(GL_FOG_COLOR, fogColor);
glFogf(GL_FOG_DENSITY, 0.35);
glHint(GL_FOG_HINT, GL_DONT_CARE);
glFogf(GL_FOG_START, 1.0);
glFogf(GL_FOG_END, 5.0);
6.3.2 霧方程式
void glFog{if}(GLenum pname, TYPE param);
void glFog{if}v(GLenum pname, TYPE* param);
RGBA模式下的霧
顏色索引模式下的霧
霧座標
void glFogCoord{fd}(TYPE z);
void glFogCoord{fd}v(const TYPE* z);
此時,視點移動對物體指定霧座標的頂點的霧效果沒有影響。
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
6.4 點參數
點參數是一種自動、優雅的解決方案。它根據點和觀察點的距離,對點的大小和亮度進行衰減。
void glPointParameter{if}(GLenum pname, GLfloat param);
void glPointParameter{if}v(GLenum panme, const TYPE* param);
6.5 多邊形偏移
着重顯示實心物體的邊緣。
多邊形偏移可也以用於在表面上生成貼花、使用隱藏直線消除來渲染圖像。除了直線和多邊形外,這個技巧也可以用於點圖元。
使用glEnable()調用適當的參數(GL_POLYGON_OFFSET_FILL、GL_POLYGON_OFFSET_LINE、GL_POLYGON_OFFSET_POINT)來啓用多邊形偏移。還必須調用glPolygonMode()函數設置當前的多邊形光柵化方法。
void glPolygonOffset(GLfloat factor, GLfloat units);
factor = 0.1f,units = 0.0f
factor = 0.1f,units = 536.0f
factor = 1.4f,units = 0.0f