使用立方体映射创建帧缓冲区时发生GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT错误



我正试图为环境映射创建具有立方体映射的帧缓冲区,但在将立方体映射作为颜色附件进行附件时,它会出现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();

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

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

有关更简洁的语句,请参阅Framebuffer对象完整性规则的要点7。

简单地说,您要么需要使用深度立方体映射,要么根本没有深度附件。很可能这两个选项中较晚的一个是你想要的,听起来你真的只对颜色感兴趣,而对深度不感兴趣。



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

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

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

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

最新更新