提供该效果的解决方案可以通过面剔除通过对正面和背面进行单独的模板测试来实现,并且(参见glStencilFuncSeparate
和glStencilOpSeparate
)。遗憾的是,几何体的背面必须在一个单独的步骤中绘制。
该过程可以描述为以下步骤:
为了使算法起作用,您必须将所有基元绘制成相同的缠绕顺序。你必须告诉OpenGL方向glFrontFace
。顺时针GL_CW
或逆时针GL_CCW
。
GLES20.glStencilMask(0xFF);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_STENCIL_BUFFER_BIT);
GLES20.glFrontFace(GLES20.GL_CCW); // depends on your geometry "GL_CCW" or "GL_CW"
GLES20.glDisable(GLES20.GL_CULL_FACE);
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glDepthFunc(GLES20.GL_LESS); // default
GLES20.glColorMask(false,false,false,false);
GLES20.glEnable(GLES20.GL_STENCIL_TEST);
GLES20.glStencilFuncSeparate(GLES20.GL_FRONT, GLES20.GL_ALWAYS, 1, 0xFF);
GLES20.glStencilFuncSeparate(GLES20.GL_BACK, GLES20.GL_ALWAYS, 1, 0xFF);
GLES20.glStencilOpSeparate(GLES20.GL_FRONT, GLES20.GL_KEEP, GLES20.GL_KEEP, GLES20.GL_REPLACE);
GLES20.glStencilOpSeparate(GLES20.GL_BACK, GLES20.GL_KEEP, GLES20.GL_KEEP, GLES20.GL_KEEP);
// draw the holes
// ....
GLES20.glStencilFuncSeparate(GLES20.GL_FRONT, GLES20.GL_EQUAL, 0, 0xFF);
GLES20.glStencilOpSeparate(GLES20.GL_FRONT, GLES20.GL_KEEP, GLES20.GL_KEEP, GLES20.GL_KEEP);
GLES20.glStencilFuncSeparate(GLES20.GL_BACK, GLES20.GL_ALWAYS, 0, 0xFF);
GLES20.glStencilOpSeparate(GLES20.GL_BACK, GLES20.GL_KEEP, GLES20.GL_KEEP, GL_REPLACE);
GLES20.glEnable(GLES20.GL_CULL_FACE);
GLES20.glCullFace(GLES20.GL_FRONT);
// draw the geometry the 1. time ("draw" back faces)
// ....
GLES20.glCullFace(GLES20.GL_BACK);
GLES20.glColorMask(true,true,true,true);
// draw the geometry the 2. time (draw front faces)
// ....