Java-Gaming.org Hi !
Featured games (91)
games approved by the League of Dukes
Games in Showcase (804)
Games in Android Showcase (239)
games submitted by our members
Games in WIP (868)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Polygon corners with GL_LINE  (Read 14511 times)
0 Members and 1 Guest are viewing this topic.
Offline Optimo

Junior Devvie




I'm gon have to know, how ya garden grow


« Posted 2016-10-31 20:43:33 »

I'm making a rectangle with:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
        glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
        GL11.glBegin(GL_POLYGON);
        //top line
        glVertex2f(mX, mY);
        glVertex2f(mX2, mY);        
        //right line
        //glVertex2f(mX2, mY);
        glVertex2f(mX2, mY2);
        //bottom line
        //glVertex2f(mX2, mY2);
        glVertex2f(mX, mY2);        
        //left line
       // glVertex2f(mX, mY2);
        //glVertex2f(mX, mY);
        glEnd();


My corners don't act like proper connecting corners. If I have the shape on GL_FILL, the corners look totally right. If I have it on GL_LINE, the corners of the lines do not totally touch. They stop short of each other on the part that doesn't overlap so that you have an effect looking sort of like: #. Like so:
.
Red is line, black is width. Even at line width 1f the lines do this.

How can I draw a rectangle with proper corners?
Offline KaiHH

JGO Kernel


Medals: 796



« Reply #1 - Posted 2016-10-31 20:51:48 »

You can compute and render the "caps" of the lines manually, so that they connect properly (there might be one or two computer graphics papers on that), or: Have a look at NanoVG to render proper vector graphics with OpenGL, which is supported by the latest LWJGL 3.1.0 release.
Offline theagentd
« Reply #2 - Posted 2016-11-01 03:35:03 »

You have to do it manually. Here's an example:






Myomyomyo.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Optimo

Junior Devvie




I'm gon have to know, how ya garden grow


« Reply #3 - Posted 2016-11-01 03:41:17 »

Can you show me how that is done (manually)? I thought I understood because I'm only making a rectangle, but looking at what you have with all those angles and how it looks proper, I must not fully understand how to do it.

Self calculation is way more prudent than adding a library at this point.
Offline theagentd
« Reply #4 - Posted 2016-11-01 05:29:21 »

You basically draw lines using triangles to accomplish this. A line is defined by two points and a line width, which in turn forms a quad. To get the result I did, you need extra information. The shape of a line's corners depends not just on the line itself, but also on the previous and next lines that we're connecting it to.




So, given four input 2D vertex positions (V1-V4) and a line width, we need to do the following:


1. Calculate the normalized vectors of each line: L1 = normalize(V2-V1), L2 = normalize(V3-V2), L3 = normalize(V4-V3).

2. We then calculate the directions of the green lines. This is done by normalizing the average of two line directions and rotating it 90 degrees (= calculate the normal of a line): G1 = rotate90Degrees(normalize(L1+L2)), G2 = rotate90Degrees(normalize(L2+L3)). rotate90Degrees() takes in (x, y) and returns (-y, x).

3. We now know that the four blue dots we're looking for are equal to
B1 and B2 = V2 +- G1*lineWidth/2 * x
and
B3 and B4 = V3 +- G2*lineWidth/2 * y
.


If we set x and y to 1.0, the system works for straight lines, but as the angles at V2 and V3 get smaller we'll get thinner and thinner lines, so we need to compensate for that. Let's imagine some cases and try to come up with how x (and y) should be calculate:
 - If L2 just continues in the exact same direction as L1 (180 degree angle), no compensation is necessary in that case. In this case we want x to be equal to 1.0.
 - If L1 and L2 form a 90 degree corner, it's clear that the green line needs to cover the hypothenuse of a right triangle. Given two sides of 1 and 1, the hypothenuse becomes sqrt(2), so in this case we want x=sqrt(2).
 - As the angle between L1 and L2 goes towards 0, the green lines become more and more aligned with the red lines, so the compensation will tend to infinity in this case. Hence, it makes sense that a division by 0 occurs.

