OpenGL學習二十九 模板緩衝區與模板測試

2021-09-01 21:59:37 字數 4236 閱讀 1433

幀緩衝區有許多緩衝區構成,這些緩衝區大致分為

顏色緩衝區:用於繪圖的緩衝區,它包含了顏色索引或者rgba顏色資料。

深度緩衝區:儲存每個畫素的深度值,當啟動深度測試時,片段畫素深度值和深度緩衝區深度值進行比較,決定片段哪些畫素點資料可以替換到顏色緩衝區中。

模板緩衝區:就像使用紙板和噴漆一樣精確的混圖一樣,當啟動模板測試時,通過模板測試的片段畫素點會被替換到顏色緩衝區中,從而顯示出來,未通過的則不會儲存到顏色緩衝區中,從而達到了過濾的功能。

累積緩衝區:累積緩衝區允許你把渲染到顏色緩衝區的值,拷貝到累積緩衝區。在多次拷貝操作到累積緩衝區時,可以用不同方式的把顏色緩衝區內容和當前累積緩衝區的內容進行重複混合

模板測試

模板測試只有存在模板緩衝區的情況下進行,模板測試把畫素儲存在模板緩衝區的點與乙個參考值進行比較(glstencilfunc),根據測試結果,對模板緩衝區的值進行響應的修改glstencilop

void glstencilfunc (glenum func, glint ref, gluint mask);

func:gl_never 從來不能通過

gl_always 永遠可以通過(預設值)

gl_less 小於參考值可以通過

gl_lequal 小於或者等於可以通過

gl_equal 等於通過

gl_gequal 大於等於通過

gl_greater 大於通過

gl_notequal 不等於通過

ref: 參考值

mask:掩碼,書上說模板測試只在哪些對應為1的位上進行。(不是很確定具體作用)

舉例:glstencilfunc (gl_less, 1.0, 1.0);模板緩衝區對應的畫素點的值如果小於1.0,則通過模板測試

void glstencilop (glenum fail, glenum zfail, glenum zpass);

fail模板測試未通過時該如何變化;zfail表示模板測試通過,但深度測試未通過時該如何變化;zpass表示模板測試和深度測試或者未執行深度測試均通過時該如何變化

gl_keep(不改變,這也是預設值)

gl_zero(回零)

gl_replace(使用測試條件中的設定值來代替當前模板值)

gl_incr(增加1,但如果已經是最大值,則保持不變),

gl_incr_wrap(增加1,但如果已經是最大值,則從零重新開始)

gl_decr(減少1,但如果已經是零,則保持不變),

gl_decr_wrap(減少1,但如果已經是零,則重新設定為最大值)

gl_invert(按位取反)

未啟用模板緩衝區

glclear(gl_color_buffer_bit|gl_depth_buffer_bit); 

glloadidentity(); 

gltranslatef(0, 0, -20); 

glcolor3f(1.0f,1.0f,1.0f);

dradius = 5.0*(sqrt(2.0)/2.0); 

glbegin(gl_line_strip); 

for (dangel=0;dangel<380.0;dangel+=0.1) 

glend(); 

glcolor3f(1.0f,0.0f,0.0f); 

glrectf(-5,-5,5,5);

初始清除背景填充顏色為藍色

以上這部分**可以用如下3張圖表示繪製的過程

開啟模板緩衝區

void init() 

glclear(gl_color_buffer_bit|gl_depth_buffer_bit|gl_stencil_buffer_bit);//1

glloadidentity(); 

gltranslatef(0, 0, -20);  

glstencilfunc(gl_never,0x0,0xff);  //2

glstencilop(gl_incr,gl_incr,gl_incr);//3

glcolor3f(1.0f,1.0f,1.0f);

dradius = 5.0*(sqrt(2.0)/2.0); 

glbegin(gl_line_strip); 

for (dangel=0;dangel<380.0;dangel+=0.1) 

glend(); 

glstencilfunc(gl_notequal,0x1,0xff);  //4

