0

我正在尝试使用立方体贴图为环境贴图创建帧缓冲区,但是在将立方体贴图作为颜色附件附加时,它会给出 GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 错误。

void FrameBuffer::create(size_t width, size_t height) {
    this->width=width;
    this->height=height;

    glGenFramebuffersEXT(1, &id);

    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
void FrameBuffer::attachDepthTexture() {
    glGenTextures(1, &depthTexture);
    glBindTexture(GL_TEXTURE_2D, depthTexture);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
    glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY); 

    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
    glBindTexture(GL_TEXTURE_2D, 0);

    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id);
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, depthTexture, 0);

    checkStatus();
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
void FrameBuffer::attachDepthTextureCube() {
    glGenTextures(1, &depthTexture);

    glBindTexture(GL_TEXTURE_CUBE_MAP, depthTexture);

    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

    for (int face=0; face<6; face++)
        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+face, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
    glBindTexture(GL_TEXTURE_CUBE_MAP, 0);

    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id);
    for(int face=0; face<6; face++)
        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X+face, depthTexture, 0);

    checkStatus();
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
void FrameBuffer::attachColorTextureCube(GLuint i=0) {
    i=clamp(i, 0, GL_MAX_COLOR_ATTACHMENTS_EXT-1);

    glGenTextures(1, &colorTexture[i]);

    glBindTexture(GL_TEXTURE_CUBE_MAP, colorTexture[i]);

    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

    for(int face=0; face<6; face++)
        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+face, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
    glBindTexture(GL_TEXTURE_CUBE_MAP, 0);

    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id);
    for(int face=0; face<6; face++)
        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X+face, colorTexture[i], 0);

    checkStatus();
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}

函数调用在这里完成:

    reflectionFrameBuffer.create(Game::Settings::screenWidth, Game::Settings::screenHeight);
    reflectionFrameBuffer.attachDepthTexture();
    reflectionFrameBuffer.attachColorTextureCube();
4

2 回答 2

0

我怀疑您的问题与您有一个 2D 纹理的深度缓冲区附件和一个立方体贴图的颜色缓冲区附件有关。这违反了帧缓冲区对象规范,因为它与附加分层图像有关。

立方体贴图纹理真的应该被认为是一个专门的纹理数组——它们本质上是一个由 6 个 2D 纹理组成的数组,具有特殊的纹理查找功能。因此,它们是分层的图像;事实上,您可以使用层语义(在此处解释)来处理几何着色器中的每个立方体贴图面。

有关更简洁的陈述,请参阅 Framebuffer Object Completeness Rules的要点 7 。

简而言之,您要么需要使用深度立方体贴图,要么根本不需要深度附件。很可能这两个选项中的后者是您想要的,听起来您真的只对颜色感兴趣而不是深度。



免责声明:还值得一提的是,我上面链接的 Wiki 属于基于 ARB 扩展的最终 FBO 规范。

EXT 扩展非常不完整,缺乏对多样本纹理附件的支持。此外,EXT 扩展在确定完整性方面有更严格的规则(除其他外,每个附件必须具有相同的尺寸)。良好的驱动程序/硬件配对通常会实现这两个扩展,并且如果您选择使用 EXT 扩展,则会强制执行更严格的完整性细微差别。

因此,除非您的目标是未实现 ARB 扩展的平台,否则您应该不惜一切代价避免使用 EXT。如果您被迫使用 EXT 扩展,请注意它与 ARB 扩展之间的区别。

于 2013-08-09T17:41:47.517 回答
0

我得到了我的错误......我为立方体贴图使用了不同的纹理宽度和高度

于 2013-08-10T15:24:16.510 回答