DirectX Textures for Tile-Based Games

snarfblam

Mega-Ultra Chicken
Joined
Jun 10, 2003
Messages
1,832
Location
USA
User Rank
*Expert*
Im really into old school video gaming (i.e. NES/SNES/Genesis). Im getting into DirectX, using Direct3D to make 2D games. Given a bitmap that contains a number of tile images (i.e. a tile sheet, aka sprite sheet), does anyone have any tips for loading up the bitmap and chopping it into textures (one texture per tile)? Or any other relevant recommendations while we are at it? Ive only started learning yesterday, so any advice would be helpful, and it seems to be pretty difficult to find specific, helpful information on the topic.
 
Texture coordinates

If youre using Direct3D, then there may be no need to chop up the textures. Textured vertices have a tu/tv component which allows you to specify which parts of the texture to apply to the primitive. For example, say your image is made up of 100 frames arranged in a row-ordered 10x10 grid; rather than chop up the texture, make it so that your vertices use tu/tv values in increments of 0.1.

[0,0][0.1,0.1] would be the first frame, [0.1,0][0.2,0.1] would be the second frame, [0,0.1][0.1,0.2] would be the 11th frame, and so on.

Good luck :cool:
 
What I have right now is a grid of vertices where vertices are stored in a single vertex buffer and shared between tiles. That is, the right two vertices of the tile at (10,10) are the two vertices that are used for the left of (11, 10). In order to do this I need to have tu/tv coordinates that correspond to the grid. In other words, the vertex at 7, 4 has value of tu = 7, tv = 4. It seems like a more efficient (albeit less dynamic) way to use memory. If it becomes necessary, though, I will define four vertices per tile.

My other concern then is that it would be difficult to ensure that the texels align with the screen pixels when using fractional texture coordinates. Is this common practice? If I am off by even a tiny amount, wouldnt it cause the texture to be stretched and bilinearly (or anisotropically or whatever) filtered?
 
Last edited by a moderator:
Avoid shared vertices

marble_eater said:
My other concern then is that it would be difficult to ensure that the texels align with the screen pixels when using fractional texture coordinates. Is this common practice? If I am off by even a tiny amount, wouldnt it cause the texture to be stretched and bilinearly (or anisotropically or whatever) filtered?

For 2D applications, I would expect this to be fairly common practice. In my experience it is fairly simple to ensure the texture coordinates do not overlap into neighbouring tiles assuming you dont have huge textures (eg max 1024). The usefulness of this approach is even more evident when you have animated sprites.

I realise that I didnt explain the other main reason why this single-texture approach is preferable - you can render more primitives at a time. Whenever you render primitives, the current texture is applied to all of them. If they are all taking slices from the same common texture, it is possible to render the entire lot with a few rendering call. However, if each primitive uses a different texture, you can only render a few sprites at a time (those with the same tile), which is difficult to optimize.

Regarding using shared vertices, that is unlikely to work with either method, as youre forced into either having adjacent primitives use adjacent texture tiles (if using a single texture), or rendering each primitive individually (if using multiple textures).

:)
 
I understand that rendering multiple textures without changing the texture or, better yet, with a single call to DrawPrimitives is faster than setting the texture and rendering each tile, but what I am programming is intended to be a re-usable engine with capabilities similar to that of the NES or SNES (if you are familiar), in which case said optimizations are difficult to implement.

Another concern is that older hardware will have issues with the larger textures and fractional texture coordinates that would be used for sprite sheets. I have heard of similar problems on older hardware using MDX. I would hate to get far into the process of creating an application only to find that there was a graphical issue with a fundamental aspect of my rendering engine.

I know I sound awfully stubborn, but dont get the wrong idea. Im just voicing my thought process. I am considering using your proposed solution.
 
Chop with GDI+

Okay, back to your original question. Looking through the SDK doesnt inspire confidence in chopping up textures once theyve been loaded. However, the Texture class has a constructor which takes a Bitmap parameter (there is also a static FromBitmap method), so you could use GDI+ to do the chopping and then just create textures from that.

Good luck. :cool:
 
The idea has already occurred to me, but I am reluctant to use that method. In my experience, tile-based operations with bitmaps tends to be very slow in GDI+. But right now my options are either that or the use of texture coordinates.
 
When using your most recent suggestion the load time for the textures is exceptionally long. My current solution is to draw tiles onto a tile sheet, load the tile sheet, use GDI+ to chop it up, create an array of textures, save the textures to a single file, and load textures from that file at runtime. It sounds like a difficult process but I have it automated for the most part and the load time is significantly smaller.

I will try your recommendation of using a single texture and fractional coordinates, but I am a little uneasy about the fact that tile data is stored in the vertex buffer, which adds a layer of complexity to the whole operation. When doing something such as animating a particular tile, instead of simply changing a tile index each frame, I will have to lock the buffer, update the texture coordinates, then unlock the buffer.
 
Maybe XNA Would Help You?

I know that you use C# Express, so I thought you might be interested in the XNA framework. I dont know if you are using MDX out of choice, or just didnt know XNA is out there; however, this website, http://www.xnadevelopment.com/tutorials.shtml, has some pretty cool examples of basic XNA development. XNA is still in beta 2 so some things may change, but its alot easier to get an XNA Hello World, than an MDX Hello World, at least in my opinion.
 
I specifically chose MDX over XNA because it is more mature and has more support. Currently my only issue is whether I should implement tile sheets by extracting each tile as a texture or by using fractional texture coordinates with a single texture. Unfortunately, both methods seem to have drawbacks (the former uses more resources and takes longer to initialize, the latter requires that I lock my vertices and modify them in order to change tile data).

But thank you for the link. Looks like it will be a great resource when I get myself started with XNA.
 
Back
Top