Am Wednesday 17 June 2009 18:29:57 schrieb Tony Wasserka:
@@ -300,6 +301,12 @@ HRESULT WINAPI
D3DXCreateFontIndirectW(LPDIRECT3DDEVICE9 device, CONST D3DXFONT_
object->device=device; object->desc=*desc;
- object->hdc = CreateCompatibleDC(NULL);
Device contexts are scarce resources, please avoid holding one all the time. Instead, create it in GetDC and destroy it in ReleaseDC. Besides this, after ReleaseDC the DC is supposed to be invalid - the only way to do this is to destroy it. (Yes, I know that's broken in wined3d too. Needs fixing there as well)
You'll also have to attach the DC to the font bitmap, or whatever you have, to have it draw to the correct device. I think the current code means that the DC will draw to the screen directly, which is maybe not what you want.
If the font has a d3d surface underneath, you should use d3dsurface9::GetDC
Stefan Dösinger schrieb:
Am Wednesday 17 June 2009 18:29:57 schrieb Tony Wasserka:
@@ -300,6 +301,12 @@ HRESULT WINAPI
D3DXCreateFontIndirectW(LPDIRECT3DDEVICE9 device, CONST D3DXFONT_
object->device=device; object->desc=*desc;
- object->hdc = CreateCompatibleDC(NULL);
Device contexts are scarce resources, please avoid holding one all the time. Instead, create it in GetDC and destroy it in ReleaseDC. Besides this, after ReleaseDC the DC is supposed to be invalid - the only way to do this is to destroy it. (Yes, I know that's broken in wined3d too. Needs fixing there as well)
You'll also have to attach the DC to the font bitmap, or whatever you have, to have it draw to the correct device. I think the current code means that the DC will draw to the screen directly, which is maybe not what you want.
If the font has a d3d surface underneath, you should use d3dsurface9::GetDC
Hi, thanks for your comment I must admit that I am not that experienced with GDI, but I think creating the DC is inevitable: The function ID3DXFont_GetGlyphData uses GetGlyphOutline (with GGO_GRAY8_BITMAP, i.e. no drawing to screen or bitmap) to get the pixel data of a specific glyph which is (manually) copied to an internal texture then. Thus, I'll need a DC whenever GetGlyphData is called. 1) The handle to the DC returned by GetDC must always have the same value (at least I think so, I'll test that tomorrow) and more important 2) GetGlyphData is called once per Glyph in a string passed to DrawText, which might be VERY often depending on the usage of the ID3DXFont object. Because of that, DCs would need to be created and deleted very often per frame (lateron maybe not as often as we're caching the glyphs), so I think holding the DC all the time is better than creating and deleting them that often (correct me if I'm wrong here). By the way, ID3DXFont does not provide any ReleaseDC method, so there'd also be quite a problem when to delete the DC again after it was created in GetDC ;)
About the IDirect3DSurface/Texture9_GetDC approach: I also thought about that (I even hoped it could solve the format conversion hell from the texturing code), but it only supports a bunch of formats (not so bad as I'm using A8R8G8B8 anyways), but no alpha channels, and without alpha the fonts look ugly. Again, correct me if MSDN is just wrong documented and the alpha channel does actually work well.
I'm not sure whether that explanation makes the first point about ReleaseDC redundant - at least I don't understand it :D I'm already calling DeleteDC in ID3DXFont_Release, that should be enough, shouldn't it?
Best regards, Tony