Main Menu

FBO and OpenGL

Started by ashwin_9891, June 17, 2009, 12:11:36

Previous topic - Next topic

ashwin_9891

Hiiiii guys.. I am a noob to OpenGL Programming.. However, I am stuck with a project where in i need to use FBOs.. Please can you provide me code fragments of using FBOs as render targets(say u draw a triangle in it attaching shaders) and display the FBO on the screen(using it as texture ??).. please clarify... thanks..  :)

Kai

Hi,

you ask for much more than can be explained in a single post, so I suggest you to have a look at http://www.songho.ca/opengl/gl_fbo.html.
It provides good explanation of this topic as well as a sample project in C++.

ashwin_9891

Thanks for the reply. However, the problem is i am stuck with the programming part. Please explain. Thanks. I want to draw a triangle in a FBO and show it on the screen. How do i achieve this ??

Kai

Things to do in order:
- Create texture with glGenTextures
- Create FBO with glGenFramebuffersEXT
- "Activate" FBO with glBindFramebufferEXT
- Attach texture to FBO with glFramebufferTexture2DEXT
- Check FBO status with glCheckFramebufferStatusEXT
- Draw a triangle (you should know how to do that, at least)
- "Deactivate" FBO with glBindFramebufferEXT (set buffer id to 0)
- Bind texture with glBindTexture
- Draw a textured quad (with texturing (2D) enabled and assigned texture co-ordinates)

If you are new to OpenGL, as you said, and don't know DirectX either, I suggest you first start to learn the "basics" of OpenGL before struggling with FBOs and such, because you would not learn much from posted source code that was given to you in order to work as a copy-and-paste solution.

ashwin_9891

Hi.. The problem is my project work is on that only.. So no other go.. I have to learn up about FBOs.. So, The triangle drawing part i think it can be done using glVertexAttribPointer and glDrawArrays rite ?? and also is it possible to attach shaders(vertex shaders) and program objects with FBOs ?? Please explain.. Thanks for the reply.. That cleared a lot of things.. thanks :)

Ciardhubh

Quote from: ashwin_9891 on June 19, 2009, 08:16:42
So, The triangle drawing part i think it can be done using glVertexAttribPointer and glDrawArrays rite ?? and also is it possible to attach shaders(vertex shaders) and program objects with FBOs ??

Once the FBO has been bound, rendering is done the same way as it is without an FBO. Drawing and shaders work the same on FBOs as they do without.

ashwin_9891

Thanks for the explanation. That did help a lot. So once the FBO is set it is as good as my window buffer so untill i do a texture mapping onto the screen rite ??

ashwin_9891

Hiiii.. My project involves a few FBO on which some rendering is done and i need to display them.. So i will be basically binding them and unbinding them continuously.. will that create any problems ?? As in i have linked some programs with the FBO and now there is a unbind and then i bind it.. will they still be there on the texture when i draw it onto screen ?? I am so confused.. please explain..

Kai

QuoteSo i will be basically binding them and unbinding them continuously.. will that create any problems ??
If by "problems" you mean "side effects" then binding a FBO will alter the way the GL renders primitives. Instead of being rendered in the window's framebuffer they will be rendered into texture(s) that is/are attached to the FBO.
To clear things up here: You do not render into or onto an FBO; you render onto the textures that are attached to the FBO.
For a deeper understanding of FBOs, that you obviously are seeking, it is worth reading the spec of that extension http://www.opengl.org/wiki/GL_EXT_framebuffer_object.

QuoteAs in i have linked some programs with the FBO and now there is a unbind and then i bind it.. will they still be there on the texture when i draw it onto screen ??
You do not "link" shader programs to FBOs. FBOs are in that way very non-invasive. They only affect where primitives will be rendered to and none else. Of course, as applied above, if you want to learn more, please read the spec. It will give you information about which textures you can actually render to and such.


ashwin_9891

Thanks for those replies.. It is posible to use vertex shaders with FBOs right ?? If am to maintain a lot of FBOs, i heard that switching FBOs is a tough job, than switching buffers.. So wat would you suggest ?? one FBO with many render buffers and textures ? or many FBOs itself ? Please explain..

Kai