Let's try x = 1 / (dot(L1, L2)*0.5+0.5). If the two vectors are going in the same direction, the result is 1/(1.0*0.5+0.5) = 1.0 as it should. For a 0 angle, the dot product is -1: 1/(-1*0.5+0.5) = 1/0, again as it should. However, for a 90 degree angle, the dot product is zero: 1/(0*0.5+0.5) = 1/0.5 = 2, which is wrong. We need to pass the divider through sqrt(), which results in:


4. Calculate x = 1 / sqrt(dot(L1, L2)*0.5+0.5) and y = 1 / sqrt(dot(L2, L3)*0.5+0.5).

5. At this point, we have everything we need to calculate the four blue points using the formulas in 3. These four points are then used to construct two triangles that form a quad.

Myomyomyo.
Offline Optimo

Junior Devvie




I'm gon have to know, how ya garden grow


« Reply #5 - Posted 2016-11-01 07:29:40 »

Damn yo, that is a hella, hella explanation. Thank you! I feel like I understand most of it but not fully.

Should this
L1 = normalize(V2-V1), L2 = normalize(V2-V1), L3 = normalize(V2-V1)
be
L1 = normalize(V2-V1), L2 = normalize(V3-V2), L3 = normalize(V4-V3)
?

These lines
B1 = V2 +- G1*lineWidth/2 * x
and
B2 = V3 +- G2*lineWidth/2 * y
yield 2 vertex points each?

I may be getting confused at points because I was thinking you were trying to simplify the representation of the math, but V1, L1, and G1 all actually represent Vertex2 data objects? B1 and B2 are both data objects that represent a line made up of the 4 vertices for B11 & B12 and B21 & B22?
Offline theagentd
« Reply #6 - Posted 2016-11-01 08:10:24 »

Concerning the L1-L4 lines: Yes, copy paste error. I've edited my original post.

Concerning B1 and B2: No, you construct 4 vertices due to the +- there. One of B1 is V2 - G1*lineWidth/2*x and one is V2 + G1*lineWidth/2*x.

Yes, all values listed except lineWidth, x and y are vectors here.

Myomyomyo.
Offline Optimo

Junior Devvie




I'm gon have to know, how ya garden grow


« Reply #7 - Posted 2016-11-01 08:28:52 »

Concerning B1 and B2: No, you construct 4 vertices due to the +- there. One of B1 is V2 - G1*lineWidth/2*x and ones is V2 + G1*lineWidth/2*x.
To be clear, 4 vertices total from those 2 lines? 2 vertices from each line?

Are B1 and B2 a data type? B1 and B2 have 2 vertices each? Like, those lines wouldn't work as code, or is that syntactically correct?
Offline theagentd
« Reply #8 - Posted 2016-11-01 10:05:53 »

Sorry, was stupid of me to write "B1=" and "B2=". I've modified the original post again.

As you can see on the image, there are 4 points we're interested in. They are located at the intersection points of the red lines, and also intersecting the green lines (G1 and G2). The two points that are on G1 are generated by taking V2 and moving in both directions along G1 a certain distance, which is where the +- comes from.

Sorry about that; I hope this clarifies it.

Myomyomyo.
Offline Optimo

Junior Devvie




I'm gon have to know, how ya garden grow


« Reply #9 - Posted 2016-11-01 13:20:02 »

Ah, thank you so much! You have been most helpful. I think I do now understand what I need to do for this. I'll report back how I do.  Grin
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline theagentd
« Reply #10 - Posted 2016-11-01 15:02:18 »

Good luck!

Myomyomyo.
Offline JoeGameSaga

Junior Newbie


Exp: 10 years



« Reply #11 - Posted 2016-11-01 15:09:12 »

1. Calculate the normalized vectors of each line: L1 = normalize(V2-V1), L2 = normalize(V3-V2), L3 = normalize(V4-V3).

Thanks for your detailed explanation to Optimo AgentD! Enjoyed reading this thread on my lunch break. Its been awhile since I worked with OGL can you remind me why it is important to first normalize the vectors in step 1? This is probably a stupid question from someone who spent the last month looking at cosine angles lol

