Problem loading a .dds Cubemap into OpenGL

Started by
4 comments, last by dpadam450 12 years, 6 months ago
Hi, I'm trying to load a cubemap stored in .dds format into OpenGL using DevIL, but it seems I can only read in the "first" cubemap-texture (the one on the positive X-axis). The cubemap is saved correctly (I loaded it in the Directx Texture Tool and DDSViewer), so I don't think there's a problem there. I'm using the code below to load the cubemap. As you see I use ilGetData() to read in the data, but it seems ilGetData() keeps pointing to the beginning of the cubemap instead of "moving on".

ilGenImages(1, &cubeID);
ilBindImage(cubeID);

bool success = ilLoadImage("cubemap.dds");
if (success)
{
	glEnable(GL_TEXTURE_CUBE_MAP);
	glGenTextures(1, &cubeID);
	glBindTexture(GL_TEXTURE_CUBE_MAP, cubeID);
		
	int height = ilGetInteger(IL_IMAGE_HEIGHT);
        int width = ilGetInteger(IL_IMAGE_WIDTH);

	glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH), 
			ilGetInteger(IL_IMAGE_HEIGHT),0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, (ILubyte*)ilGetData());
	glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH), 
			ilGetInteger(IL_IMAGE_HEIGHT),0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, (ILubyte*)ilGetData());

	glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH), 
			ilGetInteger(IL_IMAGE_HEIGHT),0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, (ILubyte*)ilGetData());
	glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH), 
			ilGetInteger(IL_IMAGE_HEIGHT),0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, (ILubyte*)ilGetData());

	glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH), 
			ilGetInteger(IL_IMAGE_HEIGHT),0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, (ILubyte*)ilGetData());
	glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH), 
			ilGetInteger(IL_IMAGE_HEIGHT),0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, (ILubyte*)ilGetData());

	//enable filtering
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP);
	glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP);

	glDisable(GL_TEXTURE_CUBE_MAP);

	return 1;
}

Does someone see what I'm doing wrong please? The DevIL help-files don't even mention cubemaps. Thank you!
Advertisement
What do ilGetInteger(IL_IMAGE_HEIGHT) and ilGetInteger(IL_IMAGE_WIDTH) return?
I believe the cubemap is just a 1x6 (or 6x1) image. If so, try something like

(ILubyte*)ilGetData() + face * width * width * bpp

where face is the number of the face you are trying to access.
deathkrushPS3/Xbox360 Graphics Programmer, Mass Media.Completed Projects: Stuntman Ignition (PS3), Saints Row 2 (PS3), Darksiders(PS3, 360)
ilGetInteger(IL_IMAGE_HEIGHT) and ilGetInteger(IL_IMAGE_WIDTH) both return 256 (which makes sense I think, cause each image in the cubemap is indeed 256x256. Or isn't that the way it works?)

Also, modifiying the pointer to the data, like: (ILubyte*)ilGetData() + 256 * 256 * 4, crashes the application (Memory Access violation error). So I guess, only the first cubemap face gets loaded. Not sure why though.

When I "manually" load 6 different textures (not stored in a cubemap, I mean) in the cubemap, everything works like a charm. So, I think there is something I'm overlooking in my loading code.

Thank you!
I looked at the DevIL documentation and there is an interesting function iluActiveImage. It may be exactly what you want.

EDIT: Wow, the doc is horrible. The correct function name is actually ilActiveImage. There is also a useful #define in the header: IL_NUM_IMAGES. You may want to try ilGetInteger(IL_NUM_IMAGES) and see if it returns 6.
deathkrushPS3/Xbox360 Graphics Programmer, Mass Media.Completed Projects: Stuntman Ignition (PS3), Saints Row 2 (PS3), Darksiders(PS3, 360)
I have the same problem.
A file with 6 faces gets loaded, but ilGetInteger(IL_NUM_IMAGES) give 0 as result.
I can get hold of one image, but ilActiveImage return false if I try to use anything other than 0, which might be consistent with "number of images", but then again, the file has 6 layers!

Any ideas?
Are my dds-files not supported? They come from the rendermonkey examples and can be loaded with GIMP.
Try ilActiveMipmap(1), call ilGetData() and see if the bytes are different in the debugger than the other bytes.

or
ilutGLLoadImage : Loads an image file directly into an OpenGL texture.

The DDS header knows if it is a cubemap apparently, so it might load it properly.

NBA2K, Madden, Maneater, Killing Floor, Sims http://www.pawlowskipinball.com/pinballeternal

This topic is closed to new replies.

Advertisement