ios - OpenGL ES 2.0 - GL_POINTS 和模板缓冲区

标签 ios objective-c opengl-es opengl-es-2.0 stencil-buffer

我正在尝试通过应用模板缓冲区使用 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 。关于这个问题我有几个问题:
  • 是否可以使用带有 GL_POINTS 的模板缓冲区?
  • 渲染到纹理时是否可以使用模板缓冲区?
  • 模板纹理是否必须具有任何特殊属性(纯色、内部格式...等)?
  • 我的代码有任何明显的错误吗?

  • 这是我正在寻找的结果:
    enter image description here

    更新:

    正如所选答案所指出的,我的问题主要是我没有将模板附加到 FBO 的模板附件上:
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
                          GL_RENDERBUFFER, stencilBufferId);
    

    我不知道渲染到纹理时需要它。其次,我没有使用正确的模板测试。
    glStencilFunc(GL_EQUAL, 1, 1);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
    

    做了工作。

    最佳答案

    按顺序解决您的问题:

    1. Is is possible to use a stencil buffer with GL_POINTS?


    是的。模板测试适用于所有片段,无论渲染的原始类型如何。在不应用模板测试的情况下写入帧缓冲区的唯一情况是使用 glClear()。 .

    1. 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);
    

    1. 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 支持深度/模板纹理。

    1. Are there any apparent mistakes with my code?


    也许。看起来有点奇怪的一件事是,您从未真正在显示的代码中应用模板测试。当您启用模板测试时,您只使用 GL_ALWAYSGL_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/

    相关文章:

    objective-c - objectForKey 和 valueForKey 的区别?

    objective-c - UITableView dataSource 必须从 tableView :cellForRowAtIndexPath error 返回一个单元格

    objective-c - 如何访问动画 GIF 的帧

    android - 无法获取 opengl OutOfMemory 错误 1285

    android - 在 OpenGL 中将 alpha mask 应用于视频

    ios - 是否有可能恢复你上次在 UIwebView Xcode 5 中的位置

    ios - RTCDataChannel 不工作 iOS

    javascript - react native 重复错误 : Duplicated files or mocks

    ios - 具有三种不同 WebView 的 iPad App?

    iphone - 渲染到纹理或离屏帧缓冲区