Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 10 of 12

Thread: FBO render to texture using VBO

Hybrid View

  1. #1
    Junior Member Newbie
    Join Date
    Nov 2012
    Posts
    7

    FBO render to texture using VBO

    I'm using OpenTK and am trying to render to an FBO texture as per the tutorial here:

    http://www.opentk.com/node/397
    http://www.opentk.com/files/Program_0.cs

    This example uses immediate mode to draw triangles to the texture but I'd like to use VBO. I'm very new to OpenGL and have my rendering working using VBO but I don't know how to replace the random triangle rendering in this tutorial with DrawElements using VBO.

    Does anyone know of a tutorial which uses VBO to render to a FBO?

  2. #2
    Junior Member Newbie
    Join Date
    Nov 2012
    Posts
    7
    Alternatively my code is below if someone is able to see the problem.

    My working VBO render (renders my world as expected):

    Code :
    protected override void OnRenderFrame_VBO(FrameEventArgs e)
    {
        base.OnRenderFrame(e);
        GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
     
        // Camera.
        Matrix4 lookat = Matrix4.LookAt(this.Camera, this.Target, this.LocalUp);
        GL.MatrixMode(MatrixMode.Modelview);
        GL.LoadMatrix(ref lookat);
        GL.Viewport(0, 0, this.Width, this.Height);
        double aspect_ratio = this.Width / (double)this.Height;
        OpenTK.Matrix4 perspective = OpenTK.Matrix4.CreatePerspectiveFieldOfView(fov, (float)aspect_ratio, 1, 25000);
        GL.MatrixMode(MatrixMode.Projection);
        GL.LoadMatrix(ref perspective);
     
        // Colour Array.
        GL.BindBuffer(BufferTarget.ArrayBuffer, buffers.ColoursBufferId);
        GL.ColorPointer(4, ColorPointerType.UnsignedByte, sizeof(int), IntPtr.Zero);
        GL.EnableClientState(ArrayCap.ColorArray);
        GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
     
        // Vertex Data Array.
        GL.BindBuffer(BufferTarget.ArrayBuffer, buffers.VertexDataArrayBufferId);
        GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(world.Vertices.Length * Vector3.SizeInBytes), world.Vertices, BufferUsageHint.StreamDraw);
        GL.VertexPointer(3, VertexPointerType.Float, Vector3.SizeInBytes, IntPtr.Zero);
        GL.EnableClientState(ArrayCap.VertexArray);
        GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
     
        // Index Array.
        GL.BindBuffer(BufferTarget.ElementArrayBuffer, buffers.ElementIndicesBufferId);
     
        GL.DrawElements(BeginMode.Triangles, world.Indices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);
        this.SwapBuffers();
    }

    And my FBO code which is not working (renders all red):

    Code :
    public static void OnLoad(EventArgs e)
    {
     
        <<Working VBO creation logic here>>
     
        // Create Color Tex
        GL.GenTextures(1, out buffers.ColourTexture);
        GL.BindTexture(TextureTarget.Texture2D, buffers.ColourTexture);
        GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, this.OffscreenFBOWidth, this.OffscreenFBOHeight, 0, PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero);
        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToBorder);
        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToBorder);
        // GL.Ext.GenerateMipmap( GenerateMipmapTarget.Texture2D );
     
        // Create a FBO and attach the textures
        GL.Ext.GenFramebuffers(1, out buffers.FBOHandle);
        GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, buffers.FBOHandle);            
        GL.Ext.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext, TextureTarget.Texture2D, buffers.ColourTexture, 0);
     
        if (GL.Ext.CheckFramebufferStatus(FramebufferTarget.FramebufferExt) != FramebufferErrorCode.FramebufferCompleteExt)
        {
            throw new Exception(GL.Ext.CheckFramebufferStatus(FramebufferTarget.FramebufferExt).ToString());
        }
     
        GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0);
        GL.BindTexture(TextureTarget.Texture2D, 0);
    }
     
    protected override void OnRenderFrame(FrameEventArgs e)
    {
        base.OnRenderFrame(e);
        GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
     
        // Camera.
        Matrix4 lookat = Matrix4.LookAt(this.Camera, this.Target, this.LocalUp);
        GL.MatrixMode(MatrixMode.Modelview);
        GL.LoadMatrix(ref lookat);
        GL.Viewport(0, 0, this.OffscreenFBOWidth, this.OffscreenFBOHeight);
        double aspect_ratio = Width / (double)Height;
        OpenTK.Matrix4 perspective = OpenTK.Matrix4.CreatePerspectiveFieldOfView(fov, (float)aspect_ratio, 1, 25000);
        GL.MatrixMode(MatrixMode.Projection);
        GL.LoadMatrix(ref perspective);
     
        // Bind FBO.
        GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, buffers.FBOHandle);
     
        GL.ClearColor(0f, 0f, .7f, 0f);
        GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
     
        // Render VBO.
        // Colour Array. 
        GL.BindBuffer(BufferTarget.ArrayBuffer, buffers.ColoursBufferId);
        GL.ColorPointer(4, ColorPointerType.UnsignedByte, sizeof(int), IntPtr.Zero);
        GL.EnableClientState(ArrayCap.ColorArray);
        GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
     
        // Vertex Data Array.
        GL.BindBuffer(BufferTarget.ArrayBuffer, buffers.VertexDataArrayBufferId);
        GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(world.Vertices.Length * Vector3.SizeInBytes), world.Vertices, BufferUsageHint.StreamDraw);
        GL.VertexPointer(3, VertexPointerType.Float, Vector3.SizeInBytes, IntPtr.Zero);
        GL.EnableClientState(ArrayCap.VertexArray);
        GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
     
        // Index Array.
        GL.BindBuffer(BufferTarget.ElementArrayBuffer, buffers.ElementIndicesBufferId);
        GL.DrawElements(BeginMode.Triangles, world.Indices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);   
     
        GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0);            
     
        GL.ClearColor(.4f, 0f, 0f, 0f);
        GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);            
        GL.Enable(EnableCap.Texture2D);
     
        GL.BindTexture(TextureTarget.Texture2D, 0);           
     
        GL.PushMatrix();
        {
            GL.Translate(-1.1f, 0f, 0f);
            GL.BindTexture(TextureTarget.Texture2D, buffers.ColourTexture);            
     
            GL.Begin(BeginMode.Quads);
            {
                GL.TexCoord2(0f, 1f);
                GL.Vertex2(-1.0f, 1.0f);
                GL.TexCoord2(0.0f, 0.0f);
                GL.Vertex2(-1.0f, -1.0f);
                GL.TexCoord2(1.0f, 0.0f);
                GL.Vertex2(1.0f, -1.0f);
                GL.TexCoord2(1.0f, 1.0f);
                GL.Vertex2(1.0f, 1.0f);
            }
            GL.End();                
        }
        GL.PopMatrix();            
     
        this.SwapBuffers();
    }

    I'll take any pointers...

  3. #3
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,106
    I think your quad points are mixed up

    try
    Code :
      GL.TextCoord2(0.0f,0.0f);
      GL.Vertex2(-1.0f,-1.0f);
      GL.TextCoord2(1.0f,0.0f);
      GL.Vertex2(1.0f,-1.0f);
      GL.TextCoord2(1.0f,1.0f);
      GL.Vertex2(1.0f,1.0f);
      GL.TextCoord2(0.0f,1.0f);
      GL.Vertex2(-1.0f,1.0f);

  4. #4
    Junior Member Newbie
    Join Date
    Nov 2012
    Posts
    7
    Just tried your code but still no joy.

    Thanks for the suggestion I really appreciate it.

  5. #5
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,106
    If you don't bind a texture for the quad draw but just set a colour does the quad draw in the colour?
    eg render a blue quad over the background.

    Code :
     
    GL.Begin(BeginMode.Quads);
      GL.Color3f(0.0f,1.0f,0.0f); 
      GL.Vertex2(-1.0f, 1.0f);
      GL.Vertex2(-1.0f, -1.0f);
      GL.Vertex2(1.0f, -1.0f);
      GL.Vertex2(1.0f, 1.0f); 
    GL.End();

    This will at least remove the quad draw as a problem

  6. #6
    Junior Member Newbie
    Join Date
    Nov 2012
    Posts
    7
    Good idea.

    Code :
    GL.PushMatrix();
    {
        GL.BindTexture(TextureTarget.Texture2D, 0);           
        GL.Begin(BeginMode.Quads);
        {
            GL.Color3(0f, .6f, 0f);
            GL.Vertex2(-1.0f, -1.0f);
            GL.Vertex2(1.0f, -1.0f);
            GL.Vertex2(1.0f, 1.0f);
            GL.Vertex2(-1.0f, 1.0f);
        }
        GL.End();
     
        GL.Begin(BeginMode.Quads);
        {
            GL.Color3(0f, 0f, .6f);
            GL.Vertex2(-1.0f, 1.0f);
            GL.Vertex2(-1.0f, -1.0f);
            GL.Vertex2(1.0f, -1.0f);
            GL.Vertex2(1.0f, 1.0f);
        }
        GL.End();           
    }
    GL.PopMatrix();

    I've tried the above (drawing the quad as you suggested and how it was originally) but I don't see either quad.

    That's great though. Now I know it's not a FBO issue. Thanks.

    I guess I need to reset the view after my VBO rendering. I thought this was achieved with GL.LoadIdentity() but adding GL.LoadIdentity() makes no difference.

  7. #7
    Junior Member Newbie
    Join Date
    Nov 2012
    Posts
    7
    Ok, finally got the quad rendering on screen.

    Once the VBO has been drawn to the FBO I'm calling GL.LoadIdentity() before and after applying a Modelview Matrix.

    Code :
    // Draw VBO to FBO.
    GL.DrawElements(BeginMode.Triangles, world.Indices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);
    // Stop rendering to FBO.
    GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0);
     
    // Reset Matrix.
    GL.LoadIdentity();
    GL.MatrixMode(MatrixMode.Modelview);
    GL.LoadIdentity();
     
    // Draw FBO as texture.
    GL.ClearColor(0f, Convert.ToSingle(this.rand.NextDouble()), 1f, 0f);    // Greenish.
    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
     
    GL.PushMatrix();
    {
        GL.BindTexture(TextureTarget.Texture2D, Rendering.Controller.buffers.ColourTexture);
        GL.Begin(BeginMode.Quads);
        {
            GL.TexCoord2(0.0f, 0.0f);
            GL.Vertex2(-1.0f, -1.0f);
            GL.TexCoord2(1.0f, 0.0f);
            GL.Vertex2(1.0f, -1.0f);
            GL.TexCoord2(1.0f, 1.0f);
            GL.Vertex2(1.0f, 1.0f);
            GL.TexCoord2(0.0f, 1.0f);
            GL.Vertex2(-1f, 1.0f);
        }
        GL.End();
    }
    GL.PopMatrix();

    The FBO isn't rendering full-screen and the colours are all a shade of green, but I think that's progress.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •