I want to texture the background of my game with one large texture, but I realize there are limits on texture size and some other issues. First I thought that you could only load square textures, is this true? I tried loading a 640x480 png and mapping it to a 640x480 quad, I think it showed up as a square, I didnt measure the actul pixels, but it wasnt 640x480 thats for sure. so it seems like the next thing to do would be to break it into tiles (four or so would be ideal) and map each to a seperate quad. Which brings me to my next question: I have been told that it could slow things down if I switch textures too often, at what point may this happen, are we talking like 5-10 textures or 100-500? Also, should I not load textures bigger than 512x512, or is there some set limitation?
[quote]First I thought that you could only load square textures, is this true?
[/quote]
No, the width and height have to be of size 2^n + 2 * border where border is either 0 or 1. I haven’t used borders yet, so I’m not sure how to use them or what to use them for.
[quote]I have been told that it could slow things down if I switch textures too often, at what point may this happen
[/quote]
I guess this probably depends on your hardware configuration. IIRC switching the texture object can cause some kind of state validation inside the openGL driver. Each time you do this there is probably some overhead involved. I think the real issue is when the total amount of texture data you want to use in a single frame no longer fits in the texture memory of your graphics card. If you load more image data then there is available memory, the driver needs to replace unused texture data with the texture data you want to use. This can potentially cause lots of data transfer over the AGP bus, which could slow everything down. To optimize this you could for instance sort polygons by the texture they use and render in that order, which would minimize texture switching.
Now I have to say I this is only theoretical knowledge. I have no practical experience in writing this kind of optimized code Maybe one of the other guys can give you more practical advice…
[quote]should I not load textures bigger than 512x512, or is there some set limitation?
[/quote]
You can get the maximum texture dimension from opengl by calling glGetInteger( GL_MAX_TEXTURE_SIZE ). The docs state
[quote]The value gives a rough estimate of the largest texture that the GL can handle. The value must be at least 64.
[/quote]
Ok, that gives me a clearer picture of what I’m dealling with So it seems I need to create a texture that is 1024x512 with some empty space on the edges, or figure out some odd sizes to tile my 640x480 area. I think I like the idea of using the 1024x512 texture bettter, but it seems like loading something that size may take a while. Perhaps I should look into using NIO for that…
Brighten up good news ahead
First, only think about saving on state changes, i.e. using as few texture changes as possbile, when you are going for absolute maximum performance. Yes, rendering a thousand objects with each texture set seperately will be slow, but in your everyday scene, you don’t have as much as a tenth of that visible at once. And all that optimisations tend to mess up your beautifully object-oriented java code.
Second, don’t worry about square textures and the like. You have texture coordinates at hand for all of your faces, so you can make maximum use of your textures by just storing smaller texture pieces into space left in larger textures by non-square images. I know it is tempting to think of textures as logical units (“this is the stone wall texture”) but that’s not The Path Of Light
Check out this article (well, the first few lines) its about lightmaps but applies to all texures you use. http://www.blackpawn.com/texts/lightmaps/default.html
Cheers W.
Addendum: I’m loading six 512x512 faces for my skybox cubemap without any feelable delay (make it under a second) with ImageIO.read(), so don’t worry about load times. Okay, I’ve got Dual-Xeons, but the second processor is idle, I swear.
Aren’t borders used to prevent “cracking” between quads which use textures that have been cut up from a larger image?
SNR
Check out {ARB/EXT/NV}_texture_rectangle (yes, it’s a mess) and ARB_texture_non_power_of_two for rectangle textures. Watch out for implementation limitations and hardware support though.
Yes, the tight mapping demonstrated in the lightmap compression tutorial I referred to above is only suitable if you create your maps computationally and can guarantee that all uv coordinates match perfectly. In a manually painted texture, you usually color the background to average the details you’ve painted, so that small uv gaps will go unnoticed.
Take a look here http://www.ascendancy.at/ascengine/, I’ve included an image of such a texture on the bottom of the page to demonstrate the effect.
Cheers
Wolfgang