Is a 2d tile engine using direct3d feasible?

Started by
4 comments, last by __filip 18 years, 8 months ago
I've been working on a SNES-rpg style tile-engine for a good while now, but it's not really going as planned. The idea of using "tiles" in direct3d seems problematic, since a modest 25x25 tiles per screen results in well over 500 calls to DrawPrimitive, and brings my relatively good computer down to a crawl. (At least I'm assuming the calls to DrawPrimitive are the culprit. If 500 isn't really a lot then I'll have to look elsewhere for the problem.) Is DirectDraw or some other 2d API a better option, or is there some trick to getting such a tile-engine to run well using D3D?
Advertisement
Direct3D should work fine. Just make sure you put as many tiles as posible in the same texture to minimize the number of calls to DrawPrimitive. If you put all tiles in the same texture you only have to call DrawPrimitive once. Don't call DrawPrimitive once for every tile.
As __filip mentioned, you should avoid DrawPrimitive() calls as much as possible. Put your tiles into one texture, change the texcoords of each quad and draw all tiles at once.

Alternatively you could use ID3DXSprite, which does this automatically, and is very fast and easy to use.
I've been drawing the same six vertices of a tile translated to each of the possible locations. At the highest level, that allows me to draw the tiles just like I would using Directdraw.

But I guess what I should be doing is creating a large grid of the whole map in the vertex buffer, and drawing it all at once? Come to think of it, that makes a lot more sense, and I should probably try it that way.
Quote:Original post by bjle
But I guess what I should be doing is creating a large grid of the whole map in the vertex buffer, and drawing it all at once? Come to think of it, that makes a lot more sense, and I should probably try it that way.

That's one way of doing it.
Just to give you some ideas, here's how I handle it in my 2D engine. I have drawQuad() method in my renderer class. This method adds 6 new vertices to an list of vertices. Then, at the end of a frame, I draw all of these with one DrawUserPrimitives() call (that's DrawPrimitiveUP in unmanaged DirectX), and then vertex list is cleared.
I haven't done any serious stress-tests yet, but it seems to be working just fine.

A few tips:

Don't put your whole map in one vertex buffer, that will just lead to a lot of unnecessary culling (I assume you don't use index buffers). Instead split your map up into smaller "chunks". A chunk may for example represent 32x32 tiles. Create one vertex buffer for each chunk and only render those chunks that are visible (completely or partially). This will be a lot faster than using only one vertex buffer for large maps. For a small map you can use just one large vertex buffer. To speed things up even more you should look into index buffers and the function DrawIndexPrimitive().

This topic is closed to new replies.

Advertisement