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 7 of 7

Thread: Problem with glReadPixels on a part of a view on ATI cards

  1. #1
    Intern Newbie
    Join Date
    Oct 2010
    Posts
    47

    Problem with glReadPixels on a part of a view on ATI cards

    Hello,

    I can't find what is wrong on ATI cards. On nvidia I have no problem.
    Maybe you will have an idea...

    I have 3 views :
    - a 2D (ortho) view on the left
    - two 3D (pers) view on the right, one above the other.
    The model is drawn on the 3 views and the 2D view shares the display lists.

    When I close one 3D view, the remaining view takes all the place on the right of the 2D view.

    Problem : glReadPixels returns 0 where the closed 3D view was. So on the half of the view it returns 0 and on the other half it is correct.
    I saw with gDebugger that the depth buffer is wrong on the half of the view.
    I have not this problem on nvidia.
    I debugged on 2 pc, one nvidia and one ati : they use the same handles on opengl contexts.
    The only difference in visual studio debugger is the "unused" member in the HGLRC structure : it is always 0 on nvidia, and never 0 on ati. But I don't know the meaning of this variable :
    on nvidia : HGLRC__* hGLContext { unused=0 }
    on ati : HGLRC__* hGLContext { unused=973096704 } // and other values

    I do a wglMakeCurrent before using glReadPixels to be sure.
    There is no error with glGetError() and glCheckFramebufferStatus(GL_FRAMEBUFFER).

    It seems that something is not well initialized or updated for ATI but I don't know what...
    If you have an idea...

    Thanks in advance.

  2. #2
    Super Moderator OpenGL Guru
    Join Date
    Feb 2000
    Location
    Montreal, Canada
    Posts
    4,264
    glCheckFramebufferStatus is for FBO, not for the main surface.

    Are you refreshing the window before using glReadPixels?
    The usual pattern of calls is
    glClear(...);
    RenderStuff();
    glReadPixels(......);
    SwapBuffers();

    or better yet, render to an actual FBO since that is what it is for. It is more reliable then rendering to a window and reading back.
    ------------------------------
    Sig: http://glhlib.sourceforge.net
    an open source GLU replacement library. Much more modern than GLU.
    float matrix[16], inverse_matrix[16];
    glhLoadIdentityf2(matrix);
    glhTranslatef2(matrix, 0.0, 0.0, 5.0);
    glhRotateAboutXf2(matrix, angleInRadians);
    glhScalef2(matrix, 1.0, 1.0, -1.0);
    glhQuickInvertMatrixf2(matrix, inverse_matrix);
    glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
    glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);

  3. #3
    Intern Newbie
    Join Date
    Oct 2010
    Posts
    47
    Thanks for your answer.
    For the fun, here are the depth buffers... http://imageshack.us/photo/my-images...pthbuffer.png/

    To answer, the view is refreshed because I added geometry. And the glReadPixels is called on a mouse event over the view.

    I did some tests :
    - I can obtain the same problem by resizing the views : with the two 3D views, one above the other ; I reduce the size of one view so that the other take the place. And I have the problem.
    So it is not a mistake in my code when deleting an opengl context ; I do not create a zombie context.
    - If I undock the 2 views I have the problem on the 2 views
    - If I close the 2 views with problem and I create a new 3D view this one has no problem.
    Maybe this will give an idea to someone...

    On two cards I upgraded the drivers and I have no more the problem.
    On an old card it is not possible to upgrade and I have the problem...
    Maybe it is a bug in the driver but I don't know what generates the problem...

  4. #4
    Super Moderator OpenGL Guru
    Join Date
    Feb 2000
    Location
    Montreal, Canada
    Posts
    4,264
    So, you are using glReadPixels to read the depth buffer?
    It looks like the depth buffer is stretched started from the middle. Is it causing a problem with the output to your window or is it just a problem for glReadPixels?
    If it is glReadPixels, then I would just go with rendering to an FBO (attach a render buffer and render your scene to it). You can even choose to render to depth only for your FBO.

    http://www.opengl.org/wiki/Framebuff...les#Depth_only
    ------------------------------
    Sig: http://glhlib.sourceforge.net
    an open source GLU replacement library. Much more modern than GLU.
    float matrix[16], inverse_matrix[16];
    glhLoadIdentityf2(matrix);
    glhTranslatef2(matrix, 0.0, 0.0, 5.0);
    glhRotateAboutXf2(matrix, angleInRadians);
    glhScalef2(matrix, 1.0, 1.0, -1.0);
    glhQuickInvertMatrixf2(matrix, inverse_matrix);
    glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
    glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);

  5. #5
    Intern Newbie
    Join Date
    Oct 2010
    Posts
    47
    Quote Originally Posted by V-man View Post
    So, you are using glReadPixels to read the depth buffer?
    Yes. To then use gluUnProject to show world coordinates in the status bar or to move in the scene on some mouse events.

    Is it causing a problem with the output to your window or is it just a problem for glReadPixels?
    It is incredible (for me...) but there is no drawing problem. Maybe a chance with our drawing order ?
    Only the world coordinates in the status bar are false and the scene do not move correctly in the half of the view...

    If it is glReadPixels, then I would just go with rendering to an FBO (attach a render buffer and render your scene to it). You can even choose to render to depth only for your FBO.
    http://www.opengl.org/wiki/Framebuff...les#Depth_only
    I will read your link.
    If I understand this means to draw the scene several times more (on mouse events for me) to the depth buffer.

    I will try to test your advice. To see if the depth buffer is correctly updated.
    Thanks

    [Edit]
    Maybe glReadPixels works well. The question is maybe why is the depth buffer invalid after drawing correctly ?
    [/Edit]
    Last edited by AllForum; 03-11-2013 at 02:50 AM.

  6. #6
    Super Moderator OpenGL Guru
    Join Date
    Feb 2000
    Location
    Montreal, Canada
    Posts
    4,264
    You would already need to re-render the scene on mouse move even if you are using the main window.
    Usually, SwapBuffer invalidates the backbuffer.
    On Windows, for the pixelformat descriptor, you can try setting PFD_SWAP_COPY and in this case, you don't need to re-render. However, the MSDN documentation says this is a hint only, and it might not be provided by the driver.
    ------------------------------
    Sig: http://glhlib.sourceforge.net
    an open source GLU replacement library. Much more modern than GLU.
    float matrix[16], inverse_matrix[16];
    glhLoadIdentityf2(matrix);
    glhTranslatef2(matrix, 0.0, 0.0, 5.0);
    glhRotateAboutXf2(matrix, angleInRadians);
    glhScalef2(matrix, 1.0, 1.0, -1.0);
    glhQuickInvertMatrixf2(matrix, inverse_matrix);
    glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
    glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);

  7. #7
    Intern Newbie
    Join Date
    Oct 2010
    Posts
    47
    Hello V-man,

    Thanks for following my post.
    And you have found something !

    As I am discovering FBO it was easier to quickly test the pixel format.
    And with our classical pixelformat, which contains PFD_SWAP_COPY, I have not the problem.

    I use MSAA antialiasing when it is possible. In this case I have the problem. And the pixel format is different. So I will look tomorrow if there is something to change in the pixel format or if the problem comes from the MSAA.

    Thanks for your help : i have two things to test now !


    I join the pixelformats.
    For MSAA :
    Code :
    int iAttributes[] =
        {
            WGL_SAMPLES_ARB,(int)ComputedAASize, 
            WGL_SAMPLE_BUFFERS_ARB,1,
            WGL_DRAW_TO_WINDOW_ARB,1,
            WGL_SUPPORT_OPENGL_ARB,1,
            WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
            WGL_COLOR_BITS_ARB,32,
            WGL_ALPHA_BITS_ARB,8,
            WGL_DEPTH_BITS_ARB,24,
            WGL_STENCIL_BITS_ARB,1,
            WGL_DOUBLE_BUFFER_ARB,1,
            WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
            WGL_AUX_BUFFERS_ARB, 0,
            WGL_RED_BITS_ARB, 8,
            WGL_GREEN_BITS_ARB, 8,
            WGL_BLUE_BITS_ARB, 8,
            WGL_ALPHA_BITS_ARB,8,
            WGL_ACCUM_BITS_ARB, 0,
            0,0
        };
        valid = wglChoosePixelFormatARB(hDC,iAttributes,fAttributes,1,&M_PixelFormat,&numFormats);

    Classical pixelformat :

    Code :
    PIXELFORMATDESCRIPTOR pixelDescriptor;
     
        pixelDescriptor.nSize = sizeof(PIXELFORMATDESCRIPTOR);
        pixelDescriptor.nVersion = 1;
     
        pixelDescriptor.dwFlags
            = PFD_DRAW_TO_WINDOW
            | PFD_SUPPORT_OPENGL 
            | PFD_DOUBLEBUFFER
            | PFD_SWAP_COPY
            | PFD_STEREO_DONTCARE
    #if WINVER>=0x0600    // Vista
            | 0x00008000
    #endif
            ;
     
        pixelDescriptor.iPixelType = PFD_TYPE_RGBA;
        pixelDescriptor.cColorBits = 32;
        pixelDescriptor.cRedBits = 8;
        pixelDescriptor.cRedShift = 24;
        pixelDescriptor.cGreenBits = 8;
        pixelDescriptor.cGreenShift = 16;
        pixelDescriptor.cBlueBits = 8;
        pixelDescriptor.cBlueShift = 8;
        pixelDescriptor.cAlphaBits = 8;
        pixelDescriptor.cAlphaShift = 0;
        pixelDescriptor.cAccumBits = 0;
        pixelDescriptor.cAccumRedBits = 0;
        pixelDescriptor.cAccumGreenBits = 0;
        pixelDescriptor.cAccumBlueBits = 0;
        pixelDescriptor.cAccumAlphaBits = 0;
        pixelDescriptor.cDepthBits = 24;
        pixelDescriptor.cStencilBits = 1;
        pixelDescriptor.cAuxBuffers = 0;
        pixelDescriptor.iLayerType = PFD_MAIN_PLANE;
        pixelDescriptor.bReserved = 0;
        pixelDescriptor.dwLayerMask = 0;
        pixelDescriptor.dwVisibleMask = 0;
        pixelDescriptor.dwDamageMask = 0;
     
        int pixelIndex = ChoosePixelFormat(hDC, &pixelDescriptor);
    Last edited by AllForum; 03-11-2013 at 10:15 AM. Reason: typo

Posting Permissions

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