1 Reply Latest reply on Sep 11, 2013 8:49 AM by lerimini

    Strange behaviour of glTexSubImage3d

    lerimini

      Our application uses glTexSubImage3d function to transfer 3d data from cpu to gpu. Starting from Catalyst 12.6  data transfer doesn't work correctly with the following dataset dimensions: 192x172x161 (it worked fine on earlier versions but not on the last one -12.8). Opengl returns no error but data are completely wrong. The problem isn't present with other daset dimensions.

       

      Do you have open issues about that? Thank you for your help.

        • Re: Strange behaviour of glTexSubImage3d
          lerimini

          Add some information and a code snippet to reproduce te problem.

           

          ATI E2400 with driver version 8.960; OS: Windows XP Embedded.

           

          Code:

           

          //Clear all pixels
          glClear(GL_COLOR_BUFFER_BIT);

           

           

          //good (128x128x128 volume dataset works fine)
          //int Width = 128;
          //int Height = 128;
          //int Depth = 128;

           

           

          ////bad
          int Width = 192;
          int Height = 172;
          int Depth = 161;
          GLuint my3dTexture = 0;
          unsigned char* my3DBuffer = NULL;

           

           

          //Generate 3d texture and allocate video memory and texture properties
          glGenTextures(1, &my3dTexture);
          glBindTexture(GL_TEXTURE_3D, my3dTexture);

           

           

          glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
          glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
          glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
          glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
          glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
          glPixelStorei(GL_PACK_ALIGNMENT, 1);

           

           

          //Allocate memory client size
          my3DBuffer = new unsigned char[Width * Height * Depth];

           

           

          //Grayscale gradient along z-direction
          for(int z=0; z<Depth; z++)
          {
          float fValue = (float)z / (float)Depth;
          unsigned char value = (unsigned char) (fValue * 255.0f);
          for(int x=0; x<Width; x++)
          for(int y=0; y<Height; y++)
          {
          my3DBuffer[(z*Width*Height + y*Width + x)] = value;
          }
          }

           

          //Transferring to gpu

          glTexImage3D(GL_TEXTURE_3D, 0, GL_R8, Width, Height, Depth, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
          glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, Width, Height, Depth, GL_RED, GL_UNSIGNED_BYTE, my3DBuffer);

           

           

           

           

          //Draw a quad using texure mapping (diagonal)
          // (0.25, 0.25, 0.0) and (0.75, 0.75, 0.0)
          glEnable(GL_TEXTURE_3D);
          glColor3f(1.0,1.0,1.0);

           

           

          glBegin(GL_QUADS);
          glTexCoord3f(0.0,0.0,0.0);
          glVertex3f(0.25, 0.25, 0.0);
          glTexCoord3f(1.0,0.0,0.0);
          glVertex3f(0.75, 0.25, 0.0);
          glTexCoord3f(1.0,1.0,1.0);
          glVertex3f(0.75, 0.75, 0.0);
          glTexCoord3f(0.0,1.0,1.0);
          glVertex3f(0.25, 0.75, 0.0);
          glEnd();
          glDisable(GL_TEXTURE_3D);
          glBindTexture(GL_TEXTURE_3D, 0);

           

           

          // Don't wait start processing buffered OpenGL routines)
          glFlush();

           

           

          if(my3DBuffer!=NULL)
          {
          delete[] my3DBuffer;
          my3DBuffer = NULL;
          }

           

           

          if(my3dTexture!=0)
          {
          glDeleteTextures(1, &my3dTexture);
          my3dTexture = 0;
          }

           

           

          Output:

          bad.JPG

           

          Changing format to GL_LUMINANCE works fine, but the nicest thing is that it works fine also if i add the instruction

           

          glPixelTransferf(GL_RED_BIAS, 0.0000001f);

           

          just before executing glTexImage3D.

           

          Also the combination GL_RED + GL_FLOAT or GL_RED + GL_BYTE works fine. It seems that is not working only the one that I need.