I'm currently working on developing an internal ui for games (just like imgui) and am stuck on the quality of fonts when they are rendered through DrawText (ID3DXFont), I've tried to use DrawTextA and link a sprite to the rendering of the font but it doesn't look like there is a difference. When comparing it to imgui it seems as if the quality of the text is much higher and is anti-aliased properly, although when using ANTIALIASED_QUALITY when creating the font doesnt seem much like the anti-aliasing done in imgui at all. I'd like to make my text look at good as imgui's as im really fed up with ID3DXFont looks but am wondering on how to make it look better.
Here's some examples between ID3DXFont and Imgui (both fonts are Arial Bold and rendered with size 23)
ImGui (in d3d9):
ID3DXFont:
this is what my text rendering looks like:
ID3DXSprite* Sprite = nullptr;
D3DXCreateSprite(Device, &Sprite);
Sprite->Begin(D3DXSPRITE_ALPHABLEND);
Font->DrawTextA(Sprite, Text.c_str( ), Text.length( ), &Size, DT_NOCLIP, D3DColor);
Sprite->End( );
Sprite->Release( );
and my font initialization:
D3DXCreateFont(Device, 23.f, 0, FW_BOLD, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH, "Arial", &Font);
The first thing to say is that Direct3D 9's ID3DXFont interface is extremely old at this point, dating back to 2002 or even earlier. D3DX9, D3DX10, and D3DX11 are all deprecated as is the legacy DirectX SDK itself. See this blog post.
For Direct3D 10 or later, the recommended solution for high-quality, scalable font rendering on DirectX surfaces is DirectWrite (using Direct2D to render). The interop is a little complicated prior to DirectX 11.1, but is pretty simple with it (Windows 7 SP1 + KB2670838 installed, Windows 8.x, and Windows 10). See Microsoft Docs for DX11 / DX12.
The ID3DXFont solution as well as SpriteFont in the DirectX Tool Kit for DX11 / DX12 capture the TrueType glyphs into a texture at a specific font-size and then render them as a sprite-sheet. This is very fast, but does not have the scaling behavior of a vector-font solution like DirectWrite, FreeType, etc. That said, sprite-sheet fonts tend to look great as long as you are rendering them at the same resolution as they were captured at.
The images you show above are not 23 points high so they are going to squash a bit and you'll notice the difference between FreeType and a sprite-sheet solution in that case.
The D3XD9 ID3DXFont solution is a little more primitive than SpriteFont. D3DX9 always uses D3DFMT_A8R8G8B8 for the captured texture. SpriteFont can use a DXGI_FORMAT_R8G8B8A8, DXGI_FORMAT_B4G4R4A4, or DXGI_FORMAT_BC2_UNORM encoding. SpriteFont is also optimized for premultiplied alpha rendering.
Related
I'm developing a video player in Qt C++ using QtAV. QtAV uses ffmpeg internally. I need to show semi transparent overlays both my watermark logo and subtitles. I'm writing the application for windows. I use OpenAL library. OpenGL and Direct2D are the choice for renderers.
If I use OpenGL renderer, it works fine in some systems. The overlay works fine. But in some other systems the whole application will be just a black window. Nothing else I can see.
If I use Direct2D, the overlay wont work. And the renderer is a bit slow. But it works on all systems, without this overlays.
I have no code to show here because its not the coding issue. Even the examples in QtAV are not working. I need to find a way to show the overlays using Direct2D renderer OR find a solid way to use OpenGL rendering on all systems without fail.
Direct2D is not well supported in QtAV. So you may need to implement your own functions to add filters in your video render. That includes text draw functions, setting transparency etc.
I wonder if it's possible to use Awesomium to render the GUI over the DirectX 11 game (I do NOT use .NET, it's C++/DirectX 11 game)?
It would involve:
Rendering the scene on the window with DirectX 11 (just as I am doing it now).
Rendering the GUI with Awesomium from HTML/CSS over the previously rendered scene.
Note that some GUI elements should be semi-transparent or rounded - so it's not only rendering on some rect, but also blending.
Is it possible? Or maybe I could make it another way (e.g. telling Awesomium to use DirectX for rendering somehow)?
Or maybe I could draw an semi-transparent DirectX texture in Awesomium, and then render it over the scene with DirectX? I know that rendering to texture resource is possible with Awesomium, but does it supports transparency & semi-transparency?
If not, are the good alternatives for what I wanted to achive with Awesomium?
Yes. It can be done.
If you look at the documentation of the Awesomium WebView class it has a surface() method which will return the views backing bitmap.
Here is some c++ documentation for the class.
http://awesomium.com/docs/1_7_0/cpp_api/class_awesomium_1_1_web_view.html
You can copy this bitmap to a texture in DirectX and render it as layer on top of your game creating your UI.
You also have to route and translate input into Awesomium. You can style your UI however you like using HTML, CSS and Javascript. You can make it rounded in this way and introduce transparency.
I won't repeat a perfectly good tutorial on doing this. You can find one here.
http://www.gamedev.net/blog/32/entry-2260646-sweet-snippets-rendering-web-pages-to-texture-using-awesomium-and-direct3d/
How you render your texture after it is written doesn't have anything to do with Awesomium. Choose your blend modes and/or use shaders with output texture for desired effect.
Using Windows Image Component (WIC), I want to do the following for my windows desktop application (Direct2D/C++ with Windows 7 SP1 - Visual Studio 2013)
Choose any type of RenderTarget (Direct2D Hwnd/Bitmap/WICBitmap -
etc) for drawing
Create a empty bitmap (D2D1Bitmap or IWICBitmap -
whichever applicable)
Begin draw - Fill colour, draw some lines and ellipses -
End draw ==> (All in the Bitmap)
At some point of time, I need to
save the drawn content in the bitmap as an image in my computer
Place the bitmap in the x1,y1 (top left - xy coordinates) and x2,y2
(bottom right - xy coordinates) of the render target. Because the
rest of the space of the window would be used by toolbar.
How do I achieve this using C++/Direct2D?
GDI+ Code for my functionality:
Bitmap* pBmp = NULL; //create null or empty bitmap
Graphics* pGrBuf = NULL; //initialise graphics to null
pBmp = new Bitmap((INT)rectClient.Width, (INT)rectClient.Height);
pGrBuf = new Graphics(pBmp);
On this Graphics, I could always draw Lines, Rectangles, etc..
pGrBuf.DrawRectangle(....)
pGrBuf.DrawLine(...)
In the end, for achieving point number 5
//leave some space (30, 30 in xy co-ordinates) for putting the toolbox in the top
pGrBuf.DrawImage(m_pBmp, 30.0f, 30.0f);
The code for point 4 is intentionally omitted.
The question have a simple, unambiguous answer, but there are some details that you should (re)consider.
Direct2D is not a panacea framework that will easily outperform others. It's not very clear what are your drawings about and whats their purpose, but there are cases where Direct2D usage is not very appropriate. If you replace GDI(+) with D2D, some of your sufferings will be:
(officialy) limited OS support, according to the DirectX version and/or the functions you will use. You will have to forget about Windows XP, (very possibly) Windows Vista and (less possibly) Windows 7
the performance (compared to GDI+, GDI) is not always greater. Mainly depends from the way and the purpose you use D2D. There are cases where D2D has very poor performance (usually wrong usage or misunderstood concepts).
But also, the advantages that Direct2D could provide are countless.
Roughly said, Direct2D is nothing but a wrapper around Direct3D. It was introduced with the DirectX 10 and its usage was very similar to GDI(+). But with DirectX 11(1), the Direct2D "principles" were changed and now its more D3D-like. It adds another approaches and drops old ones. It could be a little bit confusing at first. Confusing, also because all the tutorials, articles and whatever D2D resources (including MSDN) in the web are mixed up between the D2D versions. Some of them are for the old version and recommend one thing (approach), other describe the new version.
Anyway, I recommend the new version - ie Direct2D 11.1.
To your question...
The "RenderTarget" is a concept from the "old" D2D. The new one is a DeviceContext
The DeviceContext has a target that could be a D2D1Bitmap(1) - offscreen one, a swap chain's back buffer.
The most typical drawing approach is to call drawing functions within a DeviceContext.BeginScene --- DeviceContext.EndScene block. The drawing functions are very similar to the GDI(+) ones.
There are several ways to do that. You can do it with the help of WIC. Also you can copy your D2D1Bitmap data to a DIBBitmap or you can even (re)draw it over a GDI context.
There is a function DeviceContext.DrawImage, but the way you will do it depends on many things. For example, you could have two bitmaps, that are drawn over two different HWnd (one for the toolbar, another one for the other drawing).
Here are some resources that could help you:
What is Direct2D for
Drawing a rectangle with Direct2D
Very well explained guide about migrating to Direct2D 1.1
Answer to another question here, related to Direct2D, but explains in short the way you should draw to a HWnd
I already have a Direct3d device at my beck and call...
I am working on a Windows 8 modern UI application (Metro if you will)
What's the general technique of getting text drawn to the screen?
Extra points: Can I do 3d stuff with it too? This is what originally got me here as I started to do some direct2d thing then I thought, but how can I do 3d with direct2d... second of all the d2d create text functions require a handle to a window hwnd and there is no such thing (or it has been abstracted away) in windows 8 metro apps.
Anyone got any good examples or demos I can take a look at?
You should look into DirectWrite.
Regarding your second question you can render your text to a texture and then when you render that texture on screen do 3d stuff with it.
Rendering text with DirectWrite and Direct2D it's relatively simple, however, if you want something higher level, you can look into Drawing Library for Windows Store Apps, which wraps raw DirectX calls into some more GDI like.
I'd like to have some text in my OpenGL application. However, I'm using 3.1+, and all articles I found on the Internet use deprecated features, like display lists or glBitmap or (the worst case) GLUT.
What should I use on Win32 then? (except pre-written text in pre-made textures, of course)
Freetype is a software font engine that supports SFNT-based bitmap fonts.