DirectX sprite performance

Started by
13 comments, last by jnye 19 years, 2 months ago
I've written my own 2D sprite class using pre-transformed vertex coordinates. Everything works great, but it just doesn't seem like I can get the perfomance I need out of DirectX. I need to display over 100 sprites on screen (each with a different coordinates and different texture). It seems like DirectX should be able to handle this, but I can't seem to do anything to improve the performance. I've heard locking/unlocking the vertex buffer is a performance hit, but I've rewritten everything to eliminate this and still no change. Just for testing, I've pretty much minimized the calls to SetTexture, SetStreamSource, etc. and still no improvement. I've tried 1 vertex buffer vs. a vertex buffer for each sprite, hardware/software processing, and different memory pools...all to no avail. It seems that calling DrawPrimitive over 100 times is too slow, not matter what I do with everything else. Is there any way to reduce the DrawPrimitive calls even though I need to change textures often? Any recommendations or ideas? Thanks.
Advertisement
Have you tried using D3DXSprite, it's optimized pretty well.

Recent Topic
I'm trying that now, but would prefer not to use it.

I would like to maintain a little more control over my class. Do anyone know if D3DXSprite automatically handles breaking textures down if they are larger than the video card supports? Also, doesn't D3DXSprite blur the sprite...I want an exact image of my source file.
This article might interest you.

Dissecting Sprites in Direct3D
Yeah, I read that and it all makes sense. But still doesn't solve the performance issue.

I did notice this posted in the forum discussing the article:

6. Try to use as little DrawPrimitive as possible. I.e. to draw 100 spries on screen dont call DrawPrimitive 100 times. Instead create and fill an array of 100x3x2 vertices and DrawPrimitive( TRIANLELIST ) once with those.

Is there a way to do this with multiple textures? Or is this assuming one big tuxture for the call to DrawPrimitive (which is not very realistic with 100 sprites).
If all your sprites use the same texture you only need one call to drawprimitive

1. Put all your sprite bitmaps in the same texture and use texture coordinates to access the various sprite.

2. Create a vertex buffer that can hold all 100 sprites. Use a temp array, something like vector<VertexType> Temp. Draw functions save verticies to this array.

3. When all drawing is done lock your vertex buffer and copy the temp array to the vertex buffer.

4. set states, ect and then call
DrawPrimitive(D3DPT_TRIANGLELIST,0,(m_verBatch.size()/3));
I use trianglelist because I want to, others use D3DPT_TRIANGLESTRIP which uses fewer vertex.
If you can't combine all sprites into one texture use as few as possible and use one drawprimitive call for each texture.
I tried D3DXSprite and it increased performance a little bit, but far from acceptable.

I guess I need to get all of my sprites onto 1 texture to really get the performance I need.

However, this would require a larger texture and I need to guarantee my game will run on older video cards. If I stick to 256 x 256 textures, I will still need to switch textures and call DrawPrimitive almost as often as I am now.

Any additional suggestions?
Sorry, I posted that last message at the same time as you.

Even with my sprites on a few different textures, I will need to switch back and forth constantly because of drawing order. I'm not sure if this solves my problem.
I use a 512 x 512 texture to hold all sprites on my app. Also look up drawindexedprimitives as this can help reduce vertex count. Also if you use a z coordinate in the vertex data that way sprites are drawn at various levels. I am not sure exactly what your trying to do though.

This topic is closed to new replies.

Advertisement