cancel
Showing results for 
Search instead for 
Did you mean: 

Archives Discussions

lerimini
Journeyman III

Strange behaviour of glTexSubImage3d

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.

0 Likes
1 Reply
lerimini
Journeyman III

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.

0 Likes