Pixel Artist, Indie Game Developer, Father of two. Call me Joe Smiley
Offline theagentd
« Reply #12 - Posted 2016-11-01 15:32:49 »

Two reasons:

1. You probably already know this, but dot(A, B) = |A|*|B|*cos(angle between A and B). If we normalize A and B, |A| and |B| will both become 1.0, so we end up with just cos(angle), which is what we need in point 4.

2. When calculating the direction of G1 and G2, we essentially add two line directions together and normalize the result to get the "average" direction. If the two vectors aren't normalized, the result will be skewed by the length of the two lines. If we have that L1 = (1 000 000, 0) and L2 = (0, 1), we want the result to still be exactly inbetween the two lines (0.707, 0.707). However, normalizing (1 000 000 + 0, 0 + 1) without normalizing the inputs first will massively skew the results as L1 is so much longer, so the result is something like (0.9999..., 0.0000...). This would in turn screw up the calculation for x and y because of the assumptions there.

Myomyomyo.
Offline JoeGameSaga

Junior Newbie


Exp: 10 years



« Reply #13 - Posted 2016-11-01 15:57:34 »

ahh I see your answer makes perfect sense. I was thinking along the lines that the actual length of a vector was important to create the sharper edges in your example.


I think I see what is causing the confusion for me now. I have been reading a lot of math notation, rather than coding, recently, so the following line of code is ambiguous for me to understand what you are doing.


B1 and B2 = V2 +- G1*lineWidth/2 * x
and
B3 and B4 = V3 +- G2*lineWidth/2 * y
.


B1 and B2 <--- is this a logical "and"? or do you mean B1 = (V2 +- G1*lineWidth/2 * x) and B1 = B2 ?

The properies of B1 and B3 appear to be undefined. Just very unclear here what you are trying to express, sorry.

also what is "+-", in my mind it looks like a numerator of some kind, maybe a function?

Pixel Artist, Indie Game Developer, Father of two. Call me Joe Smiley
Offline Optimo

Junior Devvie




I'm gon have to know, how ya garden grow


« Reply #14 - Posted 2016-11-01 16:59:11 »

Well sir, I got something, but it ain't right. Perhaps you can find my mistake? I'm stumped atm.

