2
\$\begingroup\$

I'd like to use texture images that are not a sprite sheet or other form of texture atlas, mainly because I'll be consistently adding and swapping textures while I figure out the direction my game takes.

In Java, I'm using slick2d's TextureLoader to load a texture, and then I bind it with an unique id. However, when not using a spritesheet I have many more images to bind, which causes a potential performance problem. I've noticed that calling glBindTexture for every block I'm drawing is bad, it drops my FPS to 1.

I'm already rendering blocks with glCallList so I've found a middle-ground. I bind a single block texture and then render all blocks of that type in the chunk, and repeat for each unique block type. However, that's still less than preferable.

Is there a better way to efficiently use multiple textures without an atlas or sprite sheet?

\$\endgroup\$
5
  • \$\begingroup\$ Please clarify, are you using sprites or texture mapping? It sounds like you want a texture atlas and vertex buffers. Ditch glCallList in favor of VBOs. And never EVER use glBegin(...) / glEnd()! \$\endgroup\$ – MickLH Dec 1 '13 at 8:18
  • \$\begingroup\$ "I've noticed that calling glBindTexture for every block I'm drawing is bad, drops fps to 1." I belive even if you do this it shouldn't be 1 fps! unless you're drawing millions of blocks. Maybe you are doing something else wrong. \$\endgroup\$ – concept3d Dec 1 '13 at 8:23
  • 1
    \$\begingroup\$ are you using immediate mode ? don't do that :) \$\endgroup\$ – concept3d Dec 1 '13 at 8:27
  • \$\begingroup\$ I'm going to contradict the other comments here - immediate mode is slower, but it's not that slow. Quake and Quake 2 used immediate mode but they didn't run at 1fps. You're most likely doing something else wrong, but it's difficult to guess what it might be from your description. \$\endgroup\$ – Maximus Minimus Dec 1 '13 at 11:28
  • 2
    \$\begingroup\$ If you're going to be constantly adding and swapping textures, it sounds worth investing in a tool (maybe offline, maybe running at load time in your game engine) to automatically build atlases from discrete textures. Then you can have the best of both worlds. \$\endgroup\$ – Nathan Reed Dec 18 '13 at 7:36
1
\$\begingroup\$

It seems very odd that you see the performance of your game fall to 1 FPS. It's likely there is more to that than just the texture binding, but that is not really relevant to the issue, because it is still true that binding a new texture for every draw call is expensive and will have some negative impact on performance, which you are looking to alleviate.

Unfortunately, the technique of using texture atlases is designed to help combat exactly the problem you are seeing (a sprite sheet is just a specialized texture atlas where every sub-image is stored in a cell in a regular grid).

State changes on the GPU are slow and should be down as infrequently as possible. This includes changes of texture and shader state. In your case, you're changing the texture every time you render a new object, which is just about the worst-case scenario you can have without being intentional about degrading performance.

Minimizing state changes improves performance, and your middle ground solution (to draw everything using the same texture at once) does eliminate a lot of state changes. It's a valid approach, and one that is commonly used.

Sprite sheets or texture atlases allow you to further minimize your texture state changes, and are consequently superior if you can use them.

So unfortunately, the answer to your question is you can't improve this scenario(*) beyond what you have described as your middle ground solution or using the sprite sheets you explicitly don't want to use.

(*) I am speaking only of the texture-state-change-related performance, obviously. I still suspect that something else is wrong in your code, but that's neither here nor there.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.