158 lines
3.7 KiB
C++
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)
|
|
: Wrapper {ptr_or_throw<SDLError>(r),
|
|
[r](SDL_Renderer*) noexcept { SDL_DestroyRenderer(r); }},
|
|
info {_info(r)}
|
|
{}
|
|
|
|
Renderer::Renderer(SDL_Window* w, const int index, const uint32_t flags = 0)
|
|
: Renderer {ptr_or_throw<SDLError>(SDL_CreateRenderer(w, index, flags))}
|
|
{}
|
|
|
|
auto Renderer::blend_mode() -> SDL_BlendMode
|
|
{
|
|
SDL_BlendMode mode {};
|
|
success_or_throw<SDLError>(SDL_GetRenderDrawBlendMode(_data(), &mode));
|
|
|
|
return mode;
|
|
}
|
|
|
|
auto Renderer::blend_mode(const SDL_BlendMode mode) -> Renderer*
|
|
{
|
|
success_or_throw<SDLError>(SDL_SetRenderDrawBlendMode(_data(), mode));
|
|
|
|
return this;
|
|
}
|
|
|
|
auto Renderer::clear() -> Renderer*
|
|
{
|
|
success_or_throw<SDLError>(SDL_RenderClear(_data()));
|
|
|
|
return this;
|
|
}
|
|
|
|
auto Renderer::copy(const Texture* t, const SDL_Rect* src, const SDL_Rect* dst)
|
|
-> Renderer*
|
|
{
|
|
success_or_throw<SDLError>(SDL_RenderCopy(_data(), t->_data(), src, dst));
|
|
|
|
return this;
|
|
}
|
|
|
|
auto Renderer::draw_color() -> Color
|
|
{
|
|
Color c;
|
|
success_or_throw<SDLError>(
|
|
SDL_GetRenderDrawColor(_data(), &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(), 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(), a.x, a.y, b.x, b.y));
|
|
|
|
return this;
|
|
}
|
|
|
|
auto Renderer::draw_lines(const std::vector<SDL_Point>& pts) -> Renderer*
|
|
{
|
|
success_or_throw<SDLError>(
|
|
SDL_RenderDrawLines(_data(), pts.data(), (int)pts.size()));
|
|
|
|
return this;
|
|
}
|
|
|
|
auto Renderer::draw_point(const SDL_Point& p) -> Renderer*
|
|
{
|
|
success_or_throw<SDLError>(SDL_RenderDrawPoint(_data(), p.x, p.y));
|
|
|
|
return this;
|
|
}
|
|
|
|
auto Renderer::draw_points(const std::vector<SDL_Point>& pts) -> Renderer*
|
|
{
|
|
success_or_throw<SDLError>(
|
|
SDL_RenderDrawPoints(_data(), pts.data(), (int)pts.size()));
|
|
|
|
return this;
|
|
}
|
|
|
|
auto Renderer::draw_rect(const SDL_Rect* 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(), 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::vector<SDL_Rect>& rs) -> Renderer*
|
|
{
|
|
success_or_throw<SDLError>(SDL_RenderDrawRects(_data(), rs.data(), (int)rs.size()));
|
|
|
|
return this;
|
|
}
|
|
|
|
auto Renderer::fill_rect(const SDL_Rect* r) -> Renderer*
|
|
{
|
|
success_or_throw<SDLError>(SDL_RenderFillRect(_data(), r));
|
|
|
|
return this;
|
|
}
|
|
|
|
auto Renderer::fill_rects(const std::vector<SDL_Rect>& rs) -> Renderer*
|
|
{
|
|
success_or_throw<SDLError>(SDL_RenderFillRects(_data(), rs.data(), (int)rs.size()));
|
|
|
|
return this;
|
|
}
|
|
|
|
auto Renderer::output_size() -> Size
|
|
{
|
|
Size s {};
|
|
success_or_throw<SDLError>(SDL_GetRendererOutputSize(_data(), &s.w, &s.h));
|
|
|
|
return s;
|
|
}
|
|
|
|
void Renderer::present() noexcept
|
|
{
|
|
SDL_RenderPresent(_data());
|
|
}
|
|
|
|
auto Renderer::viewport() noexcept -> SDL_Rect
|
|
{
|
|
SDL_Rect vp;
|
|
SDL_RenderGetViewport(_data(), &vp);
|
|
|
|
return vp;
|
|
}
|
|
|
|
auto Renderer::viewport(const SDL_Rect* vp) -> Renderer*
|
|
{
|
|
success_or_throw<SDLError>(SDL_RenderSetViewport(_data(), vp));
|
|
|
|
return this;
|
|
}
|