I'm using this for a dragged selection box. Mouse coordinates (@click and present) are input. It appears to have some of the correct points, but part of it draws off to the origin. I was going to use GL_TRIANGLE_STRIP, but this seemed just as good for testing for now. I could be wrong.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
   public void drawDragBox(double mX, double mY, double mX2, double mY2)
   {
       float lineWidth = 4.6f;
       
       Vector2f V1 = new Vector2f((float)mX, (float)mY);
       Vector2f V2 = new Vector2f((float)mX, (float)mY2);
       Vector2f V3 = new Vector2f((float)mX2, (float)mY2);
       Vector2f V4 = new Vector2f((float)mX2, (float)mY);    
       
       Vector2f L1 = (V1.subtract(V2)).normalize(); //subtract V1 [b]FROM[/b] V2 and then normalize
       Vector2f L2 = (V2.subtract(V3)).normalize();
       Vector2f L3 = (V3.subtract(V4)).normalize();
       Vector2f L4 = (V4.subtract(V1)).normalize();
       
       Vector2f G1 = rotate90Degrees(L1.add(L2).normalize());
       Vector2f G2 = rotate90Degrees(L2.add(L3).normalize());
       Vector2f G3 = rotate90Degrees(L3.add(L4).normalize());
       Vector2f G4 = rotate90Degrees(L4.add(L1).normalize());
       
       double x1 = 1 / Math.sqrt(L4.dot(L1)*0.5+0.5);
       double y1 = 1 / Math.sqrt(L1.dot(L2)*0.5+0.5);
       
       double x2 = 1 / Math.sqrt(L1.dot(L2)*0.5+0.5); //the line theagentd's example was built for
       double y2 = 1 / Math.sqrt(L2.dot(L3)*0.5+0.5);
       
       double x3 = 1 / Math.sqrt(L2.dot(L3)*0.5+0.5);
       double y3 = 1 / Math.sqrt(L3.dot(L4)*0.5+0.5);
       
       double x4 = 1 / Math.sqrt(L3.dot(L4)*0.5+0.5);
       double y4 = 1 / Math.sqrt(L4.dot(L1)*0.5+0.5);  

       
       //B1 = V2 + G1*lineWidth/2 * x  >> V2.add(G1.scale(lineWidth/2 * x)
       //B2 = V2 - G1*lineWidth/2 * x
       //and
       //B3 = V3 + G2*lineWidth/2 * y
       //B4 = V3 - G2*lineWidth/2 * y

       //assemble vertices for drawing triangles
       Vector2f A1 = V1.add(G4.scale((float)(lineWidth/2 * x1)));
       Vector2f A2 = (G4.scale((float)(lineWidth/2 * x1))).subtract(V1); //subtract FROM V1
       
       Vector2f A3 = V2.add(G1.scale((float)(lineWidth/2 * y1)));
       Vector2f A4 = (G1.scale((float)(lineWidth/2 * y1))).subtract(V2);
       
       Vector2f B1 = V2.add(G1.scale((float)(lineWidth/2 * x2)));
       Vector2f B2 = (G1.scale((float)(lineWidth/2 * x2))).subtract(V2);
       
       Vector2f B3 = V3.add(G2.scale((float)(lineWidth/2 * y2)));
       Vector2f B4 = (G2.scale((float)(lineWidth/2 * y2))).subtract(V3);
       
       Vector2f C1 = V3.add(G2.scale((float)(lineWidth/2 * x3)));
       Vector2f C2 = (G2.scale((float)(lineWidth/2 * x3))).subtract(V3);
       
       Vector2f C3 = V4.add(G3.scale((float)(lineWidth/2 * y3)));
       Vector2f C4 = (G3.scale((float)(lineWidth/2 * y3))).subtract(V4);
       
       Vector2f D1 = V4.add(G3.scale((float)(lineWidth/2 * x4)));
       Vector2f D2 = (G3.scale((float)(lineWidth/2 * x4))).subtract(V4);
       
       Vector2f D3 = V1.add(G4.scale((float)(lineWidth/2 * y4)));
       Vector2f D4 = (G4.scale((float)(lineWidth/2 * y4))).subtract(V1);
     
       glColor3f(1, 0, 0);
        GL11.glLineWidth(lineWidth);
        GL11.glBegin(GL_TRIANGLES);

        glVertex2f(A1.x, A1.y);
        glVertex2f(A2.x, A2.y);
        glVertex2f(A3.x, A3.y);
       
        glVertex2f(A3.x, A3.y);
        glVertex2f(A4.x, A4.y);
        glVertex2f(A2.x, A2.y);
       
        glVertex2f(B1.x, B1.y);
        glVertex2f(B2.x, B2.y);
        glVertex2f(B3.x, B3.y);
       
        glVertex2f(B3.x, B3.y);
        glVertex2f(B4.x, B4.y);
        glVertex2f(B2.x, B2.y);        
 
        glVertex2f(C1.x, C1.y);
        glVertex2f(C2.x, C2.y);
        glVertex2f(C3.x, C3.y);
       
        glVertex2f(C3.x, C3.y);
        glVertex2f(C4.x, C4.y);
        glVertex2f(C2.x, C2.y);
       
        glVertex2f(D1.x, D1.y);
        glVertex2f(D2.x, D2.y);
        glVertex2f(D3.x, D3.y);
       
        glVertex2f(D3.x, D3.y);
        glVertex2f(D4.x, D4.y);
        glVertex2f(D2.x, D2.y);

        glEnd();
   }
   
   //rotates a vector 90 degrees
   public Vector2f rotate90Degrees(Vector2f vec)
   {
      Vector2f rotVec = new Vector2f(-vec.y, vec.x);
     
      return rotVec;
   }
Offline Riven
Administrator

« JGO Overlord »


Medals: 1371
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #15 - Posted 2016-11-01 17:56:54 »

where is glEnd() ?

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Offline Optimo

Junior Devvie




I'm gon have to know, how ya garden grow


« Reply #16 - Posted 2016-11-01 18:04:28 »

