OpenGL VBO Loading Font data - opengl

I need to draw a VBO consisting of font data, mainly numbers. How do I obtain the data and send it to the VBO?
I know that there is a library called freetype which should do this, but that uses bitmap fonts and I do not need bitmaps in my project. I just want polygon data which I can fill with my own color and reposition/scale.
Freetype also does outline fonts, but how do I go about tessellating the outline fonts to create accurate geometry?
Is what I am trying to achieve difficult? Can I find some examples of something similar?

Is what I am trying to achieve difficult?
In the case of rendering crisp fonts at all sizes with proper gamma correction and antialiasing: Yes!
This is actually a subject of active research.
Can I find some examples of something similar?
Just use a ready to use font drawing library for OpenGL, like FTGL.

A solution that could work is to save the font data as XY coordinates with indices from a 3D Modeling program. Than this data is loaded at startup, the result being the desired one.
Of course that this does not work when changing fonts and it takes time, but if the font will not change, it does its job.

Related

How can i draw outline or shadow to a text with using OpenCV?

In my C++ project, im using OpenCV library to implement image processing algorithms.
I want to draw outline or shadow to texts that i drew on frames with using OpenCV's putText function. I have researched about it but only solution that i found is drawing the same text twice. This solution drops the FPS of my overall project because im drawing many texts on the frames.
Do i have to code a new font library for my project or is there any simpler solutions to it?
thanks in advance.
EDIT: I tried FreeType with different ttf fonts that i found in various websites. Yes, there are some fonts that has default shadow or outlines in it. The problem here is i can't change the colour of the shadow of it. Yes, i can change the colour of overall font but shadow colour becomes the same as the font. I want black or white shadow that can highlight the text.
The simplest thing to do is draw the text once to an empty image, say A. then mask your main image several times with A, shifting A as required.
You could use freetype. OpenCV can be compiled with FreeType which will allow you to load fonts from ttf files. then you can look up for a free font online which suits four needs of make your own ttf file.
Here is a link on how to use FreeType with opencv.
https://docs.opencv.org/3.4/d9/dfa/classcv_1_1freetype_1_1FreeType2.html

How to send QImage to Qt3D Entity from C++ to QML for using it as texture?

I need to change the texture of a plane in a 3D scene. In the BackEnd class in C++ I make a new QImage for setting it on a texture. I want to send it as a signal to my QML and there assign it to the planes material property.
But it looks like TextureMaterial etc. can only use a URL path to a texture file. I cant't save my Images to my hard drive to use them as a URL path. It will be too long. I need to change my texture 20+ times in a second and there are other things which this program should to do in the same time.
Is there any way to do this?
You can have a look at my implementation of a background image in Qt3D.
The way I achieved what you are looking for is by using the classes QTextureMaterial, QTexture2D and QPaintedTextureImage. I had to flip the image before drawing it that's why I subclassed QPaintedTextureImage but this might also just be what you need. Instead of loading the texture from disk, like I did, you could set the QImage on your subclass as an attribute. You only need to make the C++ class available to QML and set it on your plane (maybe you could even use PaintedTextureImage directly and write the image painting in their JavaScript-style language).
You can add your QPaintedTextureIage to the QTexture2D and then set the result as the texture on the QTextureMaterial. I'm not sure if this yields the best performance, though.
You could also try to follow these steps but they seem to be a bit more involved. This would mean you have to implement your own version of QAbstractTextureImage and return the appropriate QTextureImageDataGeneratorPtr. You can checkout the sources to gain a better understanding.

OpenGL & Qt : display a label on the mouseover

