Browse Source

opengl: Make diagonal lines match the software renderer.

OpenGL leaves the final line segment open, SDL's software renderer does not,
so we need a tiny bit of trigonometry here to move one more pixel in the right
direction.
Ryan C. Gordon 4 years ago
parent
commit
0e4ce84801

+ 8 - 9
src/render/opengl/SDL_render_gl.c

@@ -865,15 +865,8 @@ GL_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPo
         *(verts++) = 0.5f + points[i].y;
     }
 
-    /* If the line segment is completely horizontal or vertical,
-       make it one pixel longer, to satisfy the diamond-exit rule.
-       We should probably do this for diagonal lines too, but we'd have to
-       do some trigonometry to figure out the correct pixel and generally
-       when we have problems with pixel perfection, it's for straight lines
-       that are missing a pixel that frames something and not arbitrary
-       angles. Maybe !!! FIXME for later, though. */
-
-    /* update the last line. */
+    /* Make the last line segment one pixel longer, to satisfy the
+       diamond-exit rule. */
     verts -= 4;
     {
         const GLfloat xstart = verts[0];
@@ -885,6 +878,12 @@ GL_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPo
             verts[2] += (xend > xstart) ? 1.0f : -1.0f;
         } else if (xstart == xend) {  /* vertical line */
             verts[3] += (yend > ystart) ? 1.0f : -1.0f;
+        } else {  /* bump a pixel in the direction we are moving in. */
+            const GLfloat deltax = xend - xstart;
+            const GLfloat deltay = yend - ystart;
+            const GLfloat angle = SDL_atan2f(deltay, deltax);
+            verts[2] += SDL_cosf(angle);
+            verts[3] += SDL_sinf(angle);
         }
     }
 

+ 8 - 9
src/render/opengles/SDL_render_gles.c

@@ -578,15 +578,8 @@ GLES_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_F
         *(verts++) = 0.5f + points[i].y;
     }
 
-    /* If the line segment is completely horizontal or vertical,
-       make it one pixel longer, to satisfy the diamond-exit rule.
-       We should probably do this for diagonal lines too, but we'd have to
-       do some trigonometry to figure out the correct pixel and generally
-       when we have problems with pixel perfection, it's for straight lines
-       that are missing a pixel that frames something and not arbitrary
-       angles. Maybe !!! FIXME for later, though. */
-
-    /* update the last line. */
+    /* Make the last line segment one pixel longer, to satisfy the
+       diamond-exit rule. */
     verts -= 4;
     {
         const GLfloat xstart = verts[0];
@@ -598,6 +591,12 @@ GLES_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_F
             verts[2] += (xend > xstart) ? 1.0f : -1.0f;
         } else if (xstart == xend) {  /* vertical line */
             verts[3] += (yend > ystart) ? 1.0f : -1.0f;
+        } else {  /* bump a pixel in the direction we are moving in. */
+            const GLfloat deltax = xend - xstart;
+            const GLfloat deltay = yend - ystart;
+            const GLfloat angle = SDL_atan2f(deltay, deltax);
+            verts[2] += SDL_cosf(angle);
+            verts[3] += SDL_sinf(angle);
         }
     }
 

+ 8 - 9
src/render/opengles2/SDL_render_gles2.c

@@ -800,15 +800,8 @@ GLES2_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_
         *(verts++) = 0.5f + points[i].y;
     }
 
-    /* If the line segment is completely horizontal or vertical,
-       make it one pixel longer, to satisfy the diamond-exit rule.
-       We should probably do this for diagonal lines too, but we'd have to
-       do some trigonometry to figure out the correct pixel and generally
-       when we have problems with pixel perfection, it's for straight lines
-       that are missing a pixel that frames something and not arbitrary
-       angles. Maybe !!! FIXME for later, though. */
-
-    /* update the last line. */
+    /* Make the last line segment one pixel longer, to satisfy the
+       diamond-exit rule. */
     verts -= 4;
     {
         const GLfloat xstart = verts[0];
@@ -820,6 +813,12 @@ GLES2_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_
             verts[2] += (xend > xstart) ? 1.0f : -1.0f;
         } else if (xstart == xend) {  /* vertical line */
             verts[3] += (yend > ystart) ? 1.0f : -1.0f;
+        } else {  /* bump a pixel in the direction we are moving in. */
+            const GLfloat deltax = xend - xstart;
+            const GLfloat deltay = yend - ystart;
+            const GLfloat angle = SDL_atan2f(deltay, deltax);
+            verts[2] += SDL_cosf(angle);
+            verts[3] += SDL_sinf(angle);
         }
     }