ios - 在 iOS 中使用模板缓冲区

标签 ios opengl-es stencil-buffer

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

这是一个 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 channel 替换了黑色,并在我的渲染中启用了混合。

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

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

最佳答案

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

你画了片段吗? (更新模板缓冲区):(不更新模板缓冲区);

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

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

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

关于ios - 在 iOS 中使用模板缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11383940/

相关文章:

iphone - 在 Windows/Linux 上的 iPhone 上编程?

ios - WatchKit 的 willActivate() 函数。 Xcode 不喜欢 self.view.insertSubview

ios - 我的iOS项目中的GPUImage cocoapod触发了“找不到'OpenGL/OpenGL.h'文件”

opengl - OpenGL 中的门户使用模板缓冲区 - 如何避免在门户前面绘制内容?

android - 在 arcore 中的 3d 对象上使用模板蒙版时出现问题

ios - WKWebView如何显示指向http : pages的链接

ios - 使用核心数据从 TableView 打开编辑 View Controller

iOS OpenGL ES - 模拟器和设备上的不同纹理行为

java - 2d手游开发: OpenGL ES 2. 0还是cocos2d-x?

c++ - 将 OpenGL 模板功能移植到 DirectX 11