LWJGL Forum
Programming => OpenGL => Topic started by: Wolftein on November 28, 2009, 19:05:56
-
Hello.. Im Using an fbo for rendering my scene to texture but i have a problem. When i render a normal texture to the screen, the texture renders fine, but when i render the fbo to the screen its render wierd, its like the fbo its rotated 90 degrees..
Opengl Property
// Enable texturing 2D
GL11.glEnable( GL11.GL_TEXTURE_2D );
// Calculate The Aspect Ratio Of The Window
GL11.glViewport( 0, 0, iViewPortX, iViewPortY );
GL11.glMatrixMode( GL11.GL_PROJECTION ); // Select The Projection Matrix
GL11.glLoadIdentity( ); // Reset The Projection Matrix
GL11.glOrtho( 0.0f, iWidth, iHeight, 0.0f, -1.0f, 1.0f );
GL11.glMatrixMode( GL11.GL_MODELVIEW ); // Select The Modelview Matrix
GL11.glLoadIdentity( );
// Disable ZBuffer
GL11.glDisable( GL11.GL_DEPTH_TEST );
GL11.glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
Render
static private void Renderizable( Texture Texture, int iX, int iY, float fSourceX,
float fSourceY, float fWidth, float fHeight )
{
// Get the texture property
int imageWidth = Texture.GetImageWidth( ), imageHeight = Texture.GetImageHeight( );
float imageClampedWidth = Texture.GetWidth( ), imageClampedHeight = Texture.GetHeight( );
// Bind the Texture for rendering.
Texture.Bind( );
// Generate Texture Mapping
float minX = (fSourceX / imageWidth) * imageClampedWidth;
float minY = (fSourceY / imageHeight) * imageClampedHeight;
float maxX = ((fSourceX + fWidth - 1.0f) / imageWidth) * imageClampedWidth;
float maxY = ((fSourceY + fHeight - 1.0f) / imageHeight) * imageClampedHeight;
// Direct Rendering to the opengl driver.
GL11.glBegin(GL11.GL_TRIANGLE_STRIP);
GL11.glTexCoord2f( minX, minY); GL11.glVertex2f( iX, iY );
GL11.glTexCoord2f( minX, maxY); GL11.glVertex2f( iX, iY + fHeight );
GL11.glTexCoord2f( maxX, minY); GL11.glVertex2f( iX + fWidth, iY );
GL11.glTexCoord2f( maxX, maxY); GL11.glVertex2f( iX + fWidth, iY + fHeight );
GL11.glEnd();
}
And here is the problem.
(http://img132.imageshack.us/img132/7687/fborendering.jpg)
-
GL11.glBegin(GL11.GL_TRIANGLE_STRIP);
GL11.glTexCoord2f( minX, minY); GL11.glVertex2f( iX, iY );
GL11.glTexCoord2f( minX, maxY); GL11.glVertex2f( iX, iY + fHeight );
GL11.glTexCoord2f( maxX, maxY); GL11.glVertex2f( iX + fWidth, iY + fHeight ); // invert these 2 lines
GL11.glTexCoord2f( maxX, minY); GL11.glVertex2f( iX + fWidth, iY ); // for proper CCW vertexes
GL11.glEnd();
-
GL11.glBegin(GL11.GL_TRIANGLE_STRIP);
GL11.glTexCoord2f( minX, minY); GL11.glVertex2f( iX, iY );
GL11.glTexCoord2f( minX, maxY); GL11.glVertex2f( iX, iY + fHeight );
GL11.glTexCoord2f( maxX, maxY); GL11.glVertex2f( iX + fWidth, iY + fHeight ); // invert these 2 lines
GL11.glTexCoord2f( maxX, minY); GL11.glVertex2f( iX + fWidth, iY ); // for proper CCW vertexes
GL11.glEnd();
Keeps doing the same thing.. Also when i render that fbo to another fbo, render good.
Fbo Class
public class RendererFrameBuffer
{
/**
* Fbo Texture
**/
private Texture pkTexture;
/**
* Fbo Viewport.
**/
private int iViewPortX;
private int iViewPortY;
/**
* Render Index
**/
private int iRenderBuffer;
/**
* Frame Index
**/
private int iFrameBuffer;
/**
* Scratch buffer for texture ID's
*/
private IntBuffer textureIDBuffer = BufferUtils.createIntBuffer( 1 );
/**
* Constructor
*
* @param texture
*/
public RendererFrameBuffer( Texture texture, int iViewPortX, int iViewPortY )
{
this.iViewPortX = iViewPortX;
this.iViewPortY = iViewPortY;
pkTexture = texture;
CreateFrameBuffer( );
}
/**
* Constructor
*
* @param width
* @param height
*/
public RendererFrameBuffer( int iWidth, int iHeight, int iViewPortX, int iViewPortY )
{
this( TextureManager.CreateNullTexture(iWidth, iHeight), iViewPortX, iViewPortY );
}
/**
* Create the FBO (Frame Buffer Object)
*/
private void CreateFrameBuffer( )
{
// create the int buffer for extraction
IntBuffer textureID = BufferUtils.createIntBuffer( 1 );
// create the frameObjectID
EXTFramebufferObject.glGenFramebuffersEXT(textureID);
iFrameBuffer = textureID.get( 0 );
// create the render buffer ID
EXTFramebufferObject.glGenRenderbuffersEXT(textureID);
iRenderBuffer = textureID.get( 0 );
// Generate the FrameBuffer Texture
try {
// Firt bind the frameBuffer
BindFrameBuffer( iFrameBuffer );
// create The texture Buffer
EXTFramebufferObject.glFramebufferTexture2DEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT,
EXTFramebufferObject.GL_COLOR_ATTACHMENT0_EXT,
GL11.GL_TEXTURE_2D,
pkTexture.GetID( ),
0 );
// Second bind the render buffer
BindRenderBuffer( iFrameBuffer );
// initialize depth renderBuffer
EXTFramebufferObject.glRenderbufferStorageEXT(EXTFramebufferObject.GL_RENDERBUFFER_EXT,
GL14.GL_DEPTH_COMPONENT24,
pkTexture.GetTextureWidth( ),
pkTexture.GetTextureHeight( ));
// initialize frame renderBuffer
EXTFramebufferObject.glFramebufferRenderbufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT,
EXTFramebufferObject.GL_DEPTH_ATTACHMENT_EXT,
EXTFramebufferObject.GL_RENDERBUFFER_EXT,
iRenderBuffer);
// check for any error
CheckErrorFrameBuffer( iFrameBuffer );
// release the frameBuffer
BindFrameBuffer( 0 );
} catch ( Exception ex )
{
System.out.println("An error ocurred when try to create a RendererFrameBuffer");
}
}
/**
* Start the rendering into the
* frame buffer
*/
public void Enable( )
{
// save the atributes of the client
GL11.glPushAttrib(GL11.GL_VIEWPORT_BIT);
// Set the Buffer Context property
GL11.glViewport( 0, 0, iViewPortX, iViewPortY );
GL11.glClearColor( 0.0f, 0.0f, 0.0f, 0.0f);
GL11.glClear( GL11.GL_COLOR_BUFFER_BIT );
GL11.glLoadIdentity( );
// bind the frameBuffer
BindFrameBuffer( iFrameBuffer );
}
/**
* Stop using the frameBuffer
*/
public void Update( )
{
// Flush to the screen
GL11.glFlush( );
// unbind the frameBuffer
BindFrameBuffer( 0 );
// restore the atributes
GL11.glPopAttrib( );
}
/**
* @return The buffer texture
*/
public Texture GetTexture( )
{
return pkTexture;
}
/**
* Bind the frameID like the current frameBuffer
* if's 0, then unbind it
*
* @param frameID
*/
private final void BindFrameBuffer( int frameID )
{
EXTFramebufferObject.glBindFramebufferEXT( EXTFramebufferObject.GL_FRAMEBUFFER_EXT, frameID );
}
/**
* Bind the renderID like the current renderBuffer
* if's 0, then unbind it
*
* @param renderID
*/
private final void BindRenderBuffer( int renderID )
{
EXTFramebufferObject.glBindRenderbufferEXT( EXTFramebufferObject.GL_RENDERBUFFER_EXT, renderID);
}
/**
* Check if the framebuffer has an
* error on creation
*
* @param frameID
*/
private final void CheckErrorFrameBuffer( int frameID )
{
// get the frameBufferError
int frameBuffer = EXTFramebufferObject.glCheckFramebufferStatusEXT( EXTFramebufferObject.GL_FRAMEBUFFER_EXT );
// print the error
switch( frameBuffer )
{
case EXTFramebufferObject.GL_FRAMEBUFFER_COMPLETE_EXT:
break;
case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
System.out.println( "FrameBuffer: " + frameID
+ ", has caused a GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT exception" );
case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
System.out.println( "FrameBuffer: " + frameID
+ ", has caused a GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT exception" );
case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
System.out.println( "FrameBuffer: " + frameID
+ ", has caused a GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT exception" );
case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
System.out.println( "FrameBuffer: " + frameID
+ ", has caused a GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT exception" );
case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
System.out.println( "FrameBuffer: " + frameID
+ ", has caused a GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT exception" );
case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
System.out.println( "FrameBuffer: " + frameID
+ ", has caused a GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT exception" );
default:
System.out.println( "Unexpected reply from glCheckFramebufferStatusEXT: " + frameID);
}
}
/**
* This is a helper function, that
* check if the FrameBufferObject
* are supported
*
* @return
*/
public final static boolean isSupported( )
{
return GLContext.getCapabilities().GL_EXT_framebuffer_object;
}
-
Is it 90 degrees off, or is it upside-down?
-
Is it 90 degrees off, or is it upside-down?
is upside-down.
-
OpenGL puts (0,0) of a texture at the bottom-left instead of the top-left. My guess is that when you load your normal textures you are flipping the image so that it looks right. However, when you render to a texture, this flip is not done. That is probably what is causing your problem.
-
Fixed!
/**
* Start the rendering into the
* frame buffer
*/
public void Enable() {
// save the atributes of the client
GL11.glPushAttrib(GL11.GL_VIEWPORT_BIT);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glPushMatrix();
// bind the frameBuffer
BindFrameBuffer(iFrameBuffer);
// Set the Buffer Context property
GL11.glViewport(0, 0, iViewPortX, iViewPortY);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, iViewPortX, 0, iViewPortY, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glLoadIdentity();
}
/**
* Stop using the frameBuffer
*/
public void Update() {
// Flush to the screen
//GL11.glFlush();
// unbind the frameBuffer
BindFrameBuffer(0);
// restore the atributes
GL11.glPopAttrib();
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glPopMatrix();
GL11.glMatrixMode(GL11.GL_MODELVIEW);
}
The problem was that in normal mode rendering from (0,0) starting from the top to (Width,Height)
GL11.glOrtho(0, iViewPortX, iViewPortY, 0, 1, -1);
And the correct FBO Rendering is
GL11.glOrtho(0, iViewPortX, 0, iViewPortY, 1, -1);
Rendering to fbo we have to flip the orthogonal. is this a bug or fbo work this way?
-
Did you read my comment above? :P
OpenGL's default behavior is to have the origin (0, 0) at the bottom-left instead of the top-left (for textures, view, etc.). Usually its handled by setting the texture coordinates so that (0.0, 0.0) is at the bottom-left part of the polygon instead of the top-left, although you can also handle it the way you are currently doing it (by changing the parameters to glOrtho() ).