帧缓冲区有许多缓冲区构成,这些缓冲区大致分为:
颜色缓冲区:用于绘图的缓冲区,它包含了颜色索引或者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; }
相关推荐
OpenGL模板缓冲区是一种图形处理技术,常用于实现复杂的遮罩效果和高级...总的来说,这个源代码示例是一个很好的学习工具,可以帮助开发者掌握OpenGL模板缓冲区的使用,并激发他们在3D图形编程中实现创新效果的灵感。
模板测试的工作原理是通过对比帧缓冲区中的模板缓冲区和我们设定的模板值来决定像素是否应该被绘制。当一个像素的模板值与预设的比较操作符匹配时,像素才会被绘制。我们可以自由设置和修改这个模板缓冲区,从而实现...
特别地,文档中还提到了一些其它的函数和技巧,例如使用glScalef函数实现镜像效果,尽管这不是与模板缓冲区直接相关,但也是图形处理中常见的技巧。 总的来说,OpenGL中的蒙板缓冲区非常强大,它不仅能够帮助开发者...
而模板缓冲区则是OpenGL中的一个辅助缓冲区,可以用来存储每个像素的8位模板值。通过比较模板值和用户定义的测试掩码,我们可以实现复杂的渲染效果,如遮罩、剪裁、深度复杂度排序等。 在wxWidgets中,它是一个C++...
在现代GPU中,每个像素都有四个主要的缓冲区:颜色缓冲区(Color Buffer)存储最终的颜色信息,深度缓冲区(Z-Buffer或Depth Buffer)处理深度测试以决定哪个像素应该覆盖另一个,以及模板缓冲区。模板缓冲区是一个与...
模板缓冲区是一个与颜色缓冲区、深度缓冲区并行的附加缓冲区,用于存储每个像素的模板值。这些值可以被用来控制像素是否应该被绘制,或者如何被绘制。 在iOS和Xcode环境下,使用OpenGL ES(OpenGL for Embedded ...
以上内容仅是OpenGL编程的基础,实际应用中可能还需要处理光照、着色、深度测试、模板缓冲、混合模式等复杂效果。对于初学者,理解并手动实现这些功能有助于深化对图形学原理的理解。尽管如此,由于OpenGL的复杂性,...
10. **帧缓冲区(Frame Buffer)**:OpenGL默认使用帧缓冲区进行渲染,但也可以自定义附加缓冲区,如颜色缓冲区、深度缓冲区和模板缓冲区。 11. **混合(Blending)**:混合功能允许半透明效果,通过组合新像素和旧...
它允许开发者根据模板缓冲区(Stencil Buffer)中的值来决定是否绘制某个像素。模板测试通常用于实现一些高级的图形效果,如阴影、反射、折射等。 当片段着色器处理完片段之后,模板测试(Stencil Test) 就开始执行...
压缩包中的OpenGL3.3_StencilBuffer_Outlines可能包含了一些示例代码、教程或资源,用于演示如何在OpenGL 3.3环境中配置和使用模板缓冲区来实现轮廓效果。这些文件可以帮助开发者更好地理解和实践Stencil Buffer技术...
模板测试会比较模板缓冲区中的值与预设的条件,如果满足条件,则允许像素通过,否则会被拒绝。模板操作则允许我们修改模板缓冲区的值,以创建复杂的遮罩效果。 在实际应用中,我们可能需要设置一系列的模板函数和...
10. **资源释放**:当程序结束时,别忘了释放OpenGL资源,如删除着色器、删除缓冲区对象,以及释放设备上下文。 这个"OpenGL单文档模板"应该包含了上述步骤的实现,使得开发者可以直接在模板基础上添加自己的图形...
5. **片段操作**:包括片段着色器、颜色混合、深度测试、模板测试等,这些都是决定像素是否被写入帧缓冲区的关键步骤。 6. **纹理和图像处理**:详细解析纹理对象、纹理坐标映射、MIP贴图、纹理过滤和纹理环境设置...
3. **顶点数组对象**(Vertex Array Object, VAO)和**缓冲区对象**(Buffer Object, BO):用于高效地存储和传输顶点数据到GPU。VAO是顶点数据的配置信息,BO则用来存储顶点数据。 4. **纹理**(Texture):在2D...
- **高级功能**:探讨了一些更复杂的特性,如混合、深度测试、模板缓冲区等。 #### 四、实施者视角下的OpenGL - **OpenGL的内部结构**:从实现者的角度介绍OpenGL的架构设计和技术细节。 - **性能优化技巧**:提供...
- 深度测试与模板测试:讲解如何处理图形的前后遮挡关系。 - 光照模型:介绍如何模拟现实世界中的光照效果。 - 纹理映射和混合:如何使用纹理增强图形表现力,以及如何实现透明和混合效果。 - 属性和状态管理:如何...
5. **交换缓冲区**:在每一帧结束时,调用`[EAGLContext presentRenderbuffer:GL_RENDERBUFFER]`呈现渲染结果到屏幕。 在实际项目中,你可能还需要处理触摸事件、添加纹理、实现动画效果等。提供的模板是一个很好的...
OpenGL支持多种类型的缓冲区,包括颜色缓冲区、深度缓冲区和模板缓冲区。帧缓冲对象允许你创建离屏渲染目标,这对于后期处理效果和多重采样抗锯齿(MSAA)很有用。 **9. 纹理映射** 纹理映射是将图像数据应用到几何...
在介绍基本概念之后,书中详细讲解了现代OpenGL中的资源管理,如缓冲区对象、纹理、帧缓冲和着色器程序。这些资源在GPU上存储和处理数据,对于高效的图形渲染至关重要。同时,作者会讨论不同的纹理类型和过滤选项,...