Feal87's Blog

Just another programming weblog.

Posts Tagged ‘Sprite’

Remake of ID3DX10Font / ID3DXFont

Posted by feal87 on June 1, 2009

Continuing from where I left at the previous post, I’ll talk about another necessary remake I’ve done for my game engine. As you probably know, the D3DX library contains other than the sprite drawing class, a text drawing class called ID3DX10Font / ID3DXFont. It is based over GDI and use the Sprite class for drawing the text.

As I have deleted the sprite class from my engine references thanks to the SpriteAlternative class, I needed an alternative for the text writing class. Another reason of the remake was that for unknown reason the results of the SAME identical text drawed with the DirectX9 and DirectX10 class was quite different in style.
I had quite a few ways to implement the class :

1) Using GDI/GDI+ create a texture with all the gliphs needed by the text I’m writing and write the characters one by one using different texture coordinates.
2) Using Precreated Bitmap Fonts
3) Using GDI+ to create the textures with the whole text needed and use a cache system to prevent useless recreation of the same texture.

The first method is the same as the basic class offered by D3DX, while it is quite performant, it use a LOT of CPU power (at least on my Core 2 Duo 2.00 ghz) and it is quite intricated (lots of directx calls).
The second method is the method most used by games all over the world, but it not very flexible. Having a different bitmap font for each type of size/style/font is nice if you have to create a particular game and stops there, but with an engine is better to give flexibility even at the cost of speed sometimes.
The third method, the one i choose, is VERY good for static text and still optimal for changing text. Other than that, this method have a very low CPU usage. (the graphics is generated once and just drawed the rest of the times just like any texture with the SpriteAlternative class).

After lots of brainstorming and work the FontAlternative class was born.

Font Alternative Class Diagram

Font Alternative Class Diagram

I’ve created 2 classes, the first, CachedText, is the class that contains the details of a text cached in the system, the second, FontAlternative, is the actual font class.
Let’s analyze the members of the two classes :

CachedText :

1) Colore – Color of the text.
2) Dimensioni – Size of the rectangle where i’m writing.
3) Font – Font using for the drawing. (System.Drawing.Font)
4) Text – Text to draw.
5) Texture – Texture ready to be drawed.

FontAlternative :

1) CacheTesti – A dynamic cache that contains a series of texts already drawed by the system and ready to be drawed again.
2) ClearCache – Clear the texts cache.
3) MeasureString – Return the size of the rect needed to draw a string with a certain font.
4) UnloadContent – Clear the cache and dispose of the various resources used. (it is executed on the various situation where the device is lost/reset etc…)
5) Draw – Search a text inside the cache. If not found it create a new cache entry and then draws it. If found it just draws it.
6) DrawCached – Draw a passed cached text directly.

Font Alternative Usage

Font Alternative Usage

Using the new class is pretty simple :

1) First we start the SpriteAlternative engine which this class is based on.
2) Check if we have the reference to the cached text.
3a) If no, we call the FontAlternative.Draw() that search in its cache for the text and if not found create a new cache entry and returns it.
4a) Save the cache reference returned from the FontAlternative.Draw() function.
3b) Draw using the FontAlternative.DrawCached() that draws directly the texture.
5) Close the SpriteAlternative engine.

The results from this change? Well, while the speed is not changed that much (0.070 ms gain over a 3,5 ms application), the CPU gain was massive (over 15% of less CPU power used by the same app) and now I have full control over my application. (the only thing i still use of the D3DX default class library is the effects framework (and i have plans for that :D))
I suggest anyone starting to create an engine to have a shot in these remakes because they will save you lots of headcache later on.

I still don’t know what we’ll talk next time, but I hope you’ll anyway look forward to it.
See ya 😉

Posted in General | Tagged: , , , , , | 12 Comments »

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. 😉

Posted in General | Tagged: , , , , | Leave a Comment »