Results 1 to 5 of 5

Thread: Read the PBuffer (glReadPixels too Slow...)

  1. #1
    Junior Member
    Join Date
    May 2006
    Posts
    5

    Read the PBuffer (glReadPixels too Slow...)

    Hi,

    My program is rendered in a PBuffer and I wanted to know if there is another way better than glReadPixels() to access to the rendered Surface because I need to use it 45 times per second and know framerate falls to 17FPS ?
    I don't really need to copy the rendered Surface but just to read it...

    Does glGetPointerv works? How could I use it? I tried to use it but I don't know exactly how... I am in the good way?

  2. #2
    Junior Member
    Join Date
    Oct 2004
    Location
    UK
    Posts
    24
    Hi Norwy,

    Generally glReadPixels() is slow and should really only be used when doing screencapture at which point performance is non critical. The main cause for this loss of performance is due to synchronisation: the glReadPixels() call forces synchronisation between the CPU and the Graphics Core thus serialising them and resulting in lost CPU and Graphics Core performance. At which point it does not matter that much if you access only a single pixel or copy the whole buffer, you lost most of the performance with the synchronisation.

    For most applications which access the render target there is usually some other way to achieve the same result without having to read the rendertarget. Could you explain in more detail why you are trying to acccess the rendered surface 45 times per second using glReadPixels ?

    Thanks,

    K-

    ------------------------------------
    Kristof Beets
    Third Party Relations Manager
    Business Development, PowerVR
    www.imgtec.com
    ------------------------------------

  3. #3
    Junior Member
    Join Date
    May 2006
    Posts
    5
    I am doing an offscreen rendering to put the result in a surface that I use in a 2D library (its a bit strange but it does exactly what I want with glReadPixels but it's too slow) 45 times per second...

    It's like the Render to Texture Method except that I need to access directly to the buffer. Do you know how could I do it by this way ?

    I made this:

    Code :
    unsigned char pixels = new unsigned char [glWindowWidth*glWindowHeight*4]; 
    GLuint RenderedTex; 
    glGenTextures(1, &RenderedTex); 
    glBindTexture(GL_TEXTURE_2D, RenderedTex); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glWindowWidth, glWindowHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 
     
    void drawScene(int width, int height) 
    { 
    // Scene ... 
     
    glEnable(GL_TEXTURE_2D); 
    glBindTexture(GL_TEXTURE_2D, RenderedTex); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 
    }

    It's typically the Render to Texture method but the problem is that I can not reach the modified internal buffer of the texture... And I don't know why the last parameter pixels is required (it doesn't work without)...

  4. #4
    Senior Member
    Join Date
    May 2006
    Posts
    353
    One thing you could try is to have multiple pbuffers, and while you render to one you read from another that was previously rendered to. That way you give the graphics core more time to finish rendering a certain frame before you try reading it. The number of pbuffers you need depends on the amount of command buffering the OpenGL ES implementation does. 3 or 4 might be a good number to start from.

    Pseudocode:
    Code :
    // one time pbuffer initialization
    EGLSurface pbuffer[NUM_PBUFFERS];
    for (int i = 0; i < NUM_PBUFFERS; ++i)
        pbuffer[i] = eglCreatePbufferSurface(eglDisplay, eglConfig, attribs);
     
    // per frame render target setup
    void renderScene()
    {
        static int frameNumber = 0;
     
        int writeBuffer = frameNumber % NUM_PBUFFERS;
        int readBuffer = (frameNumber + 1) % NUM_PBUFFERS;
        eglMakeCurrent(eglDisplay, pbuffer[writeBuffer], pbuffer[readBuffer], eglContext);
        ...
     
        frameNumber++;
    }

    Quote Originally Posted by norwy
    I am doing an offscreen rendering to put the result in a surface that I use in a 2D library (its a bit strange but it does exactly what I want with glReadPixels but it's too slow) 45 times per second...

    It's like the Render to Texture Method except that I need to access directly to the buffer. Do you know how could I do it by this way ?
    There are only two ways to get the contents of a surface: glReadPixels and, if the surface is a pixmap, whatever way of access the native 2D graphics system provides. However, both methods have the same problem of synchronisation.

    It's typically the Render to Texture method but the problem is that I can not reach the modified internal buffer of the texture... And I don't know why the last parameter pixels is required (it doesn't work without)...
    You just upload an array of bytes to the OpenGL ES implementation as a texture there. This is not render to texture.
    Georg Kolling, Imagination Technologies
    Please ask questions specific to PowerVR hardware or SDKs on the PowerVR Insider Forum
    DevTech@imgtec.com | http://www.powervrinsider.com

  5. #5
    Junior Member
    Join Date
    May 2006
    Posts
    5
    Thanks to all, it works now, the good way was to render into a Pixmap with eglCreatePixmapSurface method and then read easily its pixels.

    Now it runs @ 45FPS and not @ 17FPS with glReadPixels... exactly as I wanted...

    Thank you all...

Similar Threads

  1. glReadPixels too slow
    By e7fendy in forum OpenGL ES 2X - for programmable 3D graphics pipelines
    Replies: 1
    Last Post: 09-05-2011, 02:01 PM
  2. HELP! SLOW
    By vega in forum OpenGL ES general technical discussions
    Replies: 1
    Last Post: 08-01-2005, 08:48 AM

Posting Permissions

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