glstencilop(gl_keep,gl_keep,keep); //5

glcolor3f(1.0f,0.0f,0.0f); 

glrectf(-5,-5,5,5); 

當執行到1處,3個緩衝區都被清空

顏色緩衝區:每個畫素點顏色都是藍色

深度緩衝區:每個畫素點深度都是1.0

模板緩衝區:每個畫素點模板值都是0

執行到2,3處,模板測試條件是從不通過測試,如果不通過測試結果是模板值+1

接著應用模板測試進行繪製一組點,由於模板測試條件是從不通過測試,所以顏色緩衝器值不會變化,但是繪製的點對應的畫素點的模板值變為1,此時

顏色緩衝區:每個畫素點顏色都是藍色

深度緩衝區:每個畫素點深度都是1.0

模板緩衝區:點陣列對應的模板值是1,其他區域畫素點的模板值還是0

執行到4,5處,模板測試條件是模板值不一定1則通過測試,如果不通過測試結果是模板值+1

接著應用剛才的模板測試進行繪製乙個(-5,-5,5,5)的矩形,在這個矩形區域內,畫素點的模板值分為2中,值為1的是上1步的點陣列。值為0的是上一步非的點陣列畫素點。那個根據模板測試條件,模板值為0的畫素點通過測試,可以進行替換顏色緩衝區的值(替換成紅色),模板值為0的畫素點不能通過測試,因此不能改變顏色緩衝區的值

顏色緩衝區:(-5,-5,5,5)區域內 模板值為0的畫素點為紅色,其他區域都為藍色

深度緩衝區:每個畫素點深度都是1.0

模板緩衝區:點陣列對應的模板值是1,其他區域畫素點的模板值還是0

模板查詢

可以用glgetinteger函式獲取與模板相關的引數值

gl_stencil_func

模板函式

gl_stencil_ref

模板參考值

gl_stencil_value_mask

模板掩碼

gl_stencil_fail

模板測試失敗後操作

gl_stencil_pass_depth_fail

模板測試通過深度測試失敗後的操作

gl_stencil_pass_depth_pass

模板測試深度測試都通過後的操作

#include "header.h"

float dradius =0;

float dangel;

float aspect=0;

void init()

void display()

glend();

glstencilfunc(gl_notequal,0x1,0xff);

glstencilop(gl_incr,gl_incr,gl_incr);//

glcolor3f(1.0f,0.0f,0.0f);

glrectf(-5,-5,5,5);

glutswapbuffers();

} void reshape(int w, int h)

int main(int argc, char** argv)

OpenGL學習二十九 模板緩衝區與模板測試

幀緩衝區有許多緩衝區構成,這些緩衝區大致分為 顏色緩衝區 用於繪圖的緩衝區,它包含了顏色索引或者rgba顏色資料。深度緩衝區 儲存每個畫素的深度值,當啟動深度測試時,片段畫素深度值和深度緩衝區深度值進行比較,決定片段哪些畫素點資料可以替換到顏色緩衝區中。模板緩衝區 就像使用紙板和噴漆一樣精確的混圖一...

黑板模式(二十九)

黑板模式 blackboarddesignpattern 是觀察者模式的乙個擴充套件,知名度並不高,但是我們使用的範圍卻非常廣。黑板模式的意圖如下 允許訊息的讀寫同時進行,廣泛地互動訊息。簡單地說,黑板模式允許多個訊息讀寫者同時存在,訊息的生產者和消費者完全分開。這就像乙個黑板,任何乙個教授 訊息的...

C 學習(二十九)內聯inline

內聯函式適用能夠快速執行的函式,此時使用內聯省去了函式的呼叫開銷。內聯函式像巨集一樣都是在編譯期展開,內嵌到呼叫處。inline省去普通函式的壓棧和call,以空間換時間,僅僅省去了函式呼叫的開銷 當函式體比較小的時候,內聯該函式可以令目標 更加高效.對於訪問函式以及其它函式體比較短,效能關鍵的函式...