OpenGL模板缓冲区与模板测试

转载 2015年07月10日 16:01:31

原文地址:http://www.blogjava.net/qileilove/archive/2014/01/23/409269.html

帧缓冲区有许多缓冲区构成,这些缓冲区大致分为:

    颜色缓冲区:用于绘图的缓冲区,它包含了颜色索引或者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)
{
glVertex2d(dRadius*cos(dAngel),dRadius*sin(dAngel));
dRadius*=1.003;
}
glEnd();
glColor3f(1.0f,0.0f,0.0f);
glRectf(-5,-5,5,5);

 

初始清除背景填充颜色为蓝色
  以上这部分代码可以用如下3张图表示绘制的过程
  开启模板缓冲区
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);


  当执行到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函数获取与模板相关的参数值
#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("模板缓冲区与模板测试");
glewInit();
init();
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}


相关文章推荐

OpenGL学习二十九:模板缓冲区与模板测试

帧缓冲区有许多缓冲区构成,这些缓冲区大致分为: 颜色缓冲区:用于绘图的缓冲区,它包含了颜色索引或者RGBA颜色数据。 深度缓冲区:存储每个像素的深度值,当启动深度测试时,片段像素深度值和深度缓...

opengl模板测试实例

在opengl中, 可以开启模板测试功能,来限定某一部分是可画的,某一部分是不可画的。这可通过设置模板模式来控制哪部分是可画的, 有点类似在墙上喷字。  虽说剪刀测试也可以限定蓝屏的某一部分可画,但...

OpenGL--模板测试

理论基础 模板测试:通俗点讲就是为屏幕每个像素设置了一个模板值,然后拿一个参考值与之比较,满足条件就通过,则对应像素就会绘制,否则不绘制。类似深度测试一样,只是服务情形不同,深度测试主要用来消除背面...

OpenGL模板测试

模板测试 模板测试是所有OpenGL测试中比较复杂的一种。首先,模板测试需要一个模板缓冲区,这个缓冲区是在初始化OpenGL时指定的。如果使用GLUT工具包,可以在调用glutInitDisplayM...

openGL模板测试遇到的问题

运行openGL入门教程中,模板测试程序,核心代码如下: void draw_sphere() {     // 设置光源     glEnable(GL_LIGHTING); ...

OpenGL学习脚印:模板测试(stencil testing)

写在前面 上一节介绍了深度测试,本节继续学习一个高级主题-模板测试(stencil testing)。模板缓冲同之前介绍的颜色缓冲、深度缓冲类似,通过它我们可以实现很多的特效,例如轮廓、镜面效果,阴...

OpenGL(十四) 模板测试

启用模板测试时,OpenGL会在内存中开辟一块空间作为模板缓冲区,里边保存了每个像素的“模板值”,模板测试的过程就是把每一个像素的模板值与一个设定的模板参考值进行比较,符合设定条件的通过测试,不符合条...
  • dcrmg
  • dcrmg
  • 2016-11-17 22:33
  • 441

OpenGL模板测试之镜像模型解析

#include #include #include #include using namespace std; static GLfloat mirror_x = 0; static ...

OpenGL中的Alpha测试,深度测试,模板测试,裁减测试

片断测试其实就是测试每一个像素,只有通过测试的像素才会被绘制,没有通过测试的像素则不进行绘制。OpenGL提供了多种测试操作,利用这些操作可以实现一些特殊的效果。 我们在前面的课程中,曾经提到了“深...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)