Add a simple colored renderer
This commit is contained in:
parent
4e37e7a54f
commit
e42c5dc054
2 changed files with 183 additions and 0 deletions
54
libs/gfx/include/psemek/gfx/renderer/simple.hpp
Normal file
54
libs/gfx/include/psemek/gfx/renderer/simple.hpp
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#pragma once
|
||||
|
||||
#include <psemek/gfx/drawable.hpp>
|
||||
#include <psemek/gfx/color.hpp>
|
||||
#include <psemek/geom/matrix.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace psemek::gfx
|
||||
{
|
||||
|
||||
struct simple_renderer
|
||||
{
|
||||
// Attributes:
|
||||
// 0: vec3 position
|
||||
// 1: vec4 color (if uniform color is not set)
|
||||
|
||||
struct render_state
|
||||
{
|
||||
drawable const * mesh = nullptr;
|
||||
std::optional<color_rgba> color;
|
||||
};
|
||||
|
||||
struct render_object
|
||||
{
|
||||
virtual std::vector<render_state> get_render_states() = 0;
|
||||
|
||||
virtual ~render_object() {}
|
||||
};
|
||||
|
||||
struct render_options
|
||||
{
|
||||
geom::matrix<float, 4, 4> transform;
|
||||
};
|
||||
|
||||
simple_renderer();
|
||||
~simple_renderer();
|
||||
|
||||
void add(render_object * o);
|
||||
void remove(render_object * o);
|
||||
|
||||
void push(render_state s);
|
||||
|
||||
void render(render_options const & opts);
|
||||
|
||||
private:
|
||||
struct impl;
|
||||
std::unique_ptr<struct impl> pimpl_;
|
||||
struct impl & impl() { return *pimpl_; }
|
||||
struct impl const & impl() const { return *pimpl_; }
|
||||
};
|
||||
|
||||
}
|
||||
129
libs/gfx/source/renderer/simple.cpp
Normal file
129
libs/gfx/source/renderer/simple.cpp
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
#include <psemek/gfx/renderer/simple.hpp>
|
||||
|
||||
#include <psemek/gfx/program.hpp>
|
||||
|
||||
namespace psemek::gfx
|
||||
{
|
||||
|
||||
static char const attrib_color_vertex_source[] =
|
||||
R"(#version 330
|
||||
|
||||
uniform mat4 u_transform;
|
||||
|
||||
layout (location = 0) in vec4 in_position;
|
||||
layout (location = 1) in vec4 in_color;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = u_transform * in_position;
|
||||
color = in_color;
|
||||
}
|
||||
)";
|
||||
|
||||
static char const uniform_color_vertex_source[] =
|
||||
R"(#version 330
|
||||
|
||||
uniform mat4 u_transform;
|
||||
uniform vec4 u_color;
|
||||
|
||||
layout (location = 0) in vec4 in_position;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = u_transform * in_position;
|
||||
color = u_color;
|
||||
}
|
||||
)";
|
||||
|
||||
static char const fragment_source[] =
|
||||
R"(#version 330
|
||||
|
||||
in vec4 color;
|
||||
out vec4 out_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
out_color = color;
|
||||
}
|
||||
)";
|
||||
|
||||
struct simple_renderer::impl
|
||||
{
|
||||
program attrib_color_program{attrib_color_vertex_source, fragment_source};
|
||||
program uniform_color_program{uniform_color_vertex_source, fragment_source};
|
||||
|
||||
std::vector<render_object *> objects;
|
||||
std::vector<render_state> attrib_color_states;
|
||||
std::vector<render_state> uniform_color_states;
|
||||
};
|
||||
|
||||
simple_renderer::simple_renderer()
|
||||
: pimpl_{std::make_unique<struct impl>()}
|
||||
{}
|
||||
|
||||
simple_renderer::~simple_renderer() = default;
|
||||
|
||||
void simple_renderer::add(render_object * o)
|
||||
{
|
||||
impl().objects.push_back(o);
|
||||
}
|
||||
|
||||
void simple_renderer::remove(render_object * o)
|
||||
{
|
||||
auto it = std::find(impl().objects.begin(), impl().objects.end(), o);
|
||||
if (it != impl().objects.end())
|
||||
impl().objects.erase(it);
|
||||
}
|
||||
|
||||
void simple_renderer::push(render_state s)
|
||||
{
|
||||
if (s.mesh)
|
||||
{
|
||||
if (s.color)
|
||||
impl().uniform_color_states.push_back(s);
|
||||
else
|
||||
impl().attrib_color_states.push_back(s);
|
||||
}
|
||||
}
|
||||
|
||||
void simple_renderer::render(render_options const & opts)
|
||||
{
|
||||
for (auto o : impl().objects)
|
||||
{
|
||||
for (auto const & s : o->get_render_states())
|
||||
push(s);
|
||||
}
|
||||
|
||||
if (!impl().attrib_color_states.empty())
|
||||
{
|
||||
impl().attrib_color_program.bind();
|
||||
impl().attrib_color_program["u_transform"] = opts.transform;
|
||||
|
||||
for (auto const & s : impl().attrib_color_states)
|
||||
{
|
||||
s.mesh->draw();
|
||||
}
|
||||
|
||||
impl().attrib_color_states.clear();
|
||||
}
|
||||
|
||||
if (!impl().uniform_color_states.empty())
|
||||
{
|
||||
impl().uniform_color_program.bind();
|
||||
impl().uniform_color_program["u_transform"] = opts.transform;
|
||||
|
||||
for (auto const & s : impl().uniform_color_states)
|
||||
{
|
||||
impl().uniform_color_program["u_color"] = to_colorf(*s.color);
|
||||
s.mesh->draw();
|
||||
}
|
||||
|
||||
impl().uniform_color_states.clear();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue