Sprites on Videocard, GRRrrrr!

Started by
11 comments, last by Thevenin 15 years, 11 months ago
I'm going in big circles here, I don't know how to store sprites on the video card for my 2D game. I cannot put a "power of 2" constraint on my textures, because most are not even known at compile time, and I cannot restrict proper rendering of the game to people who have top-of-the-line video cards that can handle "non power of two" without issues, because my target audience is not main-stream gamers. What should I do?
Advertisement
Theres probably a better solution, but you could just pad the non-power of 2 textures with transparent pixels on the appropriate dimensions.
But some are really small and numerous (easily hundreds of them), and others may have very strange dimensions (for instance, 1x100). [disturbed]
I think you want to use a texture atlas, so that you can have all your sprites on as few textures as possible. That way you can use each sprite just based on its texture coordinates, and you can pack all of them into one big power of 2 texture.
Quote:Original post by Funkymunky
I think you want to use a texture atlas, so that you can have all your sprites on as few textures as possible. That way you can use each sprite just based on its texture coordinates, and you can pack all of them into one big power of 2 texture.


No. That extension takes in power-of-two textures, and forms cumulative power-of-two-textures. My sprites are not power-of-two textures to begin with.
Quote:Original post by Thevenin
Quote:Original post by Funkymunky
I think you want to use a texture atlas, so that you can have all your sprites on as few textures as possible. That way you can use each sprite just based on its texture coordinates, and you can pack all of them into one big power of 2 texture.


No. That extension takes in power-of-two textures, and forms cumulative power-of-two-textures. My sprites are not power-of-two textures to begin with.
It's easy to extend the code to use non-power-of-2 textures though, it just means you have a bit more book keeping. One example way you could do it, is to keep track of what 8x8 texel blocks are in use on the texture, and to search for a large enough free space when adding a new sprite. That'll give you a little wasted space, but will make book keeping much simpler, because you'll be working with a grid system.

This is effectively what I do in my engine (Although I use power-of-2 textures everywhere).
Quote:Original post by Evil Steve
Quote:Original post by Thevenin
Quote:Original post by Funkymunky
I think you want to use a texture atlas, so that you can have all your sprites on as few textures as possible. That way you can use each sprite just based on its texture coordinates, and you can pack all of them into one big power of 2 texture.


No. That extension takes in power-of-two textures, and forms cumulative power-of-two-textures. My sprites are not power-of-two textures to begin with.
It's easy to extend the code to use non-power-of-2 textures though, it just means you have a bit more book keeping. One example way you could do it, is to keep track of what 8x8 texel blocks are in use on the texture, and to search for a large enough free space when adding a new sprite. That'll give you a little wasted space, but will make book keeping much simpler, because you'll be working with a grid system.

This is effectively what I do in my engine (Although I use power-of-2 textures everywhere).


It becomes a totally different story when you don't use power-of-2 textures.

And no, using 8x8 texal blocks is going to cause too much waste, let alone the performance hit of excess texture binds (since I'd unlikely code the grid system to find optimal slots for placement).
It's not too tricky to write some code to pack sprites into a texture atlas dynamically and deal with non-POT sprites. As new sprites are loaded you try and find space in an existing atlas and place it there, or if there isn't enough space you create a new texture atlas and place it in there instead. You'll get some wasted space, but it'll be minimal overall.

Bear in mind that this is 2d
">bin packing, so it's NP-hard, but there are some simple heristic algorithms that work effectivly. If you load sprites in bursts then "First Fit Decreasing" should work nicely. If you load sprites at various points and not in batches then you might have better results by specifying different bins to deal with different ranges of sprite sizes (eg. a bin for anything under 32x32, a bin for anything with a width < 16, etc. etc.).

Memory allocators often face similar problems (dealing with allocations of varying sizes and avoiding wastage and fragmentation) so googling for algorithms used for those would be a good idea too.
No. It's incredibly tricky (alot harder than level 37). Batching cannot be used on my code -- the sprites need to be available as soon as they are allocated. I'm not about to spend the rest of my summer designing a bin-packer that fits my criteria; there is no System.Binpacker already made for me.
Quote:Original post by Thevenin
No. It's incredibly tricky (alot harder than level 37). The sprite sizes are arbitrary -- the only assumption I can make is that they are probably going to be less than 1024x1024 in size.
And they have to be available readily -- meaning no batching.

I think you're over thinking this. Allocate one or more large textures (say, 1024x1024), then after you've loaded your raw pixel data copy it into an unoccupied portion of the texture atlas. If it won't fit in any current atlas because of existing sprites then allocate a new texture and place it in there.

What's wrong with doing this?

This topic is closed to new replies.

Advertisement