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.
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
diff --git a/src/render/opengl/SDL_render_gl.c b/src/render/opengl/SDL_render_gl.c
index f749ce3..364f9b3 100644
--- a/src/render/opengl/SDL_render_gl.c
+++ b/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);
}
}
diff --git a/src/render/opengles/SDL_render_gles.c b/src/render/opengles/SDL_render_gles.c
index a6cf22e..8525358 100644
--- a/src/render/opengles/SDL_render_gles.c
+++ b/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);
}
}
diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c
index 7f24726..4f02a68 100644
--- a/src/render/opengles2/SDL_render_gles2.c
+++ b/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);
}
}