Skip to content

Commit

Permalink
opengl: Use GL_LINE_STRIP instead of breaking down into seperate GL_L…
Browse files Browse the repository at this point in the history
…INES.

Surely GL drivers have improved in the last seven years. I hope...?
  • Loading branch information
icculus committed Nov 8, 2020
1 parent b198feb commit 93a2c58
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 101 deletions.
58 changes: 23 additions & 35 deletions src/render/opengl/SDL_render_gl.c
Expand Up @@ -851,52 +851,41 @@ GL_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FP
static int
GL_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
{
GLfloat *verts;
int i;

SDL_assert(count >= 2); /* should have been checked at the higher level. */

verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, (count-1) * 4 * sizeof (GLfloat), 0, &cmd->data.draw.first);
const size_t vertlen = (sizeof (GLfloat) * 2) * count;
GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, vertlen, 0, &cmd->data.draw.first);
if (!verts) {
return -1;
}

cmd->data.draw.count = count;

/* GL_LINE_STRIP seems to be unreliable on various drivers, so try
to build out our own GL_LINES. :(
If the line segment is completely horizontal or vertical,
/* Offset to hit the center of the pixel. */
for (i = 0; i < count; i++) {
*(verts++) = 0.5f + points[i].x;
*(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. */

for (i = 0; i < count-1; i++, points++) {
GLfloat xstart = 0.5f + points[0].x; /* 0.5f to get to the center of the pixel. */
GLfloat ystart = 0.5f + points[0].y;
GLfloat xend = 0.5f + points[1].x;
GLfloat yend = 0.5f + points[1].y;

if (xstart == xend) { /* vertical line */
if (yend > ystart) {
yend += 1.0f;
} else {
ystart += 1.0f;
}
} else if (ystart == yend) { /* horizontal line */
if (xend > xstart) {
xend += 1.0f;
} else {
xstart += 1.0f;
}
/* update the last line. */
verts -= 4;
{
const GLfloat xstart = verts[0];
const GLfloat ystart = verts[1];
const GLfloat xend = verts[2];
const GLfloat yend = verts[3];

if (ystart == yend) { /* horizontal line */
verts[2] += (xend > xstart) ? 1.0f : -1.0f;
} else if (xstart == xend) { /* vertical line */
verts[3] += (yend > ystart) ? 1.0f : -1.0f;
}

*(verts++) = xstart;
*(verts++) = ystart;
*(verts++) = xend;
*(verts++) = yend;
}

return 0;
Expand Down Expand Up @@ -1267,10 +1256,9 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
const size_t count = cmd->data.draw.count;
SDL_assert(count >= 2);
SetDrawState(data, cmd, SHADER_SOLID);
data->glBegin(GL_LINES);
for (i = 0; i < count-1; ++i, verts += 4) {
data->glBegin(GL_LINE_STRIP);
for (i = 0; i < count; ++i, verts += 2) {
data->glVertex2f(verts[0], verts[1]);
data->glVertex2f(verts[2], verts[3]);
}
data->glEnd();
break;
Expand Down
55 changes: 22 additions & 33 deletions src/render/opengles/SDL_render_gles.c
Expand Up @@ -564,52 +564,41 @@ GLES_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_
static int
GLES_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
{
GLfloat *verts;
int i;

SDL_assert(count >= 2); /* should have been checked at the higher level. */

verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, (count-1) * 4 * sizeof (GLfloat), 0, &cmd->data.draw.first);
const size_t vertlen = (sizeof (GLfloat) * 2) * count;
GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, vertlen, 0, &cmd->data.draw.first);
if (!verts) {
return -1;
}

cmd->data.draw.count = count;

/* GL_LINE_STRIP seems to be unreliable on various drivers, so try
to build out our own GL_LINES. :(
If the line segment is completely horizontal or vertical,
/* Offset to hit the center of the pixel. */
for (i = 0; i < count; i++) {
*(verts++) = 0.5f + points[i].x;
*(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. */

for (i = 0; i < count-1; i++, points++) {
GLfloat xstart = 0.5f + points[0].x; /* 0.5f to get to the center of the pixel. */
GLfloat ystart = 0.5f + points[0].y;
GLfloat xend = 0.5f + points[1].x;
GLfloat yend = 0.5f + points[1].y;

if (xstart == xend) { /* vertical line */
if (yend > ystart) {
yend += 1.0f;
} else {
ystart += 1.0f;
}
} else if (ystart == yend) { /* horizontal line */
if (xend > xstart) {
xend += 1.0f;
} else {
xstart += 1.0f;
}
/* update the last line. */
verts -= 4;
{
const GLfloat xstart = verts[0];
const GLfloat ystart = verts[1];
const GLfloat xend = verts[2];
const GLfloat yend = verts[3];

if (ystart == yend) { /* horizontal line */
verts[2] += (xend > xstart) ? 1.0f : -1.0f;
} else if (xstart == xend) { /* vertical line */
verts[3] += (yend > ystart) ? 1.0f : -1.0f;
}

*(verts++) = xstart;
*(verts++) = ystart;
*(verts++) = xend;
*(verts++) = yend;
}

return 0;
Expand Down Expand Up @@ -958,7 +947,7 @@ GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vert
SDL_assert(count >= 2);
SetDrawState(data, cmd);
data->glVertexPointer(2, GL_FLOAT, 0, verts);
data->glDrawArrays(GL_LINES, 0, (GLsizei) ((count-1) * 2));
data->glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) ((count-1) * 2));
break;
}

Expand Down
55 changes: 22 additions & 33 deletions src/render/opengles2/SDL_render_gles2.c
Expand Up @@ -786,52 +786,41 @@ GLES2_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL
static int
GLES2_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
{
GLfloat *verts;
int i;

SDL_assert(count >= 2); /* should have been checked at the higher level. */

verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, (count-1) * 4 * sizeof (GLfloat), 0, &cmd->data.draw.first);
const size_t vertlen = (sizeof (GLfloat) * 2) * count;
GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, vertlen, 0, &cmd->data.draw.first);
if (!verts) {
return -1;
}

cmd->data.draw.count = count;

/* GL_LINE_STRIP seems to be unreliable on various drivers, so try
to build out our own GL_LINES. :(
If the line segment is completely horizontal or vertical,
/* Offset to hit the center of the pixel. */
for (i = 0; i < count; i++) {
*(verts++) = 0.5f + points[i].x;
*(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. */

for (i = 0; i < count-1; i++, points++) {
GLfloat xstart = 0.5f + points[0].x; /* 0.5f to get to the center of the pixel. */
GLfloat ystart = 0.5f + points[0].y;
GLfloat xend = 0.5f + points[1].x;
GLfloat yend = 0.5f + points[1].y;

if (xstart == xend) { /* vertical line */
if (yend > ystart) {
yend += 1.0f;
} else {
ystart += 1.0f;
}
} else if (ystart == yend) { /* horizontal line */
if (xend > xstart) {
xend += 1.0f;
} else {
xstart += 1.0f;
}
/* update the last line. */
verts -= 4;
{
const GLfloat xstart = verts[0];
const GLfloat ystart = verts[1];
const GLfloat xend = verts[2];
const GLfloat yend = verts[3];

if (ystart == yend) { /* horizontal line */
verts[2] += (xend > xstart) ? 1.0f : -1.0f;
} else if (xstart == xend) { /* vertical line */
verts[3] += (yend > ystart) ? 1.0f : -1.0f;
}

*(verts++) = xstart;
*(verts++) = ystart;
*(verts++) = xend;
*(verts++) = yend;
}

return 0;
Expand Down Expand Up @@ -1351,7 +1340,7 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
const size_t count = cmd->data.draw.count;
SDL_assert(count >= 2);
if (SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID) == 0) {
data->glDrawArrays(GL_LINES, 0, (GLsizei) ((count-1) * 2));
data->glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) ((count-1) * 2));
}
break;
}
Expand Down

0 comments on commit 93a2c58

Please sign in to comment.