← Back to team overview

kicad-developers team mailing list archive

Re: Text in opengl

 

On 02/23/2014 09:59 AM, Lorenzo Marcantonio wrote:
I really find ugly/distracting the messy line width in text in the
opengl view, so investigated the thing...

At the moment it generates the endpoint list and draw it thru the GAL
DrawPolyline function. This substantially convert the line to a polygon
to rasterize it with round endcaps, getting bluntly rounded by the
transformation/projection matrices. I agree that's the right way to draw
tracks and similar things. It also seems to me that the line is drawn
with a fragment shader using a technique like that used for the circle
(I never used shaders and I'm a bit confused... the comments talk about
a *vertex* shader? AFAIK they aren't even supported on the
Intel-Tungsten...)

Truly they are. Vertex shaders are said to be supported since OpenGL 2.0, so fortunately most of current GPUs are compatible.

In the process it pumps quite a bit of vertices (I'd say about 12 for
a single line segment, but maybe I'm wrong).

You are right.

I think text could be better drawn using the classic GL_LINE_STRIP
primitive and glLineWidth for setting the width. In aliased mode these
are guaranteed to produce uniform line widths, since simply generate
parallel fragments. Truly, line width >1 are not guaranteed but I never
seen a GPU not doing these...

I do not want to discourage you, but I am somehow sure that after deploying the code, you will find at least a few combinations of GPU/driver (most likely open)/OS that support only 1 pixel wide lines.

Also this would pump only 1-2 vertices for line and, given how much text
there is on a board with netlist name shown, should be quite
a performance improvement. On a medium sized board I see:

09:50:25: Debug: RecacheAllItems::immediately: 1 1605,7 ms
09:50:25: Debug: Uploading 2097152 vertices to GPU / 62,8 ms

When showing netnames and pad numbers. Disabling them I have:

09:51:02: Debug: RecacheAllItems::immediately: 1 1091,1 ms
09:51:02: Debug: Uploading 1048576 vertices to GPU / 35,3 ms

That would need adding a DrawSimplePolyline member to the GAL layer
doing the different draw processing. The bad side would be that this
would apply even to copper text; I don't think the difference will be
significant (since it's visual only, anyway)... if really wanted to
maintain the 'precision' off copper text a flag could be added to the
text function.

What do you think of that? Have I missed something crucially important?

Assuming that *every* card supports lines wider than 1 pixel, you are still limited to available line width range. In my case (integrated Intel GPU), http://pastebin.com/86jqj2bV outputs:
line width range: 1.000000 - 5.000000
line granularity: 0.500000
I am afraid you will not get much more on better video cards. As transformations do not apply to line width, you can have up to 5 pixel wide lines (at least in my case). This may be a problem for copper texts (as you rather expect them to apply to WYSIWYG), but should not be a limitation for netnames (depends on sight quality). Currently, OpenGL GAL makes use of VBOs. Most of "static" data (e.g. tracks, vias) are cached in GPU memory and to draw them you only send vertex indices. "Dynamic" data (e.g. preview, selection box, other temporary drawings) is collected and sent in one batch. Only grid and compositing (draw a few textured quads) are done using direct mode.
It leads to 2 options:
- Handling a VBO for line strips (and probably a shader or some other way of controlling line width per line, not for the whole batch). I am not sure if degenerated vertices (i.e. two consecutives vertices with the same coordinates to indicate beginning of a new line) work in GL_LINE_STRIP mode, otherwise you have to use GL_LINE instead. - Drawing using direct mode, but in this case all lines should be drawn at the same time. Also I wonder how does it compete with current VBO batch in terms of performance. If I had to choose, I would go for bitmap fonts. It makes every character one quad or two triangles. Or maybe antialiasing could solve the problem?

Regards,
Orson

PS: for the XXX todo comments in the following bezier curves I'd
recommend the de Casteljau algorithm (which seems to be the current
standard for drawing them). Too bad they deprecated evaluators in newer
OpenGL, if hw accelerated like in the old FireGL they would be *the*
solution, here.



Follow ups

References