OpenGL ES 中的模板测试
模板测试的主要功能是丢弃一部分片元,相对于深度检测来说,模板测试提出的片元数量相对较少。模板测试发生在剪裁测试之后,深度测试之前。
使用模板测试时很重要的代码提示:
1 1.glClear( GL_STENCIL_BUFFER_BIT); 2 //启用模板测试 3 2.glEnable(GL_STENCIL_TEST);
大多数情况你的模板遮罩(stencil mask)写为0x00或0xFF就行。
1 // 0xFF == 0b11111111,此时,模板值与它进行按位与运算结果是模板值,模板缓冲可写 2 glStencilMask(0xFF); 3 4 // 0x00 == 0b00000000 == 0,此时,模板值与它进行按位与运算结果是0,模板缓冲不可写 5 glStencilMask(0x00);
glStencilMask允许我们给模板值设置一个位遮罩(Bitmask),它与模板值进行按位与(AND)运算决定缓冲是否可写。默认设置的位遮罩都是1,这样就不会影响输出,但是如果我们设置为0x00,所有写入深度缓冲最后都是0。
另外,可以通过glStencilFunc和glStencilOp决定模板测试通过或失败以及怎样影响模板缓冲。
1 void glStencilFunc(GLenum func, GLint ref, GLuint mask);
- func:设置模板测试操作。这个测试操作应用到已经储存的模板值和glStencilFunc的ref值上,可用的选项是:
GL_NEVER、GL_LEQUAL、GL_GREATER、GL_GEQUAL、GL_EQUAL、GL_NOTEQUAL、GL_ALWAYS。它们的语义和深度缓冲的相似。
- ref:指定模板测试的引用值。模板缓冲的内容会与这个值对比。
- mask:指定一个遮罩,在模板测试对比引用值和储存的模板值前,对它们进行按位与(and)操作,初始设置为1。
代码片段如下:
1 glStencilFunc(GL_EQUAL, 1, 0xFF); 2 //它会告诉OpenGL,无论何时,一个片段模板值等于(GL_EQUAL)引用值1,片段就能通过测试被绘制了,否则就会被丢弃。
glStencilFunc只描述了OpenGL对模板缓冲做什么,而不是描述我们如何更新缓冲。这就需要glStencilOp方法了。
1 void glStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass);
- sfail: 如果模板测试失败将采取的动作。
- dpfail: 如果模板测试通过,但是深度测试失败时采取的动作。
- dppass: 如果深度测试和模板测试都通过,将采取的动作。
glStencilOp函数默认设置为 (GL_KEEP, GL_KEEP, GL_KEEP) ,所以任何测试的任何结果,模板缓冲都会保留它的值。
默认行为不会更新模板缓冲,所以如果你想写入模板缓冲的话,你必须像任意选项指定至少一个不同的动作。
注意:三维遮罩
1 glDepthMask(GL_TRUE);//启用写入深度值 2 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 3 glStencilFunc(GL_ALWAYS, 1, 0xFF); 4 glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP); 5 glStencilMask(0xFF);