mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-14 16:09:06 +07:00
render command_block
This commit is contained in:
@@ -182,7 +182,7 @@ namespace e2d
|
|||||||
attribute_type type,
|
attribute_type type,
|
||||||
bool normalized) noexcept;
|
bool normalized) noexcept;
|
||||||
|
|
||||||
const attribute_info& attribute(std::size_t i) const noexcept;
|
const attribute_info& attribute(std::size_t index) const noexcept;
|
||||||
std::size_t attribute_count() const noexcept;
|
std::size_t attribute_count() const noexcept;
|
||||||
std::size_t bytes_per_vertex() const noexcept;
|
std::size_t bytes_per_vertex() const noexcept;
|
||||||
private:
|
private:
|
||||||
@@ -708,6 +708,118 @@ namespace e2d
|
|||||||
topology topology_ = topology::triangles;
|
topology topology_ = topology::triangles;
|
||||||
u8 _pad[7] = {0};
|
u8 _pad[7] = {0};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class swap_command final {
|
||||||
|
public:
|
||||||
|
swap_command() = default;
|
||||||
|
swap_command(bool vsync);
|
||||||
|
swap_command& vsync(bool value) noexcept;
|
||||||
|
bool& vsync() noexcept;
|
||||||
|
bool vsync() const noexcept;
|
||||||
|
private:
|
||||||
|
bool vsync_ = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
class draw_command final {
|
||||||
|
public:
|
||||||
|
draw_command() = delete;
|
||||||
|
draw_command(const material& mat, const geometry& geo) noexcept;
|
||||||
|
|
||||||
|
draw_command& material_ref(const material& value) noexcept;
|
||||||
|
draw_command& geometry_ref(const geometry& value) noexcept;
|
||||||
|
|
||||||
|
const material& material_ref() const noexcept;
|
||||||
|
const geometry& geometry_ref() const noexcept;
|
||||||
|
|
||||||
|
draw_command& properties(const property_block& value);
|
||||||
|
property_block& properties() noexcept;
|
||||||
|
const property_block& properties() const noexcept;
|
||||||
|
private:
|
||||||
|
const material* material_ = nullptr;
|
||||||
|
const geometry* geometry_ = nullptr;
|
||||||
|
property_block properties_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class clear_command final {
|
||||||
|
public:
|
||||||
|
enum class buffer : u8 {
|
||||||
|
color = (1 << 0),
|
||||||
|
depth = (1 << 1),
|
||||||
|
stencil = (1 << 2),
|
||||||
|
color_depth = color | depth,
|
||||||
|
color_stencil = color | stencil,
|
||||||
|
depth_stencil = depth | stencil,
|
||||||
|
color_depth_stencil = color | depth | stencil
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
clear_command() = default;
|
||||||
|
clear_command(buffer clear_buffer) noexcept;
|
||||||
|
|
||||||
|
clear_command& color_value(const color& value) noexcept;
|
||||||
|
clear_command& depth_value(f32 value) noexcept;
|
||||||
|
clear_command& stencil_value(u8 value) noexcept;
|
||||||
|
|
||||||
|
color& color_value() noexcept;
|
||||||
|
f32& depth_value() noexcept;
|
||||||
|
u8& stencil_value() noexcept;
|
||||||
|
|
||||||
|
const color& color_value() const noexcept;
|
||||||
|
f32 depth_value() const noexcept;
|
||||||
|
u8 stencil_value() const noexcept;
|
||||||
|
|
||||||
|
buffer& clear_buffer() noexcept;
|
||||||
|
buffer clear_buffer() const noexcept;
|
||||||
|
private:
|
||||||
|
color color_value_ = color::clear();
|
||||||
|
f32 depth_value_ = 1.f;
|
||||||
|
u8 stencil_value_ = 0;
|
||||||
|
buffer clear_buffer_ = buffer::color_depth_stencil;
|
||||||
|
u8 _pad[2] = {0};
|
||||||
|
};
|
||||||
|
|
||||||
|
class viewport_command final {
|
||||||
|
public:
|
||||||
|
viewport_command() = default;
|
||||||
|
viewport_command(const b2u& rect) noexcept;
|
||||||
|
viewport_command& rect(const b2u& value) noexcept;
|
||||||
|
b2u& rect() noexcept;
|
||||||
|
const b2u& rect() const noexcept;
|
||||||
|
private:
|
||||||
|
b2u rect_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class render_target_command final {
|
||||||
|
public:
|
||||||
|
render_target_command() = default;
|
||||||
|
render_target_command(const render_target_ptr& rt) noexcept;
|
||||||
|
render_target_command& render_target(const render_target_ptr& value) noexcept;
|
||||||
|
render_target_ptr& render_target() noexcept;
|
||||||
|
const render_target_ptr& render_target() const noexcept;
|
||||||
|
private:
|
||||||
|
render_target_ptr render_target_;
|
||||||
|
};
|
||||||
|
|
||||||
|
using command_value = stdex::variant<
|
||||||
|
swap_command,
|
||||||
|
draw_command,
|
||||||
|
clear_command,
|
||||||
|
viewport_command,
|
||||||
|
render_target_command>;
|
||||||
|
|
||||||
|
template < std::size_t N >
|
||||||
|
class command_block final {
|
||||||
|
public:
|
||||||
|
command_block() = default;
|
||||||
|
|
||||||
|
command_block& clear() noexcept;
|
||||||
|
command_block& add_command(command_value&& value);
|
||||||
|
command_block& add_command(const command_value& value);
|
||||||
|
const command_value& command(std::size_t index) const noexcept;
|
||||||
|
std::size_t command_count() const noexcept;
|
||||||
|
private:
|
||||||
|
array<command_value, N> commands_;
|
||||||
|
std::size_t command_count_ = 0;
|
||||||
|
};
|
||||||
public:
|
public:
|
||||||
render(debug& d, window& w);
|
render(debug& d, window& w);
|
||||||
~render() noexcept final;
|
~render() noexcept final;
|
||||||
@@ -746,20 +858,15 @@ namespace e2d
|
|||||||
const pixel_declaration& depth_decl,
|
const pixel_declaration& depth_decl,
|
||||||
render_target::external_texture external_texture);
|
render_target::external_texture external_texture);
|
||||||
|
|
||||||
void draw(
|
template < std::size_t N >
|
||||||
const material& mat,
|
render& execute(const command_block<N>& commands);
|
||||||
const geometry& geo);
|
render& execute(const command_value& command);
|
||||||
|
|
||||||
void draw(
|
render& execute(const swap_command& command);
|
||||||
const material& mat,
|
render& execute(const draw_command& command);
|
||||||
const geometry& geo,
|
render& execute(const clear_command& command);
|
||||||
const property_block& props);
|
render& execute(const viewport_command& command);
|
||||||
|
render& execute(const render_target_command& command);
|
||||||
render& clear_depth_buffer(f32 value) noexcept;
|
|
||||||
render& clear_stencil_buffer(u8 value) noexcept;
|
|
||||||
render& clear_color_buffer(const color& value) noexcept;
|
|
||||||
render& set_viewport(const b2u& rect) noexcept;
|
|
||||||
render& set_render_target(const render_target_ptr& rt) noexcept;
|
|
||||||
private:
|
private:
|
||||||
class internal_state;
|
class internal_state;
|
||||||
std::unique_ptr<internal_state> state_;
|
std::unique_ptr<internal_state> state_;
|
||||||
|
|||||||
@@ -106,6 +106,59 @@ namespace e2d
|
|||||||
stdex::invoke(f, p.first, p.second);
|
stdex::invoke(f, p.first, p.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// render::command_block
|
||||||
|
//
|
||||||
|
|
||||||
|
template < std::size_t N >
|
||||||
|
render::command_block<N>& render::command_block<N>::clear() noexcept {
|
||||||
|
commands_.clear();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < std::size_t N >
|
||||||
|
render::command_block<N>& render::command_block<N>::add_command(command_value&& value) {
|
||||||
|
E2D_ASSERT(command_count_ < commands_.size());
|
||||||
|
commands_[command_count_] = std::move(value);
|
||||||
|
++command_count_;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < std::size_t N >
|
||||||
|
render::command_block<N>& render::command_block<N>::add_command(const command_value& value) {
|
||||||
|
E2D_ASSERT(command_count_ < commands_.size());
|
||||||
|
commands_[command_count_] = value;
|
||||||
|
++command_count_;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < std::size_t N >
|
||||||
|
const render::command_value& render::command_block<N>::command(std::size_t index) const noexcept {
|
||||||
|
E2D_ASSERT(index < command_count_);
|
||||||
|
return commands_[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
template < std::size_t N >
|
||||||
|
std::size_t render::command_block<N>::command_count() const noexcept {
|
||||||
|
return command_count_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// render
|
||||||
|
//
|
||||||
|
|
||||||
|
template < std::size_t N >
|
||||||
|
render& render::execute(const command_block<N>& commands) {
|
||||||
|
E2D_ASSERT(
|
||||||
|
std::this_thread::get_id() ==
|
||||||
|
modules::main_thread<render>());
|
||||||
|
|
||||||
|
for ( std::size_t i = 0; i < commands.command_count(); ++i ) {
|
||||||
|
execute(commands.command(i));
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -180,11 +180,10 @@ int e2d_main() {
|
|||||||
.property("u_time", game_time)
|
.property("u_time", game_time)
|
||||||
.property("u_MVP", projection);
|
.property("u_MVP", projection);
|
||||||
|
|
||||||
the<render>()
|
the<render>().execute(render::command_block<64>()
|
||||||
.clear_depth_buffer(1.f)
|
.add_command(render::clear_command()
|
||||||
.clear_stencil_buffer(0)
|
.color_value({1.f, 0.4f, 0.f, 1.f}))
|
||||||
.clear_color_buffer({1.f, 0.4f, 0.f, 1.f})
|
.add_command(render::draw_command(material, geometry)));
|
||||||
.draw(material, geometry);
|
|
||||||
|
|
||||||
the<window>().swap_buffers(true);
|
the<window>().swap_buffers(true);
|
||||||
the<input>().frame_tick();
|
the<input>().frame_tick();
|
||||||
|
|||||||
@@ -247,11 +247,10 @@ int e2d_main() {
|
|||||||
.property("u_time", game_time)
|
.property("u_time", game_time)
|
||||||
.property("u_MVP", MVP);
|
.property("u_MVP", MVP);
|
||||||
|
|
||||||
the<render>()
|
the<render>().execute(render::command_block<64>()
|
||||||
.clear_depth_buffer(1.f)
|
.add_command(render::clear_command()
|
||||||
.clear_stencil_buffer(0)
|
.color_value({1.f, 0.4f, 0.f, 1.f}))
|
||||||
.clear_color_buffer({1.f, 0.4f, 0.f, 1.f})
|
.add_command(render::draw_command(material, geometry)));
|
||||||
.draw(material, geometry);
|
|
||||||
|
|
||||||
the<window>().swap_buffers(true);
|
the<window>().swap_buffers(true);
|
||||||
the<input>().frame_tick();
|
the<input>().frame_tick();
|
||||||
|
|||||||
@@ -205,37 +205,32 @@ int e2d_main() {
|
|||||||
.property("u_time", game_time)
|
.property("u_time", game_time)
|
||||||
.property("u_MVP", MVP);
|
.property("u_MVP", MVP);
|
||||||
|
|
||||||
material.properties()
|
the<render>().execute(render::command_block<64>()
|
||||||
.sampler("u_texture", render::sampler_state()
|
.add_command(render::render_target_command(rt))
|
||||||
.texture(texture)
|
.add_command(render::viewport_command(rt->size()))
|
||||||
.min_filter(render::sampler_min_filter::linear)
|
.add_command(render::clear_command()
|
||||||
.mag_filter(render::sampler_mag_filter::linear));
|
.color_value({0.f, 0.4f, 0.f, 1.f}))
|
||||||
|
.add_command(render::draw_command(material, geometry)
|
||||||
|
.properties(render::property_block()
|
||||||
|
.sampler("u_texture", render::sampler_state()
|
||||||
|
.texture(texture)
|
||||||
|
.min_filter(render::sampler_min_filter::linear)
|
||||||
|
.mag_filter(render::sampler_mag_filter::linear))))
|
||||||
|
.add_command(render::render_target_command(nullptr))
|
||||||
|
.add_command(render::viewport_command(the<window>().real_size()))
|
||||||
|
.add_command(render::clear_command()
|
||||||
|
.color_value({1.f, 0.4f, 0.f, 1.f}))
|
||||||
|
.add_command(render::draw_command(material, geometry)
|
||||||
|
.properties(render::property_block()
|
||||||
|
.sampler("u_texture", render::sampler_state()
|
||||||
|
.texture(rt->color())
|
||||||
|
.min_filter(render::sampler_min_filter::linear)
|
||||||
|
.mag_filter(render::sampler_mag_filter::linear))))
|
||||||
|
.add_command(render::swap_command(true)));
|
||||||
|
|
||||||
the<render>()
|
std::this_thread::sleep_for(
|
||||||
.set_render_target(rt)
|
time::to_chrono(make_milliseconds(10)));
|
||||||
.set_viewport(rt->size())
|
|
||||||
.clear_depth_buffer(1.f)
|
|
||||||
.clear_stencil_buffer(0)
|
|
||||||
.clear_color_buffer({0.f, 0.4f, 0.f, 1.f})
|
|
||||||
.draw(material, geometry);
|
|
||||||
|
|
||||||
material.properties()
|
|
||||||
.sampler("u_texture", render::sampler_state()
|
|
||||||
.texture(rt->color())
|
|
||||||
.min_filter(render::sampler_min_filter::linear)
|
|
||||||
.mag_filter(render::sampler_mag_filter::linear));
|
|
||||||
|
|
||||||
the<render>()
|
|
||||||
.set_render_target(nullptr)
|
|
||||||
.set_viewport(the<window>().real_size())
|
|
||||||
.clear_depth_buffer(1.f)
|
|
||||||
.clear_stencil_buffer(0)
|
|
||||||
.clear_color_buffer({1.f, 0.4f, 0.f, 1.f})
|
|
||||||
.draw(material, geometry);
|
|
||||||
|
|
||||||
std::this_thread::sleep_for(time::to_chrono(make_milliseconds(10)));
|
|
||||||
|
|
||||||
the<window>().swap_buffers(true);
|
|
||||||
the<input>().frame_tick();
|
the<input>().frame_tick();
|
||||||
window::poll_events();
|
window::poll_events();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,34 @@ namespace
|
|||||||
}
|
}
|
||||||
#undef DEFINE_CASE
|
#undef DEFINE_CASE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class command_value_visitor final : private noncopyable {
|
||||||
|
public:
|
||||||
|
command_value_visitor(render& render) noexcept
|
||||||
|
: render_(render) {}
|
||||||
|
|
||||||
|
void operator()(const render::swap_command& command) const {
|
||||||
|
render_.execute(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(const render::draw_command& command) const {
|
||||||
|
render_.execute(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(const render::clear_command& command) const {
|
||||||
|
render_.execute(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(const render::viewport_command& command) const {
|
||||||
|
render_.execute(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(const render::render_target_command& command) const {
|
||||||
|
render_.execute(command);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
render& render_;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace e2d
|
namespace e2d
|
||||||
@@ -199,9 +227,9 @@ namespace e2d
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
const vertex_declaration::attribute_info& vertex_declaration::attribute(std::size_t i) const noexcept {
|
const vertex_declaration::attribute_info& vertex_declaration::attribute(std::size_t index) const noexcept {
|
||||||
E2D_ASSERT(i < attribute_count_);
|
E2D_ASSERT(index < attribute_count_);
|
||||||
return attributes_[i];
|
return attributes_[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t vertex_declaration::attribute_count() const noexcept {
|
std::size_t vertex_declaration::attribute_count() const noexcept {
|
||||||
@@ -828,4 +856,173 @@ namespace e2d
|
|||||||
E2D_ASSERT(index < vertices_count_);
|
E2D_ASSERT(index < vertices_count_);
|
||||||
return vertices_[index];
|
return vertices_[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// swap_command
|
||||||
|
//
|
||||||
|
|
||||||
|
render::swap_command::swap_command(bool vsync)
|
||||||
|
: vsync_(vsync) {}
|
||||||
|
|
||||||
|
render::swap_command& render::swap_command::vsync(bool value) noexcept {
|
||||||
|
vsync_ = value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool& render::swap_command::vsync() noexcept {
|
||||||
|
return vsync_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool render::swap_command::vsync() const noexcept {
|
||||||
|
return vsync_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// draw_command
|
||||||
|
//
|
||||||
|
|
||||||
|
render::draw_command::draw_command(const material& mat, const geometry& geo) noexcept
|
||||||
|
: material_(&mat)
|
||||||
|
, geometry_(&geo) {}
|
||||||
|
|
||||||
|
render::draw_command& render::draw_command::material_ref(const material& value) noexcept {
|
||||||
|
material_ = &value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
render::draw_command& render::draw_command::geometry_ref(const geometry& value) noexcept {
|
||||||
|
geometry_ = &value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const render::material& render::draw_command::material_ref() const noexcept {
|
||||||
|
E2D_ASSERT(material_);
|
||||||
|
return *material_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const render::geometry& render::draw_command::geometry_ref() const noexcept {
|
||||||
|
E2D_ASSERT(geometry_);
|
||||||
|
return *geometry_;
|
||||||
|
}
|
||||||
|
|
||||||
|
render::draw_command& render::draw_command::properties(const property_block& value) {
|
||||||
|
properties_ = value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
render::property_block& render::draw_command::properties() noexcept {
|
||||||
|
return properties_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const render::property_block& render::draw_command::properties() const noexcept {
|
||||||
|
return properties_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// clear_command
|
||||||
|
//
|
||||||
|
|
||||||
|
render::clear_command::clear_command(buffer clear_buffer) noexcept
|
||||||
|
: clear_buffer_(clear_buffer) {}
|
||||||
|
|
||||||
|
render::clear_command& render::clear_command::color_value(const color& value) noexcept {
|
||||||
|
color_value_ = value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
render::clear_command& render::clear_command::depth_value(f32 value) noexcept {
|
||||||
|
depth_value_ = value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
render::clear_command& render::clear_command::stencil_value(u8 value) noexcept {
|
||||||
|
stencil_value_ = value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
color& render::clear_command::color_value() noexcept {
|
||||||
|
return color_value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
f32& render::clear_command::depth_value() noexcept {
|
||||||
|
return depth_value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8& render::clear_command::stencil_value() noexcept {
|
||||||
|
return stencil_value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const color& render::clear_command::color_value() const noexcept {
|
||||||
|
return color_value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
f32 render::clear_command::depth_value() const noexcept {
|
||||||
|
return depth_value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 render::clear_command::stencil_value() const noexcept {
|
||||||
|
return stencil_value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
render::clear_command::buffer& render::clear_command::clear_buffer() noexcept {
|
||||||
|
return clear_buffer_;
|
||||||
|
}
|
||||||
|
|
||||||
|
render::clear_command::buffer render::clear_command::clear_buffer() const noexcept {
|
||||||
|
return clear_buffer_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// viewport_command
|
||||||
|
//
|
||||||
|
|
||||||
|
render::viewport_command::viewport_command(const b2u& rect) noexcept
|
||||||
|
: rect_(rect) {}
|
||||||
|
|
||||||
|
render::viewport_command& render::viewport_command::rect(const b2u& value) noexcept {
|
||||||
|
rect_ = value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
b2u& render::viewport_command::rect() noexcept {
|
||||||
|
return rect_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const b2u& render::viewport_command::rect() const noexcept {
|
||||||
|
return rect_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// render_target_command
|
||||||
|
//
|
||||||
|
|
||||||
|
render::render_target_command::render_target_command(const render_target_ptr& rt) noexcept
|
||||||
|
: render_target_(rt) {}
|
||||||
|
|
||||||
|
render::render_target_command& render::render_target_command::render_target(const render_target_ptr& value) noexcept {
|
||||||
|
render_target_ = value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
render_target_ptr& render::render_target_command::render_target() noexcept {
|
||||||
|
return render_target_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const render_target_ptr& render::render_target_command::render_target() const noexcept {
|
||||||
|
return render_target_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// render
|
||||||
|
//
|
||||||
|
|
||||||
|
render& render::execute(const command_value& command) {
|
||||||
|
E2D_ASSERT(
|
||||||
|
std::this_thread::get_id() ==
|
||||||
|
modules::main_thread<render>());
|
||||||
|
|
||||||
|
E2D_ASSERT(!command.valueless_by_exception());
|
||||||
|
stdex::visit(command_value_visitor(*this), command);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace
|
|||||||
|
|
||||||
class property_block_value_visitor : private noncopyable {
|
class property_block_value_visitor : private noncopyable {
|
||||||
public:
|
public:
|
||||||
property_block_value_visitor(debug& debug, uniform_info ui)
|
property_block_value_visitor(debug& debug, uniform_info ui) noexcept
|
||||||
: debug_(debug)
|
: debug_(debug)
|
||||||
, ui_(std::move(ui)) {}
|
, ui_(std::move(ui)) {}
|
||||||
|
|
||||||
@@ -768,26 +768,24 @@ namespace e2d
|
|||||||
std::move(depth_rb)));
|
std::move(depth_rb)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void render::draw(
|
render& render::execute(const swap_command& command) {
|
||||||
const material& mat,
|
|
||||||
const geometry& geo)
|
|
||||||
{
|
|
||||||
E2D_ASSERT(
|
E2D_ASSERT(
|
||||||
std::this_thread::get_id() ==
|
std::this_thread::get_id() ==
|
||||||
modules::main_thread<render>());
|
modules::main_thread<render>());
|
||||||
|
|
||||||
draw(mat, geo, property_block());
|
state_->wnd().swap_buffers(command.vsync());
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void render::draw(
|
render& render::execute(const draw_command& command) {
|
||||||
const material& mat,
|
|
||||||
const geometry& geo,
|
|
||||||
const property_block& props)
|
|
||||||
{
|
|
||||||
E2D_ASSERT(
|
E2D_ASSERT(
|
||||||
std::this_thread::get_id() ==
|
std::this_thread::get_id() ==
|
||||||
modules::main_thread<render>());
|
modules::main_thread<render>());
|
||||||
|
|
||||||
|
const material& mat = command.material_ref();
|
||||||
|
const geometry& geo = command.geometry_ref();
|
||||||
|
const property_block& props = command.properties();
|
||||||
|
|
||||||
for ( std::size_t i = 0; i < mat.pass_count(); ++i ) {
|
for ( std::size_t i = 0; i < mat.pass_count(); ++i ) {
|
||||||
const pass_state& pass = mat.pass(i);
|
const pass_state& pass = mat.pass(i);
|
||||||
const property_block& main_props = main_property_cache()
|
const property_block& main_props = main_property_cache()
|
||||||
@@ -802,59 +800,59 @@ namespace e2d
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
render& render::clear_depth_buffer(f32 value) noexcept {
|
|
||||||
E2D_ASSERT(
|
|
||||||
std::this_thread::get_id() ==
|
|
||||||
modules::main_thread<render>());
|
|
||||||
|
|
||||||
const render_target_ptr& rt = state_->render_target();
|
|
||||||
if ( !rt || rt->state().depth() || !rt->state().depth_rb().empty() ) {
|
|
||||||
GL_CHECK_CODE(state_->dbg(), glClearDepth(
|
|
||||||
math::numeric_cast<GLclampd>(math::saturate(value))));
|
|
||||||
GL_CHECK_CODE(state_->dbg(), glClear(GL_DEPTH_BUFFER_BIT));
|
|
||||||
}
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
render& render::clear_stencil_buffer(u8 value) noexcept {
|
render& render::execute(const clear_command& command) {
|
||||||
E2D_ASSERT(
|
E2D_ASSERT(
|
||||||
std::this_thread::get_id() ==
|
std::this_thread::get_id() ==
|
||||||
modules::main_thread<render>());
|
modules::main_thread<render>());
|
||||||
|
|
||||||
const render_target_ptr& rt = state_->render_target();
|
bool clear_color =
|
||||||
if ( !rt || rt->state().depth() || !rt->state().depth_rb().empty() ) {
|
math::enum_to_number(command.clear_buffer())
|
||||||
GL_CHECK_CODE(state_->dbg(), glClearStencil(
|
& math::enum_to_number(clear_command::buffer::color);
|
||||||
math::numeric_cast<GLint>(value)));
|
bool clear_depth =
|
||||||
GL_CHECK_CODE(state_->dbg(), glClear(GL_STENCIL_BUFFER_BIT));
|
math::enum_to_number(command.clear_buffer())
|
||||||
}
|
& math::enum_to_number(clear_command::buffer::depth);
|
||||||
return *this;
|
bool clear_stencil =
|
||||||
}
|
math::enum_to_number(command.clear_buffer())
|
||||||
|
& math::enum_to_number(clear_command::buffer::stencil);
|
||||||
render& render::clear_color_buffer(const color& value) noexcept {
|
|
||||||
E2D_ASSERT(
|
|
||||||
std::this_thread::get_id() ==
|
|
||||||
modules::main_thread<render>());
|
|
||||||
|
|
||||||
const render_target_ptr& rt = state_->render_target();
|
const render_target_ptr& rt = state_->render_target();
|
||||||
if ( !rt || rt->state().color() || !rt->state().color_rb().empty() ) {
|
bool has_color = !rt || rt->state().color() || !rt->state().color_rb().empty();
|
||||||
|
bool has_depth = !rt || rt->state().depth() || !rt->state().depth_rb().empty();
|
||||||
|
|
||||||
|
GLbitfield clear_mask = 0;
|
||||||
|
if ( has_color && clear_color ) {
|
||||||
|
clear_mask |= GL_COLOR_BUFFER_BIT;
|
||||||
GL_CHECK_CODE(state_->dbg(), glClearColor(
|
GL_CHECK_CODE(state_->dbg(), glClearColor(
|
||||||
math::numeric_cast<GLclampf>(math::saturate(value.r)),
|
math::numeric_cast<GLclampf>(math::saturate(command.color_value().r)),
|
||||||
math::numeric_cast<GLclampf>(math::saturate(value.g)),
|
math::numeric_cast<GLclampf>(math::saturate(command.color_value().g)),
|
||||||
math::numeric_cast<GLclampf>(math::saturate(value.b)),
|
math::numeric_cast<GLclampf>(math::saturate(command.color_value().b)),
|
||||||
math::numeric_cast<GLclampf>(math::saturate(value.a))));
|
math::numeric_cast<GLclampf>(math::saturate(command.color_value().a))));
|
||||||
GL_CHECK_CODE(state_->dbg(), glClear(GL_COLOR_BUFFER_BIT));
|
|
||||||
}
|
}
|
||||||
|
if ( has_depth ) {
|
||||||
|
if ( clear_depth ) {
|
||||||
|
clear_mask |= GL_DEPTH_BUFFER_BIT;
|
||||||
|
GL_CHECK_CODE(state_->dbg(), glClearDepth(
|
||||||
|
math::numeric_cast<GLclampd>(math::saturate(command.depth_value()))));
|
||||||
|
}
|
||||||
|
if ( clear_stencil ) {
|
||||||
|
clear_mask |= GL_STENCIL_BUFFER_BIT;
|
||||||
|
GL_CHECK_CODE(state_->dbg(), glClearStencil(
|
||||||
|
math::numeric_cast<GLint>(command.stencil_value())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GL_CHECK_CODE(state_->dbg(), glClear(clear_mask));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
render& render::set_viewport(const b2u& rect) noexcept {
|
render& render::execute(const viewport_command& command) {
|
||||||
E2D_ASSERT(
|
E2D_ASSERT(
|
||||||
std::this_thread::get_id() ==
|
std::this_thread::get_id() ==
|
||||||
modules::main_thread<render>());
|
modules::main_thread<render>());
|
||||||
|
|
||||||
const b2u vp = make_minmax_rect(rect);
|
const b2u vp = make_minmax_rect(command.rect());
|
||||||
GL_CHECK_CODE(state_->dbg(), glViewport(
|
GL_CHECK_CODE(state_->dbg(), glViewport(
|
||||||
math::numeric_cast<GLint>(vp.position.x),
|
math::numeric_cast<GLint>(vp.position.x),
|
||||||
math::numeric_cast<GLint>(vp.position.y),
|
math::numeric_cast<GLint>(vp.position.y),
|
||||||
@@ -863,12 +861,12 @@ namespace e2d
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
render& render::set_render_target(const render_target_ptr& rt) noexcept {
|
render& render::execute(const render_target_command& command) {
|
||||||
E2D_ASSERT(
|
E2D_ASSERT(
|
||||||
std::this_thread::get_id() ==
|
std::this_thread::get_id() ==
|
||||||
modules::main_thread<render>());
|
modules::main_thread<render>());
|
||||||
|
|
||||||
state_->set_render_target(rt);
|
state_->set_render_target(command.render_target());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user