Vector-based fonts on OpenGL - c++

I started working at this company that uses an 2D OpenGL implementation to show our system's data (which runs on Windows.) The whole system was built with C++ (using C++Builder 2007). Thing is, all the text they print there are pixelized when you zoom in, which I think happens because the text is a bitmap:
From what I know they use the same font files as Windows does. I asked around here on why this happens and the answer I got is that the guy who implemented it (which doesn't work at the company anymore) said fonts on OpenGL are hard and this was the best he could do or something like it.
My question is: is there any simple and effective way to make the text also a vector (the same way those lines in the picture are?) So when I zoom the camera, which happens a lot, they don't pixelize. I have little knowledge of OpenGL and if you have some guide and/or tutorial related to this to point me towards the right direction I'd be very thankful. Basically any material would be great.

Most of OpenGL text rendering libraries come to this: creating bitmaps for the fonts. This means you are going to have problems with scaling and aliasing unless you do some hacks.
One of the popular hacks is Valve's approach: Chris Green. 2007. "Improved Alpha-Tested Magnification for Vector Textures and Special Effects.". You use signed distance field algo to generate your fonts bitmap which then helps you to smooth the text outlines on scale during rendering. Wikidot has the C++ implementation for Distance field generation.
If you stick to NVidia specific hardware, you can try the NVidia Path extension which allows you to render graphics directly on GPU. Remember, it is a NVidia only thing.
But in general, signed distance field based approach is the smoothest and easiest to implement.
BTW, freetype-gl uses Valve's approach and also the modern pipeline.

You can try freetype-gl its a library for font rendering in OpenGL.

The issue with using fonts in OpenGL is that they are handled inconsistently across platforms, and that they have minimal support. If you're willing to go with a helper library for OpenGL (SDL comes to mind), then this behaviour will likely be wrapped, meaning that you merely need to provide a suitable font file for them to use.

You may try out FTOGL4 , the fonts for OpenGL4

Related

Replicating Cathode retro terminal effect?

I'm trying to replicate the effect of Cathode but i'm not really aware of any rendering effects in SDL. Does anyone know the technique used in Cathode? Are they using OpenGL and shaders maybe?
If you are still interested in the subject I'm working on a similar project. The effects were obtained by using GLSL shaders.
You can grab the source code here: https://github.com/Swordifish90/cool-old-term/
The shaders strings might not be extremely readable due to the extensive use of the ternary operators (needed to customize the appearance) but they should give you a really good idea.
If you poke around a bit in the application bundle, you'll find that the only relevant framework is GLKit which, according to Apple, will "reduce the effort required to create new shader-based apps".
There's also a bunch of ".fragdata", ".vertdata", and ".glsldata" files, which are encrypted.
Very unfortunate for you.
So I would say: Yes, it's OpenGL shaders all the way.
Unfortunately, since the shaders are encrypted, you're going to have to locate suitable algorithms elsewhere.
(Perhaps it's possible to use the OpenGL debugging and profiling tools to capture the shader source as it is compiled, but I doubt it.)
You may have realized that Android phones have (had?) such animations when you put them to sleep. That code is available under in file named ElectronBeam.java.
However it is Java code and uses GLES 1.0 with GLES 1.1 Extenstions but algorithm for bending screen should be understandable.
Seems to be based on GLTerminal which uses OpenGL, it would have to use OpenGL and shaders for speed.
I guess the fastest approximation would be to render the text to buffers within OpenGL and use a deformed 2d grid to create the "rounded corners" radial distortion.
But it would take a lot of work to add all the features that cathode has, not to mention to run them quickly.
I suspect emulating a CRT perfectly is a bit like emulating an analog synth perfectly - hard to impossible.
If you want to work quickly and not killing the CPU, the GPU is the best solution! So pixel shaders. pixel shaders can do all of these effects. Once I made such an application. I wrote it in Silverlight, but it does not matter, I used the pixel shader.
Suggests to write this in Qt4 and add to the QWidget pixel shader effects.

OpenGL text rendering methods and trade-offs

Background
I work on the game Bitfighter. We're still compatible with OpenGL 1.1 and compile for OSX, Windows, and Linux.
We use vector graphics for everything, including text rendering and manipulation. We use a slightly-modified variation of 'FontStrokeRoman' from GLUT, which is just a bunch of static lines. We like this as it seems to perform very well, easy to rotate/scale/manipulate. We also allow for in-game chat so text is drawn on the fly.
Problem
We want to use more/different fonts.
We've found several other fonts we like, but they are all TTF-type fonts that are built as polygons (with curves, etc.) instead of strokes or spines. This brings up a few problems:
We'd have to use textures (which we've avoided so far in the game)
They're not easily resizable/rotatable/etc.
Performance is significantly less (theoretically?)
We've experimented with converting the TTF fonts to polygon point arrays and then triangulating the fill. This however has been difficult to render nicely - pixel hinting/anti-aliasing seems difficult to do in this case.
We've even experimented with skeletonize-ing the polygon fonts using libraries like 'campskeleton', so we can output a vector-stroke font (with not much success that looks good).
What should we do?
I know this question is somewhat general. We want to keep performance and text manipulation abilities but be able to use better fonts. I am open to any suggestion in any direction.
Some solutions could be answers to the following:
How do we properly anti-alias polygon-based text and still keep performance?
Do textures really perform worse than static point arrays? Maybe I have a faulty assumption
Can textured fonts be resized/rotated in a fast manner?
Something entirely different?
After some convincing (thanks Serge) and trying out several of the suggestions here (including FTGL that uses freetype), we have settled on:
Font-Stash which uses stb_truetype
This seemed perfect for our game. Rendering performance was comparable to the vector-based stroke font we used - textured quads really are not that slow, once generated, and the caching from Font-Stash helps immensely. Also, the use of stb_truetype allowed us to not require another dependency in the game across all platforms.
For what its worth, this solution was roughly an order of magnitude faster than using FTGL for true-type fonts, probably because of the caching.
Thanks for the suggestions and pointers.
Update
The Font-Stash link above was a fork of the original here. The original has since been updated, has added some of the features that the fork, and can allow different rendering back-ends.
I'm no OpenGL expert, or graphical expert in general.
And, really, Raptor, I -hate- to be the guy that says this, because I know how you feel right now.
I really hate to say it, but honestly, I'd just give TTF fonts a shot, using their textures and polygons as they were intended. I doubt that such a usage would truly be detrimental towards your performance these days. It would likely be more valuable to save time to use them as is, rather than spending time to experiment around for some clever solution that more fits your desires.
I doubt that text drawing using polygons/textures would be detrimental, whatsoever, to you performance. This especially applies for today's computers. How many years back, technologically, do you intend on supporting with your application? Or perhaps you wish to run it on the Raspberry PI as well? Or other mobile platforms that do not have high graphical capabilities? Support of any of these could, perhaps, invalidate my claims.
But, like I said, I really hate to be the guy that suggests you to trudge forward as is. Because, I've been there, asking for performance advice (sometimes over even tinier things) and just groaning when someone says 'forget about it, the compiler will handle it' or 'computers are so advanced you shouldn't worry about it'. I honestly hope that someone else comes in with experience, and a good answer for you. However, if not, I just want let you know: I cannot foresee the possibility that using TTF, as it was intended, would be detrimental whatsoever to your gameplay performance.
Did you try outline glyph decomposition using freetype FT_Outline_Decompose ?
Freetype is the tool of choice for font rendering and glyph outlines extraction. Hinting is supported and rendering modes allows you to specify that you want antialiazing, hinting, monochrome targets etc.
Freetype also has a built in glyph/bitmaps cache mechanism which may be useful.
Note : OGFLT seems to bridge the gap between freetype and opengl although I never has the chance to use it

Rendering Vector Graphics in OpenGL? [duplicate]

This question already has answers here:
Displaying SVG in OpenGL without intermediate raster
(5 answers)
Closed 5 years ago.
Is there a way to load a vector graphics file and then render it using OpenGL? This is a vague question as I don't know much about file formats for vector graphics. I know of SVG, though.
Turning it to raster isn't really helpful as I want to do real time zooming in on the objects.
I see most of the answers are about Qt somehow, even though the original question doesn't mention it. Here's my answer in terms of OpenGL alone (which also benefits greatly from the passage of time, as it could not have been given in 2010):
Since 2011, the state of the art is Mark Kilgard's baby, NV_path_rendering, which is currently only a vendor (Nvidia) extension as you might have guessed already from its name. There are a lot of materials on that:
https://developer.nvidia.com/nv-path-rendering Nvidia hub, but some material on the landing page is not the most up-to-date
http://developer.download.nvidia.com/devzone/devcenter/gamegraphics/files/opengl/gpupathrender.pdf Siggraph 2012 paper
http://on-demand.gputechconf.com/gtc/2014/presentations/S4810-accelerating-vector-graphics-mobile-web.pdf GTC 2014 presentation
http://www.opengl.org/registry/specs/NV/path_rendering.txt official extension doc
NV_path_rendering is now used by Google's Skia library behind the scenes, when available. (Nvidia contributed the code in late 2013 and 2014.)
You can of course load SVGs and such https://www.youtube.com/watch?v=bCrohG6PJQE. They also support the PostScript syntax for paths. You can also mix path rendering with other OpenGL (3D) stuff, as demoed at:
https://www.youtube.com/watch?v=FVYl4o1rgIs
https://www.youtube.com/watch?v=yZBXGLlmg2U
An upstart having even less (or downright no) vendor support or academic glitz is NanoVG, which is currently developed and maintained. (https://github.com/memononen/nanovg) Given the number of 2D libraries over OpenGL that have come and gone over time, you're taking a big bet using something not supported by a major vendor, in my humble opinion.
This isn't an implementation, but very relevant to your question and viewers.
Chapter 25. Rendering Vector Art on the GPU
https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch25.html
Let me expand on Greg's answer.
It's true that Qt has a SVG renderer class, QSvgRenderer. Also, any drawing that you do in Qt can be done on any "QPaintDevice", where we're interested in the following "paint devices":
A Qt widget;
In particular, a GL-based Qt widget (QGLWidget);
A Qt image
So, if you decide to use Qt, your options are:
Stop using your current method of setting up the window (and GL context), and start using QGLWidget for all your rendering, including the SVG rendering. This might be a pretty small change, depending on your needs. QGLWidget isn't particularly limiting in its capabilities.
Use QSvgRenderer to render to a QImage, then put the data from that QImage into a GL texture (as you normally would), and render it any way you want (e.g. into a rectangular GL_QUAD). Might have worse performance than the other method but requires the least change to your code.
Wondering what QGLWidget does exactly? Well, when you issue Qt rendering commands to a QGLWidget, they're translated to GL calls for you. And this also happens when the rendering commands are issued by the SVG renderer. So in the end, your SVG is going to end up being rendered via a bunch of GL primitives (lines, polygons, etc).
This has a disadvantage. Different videocards implement OpenGL slightly differently, and Qt does not (and can not) account for all those differences. So, for example, if your user has a cheap on-board Intel videocard, then his videocard doesn't support OpenGL antialiasing, and this means your SVG will also look aliased (jaggy), if you render it directly to a QGLWidget. Going through a QImage avoids such problems.
You can use the QImage method when you're zooming in realtime, too. It just depends on how fast you need it to be. You may need careful optimizations such as reusing the same QImage, and enabling clipping for your QPainter.
Qt has good support for directly rendering SVG images using OpenGL functionality (see the documentation for QSvgRenderer).
I hope that helps.
It has primitives like GL_LINES and GL_LINE_STRIP for drawing lines in space if that's what you mean. Edit: This site has some information: http://www.falloutsoftware.com/tutorials/gl/gl2p5.htm

Cross-platform drawing library

I've been looking for a good cross-platform 2D drawing library that can be called from C++ and can be used to draw some fairly simple geometry; lines, rectangles, circles, and text (horizontal and vertical) for some charts, and save the output to PNG.
I think a commercial package would be preferable over open source because we would prefer not to have to worry about licensing issues (unless there's something with a BSD style license with no credit clause). I've looked at Cairo Graphics which seemed promising, but the text rendering looks like crap out of the box, and upgrading the text back-end brings us into murky license land.
I need it for Windows, Mac and Linux. Preferably something fairly lightweight and simple to integrate. I've thought about Qt but that's way too heavy for our application.
Any ideas on this would be awesome.
Try Anti-Grain Geometry. From the description:
Anti-Grain Geometry (AGG) is an Open Source, free of charge graphic library, written in industrially standard C++. The terms and conditions of use AGG are described on The License page. AGG doesn't depend on any graphic API or technology. Basically, you can think of AGG as of a rendering engine that produces pixel images in memory from some vectorial data. But of course, AGG can do much more than that. The ideas and the philosophy of AGG are:
Anti-Aliasing.
Subpixel Accuracy.
The highest possible quality.
High performance.
Platform independence and compatibility.
Flexibility and extensibility.
Lightweight design.
Reliability and stability (including numerical stability).
Another one: Skia. Used in Android and Chrome, under active development, HW acceleration.
Have a look at SFML. It's open source but the license is very permissive.
Drawing simple shapes
Displaying text
Antigrain does high quality primitive rendering and seems to be able to render true type fonts and has a commercial license available upon request.
http://www.antigrain.com/
Have you tried FLTK? It is lightweight, cross-platform, has support for 2D/3D graphics and comes with a good widget set (including a charting component). The API is simple and straight forward.
Use SDL
There is also libgd - simple one, but well-written.
Regarding Cairo Graphics, I can't believe it renders text that looks bad. If you are particularly concerned about text rendering, State of the Text Rendering from Jan 2010 gives quite good overview.
I use CImg: cross platform (self contained single header file), simple, concise.
PNG is not natively supported but can be handled if ImageMagick is installed (see supported formats).
See also this related question.
You might use Allegro 5 (since SDL and SFML are mentioned). This provides all of the platforms you require (and more) and can render shapes and save to PNG. Version 5 has a much improved API and hardware acceleration. With any of these low level cross platform libraries you'd have to find your own charting solution.
I put some notes on my blog about Allegro and using it on the Mac.
OpenGL?
I would go for AGG or Cairo.

CoreImage for Win32

For those not familiar with Core Image, here's a good description of it:
http://developer.apple.com/macosx/coreimage.html
Is there something equivalent to Apple's CoreImage/CoreVideo for Windows? I looked around and found the DirectX/Direct3D stuff, which has all the underlying pieces, but there doesn't appear to be any high level API to work with, unless you're willing to use .NET AND use WPF, neither of which really interest me.
The basic idea would be create/load an image, attach any number of filters that can be chained together, forming a graph, and then render the image to an HDC, using the GPU to do most of the hard work. DirectX/Direct3D has these pieces, but you have to jump through a lot of hoops (or so it appears) to use it.
There are a variety of tools for working with shaders (such as RenderMonkey and FX-Composer), but no direct equivalent to CoreImage.
But stacking up fragment shaders on top of each other is not very hard, so if you don't mind learning OpenGL it would be quite doable to build a framework that applies shaders to an input image and draws the result to an HDC.
Adobe's new Pixel Blender is the closest technology out there. It is cross-platform -- it's part of the Flash 10 runtime, as well as the key pixel-oriented CS4 apps, namely After Effects and (soon) Photoshop. It's unclear, however, how much is currently exposed for embedding in other applications at this point. In the most extreme case it should be possible to embed by embedding a Flash view, but that is more overhead than would obviously be idea.
There is also at least one smaller-scale 3rd party offering: Conduit Pixel Engine. It is commercial, with no licensing price clearly listed, however.
I've now got a solution to this. I've implemented an ImageContext class, a special Image class, and a Filter class that allows similar functionality to Apple's CoreImage. All three use OpenGL (I gave up trying to get this to work on DirectX due to image quality issues, if someone knows DirectX well contact me, because I'd love to have a Dx version) to render an image(s) to a context and use the filters to apply their effects (as HLGL frag shaders). There's a brief write up here:
ImageKit
with a screen shot of an example filter and some sample source code.