OpenGL ES 中的模板测试

Posted bky2016

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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);

 

以上是关于OpenGL ES 中的模板测试的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL ES 学习教程(十三) Stencil_TEST(模板缓冲测试)

OpenGL ES 中的模板测试

◮OpenGL-模板测试

◮OpenGL-模板测试

为啥模板测试不丢弃片段?

OpenGL ES 2.0中的剪切平面