前面的简单,看到后面,慢慢的有难度了,stencil 模板测试,要看好久才能理解。看了 ARM 的那篇文章,瞬间透彻了。 原来是一个 GPU 硬件版本的预设回调函数。[旺柴][旺柴]
在 OpenGLES 中,有三个可以绘制的 buffer(缓存),color buffer(颜色缓存),depth buffer(深度缓存)和 stencil buffer(模板缓存)。 对于 color buffer 和 depth buffer 来说,buffer 里面存储的一般都是浮点数,然而对于 stencil buffer,buffer 存储的是无符号整数,确切的说,0 或者 1。 在 OpenGLES 中,stencil buffer 一般最大有 8 位,这就意味着 stencil buffer 的最大值就是 0xFF。 首先要建立起来的观念就是 stencil buffer 的操作并不是加减乘除等算术运算,而是位操作运算。
void glStencilMask(GLuint mask);
void glStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass);
void glStencilFunc(GLenum func, GLint ref, GLuint mask);
伪代码:
// stencil test 比较的时候需要 mask
status = glStencilFunc.func((stencilbuf[x,y] & glStencilFunc.mask), (glStencilFunc.ref & glStencilFunc.mask));
status |= depth_test_result;
if (status == stencil_test_fail) stencilop = glStencilOp.sfailop;
else if (status == stencil_test_pass & depth_test_fail) stencilop = glStencilOp.dpfailop;
else if (status == stencil_test_pass & depth_test_pass) stencilop = glStencilOp.dppassop;
// stencil test 结束后的操作不需要 mask
stencil_new_value = stencilop(stencilbuf[x,y]);
// 写入 stencil buffer 的时候需要另一个 mask
stencilbuf[x,y] = (stencil_new_value & glStencilMask.mask) | (stencilbuf[x,y] & (~glStencilMask.mask));
GL_ALWAYS
,用 1 更新物体将被渲染的片段。尽量多用 GL_KEEP,避免 GL_REPLACE。 假如应用程序只希望写 stencil buffer,下面两种情况是等价的。
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
glStencilFunc(GL_ALWAYS, ref, mask);
glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
glStencilFunc(GL_NOTEQUAL, ref, mask);