模板缓冲区
简介
整个图形渲染管线中包含了许多步骤,其中一步是模板测试,它在透明度测试之后,深度测试之前。
模板缓冲中的模板值通常是8位的,因此每个片段/像素共有256种不同的模板值,模板缓冲区与深度缓冲区的大小相同。在使用的过程中,一般先开启模板缓冲,绘制一个物体作为我们的模板,这个过程实际上就是写入模板缓冲的过程;接着我们利用模板缓冲中的值决定是丢弃还是保留后续绘图中的片元。
作用
模板测试的作用有许多,常见的:
- 绘制物体轮廓
- 实现镜面效果
- 实现阴影效果
等等。
函数
- 使能模板测试
glEnable(GL_STENCIL_TEST);
- 设置模板缓冲区的写入掩码(默认为 0xFF)
glStencilMask(GLuint mask);
表示哪些位可以写入,比如:0x01,表示右边第一位可写入。
- 清除模板缓冲区中的值(默认为 0)
glClearStencil(GLint s);
- 设置模板测试是否通过的规则
glStencilFunc(GLenum func, GLint ref, GLuint mask);
枚举值 | 描述 |
---|---|
GL_NEVER | 永远不能通过 |
GL_ALWAYS | 永远可以通过 |
GL_LESS | 小于(参考值&掩码)可以通过 |
GL_LEQUAL | 小于或者等于(参考值&掩码)可以通过 |
GL_EQUAL | 等于(参考值&掩码)通过 |
GL_GEQUAL | 大于等于(参考值&掩码)通过 |
GL_GREATER | 大于(参考值&掩码)通过 |
GL_NOTEQUAL | 不等于(参考值&掩码)通过 |
ref:参考值。
mask:掩码。用于分别于参考值(ref)和模板缓冲区值进行与(&)运算,再将结果进行比较。
- 根据测试结果修改模板缓冲区的值
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_STENCIL_BUFFER_BIT);
例子
要实现轮廓效果,我们的思路是:
- 绘制两个box。
- 再绘制两个更大的box,但是1中绘制box的像素位置不再绘制2中box,这样就得到轮廓。
下面介绍绘制过程,以及绘制过程中模板缓冲区的变化:
- 绘制之前先清空缓冲区:
glClear(GL_STENCIL_BUFFER_BIT);
此时模板缓冲区为:
0000000000000000000
0000000000000000000
0000000000000000000
0000000000000000000
0000000000000000000
0000000000000000000
0000000000000000000
初始化也为0
- 使能模板缓冲区写入,绘制两个矩形:
glStencilFunc(GL_ALWAYS, 1, 0xFF); //GL_ALWAYS总是测试通过
//并且glStencilMask(0xFF);表示可写入,则将1写入模板缓冲区
glStencilMask(0xFF);
DrawTwoContainers();//绘制两个box
此时缓冲区为:
0000000000000000000
0000001111100000000
0000001111100000000
0000001111111111000
0000000000111110000
0000000000111110000
0000000000000000000
- 绘制两个大的box:
glStencilFunc(GL_NOTEQUAL, 1, 0xFF);//模板缓冲区中不等于1的模板对应的片段测试通过
glStencilMask(0x00); //模板禁止写入
glDisable(GL_DEPTH_TEST);
...//绘制两个放大的box
总结
总的来说,只要掌握了模板缓冲区的值的变换,就能理解代码。从而能够利用模板缓冲区来减少硬件的计算量,做一些更好的功能。