[Help]: FBO Issues.

Started by Wolftein, November 28, 2009, 19:05:56

Previous topic - Next topic

Wolftein

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.


broumbroum

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();

Wolftein

Quote from: broumbroum on November 28, 2009, 23:27:39
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;
    }

Fool Running

Is it 90 degrees off, or is it upside-down?
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D

Wolftein


Fool Running

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.
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D

Wolftein

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?

Fool Running

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() ).
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D