Mercurial > sdl-ios-xcode
diff src/video/win32/SDL_gdirender.c @ 3536:0267b8b1595c
Added interfaces for batch drawing of points, lines and rects:
SDL_DrawPoints()
SDL_BlendPoints()
SDL_BlendLines()
SDL_DrawLines()
SDL_FillRects()
SDL_BlendRects()
SDL_RenderPoints()
SDL_RenderLines()
SDL_RenderRects()
Renamed SDL_RenderFill() to SDL_RenderRect()
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Wed, 09 Dec 2009 15:56:56 +0000 |
parents | b403f790df65 |
children | 0f958e527e5e |
line wrap: on
line diff
--- a/src/video/win32/SDL_gdirender.c Mon Dec 07 10:08:24 2009 +0000 +++ b/src/video/win32/SDL_gdirender.c Wed Dec 09 15:56:56 2009 +0000 @@ -61,10 +61,12 @@ void **pixels, int *pitch); static void GDI_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture); static int GDI_SetDrawBlendMode(SDL_Renderer * renderer); -static int GDI_RenderPoint(SDL_Renderer * renderer, int x, int y); -static int GDI_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, - int y2); -static int GDI_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect); +static int GDI_RenderPoints(SDL_Renderer * renderer, const SDL_Point * points, + int count); +static int GDI_RenderLines(SDL_Renderer * renderer, const SDL_Point * points, + int count); +static int GDI_RenderRects(SDL_Renderer * renderer, const SDL_Rect ** rects, + int count); static int GDI_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_Rect * dstrect); static int GDI_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, @@ -192,9 +194,9 @@ renderer->LockTexture = GDI_LockTexture; renderer->UnlockTexture = GDI_UnlockTexture; renderer->SetDrawBlendMode = GDI_SetDrawBlendMode; - renderer->RenderPoint = GDI_RenderPoint; - renderer->RenderLine = GDI_RenderLine; - renderer->RenderFill = GDI_RenderFill; + renderer->RenderPoints = GDI_RenderPoints; + renderer->RenderLines = GDI_RenderLines; + renderer->RenderRects = GDI_RenderRects; renderer->RenderCopy = GDI_RenderCopy; renderer->RenderReadPixels = GDI_RenderReadPixels; renderer->RenderWritePixels = GDI_RenderWritePixels; @@ -685,96 +687,128 @@ } static int -GDI_RenderPoint(SDL_Renderer * renderer, int x, int y) +GDI_RenderPoints(SDL_Renderer * renderer, const SDL_Point * points, int count) { GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; + int i; + COLORREF color; if (data->makedirty) { + /* Get the smallest rectangle that contains everything */ + SDL_Window *window = SDL_GetWindowFromID(renderer->window); SDL_Rect rect; - rect.x = x; - rect.y = y; - rect.w = 1; - rect.h = 1; + rect.x = 0; + rect.y = 0; + rect.w = window->w; + rect.h = window->h; + if (!SDL_EnclosePoints(points, count, &rect, &rect)) { + /* Nothing to draw */ + return 0; + } SDL_AddDirtyRect(&data->dirty, &rect); } - SetPixel(data->current_hdc, x, y, - RGB(renderer->r, renderer->g, renderer->b)); + color = RGB(renderer->r, renderer->g, renderer->b); + for (i = 0; i < count; ++i) { + SetPixel(data->current_hdc, points[i].x, points[i].y, color); + } + return 0; } static int -GDI_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2) +GDI_RenderLines(SDL_Renderer * renderer, const SDL_Point * points, int count) { GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; - POINT points[2]; HPEN pen; BOOL status; if (data->makedirty) { - SDL_Rect rect; + /* Get the smallest rectangle that contains everything */ + SDL_Window *window = SDL_GetWindowFromID(renderer->window); + SDL_Rect clip, rect; - if (x1 < x2) { - rect.x = x1; - rect.w = (x2 - x1) + 1; - } else { - rect.x = x2; - rect.w = (x1 - x2) + 1; + clip.x = 0; + clip.y = 0; + clip.w = window->w; + clip.h = window->h; + SDL_EnclosePoints(points, count, NULL, &rect); + if (!SDL_IntersectRect(&rect, &clip, &rect)) { + /* Nothing to draw */ + return 0; } - if (y1 < y2) { - rect.y = y1; - rect.h = (y2 - y1) + 1; - } else { - rect.y = y2; - rect.h = (y1 - y2) + 1; - } + SDL_AddDirtyRect(&data->dirty, &rect); } /* Should we cache the pen? .. it looks like GDI does for us. :) */ pen = CreatePen(PS_SOLID, 1, RGB(renderer->r, renderer->g, renderer->b)); SelectObject(data->current_hdc, pen); - points[0].x = x1; - points[0].y = y1; - points[1].x = x2; - points[1].y = y2; - status = Polyline(data->current_hdc, points, 2); + { + LPPOINT p = SDL_stack_alloc(POINT, count); + int i; + + for (i = 0; i < count; ++i) { + p[i].x = points[i].x; + p[i].y = points[i].y; + } + status = Polyline(data->current_hdc, p, count); + SDL_stack_free(p); + } DeleteObject(pen); /* Need to close the endpoint of the line */ - SetPixel(data->current_hdc, x2, y2, - RGB(renderer->r, renderer->g, renderer->b)); + if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) { + SetPixel(data->current_hdc, points[count-1].x, points[count-1].y, + RGB(renderer->r, renderer->g, renderer->b)); + } if (!status) { - WIN_SetError("FillRect()"); + WIN_SetError("Polyline()"); return -1; } return 0; } static int -GDI_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect) +GDI_RenderRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count) { GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; RECT rc; HBRUSH brush; - int status; + int i, status = 1; if (data->makedirty) { - SDL_AddDirtyRect(&data->dirty, rect); - } + SDL_Window *window = SDL_GetWindowFromID(renderer->window); + SDL_Rect clip, rect; - rc.left = rect->x; - rc.top = rect->y; - rc.right = rect->x + rect->w; - rc.bottom = rect->y + rect->h; + clip.x = 0; + clip.y = 0; + clip.w = window->w; + clip.h = window->h; + + for (i = 0; i < count; ++i) { + if (SDL_IntersectRect(rects[i], &clip, &rect)) { + SDL_AddDirtyRect(&data->dirty, &rect); + } + } + } /* Should we cache the brushes? .. it looks like GDI does for us. :) */ brush = CreateSolidBrush(RGB(renderer->r, renderer->g, renderer->b)); SelectObject(data->current_hdc, brush); - status = FillRect(data->current_hdc, &rc, brush); + for (i = 0; i < count; ++i) { + const SDL_Rect *rect = rects[i]; + + rc.left = rect->x; + rc.top = rect->y; + rc.right = rect->x + rect->w; + rc.bottom = rect->y + rect->h; + + status &= FillRect(data->current_hdc, &rc, brush); + } DeleteObject(brush); if (!status) {