Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenGL framebuffer: can clear it, but can't draw to it

On a Mac, I've got an OpenGL setup that is working just fine apart from framebuffers - texturing works, etc. So I know that texturing is enabled, I have a valid context, etc. All works flawlessly until I try to create a framebuffer.

I created a framebuffer with glGenFramebuffers, glBindFramebuffer, and glFramebufferTexture2D, and glCheckFramebufferStatus is returning GL_FRAMEBUFFER_COMPLETE. If I then call glClear, followed by a call to glGetTexImage, the returned data shows that the glClear acted on the texture bound to the framebuffer just as it should. I can set glClearColor to anything I want, and the glClear sets the texture data correctly.

But that's where the good news stops. I can't draw anything into the framebuffer, whether I use VBOs or glBegin/glEnd. The texture data from the texture bound to the framebuffer is untouched by the draw calls (though the glClear results still appear). This is all true even if I call glFlush and glFinish before the glGetTexImage call. Also, glGetError is returning no error as to any of my calls.

I've posted below some sample code that I added at a relevant point in the program just to try to work on this issue, in case that gives anyone an idea. (This doesn't include the glClear call, but I know from separate testing at the same point that that works OK).

    glGenFramebuffers(1, &fb);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbTexID, 0);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); 
if(status != GL_FRAMEBUFFER_COMPLETE)
    Debugger(); 

glEnable(GL_TEXTURE_2D); 
glCullFace(GL_NONE); 
glGenTextures(1,(GLuint*)&tex); 
glBindTexture(GL_TEXTURE_2D,tex); 
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,1024,1024,0,GL_RGBA,GL_UNSIGNED_BYTE,NULL); 
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR );
glTexParameterf( 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 );

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1024, 1024, 0, -5000, 5000); 
glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); 
glViewport(0, 0, 1024, 1024); 
glColor4f(1,1,1,1); 
glBegin(GL_TRIANGLES);
    glTexCoord2f(0, 0);
    glVertex2f(0, 0);
    glTexCoord2f(1, 0);
    glVertex2f(1024, 0);
    glTexCoord2f(0, 1);
    glVertex2f(0, 1024);
glEnd();
glFlush();
glFinish(); 
unsigned char *dd = new unsigned char[1024*1024*4]; 
glBindTexture(GL_TEXTURE_2D, fbTexID); //I've tried calling glBindFramebuffer(GL_FRAMEBUFFER,0) before this bind - makes no difference
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, dd);
delete dd; 
like image 729
RedMarbleGames Avatar asked Sep 06 '11 18:09

RedMarbleGames


2 Answers

Your texture did not work because it was bound! You cannnot have a bound texture work on a FBO as a rendertarget! This is something that isn't very documented, but makes sense when you think about it The driver developers need some safeguards too, just in case you do something weird like reading and writing to the same texture at the same time

like image 62
gonzo Avatar answered Oct 09 '22 01:10

gonzo


OK, answered my own question. It seems that the texture you generate to be the surface that the frame buffer draws to must be generated after the frame buffer is generated. So, this works:

glGenFramebuffers...
glBindFramebuffer...
glGenTextures...
glBindTexture...
glTexParameterf etc.
glFramebufferTexture2D...

but this does not:

glGenTextures...
glBindTexture...
glGenFramebuffers
glBindFramebuffer...
glFramebufferTexture2D...

I don't see this addressed anywhere, and it seems surprising, but my code went from not working to working just by moving the generation of the texture.

like image 26
RedMarbleGames Avatar answered Oct 09 '22 01:10

RedMarbleGames