where is glEnd() ?
Edited my post. I had deleted some irrelevant things from my code for the post and glEnd() got caught in it.
Offline theagentd
« Reply #17 - Posted 2016-11-02 07:14:17 »

At least show a screenshot so we can see what happens.

Myomyomyo.
Offline Optimo

Junior Devvie




I'm gon have to know, how ya garden grow


« Reply #18 - Posted 2016-11-02 07:31:33 »

Quote
At least show a screenshot so we can see what happens.
I'd love to  Grin . Maybe you can help me with this one too? I'm quite new still.

PrintScreen doesn't work. I looked for a bit but found no ready-to-go screenshot code for LWJGL3 or OpenGL. Any recommendations are welcome. Otherwise, my next goal will be to find and implement screenshot code in my project. Will have a screenshot for you fine folks then. Smiley
Offline theagentd
« Reply #19 - Posted 2016-11-02 09:44:41 »

I use Fraps personally. You can also easily implement this in code using glReadPixels(). glReadPixels() reads pixels from the currently bound framebuffer (or the window's backbuffer if you have no FBO bound). Just read pixels back to a ByteBuffer, copy the result to a BufferedImage, write it out using ImageIO.

Myomyomyo.
Offline Optimo

Junior Devvie




I'm gon have to know, how ya garden grow


« Reply #20 - Posted 2016-11-02 09:50:52 »

I was going to mention in my later response, this person's answer has worked for me. I'm currently hooking that in, then will get some screenshots up.

Edit: Now that I put this to use, it freezes the screen a bit. I wonder what kind of performance/functional drawbacks that presents? Seems like most games I've played don't do that but you can tell it's doing something sometimes. Perhaps this should go on another thread?
Offline Optimo

Junior Devvie




I'm gon have to know, how ya garden grow


« Reply #21 - Posted 2016-11-02 11:14:27 »

Hopefully this album will cover it. Not sure if it would be preferred to have set this up here. Can do tho if so. But yea, the comments on those images matter. Let me know if you need any other info. Thanks!
Offline theagentd
« Reply #22 - Posted 2016-11-02 14:31:14 »

Assuming you're using JOML, your vector math code is completely broken. add(), scale(), normalize(), subtract(), etc all modify the current object; they don't return a new object.

Here are a few of the problems your code has:
 - On line 10, you take V1, subtract V2 from it, then normalize it. In other words, L1 and V1 are the same objects, and you've permanently modified V1 so that the computation on line 8 will be wrong.
- On line 15, G1 is ALSO the same object as V1. rotate90Degrees() actually does return a new vector, but L1 still gets L2 added to it and is normalized permanently.
 - On line 40, you're again modifying V1 like crazy.

Honestly, this kind of math is so simple that it doesn't really warrant using vector classes to accomplish it. I'd recommend you start with something simpler: A function for drawing a single line given four points (V1 to V4). It should only draw a single line between the V2 and V3, but needs V1 and V4 to get the ends of the line right. Using such a function, you can easily draw a box by just calling it 4 times for each side.

Myomyomyo.
Offline Optimo

Junior Devvie




I'm gon have to know, how ya garden grow


« Reply #23 - Posted 2016-11-02 15:10:07 »

It's a different Vector2f class. Not JOML. It does the things you'd think it should do. Line 10 subtracts V1 from V2 and doesn't modify V1 for instance.

Yea, scaled back version is probably the way to go. At least for proof of concept.
Offline Optimo

Junior Devvie




I'm gon have to know, how ya garden grow


« Reply #24 - Posted 2016-11-03 11:46:07 »

Got it working. The Vector2f class I used has its documentation backwards. I specifically looked which way subtract is when I first tried to do this. It is opposite how they say it. Adjusting accordingly fixed it. Do most people just use JOML? I got this class while I was learning. It's from MIT.

I backed up and was going to implement a version that just took 4 coordinates and made 4 new coordinates that were 45degrees inward. This is where I found that the subtract is backwards how they say.

I'm going to include my code and some screenshots in case they can help anyone else. Thanks for the thorough help!  Grin


My parentheses went ham as I was trying to debug. CBA to delete the superfluous ones now.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
   //take in mouse coordinates @click and present and make a box
   public void drawDragBox3(double mX, double mY, double mX2, double mY2)
   {
       float lineWidth = 50f;
       
       Vector2f V1 = new Vector2f((float)mX, (float)mY);
       Vector2f V2 = new Vector2f((float)mX, (float)mY2);
       Vector2f V3 = new Vector2f((float)mX2, (float)mY2);
       Vector2f V4 = new Vector2f((float)mX2, (float)mY);          

       Vector2f L1 = (V2.subtract(V1)).normalize(); //subtract V1 [b]FROM[/b] V2 and then normalize
       Vector2f L2 = (V3.subtract(V2)).normalize();
       Vector2f L3 = (V4.subtract(V3)).normalize();
       Vector2f L4 = (V1.subtract(V4)).normalize();
       
       Vector2f G1 = rotate90Degrees((L1.add(L2)).normalize());
       Vector2f G2 = rotate90Degrees((L2.add(L3)).normalize());
       Vector2f G3 = rotate90Degrees((L3.add(L4)).normalize());
       Vector2f G4 = rotate90Degrees((L4.add(L1)).normalize());
       
       double x1 = 1 / Math.sqrt(((L4.dot(L1))*0.5)+0.5);
       double y1 = 1 / Math.sqrt(((L1.dot(L2))*0.5)+0.5);
       
       double x2 = 1 / Math.sqrt(((L1.dot(L2))*0.5)+0.5); //the line theagentd's example was built for
       double y2 = 1 / Math.sqrt(((L2.dot(L3))*0.5)+0.5);
       
       double x3 = 1 / Math.sqrt(((L2.dot(L3))*0.5)+0.5);
       double y3 = 1 / Math.sqrt(((L3.dot(L4))*0.5)+0.5);
       
       double x4 = 1 / Math.sqrt(((L3.dot(L4))*0.5)+0.5);
       double y4 = 1 / Math.sqrt(((L4.dot(L1))*0.5)+0.5);      

       Vector2f A1 = V1.add(G4.scale((float)(lineWidth/2 * x1)));
       Vector2f A2 = V1.subtract((G4.scale((float)(lineWidth/2 * x1)))); //subtract FROM V1
       
       Vector2f A3 = V2.add(G1.scale((float)(lineWidth/2 * y1)));
       Vector2f A4 = V2.subtract((G1.scale((float)(lineWidth/2 * y1))));
       
       Vector2f B1 = V2.add(G1.scale((float)(lineWidth/2 * x2)));
       Vector2f B2 = V2.subtract((G1.scale((float)(lineWidth/2 * x2))));
       
       Vector2f B3 = V3.add(G2.scale((float)(lineWidth/2 * y2)));
       Vector2f B4 = V3.subtract((G2.scale((float)(lineWidth/2 * y2))));
       
       Vector2f C1 = V3.add(G2.scale((float)(lineWidth/2 * x3)));
       Vector2f C2 = V3.subtract((G2.scale((float)(lineWidth/2 * x3))));
       
       Vector2f C3 = V4.add(G3.scale((float)(lineWidth/2 * y3)));
       Vector2f C4 = V4.subtract((G3.scale((float)(lineWidth/2 * y3))));
       
       Vector2f D1 = V4.add(G3.scale((float)(lineWidth/2 * x4)));
       Vector2f D2 = V4.subtract((G3.scale((float)(lineWidth/2 * x4))));
       
       Vector2f D3 = V1.add(G4.scale((float)(lineWidth/2 * y4)));
       Vector2f D4 = V1.subtract((G4.scale((float)(lineWidth/2 * y4))));
     
       glDisable(GL_BLEND);
       glColor3f(1, 0, 0);
        GL11.glLineWidth(lineWidth);
        //glEnable(GL_LINE_SMOOTH);
        glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
        GL11.glBegin(GL_TRIANGLE_STRIP);
       
        glVertex2f(A1.x, A1.y);        
        glVertex2f(A4.x, A4.y);
        glVertex2f(A3.x, A3.y);
       
        glVertex2f(B4.x, B4.y);
        glVertex2f(B3.x, B3.y);
       
        glVertex2f(C4.x, C4.y);
        glVertex2f(C3.x, C3.y);
       
        glVertex2f(D4.x, D4.y);
        glVertex2f(D3.x, D3.y);
        glVertex2f(A4.x, A4.y);

        glEnd();
       
         glColor3f(1, 1, 1);
   }


Working demo:


Running with glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);


