PDA

View Full Version : wide, cruved lines (without gaps)



revillo
05-18-2009, 12:49 AM
Hi. First of all i have to say that i'm new to OpenGL programming and to this forums.

I'm trying to render lines in OpenGL. These lines connect related elements in different graph representations. The lines are curved, because there can be one or more elements in a specific graph, linked to one element in the other graph. So the lines first connect to a bundling point, then the lines connect to the related element.

So i have the start-, bundling- and end-point of the curve in a floatBuffer.

Then i'm using

glMap1f(GL.GL_MAP1_VERTEX_3, 0.0f, 1.0f, 3, 3, points)
and draw the line within the following loop

gl.glBegin(GL.GL_LINE_STRIP);
for (int i = 0; i <= 10; i++) {
gl.glEvalCoord1f((float) i / 10);
}
gl.glEnd();

So the line is drawn and curved. It works. But the problem is, when i increment the line-width, V-shaped gaps are appearing between the stippled lines. In my case, i really need this lines perfect at any width.

I used the search for a while and i did find someone with the exact same problem, but unfortunatly there was no sufficient solution. The tipp was, to fit in points in the V-shaped gaps. But as i mentioned, i need the lines to be perfect.

So my approached now would be to

a) setting up polygons instead of lines. This would mean, getting the points that would be connected with lines and calculate a normal vector. Add and subtract half of the width in the direction of the normal vector to get 4 instead of 2 points. Create a polygon with this 4 points. From the second stipple-piece on i would need to use GL_QUAD_STIPPLE i think. I would use the same approach as just mentioned, but the two end-points of the prevoius polygon would add up. So i would have 6 points. The 2 of the previous and then my 4 calculated.

b) creating a surface that looks like a line. Is this possible in OpenGL and would this be a good approach? The idea is the following. Given the 3 points (start, bundling and end) i first create a straigth between the start and the end and calculate the normal vector of this straight. Now i calculate 6 points by - like above - add and subtract (width/2) in the direction of the normal vector form the 3 points. Then i would try to create a surface using the 6 points which looks like a line but would no have the gaps. Does anybody know if this is possible?

What approach would you guys take? As i mentioned, OpenGL is new to me so a hint from you guys would be really helpful. Or maybe you have another idea? I also would appreciate some references with this problem. Used search on ACM, CiteSeer and also the library of my university but i didn't find any papers on this problem. But i guess the solution of this (rather simple) problem could be far in the past, which could be the reason for not finding anything.

dletozeun
05-18-2009, 01:22 AM
It is quite hard to follow you without any picture. To solve your issue, as you said the idea is to draw polygons.

What you can do is draw a quad between the beginning point and the end point. In addition, you can draw something like a triangle fan at each line joint to avoid V-shaped-holes. Instead you will get a smooth curved joint depending on the number of triangles drawn for this one.

I do not have time to make a drawing right now but I hope you get the idea. :)

revillo
05-18-2009, 02:09 AM
Thanks for the quick answer. So i will go for the polygon-approach.

The triangle fan sounds like a good solution, but i would have to calculate really a lot of points (if i get your idea right).

zed
05-18-2009, 02:27 AM
a fans not gonna work, but its close. think of segment cut out of a hollow tube.
Ive done it before + u dont need that many points, even with wide lines ~10 should look good

dletozeun
05-18-2009, 02:29 AM
With the triangle fan you can control the points count used to fill the hole. You even just draw one triangle to fill this one and not adding any extra point.

revillo
05-18-2009, 03:19 AM
With the triangle fan you can control the points count used to fill the hole. You even just draw one triangle to fill this one and not adding any extra point.
Not sure if i understand you correctly. You mean to draw normal lines and only use triangles to fill the gaps. As i'm drawing 10 stipples right now, this would mean to fit in 10 triangles between the gaps.

My idea was to use no lines anymore, only polygons.


a fans not gonna work, but its close. think of segment cut out of a hollow tube.
Ive done it before + u dont need that many points, even with wide lines ~10 should look good
If i understand you correctly, you mean to use 10 polygons to render the line, but not triangles. Is this right? Can you a little more into detail.

Sorry if i got your answers wrong, i'm no native speaker as you surely noticed.

zed
05-18-2009, 04:25 PM
I apologize I was wrong dletozeun (I dont know why but on these boards my IQ drops like 50 points)
yes a tri fan is whats needed

