0

Background:
I am trying to draw primitives into the default window-system framebuffer object. I have three objects which correctly get rendered. Now, I want to generate my own framebuffer object to contain these same images, but have each object rendered in a flat unique color ID to be used for selection during run-time. The user will be presented with three objects, will select one of the objects by a mouse click, then the code will read a pixel in the framebuffer object to determine the color. Once the color has been read, the color of the object will be changed to indicate that it has been selected.

Problem:
For some reason, glBindFramebuffer(GL_FRAMEBUFFER, fbo); is giving me a GL_INCOMPLETE_DRAW_BUFFER after a call to glCheckFramebufferStatus(GL_FRAMEBUFFER). The code is attached. Maybe I'm not setting the framebuffer object up correctly? Or, maybe VMWare doesn't allow framebuffer objects? I would like to have some sanity check to ensure this is the correct way of doing framebuffer objects.

Code (hopefully just the relevant parts):

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);
}

Now, I'm not sure if I need to do anything special before I call my initFrameBuffers method, but this is what I'm doing. My main function just makes a call to initFrameBuffers, then calls my init() method, which draws three objects into the default window-system FBO.

I have tried this same code in a newer version of Kubuntu, and it gives me a different error code: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT instead of GL_INCOMPLETE_DRAW_BUFFER. I'm definitely not sure on what is going on here. I'm reading through the red book eighth edition, and am following what they suggest, but cannot seem to get past getting my framebuffer to bind.

8
  • Did you create a VAO before? I think it's required to use framebuffers. Commented May 27, 2013 at 4:50
  • Try making calls to glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &w), etc. to see if the renderbuffers are being created properly. Commented May 27, 2013 at 5:15
  • 3
    glBindFramebuffer cannot give you completeness errors. So where exactly are you check for completeness? Commented May 27, 2013 at 7:04
  • @subb: Yeah, in the init() method call, I generate my vertices, store them in a data structure containing a std::vector<vec4> (for the vertices), std::vector<vec3> normals (for the vertex normals), and std::vector<vec4> colors (for the vertex colors only in the new framebuffer). The VAOs are generated in init() by calling glGenVertexArrays(NumVAOs, vaos);. Also, the VBOs are generated on the next line of code by calling glGenBuffers(NumVBOs, vbos); Commented May 27, 2013 at 13:24
  • @Nicol Bolas: Well look at that... it doesn't check for completeness of a framebuffer. I was checking for completeness after each gl* call within the initFrameBuffers() method by calling a checkErrors() function. This switched based on the result from a call to glCheckFramebufferStatus(GL_FRAMEBUFFER). Checking for the errors again after I bind my renderbuffer objects to the framebuffer object results in a GL_FRAMEBUFFER_COMPLETE return value. So the framebuffer is now setup with a color and depth renderbuffer, but why can't I draw in it? It always draws in the window-system framebuffer. Commented May 27, 2013 at 13:28

1 Answer 1

1

As was pointed out, glBindFramebuffer(..) does not return a state indicating frame buffer completeness. I was using the call to glCheckFramebufferStatus(GL_FRAMEBUFFER) after each call within my initFrameBuffers() routine. However, I did not check the status after I was binding the render buffers to the frame buffer. If I would have done so, I would have seen that I was indeed setting the render and frame buffers up correctly.

Regarding usage of the frame buffer, I must have been leaving the window-system frame buffer attached whenever I was performing a draw, since every draw was not occurring within the FBO, but on the window-system frame buffer. After paying attention to where I was binding the FBOs and how I was calling glDrawBuffer and glReadBuffer, I seem to have gotten it correct. I can now render an object into the window-system frame buffer using Phong lighting then render the same object into the FBO using a solid color. Once the object has been rendered into the two buffers, I can use glReadPixels to determine when the user clicks on the object by performing a color look-up from within the FBO.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.