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 10

Thread: glCopyPixels(), Pre-rendering + recalling colour & depth channels.

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

    glCopyPixels(), Pre-rendering + recalling colour & depth channels.

    I am using OpenGL in 2D mode to make a game with a static environment from a fixed camera perspective.

    I want to
    1. Pre-render the static environment.
    2. Store the resulting 2D image to the GPU including both colour and depth channels
    3. Recall the pixels quickly.

    Here is what I think I am supposed to do:

    1. Create a frame buffer object
    2. Create two renderbuffer objects: one colour, one depth, both 256x256 pixels
    3. Attach both renderbuffers to the appropriate attachment points on the framebuffer.
    4. Bind the virtual frame buffer, draw an image with depth parameters specified.

    5. use glCopyPixels() to copy it to the screen. <--XX DANGER: THIS IS WHERE THINGS GO WRONG

    Code :
       steps_1_through_4_above();   //create an FBO w/ 2xRBOs, and draw a picture to it.
       glLoadIdentity ();
       glOrtho (0, 256, 256, 0, 0, 1);
       glViewport(0,0,256,256);
       glMatrixMode (GL_MODELVIEW);
       glPixelTransferi(GL_MAP_COLOR,true);
       glRasterPos2i(256,256);
       glCopyPixels(0,0,256,256,GL_COLOR);

    My problem is specifically that I cannot seem to figure out how to copy the pixels from one frame buffer to another one.

    I think I've isolated the problem to specifically this and nothing else that is obvious. steps 1 through 4 are working properly, and I am properly invoking my OSes double-buffer switching routine in order to actually display the results. I get a black square but not the image I rendered, which I checked with some alternate code that renders to a texture (a technique I am familiar with).

    I believe my problem is a misunderstanding with glCopyPixels(). I could not find a working example of glCopyPixels() copying from a virtual frame buffer object to the screen, so finally I ask for advice.

    How do I copy pixels from one frame buffer object to another including the depth and colour components?

    Thanks.
    Last edited by TheSuese; 08-06-2012 at 07:38 AM. Reason: clarify title

  2. #2
    Member Regular Contributor
    Join Date
    Apr 2009
    Posts
    258
    Please, dont use glCopyPixels, for anything.
    You have FBO's then i assume you also have access to glBlitFramebuffer (they are actually very similar in how you could use them).

    Since you want to copy from one framebuffer to another, you need to utilize read and draw framebuffer bindings:
    If you want to use glCopyPixels you need to have RasterPos set to begining of the region (ie. 0,0).

    Code :
    glBindFramebuffer(GL_READ_FRAMEBUFFER, FBO); //this binds stuff you rendered as 'source'
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); //this binds default fbo (ie. window) as 'destanation'
     
    //glCopyPixels/glBlitFramebuffer does actual copying here.

  3. #3
    Junior Member Newbie
    Join Date
    Aug 2012
    Posts
    7
    Hmm, okay. I did not know this was possible.
    The documentation says the first argument of glBindFramebuffer "Must always be GL_FRAMEBUFFER"

    I tried it but it would not compile.

    Code :
        glBindFramebufferEXT(GL_READ_FRAMEBUFFER,my_fbo);
        glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER,0);

    Compiler says "GL_READ_FRAMEBUFFER undeclared".

    Same thing happens if I try GL_READ_FRAMEBUFFER_EXT: Undeclared.

    Suggestions?

  4. #4
    Member Regular Contributor
    Join Date
    Apr 2009
    Posts
    258
    Check your extension string. If you are on GL < 3.0 and dont have GL_ARB_framebuffer_blit extension then you wont have the tokens (and blit) without the suffix.
    Versions with the suffix are in GL_EXT_framebuffer_blit. If you dont have this as well, then you wont be able to use glBlitFramebuffer nor glCopyPixels to directly copy from one framebuffer to another.

    You will have to write a simple shader that samples the texture (you will need to render to texture and not renderbuffer) and fills fullscreen quad with its content.

  5. #5
    Junior Member Newbie
    Join Date
    Aug 2012
    Posts
    7
    So are these features particularly well-supported in various environments? I'm testing in C but I will be working in Java for Android / OUYA. Am I really getting a performance boost by firing this technique through the graphics accelerator or should I just brave the dirty-stinking home-brew java code that's going to push hundreds of sprites onto the screen using a z-depth map and pray it performs?

  6. #6
    Junior Member Newbie
    Join Date
    Aug 2012
    Posts
    7
    Code :
    void select_texture(){
         glLoadIdentity();
         glOrtho (0, 256, 0, 256, 0, 1);
         glViewport(0,0,256,256);
         glMatrixMode (GL_MODELVIEW);
     
    }
     
    void select_screen(int w,int h){
         glLoadIdentity ();
         glOrtho (0, w, h, 0, 0, 1);
         glViewport(0,0,w,h);
         glMatrixMode (GL_MODELVIEW);
     
    }
    int main() {
     
    	GLuint my_fbo;
    	GLuint color_rb;
     
    	set_gfx_mode(GFX_OPENGL_WINDOWED, 512, 512, 0, 0);
     
        glDisable(GL_DEPTH_TEST);
        glEnable(GL_TEXTURE_2D);
     
        glGenRenderbuffersEXT(1,&color_rb);
     
        glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, color_rb);
        glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_RGB, 256, 256 );
     
        glGenFramebuffersEXT(1, &my_fbo);    
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, my_fbo);    
        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, color_rb );
     
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,my_fbo);
        select_texture();
        glClearColor(0,0,1,1);
        glClear( GL_COLOR_BUFFER_BIT );
     
     
        //clear our 'screen'.
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);
        glClearColor(0.2,0.2,0.2,1);
        glClear( GL_COLOR_BUFFER_BIT );
     
        select_screen(512,512);
        glBindFramebufferEXT(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT,my_fbo);
        glBindFramebufferEXT(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT,0);
        glPixelTransferi(GL_MAP_COLOR,GL_TRUE);
        glRasterPos2i(0,256);
        glCopyPixels(0,0,256,256,GL_COLOR);
     
    	/* Flip the backbuffer on screen */
    	allegro_gl_flip();
     
    	return 0;
    }


    My expectation is a blue box. The result is a black box.

    These were the closest symbols I could find to GL_READ_FRAMBUFFER and GL_DRAW_FRAMEBUFFER. I also couldn't find FrameBufferBlit()

  7. #7
    Senior Member OpenGL Pro BionicBytes's Avatar
    Join Date
    Mar 2009
    Location
    UK, London
    Posts
    1,171
    void select_texture(){
    glLoadIdentity();
    glOrtho (0, 256, 0, 256, 0, 1);
    glViewport(0,0,256,256);
    glMatrixMode (GL_MODELVIEW);
    You are not specifying the correct matrix before using this, are you?
    glMatrixMode (GL_PROJECTION);

    For the blit functionality, you need to be checking for ARB_FRAMEBUFFER_OBJECT and then initialise those pointer functions and use the appropriate header(s).

  8. #8
    Junior Member Newbie
    Join Date
    Aug 2012
    Posts
    7
    Hmm.. Thanks for the reply.

    Check out select_screen(w,h) function in my example above, then check out how it is applied:

    Code :
        select_screen(512,512);
        glBindFramebufferEXT(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT,my_fbo);
        glBindFramebufferEXT(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT,0);
        glPixelTransferi(GL_MAP_COLOR,GL_TRUE);
        glRasterPos2i(0,256);
        glCopyPixels(0,0,256,256,GL_COLOR);
    New identity loaded,the orthogonic projections are set, Viewport set, and GL_MODE_VIEW is definitely selected.

    Does it look like I am at least close to getting it right?

  9. #9
    Junior Member Newbie
    Join Date
    Aug 2012
    Posts
    7
    I re-read your comment with a little more scrutiny. I will let you know...

  10. #10
    Junior Member Newbie
    Join Date
    Aug 2012
    Posts
    7
    I tried this:

    Code :
    void select_screen(int w,int h){
         glMatrixMode (GL_PROJECTION);     
         glLoadIdentity ();
         glOrtho (0, w, h, 0, 0, 1);
         glViewport(0,0,w,h);
         glMatrixMode (GL_MODELVIEW);     
    }

    and this:

    Code :
    void select_screen(int w,int h){
         glMatrixMode (GL_PROJECTION);     
         glLoadIdentity ();
         glOrtho (0, w, h, 0, 0, 1);
         glViewport(0,0,w,h);
    }

    Neither seems to do what I'm expecting.

    Perhaps if someone could show me a working example that would help clear everything up. I can't find one on the net.

    Thanks.

Posting Permissions

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