first point originates from where the two segments meet
here Im using just one tri between the quads, u can use a tri fan if u want the lines to look extra round, but even just one tri looks pretty good

in wireframe so u can understand how the line is constructed
http://www.zedzeek.com/junk/line.jpg
if u want a more 3d look an alternative is to create a 3d cylinder mesh, here Im using a Bspline I think
http://www.zedzeek.com/junk/line2.jpg

revillo
05-18-2009, 11:47 PM
Thanks zed. With the picture i get a really good idea.

Now i only need to calculate the points on the curve by myself i think as the OpenGL evaluation function is void.

Thanks again for your help guys.

dletozeun
05-19-2009, 01:47 AM
I apologize I was wrong dletozeun (I dont know why but on these boards my IQ drops like 50 points)
yes a tri fan is whats needed


Don't be sorry :) Actually I did not understand why I was wrong and I was waiting that you post a picture to illustrate your idea which is eventually what I was trying to explain too.



My idea was to use no lines anymore, only polygons.


My idea was to use only polygons too. I do not understand how it could be achieved another way... anyway zed's picture explains it clearly. :)

revillo
08-13-2009, 01:58 AM
Hey guys. I stopped working on this project back then, but now i restated working.

I wanted to do it as you described. But now i have a mathematical problem:

To draw that polygon lines, i need to generate 2 vertices from 1.

line:
A x----------------x B

polygon line:
A1 x----------------x B1

A2 x----------------x B2

In a 2D Space, this wouldn't be a problem. I could use normals to generate these points. Something like this:
A1 = A + width/2 * normal;
A2 = A - width/2 * normal;

Same thing could possibly work in 3D, but i don't have a clue how to obtain the normals or any reasonable direction vector. In 3D space i would need a plane to get a normal. But i don't know how to create a reasonable plane in space.

In 2D my idea was to create the normals at a vertex as the mean normal of the joining segments.

--------line a------------x-------------line b-----------

Imagine this lines are not straight. At vertex x i would use normal(a) + normal(b). This would be the mean normal and so the line would look good.

But in 3D? How to create them? It should look like a line on the screen, so z-axis could be ignored (or not?).

madmortigan
08-13-2009, 03:50 AM
Howdy

If you model your lines in 3d as polygons, to get them drawn properly at different line widths, when you rotate your model, viewing the polygons from the side, your lines will become thin again.

A line with some width in 3d is a cylinder, mathematically speaking. You could model your lines as pipes, with square cross-section, for example. Performance would not be as good, but still easily done in today's hardware.

madmortigan

revillo
08-13-2009, 05:08 AM
Thanks for your answer madmortigan. In my special situation, the models won't be rotated. It's a graph and the scene keeps it's perspective. But some elements are deeper than other, so it's still 3D.

Tubes are for two reasons no option for me: I am new to OpenGL and because of the performance. In the graph there can be many many lines at once. The application should also run via webstart. So performance is an issue.

The tubes are also too complex for my skills at the moment. I use Java and JOGL, so i'm not able to use GLE library. I would have to draw the cylinders by myself and use vertex shaders to fill the gaps. That's not what i want to do at the moment.

My actual problem is the generation of 2 vertices out of one. From a linestrip to a triangle- or quadstrip.

http://img219.imageshack.us/img219/4337/polyline.png

Maybe this picture describes it better (don't look at the angles or correctness ;) ). I have written a NURBS class that calculates the curve points (black in the picture). Now i want to draw the line als triangle- or quadstrip (Quad would be better i think, because i want to map rectangle textures). Therefore, i need to calculate 2 vertices (green) out of one (black). This could be done by addition and subtraction of a direction vector to the original vertice (black). This direction vector, which would be normals in 2D, are the green ones in my picture.

madmortigan
08-13-2009, 05:35 AM
You seem to have worked this out, but just in case, and to answer your previous question, I think the vector you're missing to generate the green direction vectors in 3d is the view direction vector, ie the vector joining the black curve points and the camera position.

If you take the tangent vector on the black curve (eg., the vector joining two consecutive curve points would do), and do a cross product with the camera-to-point vector, you'll get the direction of the green vectors.

I hope this helps.

madm

revillo
08-13-2009, 08:03 AM
Thats it, thanks you very much madmortigan!

The only problem left now are the aliased edges of the quadstrip.

http://img228.imageshack.us/img228/2717/aliasedpolylinequadstri.png

Antialiasing is activated. But i guess i can figure this one out. There should be threads with this problem.