我正在尝试通过应用模板缓冲区使用 GL_POINTS 在 OpenGL ES 2.0 中绘制纹理。模板缓冲区应该来自纹理。我将结果渲染到另一个纹理,然后将纹理呈现到屏幕上。这是我渲染到纹理的代码:
//Initialize buffers, initialize texture, bind frameBuffer
.....
glClearStencil(0);
glClear (GL_STENCIL_BUFFER_BIT);
glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS, 1, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glBindTexture(GL_TEXTURE_2D, stencil);
glUseProgram(program[PROGRAM_POINT].id);
glDrawArrays(GL_POINTS, 0, (int)vertexCount);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glStencilFunc(GL_NEVER, 0, 1);
glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);
glBindTexture(GL_TEXTURE_2D, texture);
glUseProgram(program[PROGRAM_POINT].id);
glDrawArrays(GL_POINTS, 0, (int)vertexCount);
glDisable(GL_STENCIL_TEST);
....
//Render texture to screen
我得到的结果只是我的纹理被绘制而没有从模板上应用任何 mask 。关于这个问题我有几个问题:
这是我正在寻找的结果:
更新:
正如所选答案所指出的,我的问题主要是我没有将模板附加到 FBO 的模板附件上:
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, stencilBufferId);
我不知道渲染到纹理时需要它。其次,我没有使用正确的模板测试。
glStencilFunc(GL_EQUAL, 1, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
做了工作。
最佳答案
按顺序解决您的问题:
- Is is possible to use a stencil buffer with GL_POINTS?
是的。模板测试适用于所有片段,无论渲染的原始类型如何。在不应用模板测试的情况下写入帧缓冲区的唯一情况是使用
glClear()
。 .
- Is is possible to use a stencil buffer when rendering to a texture?
是的。但是,当您使用 FBO 渲染到纹理时,默认帧缓冲区的模板缓冲区将 不是 使用。您必须创建一个模板渲染缓冲区,并将其附加到 FBO 的模板附件:
GLuint stencilBufferId = 0;
glGenRenderbuffers(1, &stencilBufferId);
glBindRenderbuffer(GL_RENDERBUFFER, stencilBufferId);
glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, stencilBufferId);
- Does the stencil texture have to have any special properties (solid colour, internal format...etc)?
OpenGL ES 2.0 没有模板纹理。您必须使用渲染缓冲区作为模板附件,如上面的代码片段所示。
GL_STENCIL_INDEX8
是唯一支持可用作模板附件的渲染缓冲区格式。 ES 3.0 支持深度/模板纹理。
- Are there any apparent mistakes with my code?
也许。看起来有点奇怪的一件事是,您从未真正在显示的代码中应用模板测试。当您启用模板测试时,您只使用
GL_ALWAYS
和 GL_NEVER
用于模板功能。顾名思义,这些功能要么总是通过模板测试,要么永远不会通过模板测试。所以你不要让片段通过/失败取决于模板值。在第二次抽奖之前,我会期待这样的事情:glStencilFunc(GL_EQUAL, 1, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
这只会渲染当前模板缓冲区值为 1 的片段,这对应于您使用上一次绘制调用渲染的片段。
关于ios - OpenGL ES 2.0 - GL_POINTS 和模板缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26519463/