bwidgets/src/core/renderer.cpp

158 lines
3.7 KiB
C++

#include <basic_widgets/core/renderer.hpp>
#include <basic_widgets/core/texture.hpp>
using namespace bwidgets;
Renderer::Renderer(SDL_Renderer* r) : _data {ptr_or_throw<SDLError>(r)}, info {_info(r)}
{}
Renderer::Renderer(SDL_Window* w, const int index, const uint32_t flags = 0)
: Renderer {SDL_CreateRenderer(w, index, flags)}
{}
auto Renderer::blend_mode() -> SDL_BlendMode
{
SDL_BlendMode mode {};
success_or_throw<SDLError>(SDL_GetRenderDrawBlendMode(_data.get(), &mode));
return mode;
}
auto Renderer::blend_mode(const SDL_BlendMode mode) -> Renderer*
{
success_or_throw<SDLError>(SDL_SetRenderDrawBlendMode(_data.get(), mode));
return this;
}
auto Renderer::clear() -> Renderer*
{
success_or_throw<SDLError>(SDL_RenderClear(_data.get()));
return this;
}
auto Renderer::copy(const Texture& t, const SDL_Rect* const src,
const SDL_Rect* const dst) -> Renderer*
{
success_or_throw<SDLError>(SDL_RenderCopy(_data.get(), t._data.get(), src, dst));
return this;
}
auto Renderer::draw_color() -> Color
{
Color c;
success_or_throw<SDLError>(
SDL_GetRenderDrawColor(_data.get(), &c().r, &c().g, &c().b, &c().a));
return c;
}
auto Renderer::draw_color(const Color c) -> Renderer*
{
success_or_throw<SDLError>(
SDL_SetRenderDrawColor(_data.get(), c().r, c().g, c().b, c().a));
return this;
}
auto Renderer::draw_line(const SDL_Point a, const SDL_Point b) -> Renderer*
{
success_or_throw<SDLError>(SDL_RenderDrawLine(_data.get(), a.x, a.y, b.x, b.y));
return this;
}
auto Renderer::draw_lines(const std::span<SDL_Point> pts) -> Renderer*
{
success_or_throw<SDLError>(
SDL_RenderDrawLines(_data.get(), pts.data(), (int)pts.size()));
return this;
}
auto Renderer::draw_point(const SDL_Point p) -> Renderer*
{
success_or_throw<SDLError>(SDL_RenderDrawPoint(_data.get(), p.x, p.y));
return this;
}
auto Renderer::draw_points(const std::span<SDL_Point> pts) -> Renderer*
{
success_or_throw<SDLError>(
SDL_RenderDrawPoints(_data.get(), pts.data(), (int)pts.size()));
return this;
}
auto Renderer::draw_rect(const SDL_Rect* const r) -> Renderer*
{
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.
if (r != nullptr)
viewport({vp.x + r->x, vp.y + r->y, r->w - 1, r->h - 1}); // crop extra pixel
success_or_throw<SDLError>(SDL_RenderDrawRect(_data.get(), nullptr));
// add missing pixel. works sometimes…
if (r != nullptr) draw_point({r->w - 1, r->h - 1});
else draw_point({vp.w - 1, vp.h - 1});
viewport(&vp);
return this;
}
auto Renderer::draw_rects(const std::span<SDL_Rect> rs) -> Renderer*
{
success_or_throw<SDLError>(
SDL_RenderDrawRects(_data.get(), rs.data(), (int)rs.size()));
return this;
}
auto Renderer::fill_rect(const SDL_Rect* const r) -> Renderer*
{
success_or_throw<SDLError>(SDL_RenderFillRect(_data.get(), r));
return this;
}
auto Renderer::fill_rects(const std::span<SDL_Rect> rs) -> Renderer*
{
success_or_throw<SDLError>(
SDL_RenderFillRects(_data.get(), rs.data(), (int)rs.size()));
return this;
}
auto Renderer::output_size() -> Size
{
Size s {};
success_or_throw<SDLError>(SDL_GetRendererOutputSize(_data.get(), &s.w, &s.h));
return s;
}
void Renderer::present() noexcept
{
SDL_RenderPresent(_data.get());
}
auto Renderer::viewport() noexcept -> SDL_Rect
{
SDL_Rect vp;
SDL_RenderGetViewport(_data.get(), &vp);
return vp;
}
auto Renderer::viewport(const SDL_Rect* const vp) -> Renderer*
{
success_or_throw<SDLError>(SDL_RenderSetViewport(_data.get(), vp));
return this;
}