From: Ingo Ruhnke Date: Thu, 31 Jul 2014 19:03:59 +0000 (+0200) Subject: Merged drawing code from SDLLightmap and SDLRenderer into helper class SDLPainter X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=d70f6d036935da2db6b19a7adc742bc691fb2554;p=supertux.git Merged drawing code from SDLLightmap and SDLRenderer into helper class SDLPainter --- diff --git a/src/video/sdl/sdl_lightmap.cpp b/src/video/sdl/sdl_lightmap.cpp index b9ab7be22..d7149600b 100644 --- a/src/video/sdl/sdl_lightmap.cpp +++ b/src/video/sdl/sdl_lightmap.cpp @@ -20,6 +20,7 @@ #include "video/sdl/sdl_surface_data.hpp" #include "video/sdl/sdl_texture.hpp" #include "video/sdl/sdl_renderer.hpp" +#include "video/sdl/sdl_painter.hpp" SDLLightmap::SDLLightmap() : renderer(static_cast(Renderer::instance())->get_sdl_renderer()), @@ -86,70 +87,25 @@ SDLLightmap::do_draw() void SDLLightmap::draw_surface(const DrawingRequest& request) { - //FIXME: support parameters request.alpha, request.angle, request.blend - const Surface* surface = (const Surface*) request.request_data; - boost::shared_ptr sdltexture = boost::dynamic_pointer_cast(surface->get_texture()); - - SDL_Rect dst_rect; - dst_rect.x = request.pos.x; - dst_rect.y = request.pos.y; - dst_rect.w = sdltexture->get_image_width(); - dst_rect.h = sdltexture->get_image_height(); - - SDL_SetTextureBlendMode(sdltexture->get_texture(), SDL_BLENDMODE_ADD); - SDL_RenderCopy(renderer, sdltexture->get_texture(), NULL, &dst_rect); + SDLPainter::draw_surface(renderer, request); } void SDLLightmap::draw_surface_part(const DrawingRequest& request) { - //FIXME: support parameters request.alpha, request.angle, request.blend - const Surface* surface = (const Surface*) request.request_data; - boost::shared_ptr sdltexture = boost::dynamic_pointer_cast(surface->get_texture()); - - SDL_Rect dst_rect; - dst_rect.x = request.pos.x; - dst_rect.y = request.pos.y; - dst_rect.w = sdltexture->get_image_width(); - dst_rect.h = sdltexture->get_image_height(); - - SDL_SetTextureBlendMode(sdltexture->get_texture(), SDL_BLENDMODE_ADD); - SDL_RenderCopy(renderer, sdltexture->get_texture(), NULL, &dst_rect); + SDLPainter::draw_surface_part(renderer, request); } void SDLLightmap::draw_gradient(const DrawingRequest& request) { - log_info << "draw_gradient" << std::endl; + SDLPainter::draw_gradient(renderer, request); } void SDLLightmap::draw_filled_rect(const DrawingRequest& request) { - log_info << "draw_filled_rect" << std::endl; - - const FillRectRequest* fillrectrequest - = (FillRectRequest*) request.request_data; - - SDL_Rect rect; - rect.x = request.pos.x; - rect.y = request.pos.y; - rect.w = fillrectrequest->size.x; - rect.h = fillrectrequest->size.y; - - Uint8 r = static_cast(fillrectrequest->color.red * 255); - Uint8 g = static_cast(fillrectrequest->color.green * 255); - Uint8 b = static_cast(fillrectrequest->color.blue * 255); - Uint8 a = static_cast(fillrectrequest->color.alpha * 255); - - log_info << fillrectrequest->color.red << " " << fillrectrequest->color.green << std::endl; - - if((rect.w != 0) && (rect.h != 0)) - { - SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_ADD); - SDL_SetRenderDrawColor(renderer, r, g, b, a); - SDL_RenderFillRect(renderer, &rect); - } + SDLPainter::draw_filled_rect(renderer, request); } void diff --git a/src/video/sdl/sdl_painter.cpp b/src/video/sdl/sdl_painter.cpp new file mode 100644 index 000000000..b47c7f1a6 --- /dev/null +++ b/src/video/sdl/sdl_painter.cpp @@ -0,0 +1,292 @@ +// SuperTux +// Copyright (C) 2014 Ingo Ruhnke +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "video/sdl/sdl_painter.hpp" + +#include "SDL.h" + +#include "video/drawing_request.hpp" +#include "video/sdl/sdl_texture.hpp" + +void +SDLPainter::draw_surface(SDL_Renderer* renderer, const DrawingRequest& request) +{ + //FIXME: support parameters request.angle, request.blend + const Surface* surface = (const Surface*) request.request_data; + boost::shared_ptr sdltexture = boost::dynamic_pointer_cast(surface->get_texture()); + + SDL_Rect dst_rect; + dst_rect.x = request.pos.x; + dst_rect.y = request.pos.y; + dst_rect.w = sdltexture->get_image_width(); + dst_rect.h = sdltexture->get_image_height(); + + Uint8 r = static_cast(request.color.red * 255); + Uint8 g = static_cast(request.color.green * 255); + Uint8 b = static_cast(request.color.blue * 255); + Uint8 a = static_cast(request.color.alpha * request.alpha * 255); + SDL_SetTextureColorMod(sdltexture->get_texture(), r, g, b); + SDL_SetTextureAlphaMod(sdltexture->get_texture(), a); + + if (surface->get_flipx()) + { + SDL_RenderCopyEx(renderer, sdltexture->get_texture(), NULL, &dst_rect, 0, NULL, SDL_FLIP_HORIZONTAL); + } + else + { + switch(request.drawing_effect) + { + case VERTICAL_FLIP: + SDL_RenderCopyEx(renderer, sdltexture->get_texture(), NULL, &dst_rect, 0, NULL, SDL_FLIP_VERTICAL); + break; + + case HORIZONTAL_FLIP: + SDL_RenderCopyEx(renderer, sdltexture->get_texture(), NULL, &dst_rect, 0, NULL, SDL_FLIP_HORIZONTAL); + break; + + default: + case NO_EFFECT: + SDL_RenderCopy(renderer, sdltexture->get_texture(), NULL, &dst_rect); + break; + } + } +} + +void +SDLPainter::draw_surface_part(SDL_Renderer* renderer, const DrawingRequest& request) +{ + //FIXME: support parameters request.angle, request.blend + const SurfacePartRequest* surface = (const SurfacePartRequest*) request.request_data; + const SurfacePartRequest* surfacepartrequest = (SurfacePartRequest*) request.request_data; + + boost::shared_ptr sdltexture = boost::dynamic_pointer_cast(surface->surface->get_texture()); + + SDL_Rect src_rect; + src_rect.x = surfacepartrequest->source.x; + src_rect.y = surfacepartrequest->source.y; + src_rect.w = surfacepartrequest->size.x; + src_rect.h = surfacepartrequest->size.y; + + SDL_Rect dst_rect; + dst_rect.x = request.pos.x; + dst_rect.y = request.pos.y; + dst_rect.w = surfacepartrequest->size.x; + dst_rect.h = surfacepartrequest->size.y; + + Uint8 r = static_cast(request.color.red * 255); + Uint8 g = static_cast(request.color.green * 255); + Uint8 b = static_cast(request.color.blue * 255); + Uint8 a = static_cast(request.color.alpha * request.alpha * 255); + SDL_SetTextureColorMod(sdltexture->get_texture(), r, g, b); + SDL_SetTextureAlphaMod(sdltexture->get_texture(), a); + + if (surface->surface->get_flipx()) + { + SDL_RenderCopyEx(renderer, sdltexture->get_texture(), &src_rect, &dst_rect, 0, NULL, SDL_FLIP_HORIZONTAL); + } + else + { + switch(request.drawing_effect) + { + case VERTICAL_FLIP: + SDL_RenderCopyEx(renderer, sdltexture->get_texture(), &src_rect, &dst_rect, 0, NULL, SDL_FLIP_VERTICAL); + break; + + case HORIZONTAL_FLIP: + SDL_RenderCopyEx(renderer, sdltexture->get_texture(), &src_rect, &dst_rect, 0, NULL, SDL_FLIP_HORIZONTAL); + break; + + default: + case NO_EFFECT: + SDL_RenderCopy(renderer, sdltexture->get_texture(), &src_rect, &dst_rect); + break; + } + } +} + +void +SDLPainter::draw_gradient(SDL_Renderer* renderer, const DrawingRequest& request) +{ + const GradientRequest* gradientrequest + = (GradientRequest*) request.request_data; + const Color& top = gradientrequest->top; + const Color& bottom = gradientrequest->bottom; + + SDL_Rect viewport; + SDL_RenderGetViewport(renderer, &viewport); + + // calculate the maximum number of steps needed for the gradient + int n = static_cast(std::max(std::max(fabsf(top.red - bottom.red), + fabsf(top.green - bottom.green)), + std::max(fabsf(top.blue - bottom.blue), + fabsf(top.alpha - bottom.alpha))) * 255); + for(int i = 0; i < n; ++i) + { + SDL_Rect rect; + rect.x = 0; + rect.y = viewport.h * i / n; + rect.w = viewport.w; + rect.h = (viewport.h * (i+1) / n) - rect.y; + + float p = static_cast(i+1) / static_cast(n); + Uint8 r = static_cast(((1.0f - p) * top.red + p * bottom.red) * 255); + Uint8 g = static_cast(((1.0f - p) * top.green + p * bottom.green) * 255); + Uint8 b = static_cast(((1.0f - p) * top.blue + p * bottom.blue) * 255); + Uint8 a = static_cast(((1.0f - p) * top.alpha + p * bottom.alpha) * 255); + + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(renderer, r, g, b, a); + SDL_RenderFillRect(renderer, &rect); + } +} + +void +SDLPainter::draw_filled_rect(SDL_Renderer* renderer, const DrawingRequest& request) +{ + const FillRectRequest* fillrectrequest + = (FillRectRequest*) request.request_data; + + SDL_Rect rect; + rect.x = request.pos.x; + rect.y = request.pos.y; + rect.w = fillrectrequest->size.x; + rect.h = fillrectrequest->size.y; + + Uint8 r = static_cast(fillrectrequest->color.red * 255); + Uint8 g = static_cast(fillrectrequest->color.green * 255); + Uint8 b = static_cast(fillrectrequest->color.blue * 255); + Uint8 a = static_cast(fillrectrequest->color.alpha * 255); + + int radius = std::min(std::min(rect.h / 2, rect.w / 2), + static_cast(fillrectrequest->radius)); + + if (radius) + { + int slices = radius; + + // rounded top and bottom parts + std::vector rects; + rects.reserve(2*slices + 1); + for(int i = 0; i < slices; ++i) + { + float p = (static_cast(i) + 0.5f) / static_cast(slices); + int xoff = radius - static_cast(sqrtf(1.0f - p*p) * radius); + + SDL_Rect tmp; + tmp.x = rect.x + xoff; + tmp.y = rect.y + (radius - i); + tmp.w = rect.w - 2*(xoff); + tmp.h = 1; + rects.push_back(tmp); + + SDL_Rect tmp2; + tmp2.x = rect.x + xoff; + tmp2.y = rect.y + rect.h - radius + i; + tmp2.w = rect.w - 2*xoff; + tmp2.h = 1; + + if (tmp2.y != tmp.y) + { + rects.push_back(tmp2); + } + } + + if (2*radius < rect.h) + { + // center rectangle + SDL_Rect tmp; + tmp.x = rect.x; + tmp.y = rect.y + radius + 1; + tmp.w = rect.w; + tmp.h = rect.h - 2*radius - 1; + rects.push_back(tmp); + } + + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(renderer, r, g, b, a); + SDL_RenderFillRects(renderer, &*rects.begin(), rects.size()); + } + else + { + if((rect.w != 0) && (rect.h != 0)) + { + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(renderer, r, g, b, a); + SDL_RenderFillRect(renderer, &rect); + } + } +} + +void +SDLPainter::draw_inverse_ellipse(SDL_Renderer* renderer, const DrawingRequest& request) +{ + const InverseEllipseRequest* ellipse = (InverseEllipseRequest*)request.request_data; + + SDL_Rect viewport; + SDL_RenderGetViewport(renderer, &viewport); + + float x = request.pos.x; + float w = ellipse->size.x; + float h = ellipse->size.y; + + int top = request.pos.y - (h / 2); + + const int max_slices = 256; + SDL_Rect rects[2*max_slices+2]; + int slices = std::min(static_cast(ellipse->size.y), max_slices); + for(int i = 0; i < slices; ++i) + { + float p = ((static_cast(i) + 0.5f) / static_cast(slices)) * 2.0f - 1.0f; + int xoff = static_cast(sqrtf(1.0f - p*p) * w / 2); + + SDL_Rect& left = rects[2*i+0]; + SDL_Rect& right = rects[2*i+1]; + + left.x = 0; + left.y = top + (i * h / slices); + left.w = x - xoff; + left.h = (top + ((i+1) * h / slices)) - left.y; + + right.x = x + xoff; + right.y = left.y; + right.w = viewport.w - right.x; + right.h = left.h; + } + + SDL_Rect& top_rect = rects[2*slices+0]; + SDL_Rect& bottom_rect = rects[2*slices+1]; + + top_rect.x = 0; + top_rect.y = 0; + top_rect.w = viewport.w; + top_rect.h = top; + + bottom_rect.x = 0; + bottom_rect.y = top + h; + bottom_rect.w = viewport.w; + bottom_rect.h = viewport.h - bottom_rect.y; + + Uint8 r = static_cast(ellipse->color.red * 255); + Uint8 g = static_cast(ellipse->color.green * 255); + Uint8 b = static_cast(ellipse->color.blue * 255); + Uint8 a = static_cast(ellipse->color.alpha * 255); + + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(renderer, r, g, b, a); + SDL_RenderFillRects(renderer, rects, 2*slices+2); +} + +/* EOF */ diff --git a/src/video/sdl/sdl_painter.hpp b/src/video/sdl/sdl_painter.hpp new file mode 100644 index 000000000..db317167b --- /dev/null +++ b/src/video/sdl/sdl_painter.hpp @@ -0,0 +1,39 @@ +// SuperTux +// Copyright (C) 2014 Ingo Ruhnke +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef HEADER_SUPERTUX_VIDEO_SDL_PAINTER_HPP +#define HEADER_SUPERTUX_VIDEO_SDL_PAINTER_HPP + +#include "SDL.h" +#include "video/renderer.hpp" + +class SDLPainter +{ +public: + static void draw_surface(SDL_Renderer* renderer, const DrawingRequest& request); + static void draw_surface_part(SDL_Renderer* renderer, const DrawingRequest& request); + static void draw_gradient(SDL_Renderer* renderer, const DrawingRequest& request); + static void draw_filled_rect(SDL_Renderer* renderer, const DrawingRequest& request); + static void draw_inverse_ellipse(SDL_Renderer* renderer, const DrawingRequest& request); + +private: + SDLPainter(const SDLPainter&); + SDLPainter& operator=(const SDLPainter&); +}; + +#endif + +/* EOF */ diff --git a/src/video/sdl/sdl_renderer.cpp b/src/video/sdl/sdl_renderer.cpp index eb8a03129..892e39ade 100644 --- a/src/video/sdl/sdl_renderer.cpp +++ b/src/video/sdl/sdl_renderer.cpp @@ -21,6 +21,7 @@ #include "video/drawing_request.hpp" #include "video/sdl/sdl_surface_data.hpp" #include "video/sdl/sdl_texture.hpp" +#include "video/sdl/sdl_painter.hpp" #include #include @@ -98,271 +99,31 @@ SDLRenderer::~SDLRenderer() void SDLRenderer::draw_surface(const DrawingRequest& request) { - //FIXME: support parameters request.angle, request.blend - const Surface* surface = (const Surface*) request.request_data; - boost::shared_ptr sdltexture = boost::dynamic_pointer_cast(surface->get_texture()); - - SDL_Rect dst_rect; - dst_rect.x = request.pos.x; - dst_rect.y = request.pos.y; - dst_rect.w = sdltexture->get_image_width(); - dst_rect.h = sdltexture->get_image_height(); - - Uint8 r = static_cast(request.color.red * 255); - Uint8 g = static_cast(request.color.green * 255); - Uint8 b = static_cast(request.color.blue * 255); - Uint8 a = static_cast(request.color.alpha * request.alpha * 255); - SDL_SetTextureColorMod(sdltexture->get_texture(), r, g, b); - SDL_SetTextureAlphaMod(sdltexture->get_texture(), a); - - if (surface->get_flipx()) - { - SDL_RenderCopyEx(renderer, sdltexture->get_texture(), NULL, &dst_rect, 0, NULL, SDL_FLIP_HORIZONTAL); - } - else - { - switch(request.drawing_effect) - { - case VERTICAL_FLIP: - SDL_RenderCopyEx(renderer, sdltexture->get_texture(), NULL, &dst_rect, 0, NULL, SDL_FLIP_VERTICAL); - break; - - case HORIZONTAL_FLIP: - SDL_RenderCopyEx(renderer, sdltexture->get_texture(), NULL, &dst_rect, 0, NULL, SDL_FLIP_HORIZONTAL); - break; - - default: - case NO_EFFECT: - SDL_RenderCopy(renderer, sdltexture->get_texture(), NULL, &dst_rect); - break; - } - } + SDLPainter::draw_surface(renderer, request); } void SDLRenderer::draw_surface_part(const DrawingRequest& request) { - //FIXME: support parameters request.angle, request.blend - const SurfacePartRequest* surface = (const SurfacePartRequest*) request.request_data; - const SurfacePartRequest* surfacepartrequest = (SurfacePartRequest*) request.request_data; - - boost::shared_ptr sdltexture = boost::dynamic_pointer_cast(surface->surface->get_texture()); - - SDL_Rect src_rect; - src_rect.x = surfacepartrequest->source.x; - src_rect.y = surfacepartrequest->source.y; - src_rect.w = surfacepartrequest->size.x; - src_rect.h = surfacepartrequest->size.y; - - SDL_Rect dst_rect; - dst_rect.x = request.pos.x; - dst_rect.y = request.pos.y; - dst_rect.w = surfacepartrequest->size.x; - dst_rect.h = surfacepartrequest->size.y; - - Uint8 r = static_cast(request.color.red * 255); - Uint8 g = static_cast(request.color.green * 255); - Uint8 b = static_cast(request.color.blue * 255); - Uint8 a = static_cast(request.color.alpha * request.alpha * 255); - SDL_SetTextureColorMod(sdltexture->get_texture(), r, g, b); - SDL_SetTextureAlphaMod(sdltexture->get_texture(), a); - - if (surface->surface->get_flipx()) - { - SDL_RenderCopyEx(renderer, sdltexture->get_texture(), &src_rect, &dst_rect, 0, NULL, SDL_FLIP_HORIZONTAL); - } - else - { - switch(request.drawing_effect) - { - case VERTICAL_FLIP: - SDL_RenderCopyEx(renderer, sdltexture->get_texture(), &src_rect, &dst_rect, 0, NULL, SDL_FLIP_VERTICAL); - break; - - case HORIZONTAL_FLIP: - SDL_RenderCopyEx(renderer, sdltexture->get_texture(), &src_rect, &dst_rect, 0, NULL, SDL_FLIP_HORIZONTAL); - break; - - default: - case NO_EFFECT: - SDL_RenderCopy(renderer, sdltexture->get_texture(), &src_rect, &dst_rect); - break; - } - } + SDLPainter::draw_surface_part(renderer, request); } void SDLRenderer::draw_gradient(const DrawingRequest& request) { - const GradientRequest* gradientrequest - = (GradientRequest*) request.request_data; - const Color& top = gradientrequest->top; - const Color& bottom = gradientrequest->bottom; - - int w; - int h; - SDL_GetWindowSize(window, &w, &h); - - // calculate the maximum number of steps needed for the gradient - int n = static_cast(std::max(std::max(fabsf(top.red - bottom.red), - fabsf(top.green - bottom.green)), - std::max(fabsf(top.blue - bottom.blue), - fabsf(top.alpha - bottom.alpha))) * 255); - for(int i = 0; i < n; ++i) - { - SDL_Rect rect; - rect.x = 0; - rect.y = h * i / n; - rect.w = w; - rect.h = (h * (i+1) / n) - rect.y; - - float p = static_cast(i+1) / static_cast(n); - Uint8 r = static_cast(((1.0f - p) * top.red + p * bottom.red) * 255); - Uint8 g = static_cast(((1.0f - p) * top.green + p * bottom.green) * 255); - Uint8 b = static_cast(((1.0f - p) * top.blue + p * bottom.blue) * 255); - Uint8 a = static_cast(((1.0f - p) * top.alpha + p * bottom.alpha) * 255); - - SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); - SDL_SetRenderDrawColor(renderer, r, g, b, a); - SDL_RenderFillRect(renderer, &rect); - } + SDLPainter::draw_gradient(renderer, request); } void SDLRenderer::draw_filled_rect(const DrawingRequest& request) { - const FillRectRequest* fillrectrequest - = (FillRectRequest*) request.request_data; - - SDL_Rect rect; - rect.x = request.pos.x; - rect.y = request.pos.y; - rect.w = fillrectrequest->size.x; - rect.h = fillrectrequest->size.y; - - Uint8 r = static_cast(fillrectrequest->color.red * 255); - Uint8 g = static_cast(fillrectrequest->color.green * 255); - Uint8 b = static_cast(fillrectrequest->color.blue * 255); - Uint8 a = static_cast(fillrectrequest->color.alpha * 255); - - int radius = std::min(std::min(rect.h / 2, rect.w / 2), - static_cast(fillrectrequest->radius)); - - if (radius) - { - int slices = radius; - - // rounded top and bottom parts - std::vector rects; - rects.reserve(2*slices + 1); - for(int i = 0; i < slices; ++i) - { - float p = (static_cast(i) + 0.5f) / static_cast(slices); - int xoff = radius - static_cast(sqrtf(1.0f - p*p) * radius); - - SDL_Rect tmp; - tmp.x = rect.x + xoff; - tmp.y = rect.y + (radius - i); - tmp.w = rect.w - 2*(xoff); - tmp.h = 1; - rects.push_back(tmp); - - SDL_Rect tmp2; - tmp2.x = rect.x + xoff; - tmp2.y = rect.y + rect.h - radius + i; - tmp2.w = rect.w - 2*xoff; - tmp2.h = 1; - - if (tmp2.y != tmp.y) - { - rects.push_back(tmp2); - } - } - - if (2*radius < rect.h) - { - // center rectangle - SDL_Rect tmp; - tmp.x = rect.x; - tmp.y = rect.y + radius + 1; - tmp.w = rect.w; - tmp.h = rect.h - 2*radius - 1; - rects.push_back(tmp); - } - - SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); - SDL_SetRenderDrawColor(renderer, r, g, b, a); - SDL_RenderFillRects(renderer, &*rects.begin(), rects.size()); - } - else - { - if((rect.w != 0) && (rect.h != 0)) - { - SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); - SDL_SetRenderDrawColor(renderer, r, g, b, a); - SDL_RenderFillRect(renderer, &rect); - } - } + SDLPainter::draw_filled_rect(renderer, request); } void SDLRenderer::draw_inverse_ellipse(const DrawingRequest& request) { - const InverseEllipseRequest* ellipse = (InverseEllipseRequest*)request.request_data; - - int window_w; - int window_h; - SDL_GetWindowSize(window, &window_w, &window_h); - - float x = request.pos.x; - float w = ellipse->size.x; - float h = ellipse->size.y; - - int top = request.pos.y - (h / 2); - - const int max_slices = 256; - SDL_Rect rects[2*max_slices+2]; - int slices = std::min(static_cast(ellipse->size.y), max_slices); - for(int i = 0; i < slices; ++i) - { - float p = ((static_cast(i) + 0.5f) / static_cast(slices)) * 2.0f - 1.0f; - int xoff = static_cast(sqrtf(1.0f - p*p) * w / 2); - - SDL_Rect& left = rects[2*i+0]; - SDL_Rect& right = rects[2*i+1]; - - left.x = 0; - left.y = top + (i * h / slices); - left.w = x - xoff; - left.h = (top + ((i+1) * h / slices)) - left.y; - - right.x = x + xoff; - right.y = left.y; - right.w = window_w - right.x; - right.h = left.h; - } - - SDL_Rect& top_rect = rects[2*slices+0]; - SDL_Rect& bottom_rect = rects[2*slices+1]; - - top_rect.x = 0; - top_rect.y = 0; - top_rect.w = window_w; - top_rect.h = top; - - bottom_rect.x = 0; - bottom_rect.y = top + h; - bottom_rect.w = window_w; - bottom_rect.h = window_h - bottom_rect.y; - - Uint8 r = static_cast(ellipse->color.red * 255); - Uint8 g = static_cast(ellipse->color.green * 255); - Uint8 b = static_cast(ellipse->color.blue * 255); - Uint8 a = static_cast(ellipse->color.alpha * 255); - - SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); - SDL_SetRenderDrawColor(renderer, r, g, b, a); - SDL_RenderFillRects(renderer, rects, 2*slices+2); + SDLPainter::draw_inverse_ellipse(renderer, request); } void