bwidgets/src/core/renderer.cpp

159 lines
3.7 KiB
C++
Raw Normal View History

#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-11 15:52:07 +02:00
Renderer::Renderer(SDL_Renderer* r)
2021-08-14 11:50:37 +02:00
: Wrapper {ptr_or_throw<SDLError>(r),
[r](SDL_Renderer*) noexcept { SDL_DestroyRenderer(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-14 11:50:37 +02:00
: Renderer {ptr_or_throw<SDLError>(SDL_CreateRenderer(w, index, flags))}
{}
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
{
SDL_BlendMode mode {};
2021-08-13 22:00:42 +02:00
success_or_throw<SDLError>(SDL_GetRenderDrawBlendMode(_data(), &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-13 22:00:42 +02:00
success_or_throw<SDLError>(SDL_SetRenderDrawBlendMode(_data(), mode));
2021-07-16 17:18:13 +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-13 22:00:42 +02:00
success_or_throw<SDLError>(SDL_RenderClear(_data()));
2021-07-16 17:18:13 +02:00
return this;
2021-07-16 17:18:13 +02:00
}
2021-08-12 16:10:49 +02:00
auto Renderer::copy(const Texture* t, const SDL_Rect* src, const SDL_Rect* dst)
-> Renderer*
2021-07-16 17:18:13 +02:00
{
2021-08-13 22:00:42 +02:00
success_or_throw<SDLError>(SDL_RenderCopy(_data(), t->_data(), src, dst));
2021-07-16 17:18:13 +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>(
SDL_GetRenderDrawColor(_data(), &c().r, &c().g, &c().b, &c().a));
2021-07-16 17:18:13 +02:00
return c;
}
2021-08-06 14:22:56 +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>(
SDL_SetRenderDrawColor(_data(), c().r, c().g, c().b, c().a));
2021-07-16 17:18:13 +02:00
return this;
2021-07-16 17:18:13 +02:00
}
2021-08-06 14:22:56 +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-13 22:00:42 +02:00
success_or_throw<SDLError>(SDL_RenderDrawLine(_data(), a.x, a.y, b.x, b.y));
2021-07-16 17:18:13 +02:00
return this;
2021-07-16 17:18:13 +02:00
}
2021-08-06 14:22:56 +02:00
auto Renderer::draw_lines(const std::vector<SDL_Point>& pts) -> Renderer*
2021-07-16 17:18:13 +02:00
{
2021-08-13 22:00:42 +02:00
success_or_throw<SDLError>(
SDL_RenderDrawLines(_data(), pts.data(), (int)pts.size()));
2021-07-16 17:18:13 +02:00
return this;
2021-07-16 17:18:13 +02:00
}
2021-08-06 14:22:56 +02:00
auto Renderer::draw_point(const SDL_Point& p) -> Renderer*
2021-07-16 17:18:13 +02:00
{
2021-08-13 22:00:42 +02:00
success_or_throw<SDLError>(SDL_RenderDrawPoint(_data(), p.x, p.y));
2021-07-16 17:18:13 +02:00
return this;
2021-07-16 17:18:13 +02:00
}
2021-08-06 14:22:56 +02:00
auto Renderer::draw_points(const std::vector<SDL_Point>& pts) -> Renderer*
2021-07-16 17:18:13 +02:00
{
2021-08-13 22:00:42 +02:00
success_or_throw<SDLError>(
SDL_RenderDrawPoints(_data(), pts.data(), (int)pts.size()));
2021-07-16 17:18:13 +02:00
return this;
2021-07-16 17:18:13 +02:00
}
2021-08-06 14:22:56 +02:00
auto Renderer::draw_rect(const SDL_Rect* r) -> Renderer*
2021-07-16 17:18:13 +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.
if (r != nullptr)
viewport({vp.x + r->x, vp.y + r->y, r->w - 1, r->h - 1}); // crop extra pixel
2021-08-13 22:00:42 +02:00
success_or_throw<SDLError>(SDL_RenderDrawRect(_data(), 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});
else draw_point({vp.w - 1, vp.h - 1});
viewport(vp);
return this;
2021-07-16 17:18:13 +02:00
}
2021-08-06 14:22:56 +02:00
auto Renderer::draw_rects(const std::vector<SDL_Rect>& rs) -> Renderer*
2021-07-16 17:18:13 +02:00
{
2021-08-13 22:00:42 +02:00
success_or_throw<SDLError>(SDL_RenderDrawRects(_data(), rs.data(), (int)rs.size()));
2021-07-16 17:18:13 +02:00
return this;
2021-07-16 17:18:13 +02:00
}
2021-08-06 14:22:56 +02:00
auto Renderer::fill_rect(const SDL_Rect* r) -> Renderer*
2021-07-16 17:18:13 +02:00
{
2021-08-13 22:00:42 +02:00
success_or_throw<SDLError>(SDL_RenderFillRect(_data(), r));
2021-07-16 17:18:13 +02:00
return this;
2021-07-16 17:18:13 +02:00
}
2021-08-06 14:22:56 +02:00
auto Renderer::fill_rects(const std::vector<SDL_Rect>& rs) -> Renderer*
2021-07-16 17:18:13 +02:00
{
2021-08-13 22:00:42 +02:00
success_or_throw<SDLError>(SDL_RenderFillRects(_data(), rs.data(), (int)rs.size()));
2021-07-16 17:18:13 +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
{
Size s {};
2021-08-13 22:00:42 +02:00
success_or_throw<SDLError>(SDL_GetRendererOutputSize(_data(), &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-11 15:52:07 +02:00
SDL_RenderPresent(_data());
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-11 15:52:07 +02:00
SDL_RenderGetViewport(_data(), &vp);
2021-07-16 17:18:13 +02:00
return vp;
}
2021-08-06 14:22:56 +02:00
auto Renderer::viewport(const SDL_Rect* vp) -> Renderer*
2021-07-16 17:18:13 +02:00
{
2021-08-13 22:00:42 +02:00
success_or_throw<SDLError>(SDL_RenderSetViewport(_data(), vp));
2021-07-16 17:18:13 +02:00
return this;
2021-07-16 17:18:13 +02:00
}