How to draw bitmap fonts in OpenGL 3.1+? - opengl

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.

Related

Direct3D9 ID3DXFont Font Quality Seems Very Bad and Not Anti-Aliased

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.

OS native 2D API vs OpenGL

Suppose I wanted to create a text editor from scratch.
I searched around and everyone suggested using OS-specific native 2D APIs (e.g. GDI+ in Windows or XLib in Linux), especially for font rendering.
My question is: why is it that openGL isn't suited for such a task? Why is it so hard to render antialiased text and controls as in a text editor with openGL and why should I prefer the non-portable way of native 2D OS APIs?
Part of the difficulty is that OpenGL doesn't provide a font engine or any capabilities specifically for rendering text. In other words, it's not a matter of OpenGL being poorly suited to the rendering part of the task, just that OpenGL is missing a lot of pieces necessary to the task.
To render text under OpenGL, you'd typically start with some font engine to take (for example) a TrueType or OpenType font, and render a glyph from its info (e.g., FreeType). Then you need a text display engine to figure out how to render characters to display your strings decently. In a simple case like English, it has to handle things like kerning and leading. In a complex case like some Arabic scripts, you basically need kind of a feedback loop between the text rendering and the font rendering, because a glyph can take a different form depending on its context in the string.
In short, writing a text editor that renders its text via OpenGL means re-building a lot of a text rendering stack from the ground up.
If you don't care a lot about rendering quality, you might be able to get by with just rendering a few fonts to bitmaps, and displaying your text using them. This can simplify the code quite a bit, but a simple implementation will mean producing output that looks something like an MS-DOS command line. Even matching the output quality of, say, Windows 3.0 will take a fair amount of work. That's not to say it can't be done--but it could dwarf the difficulty of writing the editing part of the text editor.

A video player based on QtAV with Direct2D / OpenGL rendering

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.

Windows 8 modern UI applications and DirectX... How to draw text?

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.

2D graphic library for windows form application

I need a 2d graphic library for windows form application(Visual studio 2010).I used to work with SDL in console applications.It was really great:simple and powerful.But a friend of mine told me that it won't work in windows form application.Can you please suggest me a good library for 2d drawing in form applications written in C++?Or is there a way to use SDL in windows form applications?
*it would be great if it has these features:
load .bmp and .gif and popular image formats.
Simple to learn.
Draw text and simple 2d shapes.
Thanks.
(Sorry for my bad english)
SDL supports Windows. You should be able to use SDL by just using a Window's Handle from a control in Windows Forms. For example, if you initialize SDL to use the a "panel" by passing the panel->Handle property as the HWND, it should work fine.
Alternatively, you can use Windows Form's built-in drawing in the System.Drawing namespace.