`
tiankefeng0520
  • 浏览: 143095 次
  • 性别: Icon_minigender_1
  • 来自: 长春
社区版块
存档分类
最新评论

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

 
阅读更多

帧缓冲区有许多缓冲区构成,这些缓冲区大致分为
颜色缓冲区:用于绘图的缓冲区,它包含了颜色索引或者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函数获取与模板相关的参数值

 

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()  
{  
  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;  
}  

 

  • 大小: 3 KB
  • 大小: 12.6 KB
  • 大小: 11.7 KB
  • 大小: 6.2 KB
分享到:
评论

相关推荐

    OpenGL模板缓冲区应用示例源代码

    OpenGL模板缓冲区应用示例源代码,代码比较简单,通过修改或注释模板缓冲区控制语句就可以明白其中奥秘。

    opengl模型提取轮廓

    在opengl中绘制模型,利用模板缓冲区提取绘制需要提取轮廓的模型,并得到一张二值图(2维矩阵),最用利用opencv提取轮廓

    OpenGL ES 3.0编程指南第2版[中文][PDF]

    由资深OpenGL技术专家亲笔撰写,全面介绍OpenGL ES 3.0的各种特性及新增功能,通过大量已经编译和测试过的实例,详细讲解OpenGL ES 3.0中的应用程序接口(API)和图形管线,既涵盖简单图形的渲染方法,又深入介绍逐...

    OpenGL ES 3.0

     第11章讨论可以适用于整个帧缓冲区或者在OpenGL ES 3.0片段管线中执行片段着色器后适用于单个片段的操作。这些操作包括剪裁测试、模板测试、深度测试、多重采样、混合和抖动。本章介绍OpenGL ES 3.0图形管线的最后...

    OpenGL编程指南(第四版

    我们可以使用这些缓冲区实现诸如隐藏表面消除、模板、屏蔽、运动模糊和景深聚焦等效果。  ·第11章显示了如何使用GLU(OpenGL Utility Library,OpenGL工具函数库)中的分格化和二次方程函数。  ·第12章介绍...

    OpenGL入门学习.pdf

    一、第一个OPENGL程序...................................................................................................................4 1.1、OPENGL的优点.................................................

    hellogl:现代 OpenGL 的 Win32 模板

    你好现代 OpenGL 的 Win32 示例该示例显示了如何使用 WGL 获取 OpenGL 渲染上下文。 使用 gl3w(包含在项目中)加载 OpenGL3+ 函数。 使用着色器和缓冲区对象进行简单绘图。 使用 Visual Studio 2013。

    Tiny-Universe-Engine:试用OpenGL 3.3和SDL2

    我正在使用该项目作为学习OpenGL,开发大型项目的C风格和实践以及学习计算机图形技术的方法,例如延迟渲染,模板缓冲区阴影,过程生成,腐蚀模拟,物理渲染等。最终,我希望将其变成一个不错的轻量级太空探索游戏/...

    OpenGL关于glStencilFuncSeparate()和glStencilFunc()函数的区别讲解

    glStencilFunc()函数是OpenGL提供的对模板缓冲区进行控制的命令,这是OpenGL2.0之前使用的函数,其函数原型为 void glStencilFunc(GLenum func, GLint ref, GLuint mask). func指定比较函数,它指定了测试通过的...

    ES2.0编程指南(中文版).pdf

    华章 OpenGL ES 3.0编程指南(原书第2版)由资深OpenGL技术专家亲笔撰写,全面介绍OpenGL ES 3.0的各种特性及新增功能,通过大量已经编译和测试过的实例,详细讲解OpenGL ES 3.0中的应用程序接口(API)和图形管线,...

    sre:SRE 是使用 OpenGL 或 OpenGL-ES 2.0 的优化实时 3D 渲染引擎。 当前版本支持 Linux(OpenGL 或 OpenGL-ES 2.0,在 PC 和某些基于 ARM 的设备上)

    还支持某些帧缓冲区 OpenGL-ES 2.0 后端,包括 Raspberry Pi 1/2。 使用 GLFW 将旧版本移植到 Windows(32 位),其他平台也可行,因为前后端分离并支持 OpenGL-ES 2.0 标准以及跨平台 GUI 后端,例如作为 GLFW。 ...

    ogl_fbo_pbo_readback

    FBO创建以后必须绑定缓冲区:颜色、深度必须,模板缓冲区看需求而定。 缓冲区对象并不局限于RBO,纹理对象也可以充当缓冲区对象:创建纹理是glTexImage2D最后一个参数为NULL,在显存中只需要创建纹理对象,而并不...

    micropolis:用 OpenCL 编写的微多边形光栅化器

    光栅化器填充一个帧缓冲区,然后在 OpenGL 中将其渲染为纹理。 还有一个替代渲染后端,它使用 OpenGL 硬件细分进行性能比较。 这是它的运行视频: 汇编 在 Linux 上构建 micropolis 需要以下依赖项: 控制器 GLFW...

    CollissionDetection:球体、立方体和平面的碰撞检测和物理

    碰撞检测该程序渲染由墙壁、球和立方体...特征动态碰撞检测(球-球、球-平面、球-三角形、AABB-AABB、AABB-平面) 真实的物理React使用 OpenGL 模板缓冲区的反射效果创建向量和矩阵数据类型将天空盒用于环境环境截图

    windowsnt 技术内幕

    怎样准备70-073考试 理解工作站与客户端 理解为什么要参加70-073测试 理解Windows NT体系结构 深入理解用户模式内核模式 Windows NT Executive简介 理解Windows NT内存模型的优点 理解中央管理的优点 登录到Windows ...

Global site tag (gtag.js) - Google Analytics