@@ -6,14 +6,25 @@
#include <GL/glew.h>
namespace gfx {
#include <array>
OpenGLCanvas::OpenGLCanvas() {
namespace gfx {
namespace {
#include "gfx/basic_vertex_shader.h"
#include "gfx/rect_fragment_shader.h"
std::string_view const vertex_shader{reinterpret_cast<char const *>(gfx_basic_shader_vert), gfx_basic_shader_vert_len};
std::string_view const fragment_shader{reinterpret_cast<char const *>(gfx_rect_shader_frag), gfx_rect_shader_frag_len};
} // namespace
OpenGLCanvas::OpenGLCanvas() : border_shader_{OpenGLShader::create(vertex_shader, fragment_shader).value()} {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
void OpenGLCanvas::set_viewport_size(int width, int height) {
size_x_ = width;
size_y_ = height;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, height, 0, -1.0, 1.0);
@@ -34,4 +45,52 @@ void OpenGLCanvas::fill_rect(geom::Rect const &rect, Color color) {
glRecti(scaled.x, scaled.y, scaled.x + scaled.width, scaled.y + scaled.height);
}
void OpenGLCanvas::draw_rect(
geom::Rect const &rect, Color const &color, Borders const &borders, Corners const &corners) {
auto translated{rect.translated(translation_x_, translation_y_)};
auto inner_rect{translated.scaled(scale_)};
auto outer_rect{
inner_rect.expanded({borders.left.size, borders.right.size, borders.top.size, borders.bottom.size})};
static constexpr auto kToArr2 = [](int a, int b) {
return std::array<float, 2>{static_cast<float>(a), static_cast<float>(b)};
};
static constexpr auto kToColorArr = [](gfx::Color c) {
return std::array<float, 4>{static_cast<float>(c.r) / 255.f,
static_cast<float>(c.g) / 255.f,
static_cast<float>(c.b) / 255.f,
static_cast<float>(c.a) / 255.f};
};
border_shader_.enable();
border_shader_.set_uniform("resolution", kToArr2(size_x_, size_y_));
border_shader_.set_uniform("inner_top_left", kToArr2(inner_rect.left(), inner_rect.top()));
border_shader_.set_uniform("inner_top_right", kToArr2(inner_rect.right(), inner_rect.top()));
border_shader_.set_uniform("inner_bottom_left", kToArr2(inner_rect.left(), inner_rect.bottom()));
border_shader_.set_uniform("inner_bottom_right", kToArr2(inner_rect.right(), inner_rect.bottom()));
border_shader_.set_uniform("outer_top_left", kToArr2(outer_rect.left(), outer_rect.top()));
border_shader_.set_uniform("outer_top_right", kToArr2(outer_rect.right(), outer_rect.top()));
border_shader_.set_uniform("outer_bottom_left", kToArr2(outer_rect.left(), outer_rect.bottom()));
border_shader_.set_uniform("outer_bottom_right", kToArr2(outer_rect.right(), outer_rect.bottom()));
border_shader_.set_uniform("top_left_radii", kToArr2(corners.top_left.horizontal, corners.top_left.vertical));
border_shader_.set_uniform("top_right_radii", kToArr2(corners.top_right.horizontal, corners.top_right.vertical));
border_shader_.set_uniform(
"bottom_left_radii", kToArr2(corners.bottom_left.horizontal, corners.bottom_left.vertical));
border_shader_.set_uniform(
"bottom_right_radii", kToArr2(corners.bottom_right.horizontal, corners.bottom_right.vertical));
border_shader_.set_uniform("left_border_color", kToColorArr(borders.left.color));
border_shader_.set_uniform("right_border_color", kToColorArr(borders.right.color));
border_shader_.set_uniform("top_border_color", kToColorArr(borders.top.color));
border_shader_.set_uniform("bottom_border_color", kToColorArr(borders.bottom.color));
border_shader_.set_uniform("inner_rect_color", kToColorArr(color));
glRecti(outer_rect.left(), outer_rect.top(), outer_rect.right(), outer_rect.bottom());
border_shader_.disable();
}
} // namespace gfx