From d23d9c88e5166ae62f7592c71d7c6a5115666526 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 7 Jul 2014 23:26:34 -0700 Subject: [PATCH] Fixed bug 2421 - SDL_RenderCopyEx off by one when rotating by 90 and -90 chasesan When using SDL_RenderCopyEx, I get a problem on some platforms where the output is offset by +/-1 on other platforms and not on others. I tried it with a center of both 0,0 (and offsetting by width/height) and NULL (for centered). The rotation involved is 90, and/or -90 rotation. The rotation was a constant, no arithmetic was involved when inputting it into SDL_RenderCopyEx. This occurred with 32x32, 24x24, and 16x16 texture sizes. I apologize that I don't have more precise information, as I received the information as a bug report myself. But I have tracked the problem down to here. My program requires pixel perfect alignment on several different platforms, so this is something of a showstopper for me. -- Sylvain It appears the RenderCopyEx is done as expected, this is the red rectangle which is not correctly positionned ! So, here's patch with a 0.5 float increment, like for opengles2, for DrawLines, and also Draw Points. --- src/render/opengles/SDL_render_gles.c | 31 ++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/render/opengles/SDL_render_gles.c b/src/render/opengles/SDL_render_gles.c index 90a485bb3..72cce305a 100644 --- a/src/render/opengles/SDL_render_gles.c +++ b/src/render/opengles/SDL_render_gles.c @@ -814,12 +814,24 @@ GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points, int count) { GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; + GLfloat *vertices; + int idx; GLES_SetDrawingState(renderer); - data->glVertexPointer(2, GL_FLOAT, 0, points); - data->glDrawArrays(GL_POINTS, 0, count); + /* Emit the specified vertices as points */ + vertices = SDL_stack_alloc(GLfloat, count * 2); + for (idx = 0; idx < count; ++idx) { + GLfloat x = points[idx].x + 0.5f; + GLfloat y = points[idx].y + 0.5f; + vertices[idx * 2] = x; + vertices[(idx * 2) + 1] = y; + } + + data->glVertexPointer(2, GL_FLOAT, 0, vertices); + data->glDrawArrays(GL_POINTS, 0, count); + SDL_stack_free(vertices); return 0; } @@ -828,10 +840,22 @@ GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, int count) { GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; + GLfloat *vertices; + int idx; GLES_SetDrawingState(renderer); - data->glVertexPointer(2, GL_FLOAT, 0, points); + /* Emit a line strip including the specified vertices */ + vertices = SDL_stack_alloc(GLfloat, count * 2); + for (idx = 0; idx < count; ++idx) { + GLfloat x = points[idx].x + 0.5f; + GLfloat y = points[idx].y + 0.5f; + + vertices[idx * 2] = x; + vertices[(idx * 2) + 1] = y; + } + + data->glVertexPointer(2, GL_FLOAT, 0, vertices); if (count > 2 && points[0].x == points[count-1].x && points[0].y == points[count-1].y) { /* GL_LINE_LOOP takes care of the final segment */ @@ -842,6 +866,7 @@ GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, /* We need to close the endpoint of the line */ data->glDrawArrays(GL_POINTS, count-1, 1); } + SDL_stack_free(vertices); return 0; }