无法让 Stencil Buffer 在 iOS 4+ 中工作(5.0 工作正常)。 [OpenGL ES 2.0]

Posted

技术标签:

【中文标题】无法让 Stencil Buffer 在 iOS 4+ 中工作(5.0 工作正常)。 [OpenGL ES 2.0]【英文标题】:Unable to get Stencil Buffer to work in iOS 4+ (5.0 works fine). [OpenGL ES 2.0] 【发布时间】:2012-08-30 00:38:48 【问题描述】:

所以我尝试在 ios 中使用模板缓冲区来进行屏蔽/剪辑。你们知道为什么这段代码可能不起作用吗?这就是我与 Stencils 相关的所有内容。在 iOS 4 上,我得到一个黑屏。在 iOS 5 上,我得到了我所期望的。我在模板中绘制的图像的透明区域是稍后要绘制的唯一区域。

代码如下。

这是我设置 frameBuffer、深度和模板的地方。在 iOS 中,深度和模板是结合在一起的。

-(void)setupDepthBuffer

    glGenRenderbuffers(1, &depthRenderBuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, depthRenderBuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, self.frame.size.width * [[UIScreen mainScreen] scale], self.frame.size.height * [[UIScreen mainScreen] scale]);


-(void)setupFrameBuffer
    
    glGenFramebuffers(1, &frameBuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderBuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderBuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthRenderBuffer);

    // Check the FBO.
    if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) 
        NSLog(@"Failure with framebuffer generation: %d", glCheckFramebufferStatus(GL_FRAMEBUFFER));
    

这就是我设置和绘制模板的方式。 (下面的着色器代码。)

glEnable(GL_STENCIL_TEST);
glDisable(GL_DEPTH_TEST);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthMask(GL_FALSE);

glStencilFunc(GL_ALWAYS, 1, -1);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);

glColorMask(0, 0, 0, 0);
glClear(GL_STENCIL_BUFFER_BIT);

machineForeground.shader = [StencilEffect sharedInstance];
[machineForeground draw];
machineForeground.shader = [BasicEffect sharedInstance];

glDisable(GL_STENCIL_TEST);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE);

这是我使用模板的地方。

glEnable(GL_STENCIL_TEST);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glStencilFunc(GL_EQUAL, 1, -1);

...Draw Stuff here

glDisable(GL_STENCIL_TEST);

最后是我的片段着色器。

varying lowp vec2 TexCoordOut;
uniform sampler2D Texture;

void main(void)

    lowp vec4 color = texture2D(Texture, TexCoordOut);

    if(color.a < 0.1)
        gl_FragColor = color;
    else
        discard;

【问题讨论】:

【参考方案1】:

我能够通过解决我的着色器来解决这个问题。此代码按预期工作正常,但我的顶点数据结构要求的数据比我提供给着色器的数据多。不完全确定允许它在 iOS 5 上运行的引擎盖下发生了什么,但我能够修复它。

那是说

glColorMask(0, 0, 0, 0);

实际上并没有完成我的目标。我想要的是设置清晰的颜色,即使那样我也只想清除模板,所以我实际上正在寻找

glStencilMask(1);

【讨论】:

以上是关于无法让 Stencil Buffer 在 iOS 4+ 中工作(5.0 工作正常)。 [OpenGL ES 2.0]的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL Stencil Buffer,它们的支持程度如何?

glClear [ GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT 和 GL_STENCIL_BUFFER_BIT ]

模板缓冲区似乎无法正常工作

如何使用stencil buffer实现分层剪裁

WebGL中Stencil Buffer的运用以及ThreeJS的实现

OpenGLOpenGL中的Buffer的巧妙使用