Hello Guest

Is there a texture count limit? Hundreds of small textures VS few big textures?

  • 13 Replies
  • 16740 Views

Mainly you will be limit to the VRAM.

But does a tileset really have to exceed the 1024^2 llimit? Modern graphiccards support 2048^2 and even 4048^2 but those are rare i guess.

As for speeding up try to put as many as possible tiles on your 1024^2 texture and order them in their usage. Maybe you could create even a tmp texture that fits all tiles in one texture if there aren't that many tiles on the screen.

Right now I ended up creating a "bigimage" system which takes care of loading textures without exceeding the size limit in a hidden manner, and now my draw methods check if the texture is split or not and deal with it. There's a low performance hit when the tileset texture is split in two parts, but most computers seem able to load at least 1024^2 textures. Works fine for now ^^

Anyhow, is it better to have one tileset texture rather than one texture per tile? (I'm talking about non-split Tileset, just one texture)

Yes it is better as you don't have to bind the current texture over and over again. Image 100 single texture tiles each a seperate file. To display them you have to bind each of them to have them displayed. With just several bigger textures holding your tiles you will only need to bind thus few and access the individual tiles via glTexSubImage =)

glTexSubImage? I didn't know anything like that existed, I was doing

Code: [Select]
private void _drawEmbeddedFull(float x, float y, float w, float h, float sx, float sy, float sw, float sh) {
float fsw = sw / (float) _iWidth;
float fsh = sh / (float) _iHeight;
float fsx = sx / (float) _iWidth;
float fsy = sy / (float) _iHeight;

GL11.glTexCoord2f(fsx, fsy);
GL11.glVertex3f(x, y, _iZ);

GL11.glTexCoord2f(fsw + fsx, fsy);
GL11.glVertex3f(x + w, y, _iZ);

GL11.glTexCoord2f(fsw + fsx, fsh + fsy);
GL11.glVertex3f(x + w, y + h, _iZ);

GL11.glTexCoord2f(fsx, fsh + fsy);
GL11.glVertex3f(x, y + h, _iZ);
}

What's glTexSubImage for?

Oh, my fault. glTexSubImage is used to replace partial areas of an existing texture. Therefor your texture coordinate approach should be fast enough for the editor. Maybe for the game itself a texture of the lvl created with the help of glTexSubImage might be usefull.

Well everything seems fine, then. Thanks for your help, Evil-Devil :)


« Last Edit: March 06, 2010, 02:44:03 by lainmaster »

Hi,

don't use glVertex*d and glTexCoord*d - use the float versions of these calls.
Also you should use ARBTextureRectangle and not the NV* version.

You should check if your HW supports texture stacks - this way you can load several same sized images into one GL texture and select which layer to render via the 3rd texture coordinate. This is similar to 3D textures but without mipmapping on the layer (3rd coordinate). But this check has to be a runtime check as this extension is not available on older HW.

Ciao Matthias

Hi,

don't use glVertex*d and glTexCoord*d - use the float versions of these calls.
Also you should use ARBTextureRectangle and not the NV* version.

Tested both things separately, neither seemed to change the FPS at all. Both at the same time didn't change FPS either.

You should check if your HW supports texture stacks - this way you can load several same sized images into one GL texture and select which layer to render via the 3rd texture coordinate. This is similar to 3D textures but without mipmapping on the layer (3rd coordinate). But this check has to be a runtime check as this extension is not available on older HW.

What for?

Hi,

don't use glVertex*d and glTexCoord*d - use the float versions of these calls.
Also you should use ARBTextureRectangle and not the NV* version.

Tested both things separately, neither seemed to change the FPS at all. Both at the same time didn't change FPS either.

Matthias is right about ARBTextureRectangle... NV is an old habit.  They actually do the same thing but one is from before it was put through as a standard (NVidia / EXTension -> Architecture Review Board).

You should check if your HW supports texture stacks - this way you can load several same sized images into one GL texture and select which layer to render via the 3rd texture coordinate. This is similar to 3D textures but without mipmapping on the layer (3rd coordinate). But this check has to be a runtime check as this extension is not available on older HW.

What for?


I believe Matthias is referring to your original tile method.  For instance, if you have 6 images you want to stich together, that is 6 texture binds using the tile method.  If you load the images as the 3rd coord in a 3D texture, you save yourself the extra texture binds (which is expensive, many various engines do a secondary sort of objects to draw as many objects using the same texture as possible).  You then only need to specify which "tile" to use as the 3rd texture coordinate for each quad.

Regarding using TextureRectangle, how much slower are we talking here?  If it's reeaaaally slow, is there any chance you are accidently reloading the texture in your loop?

slow TextureRectangle rendering could also be a sign of bad support by your GPU. Some HW has issues with NPOT textures. Which GPU do you use and which OS?

