Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » OpenGL - rounded lines

Credits go to Billybob, razor, and Steve Terry for helping out!
This thread is locked; no one can reply to it. rss feed Print
OpenGL - rounded lines
gnolam
Member #2,030
March 2002
avatar

Simple question: I want to draw lines with rounded joints in OpenGL. Something like this:
{"name":"lines.png Example","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/3\/93de19c9d286247f057bc07150f06724.png","w":256,"h":256,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/3\/93de19c9d286247f057bc07150f06724"}lines.png Example

Is there an easy way to do this? Or will I have to resort to hacky black magic?

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

Steve Terry
Member #1,989
March 2002
avatar

I've seen this done before in OpenGL, well it was a very cool "oil paint" filter technique but it used rounded lines. I'm not entirely sure how you can do this, but if you can make your lines rounded at the ends, joining two will give you a rounded look. If you make the lines from bitmaps then it should be very easy to pull off.

___________________________________
[ Facebook ]
Microsoft is not the Borg collective. The Borg collective has got proper networking. - planetspace.de
Bill Gates is in fact Shawn Hargreaves' ßî+çh. - Gideon Weems

Billybob
Member #3,136
January 2003

A circle where the two meet?

gnolam
Member #2,030
March 2002
avatar

Quote:

A circle where the two meet?

That was my first thought as well. Unfortunately, I think I will require blended lines at some point. :-/

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

razor
Member #2,256
April 2002
avatar

Quote:

That was my first thought as well. Unfortunately, I think I will require blended lines at some point. :-/

In that case you could use the stencil buffer. Just draw a mask of the line, then use that to draw the actual blended line. I'm not too sure about speed but it should work.

Whoooo Oregon State University

Archon
Member #4,195
January 2004
avatar

glEnable(GL_LINE_SMOOTH);?

gnolam
Member #2,030
March 2002
avatar

razor said:

In that case you could use the stencil buffer. Just draw a mask of the line, then use that to draw the actual blended line. I'm not too sure about speed but it should work.

Neat idea, thanks! Of course, the stencil buffer is black magic to me, but I guess I had to learn how to use it at some point in my life... ;)

Archon said:

glEnable(GL_LINE_SMOOTH);?

Unfortunately, that only enables antialiasing...

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

Jakub Wasilewski
Member #3,653
June 2003
avatar

Unfortunately, the stencil buffer can't be used the same way an alpha mask can, so you lose antialiasing on your lines. Though that might not be a problem.

Alternatively, if that lines are not all that dynamic, you could render the line (together with circles at the joints) to a GL_ALPHA texture, and then use that texture with a quad to render it.

---------------------------
[ ChristmasHack! | My games ] :::: One CSS to style them all, One Javascript to script them, / One HTML to bring them all and in the browser bind them / In the Land of Fantasy where Standards mean something.

Bob
Free Market Evangelist
September 2000
avatar

Quote:

Unfortunately, the stencil buffer can't be used the same way an alpha mask can, so you lose antialiasing on your lines. Though that might not be a problem.

Huh? You get a stencil value per sample, so you can stencil test per sample. Stencil and AA work just fine together.

Note that GL_LINE_SMOOTH has little to do with anti-aliasing.

--
- Bob
[ -- All my signature links are 404 -- ]

gnolam
Member #2,030
March 2002
avatar

Bob said:

Note that GL_LINE_SMOOTH has little to do with anti-aliasing.

Huh?

The people who steadfastly refuse to publish a free command reference's 2.0 spec said:

Antialiasing is controlled with Enable and Disable using the symbolic constant LINE SMOOTH.

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

relpatseht
Member #5,034
September 2004
avatar

well, heres my "solution"

since you would really only notice the curved joints on rather thick lines, and since modern graphics cards dont draw lines, but rather 2 (i think 2 maybe more) thin long triangles to make a line, i would suggest you make your lines with 2 triangles each and have a triangle fan where they meet. (the inside corners of the lines would touch, and the open space at the top would be filled with the triangle fan)

perhaps not the best solution, but it would almost certainly be faster than the stencil buffer.

Billybob
Member #3,136
January 2003

I think a single textured quad would be faster, not that it matters too much.

