Rendering Texture from a FrameBuffer gets unexpected result

Started by Andrevv_76, January 18, 2012, 13:19:37

Previous topic - Next topic

Andrevv_76

Hi,

I'm currently new on LWJGL and GL but I have done some simple examples and tests with success.

Now I'm trying to work with FBO's, rendering to texture and for that i created an example to find out how it works... it works but do not render the expected result to screen.
The example draws four different colored quads of 50x50 on top-left corner.
First I create an FBO with texture of 256x256, rendering the quads to FBO's texture and after that, rendering the FBO's texture to the top-left corner of the screen window with the same size as the texture is (256x256)
For comparison i draw the four quads direct to the screen to see the difference.

Now the problem; the quads rendered from FBO's texture (left on screen) are in a way scaled and mirrored I do not expected. What i want is that they look the same as the direct rendered quads (right on screen)

I have tried to play around with the Viewport or Ortho settings but nothing works.

Can anyone help me for that and can explain what's happen on FBO texture rendering and how I can get to the expected result?
(See Screenshot and example code below)

Thanks!

public class SimpleFrameBufferTest {
	
	private int frameBufferId;
	private int frameBufferTexId;
	
	public void start() {
		
		try {
			Display.setDisplayMode( new DisplayMode( 800, 600 ) );
			Display.setTitle( "QuadExample" );
			Display.create();
		} catch ( LWJGLException e ) {
			e.printStackTrace();
			System.exit( 0 );
		}
		 
		// init OpenGL
		GL11.glMatrixMode( GL11.GL_PROJECTION );
		GL11.glLoadIdentity();
		GL11.glOrtho( 0, 800, 600, 0, -1, 1 );
		GL11.glMatrixMode( GL11.GL_MODELVIEW );
		
		
		createFrameBuffer();	
		// draw to frame buffer
		//glPushMatrix();
		glPushAttrib( GL_VIEWPORT_BIT );
		glViewport (0, 0, 256, 256);
		glLoadIdentity();
		
		glBindTexture(GL_TEXTURE_2D, 0);								
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferId);	
		
		// clear the frame buffer with dark gray to see the whole texture on screen
		glClearColor ( 0.1f, 0.1f, 0.1f, 0.0f ); 
		glClear (GL_COLOR_BUFFER_BIT);			
		
		draw4Quads();
		
		glPopAttrib();
		 
		
		while (!Display.isCloseRequested()) {
			Display.sync( 50 );
			render();
			Display.update();
		}
		 
