【问题标题】:Separate stencil with FBO (NVidia)使用 FBO (NVidia) 分离模板
【发布时间】:2016-11-30 11:08:46
【问题描述】:

我正在尝试使用具有单独深度和模板缓冲区的 FBO。 我知道 NVidia GPU 历史上只支持打包深度/模板。 然而,我偶然发现了 ARB_texture_stencil8 扩展,想知道如何将它用于 FBO。 此代码在 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, fboStencilTexture, 0) 上给出 gl 错误 1159:

    static GLuint fboId, rboDepth, rboStencil, TEXTURE_WIDTH, TEXTURE_HEIGHT;
    if (!fboColorTexture) {
        fboDepthTexture = fboId = rboDepth = rboStencil = TEXTURE_WIDTH = TEXTURE_HEIGHT = 0; // vid restart?
        glGenTextures(1, &fboColorTexture);
        glBindTexture(GL_TEXTURE_2D, fboColorTexture);
        qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    }
    if (!fboDepthTexture) {
        glGenTextures(1, &fboDepthTexture);
        glBindTexture(GL_TEXTURE_2D, fboDepthTexture);
        qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    }   
    if (!fboStencilTexture) {
        glGenTextures(1, &fboStencilTexture);
        glBindTexture(GL_TEXTURE_2D, fboStencilTexture);
        qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    }
    GLuint curWidth = r_virtualResolution.GetFloat() * glConfig.vidWidth, curHeight = r_virtualResolution.GetFloat() * glConfig.vidHeight;
    if (curWidth != TEXTURE_WIDTH || curHeight != TEXTURE_HEIGHT) {
        TEXTURE_WIDTH = curWidth;
        TEXTURE_HEIGHT = curHeight;
        glBindTexture(GL_TEXTURE_2D, fboColorTexture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); //NULL means reserve texture memory, but texels are undefined
        glBindTexture(GL_TEXTURE_2D, fboDepthTexture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
        glBindTexture(GL_TEXTURE_2D, fboStencilTexture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_STENCIL_INDEX8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_STENCIL_INDEX, GL_FLOAT, 0);
    }
    //-------------------------
    if (!fboId) {
        // create a framebuffer object, you need to delete them when program exits.
        glGenFramebuffersEXT(1, &fboId);
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
        // attach a texture to FBO color attachement point
        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fboColorTexture, 0);
        // attach a renderbuffer to depth attachment point
        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, fboDepthTexture, 0);
        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, fboStencilTexture, 0);
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
    }
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);

【问题讨论】:

  • "此代码给出 gl error 1159 on" 没有这样的错误代码。十六进制或十进制。事实上,在所有 OpenGL 中都没有具有该值的枚举。
  • 也许试试我的代码,看看你得到了什么错误?
  • 为了尝试您的代码,它必须是minimal reproducible example,但事实并非如此。这只是一段代码。

标签: opengl nvidia fbo stencil-buffer


【解决方案1】:

ARB_texture_stencil8 的目的是允许您使用纯模板格式作为纹理。也就是说,在着色器中读取它们。

这并不意味着您可以将模板缓冲区和深度缓冲区分开。 stencil-8 纹理背后的想法是,您可以通过复制深度/模板纹理的模板部分来生成它们的数据,或者您将渲染 完全没有深度缓冲区。

因此,您不能使用此扩展程序来保证您可以渲染到单独的深度和模板图像。这仍然取决于硬件。

此外,如果您要使用 ARB_texture_stencil8 等新功能,则不应将它们与旧的 EXT_framebuffer_object API 结合使用。所以停止使用glFramebufferTexture2DEXT,开始使用glFramebufferTexture

【讨论】:

  • 好吧,因为 glFramebufferTexture 与 glFramebufferTexture2DEXT 没有什么不同,所以真的没有动力去切换。真可惜 NVidia 不会做一个单独的模板缓冲区这样简单的事情。
  • @AntonDuzenko:“真遗憾,NVidia 不会做一个单独的模板缓冲区这样简单的事情。” 是什么让您认为它“简单”?事实上,Vulkan 甚至不允许单独的深度/模板的可能性。为什么?因为 没有人 支持它。所以底层的图形 API 甚至没有给你选择。
  • 英特尔支持它,他们不是 3d 国王。
猜你喜欢
  • 1970-01-01
  • 2012-02-22
  • 2016-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多