PDA

View Full Version : Cubemaps and GL_RGB32F_ARB



verma
03-07-2008, 09:29 PM
Hello everyone,

I've been trying to load Paul Debevec's light probes (actually the cross cube textures) into my program using GL_RGB32F_ARB internal format. To test my code, I have exactly similar code (but that's my own opinion) for loading GL_RGB (GL_UNSIGNED_BYTE) internal format. Also, I have added functions that help me load individual faces to check my image loader.

To use this texture, right now, I am just using a simple shader program which does a textureCube using the current fragment's normal(!).

The problem is, that this reflective shading works with the ubyte texture I am using, but shows up as black (indicating that no color is being read in from the texture) when I use the floating point format texture. I am really not sure what's going on, may be I am missing a subtle detail I need to pay attention to, or something's so obviously incorrect that I am overlooking.

Also, I tried using the same technique to load the image data into a GL_TEXTURE_2D just to check if my image loading is actually working. The textures show up fine.

Even if I am screwing up something really bad, at least something should show up. Below is the code I am using to load the textures.

Thanks,
verma



glPushAttrib (GL_ENABLE_BIT); check_gl ();
glEnable (GL_TEXTURE_CUBE_MAP); check_gl ();

// I find it hard to get my head around image orienation and stuff, so most of the adjustments to flips and loads have been done
// using hit and trial. But if you sit and get the image orientation right in your head, it makes sense

// generate our texture
glGenTextures (1, &texId); check_gl();
glBindTexture (GL_TEXTURE_CUBE_MAP, texId); check_gl ();

if (imageType == IMAGE_TYPE_PFM) {
fprintf (stderr, "... performing a floating point texture load.\n");
// left, -ve x
fprintf (stderr, "... loading cube face 1\n");
__loadSubImage (img, face_img, face_width, face_height, 0, face_height, width, height);
__imgFlipVertically (face_img, face_width, face_height);
glTexImage2D (GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB32F_ARB, face_width, face_height, 0, GL_RGB, GL_FLOAT, face_img); check_gl ();

// front, -ve z
fprintf (stderr, "... loading cube face 2\n");
__loadSubImage (img, face_img, face_width, face_height, face_width, face_height, width, height);
__imgFlipVertically (face_img, face_width, face_height);
glTexImage2D (GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB32F_ARB, face_width, face_height, 0, GL_RGB, GL_FLOAT, face_img); check_gl ();

// right, +ve x
fprintf (stderr, "... loading cube face 3\n");
__loadSubImage (img, face_img, face_width, face_height, 2*face_width, face_height, width, height);
__imgFlipVertically (face_img, face_width, face_height);
glTexImage2D (GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB32F_ARB, face_width, face_height, 0, GL_RGB, GL_FLOAT, face_img); check_gl ();

//top, +ve y
fprintf (stderr, "... loading cube face 4\n");
__loadSubImage (img, face_img, face_width, face_height, face_width, 2*face_height, width, height);
__imgFlipHorizontally (face_img, face_width, face_height);
glTexImage2D (GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA32F_ARB, face_width, face_height, 0, GL_RGB, GL_FLOAT, face_img); check_gl ();

// bottom, -ve y
fprintf (stderr, "... loading cube face 5\n");
__loadSubImage (img, face_img, face_width, face_height, face_width, 0, width, height);
__imgFlipHorizontally (face_img, face_width, face_height);
glTexImage2D (GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA32F_ARB, face_width, face_height, 0, GL_RGB, GL_FLOAT, face_img); check_gl ();

// back, +ve z, its upside down in the image
fprintf (stderr, "... loading cube face 6\n");
__loadSubImage (img, face_img, face_width, face_height, face_width, 3*face_height, width, height);
__imgFlipHorizontally (face_img, face_width, face_height);
glTexImage2D (GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA32F_ARB, face_width, face_height, 0, GL_RGB, GL_FLOAT, face_img); check_gl ();

free (img);
free (face_img);
}
else {
fprintf (stderr, "... performing a 8-bit per component load.\n");

// do a regular PPM loading
// left, -ve x
fprintf (stderr, "... loading cube face 1\n");
__loadSubImageC (img_c, face_img_c, face_width, face_height, 0, face_height, width, height);
__imgFlipVerticallyC (face_img_c, face_width, face_height);
glTexImage2D (GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB, face_width, face_height, 0, GL_RGB, GL_UNSIGNED_BYTE, face_img_c); check_gl ();

// front, -ve z
fprintf (stderr, "... loading cube face 2\n");
__loadSubImageC (img_c, face_img_c, face_width, face_height, face_width, face_height, width, height);
__imgFlipVerticallyC (face_img_c, face_width, face_height);
glTexImage2D (GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB, face_width, face_height, 0, GL_RGB, GL_UNSIGNED_BYTE, face_img_c); check_gl ();

// right, +ve x
fprintf (stderr, "... loading cube face 3\n");
__loadSubImageC (img_c, face_img_c, face_width, face_height, 2*face_width, face_height, width, height);
__imgFlipVerticallyC (face_img_c, face_width, face_height);
glTexImage2D (GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB, face_width, face_height, 0, GL_RGB, GL_UNSIGNED_BYTE, face_img_c); check_gl ();

//top, +ve y
fprintf (stderr, "... loading cube face 4\n");
__loadSubImageC (img_c, face_img_c, face_width, face_height, face_width, 0, width, height);
__imgFlipHorizontallyC (face_img_c, face_width, face_height);
glTexImage2D (GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB, face_width, face_height, 0, GL_RGB, GL_UNSIGNED_BYTE, face_img_c); check_gl ();

// bottom, -ve y
fprintf (stderr, "... loading cube face 5\n");
__loadSubImageC (img_c, face_img_c, face_width, face_height, face_width, 2*face_height, width, height);
__imgFlipHorizontallyC (face_img_c, face_width, face_height);
glTexImage2D (GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB, face_width, face_height, 0, GL_RGB, GL_UNSIGNED_BYTE, face_img_c); check_gl ();

// back, +ve z, its upside down in the image
fprintf (stderr, "... loading cube face 6\n");
__loadSubImageC (img_c, face_img_c, face_width, face_height, face_width, 3*face_height, width, height);
__imgFlipHorizontallyC (face_img_c, face_width, face_height);
glTexImage2D (GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB, face_width, face_height, 0, GL_RGB, GL_UNSIGNED_BYTE, face_img_c); check_gl ();

free (img_c);
free (face_img_c);
}

// set some default properties
glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); check_gl();
glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); check_gl();
glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); check_gl();
glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); check_gl();

