Solution for displaying text-based labels on opengl
-
Problem:
Displaying text-based labels (let's say max 10 numerical values with names eg "width: 10 \n height:10 .....")given:
- position in world-space 3d
- text
data specifics:
- up to 10 000 points to label
- opacity (maybe)
- points move? no
- max 200 new points/sec
- model-view and projection matrices (used in openGL)
required features:
+++ selecting (eg. to display additional data in gui)- auto positioning (so not to overlap)
- moving labels
So I have already some opengl graphics displayed. I want to draw some labels on it. Possible solutions are:
S1. Stick to OpenGL and draw labels inside it. Use font rendering eg. freetype-gl.- using opengl gives flexibility
- computing screen-space inside shader
- selecting can be tricky (openGL)
- moving can be tricky (openGL)
- required new lib(learn/test etc.) or writing own text rendering engine
S2. like S1, but render to texture instead of rendering text per glyph.
- easy (can render easily in Qt to Picture and sand to texture)
- textures can take a lot of memory
- big CPU->PGU data transfer
S3. Draw labels as QGraphicsItems
- easy (?) placing
- easy moving
- computing word-space coords on CPU
- not optimal?
S4. Draw labels inside QtQuick
- easy (?) placing
- easy moving
- computing word-space coords on CPU
- opengl-qml data sync required
- i like qtquick xD
I know the problem cannot be strictly answered but maybe you can share your thoughts about this problem?
-
I think it would be better to stay inside OpenGl. Drawing the labels using QGraphicsItem or Quick would be a lot of overhead (unless you are thinking to draw everything using QGrapicsScenen/View and not just the labels).
I have tried both methods you suggested (texture and direct text rendering). The texture method I used was to have a texture created for each unique letter. The first letter 'X' would take some time as the texture would be created for that letter but you can re-use this for subsequent uses of that particular character. Each label would be a class containing the four vertex corners for the area and a list of textures.
I find rendering the text directly is more sane and works better overall (less complicated).
For selection wouldn't it be better (and easier) to select what is drawn instead of the label? It is more natural to click on the drawn item then the label. Without knowing what you are drawing maybe this isn't true in your case.
If you will have 10,000 labels drawn at one time you won't be able to read most of them. Auto positioning is possible but this only works if you have a reasonable number of labels to draw. I have tried two methods for auto positioning; placement around the edges of the viewport with leader lines and placement a controllable distance away from the drawn item in a direction from the center of the model or viewport. I prefer the second method. This is very tough if you want to keep leader lines from crossing. With 10,000 labels it is best to draw directly on-top of the item and hope for the best.
-
Sorry for a delay, and thanks for your response.
I thought 1 texture per symbol is the most "direct" text rendering, what do you mean by rendering a text directly?
I find rendering a whole label to be easier because it can be done by eg. creating image from rich txt format and "uploading" it to a texture. And you have all the nice stuff like underlines, shadows, etc. for free ( as long using QTextDocument and QImage is considered "free" :) )As for selecting: I feel like being able to select an item by clicking anything from the item (item itself, label, arrow from item to label etc.) is the way to go from UX point of view but I may be wrong. In my case moving labels would be nice too. All of this can be achieved easier using widgets, but certainly can be done with OpenGL too.
oh, and a nice avatar you have :)
-
I thought 1 texture per symbol is the most "direct" text rendering, what do you mean by rendering a text directly?
You can draw the text directly on the window. With QOpenGLWidget your render function draws all the OpenGL stuff as normal and then you can create an instance of QPainter and render anything else you want (including text) like any other QWidget. That is what I meant by 'direct' (probably a bad choice of words on my part).
oh, and a nice avatar you have :)
That's Spiky. He is an albino hedgehog. He always tried to stab me whenever he could (he would curl up and sneeze when you pick him up). He was quite the character. His eyes were actually red which went along with his personality.
-
you can create an instance of QPainter and render anything else you want
It looks like "fixed pipeline" :) I'll check this out, thanks. Moving labels is not as easy as with GraphicsItems, is it?
That's Spiky. He is an albino hedgehog. He always tried to stab me whenever he could (he would curl up and sneeze when you pick him up). He was quite the character. His eyes were actually red which went along with his personality.
little devil, huh? At first (from afar) I thought he's a little chicken xD Didn't know that hedgehogs are such a brutal beasts :P