4

I am trying to render a simple checkerboard in a FBO and then do a glReadPixels().

When I do it without FBO, everything works fine. So I assume that my render function is ok and so is the glReadPixels(). With the FBO, all I get are the lines that I draw after the calls to FBO have been done.

Here is my code (Python, aiming cross platform):

def renderFBO():
    #WhyYouNoWorking(GL_FRAMEBUFFER) # degug function... error checking
    glBindFramebuffer( GL_DRAW_FRAMEBUFFER, framebuffer)

    glBindRenderbuffer( GL_RENDERBUFFER, renderbufferA)
    glRenderbufferStorage( GL_RENDERBUFFER, GL_RGBA, window.width, window.height)

    glBindRenderbuffer( GL_RENDERBUFFER, renderbufferB)
    glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT, window.width, window.height)    

    glBindFramebuffer( GL_DRAW_FRAMEBUFFER, framebuffer)
    glFramebufferRenderbuffer( GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbufferA)
    glFramebufferRenderbuffer( GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbufferB)

    #WhyYouNoWorking(GL_FRAMEBUFFER)

    glDrawBuffer(GL_COLOR_ATTACHMENT0)
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
    glViewport( 0, 0, window.width, window.height)


    DrawChecker(Nbr = 16, Dark = 25.0/255, Light = 75.0/255)
    for i in range(len(labelSysInfo)):
        pyglet.text.Label(labelSysInfo[i], font_name='Times New Roman', font_size=26, x=(window.width*0.68), y= (window.height*0.04*i)+(window.height*2/3), anchor_x='left', anchor_y='center', color = (250, 250, 250, 150)).draw()

    glReadPixels(0, 0, window.width, window.height, GL_RGBA, GL_UNSIGNED_BYTE, a)
    glBindFramebuffer( GL_FRAMEBUFFER, 0)

My other function:

def on_draw(dt):   
    glDrawBuffer(GL_BACK)
    glClear(GL_COLOR_BUFFER_BIT)
    glClearColor( 0.0, 0.0, 0.0, 1.0)
    glLoadIdentity()
    glEnable(GL_TEXTURE_2D)


    glDisable(GL_TEXTURE_2D)
    BlueLine() # draw a simple line. works fine
    DropFrameTest()   # draw a simple line. works fine

In the main, the call to renderFBO() is done once, and then on_draw is called periodically.

dt = pyglet.clock.tick()
renderFBO()  
pyglet.clock.schedule_interval(on_draw, 0.007)
pyglet.app.run()
genpfault
  • 51,148
  • 11
  • 85
  • 139
BaldDude
  • 1,025
  • 1
  • 19
  • 33

1 Answers1

4

At a guess, you've bound the framebuffer to the GL_DRAW_FRAMEBUFFER only. Use

glBindFramebuffer(GL_FRAMEBUFFER, ...

and

glFramebufferRenderbuffer(GL_FRAMEBUFFER, ...

to both read and write with the same FBO.

I'm sure you already have but checking for framebuffer completeness (glCheckFramebufferStatus) and for GL errors (glGetError, or the new extension) is also very useful.

[EDIT]
(The shotgun problem solving tactics from the comments)

If you see an image on the first frame, but none on the next there must be something staying behind from the previous frame.

  • The most common problem is forgetting to clear the depth buffer - but you haven't.
  • Next up are stencil buffers and blending (neither look like they're enabled to begin with).
  • Maybe a new FBO handle is being generated each frame and you're running out?
  • Another common problem is accumulating matrix transforms, but you have glLoadIdentity so should be no issue there.
jozxyqk
  • 16,424
  • 12
  • 91
  • 180
  • Tried it but it didn't work. I do call glCheckFramebufferStatus(). Thanks for your help :) – BaldDude Aug 15 '13 at 15:22
  • It's been ages since I've used python+gl, but after unbinding the FBO, can you try... glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBlitFramebuffer(0, 0, window.width, window.height, 0, 0, window.width, window.height, GL_COLOR_BUFFER_BIT, GL_NEAREST); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); so you can see the contents of your FBO – jozxyqk Aug 15 '13 at 15:29
  • Great! I did not figure how to validate the content of my FBO. Thanks for the hint. So what I get from this is that my FBO is rendered only once. Does this suggest that I am clearing the content of my FBO before I read it? – BaldDude Aug 15 '13 at 15:46
  • 1
    If you see an image on the first frame, but none on the next there must be something staying behind from the previous frame. The most common problem is forgetting to clear the depth buffer - but you haven't. Next up are stencil buffers and blending (neither look like they're enabled to begin with). Maybe a new FBO handle is being generated each frame and you're running out? Another common problem is accumulating matrix transforms, but you have glLoadIdentity so should be no issue there. – jozxyqk Aug 15 '13 at 16:40
  • 1
    Many of these are less likely as it works without the FBO bound. glReadPixels is a fairly old function. A more common, and therefore possibly more supported method is rendering to a texture (glFramebufferTexture2D) and then using glGetTexImage to retrieve the data. A final thought... The glDrawBuffer spec doesn't have GL_COLOR_ATTACHMENT0 (http://www.opengl.org/sdk/docs/man/xhtml/glDrawBuffer.xml) but the glDrawBuffers spec does. This call shouldn't be needed anyway. Best of luck, I'm off to sleep. – jozxyqk Aug 15 '13 at 16:40
  • Although the answer did not solve my problem, the comments given DID HELP. The part that help was that a new FBO handle was being generated each frame. Thanks a lot for your help. – BaldDude Aug 19 '13 at 18:19