OpenGL模板緩沖區(qū)與模板測(cè)試
幀緩沖區(qū)有許多緩沖區(qū)構(gòu)成,這些緩沖區(qū)大致分為:
顏色緩沖區(qū):用于繪圖的緩沖區(qū),它包含了顏色索引或者RGBA顏色數(shù)據(jù)。
深度緩沖區(qū):存儲(chǔ)每個(gè)像素的深度值,當(dāng)啟動(dòng)深度測(cè)試時(shí),片段像素深度值和深度緩沖區(qū)深度值進(jìn)行比較,決定片段哪些像素點(diǎn)數(shù)據(jù)可以替換到顏色緩沖區(qū)中。
模板緩沖區(qū):就像使用紙板和噴漆一樣精確的混圖一樣,當(dāng)啟動(dòng)模板測(cè)試時(shí),通過(guò)模板測(cè)試的片段像素點(diǎn)會(huì)被替換到顏色緩沖區(qū)中,從而顯示出來(lái),未通過(guò)的則不會(huì)保存到顏色緩沖區(qū)中,從而達(dá)到了過(guò)濾的功能。
累積緩沖區(qū):累積緩沖區(qū)允許你把渲染到顏色緩沖區(qū)的值,拷貝到累積緩沖區(qū)。在多次拷貝操作到累積緩沖區(qū)時(shí),可以用不同方式的把顏色緩沖區(qū)內(nèi)容和當(dāng)前累積緩沖區(qū)的內(nèi)容進(jìn)行重復(fù)混合
模板測(cè)試
模板測(cè)試只有存在模板緩沖區(qū)的情況下進(jìn)行,模板測(cè)試把像素存儲(chǔ)在模板緩沖區(qū)的點(diǎn)與一個(gè)參考值進(jìn)行比較(glStencilFunc),根據(jù)測(cè)試結(jié)果,對(duì)模板緩沖區(qū)的值進(jìn)行響應(yīng)的修改glStencilOp
void glStencilFunc (GLenum func, GLint ref, GLuint mask);
func:GL_NEVER 從來(lái)不能通過(guò)
GL_ALWAYS 永遠(yuǎn)可以通過(guò)(默認(rèn)值)
GL_LESS 小于參考值可以通過(guò)
GL_LEQUAL 小于或者等于可以通過(guò)
GL_EQUAL 等于通過(guò)
GL_GEQUAL 大于等于通過(guò)
GL_GREATER 大于通過(guò)
GL_NOTEQUAL 不等于通過(guò)
ref: 參考值
mask:掩碼,書上說(shuō)模板測(cè)試只在哪些對(duì)應(yīng)為1的位上進(jìn)行。(不是很確定具體作用)
舉例:glStencilFunc (GL_LESS, 1.0, 1.0);模板緩沖區(qū)對(duì)應(yīng)的像素點(diǎn)的值如果小于1.0,則通過(guò)模板測(cè)試
void glStencilOp (GLenum fail, GLenum zfail, GLenum zpass);
fail模板測(cè)試未通過(guò)時(shí)該如何變化;zfail表示模板測(cè)試通過(guò),但深度測(cè)試未通過(guò)時(shí)該如何變化;zpass表示模板測(cè)試和深度測(cè)試或者未執(zhí)行深度測(cè)試均通過(guò)時(shí)該如何變化
GL_KEEP(不改變,這也是默認(rèn)值)
GL_ZERO(回零)
GL_REPLACE(使用測(cè)試條件中的設(shè)定值來(lái)代替當(dāng)前模板值)
GL_INCR(增加1,但如果已經(jīng)是最大值,則保持不變),
GL_INCR_WRAP(增加1,但如果已經(jīng)是最大值,則從零重新開(kāi)始)
GL_DECR(減少1,但如果已經(jīng)是零,則保持不變),
GL_DECR_WRAP(減少1,但如果已經(jīng)是零,則重新設(shè)置為最大值)
GL_INVERT(按位取反)
未啟用模板緩沖區(qū)
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) { glVertex2d(dRadius*cos(dAngel),dRadius*sin(dAngel)); dRadius*=1.003; } glEnd(); glColor3f(1.0f,0.0f,0.0f); glRectf(-5,-5,5,5); |
初始清除背景填充顏色為藍(lán)色
以上這部分代碼可以用如下3張圖表示繪制的過(guò)程
開(kāi)啟模板緩沖區(qū)
void init() { glClearColor(0,0,1.0,0); glClearStencil(0); glClearDepth(1.0f); glEnable(GL_STENCIL_TEST); } 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) { glVertex2d(dRadius*cos(dAngel),dRadius*sin(dAngel)); dRadius*=1.003; } 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); |
當(dāng)執(zhí)行到1處,3個(gè)緩沖區(qū)都被清空
顏色緩沖區(qū):每個(gè)像素點(diǎn)顏色都是藍(lán)色
深度緩沖區(qū):每個(gè)像素點(diǎn)深度都是1.0
模板緩沖區(qū):每個(gè)像素點(diǎn)模板值都是0
執(zhí)行到2,3處,模板測(cè)試條件是從不通過(guò)測(cè)試,如果不通過(guò)測(cè)試結(jié)果是模板值+1
接著應(yīng)用模板測(cè)試進(jìn)行繪制一組點(diǎn),由于模板測(cè)試條件是從不通過(guò)測(cè)試,所以顏色緩沖器值不會(huì)變化,但是繪制的點(diǎn)對(duì)應(yīng)的像素點(diǎn)的模板值變?yōu)?,此時(shí)
顏色緩沖區(qū):每個(gè)像素點(diǎn)顏色都是藍(lán)色
深度緩沖區(qū):每個(gè)像素點(diǎn)深度都是1.0
模板緩沖區(qū):點(diǎn)數(shù)組對(duì)應(yīng)的模板值是1,其他區(qū)域像素點(diǎn)的模板值還是0
執(zhí)行到4,5處,模板測(cè)試條件是模板值不一定1則通過(guò)測(cè)試,如果不通過(guò)測(cè)試結(jié)果是模板值+1
接著應(yīng)用剛才的模板測(cè)試進(jìn)行繪制一個(gè)(-5,-5,5,5)的矩形,在這個(gè)矩形區(qū)域內(nèi),像素點(diǎn)的模板值分為2中,值為1的是上1步的點(diǎn)數(shù)組。值為0的是上一步非的點(diǎn)數(shù)組像素點(diǎn)。那個(gè)根據(jù)模板測(cè)試條件,模板值為0的像素點(diǎn)通過(guò)測(cè)試,可以進(jìn)行替換顏色緩沖區(qū)的值(替換成紅色),模板值為0的像素點(diǎn)不能通過(guò)測(cè)試,因此不能改變顏色緩沖區(qū)的值
顏色緩沖區(qū):(-5,-5,5,5)區(qū)域內(nèi) 模板值為0的像素點(diǎn)為紅色,其他區(qū)域都為藍(lán)色
深度緩沖區(qū):每個(gè)像素點(diǎn)深度都是1.0
模板緩沖區(qū):點(diǎn)數(shù)組對(duì)應(yīng)的模板值是1,其他區(qū)域像素點(diǎn)的模板值還是0
模板查詢
可以用glGetInteger函數(shù)獲取與模板相關(guān)的參數(shù)值
#include "header.h" float dRadius =0; float dAngel; float aspect=0; void init() { glClearColor(0,0,1.0,0); glClearStencil(0); glClearDepth(1.0f); glEnable(GL_STENCIL_TEST); } void display() { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); glLoadIdentity(); glTranslatef(0, 0, -20); ////glStencilFunc(GL_ALWAYS, 0,0x00); glStencilFunc(GL_NEVER,0x0,0xFF); glStencilOp(GL_INCR,GL_INCR,GL_INCR); 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) { glVertex2d(dRadius*cos(dAngel),dRadius*sin(dAngel)); dRadius*=1.003; } 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) { glViewport(0,0,w,h); aspect = (w*1.0)/h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60, aspect, 1, 100); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } int main(int argc, char** argv) { glutInit(&argc, argv); //glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_STENCIL); glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_STENCIL|GLUT_DEPTH); glutInitWindowPosition(200,200); glutInitWindowSize(600,600); glutCreateWindow("模板緩沖區(qū)與模板測(cè)試"); glewInit(); init(); glutReshapeFunc(reshape); glutDisplayFunc(display); glutMainLoop(); return 0; } |
posted on 2014-01-23 11:53 順其自然EVO 閱讀(3476) 評(píng)論(0) 編輯 收藏 所屬分類: 測(cè)試學(xué)習(xí)專欄