		Display.destroy();
	}

	private void render() {
		// render to screen
		

		// first render the frame buffer texture to screen!
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);					// switch to rendering on the screen
		
		glViewport (0, 0, 800, 600);									// set The Current Viewport
		glLoadIdentity();
		
		glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
		glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);			// Clear Screen to black
		glEnable(GL_TEXTURE_2D);										// enable texturing
		glBindTexture(GL_TEXTURE_2D, frameBufferTexId);					// bind our FBO texture
																		
		glColor4f( 1.0f, 1f, 1.0f, 0f );
		glClear (GL_COLOR_BUFFER_BIT);		
		glBegin( GL11.GL_QUADS );
		{
			glTexCoord2f( 0, 0 );
			glVertex2f( 0, 0 );
			
			glTexCoord2f( 1, 0 );
			glVertex2f( 256, 0 );
			
			glTexCoord2f( 1, 1 );
			glVertex2f( 256, 256 );
			
			glTexCoord2f( 0, 1 );
			glVertex2f( 0, 256 );
		}
		glEnd();
		glDisable( GL_TEXTURE_2D );
		
		// now draw the 4 quads  directly to screen to see the differences!
		
		glTranslatef( 300, 0, 0 );
		glColor4f( 0.1f, 0.1f, 0.1f, 0.0f ); 
		
		glBegin( GL11.GL_QUADS );
		glVertex2f( 0, 0 );
		glVertex2f( 256, 0 );
		glVertex2f( 256, 256 );
		glVertex2f( 0, 256 );
		glEnd();
		
		draw4Quads();

		glFlush ();
	}
	
	private void draw4Quads() {
		// draw 4 quads
		glBegin( GL11.GL_QUADS );
		{
			glColor4f( 1f, 1f, 1f, 0f );
			
			glVertex2f( 0, 0 );
			glVertex2f( 50, 0 );
			glVertex2f( 50, 50 );
			glVertex2f( 0, 50 );
			
			glColor4f( 1f, 0f, 0f, 0f );
			
			glVertex2f( 50, 0 );
			glVertex2f( 100, 0 );
			glVertex2f( 100, 50 );
			glVertex2f( 50, 50 );
			
			glColor4f( 0f, 1f, 0f, 0f );
			
			glVertex2f( 50, 50 );
			glVertex2f( 100, 50 );
			glVertex2f( 100, 100 );
			glVertex2f( 50, 100 );
			
			glColor4f( 0f, 0f, 1f, 0f );
			
			glVertex2f( 0, 50 );
			glVertex2f( 50, 50 );
			glVertex2f( 50, 100 );
			glVertex2f( 0, 100 );
		}
		glEnd();
	}
	
	private void createFrameBuffer() {
		frameBufferId = EXTFramebufferObject.glGenFramebuffersEXT();                                         // create a new framebuffer
		frameBufferTexId = glGenTextures();                                               // and a new texture used as a color buffer
		 
		EXTFramebufferObject.glBindFramebufferEXT( EXTFramebufferObject.GL_FRAMEBUFFER_EXT, frameBufferId );                        // switch to the new framebuffer
		 
		// initialize color texture
		glBindTexture(GL_TEXTURE_2D, frameBufferTexId);                                   // Bind the colorbuffer texture
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);               // make it linear filterd
		glTexImage2D(
			GL_TEXTURE_2D, 
			0, 
			GL_RGBA, 
			256, 
			256, 
			0,
			GL_RGBA, 
			GL_UNSIGNED_BYTE, 
			(java.nio.ByteBuffer) null
		);  
		EXTFramebufferObject.glFramebufferTexture2DEXT( 
			EXTFramebufferObject.GL_FRAMEBUFFER_EXT,
			EXTFramebufferObject.GL_COLOR_ATTACHMENT0_EXT,
			GL_TEXTURE_2D, 
			frameBufferTexId, 
			0 
		); 

		int framebuffer = EXTFramebufferObject.glCheckFramebufferStatusEXT( EXTFramebufferObject.GL_FRAMEBUFFER_EXT );
		switch ( framebuffer ) {
		    case EXTFramebufferObject.GL_FRAMEBUFFER_COMPLETE_EXT:
		        break;
		    case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
		        throw new RuntimeException( "FrameBuffer: " + frameBufferId
		                + ", has caused a GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT exception" );
		    case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
		        throw new RuntimeException( "FrameBuffer: " + frameBufferId
		                + ", has caused a GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT exception" );
		    case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
		        throw new RuntimeException( "FrameBuffer: " + frameBufferId
		                + ", has caused a GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT exception" );
		    case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
		        throw new RuntimeException( "FrameBuffer: " + frameBufferId
		                + ", has caused a GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT exception" );
		    case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
		        throw new RuntimeException( "FrameBuffer: " + frameBufferId
		                + ", has caused a GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT exception" );
		    case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
		        throw new RuntimeException( "FrameBuffer: " + frameBufferId
		                + ", has caused a GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT exception" );
		    default:
		        throw new RuntimeException( "Unexpected reply from glCheckFramebufferStatusEXT: " + framebuffer );
		}
		
		EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, 0);  
	}
	
	public static void main( String[] argv ) {
		SimpleFrameBufferTest example = new SimpleFrameBufferTest();
		System.setProperty( "org.lwjgl.util.Debug", "true" );
		example.start();
	}

}