PDA

View Full Version : FBO scaling problem



Peter Maarssen
09-26-2008, 12:16 PM
I'm sorry about all the questions, but this one has been bothering for some hours now :(

Why is it that when I display my fbo attached texture, it is all stretched vertically? When I render directly to the framebuffer all is fine..

Here is OpenGl init code (2D as you can see):


void initGL() {
glGetIntegerv(GL_VIEWPORT, vPort.ptr);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

glOrtho(0f, vPort[2], vPort[3],0f, -1f, 1f);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glDisable(GL_DEPTH_TEST);
glDisable(GL_SCISSOR_TEST);
glDisable(GL_LIGHTING);
glDisable(GL_DITHER);

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(0.0f);
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glAlphaFunc(GL_GREATER,0.1);
glEnable(GL_ALPHA_TEST);
glEnable(GL_BLEND);
glShadeModel(GL_FLAT);
glPolygonMode(GL_FRONT,GL_FILL);
}


Here the FBO binding unbinding code:


public void bindFbo()
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo);
glPushAttrib(GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT);
glViewport( 0, 0, fbo.w, fbo.h);
}

public void unbindFbo()
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glPopAttrib();
}


And last my texture display code:


glBindTexture(GL_TEXTURE_2D, fbo.texture);
glLoadIdentity();
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2d(1f,1f); glVertex3f(fbo.w,0f,0f);
glTexCoord2d(0f,1f); glVertex3f(0f,0f,0f);
glTexCoord2d(1f,0f); glVertex3f(fbo.w,fbo.h,0f);
glTexCoord2d(0f,0f); glVertex3f(0f,fbo.h,0f);
glEnd();

trinitrotoluene
09-26-2008, 12:45 PM
I am not sure for this one, but the parameters of glOrtho seem not
in the right order.

try that glOrtho(0f, vPort[2], 0f,vPort[3], -1f, 1f);

Peter Maarssen
09-26-2008, 01:14 PM
Thanks ;)
Why isn't it the right order?
I'd like the top left pixel to be (0,0).
thus I set right and bottom to w and h.
Or am I getting this wrong?

void glOrtho( GLdouble left,
GLdouble right,
GLdouble bottom,
GLdouble top,
GLdouble nearVal,
GLdouble farVal);

trinitrotoluene
09-26-2008, 02:19 PM
Then your parameters for glOrtho are correct. Then the only possible issue I see is your texture size vs texture coordinates you give when you draw your rectangle.

Peter Maarssen
09-26-2008, 02:55 PM
Texture size is 1024*1024, screen is 1024*768.
fbo.w,fbo.h=resp 1024,1024 :)

trinitrotoluene
09-26-2008, 03:10 PM
Ok you have a square texture and you draw a rectangle, so texture deformation occur. Try to draw a square and the result will be correct or modify your texture coord on your rectangle.

Peter Maarssen
09-26-2008, 05:34 PM
I draw a square :

glBegin(GL_TRIANGLE_STRIP);
glTexCoord2d(1f,1f); glVertex3f(fbo.w,0f,0f);
glTexCoord2d(0f,1f); glVertex3f(0f,0f,0f);
glTexCoord2d(1f,0f); glVertex3f(fbo.w,fbo.h,0f);
glTexCoord2d(0f,0f); glVertex3f(0f,fbo.h,0f);
glEnd();

fbo.w=fbo.h=1024

trinitrotoluene
09-26-2008, 06:02 PM
Ok I understand now, then draw a rectangle.
I think with your code some part of the square is off screen.
Try this:


glBegin(GL_TRIANGLE_STRIP);
glTexCoord2d(1f,1f); glVertex3f(1024,0f,0f);
glTexCoord2d(0f,1f); glVertex3f(0f,0f,0f);
glTexCoord2d(1f,0f); glVertex3f(1024,768,0f);
glTexCoord2d(0f,0f); glVertex3f(0f,768,0f);
glEnd();


This draw a rectangle the same size of your viewport. It
respect the width/height ratio of your viewport.

Peter Maarssen
09-27-2008, 06:20 AM
But wouldn't this mean that I'd be scaling the image? As it is a 1-0n-1 copy this shouldn't be necessary.

btw. do you have any idea what I did wrong my other post ;)

trinitrotoluene
09-27-2008, 08:28 AM
When you draw in your fbo what is the parameter of glOrtho:

glOrtho(0f, vPort[2], vPort[3],0f, -1f, 1f);
or
glOrtho(0f, fbo.w, fbo.h,0f, -1f, 1f);

In the first case, maybe the image in your texture will appear stretched vertically because the width/height (vPort[2]/vPort[3]) ratio of your projection don't match the width/height (fbo.w/fbo.h) ratio of your texture.

Peter Maarssen
09-27-2008, 03:18 PM
Yeah, I tried setting the glOrtho to the correct width/height, but even if I entered really strange numbers it kept staying the same. I think I know what the problem is. An fbo shares the context with the framebuffer, so it needs to set a lot more stuff (or so I read).
But as I had it with GL_TEXTURE_2D, I went for GL_TEXTURE_RECTANGLE_ARB and now I have a white texture (;_;)

I added:
glEnable(GL_TEXTURE_RECTANGLE_ARB);

changed the render to:


glBegin(GL_QUADS);
glTexCoord2f(0f, 0f);glVertex2f(0f, 0f);
glTexCoord2f(_width, 0f);glVertex2f(_width, 0f);
glTexCoord2f(_width, _height);glVertex2f(_width, _height);
glTexCoord2f(0f, _height);glVertex2f(0f, _height);
glEnd();


And of course changed the target in the code from my first post.
Why is it white? :D

dletozeun
09-27-2008, 03:35 PM
I think I know what the problem is. An fbo shares the context with the framebuffer, so it needs to set a lot more stuff (or so I read).


What do you mean? I don't follow you.

I don't think your problem is the posted code snippet which is really simple.

As far as I understand you, with a POT sized texture you see correctly the texture but not with a NPOT texture?

What is the problem with glOrtho?

Peter Maarssen
09-27-2008, 04:25 PM
Thanks for your reply. As I describe in my first post, I have trouble (got scaled vertically) with my POT FBO TEXTURE_2D and thus tried a TEXTURE_RECTANGLE. As these don't need to be POT I just made it the size I originally wanted it to be, my window size: 1024*768. But after adapting my code for displaying the TEXTURE_RECTANGLE it just shows a white texture.

Peter Maarssen
09-28-2008, 07:04 AM
Here are my solutions:

binding/unbinding an fbo:


public void bindFbo()
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo);
if(_width!=vPort[2] || _height!=vPort[3]){
glViewport(0, 0, _width, _height);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0f, _width, _height,0f, -1f, 1f);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
}
}

public void unbindFbo()
{
if(_width!=vPort[2] || _height!=vPort[3]){
glViewport( 0, 0, vPort[2], vPort[3]);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}


rendering an texture_rectangle:


glEnable(GL_TEXTURE_RECTANGLE_ARB);
//TEXTURE_RECTANGLE has priority above TEXTURE_2D
glBegin(GL_QUADS);
glTexCoord2f(0f, _height);glVertex2f(0f, 0f);
glTexCoord2f(_width, _height);glVertex2f(_width, 0f);
glTexCoord2f(_width, 0f);glVertex2f(_width, _height);
glTexCoord2f(0f, 0f);glVertex2f(0f, _height);
glEnd();
glDisable(GL_TEXTURE_RECTANGLE_ARB);
//so if all is correct here it should fall back to TEXTURE_2D


Hope this helps somebody else ;)