【问题标题】:Use stencil buffer with iOS在 iOS 中使用模板缓冲区
【发布时间】:2012-07-08 04:41:42
【问题描述】:

我尝试使用“模板缓冲区”从纹理显示我的渲染的一部分,但我的渲染显示时没有任何遮罩效果。

适用于 2D iOS 项目,使用 OpenGL ES 2.0 这是我的代码的相关部分:

glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
glEnable( GL_STENCIL_TEST );


// mask rendering
glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
glStencilFunc( GL_ALWAYS, 1, 1 );
glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );

glBindTexture(GL_TEXTURE_2D, _maskTexture);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);  


// scene rendering
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); 
glStencilFunc( GL_EQUAL, 1, 1 ); 
glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );  

glBindTexture(GL_TEXTURE_2D, _viewTexture);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);  

任何帮助将不胜感激!

(像往常一样法国开发者,对不起我的英语!)

精度:“_maskTexture”是黑白图片。


解决方案:


我终于用 rotoglubtim 的指示解决了我的问题。 谢谢两位。

1/ 模板缓冲区未正确创建。 它应该像这样初始化:

glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthStencilRenderbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, 
                             GL_DEPTH24_STENCIL8_OES, 
                             backingWidth, 
                             backingHeight);

这是我的渲染不受蒙版影响的主要原因。

2/ 为了能够将纹理用作遮罩,我将黑色替换为 Alpha 通道并在渲染中启用混合。

我的最终渲染代码如下所示:

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    
glVertexPointer(2, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
    
glClearStencil(0); 
glClearColor (0.0,0.0,0.0,1);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 
    

// mask rendering
glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
glEnable(GL_STENCIL_TEST);
glEnable(GL_ALPHA_TEST);
glBlendFunc( GL_ONE, GL_ONE );
glAlphaFunc( GL_NOTEQUAL, 0.0 );
glStencilFunc(GL_ALWAYS, 1, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
    
glBindTexture(GL_TEXTURE_2D, _mask);
glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);  
    
// scene rendering
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 
glStencilFunc(GL_EQUAL, 1, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
    
glDisable(GL_STENCIL_TEST);
glDisable(GL_ALPHA_TEST);
glBindTexture(GL_TEXTURE_2D, _texture);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);  

【问题讨论】:

  • 仅仅将您的问题描述为 不起作用 并没有真正的帮助。但我想你的问题是在另一个问题中解决的问题:stackoverflow.com/questions/7571075/…
  • 感谢您的评论。通过“不工作”,我的意思是“_viewTexture”的显示没有任何“_maskTexture”的蒙版效果。将来我会尝试更具体。关于你提到的帖子,我已经读过了,但如果我没记错的话,他用着色器解决了他的问题,并放弃了模板缓冲区。
  • 在阅读您的解决方案帖子时,我认为您仍然有问题(可能暂时被隐藏):您的模板测试在您的第二次渲染过程中被禁用,因此您观察到的掩蔽不会被此测试引发.此外,混合不应该对模板测试有用,只有 alpha 测试。我认为您观察到了您想要的掩蔽,但可能是出于另一个原因,即刻印。
  • @EricD:这看起来像 GLES1.1 解决方案,对吗?如果是这样:这正是我正在寻找的!

标签: ios opengl-es stencil-buffer


【解决方案1】:

简单地说,问题在于您只是在场景中绘制纹理,而没有对纹理中的内容进行任何测试。模板缓冲区不关心纹理中的颜色,它只是检查:

Did you draw a fragment ? (Update stencil buffer) : (Don't update stencil buffer);

您正在为纹理的每个像素绘制一个片段,因此纹理中的任何遮罩效果都是无用的。

如果要使用纹理进行遮罩,则需要丢弃任何不想在模板缓冲区中更新的片段。

这可以通过着色器中的 discard 关键字或 OpenGLES 1.1 中的 glAlphaTest/glAlphaFunc 来完成

【讨论】:

    猜你喜欢
    • 2011-09-05
    • 2012-03-13
    • 2016-05-03
    • 2020-11-27
    • 2020-04-19
    • 2012-07-11
    • 2016-01-31
    • 2020-12-19
    • 2013-04-08
    相关资源
    最近更新 更多