2
\$\begingroup\$

I've implemented a sprite batch class that uses a sampler array so that I can select a texture to use based on the gl_PrimitiveID. The idea was to be able to draw sprites that use different textures in a single draw call. I've managed to get it to compile the shaders and run, but the sampler indexing part does not seem to work, although I did not get any OpenGL error. I've done a bit of research and found out that it doesn't seem possible to index into a sampler array with an index that is not a compile-time constant or uniform variable.

Am I doing something wrong or is building a texture atlas the only way to draw sprites that use different textures at once?

\$\endgroup\$
1
  • \$\begingroup\$ You should be able to pass the samplers using uniforms, but don't forget that there are always limits to the number of uniforms, textures, etc. you can work with. Unfortunately I don't think there's an easier solution than either packing your textures together like you said, or intelligently batching your draw calls that use the same textures together to minimize the amount of sampler changing. \$\endgroup\$ Jun 18, 2011 at 20:09

3 Answers 3

3
\$\begingroup\$

You can use multitexturing to do this - because you can bind a different texture to each texture unit you can then use your uniforms to select which one. The limit is hardware dependent, but usually no less than 8 and very occasionally as small as 4.

http://www.opengl.org/resources/code/samples/sig99/advanced99/notes/node60.html

Multitexturing predates shaders so support is fairly global.

This does mean not using a sampler array and instead using your own logic - "just" unroll a binary search, or even better use some bit magic.

It is however fastest to use one texture for all calls and for it to be an atlas of some kind.

\$\endgroup\$
2
  • \$\begingroup\$ Note: if you're using fixed-function, NVIDIA only supports 4 textures (4 texture coordinates, 4 texture environment stages, and 4 texture accesses). \$\endgroup\$ Jul 16, 2011 at 9:02
  • \$\begingroup\$ Thank you for your answer, I think that's the best approach. \$\endgroup\$
    – Trillian
    Jul 16, 2011 at 12:45
2
\$\begingroup\$

Am I doing something wrong or is building a texture atlas the only way to draw sprites that use different textures at once?

It is not necessarily the "only" way, but it is the best way. It is the way that works on anything, from the lowly Voodoo 1 all the way to the Radeon 6990. It doesn't require shaders (though they can be useful with this).

All it requires is a bit of pre-processing on your end to put all of the images in one large image. This is hardly an onerous burden.

That being said, how many sprites do you intend to draw per frame? If it's less than a couple of hundred, an atlas isn't that important to your rendering performance. Texture atlases matter most for things like particle systems and fonts, because you're drawing lots of them.

\$\endgroup\$
0
\$\begingroup\$

The MSDN documentation for HLSL seems to think that you can only do this in Direct3D 10. Of course, OpenGL and Direct3D don't always exactly match their functionality, but it's usually pretty close, since the same cards target OpenGL and DirectX.

It could be that it is legal- just not for a target of the version that you are using.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Could you give the link to the specific MSDN article of interest? Thanks. \$\endgroup\$
    – Trillian
    Jun 18, 2011 at 18:28
  • \$\begingroup\$ This isn't quite right... \$\endgroup\$
    – jheriko
    Jul 16, 2011 at 3:08
  • \$\begingroup\$ to clarify there are very old ways around this which predate DX10. I think you are refering to the specific problem with sampler arrays. Also, do not consider DX and OpenGL to be close... they might be at points but GL has potential to run ahead until DX catches up... sometimes by many years (hw tesselation) \$\endgroup\$
    – jheriko
    Jul 16, 2011 at 3:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .