srctree

Robin Linden parent 740791ad 5de3b185
gfx/opengl: Support drawing rects w/ borders and corner radii

inlinesplit
gfx/BUILD added: 91, removed: 18, total 73
@@ -18,18 +18,6 @@ cc_library(
],
)
 
cc_library(
name = "opengl",
srcs = ["opengl_canvas.cpp"],
hdrs = ["opengl_canvas.h"],
copts = HASTUR_COPTS,
visibility = ["//visibility:public"],
deps = [
":gfx",
"@glew",
],
)
 
genrule(
name = "basic_vertex_shader",
srcs = ["basic_shader.vert"],
@@ -44,6 +32,26 @@ genrule(
cmd = "xxd -i $< >$@",
)
 
cc_library(
name = "opengl",
srcs = [
"opengl_canvas.cpp",
"opengl_shader.cpp",
":basic_vertex_shader",
":rect_fragment_shader",
],
hdrs = [
"opengl_canvas.h",
"opengl_shader.h",
],
copts = HASTUR_COPTS,
visibility = ["//visibility:public"],
deps = [
":gfx",
"@glew",
],
)
 
cc_library(
name = "sfml",
srcs = [
 
gfx/opengl_canvas.cpp added: 91, removed: 18, total 73
@@ -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
 
gfx/opengl_canvas.h added: 91, removed: 18, total 73
@@ -5,6 +5,8 @@
#ifndef GFX_OPENGL_CANVAS_H_
#define GFX_OPENGL_CANVAS_H_
 
#include "gfx/opengl_shader.h"
 
#include "gfx/icanvas.h"
 
namespace gfx {
@@ -23,11 +25,15 @@ public:
 
void clear(Color) override;
void fill_rect(geom::Rect const &, Color) override;
void draw_rect(geom::Rect const &, Color const &, Borders const &, Corners const &) override {}
void draw_rect(geom::Rect const &, Color const &, Borders const &, Corners const &) override;
void draw_text(geom::Position, std::string_view, std::span<Font const>, FontSize, FontStyle, Color) override {}
void draw_text(geom::Position, std::string_view, Font, FontSize, FontStyle, Color) override {}
 
private:
OpenGLShader border_shader_;
 
int size_x_{};
int size_y_{};
int translation_x_{};
int translation_y_{};
int scale_{1};