What Jakub suggested sounds good. Draw the line with Gimp or something at high resolution, 512x512 maybe; Load it into your program, and then use a function that can transform it to match certain parameters. Scale and rotation is all that's need for it to draw the line from any point A to point B.

Jakub Wasilewski
Member #3,653
June 2003
avatar

Quote:

Huh? You get a stencil value per sample, so you can stencil test per sample. Stencil and AA work just fine together.

Okay, which of the following assumptions is wrong?

- to use the stencil buffer to render the lines later, one would need to "render" the quads and the circle at the joint to the stencil buffer
- the stencil buffer can hold a number of bitplanes, so the above rendering will produce only a bitmask in one/several of those, not an actual transparency mask
- the actual rendering is done using a quad or some other object covering the whole area the line covered. Some parts are stenciled out with GL_STENCIL_TEST, which can only decide IF a pixel is drawn or not, so basically this would correspond to an alpha of 1.0 or 0.0
- so, if we do use it that way, we only have pixels that are 100% the color of the quad or 100% the color of what was there before
- so, the line will be jagged and not smooth, hence the phrase "you will lose the antialiasing"

---------------------------
[ ChristmasHack! | My games ] :::: One CSS to style them all, One Javascript to script them, / One HTML to bring them all and in the browser bind them / In the Land of Fantasy where Standards mean something.

Thomas Harte
Member #33
April 2000
avatar

The implied assumption that one stencil buffer pixel = one screen pixel is wrong. As with every other buffer on any card with full scene aa turned on, the stencil buffer is running at some resolution much greater than your screen such that super/subsampling (whichever marketing term you subscribe to) can properly achieve anti-aliasing.

The key part of Bob's post was "Note that GL_LINE_SMOOTH has little to do with anti-aliasing", explaining what sort of anti-aliasing he was talking about!

To be honest though, I think I must not really be following the conversation. Why has stencilling come up? With or without the main problem gnolam wants to address is how to communicate that outline to the graphics card.

Bob
Free Market Evangelist
September 2000
avatar

gnolam said:

Huh?

I believe this is a very liberal use of the term "antialising" in the specification. Notice how the enumerant is called "LINE_SMOOTH" and not "ANTIALIASED_LINE". If you also actually read the spec, you will see that line smoothing has little to do with aliasing:

The OpenGL Specification, 2.0 said:

Rasterized antialiased line segments produce fragments whose fragment squares
intersect a rectangle centered on the line segment. Two of the edges are parallel to
the specified line segment; each is at a distance of one-half the current width from
that segment: one above the segment and one below it. The other two edges pass
through the line endpoints and are perpendicular to the direction of the specified
line segment.

The line isn't sampled at a higher frequency (which is what antialising entails), but rather is smoothed out by drawing additional lines!

relpatseht said:

since modern graphics cards dont draw lines, but rather 2 (i think 2 maybe more) thin long triangles to make a line

Some hardware manufacturers may have gone down to drawing lines this way, but pretty much all Nvidia GPUs that I know of render lines as lines, not triangles.

Rendering lines as triangles has a whole lot of issues associated with it, and in no way can correctly implemenent either OpenGL or Direct3D specifications.

Jakub Wasilewski said:

Okay, which of the following assumptions is wrong?

All of them are right, except for the last two:

Jakub Wasilewski said:

- so, if we do use it that way, we only have pixels that are 100% the color of the quad or 100% the color of what was there before
- so, the line will be jagged and not smooth, hence the phrase "you will lose the antialiasing"

Ahh, but now you are confusing samples with pixels! There are typically N samples per pixels (where N is 1 to 8 these days), so you can actually get up to 8 different values when downsampling samples to pixels, if samples are only allowed to contain two different values.

