Skybox texture size

Started by mstWeal, August 14, 2010, 16:40:04

Previous topic - Next topic

mstWeal

Hello everyone,

I've made a skybox for my game with 2 different textures. I use these 2 textures for the six sides of the cube for the skybox. Now, I have a graphics card and monitor that is capable of a resolution of 1680 x 1050.

If I use textures that are of size 1024 x 1024 the skybox quality isn't that good at that screen resolution. So I made textures with a size of 2048 x 2048. They look good but they need very long to load (about 1.5 seconds for both textures on my relatively fast machine) and they need a lot of memory (about 200 megs).

Now my question: How do you create your skyboxes? Is there a way to get better loading time and much less memory consumption using such big textures? Or is the only way to "glue together" the skybox out of several smaller images for example?

mstWeal

Ok, I had a memory leak in my texture loading code. I could fix it and the big textures are now no more problem I think.

But I think my texture loading code could still need improvement. Right now I basically load a BufferedImage with ImageIO.read(File). The problem is, that I still need to copy that buffered image to another buffered image so that I can manually set the correct color model. If I directly use the image returned by ImageIO.read(File) everything looks blueish.

Basically the copy is not a huge problem but it causes the memory consumption to go pretty high in the beginning (to about 120 meg with my app now) and then all of a sudden it drops to 70 megs. I think it's also not so fast.

Here is the piece of code:
                ... Setup texture environment

                // Create an appropriate color model and raster.
		ColorModel glColorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[] { 8, 8,
				8, 0 }, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
		int rasterBands = 3;
		if (image.getColorModel().hasAlpha()) {
			rasterBands = 4;
			glColorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),
					new int[] { 8, 8, 8, 8 }, true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);
		}
		WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, textureWidth, textureHeight,
				rasterBands, null);

		// Copy the source image into a new image with the created color model and raster.
		BufferedImage texImage = new BufferedImage(glColorModel, raster, false, new Hashtable<String, Object>());
		texImage.setData(image.getData());

                ... Create buffer and pass it to OpenGL


If anybody knows how to possibly improve this please let me know.

bobjob

in order to load the image only once, try using the color format GL12.GL_BGR instead of GL11.GL_RGB

mstWeal

Wow awesome! Great that works thank you very much. How did you know that?

Matthias

You could also try TWL's PNGDecoder (also available as a stand alone JAR) - it can decode directly into a ByteBuffer. This saves you several unnecessary memory copies.