unbindCubeMap ();

glPopAttrib ();
return texId;



Here are the shaders I am using:


// vertex shader
//
varying vec3 normal; // normal in our eye space

void main () {
normal = normalize (gl_NormalMatrix * gl_Normal);
gl_Position = ftransform ();
}

// fragment shader
//
uniform samplerCube cubemap;
varying vec3 normal;

void main (void) {
vec3 n = normalize (normal);
gl_FragColor = textureCube (cubemap, n);
}

verma
03-07-2008, 09:39 PM
Sorry, forgot to mention, :D .. I am using a nVidia GeForce 8600 GTS 256 MB graphics card.

verma
03-07-2008, 09:46 PM
Seems like 16F is working.

Nicolai de Haan Brøgger
03-07-2008, 10:44 PM
Hmm, what is the size of your cube map textures (face_width, face_height)? Have you tried reducing these values when you supply the data for GL_RGB32F_ARB ?

verma
03-07-2008, 11:35 PM
256x256, the entire cube cross texture is 768x1024.

-NiCo-
03-08-2008, 12:32 AM
I believe GL_LINEAR filtering is not supported for 32 bit fp textures.

verma
03-08-2008, 12:47 AM
hmm .. that could be the case, I cannot test it right now, but as soon as I am able to I will try using GL_NEAREST and see if it works. However if this limitation exists, it should only apply to GL_TEXTURE_CUBE_MAP because I have been able to specify upto GL_LINEAR_MIPMAP_LINEAR for GL_TEXTURE_2D.

-NiCo-
03-08-2008, 01:00 AM
That's possible. I know that up till the GeForce 7 series linear fp32 filtering does work but it uses a slow software fallback implementation. Maybe it hasn't been implemented for cubemaps.
I'm not 100% sure it's not supported on GeForce 8 series but I recall reading that it's one of the reasons that it's a DX10 card and not a DX10.1 one.

Seth Hoffert
03-08-2008, 07:32 AM
I can confirm that fp32 filtering does indeed work with cubemaps on the 8800. :D

If it helps, this is the code that worked for me:


void loadFloatCube(GLuint dest)
{
glBindTexture(GL_TEXTURE_CUBE_MAP, dest);

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

GLfloat data[512 * 512 * 3];

for (unsigned int i = 0; i < 512 * 512 * 3; i++)
{
data[i] = static_cast<GLfloat>(rand()) / (static_cast<GLfloat>(RAND_MAX) + 1.0f);
}

for (unsigned int i = 0; i < 6; i++)
{
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB32F_ARB, 512, 512, 0, GL_RGB, GL_FLOAT, data);
}

glGenerateMipmapEXT(GL_TEXTURE_CUBE_MAP);
}


Maybe it has something to do with an 8600 limitation, although this would be strange.

verma
03-10-2008, 01:22 PM
hmmm .. interesting. I am using cubemaps as part of a bigger project. May be I need to run some Cubemap and RGB32F_ARB exclusive tests to figure if the problem is because of a Hardware limitation or something stupid on my part.

Thanks though.