Skip to content

Commit

Permalink
opengl: Make diagonal lines match the software renderer.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
icculus committed Nov 9, 2020
1 parent da49f79 commit 0e4ce84
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 27 deletions.
17 changes: 8 additions & 9 deletions src/render/opengl/SDL_render_gl.c
Expand Up @@ -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];
Expand All @@ -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);
}
}

Expand Down
17 changes: 8 additions & 9 deletions src/render/opengles/SDL_render_gles.c
Expand Up @@ -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];
Expand All @@ -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);
}
}

Expand Down
17 changes: 8 additions & 9 deletions src/render/opengles2/SDL_render_gles2.c
Expand Up @@ -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];
Expand All @@ -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);
}
}

Expand Down

0 comments on commit 0e4ce84

Please sign in to comment.