如何在模板中使用深度纹理,OpenGL ES 3.0

Posted

技术标签:

【中文标题】如何在模板中使用深度纹理,OpenGL ES 3.0【英文标题】:How to use depth texture with stencil, OpenGL ES 3.0 【发布时间】:2017-04-19 19:01:50 【问题描述】:

我有一个应用程序,我想使用模板遮罩为纹理渲染深度。我试试 GL_DEPTH_STENCIL_OES:

创建纹理:

glGenFramebuffers(1, fbo);
glBindFramebuffer(GL_FRAMEBUFFER, *fbo);

glGenTextures(1, depthTexture);
glBindTexture(GL_TEXTURE_2D, *depthTexture);
// using combined format: depth + stencil
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL_OES, w, h, 0, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);

// attaching both depth and stencil
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, *depthTexture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, *depthTexture, 0);

// No color output in the bound framebuffer, only depth.
GLenum drawbuffers[] =  GL_NONE ;
glDrawBuffers(1, drawbuffers);

GL_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE);

为阴影贴图创建模板蒙版:

// bind to depth fbo
glBindFramebuffer(GL_FRAMEBUFFER, *fbo);

glEnable(GL_STENCIL_TEST);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glClear(GL_STENCIL_BUFFER_BIT);

// write to stencil when objects are rendered
glStencilFunc(GL_ALWAYS, 1, 0xFF);
glStencilMask(0xFF);

drawVisibleObjects();

使用模板遮罩渲染深度:

glBindFramebuffer(GL_FRAMEBUFFER, *fbo);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_EQUAL, 1, 0xFF); // Pass test if stencil value is 1
glStencilMask(0x00); // Don't write anything to stencil buffer
glDepthMask(GL_TRUE); // Write to depth buffer

drawObjects();

执行代码时,屏幕是黑色的。这是出乎意料的,因为我没有将深度渲染到默认帧缓冲区,而是渲染到纹理。由于模板值存储在纹理中,我必须以不同的方式使用它们吗?

当使用组合深度模板纹理 GL_DEPTH_STENCIL_OES 时,使用模板附件的正确方法是什么?

【问题讨论】:

【参考方案1】:

模板值是您要渲染到的帧缓冲区的属性。如果要在 FBO0 中使用模板掩码,则需要在 FBO0 中请求模板(并在渲染到 FBO0 时填充掩码等)。

【讨论】:

以上是关于如何在模板中使用深度纹理,OpenGL ES 3.0的主要内容,如果未能解决你的问题,请参考以下文章

如何提高自定义 OpenGL ES 2.0 深度纹理生成的性能?

在 OpenGL ES 中为帧缓冲区使用深度和模板渲染缓冲区附件

OpenGL ES之“深度测试”与“模板测试”的使用流程

如何在 OpenGL ES 2.0 中使用 png 图像纹理立方体?

OpenGL ES纹理

如何确定Android OpenGL ES上的最大纹理内存