2021-07-18 18:26:12 +02:00
|
|
|
#include <basic_widgets/core/renderer.hpp>
|
|
|
|
#include <basic_widgets/core/texture.hpp>
|
2021-07-16 17:18:13 +02:00
|
|
|
|
|
|
|
using namespace bwidgets;
|
|
|
|
|
2021-08-26 18:59:52 +02:00
|
|
|
Renderer::Renderer(SDL_Renderer* r) : _data {ptr_or_throw<SDLError>(r)}, info {_info(r)}
|
2021-08-11 15:52:07 +02:00
|
|
|
{}
|
2021-07-16 17:18:13 +02:00
|
|
|
|
2021-08-08 14:30:56 +02:00
|
|
|
Renderer::Renderer(SDL_Window* w, const int index, const uint32_t flags = 0)
|
2021-08-26 18:59:52 +02:00
|
|
|
: Renderer {SDL_CreateRenderer(w, index, flags)}
|
2021-07-29 16:06:03 +02:00
|
|
|
{}
|
2021-07-16 17:18:13 +02:00
|
|
|
|
2021-08-06 14:22:56 +02:00
|
|
|
auto Renderer::blend_mode() -> SDL_BlendMode
|
2021-07-16 17:18:13 +02:00
|
|
|
{
|
2021-07-30 20:41:47 +02:00
|
|
|
SDL_BlendMode mode {};
|
2021-08-26 18:59:52 +02:00
|
|
|
success_or_throw<SDLError>(SDL_GetRenderDrawBlendMode(_data.get(), &mode));
|
2021-07-16 17:18:13 +02:00
|
|
|
|
|
|
|
return mode;
|
|
|
|
}
|
|
|
|
|
2021-08-08 14:30:56 +02:00
|
|
|
auto Renderer::blend_mode(const SDL_BlendMode mode) -> Renderer*
|
2021-07-16 17:18:13 +02:00
|
|
|
{
|
2021-08-26 18:59:52 +02:00
|
|
|
success_or_throw<SDLError>(SDL_SetRenderDrawBlendMode(_data.get(), mode));
|
2021-07-16 17:18:13 +02:00
|
|
|
|
2021-07-18 18:26:12 +02:00
|
|
|
return this;
|
2021-07-16 17:18:13 +02:00
|
|
|
}
|
|
|
|
|
2021-08-06 14:22:56 +02:00
|
|
|
auto Renderer::clear() -> Renderer*
|
2021-07-16 17:18:13 +02:00
|
|
|
{
|
2021-08-26 18:59:52 +02:00
|
|
|
success_or_throw<SDLError>(SDL_RenderClear(_data.get()));
|
2021-07-16 17:18:13 +02:00
|
|
|
|
2021-07-18 18:26:12 +02:00
|
|
|
return this;
|
2021-07-16 17:18:13 +02:00
|
|
|
}
|
|
|
|
|
2021-08-21 20:59:39 +02:00
|
|
|
auto Renderer::copy(const Texture& t, const SDL_Rect* const src,
|
|
|
|
const SDL_Rect* const dst) -> Renderer*
|
2021-07-16 17:18:13 +02:00
|
|
|
{
|
2021-08-26 18:59:52 +02:00
|
|
|
success_or_throw<SDLError>(SDL_RenderCopy(_data.get(), t._data.get(), src, dst));
|
2021-07-16 17:18:13 +02:00
|
|
|
|
2021-07-18 18:26:12 +02:00
|
|
|
return this;
|
2021-07-16 17:18:13 +02:00
|
|
|
}
|
|
|
|
|
2021-08-06 14:22:56 +02:00
|
|
|
auto Renderer::draw_color() -> Color
|
2021-07-16 17:18:13 +02:00
|
|
|
{
|
2021-08-06 14:22:56 +02:00
|
|
|
Color c;
|
2021-08-13 22:00:42 +02:00
|
|
|
success_or_throw<SDLError>(
|
2021-08-26 18:59:52 +02:00
|
|
|
SDL_GetRenderDrawColor(_data.get(), &c().r, &c().g, &c().b, &c().a));
|
2021-07-16 17:18:13 +02:00
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
2021-08-21 20:59:39 +02:00
|
|
|
auto Renderer::draw_color(const Color c) -> Renderer*
|
2021-07-16 17:18:13 +02:00
|
|
|
{
|
2021-08-13 22:00:42 +02:00
|
|
|
success_or_throw<SDLError>(
|
2021-08-26 18:59:52 +02:00
|
|
|
SDL_SetRenderDrawColor(_data.get(), c().r, c().g, c().b, c().a));
|
2021-07-16 17:18:13 +02:00
|
|
|
|
2021-07-18 18:26:12 +02:00
|
|
|
return this;
|
2021-07-16 17:18:13 +02:00
|
|
|
}
|
|
|
|
|
2021-08-21 20:59:39 +02:00
|
|
|
auto Renderer::draw_line(const SDL_Point a, const SDL_Point b) -> Renderer*
|
2021-07-16 17:18:13 +02:00
|
|
|
{
|
2021-08-26 18:59:52 +02:00
|
|
|
success_or_throw<SDLError>(SDL_RenderDrawLine(_data.get(), a.x, a.y, b.x, b.y));
|
2021-07-16 17:18:13 +02:00
|
|
|
|
2021-07-18 18:26:12 +02:00
|
|
|
return this;
|
2021-07-16 17:18:13 +02:00
|
|
|
}
|
|
|
|
|
2021-08-21 20:59:39 +02:00
|
|
|
auto Renderer::draw_lines(const std::span<SDL_Point> pts) -> Renderer*
|
2021-07-16 17:18:13 +02:00
|
|
|
{
|
2021-08-13 22:00:42 +02:00
|
|
|
success_or_throw<SDLError>(
|
2021-08-26 18:59:52 +02:00
|
|
|
SDL_RenderDrawLines(_data.get(), pts.data(), (int)pts.size()));
|
2021-07-16 17:18:13 +02:00
|
|
|
|
2021-07-18 18:26:12 +02:00
|
|
|
return this;
|
2021-07-16 17:18:13 +02:00
|
|
|
}
|
|
|
|
|
2021-08-21 20:59:39 +02:00
|
|
|
auto Renderer::draw_point(const SDL_Point p) -> Renderer*
|
2021-07-16 17:18:13 +02:00
|
|
|
{
|
2021-08-26 18:59:52 +02:00
|
|
|
success_or_throw<SDLError>(SDL_RenderDrawPoint(_data.get(), p.x, p.y));
|
2021-07-16 17:18:13 +02:00
|
|
|
|
2021-07-18 18:26:12 +02:00
|
|
|
return this;
|
2021-07-16 17:18:13 +02:00
|
|
|
}
|
|
|
|
|
2021-08-21 20:59:39 +02:00
|
|
|
auto Renderer::draw_points(const std::span<SDL_Point> pts) -> Renderer*
|
2021-07-16 17:18:13 +02:00
|
|
|
{
|
2021-08-13 22:00:42 +02:00
|
|
|
success_or_throw<SDLError>(
|
2021-08-26 18:59:52 +02:00
|
|
|
SDL_RenderDrawPoints(_data.get(), pts.data(), (int)pts.size()));
|
2021-07-16 17:18:13 +02:00
|
|
|
|
2021-07-18 18:26:12 +02:00
|
|
|
return this;
|
2021-07-16 17:18:13 +02:00
|
|
|
}
|
|
|
|
|
2021-08-21 20:59:39 +02:00
|
|
|
auto Renderer::draw_rect(const SDL_Rect* const r) -> Renderer*
|
2021-07-16 17:18:13 +02:00
|
|
|
{
|
2021-07-26 22:57:28 +02:00
|
|
|
auto vp = viewport();
|
|
|
|
// Has glitch at top-left and bottom-right corner.
|
|
|
|
// The first corner has an extra pixel at y-1 and surimpression.
|
|
|
|
// The second corner is missing a pixel.
|
2021-07-30 20:41:47 +02:00
|
|
|
if (r != nullptr)
|
|
|
|
viewport({vp.x + r->x, vp.y + r->y, r->w - 1, r->h - 1}); // crop extra pixel
|
2021-08-26 18:59:52 +02:00
|
|
|
success_or_throw<SDLError>(SDL_RenderDrawRect(_data.get(), nullptr));
|
2021-08-06 14:22:56 +02:00
|
|
|
// add missing pixel. works sometimes…
|
|
|
|
if (r != nullptr) draw_point({r->w - 1, r->h - 1});
|
2021-07-29 16:06:03 +02:00
|
|
|
else draw_point({vp.w - 1, vp.h - 1});
|
2021-07-26 22:57:28 +02:00
|
|
|
|
2021-08-19 15:00:44 +02:00
|
|
|
viewport(&vp);
|
2021-07-26 22:57:28 +02:00
|
|
|
|
2021-07-18 18:26:12 +02:00
|
|
|
return this;
|
2021-07-16 17:18:13 +02:00
|
|
|
}
|
|
|
|
|
2021-08-21 20:59:39 +02:00
|
|
|
auto Renderer::draw_rects(const std::span<SDL_Rect> rs) -> Renderer*
|
2021-07-16 17:18:13 +02:00
|
|
|
{
|
2021-08-26 18:59:52 +02:00
|
|
|
success_or_throw<SDLError>(
|
|
|
|
SDL_RenderDrawRects(_data.get(), rs.data(), (int)rs.size()));
|
2021-07-16 17:18:13 +02:00
|
|
|
|
2021-07-18 18:26:12 +02:00
|
|
|
return this;
|
2021-07-16 17:18:13 +02:00
|
|
|
}
|
|
|
|
|
2021-08-21 20:59:39 +02:00
|
|
|
auto Renderer::fill_rect(const SDL_Rect* const r) -> Renderer*
|
2021-07-16 17:18:13 +02:00
|
|
|
{
|
2021-08-26 18:59:52 +02:00
|
|
|
success_or_throw<SDLError>(SDL_RenderFillRect(_data.get(), r));
|
2021-07-16 17:18:13 +02:00
|
|
|
|
2021-07-18 18:26:12 +02:00
|
|
|
return this;
|
2021-07-16 17:18:13 +02:00
|
|
|
}
|
|
|
|
|
2021-08-21 20:59:39 +02:00
|
|
|
auto Renderer::fill_rects(const std::span<SDL_Rect> rs) -> Renderer*
|
2021-07-16 17:18:13 +02:00
|
|
|
{
|
2021-08-26 18:59:52 +02:00
|
|
|
success_or_throw<SDLError>(
|
|
|
|
SDL_RenderFillRects(_data.get(), rs.data(), (int)rs.size()));
|
2021-07-16 17:18:13 +02:00
|
|
|
|
2021-07-18 18:26:12 +02:00
|
|
|
return this;
|
2021-07-16 17:18:13 +02:00
|
|
|
}
|
|
|
|
|
2021-08-06 14:22:56 +02:00
|
|
|
auto Renderer::output_size() -> Size
|
2021-07-16 17:18:13 +02:00
|
|
|
{
|
2021-07-30 20:41:47 +02:00
|
|
|
Size s {};
|
2021-08-26 18:59:52 +02:00
|
|
|
success_or_throw<SDLError>(SDL_GetRendererOutputSize(_data.get(), &s.w, &s.h));
|
2021-07-16 17:18:13 +02:00
|
|
|
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2021-08-08 16:00:22 +02:00
|
|
|
void Renderer::present() noexcept
|
2021-07-16 17:18:13 +02:00
|
|
|
{
|
2021-08-26 18:59:52 +02:00
|
|
|
SDL_RenderPresent(_data.get());
|
2021-07-16 17:18:13 +02:00
|
|
|
}
|
|
|
|
|
2021-08-08 16:00:22 +02:00
|
|
|
auto Renderer::viewport() noexcept -> SDL_Rect
|
2021-07-16 17:18:13 +02:00
|
|
|
{
|
|
|
|
SDL_Rect vp;
|
2021-08-26 18:59:52 +02:00
|
|
|
SDL_RenderGetViewport(_data.get(), &vp);
|
2021-07-16 17:18:13 +02:00
|
|
|
|
|
|
|
return vp;
|
|
|
|
}
|
|
|
|
|
2021-08-21 20:59:39 +02:00
|
|
|
auto Renderer::viewport(const SDL_Rect* const vp) -> Renderer*
|
2021-07-16 17:18:13 +02:00
|
|
|
{
|
2021-08-26 18:59:52 +02:00
|
|
|
success_or_throw<SDLError>(SDL_RenderSetViewport(_data.get(), vp));
|
2021-07-16 17:18:13 +02:00
|
|
|
|
2021-07-18 18:26:12 +02:00
|
|
|
return this;
|
2021-07-16 17:18:13 +02:00
|
|
|
}
|