Feal87's Blog

Just another programming weblog.

Scrapping out the ID3DX10Sprite / ID3DXSprite interface

Posted by feal87 on May 31, 2009

One of the first things I’ve thought useful for my engine to have and ironically one of the last I’ve actually implemented is a remake of the default interfaces given by the extra DirectX library D3DX for drawing sprites. (2D images over quads in an orthogonal projection basically)

The reason driving me to remake these classes was about improving speed and increasing flexibility. While the default classes had the basic functionality to draw 2D images, it lacks support for custom shaders and other functionality needed in my domain. Another particular note that influenced my decision was the fact that the two classes for DirectX9 and DirectX10 had different behaviour and contract and I wanted an unified behaviour and contract for my applications.

The first thing I’ve done when I decide to start developing the classes was brainstorming. I suggest anyone that is starting a big change in their own code to think and write down what exactly do you want and how you want to make it. I figured out several ideas about how to organize the new classes :

1) Using a dynamic vertexbuffer and index buffer. Inside them adding new values each time a call is performed. Then executing several draw with different vertex offsets. (Basically the same thing that the default class does)
2) Using a dynamic vertexbuffer and index buffer and a special automanaging texture that contained all the textures to draw. When the end function is called it calls a single draw to draw everything.
3) Using a static vertexbuffer with a quad inside (trianglestrip to save memory) and draw multiple time with different world coordinates each time a call is maked.

I personally thought the first choice was quite inefficient, updating a lot of times the vertex/index buffers was not my style so I skipped thinking about this implementation.
The second choice was quite alluring, but automanaging a special texture was a quite difficult task and I didn’t know if there were any gains in speed. (I think I’ll give it a shot anyway in the near future ;))
The third choice, the one i choose, was the most simple and “effective” in my opinion. I only needed to update the world matrix and the texture each time I drawed a new quad.

Sprite Alternative Class

Sprite Alternative Class

 The contract given by the class is quite straightforward. Let’s analyze it (I’ll skip the Begin/Draw/End that I’ll analyze after) :

1) The Buffer property is the static vertex buffer containing the quad that has the protected modifier to allow the derived class to modify it.
2) The ProjectionMatrix and ViewMatrix properties allow the user to choose which transforms to use for a particular rendering.
3) The Dispose method that release all the resources used by the class. (VertexBuffer and Effect basically)
4) The LoadContent and UnloadContent that load and unload the resources used by the class in the various circumstances. (Lost Devices, Resets etc..)
5) The constructor.

Sprite Alternative Process

Sprite Alternative Process

Using the new class is quite straightforward.

1) The call to SpriteAlternative.Begin() initialize all the states/effects needed for the draws to occur.
2) The calls to SpriteAlternative.Draw() change the WorldMatrix and Texture and actually make the Draw call.
3) The call to SpriteAlternative.End() closed the effect. (Only needed in DX9 while in DX10 just does nothing)

While i did not gain a lot of frames in the process (almost 0,779 ms each frame on a 3,6 ms application and -10% on the CPU utilization on the same application), I did learn a lot from this experience and now I have a solid base on which to base various personalization (deriving from the SpriteAlternative class and giving out personalized shaders and other features…).
I suggest anyone reading this article to have a shot to recreate their own Sprite class, it is a nice experience.

I hope this has been a helpful reading for you all,
The next topic I’ll talk about is the remake of the ID3DX10Font/ID3DXFont classes,

See you later. 😉

Leave a comment