Sign in to follow this  

DirectX 9 Customs Fonts

This topic is 2849 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I have to draw text using a lookup table from a bitmap. I do not want to use D3DXFont since I have to apply an outline to each caracters after drawing it on the bitmap with TextOut API. I will use GDI+ for the Outline. I have use the following code : http://www.gamedev.net/community/forums/viewreply.asp?ID=1098396 The problem is that the contour of the letter is not very precise. In conclusion it is not pretty. I have save the bitmap generated on hard disk and then opened it with MSPaint and the letter a perfectly smooth, I mean this is not the same result as what I have on the screen with Direct3D... Here is a screenshot : http://i175.photobucket.com/albums/w155/Feltar/TextOutD3D.png What can I do to improve the quality ? Or what do I have to do to improve the rendering quality ? Best regards PS : Cross posting : http://forums.xna.com/forums/p/48445/290551.aspx#290551 [Edited by - Erakis on February 25, 2010 11:35:32 AM]

Share this post


Link to post
Share on other sites
Hi,

Here is how I'm rendering text to the Direct3D surface. First of all I'm pre-rendering all the font characters into a 32bpp bitmap.

Here is the result : http://i175.photobucket.com/albums/w155/Feltar/Direct3DLookUpFont.png

To add an outline to each caracters I'm using GDIPlus :


Graphics graphics(hdc);
graphics.SetSmoothingMode(SmoothingModeAntiAlias);
graphics.SetInterpolationMode(InterpolationModeHighQualityBicubic);
GraphicsPath path;
FontFamily fontFamily(m_szFontName);
StringFormat strformat;

// For each caracters loop ...
path.Reset();
s = path.AddString(szTempString, 1, &fontFamily, FontstyleRegular, 32, PointF(unTextOutX, unTextOutY), &strformat);
Color cOutlineColor;
cOutlineColor.SetFromCOLORREF( outlineColor );
Pen pen(cOutlineColor, 2);
pen.SetLineJoin(LineJoinRound);
s = graphics.DrawPath(&pen, &path);
Color cTextColor;
cTextColor.SetFromCOLORREF(color);
SolidBrush brush(cTextColor);
graphics.FillPath(&brush, &path);


Now from this Bitmap, I create a Direct3D texture and I copy transfert all the pixels. But during the transfert I need to simulate the alpha. I other words, I need to set an alpha = 0 for each pixel of the background and set an alpha of 255 to all other. Here is how I do it :


DWORD* pDestData = (DWORD*)d3dLockedRect.pBits;

DWORD dwTransparentColor = ((backgroundColor >> 16) & 0x000000ff) |
((backgroundColor << 16) & 0x00ff0000) |
(backgroundColor & 0x0000ff00);

pBitmapBits += m_unTextureWidth * (m_unTextureHeight - 1);
for (UINT y = 0; y < m_unTextureHeight; ++y )
{
DWORD* pRow = pBitmapBits;
for (UINT k = 0; k < m_unTextureWidth; ++k, ++pRow )
{
if (*pRow == dwTransparentColor)
{
*pRow = 0x00000000;
}
else
{
*pRow |= 0xff000000;
}
}

memcpy(pDestData, pBitmapBits, m_unTextureWidth * sizeof(DWORD));

pDestData += ( d3dLockedRect.Pitch / 4 );
pBitmapBits -= m_unTextureWidth;
}

m_CharactersTexture->UnlockRect( 0 );


And then from the texture I create a SPRITE. The result without the Outline is fair but not perfect as if I was writing text over a bitmap using MSPaint. But as you can see in the preceding image "Direct3DLookUpFont.png" some pixels of the background left mixed with those of the outline.

How can I get a better transparency ?


I feel the way I simulate the alpha value is not good... Else is someone here have an idea on how to better proceed, I am really desperate. This is 1 week as I try to display text with outline on a Direct3D surface.

Best regards

Share this post


Link to post
Share on other sites
Your current technique is formally called "color keying". It is not widely used in modern text rendering because - as you can see - the edges of the opacity are aliased.

GDI+ supports real alpha channels. If you create the temp bitmap with alpha, you can just copy the values to your D3D texture. Before drawing your text, be sure to clear the alpha channel to 0 so you actually get a transparent background.

Share this post


Link to post
Share on other sites
Also, I note that you create the Graphics object against a HDC. The HDC is a classical Win32 device context which has poor native alpha channel support (though it can support some simple alpha ops on XP and later).

For the temp bitmap (to which you initially draw the text), consider using the GDI+ Bitmap class instead. It is very robust and you can create your Graphics object directly against it.

Share this post


Link to post
Share on other sites
Sorry for my ignorance, but how to realize a bitmap with real alpha channels ?

Also if I'm using bitmap that support real alpha channels, will I get better result ? I mean sharpness edges without jagged pixels ?

So If I well understand I proceeed the same way but I use a GDI+ Bitmap class instead. And just before creating the texture I set the alpha value of each pixel having the same color as my background to 0 ?

If I use the GDI+ Bitmap class, I presume that I create the graphic object from the GDI+ Bitmap (PixelFormat32bppARGB ) ?

Thank you very much, it's very appreciated that you help me
Best regards

Share this post


Link to post
Share on other sites
To create a Bitmap with an alpha channel, just specify a pixel format that includes an alpha component when using the Bitmap ctor.

If you use a proper alpha channel, the antialiasing of the text carries through your pipeline. While it doesn't magically make the text sharper (increasing resolution will), it is more legible.

The Graphics object (which you can use to draw to a Bitmap, since Bitmap derives from Image) has a Clear method that you can use to init the pixels to a given value. This applies to the alpha channel too.

First, you should clear the Bitmap. Then, you draw your antialiased text into it. Finally, copy all the data (including the alpha as is) from the Bitmap to the D3D texture. You don't need any manual per-pixel processing here.

Share this post


Link to post
Share on other sites
Hi,

Nik02 let me tell you a thousand thanks you've made my day :)

The result is from far better quality than the traditionnal GDI.

And I no longer need to manually set the alpha component as I did before. A simple "memcpy" call do the trick and all the alpha values are maintained from the bitmap to the texture to allow transparancy. Exactly as you said. You're a pro !

Best regards

Share this post


Link to post
Share on other sites

This topic is 2849 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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