使用cubemap创建framebuffer时出现GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT错误

时间:2013-08-09 09:36:18

标签: opengl environment cube framebuffer

我正在尝试使用cubemap为环境贴图创建framebuffer,但是在将cubemap附加为颜色附件时会出现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();

2 个答案:

答案 0 :(得分:0)

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

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

有关更简洁的陈述,请参阅Framebuffer对象的第9点 Completeness Rules

简单地说,您需要使用 深度立方体地图 根本没有深度附件 。机会是你想要的两个选项的后期,听起来你真的只对颜色而不是深度感兴趣。



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

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

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

答案 1 :(得分:0)

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