10 Replies Latest reply on Jun 5, 2012 8:04 PM by sherrick01821

    Offscreen rendering with OpenGL

    sherrick01821

      I would like to do rendering into an offscreen buffer attached to a texture but don't know how to do it. Could someone tell me the calls to make?

        • Re: Offscreen rendering with OpenGL
          gsellers

          Hi,

           

          You need to use a Frame Buffer Object (FBO). It's well documented in the spec and you should be able to find examples on line. However, the basic set of operations is to:

           

          1. Create your texture (glGenTextures, glBindTexture, glTexStorage2D).
          2. Create a framebuffer object and bind it (glGenFramebuffers, glBindFramebuffer).
          3. Attach the texture to the framebuffer (glFramebufferTexture2D).
          4. Set the draw buffers to COLOR_ATTACHMENT0 (glDrawBuffers).

           

          Now when you draw, you'll draw into the texture. To render to the screen again, bind 0 as the framebuffer (glBindFramebuffer again), and set the draw buffer to GL_BACK (glDrawBuffers again).

           

          You can look up all the functions above in the OpenGL reference pages here http://www.opengl.org/sdk/docs/man4/. They should have enough information for you to get this working. Let us know if you have any issues.

           

          Cheers,

           

          Graham

            • Re: Offscreen rendering with OpenGL
              sherrick01821

              Graham:

               

              Thanks for the info. I”ll try it. One other colleague of mine says he did it but didn’t use glDrawBuffers().

               

              He does his like this. Will this work as well?

               

              Steve

               

              ============

              I declare the following globals:

               

              GLuint renderTex,framebuffer;

              GLint renderTexRes = 1742;

               

               

              ============

              Then I make the framebuffer object:

               

              //

              // create the extra framebuffer and render-target

              //

              void initRenderTexture(int resx, int resy) {

               

              const GLubyte * strExt;

               

              fprintf(stdout,"Creating render texture of %d x

              %d\n",resx,resy);

               

              // make sure OpenGL environment is OK

              strExt = glGetString (GL_EXTENSIONS);

              if (gluCheckExtension((const

              GLubyte*)"GL_EXT_framebuffer_object",

              strExt) == GL_FALSE) {

              fprintf(stderr,"GL_EXT_framebuffer_object does not

              exist!\n");

              baseGraceful(1);

              }

               

              // create the OGL framebuffer structure

              glGenFramebuffersEXT(1, &framebuffer);

              glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);

               

              // create the OGL texture structure

              glGenTextures(1, &renderTex);

              glBindTexture(GL_TEXTURE_2D, renderTex);

              glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,

              GL_LINEAR);

              glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,

              GL_LINEAR);

              glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);

              glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

               

              glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, (GLsizei)resx,

              (GLsizei)resy,

              0, GL_RGB, GL_UNSIGNED_BYTE, NULL);

               

              // attach the texture to the framebuffer

              glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,

              GL_COLOR_ATTACHMENT0_EXT,

              GL_TEXTURE_2D, renderTex, 0);

               

              return;

              }

               

              initRenderTexture(renderTexRes,renderTexRes);

               

               

              ============

              When I draw, I do the following:

               

              glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);

              glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

              glViewport((GLint)0,(GLint)0,(GLsizei)renderTexRes,(GLsizei)renderTexRes);

               

              // draw my stuff that goes on the texture

               

              // switch back to drawing to the screen

              glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

              glViewport((GLint)0,(GLint)0,(GLsizei)runx,(GLsizei)runy);

              glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

               

              // draw a polygon that uses that texture

               

               

               

              From: gsellers

              Sent: Thursday, May 31, 2012 7:44 AM

              To: Steven Herrick

              Subject: Re: Offscreen rendering with OpenGL | AMD Developer Forums

               

                          AMD Developer Forums

                          Re: Offscreen rendering with OpenGL

                          in Graphics Programming

                • Re: Offscreen rendering with OpenGL
                  gsellers

                  Hi Steve,

                   

                  Actually the call to glDrawBuffers is not necessary if you're only ever going to render to the first attachment on that FBO and won't ever change that. The default draw buffer for a user-created FBO is COLOR_ATTACHMENT0 and so that first call to glDrawBuffers is technically redundant. If you want to render to multiple attachments or otherwise do anything with a non-default state, you can delay the call to glDrawBuffers until then.

                   

                  The other thing I noticed is that you're using the EXT_framebuffer_object extension. FBOs are part of core OpenGL now and have been some time. I'd recommend using the core version of the feature rather than the extension if you can.

                   

                  Cheers,

                   

                  Graham

                    • Re: Offscreen rendering with OpenGL
                      sherrick01821

                      Graham:

                       

                      Thanks for the reply. I need help on speeding up the drawing on triangles on the GPU. Instead of the glBegin().. glend() I would like to use vertex buffer objects from what I find out by my research. If this is true then I need to know the best way to do it. My question I have is do I need a normal for every vertex point? I am drawing triangular facets and I have a x,y,z coordinate for each vertex point but I have only 1 normal for each facet right now. Do you have any example code showing how to properly implement vertex buffer objects or is there another , better way to draw triangles?

                       

                      Thanks,

                      Steve

                       

                      From: gsellers

                      Sent: Friday, June 01, 2012 7:35 AM

                      To: Steven Herrick

                      Subject: Re: Offscreen rendering with OpenGL | AMD Developer Forums

                       

                                  AMD Developer Forums

                                  Re: Offscreen rendering with OpenGL

                                  in Graphics Programming

                      • Re: Offscreen rendering with OpenGL
                        sherrick01821

                        Graham:

                         

                        Does glDrawArrays require the indices in order to properly draw triangles? I have them available if need be. The code that does glBegin() ... glEnd() only has the vertex and normal data

                         

                        Steve

                         

                        From: gsellers

                        Sent: Friday, June 01, 2012 7:35 AM

                        To: Steven Herrick

                        Subject: Re: Offscreen rendering with OpenGL | AMD Developer Forums

                         

                                    AMD Developer Forums

                                    Re: Offscreen rendering with OpenGL

                                    in Graphics Programming

                          • Re: Offscreen rendering with OpenGL
                            gsellers

                            Hi Steve,

                             

                            Yes, glDrawArrays ignores indices and effectively generates it's own, in order. If that's how your triangles are ordered, then this is the right function for you to use and you don't need to supply indices at all. If you have indices in some arbitrary order, you can use glDrawElements. To do this, place your indices in a buffer object and bind it the the GL_ELEMENT_ARRAY_BUFFER binding point and call glDrawElements. The 'indices' parameter is then interpreted as an offset into that buffer. Either way (glDrawArrays or glDrawElements), it will be substantially faster than using immediate mode.

                             

                            Cheers,

                             

                            Graham

                              • Re: Offscreen rendering with OpenGL
                                sherrick01821

                                Graham:

                                 

                                Thanks for the reply. I was able to get the vertex buffer object working. I am now going to get the framebuffer object working. What is a renderbuffer used for when a texture is attached to a framebuffer object. I need both RGBA colors because I do a glReadPixels() for colors but also need depth processed as well. Would a render buffer be used for depth processing? How is the renderbuffer used in the architecture of a frame buffer object?

                                 

                                Thanks,

                                Steve

                                 

                                From: gsellers

                                Sent: Monday, June 04, 2012 10:49 AM

                                To: Steven Herrick

                                Subject: Re: Offscreen rendering with OpenGL | AMD Developer Forums

                                 

                                            AMD Developer Forums

                                            Re: Offscreen rendering with OpenGL

                                            in Graphics Programming

                                  • Re: Offscreen rendering with OpenGL
                                    gsellers

                                    Hi Steve,

                                     

                                    You can draw into a renderbuffer or a texture using an FBO. The main difference between a renderbuffer and a texture is that you cannot read from a renderbuffer in a shader like you can with a texture. This means that the driver can pick an internal storage representation for the renderbuffer that might be more efficient for rendering to because it doesn't really need to worry about reading from it. For the most part, it won't make a difference whether you use a renderbuffer or a texture. I would recommend that you just go ahead and use textures for everything as it will simplify your application.

                                     

                                    You'll need at least two textures for your application. One should have an internal format of GL_DEPTH_COMPONENT or GL_DEPTH_STENCIL_COMPONENT and you should attach it to the GL_DEPTH_STENCIL_ATTACHMENT point on the FBO. This will become your depth buffer (assuming you need a depth buffer). The second should have a format such as GL_RGBA8 or GL_RGBA16F, for example, depending on the precision you need. The normal, operating system supplied back buffer is normally equivalent to GL_RGBA8.

                                     

                                    Once you've set up your FBO, you can render to it as normal. You can use its attachments as textures, or you can read the data back using glReadPixels, glCopyTexSubImage or other such functions. There is no need to call SwapBuffers when you have an FBO bound. Also, you should never need to call functions like glFlush or glFinish with FBOs as functions like glReadPixels implicitly finish rendering before they execute.

                                     

                                    Cheers,

                                     

                                    Graham

                                      • Re: Offscreen rendering with OpenGL
                                        sherrick01821

                                        Graham:

                                         

                                        Thanks for the reply. Ok, so I have 2 textures , one has GL_DEPTH_COMPONENT internal format and the other has GL_RGBA8. If the depth one is attached to the FBO how is the 2nd one used? I need to call glReadPixels() and read back the GL_RGBA8 values as the code expects to read 4-bytes per pixel. Can 1 FBO be attached to 2 textures at the same time?

                                        From: gsellers

                                        Sent: Tuesday, June 05, 2012 9:49 AM

                                        To: Steven Herrick

                                        Subject: Re: Offscreen rendering with OpenGL | AMD Developer Forums

                                         

                                                    AMD Developer Forums

                                                    Re: Offscreen rendering with OpenGL

                                                    in Graphics Programming

                                        • Re: Offscreen rendering with OpenGL
                                          sherrick01821

                                          Graham:

                                           

                                          A couple more questions have come to mind.

                                           

                                          1) I am trying to use the GPU hardware rendering capabilities to speed up the rendering. How do you know what features (i.e. framebuffer objects, vertex buffer objects, etc) are actually using the GPU?

                                           

                                          2) I implemented the FBO using a texture attached to the FBO as GL_RGBA8 and a renderbuffer used as the DEPTH attachment. When I did this I saw a much higher runtime as opposed to when I rendered to a XPixmap as the current context. Any ideas why that may be?

                                           

                                          3) The code I’m working with creates a texture and does a glCopyTexSubImage2D(). I believe that this copies from the framebuffer to the texture? Does any further rendering after that point go to the texture or just the framebuffer? It appears that the depth effect works fine if I uncomment out the section of code that allocates the texture and then does the glCopyTexSubImage2D() when used with the FBO but no depth effect is seen when I comment out the texture portion and use the FBO as well.

                                           

                                          I was expecting to see the FBO be really fast and see the depth effect when a texture was attached to the FBO as GL_RGBA8 and a renderbuffer attached to the FBO as the DEPTH attachment.

                                           

                                          Regards,

                                          Steve

                                           

                                          From: gsellers

                                          Sent: Tuesday, June 05, 2012 9:49 AM

                                          To: Steven Herrick

                                          Subject: Re: Offscreen rendering with OpenGL | AMD Developer Forums

                                           

                                                      AMD Developer Forums

                                                      Re: Offscreen rendering with OpenGL

                                                      in Graphics Programming