PDA

View Full Version : Fullscreen Texture Align with Frame Buffer



Mctittles
07-17-2011, 03:03 PM
I'm working on some fullscreen effects with a framebuffer, however I've ran into a snag where drawing to the framebuffer does not fill the texture completely. There is a blank border to the right and bottom of the texture. The texture size is what I set it too, it's just not drawing the data to the entire texture area. Here is the relevant code:




GLfloat textureCoordsOrtho [] = {0.0f,1.0f, 0.0f,0.0f, 1.0f,0.0f, 1.0f,1.0f};
GLfloat textureCoordsRevOrtho [] = {0.0f,0.0f, 0.0f,1.0f, 1.0f,1.0f, 1.0f,0.0f};
GLfloat verticesTL[] = {0.0f,0.0f, 0.0f,1.0f, 1.0f,1.0f, 1.0f,0.0f};
GLubyte indices[] = {0,1,2,3};

main {
...
createFramebuffer(fbo[0], fbtex[0]);
...
loop {
drawScene();
}
}
void createFramebuffer(GLuint& fbo, GLuint &fbtex) {


glGenTextures(1, &fbtex);
glBindTexture(GL_TEXTURE_2D, fbtex);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, currentWidth, currentHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbtex, 0);
{
GLenum status;
status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
switch (status) {
case GL_FRAMEBUFFER_COMPLETE:
break;
case GL_FRAMEBUFFER_UNSUPPORTED:
output << "Error: unsupported framebuffer format" << endl;
exit(0);
default:
output << "Error: invalid framebuffer config" << endl;
exit(0);
}
}
}


void drawScene(void) {
glClearColor(0.0,0.0,0.0,1.0f);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[0]);
glClearColor(1.0,0.0,0.0,1.0f);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, (GLsizei)currentWidth, (GLsizei)currentHeight, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);

glTexCoordPointer(2, GL_FLOAT, 0,textureCoordsRevOrtho);
glVertexPointer(2, GL_FLOAT, 0, verticesTL);
glDepthMask(GL_FALSE);


glPushMatrix();
glTranslatef(0.0,0.0,0.0);
glScalef(currentWidth,currentHeight,0.0f);
glBindTexture(GL_TEXTURE_2D, backTexture);
glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, indices);
glPopMatrix();



glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, (GLsizei)currentWidth, (GLsizei)currentHeight, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);

glTexCoordPointer(2, GL_FLOAT, 0,textureCoordsRevOrtho);
glVertexPointer(2, GL_FLOAT, 0, verticesTL);
glDepthMask(GL_FALSE);

glPushMatrix();
glTranslatef(0.0,0.0,0.0);
glScalef(currentWidth,currentHeight,0.0f);
glBindTexture(GL_TEXTURE_2D, fbtex[0]);
glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, indices);
glPopMatrix();

glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}


In this code, currentWidth and currentHeight is the width/height of the window. The reason there are duplicate glOrtho and glVertexePointer settings is because I was originally drawing 3d objects on the framebuffer that were getting cut off. I simplified it to use the fullscreen texture that I do later so I could see what was happening.
What happens when I run this is I get the texture drawn with a red showing to the right and bottom of it. The red color tells me it's drawing the entire frame buffer, but it is not drawing to the entire area. I set the regular buffer clearcolor to black and the framebuffer I clear red.
If I run the draw routine on the main buffer instead of the frame buffer I created, it fills the entire screen. I can't seem to find out why I'm getting a border when using the frame buffer.

Mctittles
07-17-2011, 03:32 PM
Ok, I figured it out. Here's what was going on.
The currentWidth/currentHeight variables are set to a default size when the window is created. A windows window is then created with these and shortly after the framebuffer/texture is created.
Whenever the window is resized it WM_SIZE system event is called and the currentWidth/currentHeight is reset to the size of the new window to keep things aligned.
The problem however is that the size set is not the entire window size but only the drawing area. WM_SIZE is also called once after window creation, setting the drawing area size to the new truncated size. This caused the frame buffer texture to be larger than the area being drawn to it and hence caused the extra space around it.

Mctittles
07-17-2011, 04:15 PM
Just another note here for anyone finding this post. If you need to render a scene to a frame buffer that is not the same size as the scene make sure to set glViewport to the size of the buffer texture:
glViewport(0, 0, 1024, 1024);

Then set it back when you go back to the main buffer.