From aadbfbcb8cb28d6f336d3bf01466590b12425562 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 1 Oct 2012 20:59:33 -0700 Subject: [PATCH] Added SDL_RenderSetScale() and SDL_RenderGetScale() --- include/SDL_render.h | 26 +++ src/render/SDL_render.c | 277 ++++++++++++++++++++---- src/render/SDL_sysrender.h | 30 ++- src/render/direct3d/SDL_render_d3d.c | 74 +++---- src/render/opengl/SDL_glfuncs.h | 4 +- src/render/opengl/SDL_render_gl.c | 50 ++--- src/render/opengles/SDL_glesfuncs.h | 2 +- src/render/opengles/SDL_render_gles.c | 198 ++++++++--------- src/render/opengles2/SDL_render_gles2.c | 76 +++---- src/render/software/SDL_render_sw.c | 167 ++++++++------ 10 files changed, 577 insertions(+), 327 deletions(-) diff --git a/include/SDL_render.h b/include/SDL_render.h index cac1f22c6..7ec45010d 100644 --- a/include/SDL_render.h +++ b/include/SDL_render.h @@ -436,6 +436,32 @@ extern DECLSPEC int SDLCALL SDL_RenderSetViewport(SDL_Renderer * renderer, extern DECLSPEC void SDLCALL SDL_RenderGetViewport(SDL_Renderer * renderer, SDL_Rect * rect); +/** + * \brief Set the drawing scale for rendering on the current target. + * + * \param scaleX The horizontal scaling factor + * \param scaleY The vertical scaling factor + * + * The drawing coordinates are scaled by the x/y scaling factors + * before they are used by the renderer. This allows resolution + * independent drawing with a single coordinate system. + * + * \note If this results in scaling or subpixel drawing by the + * rendering backend, it will be handled using the appropriate + * quality hints. For best results use integer scaling factors. + */ +extern DECLSPEC int SDLCALL SDL_RenderSetScale(SDL_Renderer * renderer, + float scaleX, float scaleY); + +/** + * \brief Get the drawing scale for the current target. + * + * \param scaleX A pointer filled in with the horizontal scaling factor + * \param scaleY A pointer filled in with the vertical scaling factor + */ +extern DECLSPEC void SDLCALL SDL_RenderGetScale(SDL_Renderer * renderer, + float *scaleX, float *scaleY); + /** * \brief Set the color used for drawing operations (Rect, Line and Clear). * diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index 2c4777b60..1cd270021 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -103,26 +103,22 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event) if (event->window.event == SDL_WINDOWEVENT_RESIZED) { /* Try to keep the previous viewport centered */ int w, h; - SDL_Rect viewport; SDL_GetWindowSize(window, &w, &h); if (renderer->target) { renderer->viewport_backup.x = (w - renderer->viewport_backup.w) / 2; renderer->viewport_backup.y = (h - renderer->viewport_backup.h) / 2; } else { - viewport.x = (w - renderer->viewport.w) / 2; - viewport.y = (h - renderer->viewport.h) / 2; - viewport.w = renderer->viewport.w; - viewport.h = renderer->viewport.h; - SDL_RenderSetViewport(renderer, &viewport); + renderer->viewport.x = (w - renderer->viewport.w) / 2; + renderer->viewport.y = (h - renderer->viewport.h) / 2; + renderer->UpdateViewport(renderer); } renderer->resized = SDL_TRUE; } else if (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { - int w, h; - SDL_Rect viewport; - if (!renderer->resized) { /* Window was programmatically resized, reset viewport */ + int w, h; + SDL_GetWindowSize(window, &w, &h); if (renderer->target) { renderer->viewport_backup.x = 0; @@ -130,14 +126,14 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event) renderer->viewport_backup.w = w; renderer->viewport_backup.h = h; } else { - viewport.x = 0; - viewport.y = 0; - viewport.w = w; - viewport.h = h; - SDL_RenderSetViewport(renderer, &viewport); + renderer->viewport.x = 0; + renderer->viewport.y = 0; + renderer->viewport.w = w; + renderer->viewport.h = h; + renderer->UpdateViewport(renderer); } - renderer->resized = SDL_FALSE; } + renderer->resized = SDL_FALSE; } else if (event->window.event == SDL_WINDOWEVENT_HIDDEN) { renderer->hidden = SDL_TRUE; } else if (event->window.event == SDL_WINDOWEVENT_SHOWN) { @@ -247,6 +243,8 @@ SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags) if (renderer) { renderer->magic = &renderer_magic; renderer->window = window; + renderer->scale.x = 1.0f; + renderer->scale.y = 1.0f; if (SDL_GetWindowFlags(window) & (SDL_WINDOW_HIDDEN|SDL_WINDOW_MINIMIZED)) { renderer->hidden = SDL_TRUE; @@ -867,8 +865,6 @@ SDL_RenderTargetSupported(SDL_Renderer *renderer) int SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) { - SDL_Rect viewport; - if (!SDL_RenderTargetSupported(renderer)) { SDL_Unsupported(); return -1; @@ -898,6 +894,7 @@ SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) if (texture && !renderer->target) { /* Make a backup of the viewport */ renderer->viewport_backup = renderer->viewport; + renderer->scale_backup = renderer->scale; } renderer->target = texture; @@ -906,14 +903,17 @@ SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) } if (texture) { - viewport.x = 0; - viewport.y = 0; - viewport.w = texture->w; - viewport.h = texture->h; + renderer->viewport.x = 0; + renderer->viewport.y = 0; + renderer->viewport.w = texture->w; + renderer->viewport.h = texture->h; + renderer->scale.x = 1.0f; + renderer->scale.y = 1.0f; } else { - viewport = renderer->viewport_backup; + renderer->viewport = renderer->viewport_backup; + renderer->scale = renderer->scale_backup; } - if (SDL_RenderSetViewport(renderer, &viewport) < 0) { + if (renderer->UpdateViewport(renderer) < 0) { return -1; } @@ -927,7 +927,10 @@ SDL_RenderSetViewport(SDL_Renderer * renderer, const SDL_Rect * rect) CHECK_RENDERER_MAGIC(renderer, -1); if (rect) { - renderer->viewport = *rect; + renderer->viewport.x = (int)SDL_floor(rect->x * renderer->scale.x); + renderer->viewport.y = (int)SDL_floor(rect->y * renderer->scale.y); + renderer->viewport.w = (int)SDL_ceil(rect->w * renderer->scale.x); + renderer->viewport.h = (int)SDL_ceil(rect->h * renderer->scale.y); } else { renderer->viewport.x = 0; renderer->viewport.y = 0; @@ -948,7 +951,35 @@ SDL_RenderGetViewport(SDL_Renderer * renderer, SDL_Rect * rect) { CHECK_RENDERER_MAGIC(renderer, ); - *rect = renderer->viewport; + if (rect) { + rect->x = (int)(renderer->viewport.x / renderer->scale.x); + rect->y = (int)(renderer->viewport.y / renderer->scale.y); + rect->w = (int)(renderer->viewport.w / renderer->scale.x); + rect->h = (int)(renderer->viewport.h / renderer->scale.y); + } +} + +int +SDL_RenderSetScale(SDL_Renderer * renderer, float scaleX, float scaleY) +{ + CHECK_RENDERER_MAGIC(renderer, -1); + + renderer->scale.x = scaleX; + renderer->scale.y = scaleY; + return 0; +} + +void +SDL_RenderGetScale(SDL_Renderer * renderer, float *scaleX, float *scaleY) +{ + CHECK_RENDERER_MAGIC(renderer, ); + + if (scaleX) { + *scaleX = renderer->scale.x; + } + if (scaleY) { + *scaleY = renderer->scale.y; + } } int @@ -1025,10 +1056,41 @@ SDL_RenderDrawPoint(SDL_Renderer * renderer, int x, int y) return SDL_RenderDrawPoints(renderer, &point, 1); } +static int +RenderDrawPointsWithRects(SDL_Renderer * renderer, + const SDL_Point * points, int count) +{ + SDL_FRect *frects; + int i; + int status; + + frects = SDL_stack_alloc(SDL_FRect, count); + if (!frects) { + SDL_OutOfMemory(); + return -1; + } + for (i = 0; i < count; ++i) { + frects[i].x = points[i].x * renderer->scale.x; + frects[i].y = points[i].y * renderer->scale.y; + frects[i].w = renderer->scale.x; + frects[i].h = renderer->scale.y; + } + + status = renderer->RenderFillRects(renderer, frects, count); + + SDL_stack_free(frects); + + return status; +} + int SDL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, int count) { + SDL_FPoint *fpoints; + int i; + int status; + CHECK_RENDERER_MAGIC(renderer, -1); if (!points) { @@ -1042,7 +1104,26 @@ SDL_RenderDrawPoints(SDL_Renderer * renderer, if (renderer->hidden) { return 0; } - return renderer->RenderDrawPoints(renderer, points, count); + + if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) { + return RenderDrawPointsWithRects(renderer, points, count); + } + + fpoints = SDL_stack_alloc(SDL_FPoint, count); + if (!fpoints) { + SDL_OutOfMemory(); + return -1; + } + for (i = 0; i < count; ++i) { + fpoints[i].x = points[i].x * renderer->scale.x; + fpoints[i].y = points[i].y * renderer->scale.y; + } + + status = renderer->RenderDrawPoints(renderer, fpoints, count); + + SDL_stack_free(fpoints); + + return status; } int @@ -1057,10 +1138,71 @@ SDL_RenderDrawLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2) return SDL_RenderDrawLines(renderer, points, 2); } +static int +RenderDrawLinesWithRects(SDL_Renderer * renderer, + const SDL_Point * points, int count) +{ + SDL_FRect *frect; + SDL_FRect *frects; + SDL_FPoint fpoints[2]; + int i, nrects; + int status; + + frects = SDL_stack_alloc(SDL_FRect, count-1); + if (!frects) { + SDL_OutOfMemory(); + return -1; + } + + status = 0; + nrects = 0; + for (i = 0; i < count-1; ++i) { + if (points[i].x == points[i+1].x) { + int minY = SDL_min(points[i].y, points[i+1].y); + int maxY = SDL_max(points[i].y, points[i+1].y); + + frect = &frects[nrects++]; + frect->x = points[i].x * renderer->scale.x; + frect->y = minY * renderer->scale.y; + frect->w = renderer->scale.x; + frect->h = (maxY - minY + 1) * renderer->scale.y; + } else if (points[i].y == points[i+1].y) { + int minX = SDL_min(points[i].x, points[i+1].x); + int maxX = SDL_max(points[i].x, points[i+1].x); + + frect = &frects[nrects++]; + frect->x = minX * renderer->scale.x; + frect->y = points[i].y * renderer->scale.y; + frect->w = (maxX - minX + 1) * renderer->scale.x; + frect->h = renderer->scale.y; + } else { + /* FIXME: We can't use a rect for this line... */ + frects[0].x = points[i].x * renderer->scale.x; + frects[0].y = points[i].y * renderer->scale.y; + frects[1].x = points[i+1].x * renderer->scale.x; + frects[1].y = points[i+1].y * renderer->scale.y; + status += renderer->RenderDrawLines(renderer, fpoints, 2); + } + } + + status += renderer->RenderFillRects(renderer, frects, nrects); + + SDL_stack_free(frects); + + if (status < 0) { + status = -1; + } + return status; +} + int SDL_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, int count) { + SDL_FPoint *fpoints; + int i; + int status; + CHECK_RENDERER_MAGIC(renderer, -1); if (!points) { @@ -1074,7 +1216,26 @@ SDL_RenderDrawLines(SDL_Renderer * renderer, if (renderer->hidden) { return 0; } - return renderer->RenderDrawLines(renderer, points, count); + + if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) { + return RenderDrawLinesWithRects(renderer, points, count); + } + + fpoints = SDL_stack_alloc(SDL_FPoint, count); + if (!fpoints) { + SDL_OutOfMemory(); + return -1; + } + for (i = 0; i < count; ++i) { + fpoints[i].x = points[i].x * renderer->scale.x; + fpoints[i].y = points[i].y * renderer->scale.y; + } + + status = renderer->RenderDrawLines(renderer, fpoints, count); + + SDL_stack_free(fpoints); + + return status; } int @@ -1087,10 +1248,9 @@ SDL_RenderDrawRect(SDL_Renderer * renderer, const SDL_Rect * rect) /* If 'rect' == NULL, then outline the whole surface */ if (!rect) { + SDL_RenderGetViewport(renderer, &full_rect); full_rect.x = 0; full_rect.y = 0; - full_rect.w = renderer->viewport.w; - full_rect.h = renderer->viewport.h; rect = &full_rect; } @@ -1144,10 +1304,9 @@ SDL_RenderFillRect(SDL_Renderer * renderer, const SDL_Rect * rect) /* If 'rect' == NULL, then outline the whole surface */ if (!rect) { + SDL_RenderGetViewport(renderer, &full_rect); full_rect.x = 0; full_rect.y = 0; - full_rect.w = renderer->viewport.w; - full_rect.h = renderer->viewport.h; rect = &full_rect; } return SDL_RenderFillRects(renderer, rect, 1); @@ -1157,6 +1316,10 @@ int SDL_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, int count) { + SDL_FRect *frects; + int i; + int status; + CHECK_RENDERER_MAGIC(renderer, -1); if (!rects) { @@ -1170,7 +1333,24 @@ SDL_RenderFillRects(SDL_Renderer * renderer, if (renderer->hidden) { return 0; } - return renderer->RenderFillRects(renderer, rects, count); + + frects = SDL_stack_alloc(SDL_FRect, count); + if (!frects) { + SDL_OutOfMemory(); + return -1; + } + for (i = 0; i < count; ++i) { + frects[i].x = rects[i].x * renderer->scale.x; + frects[i].y = rects[i].y * renderer->scale.y; + frects[i].w = rects[i].w * renderer->scale.x; + frects[i].h = rects[i].h * renderer->scale.y; + } + + status = renderer->RenderFillRects(renderer, frects, count); + + SDL_stack_free(frects); + + return status; } int @@ -1179,6 +1359,7 @@ SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, { SDL_Rect real_srcrect; SDL_Rect real_dstrect; + SDL_FRect frect; CHECK_RENDERER_MAGIC(renderer, -1); CHECK_TEXTURE_MAGIC(texture, -1); @@ -1198,10 +1379,9 @@ SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, } } + SDL_RenderGetViewport(renderer, &real_dstrect); real_dstrect.x = 0; real_dstrect.y = 0; - real_dstrect.w = renderer->viewport.w; - real_dstrect.h = renderer->viewport.h; if (dstrect) { if (!SDL_IntersectRect(dstrect, &real_dstrect, &real_dstrect)) { return 0; @@ -1229,8 +1409,13 @@ SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, if (renderer->hidden) { return 0; } - return renderer->RenderCopy(renderer, texture, &real_srcrect, - &real_dstrect); + + frect.x = real_dstrect.x * renderer->scale.x; + frect.y = real_dstrect.y * renderer->scale.y; + frect.w = real_dstrect.w * renderer->scale.x; + frect.h = real_dstrect.h * renderer->scale.y; + + return renderer->RenderCopy(renderer, texture, &real_srcrect, &frect); } @@ -1241,6 +1426,8 @@ SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, { SDL_Rect real_srcrect, real_dstrect; SDL_Point real_center; + SDL_FRect frect; + SDL_FPoint fcenter; CHECK_RENDERER_MAGIC(renderer, -1); CHECK_TEXTURE_MAGIC(texture, -1); @@ -1265,12 +1452,12 @@ SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, } /* We don't intersect the dstrect with the viewport as RenderCopy does because of potential rotation clipping issues... TODO: should we? */ - if (dstrect) real_dstrect = *dstrect; - else { + if (dstrect) { + real_dstrect = *dstrect; + } else { + SDL_RenderGetViewport(renderer, &real_dstrect); real_dstrect.x = 0; real_dstrect.y = 0; - real_dstrect.w = renderer->viewport.w; - real_dstrect.h = renderer->viewport.h; } if (texture->native) { @@ -1283,7 +1470,15 @@ SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, real_center.y = real_dstrect.h/2; } - return renderer->RenderCopyEx(renderer, texture, &real_srcrect, &real_dstrect, angle, &real_center, flip); + frect.x = real_dstrect.x * renderer->scale.x; + frect.y = real_dstrect.y * renderer->scale.y; + frect.w = real_dstrect.w * renderer->scale.x; + frect.h = real_dstrect.h * renderer->scale.y; + + fcenter.x = real_center.x * renderer->scale.x; + fcenter.y = real_center.y * renderer->scale.y; + + return renderer->RenderCopyEx(renderer, texture, &real_srcrect, &frect, angle, &fcenter, flip); } int diff --git a/src/render/SDL_sysrender.h b/src/render/SDL_sysrender.h index 78a026261..07d83315c 100644 --- a/src/render/SDL_sysrender.h +++ b/src/render/SDL_sysrender.h @@ -31,6 +31,20 @@ typedef struct SDL_RenderDriver SDL_RenderDriver; +typedef struct +{ + float x; + float y; +} SDL_FPoint; + +typedef struct +{ + float x; + float y; + float w; + float h; +} SDL_FRect; + /* Define the SDL texture structure */ struct SDL_Texture { @@ -80,17 +94,17 @@ struct SDL_Renderer int (*SetRenderTarget) (SDL_Renderer * renderer, SDL_Texture * texture); int (*UpdateViewport) (SDL_Renderer * renderer); int (*RenderClear) (SDL_Renderer * renderer); - int (*RenderDrawPoints) (SDL_Renderer * renderer, const SDL_Point * points, + int (*RenderDrawPoints) (SDL_Renderer * renderer, const SDL_FPoint * points, int count); - int (*RenderDrawLines) (SDL_Renderer * renderer, const SDL_Point * points, + int (*RenderDrawLines) (SDL_Renderer * renderer, const SDL_FPoint * points, int count); - int (*RenderFillRects) (SDL_Renderer * renderer, const SDL_Rect * rects, + int (*RenderFillRects) (SDL_Renderer * renderer, const SDL_FRect * rects, int count); int (*RenderCopy) (SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect); + const SDL_Rect * srcrect, const SDL_FRect * dstrect); int (*RenderCopyEx) (SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcquad, const SDL_Rect * dstrect, - const double angle, const SDL_Point *center, const SDL_RendererFlip flip); + const SDL_Rect * srcquad, const SDL_FRect * dstrect, + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip); int (*RenderReadPixels) (SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 format, void * pixels, int pitch); void (*RenderPresent) (SDL_Renderer * renderer); @@ -113,6 +127,10 @@ struct SDL_Renderer SDL_Rect viewport; SDL_Rect viewport_backup; + /* The render output coordinate scale */ + SDL_FPoint scale; + SDL_FPoint scale_backup; + /* The list of textures */ SDL_Texture *textures; SDL_Texture *target; diff --git a/src/render/direct3d/SDL_render_d3d.c b/src/render/direct3d/SDL_render_d3d.c index 21ed03f9c..0ebb7474f 100644 --- a/src/render/direct3d/SDL_render_d3d.c +++ b/src/render/direct3d/SDL_render_d3d.c @@ -188,16 +188,16 @@ static int D3D_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture); static int D3D_UpdateViewport(SDL_Renderer * renderer); static int D3D_RenderClear(SDL_Renderer * renderer); static int D3D_RenderDrawPoints(SDL_Renderer * renderer, - const SDL_Point * points, int count); + const SDL_FPoint * points, int count); static int D3D_RenderDrawLines(SDL_Renderer * renderer, - const SDL_Point * points, int count); + const SDL_FPoint * points, int count); static int D3D_RenderFillRects(SDL_Renderer * renderer, - const SDL_Rect * rects, int count); + const SDL_FRect * rects, int count); static int D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect); + const SDL_Rect * srcrect, const SDL_FRect * dstrect); static int D3D_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect, - const double angle, const SDL_Point * center, const SDL_RendererFlip flip); + const SDL_Rect * srcrect, const SDL_FRect * dstrect, + const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip); static int D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 format, void * pixels, int pitch); static void D3D_RenderPresent(SDL_Renderer * renderer); @@ -963,7 +963,7 @@ D3D_SetBlendMode(D3D_RenderData * data, int blendMode) } static int -D3D_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, +D3D_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points, int count) { D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; @@ -990,8 +990,8 @@ D3D_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, vertices = SDL_stack_alloc(Vertex, count); for (i = 0; i < count; ++i) { - vertices[i].x = (float) points[i].x; - vertices[i].y = (float) points[i].y; + vertices[i].x = points[i].x; + vertices[i].y = points[i].y; vertices[i].z = 0.0f; vertices[i].color = color; vertices[i].u = 0.0f; @@ -1009,7 +1009,7 @@ D3D_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, } static int -D3D_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, +D3D_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, int count) { D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; @@ -1036,8 +1036,8 @@ D3D_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, vertices = SDL_stack_alloc(Vertex, count); for (i = 0; i < count; ++i) { - vertices[i].x = (float) points[i].x; - vertices[i].y = (float) points[i].y; + vertices[i].x = points[i].x; + vertices[i].y = points[i].y; vertices[i].z = 0.0f; vertices[i].color = color; vertices[i].u = 0.0f; @@ -1051,8 +1051,8 @@ D3D_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, so we need to close the endpoint of the line */ if (count == 2 || points[0].x != points[count-1].x || points[0].y != points[count-1].y) { - vertices[0].x = (float) points[count-1].x; - vertices[0].y = (float) points[count-1].y; + vertices[0].x = points[count-1].x; + vertices[0].y = points[count-1].y; result = IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_POINTLIST, 1, vertices, sizeof(*vertices)); } @@ -1065,7 +1065,7 @@ D3D_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, } static int -D3D_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, +D3D_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count) { D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; @@ -1092,12 +1092,12 @@ D3D_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b); for (i = 0; i < count; ++i) { - const SDL_Rect *rect = &rects[i]; + const SDL_FRect *rect = &rects[i]; - minx = (float) rect->x; - miny = (float) rect->y; - maxx = (float) rect->x + rect->w; - maxy = (float) rect->y + rect->h; + minx = rect->x; + miny = rect->y; + maxx = rect->x + rect->w; + maxy = rect->y + rect->h; vertices[0].x = minx; vertices[0].y = miny; @@ -1140,7 +1140,7 @@ D3D_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, static int D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect) + const SDL_Rect * srcrect, const SDL_FRect * dstrect) { D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata; @@ -1155,10 +1155,10 @@ D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, return -1; } - minx = (float) dstrect->x - 0.5f; - miny = (float) dstrect->y - 0.5f; - maxx = (float) dstrect->x + dstrect->w - 0.5f; - maxy = (float) dstrect->y + dstrect->h - 0.5f; + minx = dstrect->x - 0.5f; + miny = dstrect->y - 0.5f; + maxx = dstrect->x + dstrect->w - 0.5f; + maxy = dstrect->y + dstrect->h - 0.5f; minu = (float) srcrect->x / texture->w; maxu = (float) (srcrect->x + srcrect->w) / texture->w; @@ -1239,8 +1239,8 @@ D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, static int D3D_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect, - const double angle, const SDL_Point * center, const SDL_RendererFlip flip) + const SDL_Rect * srcrect, const SDL_FRect * dstrect, + const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip) { D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata; @@ -1256,25 +1256,25 @@ D3D_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, return -1; } - centerx = (float)center->x; - centery = (float)center->y; + centerx = center->x; + centery = center->y; if (flip & SDL_FLIP_HORIZONTAL) { - minx = (float) dstrect->w - centerx - 0.5f; - maxx = (float) -centerx - 0.5f; + minx = dstrect->w - centerx - 0.5f; + maxx = -centerx - 0.5f; } else { - minx = (float) -centerx - 0.5f; - maxx = (float) dstrect->w - centerx - 0.5f; + minx = -centerx - 0.5f; + maxx = dstrect->w - centerx - 0.5f; } if (flip & SDL_FLIP_VERTICAL) { - miny = (float) dstrect->h - centery - 0.5f; - maxy = (float) -centery - 0.5f; + miny = dstrect->h - centery - 0.5f; + maxy = -centery - 0.5f; } else { - miny = (float) -centery - 0.5f; - maxy = (float) dstrect->h - centery - 0.5f; + miny = -centery - 0.5f; + maxy = dstrect->h - centery - 0.5f; } minu = (float) srcrect->x / texture->w; diff --git a/src/render/opengl/SDL_glfuncs.h b/src/render/opengl/SDL_glfuncs.h index ea3644ac1..03ee6b932 100644 --- a/src/render/opengl/SDL_glfuncs.h +++ b/src/render/opengl/SDL_glfuncs.h @@ -322,10 +322,10 @@ SDL_PROC(void, glReadPixels, SDL_PROC_UNUSED(void, glRectd, (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)) SDL_PROC_UNUSED(void, glRectdv, (const GLdouble * v1, const GLdouble * v2)) -SDL_PROC_UNUSED(void, glRectf, +SDL_PROC(void, glRectf, (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)) SDL_PROC_UNUSED(void, glRectfv, (const GLfloat * v1, const GLfloat * v2)) -SDL_PROC(void, glRecti, (GLint x1, GLint y1, GLint x2, GLint y2)) +SDL_PROC_UNUSED(void, glRecti, (GLint x1, GLint y1, GLint x2, GLint y2)) SDL_PROC_UNUSED(void, glRectiv, (const GLint * v1, const GLint * v2)) SDL_PROC_UNUSED(void, glRects, (GLshort x1, GLshort y1, GLshort x2, GLshort y2)) diff --git a/src/render/opengl/SDL_render_gl.c b/src/render/opengl/SDL_render_gl.c index 9dffc46f5..9ec7115a0 100644 --- a/src/render/opengl/SDL_render_gl.c +++ b/src/render/opengl/SDL_render_gl.c @@ -58,16 +58,16 @@ static int GL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture); static int GL_UpdateViewport(SDL_Renderer * renderer); static int GL_RenderClear(SDL_Renderer * renderer); static int GL_RenderDrawPoints(SDL_Renderer * renderer, - const SDL_Point * points, int count); + const SDL_FPoint * points, int count); static int GL_RenderDrawLines(SDL_Renderer * renderer, - const SDL_Point * points, int count); + const SDL_FPoint * points, int count); static int GL_RenderFillRects(SDL_Renderer * renderer, - const SDL_Rect * rects, int count); + const SDL_FRect * rects, int count); static int GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect); + const SDL_Rect * srcrect, const SDL_FRect * dstrect); static int GL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect, - const double angle, const SDL_Point *center, const SDL_RendererFlip flip); + const SDL_Rect * srcrect, const SDL_FRect * dstrect, + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip); static int GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 pixel_format, void * pixels, int pitch); static void GL_RenderPresent(SDL_Renderer * renderer); @@ -876,7 +876,7 @@ GL_RenderClear(SDL_Renderer * renderer) } static int -GL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, +GL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points, int count) { GL_RenderData *data = (GL_RenderData *) renderer->driverdata; @@ -894,7 +894,7 @@ GL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, } static int -GL_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, +GL_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, int count) { GL_RenderData *data = (GL_RenderData *) renderer->driverdata; @@ -959,7 +959,7 @@ GL_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, } static int -GL_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, int count) +GL_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count) { GL_RenderData *data = (GL_RenderData *) renderer->driverdata; int i; @@ -967,9 +967,9 @@ GL_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, int count) GL_SetDrawingState(renderer); for (i = 0; i < count; ++i) { - const SDL_Rect *rect = &rects[i]; + const SDL_FRect *rect = &rects[i]; - data->glRecti(rect->x, rect->y, rect->x + rect->w, rect->y + rect->h); + data->glRectf(rect->x, rect->y, rect->x + rect->w, rect->y + rect->h); } GL_CheckError("", renderer); @@ -978,11 +978,11 @@ GL_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, int count) static int GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect) + const SDL_Rect * srcrect, const SDL_FRect * dstrect) { GL_RenderData *data = (GL_RenderData *) renderer->driverdata; GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata; - int minx, miny, maxx, maxy; + GLfloat minx, miny, maxx, maxy; GLfloat minu, maxu, minv, maxv; GL_ActivateRenderer(renderer); @@ -1029,13 +1029,13 @@ GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, data->glBegin(GL_TRIANGLE_STRIP); data->glTexCoord2f(minu, minv); - data->glVertex2f((GLfloat) minx, (GLfloat) miny); + data->glVertex2f(minx, miny); data->glTexCoord2f(maxu, minv); - data->glVertex2f((GLfloat) maxx, (GLfloat) miny); + data->glVertex2f(maxx, miny); data->glTexCoord2f(minu, maxv); - data->glVertex2f((GLfloat) minx, (GLfloat) maxy); + data->glVertex2f(minx, maxy); data->glTexCoord2f(maxu, maxv); - data->glVertex2f((GLfloat) maxx, (GLfloat) maxy); + data->glVertex2f(maxx, maxy); data->glEnd(); data->glDisable(texturedata->type); @@ -1047,8 +1047,8 @@ GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, static int GL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect, - const double angle, const SDL_Point *center, const SDL_RendererFlip flip) + const SDL_Rect * srcrect, const SDL_FRect * dstrect, + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) { GL_RenderData *data = (GL_RenderData *) renderer->driverdata; GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata; @@ -1083,25 +1083,25 @@ GL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, GL_SetShader(data, SHADER_RGB); } - centerx = (GLfloat)center->x; - centery = (GLfloat)center->y; + centerx = center->x; + centery = center->y; if (flip & SDL_FLIP_HORIZONTAL) { - minx = (GLfloat) dstrect->w - centerx; + minx = dstrect->w - centerx; maxx = -centerx; } else { minx = -centerx; - maxx = (GLfloat) dstrect->w - centerx; + maxx = dstrect->w - centerx; } if (flip & SDL_FLIP_VERTICAL) { - miny = (GLfloat) dstrect->h - centery; + miny = dstrect->h - centery; maxy = -centery; } else { miny = -centery; - maxy = (GLfloat) dstrect->h - centery; + maxy = dstrect->h - centery; } minu = (GLfloat) srcrect->x / texture->w; diff --git a/src/render/opengles/SDL_glesfuncs.h b/src/render/opengles/SDL_glesfuncs.h index aab15a18a..aade01229 100644 --- a/src/render/opengles/SDL_glesfuncs.h +++ b/src/render/opengles/SDL_glesfuncs.h @@ -7,7 +7,7 @@ SDL_PROC(void, glDeleteTextures, (GLsizei, const GLuint *)) SDL_PROC(void, glDisable, (GLenum)) SDL_PROC(void, glDisableClientState, (GLenum array)) SDL_PROC(void, glDrawArrays, (GLenum, GLint, GLsizei)) -SDL_PROC(void, glDrawTexiOES, (GLint, GLint, GLint, GLint, GLint)) +SDL_PROC(void, glDrawTexfOES, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) SDL_PROC(void, glEnable, (GLenum)) SDL_PROC(void, glEnableClientState, (GLenum)) SDL_PROC(void, glFinish, (void)) diff --git a/src/render/opengles/SDL_render_gles.c b/src/render/opengles/SDL_render_gles.c index ccd221601..e2612f366 100644 --- a/src/render/opengles/SDL_render_gles.c +++ b/src/render/opengles/SDL_render_gles.c @@ -61,19 +61,19 @@ static int GLES_SetRenderTarget(SDL_Renderer * renderer, static int GLES_UpdateViewport(SDL_Renderer * renderer); static int GLES_RenderClear(SDL_Renderer * renderer); static int GLES_RenderDrawPoints(SDL_Renderer * renderer, - const SDL_Point * points, int count); + const SDL_FPoint * points, int count); static int GLES_RenderDrawLines(SDL_Renderer * renderer, - const SDL_Point * points, int count); + const SDL_FPoint * points, int count); static int GLES_RenderFillRects(SDL_Renderer * renderer, - const SDL_Rect * rects, int count); + const SDL_FRect * rects, int count); static int GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, - const SDL_Rect * dstrect); + const SDL_FRect * dstrect); +static int GLES_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_FRect * dstrect, + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip); static int GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 pixel_format, void * pixels, int pitch); -static int GLES_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect, - const double angle, const SDL_Point *center, const SDL_RendererFlip flip); static void GLES_RenderPresent(SDL_Renderer * renderer); static void GLES_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture); @@ -309,8 +309,8 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->RenderDrawLines = GLES_RenderDrawLines; renderer->RenderFillRects = GLES_RenderFillRects; renderer->RenderCopy = GLES_RenderCopy; - renderer->RenderReadPixels = GLES_RenderReadPixels; renderer->RenderCopyEx = GLES_RenderCopyEx; + renderer->RenderReadPixels = GLES_RenderReadPixels; renderer->RenderPresent = GLES_RenderPresent; renderer->DestroyTexture = GLES_DestroyTexture; renderer->DestroyRenderer = GLES_DestroyRenderer; @@ -732,43 +732,28 @@ GLES_RenderClear(SDL_Renderer * renderer) } static int -GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, +GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points, int count) { GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; - int i; - GLshort *vertices; GLES_SetDrawingState(renderer); - vertices = SDL_stack_alloc(GLshort, count*2); - for (i = 0; i < count; ++i) { - vertices[2*i+0] = (GLshort)points[i].x; - vertices[2*i+1] = (GLshort)points[i].y; - } - data->glVertexPointer(2, GL_SHORT, 0, vertices); + data->glVertexPointer(2, GL_FLOAT, 0, points); data->glDrawArrays(GL_POINTS, 0, count); - SDL_stack_free(vertices); return 0; } static int -GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, +GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, int count) { GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; - int i; - GLshort *vertices; GLES_SetDrawingState(renderer); - vertices = SDL_stack_alloc(GLshort, count*2); - for (i = 0; i < count; ++i) { - vertices[2*i+0] = (GLshort)points[i].x; - vertices[2*i+1] = (GLshort)points[i].y; - } - data->glVertexPointer(2, GL_SHORT, 0, vertices); + data->glVertexPointer(2, GL_FLOAT, 0, points); 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 */ @@ -779,13 +764,12 @@ GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, /* We need to close the endpoint of the line */ data->glDrawArrays(GL_POINTS, count-1, 1); } - SDL_stack_free(vertices); return 0; } static int -GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, +GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count) { GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; @@ -794,12 +778,12 @@ GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, GLES_SetDrawingState(renderer); for (i = 0; i < count; ++i) { - const SDL_Rect *rect = &rects[i]; - GLshort minx = rect->x; - GLshort maxx = rect->x + rect->w; - GLshort miny = rect->y; - GLshort maxy = rect->y + rect->h; - GLshort vertices[8]; + const SDL_FRect *rect = &rects[i]; + GLfloat minx = rect->x; + GLfloat maxx = rect->x + rect->w; + GLfloat miny = rect->y; + GLfloat maxy = rect->y + rect->h; + GLfloat vertices[8]; vertices[0] = minx; vertices[1] = miny; vertices[2] = maxx; @@ -809,7 +793,7 @@ GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, vertices[6] = maxx; vertices[7] = maxy; - data->glVertexPointer(2, GL_SHORT, 0, vertices); + data->glVertexPointer(2, GL_FLOAT, 0, vertices); data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } @@ -818,12 +802,12 @@ GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, static int GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect) + const SDL_Rect * srcrect, const SDL_FRect * dstrect) { GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata; - int minx, miny, maxx, maxy; + GLfloat minx, miny, maxx, maxy; GLfloat minu, maxu, minv, maxv; GLES_ActivateRenderer(renderer); @@ -856,7 +840,7 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, cropRect[3] = srcrect->h; data->glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect); - data->glDrawTexiOES(renderer->viewport.x + dstrect->x, renderer->viewport.y + dstrect->y, 0, + data->glDrawTexfOES(renderer->viewport.x + dstrect->x, renderer->viewport.y + dstrect->y, 0, dstrect->w, dstrect->h); } else { cropRect[0] = srcrect->x; @@ -865,7 +849,7 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, cropRect[3] = -srcrect->h; data->glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect); - data->glDrawTexiOES(renderer->viewport.x + dstrect->x, + data->glDrawTexfOES(renderer->viewport.x + dstrect->x, h - (renderer->viewport.y + dstrect->y) - dstrect->h, 0, dstrect->w, dstrect->h); } @@ -885,7 +869,7 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h; maxv *= texturedata->texh; - GLshort vertices[8]; + GLfloat vertices[8]; GLfloat texCoords[8]; vertices[0] = minx; @@ -906,7 +890,7 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, texCoords[6] = maxu; texCoords[7] = maxv; - data->glVertexPointer(2, GL_SHORT, 0, vertices); + data->glVertexPointer(2, GL_FLOAT, 0, vertices); data->glTexCoordPointer(2, GL_FLOAT, 0, texCoords); data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } @@ -915,67 +899,15 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, return 0; } -static int -GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, - Uint32 pixel_format, void * pixels, int pitch) -{ - GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; - SDL_Window *window = renderer->window; - Uint32 temp_format = SDL_PIXELFORMAT_ABGR8888; - void *temp_pixels; - int temp_pitch; - Uint8 *src, *dst, *tmp; - int w, h, length, rows; - int status; - - GLES_ActivateRenderer(renderer); - - temp_pitch = rect->w * SDL_BYTESPERPIXEL(temp_format); - temp_pixels = SDL_malloc(rect->h * temp_pitch); - if (!temp_pixels) { - SDL_OutOfMemory(); - return -1; - } - - SDL_GetWindowSize(window, &w, &h); - - data->glPixelStorei(GL_PACK_ALIGNMENT, 1); - - data->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h, - GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels); - - /* Flip the rows to be top-down */ - length = rect->w * SDL_BYTESPERPIXEL(temp_format); - src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch; - dst = (Uint8*)temp_pixels; - tmp = SDL_stack_alloc(Uint8, length); - rows = rect->h / 2; - while (rows--) { - SDL_memcpy(tmp, dst, length); - SDL_memcpy(dst, src, length); - SDL_memcpy(src, tmp, length); - dst += temp_pitch; - src -= temp_pitch; - } - SDL_stack_free(tmp); - - status = SDL_ConvertPixels(rect->w, rect->h, - temp_format, temp_pixels, temp_pitch, - pixel_format, pixels, pitch); - SDL_free(temp_pixels); - - return status; -} - static int GLES_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect, - const double angle, const SDL_Point *center, const SDL_RendererFlip flip) + const SDL_Rect * srcrect, const SDL_FRect * dstrect, + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) { GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata; - int minx, miny, maxx, maxy; + GLfloat minx, miny, maxx, maxy; GLfloat minu, maxu, minv, maxv; GLfloat centerx, centery; @@ -995,19 +927,18 @@ GLES_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, GLES_SetTexCoords(data, SDL_TRUE); - centerx = (GLfloat)center->x; - centery = (GLfloat)center->y; + centerx = center->x; + centery = center->y; // Rotate and translate data->glPushMatrix(); - data->glTranslatef((GLfloat)dstrect->x + centerx, (GLfloat)dstrect->y + centery, (GLfloat)0.0); - data->glRotatef((GLfloat)angle, (GLfloat)0.0, (GLfloat)0.0, (GLfloat)1.0); + data->glTranslatef(dstrect->x + centerx, dstrect->y + centery, 0.0f); + data->glRotatef((GLfloat)angle, 0.0f, 0.0f, 1.0f); if (flip & SDL_FLIP_HORIZONTAL) { - minx = (GLfloat) dstrect->w - centerx; + minx = dstrect->w - centerx; maxx = -centerx; - } - else { + } else { minx = -centerx; maxx = dstrect->w - centerx; } @@ -1015,8 +946,7 @@ GLES_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, if (flip & SDL_FLIP_VERTICAL) { miny = dstrect->h - centery; maxy = -centery; - } - else { + } else { miny = -centery; maxy = dstrect->h - centery; } @@ -1030,7 +960,7 @@ GLES_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h; maxv *= texturedata->texh; - GLshort vertices[8]; + GLfloat vertices[8]; GLfloat texCoords[8]; vertices[0] = minx; @@ -1050,7 +980,7 @@ GLES_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, texCoords[5] = maxv; texCoords[6] = maxu; texCoords[7] = maxv; - data->glVertexPointer(2, GL_SHORT, 0, vertices); + data->glVertexPointer(2, GL_FLOAT, 0, vertices); data->glTexCoordPointer(2, GL_FLOAT, 0, texCoords); data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); data->glPopMatrix(); @@ -1059,6 +989,58 @@ GLES_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, return 0; } +static int +GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, + Uint32 pixel_format, void * pixels, int pitch) +{ + GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; + SDL_Window *window = renderer->window; + Uint32 temp_format = SDL_PIXELFORMAT_ABGR8888; + void *temp_pixels; + int temp_pitch; + Uint8 *src, *dst, *tmp; + int w, h, length, rows; + int status; + + GLES_ActivateRenderer(renderer); + + temp_pitch = rect->w * SDL_BYTESPERPIXEL(temp_format); + temp_pixels = SDL_malloc(rect->h * temp_pitch); + if (!temp_pixels) { + SDL_OutOfMemory(); + return -1; + } + + SDL_GetWindowSize(window, &w, &h); + + data->glPixelStorei(GL_PACK_ALIGNMENT, 1); + + data->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h, + GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels); + + /* Flip the rows to be top-down */ + length = rect->w * SDL_BYTESPERPIXEL(temp_format); + src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch; + dst = (Uint8*)temp_pixels; + tmp = SDL_stack_alloc(Uint8, length); + rows = rect->h / 2; + while (rows--) { + SDL_memcpy(tmp, dst, length); + SDL_memcpy(dst, src, length); + SDL_memcpy(src, tmp, length); + dst += temp_pitch; + src -= temp_pitch; + } + SDL_stack_free(tmp); + + status = SDL_ConvertPixels(rect->w, rect->h, + temp_format, temp_pixels, temp_pitch, + pixel_format, pixels, pitch); + SDL_free(temp_pixels); + + return status; +} + static void GLES_RenderPresent(SDL_Renderer * renderer) { diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c index 2bdffa884..69b0aab8c 100644 --- a/src/render/opengles2/SDL_render_gles2.c +++ b/src/render/opengles2/SDL_render_gles2.c @@ -945,16 +945,16 @@ GLES2_SetOrthographicProjection(SDL_Renderer *renderer) static const float inv255f = 1.0f / 255.0f; static int GLES2_RenderClear(SDL_Renderer *renderer); -static int GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int count); -static int GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count); -static int GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count); +static int GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_FPoint *points, int count); +static int GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_FPoint *points, int count); +static int GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_FRect *rects, int count); static int GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, - const SDL_Rect *dstrect); + const SDL_FRect *dstrect); static int GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 pixel_format, void * pixels, int pitch); static int GLES2_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect, - const double angle, const SDL_Point *center, const SDL_RendererFlip flip); + const SDL_Rect * srcrect, const SDL_FRect * dstrect, + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip); static void GLES2_RenderPresent(SDL_Renderer *renderer); @@ -1054,7 +1054,7 @@ GLES2_SetDrawingState(SDL_Renderer * renderer) } static int -GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int count) +GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_FPoint *points, int count) { GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; GLfloat *vertices; @@ -1068,8 +1068,8 @@ GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int coun vertices = SDL_stack_alloc(GLfloat, count * 2); for (idx = 0; idx < count; ++idx) { - GLfloat x = (GLfloat)points[idx].x + 0.5f; - GLfloat y = (GLfloat)points[idx].y + 0.5f; + GLfloat x = points[idx].x + 0.5f; + GLfloat y = points[idx].y + 0.5f; vertices[idx * 2] = x; vertices[(idx * 2) + 1] = y; @@ -1087,7 +1087,7 @@ GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int coun } static int -GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count) +GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_FPoint *points, int count) { GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; GLfloat *vertices; @@ -1101,8 +1101,8 @@ GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count vertices = SDL_stack_alloc(GLfloat, count * 2); for (idx = 0; idx < count; ++idx) { - GLfloat x = (GLfloat)points[idx].x + 0.5f; - GLfloat y = (GLfloat)points[idx].y + 0.5f; + GLfloat x = points[idx].x + 0.5f; + GLfloat y = points[idx].y + 0.5f; vertices[idx * 2] = x; vertices[(idx * 2) + 1] = y; @@ -1126,7 +1126,7 @@ GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count } static int -GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count) +GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_FRect *rects, int count) { GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; GLfloat vertices[8]; @@ -1139,12 +1139,12 @@ GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count) /* Emit a line loop for each rectangle */ rdata->glGetError(); for (idx = 0; idx < count; ++idx) { - const SDL_Rect *rect = &rects[idx]; + const SDL_FRect *rect = &rects[idx]; - GLfloat xMin = (GLfloat)rect->x; - GLfloat xMax = (GLfloat)(rect->x + rect->w); - GLfloat yMin = (GLfloat)rect->y; - GLfloat yMax = (GLfloat)(rect->y + rect->h); + GLfloat xMin = rect->x; + GLfloat xMax = (rect->x + rect->w); + GLfloat yMin = rect->y; + GLfloat yMax = (rect->y + rect->h); vertices[0] = xMin; vertices[1] = yMin; @@ -1167,7 +1167,7 @@ GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count) static int GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, - const SDL_Rect *dstrect) + const SDL_FRect *dstrect) { GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; @@ -1294,14 +1294,14 @@ GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *s GLES2_SetTexCoords(rdata, SDL_TRUE); /* Emit the textured quad */ - vertices[0] = (GLfloat)dstrect->x; - vertices[1] = (GLfloat)dstrect->y; - vertices[2] = (GLfloat)(dstrect->x + dstrect->w); - vertices[3] = (GLfloat)dstrect->y; - vertices[4] = (GLfloat)dstrect->x; - vertices[5] = (GLfloat)(dstrect->y + dstrect->h); - vertices[6] = (GLfloat)(dstrect->x + dstrect->w); - vertices[7] = (GLfloat)(dstrect->y + dstrect->h); + vertices[0] = dstrect->x; + vertices[1] = dstrect->y; + vertices[2] = (dstrect->x + dstrect->w); + vertices[3] = dstrect->y; + vertices[4] = dstrect->x; + vertices[5] = (dstrect->y + dstrect->h); + vertices[6] = (dstrect->x + dstrect->w); + vertices[7] = (dstrect->y + dstrect->h); rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices); texCoords[0] = srcrect->x / (GLfloat)texture->w; texCoords[1] = srcrect->y / (GLfloat)texture->h; @@ -1323,7 +1323,7 @@ GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *s static int GLES2_RenderCopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, - const SDL_Rect *dstrect, const double angle, const SDL_Point *center, const SDL_RendererFlip flip) + const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) { GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; @@ -1343,8 +1343,8 @@ GLES2_RenderCopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect rdata->glEnableVertexAttribArray(GLES2_ATTRIBUTE_ANGLE); fAngle[0] = fAngle[1] = fAngle[2] = fAngle[3] = (GLfloat)angle; /* Calculate the center of rotation */ - translate[0] = translate[2] = translate[4] = translate[6] = (GLfloat)(center->x + dstrect->x); - translate[1] = translate[3] = translate[5] = translate[7] = (GLfloat)(center->y + dstrect->y); + translate[0] = translate[2] = translate[4] = translate[6] = (center->x + dstrect->x); + translate[1] = translate[3] = translate[5] = translate[7] = (center->y + dstrect->y); /* Activate an appropriate shader and set the projection matrix */ blendMode = texture->blendMode; @@ -1460,14 +1460,14 @@ GLES2_RenderCopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect GLES2_SetTexCoords(rdata, SDL_TRUE); /* Emit the textured quad */ - vertices[0] = (GLfloat)dstrect->x; - vertices[1] = (GLfloat)dstrect->y; - vertices[2] = (GLfloat)(dstrect->x + dstrect->w); - vertices[3] = (GLfloat)dstrect->y; - vertices[4] = (GLfloat)dstrect->x; - vertices[5] = (GLfloat)(dstrect->y + dstrect->h); - vertices[6] = (GLfloat)(dstrect->x + dstrect->w); - vertices[7] = (GLfloat)(dstrect->y + dstrect->h); + vertices[0] = dstrect->x; + vertices[1] = dstrect->y; + vertices[2] = (dstrect->x + dstrect->w); + vertices[3] = dstrect->y; + vertices[4] = dstrect->x; + vertices[5] = (dstrect->y + dstrect->h); + vertices[6] = (dstrect->x + dstrect->w); + vertices[7] = (dstrect->y + dstrect->h); if (flip & SDL_FLIP_HORIZONTAL) { tmp = vertices[0]; vertices[0] = vertices[4] = vertices[2]; diff --git a/src/render/software/SDL_render_sw.c b/src/render/software/SDL_render_sw.c index 4f4d38fb5..43d9d84e6 100644 --- a/src/render/software/SDL_render_sw.c +++ b/src/render/software/SDL_render_sw.c @@ -56,16 +56,16 @@ static int SW_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture); static int SW_UpdateViewport(SDL_Renderer * renderer); static int SW_RenderClear(SDL_Renderer * renderer); static int SW_RenderDrawPoints(SDL_Renderer * renderer, - const SDL_Point * points, int count); + const SDL_FPoint * points, int count); static int SW_RenderDrawLines(SDL_Renderer * renderer, - const SDL_Point * points, int count); + const SDL_FPoint * points, int count); static int SW_RenderFillRects(SDL_Renderer * renderer, - const SDL_Rect * rects, int count); + const SDL_FRect * rects, int count); static int SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect); + const SDL_Rect * srcrect, const SDL_FRect * dstrect); static int SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect, - const double angle, const SDL_Point * center, const SDL_RendererFlip flip); + const SDL_Rect * srcrect, const SDL_FRect * dstrect, + const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip); static int SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 format, void * pixels, int pitch); static void SW_RenderPresent(SDL_Renderer * renderer); @@ -344,28 +344,35 @@ SW_RenderClear(SDL_Renderer * renderer) } static int -SW_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, +SW_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points, int count) { SDL_Surface *surface = SW_ActivateRenderer(renderer); - SDL_Point *temp = NULL; - int status; + SDL_Point *final_points; + int i, status; if (!surface) { return -1; } + final_points = SDL_stack_alloc(SDL_Point, count); + if (!final_points) { + SDL_OutOfMemory(); + return -1; + } if (renderer->viewport.x || renderer->viewport.y) { - int i; - int x = renderer->viewport.x; - int y = renderer->viewport.y; + float x = renderer->viewport.x * renderer->scale.x; + float y = renderer->viewport.y * renderer->scale.y; - temp = SDL_stack_alloc(SDL_Point, count); for (i = 0; i < count; ++i) { - temp[i].x = x + points[i].x; - temp[i].y = y + points[i].x; + final_points[i].x = (int)(x + points[i].x); + final_points[i].y = (int)(y + points[i].y); + } + } else { + for (i = 0; i < count; ++i) { + final_points[i].x = (int)points[i].x; + final_points[i].y = (int)points[i].y; } - points = temp; } /* Draw the points! */ @@ -374,43 +381,48 @@ SW_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, renderer->r, renderer->g, renderer->b, renderer->a); - status = SDL_DrawPoints(surface, points, count, color); + status = SDL_DrawPoints(surface, final_points, count, color); } else { - status = SDL_BlendPoints(surface, points, count, + status = SDL_BlendPoints(surface, final_points, count, renderer->blendMode, renderer->r, renderer->g, renderer->b, renderer->a); } + SDL_stack_free(final_points); - if (temp) { - SDL_stack_free(temp); - } return status; } static int -SW_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, +SW_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, int count) { SDL_Surface *surface = SW_ActivateRenderer(renderer); - SDL_Point *temp = NULL; - int status; + SDL_Point *final_points; + int i, status; if (!surface) { return -1; } + final_points = SDL_stack_alloc(SDL_Point, count); + if (!final_points) { + SDL_OutOfMemory(); + return -1; + } if (renderer->viewport.x || renderer->viewport.y) { - int i; - int x = renderer->viewport.x; - int y = renderer->viewport.y; + float x = renderer->viewport.x * renderer->scale.x; + float y = renderer->viewport.y * renderer->scale.y; - temp = SDL_stack_alloc(SDL_Point, count); for (i = 0; i < count; ++i) { - temp[i].x = x + points[i].x; - temp[i].y = y + points[i].y; + final_points[i].x = (int)(x + points[i].x); + final_points[i].y = (int)(y + points[i].y); + } + } else { + for (i = 0; i < count; ++i) { + final_points[i].x = (int)points[i].x; + final_points[i].y = (int)points[i].y; } - points = temp; } /* Draw the lines! */ @@ -419,80 +431,91 @@ SW_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, renderer->r, renderer->g, renderer->b, renderer->a); - status = SDL_DrawLines(surface, points, count, color); + status = SDL_DrawLines(surface, final_points, count, color); } else { - status = SDL_BlendLines(surface, points, count, + status = SDL_BlendLines(surface, final_points, count, renderer->blendMode, renderer->r, renderer->g, renderer->b, renderer->a); } + SDL_stack_free(final_points); - if (temp) { - SDL_stack_free(temp); - } return status; } static int -SW_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, int count) +SW_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count) { SDL_Surface *surface = SW_ActivateRenderer(renderer); - SDL_Rect *temp = NULL; - int status; + SDL_Rect *final_rects; + int i, status; if (!surface) { return -1; } + final_rects = SDL_stack_alloc(SDL_Rect, count); + if (!final_rects) { + SDL_OutOfMemory(); + return -1; + } if (renderer->viewport.x || renderer->viewport.y) { - int i; - int x = renderer->viewport.x; - int y = renderer->viewport.y; + float x = renderer->viewport.x * renderer->scale.x; + float y = renderer->viewport.y * renderer->scale.y; - temp = SDL_stack_alloc(SDL_Rect, count); for (i = 0; i < count; ++i) { - temp[i].x = x + rects[i].x; - temp[i].y = y + rects[i].y; - temp[i].w = rects[i].w; - temp[i].h = rects[i].h; + final_rects[i].x = (int)(x + rects[i].x); + final_rects[i].y = (int)(y + rects[i].y); + final_rects[i].w = SDL_max((int)rects[i].w, 1); + final_rects[i].h = SDL_max((int)rects[i].h, 1); + } + } else { + for (i = 0; i < count; ++i) { + final_rects[i].x = (int)rects[i].x; + final_rects[i].y = (int)rects[i].y; + final_rects[i].w = SDL_max((int)rects[i].w, 1); + final_rects[i].h = SDL_max((int)rects[i].h, 1); } - rects = temp; } if (renderer->blendMode == SDL_BLENDMODE_NONE) { Uint32 color = SDL_MapRGBA(surface->format, renderer->r, renderer->g, renderer->b, renderer->a); - status = SDL_FillRects(surface, rects, count, color); + status = SDL_FillRects(surface, final_rects, count, color); } else { - status = SDL_BlendFillRects(surface, rects, count, + status = SDL_BlendFillRects(surface, final_rects, count, renderer->blendMode, renderer->r, renderer->g, renderer->b, renderer->a); } + SDL_stack_free(final_rects); - if (temp) { - SDL_stack_free(temp); - } return status; } static int SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect) + const SDL_Rect * srcrect, const SDL_FRect * dstrect) { SDL_Surface *surface = SW_ActivateRenderer(renderer); SDL_Surface *src = (SDL_Surface *) texture->driverdata; - SDL_Rect final_rect = *dstrect; + SDL_Rect final_rect; if (!surface) { return -1; } if (renderer->viewport.x || renderer->viewport.y) { - final_rect.x += renderer->viewport.x; - final_rect.y += renderer->viewport.y; + final_rect.x = (int)((renderer->viewport.x * renderer->scale.x) + dstrect->x); + final_rect.y = (int)((renderer->viewport.y * renderer->scale.y) + dstrect->y); + } else { + final_rect.x = (int)dstrect->x; + final_rect.y = (int)dstrect->y; } + final_rect.w = (int)dstrect->w; + final_rect.h = (int)dstrect->h; + if ( srcrect->w == final_rect.w && srcrect->h == final_rect.h ) { return SDL_BlitSurface(src, srcrect, surface, &final_rect); } else { @@ -514,12 +537,12 @@ GetScaleQuality(void) static int SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect, - const double angle, const SDL_Point * center, const SDL_RendererFlip flip) + const SDL_Rect * srcrect, const SDL_FRect * dstrect, + const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip) { SDL_Surface *surface = SW_ActivateRenderer(renderer); SDL_Surface *src = (SDL_Surface *) texture->driverdata; - SDL_Rect final_rect = *dstrect, tmp_rect; + SDL_Rect final_rect, tmp_rect; SDL_Surface *surface_rotated, *surface_scaled; Uint32 colorkey; int retval, dstwidth, dstheight, abscenterx, abscentery; @@ -530,27 +553,33 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, } if (renderer->viewport.x || renderer->viewport.y) { - final_rect.x += renderer->viewport.x; - final_rect.y += renderer->viewport.y; + final_rect.x = (int)((renderer->viewport.x * renderer->scale.x) + dstrect->x); + final_rect.y = (int)((renderer->viewport.y * renderer->scale.y) + dstrect->y); + } else { + final_rect.x = (int)dstrect->x; + final_rect.y = (int)dstrect->y; } + final_rect.w = (int)dstrect->w; + final_rect.h = (int)dstrect->h; surface_scaled = SDL_CreateRGBSurface(SDL_SWSURFACE, final_rect.w, final_rect.h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask ); - SDL_GetColorKey(src, &colorkey); - SDL_SetColorKey(surface_scaled, SDL_TRUE, colorkey); - tmp_rect = final_rect; - tmp_rect.x = 0; - tmp_rect.y = 0; if (surface_scaled) { + SDL_GetColorKey(src, &colorkey); + SDL_SetColorKey(surface_scaled, SDL_TRUE, colorkey); + tmp_rect = final_rect; + tmp_rect.x = 0; + tmp_rect.y = 0; + retval = SDL_BlitScaled(src, srcrect, surface_scaled, &tmp_rect); if (!retval) { _rotozoomSurfaceSizeTrig(tmp_rect.w, tmp_rect.h, -angle, &dstwidth, &dstheight, &cangle, &sangle); surface_rotated = _rotateSurface(surface_scaled, -angle, dstwidth/2, dstheight/2, GetScaleQuality(), flip & SDL_FLIP_HORIZONTAL, flip & SDL_FLIP_VERTICAL, dstwidth, dstheight, cangle, sangle); if(surface_rotated) { /* Find out where the new origin is by rotating the four final_rect points around the center and then taking the extremes */ - abscenterx = final_rect.x + center->x; - abscentery = final_rect.y + center->y; + abscenterx = final_rect.x + (int)center->x; + abscentery = final_rect.y + (int)center->y; /* Compensate the angle inversion to match the behaviour of the other backends */ sangle = -sangle;