I'm working with OpenGL and Qt. I render a scene in an OpenGLWidget. When hovering over objects in the scene, I would like to display a box near the selected object with some text. I have already implemented the selection of the object.
I thought of two possible approaches.
Place a widget (such as a QLabel) above the OpenGLWidget in
which the scene is rendered.
Render the text in a quad directly in OpenGL.
Which of the two approaches you recommend and you could please give me some suggestions on implementation. Alternatively, you could recommend another approach. Thanks!
Hi #Artic I am not a Qt expert so I can't give you information on widgets, but I can give you some pointers for creating a label with OpenGL. Giving a full implementation is tricky here because it depends a lot on how you want to display the text. But I'll try to outline some of your options.
To render text in OpenGL most people go with a technique known as bitmap fonts, see more here:
https://learnopengl.com/In-Practice/Text-Rendering
The concept of bitmap fonts is fairly straight forward, all characters are pre-rasterized to a texture and then you can sample from each part of the texture depending on the character you need. You build your label out of quads, textured with each part of the bitmap you sample from for each character.
Signed distance fields essentially use the same technique but the pre-rasterized texture of characters are rendered using signed distance fields which deal with some of the issues that standard bitmaps fonts have.
In basic terms, SDF works by generating a special texture, or image, of the font that stores the distance from the edge of each character to its centre, using the colour channels of the image to record the data.
If you use signed distance fields it won't be enough to just sample from your bitmap, fonts rendered this way require extra work (typically done using a shader program) to produce the correct rendering.
Once you have a way of generating a label you can decide if you want to display it in screen space or in world space.
If you want to display it in world space (where the label is hovering over the model or item) you will need to do more work if you want that label to always face the camera and this technique is called billboarding.
You could also render your text "on the fly" if you just want to render some text to the screen in screen space. You can use a library like SDL_ttf.
See: http://lazyfoo.net/tutorials/SDL/16_true_type_fonts/index.php
In this example you use SDL_ttf to render a string of text to a surface with dimensions of your choosing, you can then create an OpenGL texture from that surface and render it to the screen.
Sorry if this information is a bit broad, I would need a more specific question to give you further implementation details.
For an implementation, I would evaluate the pros and cons based on what you need. If you haven't implemented a system for rendering text before it's probably best to stick with something simple; there are more techniques for text rendering than I have listed here such as turning text in to polygons and other libraries which attempt to deal with some of the issues with traditional font rendering techniques but you probably don't need anything complicated.
For a recommendation on which to use I would go with the technique that you feel most comfortable with, typically doing things from scratch in OpenGL will take more time but it can provide you with a nicer set of functionality to use in the future. However if Qt already has something nice for rendering a label (such as a widget that you mentioned) it is probably worth taking the time to learn how to use it as it may yield faster results and you don't want to reinvent the wheel if you don't need to. On that note though doing things from scratch with OpenGL can be very rewarding and greatly improve your understanding since you have to get familiar with how things are done when you don't have a layer of abstraction to depend on. Ultimately it depends on you. Good luck!
You could use tool tips in Qt. The string will appear when the OpenGlWidget is hovered over. You can change the text of the tool tip based on the mouse location in the scene, using the tool tip method showText():
QToolTip::showText(QPoint &position, QString &text, QWidget *w);
There are more options for the showText() method and can be found in Qt's tool tip documentation. Also, here are more examples on how to use Qt tool tips.

QT and OpenGL how to integrate properly and display a texture

I have a few questions about using them both. At the moment I have a preexisting renderer I'm trying to use with QT and OpenGL.
A few questions are:
How can I get my results to draw in a QGraphicsScene? Is that even the right output to attempt to be using.
With OpenGL I want to be able to load textures and then be displayed in a window? Do I need to coordinate where to draw the texture or can I just say in the centre of a QWidget?
What paramenter would I usually need, I persume I need a Gluint for the texture, and then parameters for the size?
At the moment my results are quite poor, it seems to render something but basically not either in the correct window or not in the window of choice and basically it seems to 'hide' text e.g. hello, I can only see e. Odd I think.
I'm pretty sure this link will help you code with Qt and OpenGL:
http://wesley.vidiqatch.org/03-08-2009/nehe-opengl-lessons-in-qt-chapter-1-and-2
I used this and the NeHe tutorial to code a small Qt/OpenGL application, so all information you need is contained in both tutorials.

Hardware accelerated Unicode text rendering

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 :-)