Quotei heard that switching FBOs is a tough job, than switching buffers..
What exactly do you mean with "buffers"?
And: Switching FBOs is done by just one call to glBindFramebuffer.

QuoteSo wat would you suggest ?? one FBO with many render buffers and textures ? or many FBOs itself ?
One FBO is sufficient. If you need depth in your scene that is being rendered to the FBO, you need a depth render buffer, otherwise you just need to attach the rendered-to textures to the FBO.
You can call glFramebufferTexture2D as many times as you want to attach different textures to the same FBO.
If you want to render to textures of a different internal format than having separate FBOs for each type of format is the better way, because reorganization of the internal texture representation has to be done which is costly if you switch from one texture format to another.

If you could give it a try and implement what you're up to, now, you will certainly come across many other issues that need to be solved as well and that's why I previously mentioned that starting with "easy" OpenGL examples would be the better way than to dive right into that FBO thingy - despite of the fact that your project's work "only" involves FBOs.

ashwin_9891

Hiiii.. thanks for that reply.. i will go ahead with a single FBO and multiple renders.. hey please check this code bit

int DrawGLScene(GLvoid)                        
{
   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);

   glPushAttrib(GL_VIEWPORT_BIT);
   glScissor(0, 0, width, height);
   glViewport(0,0,width,height);
   glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
   glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

   glLoadIdentity();

   glTranslatef(0.0f,0.0f,-2.0f);

   GLfloat vVertices[] = {  0.0f,  0.5f, 0.0f,
                           -0.5f, -0.5f, 0.0f,
                            0.5f, -0.5f, 0.0f };
   glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
   glUseProgram ( programObject ); // to this object i have attached a vertex and fragment shader
   glVertexAttribPointer ( 0, 3, GL_FLOAT, GL_FALSE, 0, vVertices );
   glEnableVertexAttribArray ( 0 );
   glDrawArrays ( GL_TRIANGLES, 0, 3 );
   
   glPopAttrib();
   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

   
   glClearColor(0.0f, 0.0f, 0.2f, 0.5f);
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);   // Clear Screen And Depth Buffer
   
   
   glLoadIdentity();
   
   // Now bind the first texture to use it
   glBindTexture(GL_TEXTURE_2D, img);
   glEnable(GL_TEXTURE_2D);

   glTranslatef(-1.2f,0.0f,-2.0f);

   glColor4f(1.0f,1.0f,1.0f,1.0f);

      glBegin(GL_QUADS);
      glTexCoord2f(0.0f, 1.0f); glVertex3f(-0.5f, -0.5,  0.5);
   glTexCoord2f(1.0f, 1.0f); glVertex3f( 0.5, -0.5,  0.5);
   glTexCoord2f(1.0f, 0.0f); glVertex3f( 0.5,  0.5,  0.5);
   glTexCoord2f(0.0f, 0.0f); glVertex3f(-0.5,  0.5,  0.5);
   glEnd();

      glLoadIdentity();

   glDisable(GL_TEXTURE_2D);

   return TRUE;

}
This was an example i saw in the internet with just a FBO and a texture mapped quad rendering.. I tried attaching shaders to it and then tried out.. however this does not somehow seem to work.. It seems so that the fragment shader i used has been applied onto the tex quad( all i see is a rectangle with the color specified by the fragment shader.. Please help..

ashwin_9891

Hey sorry... GLfloat vVertices[] = {  0.0f,  0.5f, 0.0f,
                           -0.5f, -0.5f, 0.0f,
                            0.5f, -0.5f, 0.0f };
   glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
   glUseProgram ( programObject ); // to this object i have attached a vertex and fragment shader
   glVertexAttribPointer ( 0, 3, GL_FLOAT, GL_FALSE, 0, vVertices );
   glEnableVertexAttribArray ( 0 );
   glDrawArrays ( GL_TRIANGLES, 0, 3 );
   
after this section i am switching back to the normal Pipelining.. so i have to give a glUseProgram(0);; thanks.. thanks.. please give me suggestions to improve my skills with shaders.. thanks :)

ashwin_9891

Hiiii.. people.. One more question.. I have a context and many surfaces are created on it.. Can this be equivalently considered to be like a FBO with many textures attached to it ?? please explain..