text and rotation

Started by
18 comments, last by oliver_mpt 14 years, 2 months ago
Hello, I want to write text in my window, but with variable orientation. I have made a few test with the CD3DFont class, but it is unaffected by the world transformations. I haven't tested the ID3DXFont, because I have read that it's a frame killer. Any suggestions ? Regards Oliver
Advertisement
Aside from using some library like libttf, you could use ID3DXFont (The performance is absolutely fine, I don't know where you heard it's poor performance, but that's incorrect), and use a sprite with world transform applied to it when you call DrawText().
Hi Steve,

Thanx for the quick reply. Regarding ID3DXFont, I'm quoting below a book that I use to discover DirectX : Introduction to 3D Game Programming with DirectX 9.0 by Frank Luna, Wordware Publishing.

Chapter 9, introduction :
"This interface uses GDI internally to draw the text, and so we take a performance hit using this interface"

Oliver
Pretty much all text rendering libraries will use GDI to draw the text. ID3DXFont caches the characters it renders, so there's only a hit the first time you draw a character. After that it doesn't go anywhere near GDI.
Hi Steve,
Your remark sounds logical, I'll try using ID3DXFont then. I've digged a bit to find an exemple, but most tutos I've found use NULL for the sprite pointer.
Could you briefly outline the usage of the custom sprite so I can use it ? I'd also like to use untransformed coordinates for my text, rather than device coordinate. I've found that I should use the D3DXSPRITE_OBJECTSPACE flag for my sprite - is that correct ?

Oliver
Actually I dislike the way the base font class of the D3DX library works. (Many draws for each character or so depending on how the gliph are rendered/ordered in the textures)
If you are using lots of static text, or you need alpha blending, I would suggest rolling a personal class to draw text using GDI+. (draw the text to a texture with GDI+ and then draw the text on screen on a quad that you can transform with your matrix). Its a lot lighter on CPU load compared to the D3DX one (while using more video memory)

After all on all Vista+ systems, GDI is no more hardware accelerated so it doesn't make any difference.
Quote:Original post by oliver_mpt
Could you briefly outline the usage of the custom sprite so I can use it?
When you pass NULL for the sprite pointer, ID3DXFont uses one it prepared earlier internally. It's more efficient to pass a valid sprite pointer if you're making multiple DrawText() calls per frame, since then all characters are drawn using one sprite.
ID3DXSprite is internally implemented as a dynamic vertex buffer and static index buffer, so using one ID3DXSprite instance for multiple DrawText() calls means fewer SetStreamSource() / SetIndices() calls, which means fewer batches, which means better performance.

To use a particular sprite, you create one at app startup (When you create the font for instance) with D3DXCreateSprite(), and then call ID3DXSprite::Begin() prior to rendering any text, then pass it to the DrawText() calls, optionally changing any sprite state beforehand.

Quote:Original post by oliver_mpt
I'd also like to use untransformed coordinates for my text, rather than device coordinate. I've found that I should use the D3DXSPRITE_OBJECTSPACE flag for my sprite - is that correct ?
By default ID3DXSprite will draw in screen coordinates; is that not what you want?

Quote:Original post by feal87
Actually I dislike the way the base font class of the D3DX library works. (Many draws for each character or so depending on how the gliph are rendered/ordered in the textures)
That's true - ID3DXFont is designed as a helper class, it's not meant as any sort of ultimate text rendering class. If you use a non-NULL ID3DXSprite parameter to DrawText(), it's usually a good idea to use the D3DXSPRITE_SORT_TEXTURE flag to reduce the number of draw calls.

Quote:Original post by feal87
If you are using lots of static text, or you need alpha blending, I would suggest rolling a personal class to draw text using GDI+. (draw the text to a texture with GDI+ and then draw the text on screen on a quad that you can transform with your matrix). Its a lot lighter on CPU load compared to the D3DX one (while using more video memory)
It's quite a lot of work to write your own text renderer (Particularly if you want to handle "exotic" characters like Arabic and suchlike), I wouldn't recommend it unless ID3DXFont is proven to be too inefficient.
You can always achieve the same effect without having to write any GDI code by drawing your text to a render target and then using it as a texture.
First thanks Steve for the detailed answer.

let's see what I tried :

I have created a font (ID3DXFont* Font) and a sprite (ID3DXSprite* pD3DXSprite)
and here is the chunk of code I use :

D3DXMatrixTranslation(&TransfmMatrix, 1.0f, -1.0f, 0.0f)
char Text[] = "Some text 101";

pD3DXSprite->Begin(D3DXSPRITE_OBJECTSPACE);
pD3DXSprite->SetTransform(&TransfmMatrix);
Font->DrawText(pD3DXSprite,Text(int(strlen(Text)),&font_rect,DT_LEFT|DT_EXPANDTABS,D3DCOLOR_XRGB(155,30,200));
pD3DXSprite->End();

font_rect is set to my screen size 640x480

1) Nothing is drawn

2) I remove D3DXSPRITE_OBJECTSPACE and replace it by any other flag, the text is drawn at the screen origin. I have to use screen coordinates in D3DXMatrixTranslation to get an effective translation.

What I would like to achieve is to be able to give the transformation (translations) in untransformed coordinates (world coordinates).

Any hint on how to do that ?
This sounds similar to what you're trying to achieve, is that code any help?
Hi,

I tried the code mentionned, but it does not seem to help. In the sample you mentionned they also use screen coordinates.
My point is to NOT use screen coordinates, but world coordinates to be independent of the window size, and use homogeneous coordinates with the object vertices (specified in world, untransformed coordinates).
Is there a way to specify a translation in world coordinates ? I'm only able to translate my text (and sprite) using screen coordinates ?
Of course, I can write a mathematical expression to transform from world coordinates to screen, taking the window size into account, but I'm sure directX can do it faster than that.

Oliver

This topic is closed to new replies.

Advertisement