opengl: Use GL_LINE_STRIP instead of breaking down into seperate GL_LINES.

Surely GL drivers have improved in the last seven years. I hope...?
This commit is contained in:
Ryan C. Gordon 2020-11-08 12:37:09 -05:00
parent b198febb62
commit 93a2c58c7e
3 changed files with 64 additions and 98 deletions

View File

@ -851,21 +851,21 @@ GL_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FP
static int static int
GL_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count) GL_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
{ {
GLfloat *verts;
int i; int i;
const size_t vertlen = (sizeof (GLfloat) * 2) * count;
SDL_assert(count >= 2); /* should have been checked at the higher level. */ GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, vertlen, 0, &cmd->data.draw.first);
verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, (count-1) * 4 * sizeof (GLfloat), 0, &cmd->data.draw.first);
if (!verts) { if (!verts) {
return -1; return -1;
} }
cmd->data.draw.count = count; cmd->data.draw.count = count;
/* GL_LINE_STRIP seems to be unreliable on various drivers, so try /* Offset to hit the center of the pixel. */
to build out our own GL_LINES. :( for (i = 0; i < count; i++) {
If the line segment is completely horizontal or vertical, *(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. 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 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 do some trigonometry to figure out the correct pixel and generally
@ -873,30 +873,19 @@ GL_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPo
that are missing a pixel that frames something and not arbitrary that are missing a pixel that frames something and not arbitrary
angles. Maybe !!! FIXME for later, though. */ angles. Maybe !!! FIXME for later, though. */
for (i = 0; i < count-1; i++, points++) { /* update the last line. */
GLfloat xstart = 0.5f + points[0].x; /* 0.5f to get to the center of the pixel. */ verts -= 4;
GLfloat ystart = 0.5f + points[0].y; {
GLfloat xend = 0.5f + points[1].x; const GLfloat xstart = verts[0];
GLfloat yend = 0.5f + points[1].y; const GLfloat ystart = verts[1];
const GLfloat xend = verts[2];
const GLfloat yend = verts[3];
if (xstart == xend) { /* vertical line */ if (ystart == yend) { /* horizontal line */
if (yend > ystart) { verts[2] += (xend > xstart) ? 1.0f : -1.0f;
yend += 1.0f; } else if (xstart == xend) { /* vertical line */
} else { verts[3] += (yend > ystart) ? 1.0f : -1.0f;
ystart += 1.0f;
}
} else if (ystart == yend) { /* horizontal line */
if (xend > xstart) {
xend += 1.0f;
} else {
xstart += 1.0f;
}
} }
*(verts++) = xstart;
*(verts++) = ystart;
*(verts++) = xend;
*(verts++) = yend;
} }
return 0; return 0;
@ -1267,10 +1256,9 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
const size_t count = cmd->data.draw.count; const size_t count = cmd->data.draw.count;
SDL_assert(count >= 2); SDL_assert(count >= 2);
SetDrawState(data, cmd, SHADER_SOLID); SetDrawState(data, cmd, SHADER_SOLID);
data->glBegin(GL_LINES); data->glBegin(GL_LINE_STRIP);
for (i = 0; i < count-1; ++i, verts += 4) { for (i = 0; i < count; ++i, verts += 2) {
data->glVertex2f(verts[0], verts[1]); data->glVertex2f(verts[0], verts[1]);
data->glVertex2f(verts[2], verts[3]);
} }
data->glEnd(); data->glEnd();
break; break;

View File

@ -564,21 +564,21 @@ GLES_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_
static int static int
GLES_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count) GLES_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
{ {
GLfloat *verts;
int i; int i;
const size_t vertlen = (sizeof (GLfloat) * 2) * count;
SDL_assert(count >= 2); /* should have been checked at the higher level. */ GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, vertlen, 0, &cmd->data.draw.first);
verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, (count-1) * 4 * sizeof (GLfloat), 0, &cmd->data.draw.first);
if (!verts) { if (!verts) {
return -1; return -1;
} }
cmd->data.draw.count = count; cmd->data.draw.count = count;
/* GL_LINE_STRIP seems to be unreliable on various drivers, so try /* Offset to hit the center of the pixel. */
to build out our own GL_LINES. :( for (i = 0; i < count; i++) {
If the line segment is completely horizontal or vertical, *(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. 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 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 do some trigonometry to figure out the correct pixel and generally
@ -586,30 +586,19 @@ GLES_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_F
that are missing a pixel that frames something and not arbitrary that are missing a pixel that frames something and not arbitrary
angles. Maybe !!! FIXME for later, though. */ angles. Maybe !!! FIXME for later, though. */
for (i = 0; i < count-1; i++, points++) { /* update the last line. */
GLfloat xstart = 0.5f + points[0].x; /* 0.5f to get to the center of the pixel. */ verts -= 4;
GLfloat ystart = 0.5f + points[0].y; {
GLfloat xend = 0.5f + points[1].x; const GLfloat xstart = verts[0];
GLfloat yend = 0.5f + points[1].y; const GLfloat ystart = verts[1];
const GLfloat xend = verts[2];
const GLfloat yend = verts[3];
if (xstart == xend) { /* vertical line */ if (ystart == yend) { /* horizontal line */
if (yend > ystart) { verts[2] += (xend > xstart) ? 1.0f : -1.0f;
yend += 1.0f; } else if (xstart == xend) { /* vertical line */
} else { verts[3] += (yend > ystart) ? 1.0f : -1.0f;
ystart += 1.0f;
}
} else if (ystart == yend) { /* horizontal line */
if (xend > xstart) {
xend += 1.0f;
} else {
xstart += 1.0f;
}
} }
*(verts++) = xstart;
*(verts++) = ystart;
*(verts++) = xend;
*(verts++) = yend;
} }
return 0; return 0;
@ -958,7 +947,7 @@ GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vert
SDL_assert(count >= 2); SDL_assert(count >= 2);
SetDrawState(data, cmd); SetDrawState(data, cmd);
data->glVertexPointer(2, GL_FLOAT, 0, verts); 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; break;
} }

View File

@ -786,21 +786,21 @@ GLES2_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL
static int static int
GLES2_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count) GLES2_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
{ {
GLfloat *verts;
int i; int i;
const size_t vertlen = (sizeof (GLfloat) * 2) * count;
SDL_assert(count >= 2); /* should have been checked at the higher level. */ GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, vertlen, 0, &cmd->data.draw.first);
verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, (count-1) * 4 * sizeof (GLfloat), 0, &cmd->data.draw.first);
if (!verts) { if (!verts) {
return -1; return -1;
} }
cmd->data.draw.count = count; cmd->data.draw.count = count;
/* GL_LINE_STRIP seems to be unreliable on various drivers, so try /* Offset to hit the center of the pixel. */
to build out our own GL_LINES. :( for (i = 0; i < count; i++) {
If the line segment is completely horizontal or vertical, *(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. 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 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 do some trigonometry to figure out the correct pixel and generally
@ -808,30 +808,19 @@ GLES2_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_
that are missing a pixel that frames something and not arbitrary that are missing a pixel that frames something and not arbitrary
angles. Maybe !!! FIXME for later, though. */ angles. Maybe !!! FIXME for later, though. */
for (i = 0; i < count-1; i++, points++) { /* update the last line. */
GLfloat xstart = 0.5f + points[0].x; /* 0.5f to get to the center of the pixel. */ verts -= 4;
GLfloat ystart = 0.5f + points[0].y; {
GLfloat xend = 0.5f + points[1].x; const GLfloat xstart = verts[0];
GLfloat yend = 0.5f + points[1].y; const GLfloat ystart = verts[1];
const GLfloat xend = verts[2];
const GLfloat yend = verts[3];
if (xstart == xend) { /* vertical line */ if (ystart == yend) { /* horizontal line */
if (yend > ystart) { verts[2] += (xend > xstart) ? 1.0f : -1.0f;
yend += 1.0f; } else if (xstart == xend) { /* vertical line */
} else { verts[3] += (yend > ystart) ? 1.0f : -1.0f;
ystart += 1.0f;
}
} else if (ystart == yend) { /* horizontal line */
if (xend > xstart) {
xend += 1.0f;
} else {
xstart += 1.0f;
}
} }
*(verts++) = xstart;
*(verts++) = ystart;
*(verts++) = xend;
*(verts++) = yend;
} }
return 0; return 0;
@ -1351,7 +1340,7 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
const size_t count = cmd->data.draw.count; const size_t count = cmd->data.draw.count;
SDL_assert(count >= 2); SDL_assert(count >= 2);
if (SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID) == 0) { 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; break;
} }