Large bitmaps

I have many (~100) bitmaps that I draw in the same frame. Currently, it is done with many Draw calls. Many of bitmaps are 256x256 pixels.

I am thinking of merging the bitmaps into one big bitmap, which would enable me to use one single call to Draw(). However, this single bitmap would be very big, and I think there are limitations (PC graphic cards environment). The reason I want to do this is to improve performance (drawing time).

Would it be possible to create the big bitmap directly on the GPU, from many sources?

I would be grateful for any pointers on how to do this, or other advice.

If needed, I can shrink the current bitmaps some, but not too much.

You can store the images into

  1. a 3D texture or
  2. a layered texture containing each image in a separate layer

Thanks, 3D texture looks like what I want, using glTexSubImage3D() for each bitmap I want to load.

There is a thing I am uncertain about, and that is how to index into this 3D data structure from the shader. ‘s’ and ‘t’ will be used the same way as usual 2D arrays (ranging from 0 to 1). But the depth is used to access different bitmaps, and I suppose I need to index with 0-1 for depth also. If there are 100 bitmaps, I would have to use n/100 for ‘r’, where ‘n’ is the bitmap I want to use?

I am using mipmaps currently. Are mipmaps for 3D textures also 3D?

What about GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER? Obviously, I want filtering for ‘s’ and ‘t’, but not for ‘r’.

You’ll want to use a GL_TEXTURE_2D_ARRAY. This is a 3D texture, but without any filtering between layers. The texture index (‘r’ coord) is conveniently in 0…N-1 coords, rather than 0…1. You’ll need OpenGL 3.0 or GL_EXT_texture_array to use these. See 3.9.1 of the GL3.0 spec for more information.

I’m not sure if 3d textures or texture arrays are what you really want (it depends on what data you have and what you want to render).

Many modern games store textures in atlasses. They pack (google “bin-packing”) the textures in to a larger 2d texture, and either modify the texture coordinates (may involve splitting the geometry in case of tiling) or ‘unpack’ the atlas in the shader when sampling the texture.

nVidia has a set of tools to build and process atlasses, as part of “nVidia Texture Tools”, free to download from their website.

The bitmaps are not “unreasonably” large, so using GL_TEXTURE_2D_ARRAY seems to be just what I wanted.

Thanks for the advice!