10 Replies Latest reply on Aug 21, 2012 11:51 AM by Andrey2007AMD

    glReadPixels does different work in ATI card.

    manny85

      I have implemented opengl picking using FBO and glReadPixels.

      (I referred tutorial site : http://ogldev.atspace.co.uk/www/tutorial29/tutorial29.html)

      It works fine in NVIDIA card(GTX580). But it works strangely in ATI card(HD 7970).

       

      ---------------------------------------------------------------------------------------------------------------------

      [Problem 1]

      It works strangely when internalFormat is 'GL_RGB32UI'. The code like below.

      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, WindowWidth, WindowHeight, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, NULL);

      This is a part of initialization of FBO texture of tutorial I mentioned.

       

      It also works ATI when glReadPixels get only 1 pixel. The code like below.

      glReadPixels(x, y, 1, 1, GL_RGB_INTEGER, GL_UNSIGNED_INT, &Pixel);

       

      But I want to get any range of pixels. The code like below.

      glReadPixels(x, y, w, h, GL_RGB_INTEGER, GL_UNSIGNED_INT, pPixel);

       

      But It works strangely. Anyway I fixed this like below.

      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32I, WindowWidth, WindowHeight, 0, GL_RGBA_INTEGER, GL_INT, NULL);

      glReadPixels(x, y, w, h, GL_RGBA_INTEGER, GL_INT, pPixel);

      Also fixed fragment shader : uvec3 -> ivec4

       

      ---------------------------------------------------------------------------------------------------------------------

      Unfortunatly, it is not the end. there is serious problem I couldn't fix.

      [Problem 2]

      My application pick polygons of mesh. The problem occur when the mesh has a number of polygons(eg. over 3 million polygons). My Application picked rectangle range has a lot of holes and sometimes it doesn't pick nothing.

      I guess glReadpixels doesn't work normally. Writing to FBO texture is no matter according to some tests I have done. The problem is not occur in NVIDIA GTX580.

      Does anybody know why this problem happend and how to fix it? Any comment would be helpful for me.

        • Re: glReadPixels does different work in ATI card.
          Andrey2007AMD

          What return a function glGetError() after calling glTexImage2D/glReadPixels ?

          Whar return a function glCheckFramebufferStatus?

          Try to simplify the code, without the complex mesh. Try to select pixels from one polygon.

          1 of 1 people found this helpful
            • Re: glReadPixels does different work in ATI card.
              manny85

              First, thank you for your advice.

              There is no gl error and glCheckFramebufferStatus is GL_FRAMEBUFFER_COMPLETE.

               

              But, I was worng. It is not matter of reading pixels phase. It is matter of writing phase using FBO texture.

              Sorry, I knew problem of glReadPixels but it isn't. Here is my FBO initialize code(same as tutorial I mentioned before).

               

              glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);

               

              // color buffer(texture) init

              glBindTexture(GL_TEXTURE_2D, m_pickingTexture);

              glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32I, WindowWidth, WindowHeight, 0, GL_RGBA_INTEGER, GL_INT, NULL);

              glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_pickingTexture, 0);

               

              // depthbuffer init

              glBindTexture(GL_TEXTURE_2D, m_depthTexture);

                  glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, WindowWidth, WindowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);

                  glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthTexture, 0);

               

              And new bug I found. In shader code. 'uvec4' means four unsigned int, explaned opengl 4.2 reference.

              So, max value can be 4,294,967,295. In ATI, however, 2,147,483,647 is max value and over 2,147,483,647 cause 'Invalid operation' gl error.

               

              Anyway, I wonder why FBO texture writing work different between ATI and NVIDIA.

                • Re: glReadPixels does different work in ATI card.
                  Andrey2007AMD

                  >cause 'Invalid operation' gl error.

                  When was this error? after a calling of glUseProgram/glUseProgramObject ? or after other calls ?

                  May be try to change a shader code:

                   

                  #version 420

                   

                  #extension GL_EXT_gpu_shader4 : enable

                   

                  out uvec4 FragColor;

                  uniform uint gDrawIndex;

                  uniform uint gObjectIndex;

                   

                  void main()

                  {

                      FragColor = uvec4(float(gObjectIndex), float(gDrawIndex), float(gl_PrimitiveID + 1), 1);

                  }

                   

                  May be need to convert a "unsigned int" type to a "float" type in an explicit form.

                  Try to check this shader in AMD GPU Shader Analizer.

                  In the present time i have not the ATI Card, but i  have the ATI 5670 at the home, i can check this shader later.

                  1 of 1 people found this helpful
                    • Re: glReadPixels does different work in ATI card.
                      manny85

                      It was error in fragment shader.

                       

                      when the code is below..

                      FragColor = uvec4(float(4194967295), float(gDrawIndex), float(gl_PrimitiveID + 1), 255);

                       

                      error log is..

                      Fragment shader failed to compile with the following errors:

                      ERROR: 0:22: error(#88) Syntax error ERROR___INTEGER_CONST_OVERFLOW

                      ERROR: error(#273) 1 compilation errors.  No code generated

                       

                      but '2,147,483,647' is ok. So uvec4 works in interger range.

                • Re: glReadPixels does different work in ATI card.
                  manny85

                  Here is result of gl_PrimitiveID generation between ATI and NVIDIA.

                   

                  plane3m_ATI.PNG

                       <ATI>

                  plane3m_NVIDIA.PNG

                       <NVIDIA>

                   

                   

                  fragment shader is like that..

                   

                  float fColor = gl_PrimitiveID / fMeshSize;

                  vFragColor = vec4(fColor, fColor, fColor, 1);

                   

                  fMeshSize is the number of faces(3,189,760).

                  So, I could insist there is something different of generating gl_PrimitiveID between ATI and NVIDIA.

                   

                  It represent only when face size is large. In a case of low face mesh it works fine.

                  Thus, I guess gl_PrimitiveID has a limit value in ATI.

                  I also found that there is same gl_PrimitiveID when render large mesh. I believe each face(primitive) has a unique gl_PrimitiveID.

                  • Re: glReadPixels does different work in ATI card.
                    Andrey2007AMD

                    ATI 5670, Windows 7 32 bit (Driver 12.8):

                    pickdemo.jpg