126 lines
3.1 KiB
C++
126 lines
3.1 KiB
C++
#include <psemek/ui/painter_impl.hpp>
|
|
|
|
#include <psemek/gfx/program.hpp>
|
|
#include <psemek/gfx/array.hpp>
|
|
#include <psemek/gfx/buffer.hpp>
|
|
|
|
namespace psemek::ui
|
|
{
|
|
|
|
static char const colored_vs[] =
|
|
R"(#version 330
|
|
|
|
uniform mat4 u_transform;
|
|
|
|
layout (location = 0) in vec2 in_position;
|
|
layout (location = 1) in uint in_depth;
|
|
layout (location = 2) in vec4 in_color;
|
|
|
|
out vec4 color;
|
|
|
|
void main()
|
|
{
|
|
gl_Position = u_transform * vec4(in_position, float(in_depth) / 16777216.0 * 2.0 - 1.0, 1.0);
|
|
color = in_color;
|
|
}
|
|
)";
|
|
|
|
static char const colored_fs[] =
|
|
R"(#version 330
|
|
|
|
in vec4 color;
|
|
|
|
out vec4 out_color;
|
|
|
|
void main()
|
|
{
|
|
out_color = color;
|
|
}
|
|
)";
|
|
|
|
struct colored_vertex
|
|
{
|
|
geom::point<float, 2> position;
|
|
std::uint32_t depth;
|
|
gfx::color_rgba color;
|
|
};
|
|
static_assert(sizeof(colored_vertex) == 16);
|
|
|
|
struct painter_impl::impl
|
|
{
|
|
std::shared_ptr<struct font> font;
|
|
std::uint32_t depth = 0;
|
|
|
|
gfx::program colored_program;
|
|
gfx::array colored_vao;
|
|
gfx::buffer colored_vbo;
|
|
gfx::buffer colored_ebo;
|
|
|
|
std::vector<colored_vertex> colored_vertices;
|
|
std::vector<std::uint32_t> colored_indices;
|
|
|
|
impl();
|
|
};
|
|
|
|
painter_impl::impl::impl()
|
|
: colored_program{colored_vs, colored_fs}
|
|
{
|
|
colored_vao.bind();
|
|
colored_vbo.bind();
|
|
gl::EnableVertexAttribArray(0);
|
|
gl::VertexAttribPointer(0, 2, gl::FLOAT, gl::FALSE, sizeof(colored_vertex), reinterpret_cast<void const *>(0));
|
|
gl::EnableVertexAttribArray(1);
|
|
gl::VertexAttribIPointer(1, 1, gl::UNSIGNED_INT, sizeof(colored_vertex), reinterpret_cast<void const *>(8));
|
|
gl::EnableVertexAttribArray(2);
|
|
gl::VertexAttribPointer(2, 4, gl::UNSIGNED_BYTE, gl::TRUE, sizeof(colored_vertex), reinterpret_cast<void const *>(12));
|
|
gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, colored_ebo.id());
|
|
}
|
|
|
|
painter_impl::painter_impl()
|
|
: pimpl_{make_impl()}
|
|
{}
|
|
|
|
painter_impl::~painter_impl() = default;
|
|
|
|
void painter_impl::set_font(std::shared_ptr<struct font> font)
|
|
{
|
|
impl().font = font;
|
|
}
|
|
|
|
font const * painter_impl::font() const
|
|
{
|
|
return impl().font.get();
|
|
}
|
|
|
|
void painter_impl::draw_rect(geom::box<float, 2> const & rect, gfx::color_rgba const & color)
|
|
{
|
|
std::uint32_t const depth = impl().depth++;
|
|
std::uint32_t const base = impl().colored_vertices.size();
|
|
|
|
impl().colored_vertices.push_back({rect.corner(0.f, 0.f), depth, color});
|
|
impl().colored_vertices.push_back({rect.corner(1.f, 0.f), depth, color});
|
|
impl().colored_vertices.push_back({rect.corner(0.f, 1.f), depth, color});
|
|
impl().colored_vertices.push_back({rect.corner(1.f, 1.f), depth, color});
|
|
|
|
impl().colored_indices.insert(impl().colored_indices.end(), {base + 0, base + 1, base + 2, base + 2, base + 1, base + 3});
|
|
}
|
|
|
|
void painter_impl::render(geom::matrix<float, 4, 4> const & transform)
|
|
{
|
|
impl().colored_vbo.load(impl().colored_vertices);
|
|
impl().colored_ebo.load(impl().colored_indices);
|
|
|
|
int const colored_count = impl().colored_indices.size();
|
|
|
|
impl().colored_vertices.clear();
|
|
impl().colored_indices.clear();
|
|
|
|
impl().depth = 0;
|
|
|
|
impl().colored_program.bind();
|
|
impl().colored_program["u_transform"] = transform;
|
|
impl().colored_vao.bind();
|
|
gl::DrawElements(gl::TRIANGLES, colored_count, gl::UNSIGNED_INT, nullptr);
|
|
}
|
|
|
|
}
|