Nothing stops you from using line smothing, stenciling and multisampling together (although line smothing in combination with multisampling doesn't always give you the result you expect).

--
- Bob
[ -- All my signature links are 404 -- ]

Steve Terry
Member #1,989
March 2002
avatar

Man after thinking about it the simplest way is to use quads + triangle fans, you could probably compute all of that relatively quickly, and rendering would be really fast with all the anti-aliasing you will want.

___________________________________
[ Facebook ]
Microsoft is not the Borg collective. The Borg collective has got proper networking. - planetspace.de
Bill Gates is in fact Shawn Hargreaves' ßî+çh. - Gideon Weems

gnolam
Member #2,030
March 2002
avatar

Quote:

To be honest though, I think I must not really be following the conversation. Why has stencilling come up? With or without the main problem gnolam wants to address is how to communicate that outline to the graphics card.

As I understand it, the stencil method will allow me to use the extremely simple line/circle (line/point?) approach, but still get whatever blending I wanted.

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

Dennis
Member #1,090
July 2003
avatar

(To be honest, i don't know anything about programming OpenGL, but i think the following observation is independet of that fact. Maybe i'm wrong and all that talk above about "stencil buffers"? already adresses that problem.)

Where would you want to place the circle and how large should it be?
(here's a pic to illustrate the problem i see in that approach)
http://homepages.compuserve.de/DennisTapier/allegroforum/linesmootherror.png

Archon
Member #4,195
January 2004
avatar

Dennis: Second method, just make the lines shorter - meet at the center of the circle, rather than making the lines perpendicular.

Jakub Wasilewski
Member #3,653
June 2003
avatar

Bob:

Thanks, I stand corrected. While you can't use the nice-and-easy way GL_LINE_SMOOTH gives you, it is still possible to make them smooth, but you have to use proper multisampling.

Dennis:

I think the first would be the best, with clipping set to eliminate the protruding part.

---------------------------
[ ChristmasHack! | My games ] :::: One CSS to style them all, One Javascript to script them, / One HTML to bring them all and in the browser bind them / In the Land of Fantasy where Standards mean something.

Archon
Member #4,195
January 2004
avatar

Quote:

I think the first would be the best, with clipping set to eliminate the protruding part.

What's wrong with my suggestion?

All he has to do is draw 2 lines to meet at single point which should leave a space (should be a square at the top) - then he can draw a circle in the meeting point with the same diameter to connect the corners of the 2 lines. And it'd work even if the lines change angle.

Dennis
Member #1,090
July 2003
avatar

Archon:
I think i got it.:) pic:
http://homepages.compuserve.de/DennisTapier/allegroforum/linesmoothcorrect.png
(the circle of course needs to be filled and the white lines are only there to show that the black lines need to be understood as rotated rectangles)

Jakub:
Archon's method seems easier, because it does not involve any clipping.

Zaphos
Member #1,468
August 2001

Quote:

The line isn't sampled at a higher frequency (which is what antialising entails), but rather is smoothed out by drawing additional lines!

Isn't your definition of anti-aliasing too specific? I would think that anything which removes the effects of aliasing is a method of antialiasing.

Jakub Wasilewski
Member #3,653
June 2003
avatar

Dennis: I can only defend my choice on the grounds of "looking better", which is mainly personal preference. In your example the difference in looks wouldn't be that much, but please look at the attached image.

The left line shows my approach (not exactly your #1, but closer to that than to #2) - the center of the circle is depicted in orange, the clipping plane is blue with green normal, the red lines show the rectangle limits.

Of course, one can choose any point between the inner and outer corner of the non-rounded intersection, and make this the center of the circle. This allows for different degrees of roundness - my approach being "100%", yours being "50%".

Hm, the more I think about it, the more arguments I find for using your approach. One especially prominent is that your line is actually the shape that would be swept by a circular brush with the diameter corresponding to the line width.

Okay, you win :).

By the way, I'm wondering if gnolam actually implemented this ;).

[EDIT: Corrected some things.]

---------------------------
[ ChristmasHack! | My games ] :::: One CSS to style them all, One Javascript to script them, / One HTML to bring them all and in the browser bind them / In the Land of Fantasy where Standards mean something.

Dennis
Member #1,090
July 2003
avatar

Jakub said:

Okay, you win :).

Cookies to Archon, it was his idea;). With "I think i got it.", i meant "i understood(==got) it".

Jakub also said:

By the way, I'm wondering if gnolam actually implemented this ;).

Me too, as i said, i have no idea about OpenGL programming. I was just interested in the 'visual anomalies', which i first thought the "line, circle" approach could cause, but thanks to Archon that problem is solved.

Go to: