Does anyone have any tutorials/info for creating and rendering fonts in native directx 9 that doesn't use GDI? (eg doesn't use ID3DXFont).
I'm reading that this isn't the best solution (due to accessing GDI) but what is the 'right' way to render fonts in dx?
ID3DXFont is a great thing for easy to use, early, debug output. However, it does use the GDI for font rasterization (not hardware accelerated) and there is a significant performance hit (try it, its actually very noticable). As of DirectX 11, though, fonts will be rendered with Direct2D and be hardware accelerated.
The fastest way to render text is using what's called "Bitmap Fonts". I would explain how to do this, except that there is a lot of different ways to do implement this technique, each differing in complexity and capability. It can be as simple as a system that loads a pre-created texture and draws the letters from that, or a system that silently registers a font with Windows and creates a texture in memory at load-time (The engine I developed with a friend did this, it was very slick). Either way, you should see a very noticable performance increase with bitmap fonts.
Why this isn't a good solution?
Mixing GDI rendering and D3D rendering into the same window is a bad idea.
However, ID3DXFont does not use that. It uses GDI to rasterize the glyphs into a texture. And uses that texture to render the actual text.
About the only alternative would be using another library (e.g. FreeType) to rasterize glyphs into a texture, but I'm not sure if that would result in any substantial benefits.
Of course, for simple (e.g. non-Asian) fonts you could rasterize all glyphs into a texture beforehand, then use that texture to draw text at runtime. This way runtime does not need to use any font rendering library, it just draws quads using the texture. This approach does not scale well with large font sizes or fonts with lots of characters. Also would not handle complex typography very well (e.g. where letters have to be joined etc.)
With DirectX, the correct way to render standard fonts is with GDI.
However, IF
You want to support cross platform font rendering
with proper support for internationalization - including far eastern languages where maintaining a glyph for every character in a font is impractical
and/or You want to distribute your own fonts and render them without "installing" them...
Then libfreetype might be what you are looking for. I don't claim its easy: Its a lot more complex than using the native font api.
Personally I think that ID3DXFont is the way to go.
If you really wanted to make your own font routines, I suggest you look at:
http://creators.xna.com/en-us/utilities/bitmapfontmaker
You can use this to create a bitmap with all the characters printed on it. Then its just a matter or loading the texture and blitting the relevant chars onto the screen at the right place. (This is what XNA uses for its font drawing)
Its a lot more work, but you don't need the font to be installed on the target PC, and you have the advantage to being able to go into photoshop and edit the font appearance there.
Related
Currently I am looking to write a text editor for linux systems that does some particular text/font highlighting that involves opengl rendering. Does anyone have suggestions for a c++ graphics rendering library that works well with linux (ubuntu in particular for now)?
And advice for where to start with rendering 3d text is greatly appreciated!
EDIT: Just to clarify rendering 3d text is a strict requirement of the project.
There are basically only three ways to do this at the OpenGL level:
Raster Fonts.
Use glBitmap or glDrawPixels to draw a rectangular bunch of pixels onto the screen. The disadvantages of doing this are many:
The data describing each character is sent from your CPU to the graphics card every frame - and for every character in the frame. This can amount to significant bandwidth.
The underlying OpenGL implementation will almost certainly have to 'swizzle' the image data in some manner on it's way between CPU and frame-buffer.
Many 3D graphics chips are not designed to draw bitmaps at all. In this case, the OpenGL software driver must wait until the 3D hardware has completely finished drawing before it can get in to splat the pixels directly into the frame buffer. Until the software has finished doing that, the hardware is sitting idle.
Bitmaps and Drawpixels have to be aligned parallel to the edges of the screen, so rotated text is not possible.
Scaling of Bitmaps and Drawpixels is not possible.
There is one significant advantage to Raster fonts - and that is that on Software-only OpenGL implementations, they are likely to be FASTER than the other approaches...the reverse of the situation on 3D hardware.
Geometric Fonts.
Draw the characters of the font using geometric primitives - lines, triangles, whatever. The disadvantages of this are:
The number of triangles it takes to draw some characters can be very large - especially if you want them to look good. This can be bad for performance.
Designing fonts is both difficult and costly.
Doing fonts with coloured borders, drop-shadows, etc exacerbates the other two problems significantly.
The advantages are:
Geometric fonts can be scaled, rotated, twisted, morphed, extruded.
You can use fancy lighting models, environment mapping, texturing, etc.
If used in a 3D world, you can perform collision detection with them.
Geometric fonts scale nicely. They don't exhibit bad aliasing artifacts and they don't get 'fuzzy' as they are enlarged.
Texture-Mapped Fonts.
Typically, the entire font is stored in one or two large texture maps and each letter is drawn as a single quadrilateral. The disadvantages are:
The size of the texture map you need may have to be quite large - especially if you need both upper and lower case - and/or if you want to make the font look nice at large point sizes. This is especially a problem on hardware that only supports limited texture map sizes (eg 3Dfx Voodoo's can only render maps up to 256x256)
If you use MIPmapping, then scaling the font makes it look a litte fuzzy. If you don't use MIPmapping, it'll look horribly aliasy.
The advantages are:
Generality - you can use an arbitary full colour image for each letter of the font.
Texture fonts can be rotated and scaled - although they always look 'flat'.
It's easy to convert other kinds of fonts into texture maps.
You can draw them in the 3D scene and they will be illuminated correctly.
SPEED! Textured fonts require just one quadrilateral to be sent to the hardware for each letter. That's probably an order of magnitude faster than either Raster or Geometric fonts. Since low-end 3D hardware is highly optimised to drawing simple textured polygons, speed is also enhanced because you are 'on the fast path' through the renderer. (CAVEAT: On software-only OpenGL's, textured fonts will be S-L-O-W.
Links to some Free Font Libraries:
glut
glTexFont
fnt
GLTT
freetype
Freetype: http://freetype.sourceforge.net/index2.html
And: http://oglft.sourceforge.net/
I use FTGL, which builds on top of freetype. To create 3D, extruded text, I make these calls:
#include <FTGL/ftgl.h>
#include <FTGL/FTFont.h>
...
FTFont* font = new FTExtrudeFont("path_to_Fonts/COOPBL.ttf");
font->Depth(.5); // Text is half as 'deep' as it is tall
font->FaceSize(1); // GL unit sized text
...
FTBBox bounds = font->BBox("Text");
glEnable(GL_NORMALIZE); // Because we're scaling
glPushMatrix();
glScaled(.02,.02,.02);
glTranslated(-(bounds.Upper().X() - bounds.Lower().X())/2.0,yy,zz); // Center the text
font->Render("Text");
glPopMatrix();
glDisable(GL_NORMALIZE);
I recomend you QT wich is foundation of KDE or GTk+ for GNOME. Both of them have support for OPENGL and text. With QT you can do advanced graphics(QGraphicsView) , including animation... Take a look at QT Demo Application .
A good start would be NeHe's OpenGL Lesson 14.
http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=14
If we want to make an application like MS Paint, should we use OpenGL for render graphics?
I want to mention about performance if using traditional GDI vs. OpenGL.
And if there are exist some better libs for this purpose, please see me one.
GDI, X11, OpenGL... are rendering APIs, i.e. you usually don't use them for image manipulation (you can do this, but it requires some precautions).
In a drawing application like MS Paint, if it's pixel based, you'll normally manipulate some picture buffer with customary code, or a special image manipulation library, then send the full buffer to the rendering API.
If your data model consists of strokes and individual shapes, i.e. vector graphics, then OpenGL makes a quite good backend. However it may be worth looking into some other API for vector graphics, like OpenVG (which in its current implementations sits on top of OpenGL, but native implementations operating directly on the GPU may come).
In your usage scenario you'll not run into any performance problems on current computers, so don't choose your API from that criteria. OpenGL is definitely faster than GDI when it comes to texturing, alpha blending, etc. However depending on system and GPU pure GDI may outperform OpenGL for so simple things like drawing an arc or filling a complex self intersecting polygon with complex winding rules.
There is no good reason not to use OpenGL for this. Except maybe if you have years of experience with GDI but don't know a single thing about OpenGL.
On the other hand, OpenGL may very well be superior in many cases. Compositing layers or adjusting hue/saturation/brightness/contrast in a GLSL shader will be several orders of magnitude faster (in fact, pretty much "instantly") if there is a reasonably new card in the computer. Stroking a freedraw path with a "fuzzy" pen (i.e. blending a sprite with alpha transparency over and over again) will be orders of magnitude faster. On images with somewhat reasonable dimensions, most filter kernels should run close to realtime. Rescaling with bilinear filtering runs in hardware.
Such things won't matter on a 512x512 image, as pretty much everything is instantaneous at such resolutions, but on a typical 4096x3072 (or larger) image from your digital camera, it may be very noticeable, especially if you have 4-6 layers.
I need to render some formatted text (colours, different font sizes, underlines, bold, etc) however I'm not sure how to go about doing it. D3DXFont only allows text of a single font/size/weight/colour/etc to be rendered at once, and I cant see a practical way to "combine" multiple calls to ID3DXFont::DrawText to do such things...
I looked around and there doesn't seem to be any existing libraries that do these things, but I have no idea how to implement such a text renderer, and I couldn't even find any documentation on how such a text render would work, only rendering simple fixed width, ASCII bitmap fonts which looking at it is probably an entirely different approach that is only suitable for rendering simple blocks of text where Unicode is not important.
If there's no direct3d font renders capable of doing this, is there any other renderers (eg for use in rendering rich text in a normal window), and would rendering those to a texture in RAM, then uploading that to the video card to render onto the back buffer yield reasonable performance?
You tagged this with Direct3D, so I'm going to assume that's the target environment. Otherwise, GDI can handle all this stuff.
Actually, looking at GDI is a good place to start, since it supports this as it stands. With GDI, there is only a single font selected at a time for drawing text. Similarly, there can only be a single text color selected at a time. So, to draw a line of text that contains characters in multiple colors and/or fonts, you have to divide the line up into chunks of characters that all have the same rendering state. You set the state for that chunk (text foreground/background color, text font, text spacing, etc.), then call ::TextOut for that chunk of text, then set the state for the next chunk and draw that, and so-on.
The same principle applied in Direct3D. Each chunk of text may require its own ID3DXFont (or your own font mechanism if ID3DXFont isn't sufficient) and color, etc. You set state, draw text, set state, draw text, etc.
Now, if you want to do your own text rendering, you could do fancier things with a shader, but its probably not worth it unless you have the need for really high-quality typography.
In Windows 7 (back-filled for Vista once Windows 7 ships), you'll be able to use DirectWrite for high quality typography in a Direct3D rendering context (D3D10 and later).
In case of using Direct3D9 or early you really have big problems:
1. You always may use GDI, render your text in the HDC, copy it to the Direct3D dynamic texture and use shader to replace background to transparency by color key for example.
2. Take a look on FreeType library may be you'll find it more suitable for you than GDI, but it really will not be easy.
Any way even if you will find a good way of text rendering you obligotary will have problems with small fonts by reason of ClearType Microsoft technology. At first you will not be able just make a matrix of small symbols to type text from it (because symbol is rendered with using of this subpixel rendering). You will probably need some special shader... or you will be enforced reject to use ClearType, but as i've said before it has bad aftereffects on small fonts. At second this technology is patented by Microsoft
But if you do not need support of Windows XP you may try to use Direct2D with DirectWrite and DirectX10 (I didn't try 11). I tried them and they shown good results, you only should avoid often switching between Direct2D and Direct3D contexts, because it may seriously degrade performance. To render something to your texture you may use ID2D1Factory::CreateDxgiSurfaceRenderTarget function
I suggest measuring the performance of rendering to a bitmap and uploading to a texture.
I suspect that this pretty much what D3DXFont has to do behing the scenes anyway.
You could probably cache letters / phrases etc. if needed
I want to write a hardware accelerated text renderer using Free Type 2 to load the fonts, find the correct glyphs and their sizes etc.
My plan to do this is to have a large texture containing glyphs (for a given font,size,etc) in video memory, and a table for each texture defining information about the contents of the texture in system memory.
I can then use the table to build a vertex buffer to render the text.
The problem I'm facing is the construction of the texture, it is not practical to create a texture for every glyph in Unicode, there just too many. For Ascii in the past I just built the texture in an image editor and then filled out the table as needed myself in advance, however for this I will need some kind of dynamic system that will get the glyphs needed, but also efficently cache them to avoid repeated uploads of the same glyph to vram...(some sort of least commonly used system I guess)
Another problem is not all glyphs are the same size, I could split the texture up into a grid big enough for the largest glyphs (which I need some way to accurately work out) which makes fitting the glyphs onto the texture easy and replacing them with new glyphs (based on the least commonly used or something), however that leaves a lot of wasted space, but i'm not sure how to more efficiently pack them without running into problems with fragmentation as glyphs are swaped in and out...
Also I assume updating the texture could stall the graphics hardware if the texture is still being used for some previous text, is this a correct assumption and how can I avoid it if its the case?
Text rendering is much complex issue then "pasting" some glyphs... Not just much complex,
it is very complex: kerning, ligatures, spacing, bidirectional text, vowels, and much more...
Why wouldn't you just create a text using normal libraries for text rendering like Pango, create bitmap and display it as bitmap on your 3D object (if I understand what you need).
EDIT: Simple HTML like markup can be rendered with Pango as well: http://library.gnome.org/devel/pango/unstable/PangoMarkupFormat.html
Cairo supports hardware accelerated rendering to many surface types
There is a library called FontForge which is using Cairo for rendering, but i haven't tried it myself. You should check it and let me know how it goes :-)
I want to render font in a way that takes account of the current transforms and similar settings, especially the projection transform and viewport.
I'm thinking that the best way to do that is to have an off screen surface to render the text to, and then render that surface where I really want the text.
However I'm not certain on a number of aspects of this solution.
Is this the best way to go about it at all?
Are there far better free font renderers around that id be better off spending my time with that allow such things. I see alot of people complaining about the d3dx font interfaces for various reasons, but never a link to a better unicode capable renderer...?
Is there any advantage to useing certain surface formats and/or surface sizes (eg always using the smallest possible rather than some standard large one, which requires the extra step of trying to work the size out...)
Yeah, render to texture and then drawing a textured quad to orient and position the text is going to be the easiest way to realize this functionality.
As for D3DX text renderers, it really depends on which SDK you are using. DirectWrite (only for Windows 7 and Vista) will provide a higher quality text rendering approach for applications that need high quality text rendering in a manner that is interoperable with Direct3D.
You can of course do your own rasterization. There are font rasterization engines out there that are open source that could be repurposed for this need, but we're talking tons of coding here for a benefit that may not be distinguishable enough to warrant the development expense.
Having said that, there's a completely new alternative available to you with Direct3D and shaders, provided that you have access to the glyph outlines as curve data. The idea is to use the shader to rasterize the text and store the curve definitions in the vertex stream and associated textures. Try looking at this paper, which describes the technique.