qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請(qǐng)?jiān)L問(wèn) http://qaseven.github.io/

          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í)專欄

          <2014年1月>
          2930311234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 多伦县| 美姑县| 方城县| 偏关县| 长岭县| 保康县| 日土县| 通榆县| 吉林省| 大新县| 关岭| 隆尧县| 芦溪县| 诸暨市| 汉中市| 洛南县| 雷山县| 金秀| 高雄市| 新津县| 邹城市| 宝应县| 苗栗市| 夹江县| 黑山县| 会泽县| 宿松县| 平山县| 通山县| 阿巴嘎旗| 杭锦后旗| 灌阳县| 镇巴县| 葫芦岛市| 临桂县| 嵩明县| 安国市| 巴林左旗| 固镇县| 四平市| 淳安县|