glTexImage3D() usage

Hello,

I have been trying to write a volume renderer and am using Cg for shaders. Instead of calculating gradient’s on the fly, I am trying to pre-calculate them, store them into the volume texture (rgb - gradient, a - isovalue/ density) and then pass on to the fragment shader.

The gradient components may be negative and hence I am storing them into the vector of integers. To bind it to a texture, I am using the following,

glBindTexture(GL_TEXTURE_3D, texName);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage3D
(
GL_TEXTURE_3D,
0,
GL_RGBA8,
volume_w,
volume_h,
volume_d,
0,
GL_RGBA,
GL_INT,
volDataPtr
);

where, volDataPtr refers to the vector of integers. The reason why I am not using GL_UNSIGNED_BYTE (instead of GL_INT) is because the gradient values may be negative (and GL_UNSIGNED_BYTE goes from 0 - 255). Using GL_BYTE also doesn’t helps as the -ve values may be less than -127 (and +ve values greater than 127). Hence, using GL_INT seems logical to me.

However, this doesn’t works and I get a blank screen for my volume (GL_UNSIGNED_BYTE works, but I cannot store gradient’s then). Also, I am reading in from a .raw file and am properly typecasting into integer values before storing them into the vector.

Can anyone suggest what I may be doing wrong and/ or where exactly to look into.

Thanks,

You should know that internally OpenGL stores all textures as floating point [0…1] for unsigned input and [-1,1] for signed input. The input data you pass it is transformed using equations on page 11: http://www.opengl.org/registry/doc/glspec31.20090324.pdf

OpenGL is dividing all your data by (2^b-1) which may result in very small values if your data is not scaled properly - for example you calculate your gradient on bytes, so your gradient data range maximum is 255. Could explain the blank screen.

That makes sense, GL_INT is 32 bits, that means every value is getting divided by (2^32 - 1) and the result is too small.

But then what is the best way to store negative values in the range [-255, 255]?

You can use GL_FLOAT in which case no manipulation is done on the data. Or you can scale your data so that when the driver re-scales it, it’s in the correct range.

Edit
Actually I’m not confident about GL_FLOAT. I thought I remembered that data was not manipulated, but can’t find it from quick glance at the spec. If someone else can confirm/deny that would be great.

Thanks!!! I will try these out.