【问题标题】:OpenGL Frame Buffer Object - glBindFramebuffer ErrorOpenGL 帧缓冲区对象 - glBindFramebuffer 错误
【发布时间】:2013-05-27 04:36:57
【问题描述】:

背景:
我正在尝试将原语绘制到默认的窗口系统帧缓冲区对象中。我有三个正确渲染的对象。现在,我想生成我自己的帧缓冲区对象来包含这些相同的图像,但让每个对象都呈现在一个单一的唯一颜色 ID 中,以便在运行时用于选择。用户将看到三个对象,通过鼠标单击选择其中一个对象,然后代码将读取帧缓冲区对象中的一个像素以确定颜色。读取颜色后,对象的颜色将更改以指示它已被选中。

问题:
出于某种原因,glBindFramebuffer(GL_FRAMEBUFFER, fbo); 在致电glCheckFramebufferStatus(GL_FRAMEBUFFER) 后给了我GL_INCOMPLETE_DRAW_BUFFER。附上代码。也许我没有正确设置帧缓冲区对象?或者,也许 VMWare 不允许帧缓冲区对象?我想进行一些健全性检查,以确保这是处理帧缓冲区对象的正确方法。

代码(希望只是相关部分):

void initFrameBuffers()
{
    glGenRenderbuffers(NumRBOs, rbos);
    glBindRenderbuffer(GL_RENDERBUFFER, rbos[COLOR]);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, WIDTH, HEIGHT);
    glBindRenderbuffer(GL_RENDERBUFFER, rbos[DEPTH]);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, WIDTH, HEIGHT);

    glGenFramebuffers(1, &fbo);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);   // Causes the error
    glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbos[COLOR]);
    glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbos[DEPTH]);

    glEnable(GL_DEPTH_TEST);

    // Re-enable the default window-system framebuffer for drawing
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}

void drawToFBO()
{
    // Load the user defined framebuffer object
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
    glDrawBuffer(GL_COLOR_ATTACHMENT0);
    glViewport(0, 0, WIDTH, HEIGHT);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Draw into the user defined framebuffer object, not the default window-system FBO
    glBindVertexArray(vaos[CYLINDER]);
    glDrawArrays(GL_TRIANGLES, 0, cylinder.vertices.size());

    // Re-enable the default window-system framebuffer
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}

现在,我不确定在调用我的 initFrameBuffers 方法之前是否需要做任何特别的事情,但这就是我正在做的事情。我的主函数只是调用initFrameBuffers,然后调用我的init() 方法,它将三个对象绘制到默认的窗口系统FBO 中。

我在较新版本的 Kubuntu 中尝试了相同的代码,但它给了我一个不同的错误代码:GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 而不是 GL_INCOMPLETE_DRAW_BUFFER。我绝对不确定这里发生了什么。我正在阅读红皮书第八版,并按照他们的建议进行操作,但似乎无法通过绑定我的帧缓冲区。

【问题讨论】:

  • 您之前创建过 VAO 吗?我认为需要使用帧缓冲区。
  • 尝试调用 glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &w) 等来查看渲染缓冲区是否创建正确。
  • glBindFramebuffer 不能给你完整性错误。那么您在哪里确切地检查完整性?
  • @subb: 是的,在 init() 方法调用中,我生成了我的顶点,将它们存储在包含 std::vector (用于顶点)的数据结构中,std:: vector 法线(用于顶点法线)和 std::vector 颜色(仅用于新帧缓冲区中的顶点颜色)。通过调用 glGenVertexArrays(NumVAOs, vaos); 在 init() 中生成 VAO。此外,通过调用 glGenBuffers(NumVBOs, vbos); 在下一行代码中生成 VBO;
  • @Nicol Bolas:好吧,看看……它不检查帧缓冲区的完整性。在 initFrameBuffers() 方法中的每个 gl* 调用之后,我通过调用 checkErrors() 函数来检查完整性。这基于调用 glCheckFramebufferStatus(GL_FRAMEBUFFER) 的结果进行切换。在我将渲染缓冲区对象绑定到帧缓冲区对象后再次检查错误会导致 GL_FRAMEBUFFER_COMPLETE 返回值。所以帧缓冲区现在设置了颜色和深度渲染缓冲区,但为什么我不能在里面绘制呢?它总是在窗口系统帧缓冲区中绘制。

标签: opengl framebuffer fbo


【解决方案1】:

正如所指出的,glBindFramebuffer(..) 不返回指示帧缓冲区完整性的状态。在我的initFrameBuffers() 例程中的每次调用之后,我都在使用对glCheckFramebufferStatus(GL_FRAMEBUFFER) 的调用。但是,在将渲染缓冲区绑定到帧缓冲区后,我没有检查状态。如果我这样做了,我会看到我确实正确设置了渲染和帧缓冲区。

关于帧缓冲区的使用,每当我执行绘图时,我一定是连接了窗口系统帧缓冲区,因为每次绘制都不是发生在 FBO 内,而是发生在窗口系统帧缓冲区上。在注意了我绑定 FBO 的位置​​以及我如何调用 glDrawBufferglReadBuffer 之后,我似乎得到了正确的结果。我现在可以使用 Phong 照明将对象渲染到窗口系统帧缓冲区,然后使用纯色将相同的对象渲染到 FBO。一旦对象被渲染到两个缓冲区中,我可以使用glReadPixels 通过在 FBO 中执行颜色查找来确定用户何时单击对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-21
    • 2014-06-26
    • 2010-10-19
    • 1970-01-01
    • 1970-01-01
    • 2013-12-19
    • 2014-07-08
    • 1970-01-01
    相关资源
    最近更新 更多