Sign in to follow this  
AshleysBrain

Antialiased text rendering (D3DX9)

Recommended Posts

AshleysBrain    162
Hi, I can't figure out how to render text at a decent quality, with D3DX. I'm creating the font like this:
// Unmanaged C++
D3DXCreateFont(d3dDevice, pxSize, 0, (bold ? FW_BOLD : FW_NORMAL), 0, italics,
				   DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH|FF_DONTCARE,
				   fontface, &(pFont->d3dxfont));

Then I render it with:
    m_pD3DXSprite->Begin(D3DXSPRITE_OBJECTSPACE|D3DXSPRITE_ALPHABLEND);

	font.d3dxfont->DrawText(m_pD3DXSprite, text, -1, &rect, format, color);
	m_pD3DXSprite->End();

The result looks pretty bad compared to drawing text in MS Paint: Text rendering Any ideas what I'm doing wrong? Why is the text coming out so knobbly and aliased even with ANTIALIASED_QUALITY set? Thanks for any help.

Share this post


Link to post
Share on other sites
AshleysBrain    162
Ah, thanks. Cleartype quality improves it - but it's still nowhere near as nice as with MS Paint. Is it not possible to render text at that quality in DirectX?

Here's how it looks now. Note CLEARTYPE_QUALITY is better, but still not as good as MS Paint.

Text rendering 2

Share this post


Link to post
Share on other sites
AshleysBrain    162
Interesting link legalize, but surely I would be reinventing the wheel? Presumably MS Paint calls some GDI function that looks lovely, so why can't I get D3DX to do it that nicely?

Share this post


Link to post
Share on other sites
legalize    116
GDI doesn't natively support alpha. Using GDI directly to draw text would be slow. ID3DXFont works by grabbing glyphs from GDI and rasterizing them once using GDI into a texture. The texture is then used for drawing the text, but it isn't re-rasterized at different sizes. GDI re-rasterizes in software every time you change a parameter that controls font size (but not glyph spacing). Reproducing all the font subtlety behaviors in ID3DXFont is tedious and can also impact performance. ID3DXFont doesn't promise to get the same quality as GDI font rendering; it does remarkably well considering. If you need exact GDI quality output, then I'd suggest that you use a system memory surface that is compatible with GDI, render text to that and then make a billboard texture from that surface yourself and draw the text with the billboard.

However, all of that is going to be slower and at worse quality than the method presented by Blinn and Loop in that paper. I would not be surprised if you see GDI's text rendering ultimately replaced with the Blinn and Loop algorithm, or a variant of it, at some point in the future as Vista and subsequent releases of Windows leverage the GPU more and more for desktop operations.

Share this post


Link to post
Share on other sites
Staffan E    536
Quote:
Original post by legalize
[...] If you need exact GDI quality output, then I'd suggest that you use a system memory surface that is compatible with GDI, render text to that and then make a billboard texture from that surface yourself and draw the text with the billboard.

Either that or you can construct a bitmapped font altogether if you can stick with one single size. Then you would have full control over the quality of characters.

Share this post


Link to post
Share on other sites
legalize    116
Quote:
Original post by staaf
Quote:
Original post by legalize
[...] If you need exact GDI quality output, then I'd suggest that you use a system memory surface that is compatible with GDI, render text to that and then make a billboard texture from that surface yourself and draw the text with the billboard.

Either that or you can construct a bitmapped font altogether if you can stick with one single size. Then you would have full control over the quality of characters.


This is what ID3DXFont does.

Share this post


Link to post
Share on other sites
Staffan E    536
Ah, yes, sorry. I was going more along the line of using an external program or way to create a high quality bitmap font specifically for the situation. It could be some work but if quality is a high priority it might also be worth it.

Interesting article by the way legalize.

Share this post


Link to post
Share on other sites
AshleysBrain    162
Quote:
Original post by legalize
ID3DXFont works by grabbing glyphs from GDI and rasterizing them once using GDI into a texture.


I don't understand why this still results in poor quality text - doesn't it render each glyph with GDI (which should render glyphs at the same quality MS Paint does), then move them to a texture and render strings from the texture? As in, effectively render it to a bitmap font in video memory. Why would this result in poor quality text rendering, if it's using GDI?

So is there no way for ID3DXFont to achieve MS Paint quality? How do commercial games go about this? And is there some kind of library someone's already written to do text rendering in decent quality? I set out to draw text to the screen, and wasn't really expecting to have to design my own entire font rendering engine...

Share this post


Link to post
Share on other sites
legalize    116
Quote:
Original post by AshleysBrain
Quote:
Original post by legalize
ID3DXFont works by grabbing glyphs from GDI and rasterizing them once using GDI into a texture.


I don't understand why this still results in poor quality text - doesn't it render each glyph with GDI (which should render glyphs at the same quality MS Paint does), then move them to a texture and render strings from the texture? As in, effectively render it to a bitmap font in video memory. Why would this result in poor quality text rendering, if it's using GDI?


It uses GDI to render glyphs, but doesn't use GDI for kerning inter-character spacing, inter-line spacing, etc. It handles all the character and line spacing by drawing quads. I think there may be additional issues related to scaling. Its also possible that there are bugs in ID3DXFont; its one of the classes that has churned the most in D3DX over the years.

Quote:
So is there no way for ID3DXFont to achieve MS Paint quality?


Its not a question of whether ID3DXFont can achieve it, but can you achieve it. The answer is yes, you can achieve higher quality by using GDI to rasterize the text any way you want into a surface. However, it won't be the most performant. Quality and performance often compete and this is no exception.

Quote:
How do commercial games go about this?


They use bitmapped fonts that are created specifically for their game. Games are not hyper-obsessed with typographic quality; they don't give you a GDI font browser to pick the font for your HUD. You get what they give you and nothing else.

Share this post


Link to post
Share on other sites
Evil Steve    2017
One other thing to check - are you absolutely sure that your backbuffer is the same size as your window client area? If you're not using AdjustWindowRectEx() when you create your window, then the backbuffer and window client area are probably different sizes (CreateWindowEx() takes a window size, not client area size), which will mean your backbuffer is being stretched onto the window, which could cause artefacts.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this