An image I made to help me sort this out:
Offline theagentd
« Reply #25 - Posted 2016-11-03 12:11:17 »

That looks 100% correct! Good job! I'm glad you got it working.

Note that there are a couple of special cases you should be aware of.

 - As the angle between L1 and L2 gets smaller, x tends to infinity. This makes sense if you want a pointy end to the line (as is the case for your box rendering), but it may not always give the best result. In essence, it can cause the line to be drawn as much longer than it really is, which could be problematic.
 - Since you need four points in total draw a single line between the middle two points, it can become difficult to draw line strips where the first and last lines are missing one neighbor. In this case, you can either introduce a special case or generate the missing points from the ones you have.

Here is some more information:

 - Since you have 100% control of the vertices, it actually becomes possible to pick a line width per vertex. This allows you to draw continuous lines with varying thickness, which can look really nice.
 - Again, since you're emulating lines with triangles, there are no limit to the line width. Usually it's limited to between 1 and 16 or something like that.
 - This system does not work with line smoothing.
 - You can however use both MSAA and shader-based anti-aliasing to achieve extremely high-quality anti-aliasing.
 - Although the line width can be under 1 pixel, doing so will cause bad aliasing. It's a good idea to clamp the line width to 1 pixel and instead reduce the alpha of thin lines. Example: line width is 0.5 ---> make line width 1.0 and multiply alpha by 0.5.