Also I don't recommend to use a 3D texture (GL_TEXTURE_3D) as this will most likely be slower on many older cards. Texture stacks are available on nVidia starting with the 8800 series.

Another way to speedup rendering is by sorting your sprites/tiles accordingly, either try to draw stuff sorted based on their texture - this only works when they don't overlap, or try to group the sprites/tiles based on their usage. This of course will only help if you remove redundant state changes - like glBindTexture, glBegin/End etc.

Also make sure that you render your tiles 1:1 (without scaling down) - as texture rectangles don't have mipmaps. When you minimize a texture without mipmaps you get a) alias effects b) slower rendering compared to rendering with mipmaps.

It also helps to disable unused features like alpha blending, depth tests/updates, stencil etc. Also never disable individual color channels (glColorMask).

Quote
I believe Matthias is referring to your original tile method.  For instance, if you have 6 images you want to stich together, that is 6 texture binds using the tile method.  If you load the images as the 3rd coord in a 3D texture, you save yourself the extra texture binds (which is expensive, many various engines do a secondary sort of objects to draw as many objects using the same texture as possible).  You then only need to specify which "tile" to use as the 3rd texture coordinate for each quad.

The most consuming part of each frame is the rendering of the map, which is done by layers. The map has 3 layers, read in three for loops (layer > x > y). The tileset texture is bound once for each layer, so it surely isn't a bottleneck. Between each layer, sprites are drawn, but I have never tested my game with more than 3 sprites at the same time, usually only 1 (the player's sprite).
Each sprite has one texture with all the "poses", and only a part of the texture is drawn depending on the animation frame. Either case, it is always one bind per sprite here.

Quote
Regarding using TextureRectangle, how much slower are we talking here?  If it's reeaaaally slow, is there any chance you are accidently reloading the texture in your loop?

FPS normally in the log-in scene of my game: ~670
FPS using the ARB thingy to draw the background: ~660

The difference is pretty much insignificant in this case, maybe for the drawing of the map it could be significant.
But I was expecting to see a bigger difference when drawing, a significant increase of the FPS. At least 20 more FPS for this one image.
Note that the background in this case is drawn without resizing. Normally the background is resized to fit the screen. This should probably be the only image being resized in the entire game.

Things drawn in the log-in scene: an 800x600 32bpp background, a "log in box" with an image background (346x92 32bpp), two text input boxes which are in fact just two rectangles, and the logo (608x236 32bpp).

Quote
slow TextureRectangle rendering could also be a sign of bad support by your GPU. Some HW has issues with NPOT textures. Which GPU do you use and which OS?

GL_VENDOR: NVIDIA Corporation
GL_RENDERER: GeForce 9400 GT/PCI/SSE2
GL_VERSION: 3.2.0
GL_MAX_TEXTURE_SIZE: 8192
OS: Windows 7 64 bits
Available Processors:4
Available VRAM: 512MB
Available RAM: 2GB
Processor: AMD Phenom 9950 Quad-Core Processor 2.60 GHz

Quote
Texture stacks are available on nVidia starting with the 8800 series.
My game is running at over 600 FPS in my computer so it will run at 60FPS in older computers.
It will be an MMO RPG run in an Applet, and the target public is teenagers, who generally can't buy a new computer and may have a rather old one. Also, if a player is not at his own computer and wants to play in whatever computer, he should be able to. So 8800 series would be too high a requirement for my game.

Quote
Another way to speedup rendering is by sorting your sprites/tiles accordingly, either try to draw stuff sorted based on their texture - this only works when they don't overlap, or try to group the sprites/tiles based on their usage. This of course will only help if you remove redundant state changes - like glBindTexture, glBegin/End etc.
In the tested game scene, this is irrelevant, as there are only about 3 images, using a different texture each. This scene is pretty much irrelevant to the game itself, too. The rest of the game consist of rendering of tiles and sprites, which I optimized as much as I could think of.

Quote
Also make sure that you render your tiles 1:1 (without scaling down) - as texture rectangles don't have mipmaps. When you minimize a texture without mipmaps you get a) alias effects b) slower rendering compared to rendering with mipmaps.
Nothing is scaled. I'm 100% sure of this. Although, in other games I'm planning, I'd like zoom in and out, like in Yoshi's Story or Metal Slug 6. (2D as well)

Quote
It also helps to disable unused features like alpha blending, depth tests/updates, stencil etc. Also never disable individual color channels (glColorMask).
All check.

---

Tried to answer everything on this one, phew.

Now, considering my game seems to rune fine in GeForce 6000 series and I want to keep it that way, and that from the test, the ARB thingy didn't seem to make any difference, should I recode a lot what is already working to
use texture stacks?
use the ARB thingy?

Is it worth it?