Myomyomyo.
Offline Optimo

Junior Devvie




I'm gon have to know, how ya garden grow


« Reply #26 - Posted 2016-11-03 12:19:21 »

I know just what you are talking about with the edges going off crazy at sharp angles. I see it a lot in Adobe Illustrator. It looked to me like your example takes this into account? I wasn't sure if you were making small lines there yourself or if it was the answer for that angle problem.

Quote
or generate the missing points from the.
From the what? I reckon the vertex it is equal to.
Offline theagentd
« Reply #27 - Posted 2016-11-03 12:24:44 »

Argh, I suck at this typing thing. xD

If you're missing V1, you can just set L1 to L2 for example.

EDIT: Also, I strongly STRONGLY recommend JOML. JOML is the best thing that has happened to Java game development in a decent time. It's fast, KaiHH that develops it is super responsive and helpful if you're missing some feature, it generates zero garbage when used correctly and has pretty much anything that you could ever ask for. However, in this case you're probably better off just using raw floats as the vectors are kinda unnecessary in this case.

Myomyomyo.
Pages: [1]
  ignore  |  Print  
 
 

 
Riven (583 views)
2019-09-04 15:33:17

hadezbladez (5517 views)
2018-11-16 13:46:03

hadezbladez (2405 views)
2018-11-16 13:41:33

hadezbladez (5779 views)
2018-11-16 13:35:35

hadezbladez (1226 views)
2018-11-16 13:32:03

EgonOlsen (4664 views)
2018-06-10 19:43:48

EgonOlsen (5684 views)
2018-06-10 19:43:44

EgonOlsen (3199 views)
2018-06-10 19:43:20

DesertCoockie (4096 views)
2018-05-13 18:23:11

nelsongames (5116 views)
2018-04-24 18:15:36
A NON-ideal modular configuration for Eclipse with JavaFX
by philfrei
2019-12-19 19:35:12

Java Gaming Resources
by philfrei
2019-05-14 16:15:13

Deployment and Packaging
by philfrei
2019-05-08 15:15:36

Deployment and Packaging
by philfrei
2019-05-08 15:13:34

Deployment and Packaging
by philfrei
2019-02-17 20:25:53

Deployment and Packaging
by mudlee
2018-08-22 18:09:50

Java Gaming Resources
by gouessej
2018-08-22 08:19:41

Deployment and Packaging
by gouessej
2018-08-22 08:04:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!