From ff415be341c96d4f21e0581b4a400e690d59dcf7 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 27 Jan 2020 04:51:30 +0700 Subject: [PATCH] normalized camera viewport property --- headers/enduro2d/high/components/camera.hpp | 10 ++-- samples/bin/library/scenes/sample_04.json | 52 ++++++++++++++++++- .../high_binds/components/camera_binds.cpp | 4 +- sources/enduro2d/high/components/camera.cpp | 25 +++++++-- .../enduro2d/high/systems/frame_system.cpp | 21 ++++++-- .../render_system_drawer.cpp | 15 +++++- 6 files changed, 109 insertions(+), 18 deletions(-) diff --git a/headers/enduro2d/high/components/camera.hpp b/headers/enduro2d/high/components/camera.hpp index 8ce8e40c..f22ccc3b 100644 --- a/headers/enduro2d/high/components/camera.hpp +++ b/headers/enduro2d/high/components/camera.hpp @@ -21,19 +21,19 @@ namespace e2d camera() = default; camera& depth(i32 value) noexcept; - camera& viewport(const b2u& value) noexcept; + camera& viewport(const b2f& value) noexcept; camera& projection(const m4f& value) noexcept; camera& target(const render_target_ptr& value) noexcept; camera& background(const color& value) noexcept; [[nodiscard]] i32 depth() const noexcept; - [[nodiscard]] const b2u& viewport() const noexcept; + [[nodiscard]] const b2f& viewport() const noexcept; [[nodiscard]] const m4f& projection() const noexcept; [[nodiscard]] const render_target_ptr& target() const noexcept; [[nodiscard]] const color& background() const noexcept; private: i32 depth_ = 0; - b2u viewport_ = b2u::zero(); + b2f viewport_ = b2f::unit(); m4f projection_ = m4f::identity(); render_target_ptr target_ = nullptr; color background_ = color::clear(); @@ -89,7 +89,7 @@ namespace e2d return *this; } - inline camera& camera::viewport(const b2u& value) noexcept { + inline camera& camera::viewport(const b2f& value) noexcept { viewport_ = value; return *this; } @@ -113,7 +113,7 @@ namespace e2d return depth_; } - inline const b2u& camera::viewport() const noexcept { + inline const b2f& camera::viewport() const noexcept { return viewport_; } diff --git a/samples/bin/library/scenes/sample_04.json b/samples/bin/library/scenes/sample_04.json index 012d0001..45cc963e 100644 --- a/samples/bin/library/scenes/sample_04.json +++ b/samples/bin/library/scenes/sample_04.json @@ -3,7 +3,57 @@ "scene" : {} }, "children" : [{ - "prototype" : "../prefabs/camera_prefab.json" + "prototype" : "../prefabs/camera_prefab.json", + "components" : { + "actor" : { + "rotation" : 0.5 + }, + "camera" : { + "viewport" : [0.0,0.0,0.5,0.5] + }, + "named" : { + "name" : "camera(1)" + } + } + },{ + "prototype" : "../prefabs/camera_prefab.json", + "components" : { + "actor" : { + "rotation" : -0.5 + }, + "camera" : { + "viewport" : [0.5,0.0,0.5,0.5] + }, + "named" : { + "name" : "camera(2)" + } + } + },{ + "prototype" : "../prefabs/camera_prefab.json", + "components" : { + "actor" : { + "rotation" : 0.5 + }, + "camera" : { + "viewport" : [0.5,0.5,0.5,0.5] + }, + "named" : { + "name" : "camera(3)" + } + } + },{ + "prototype" : "../prefabs/camera_prefab.json", + "components" : { + "actor" : { + "rotation" : -0.5 + }, + "camera" : { + "viewport" : [0.0,0.5,0.5,0.5] + }, + "named" : { + "name" : "camera(4)" + } + } },{ "prototype" : "../prefabs/gnome_prefab.json", "components" : { diff --git a/sources/enduro2d/high/bindings/high_binds/components/camera_binds.cpp b/sources/enduro2d/high/bindings/high_binds/components/camera_binds.cpp index fadae356..ba40cb70 100644 --- a/sources/enduro2d/high/bindings/high_binds/components/camera_binds.cpp +++ b/sources/enduro2d/high/bindings/high_binds/components/camera_binds.cpp @@ -60,10 +60,10 @@ namespace e2d::bindings::high "viewport", sol::property( [](const gcomponent& c) -> b2f { - return c->viewport().cast_to(); + return c->viewport(); }, [](gcomponent& c, const b2f& v){ - c->viewport(v.cast_to()); + c->viewport(v); }), "projection", sol::property( diff --git a/sources/enduro2d/high/components/camera.cpp b/sources/enduro2d/high/components/camera.cpp index 1523f91e..da1bf114 100644 --- a/sources/enduro2d/high/components/camera.cpp +++ b/sources/enduro2d/high/components/camera.cpp @@ -25,7 +25,7 @@ namespace e2d const fill_context& ctx) const { if ( ctx.root.HasMember("depth") ) { - auto depth = component.depth(); + i32 depth = component.depth(); if ( !json_utils::try_parse_value(ctx.root["depth"], depth) ) { the().error("CAMERA: Incorrect formatting of 'depth' property"); return false; @@ -34,7 +34,7 @@ namespace e2d } if ( ctx.root.HasMember("viewport") ) { - auto viewport = component.viewport(); + b2f viewport = component.viewport(); if ( !json_utils::try_parse_value(ctx.root["viewport"], viewport) ) { the().error("CAMERA: Incorrect formatting of 'viewport' property"); return false; @@ -43,7 +43,7 @@ namespace e2d } if ( ctx.root.HasMember("projection") ) { - auto projection = component.projection(); + m4f projection = component.projection(); if ( !json_utils::try_parse_value(ctx.root["projection"], projection) ) { the().error("CAMERA: Incorrect formatting of 'projection' property"); return false; @@ -56,7 +56,7 @@ namespace e2d } if ( ctx.root.HasMember("background") ) { - auto background = component.background(); + color background = component.background(); if ( !json_utils::try_parse_value(ctx.root["background"], background) ) { the().error("CAMERA: Incorrect formatting of 'background' property"); return false; @@ -123,7 +123,22 @@ namespace e2d c->depth(depth); } - ///TODO(BlackMat): add 'viewport' inspector + if ( ImGui::TreeNode("viewport") ) { + E2D_DEFER([](){ ImGui::TreePop(); }); + + if ( b2f viewport = c->viewport(); + ImGui::DragFloat2("position", viewport.position.data(), 0.01f) ) + { + c->viewport(viewport); + } + + if ( b2f viewport = c->viewport(); + ImGui::DragFloat2("size", viewport.size.data(), 0.01f) ) + { + c->viewport(viewport); + } + } + ///TODO(BlackMat): add 'projection' inspector ///TODO(BlackMat): add 'target' inspector diff --git a/sources/enduro2d/high/systems/frame_system.cpp b/sources/enduro2d/high/systems/frame_system.cpp index 9efb36bf..e3186f8a 100644 --- a/sources/enduro2d/high/systems/frame_system.cpp +++ b/sources/enduro2d/high/systems/frame_system.cpp @@ -13,6 +13,15 @@ namespace { using namespace e2d; + void clear_framebuffer(render& render, window& window) { + render.execute(render::command_block<3>() + .add_command(render::target_command()) + .add_command(render::viewport_command( + window.framebuffer_size().cast_to())) + .add_command(render::clear_command() + .color_value(color::black()))); + } + template < typename Event > void for_all_cameras(ecs::registry& owner) { const auto comp = [](const auto& l, const auto& r) noexcept { @@ -42,8 +51,10 @@ namespace e2d class frame_system::internal_state final : private noncopyable { public: - internal_state(engine& e) - : engine_(e) {} + internal_state(engine& e, render& r, window& w) + : engine_(e) + , render_(r) + , window_(w) {} ~internal_state() noexcept = default; void process_frame_update(ecs::registry& owner) { @@ -67,6 +78,8 @@ namespace e2d } void process_frame_render(ecs::registry& owner) { + clear_framebuffer(render_, window_); + { E2D_PROFILER_SCOPE("ecs.pre_render"); for_all_cameras(owner); @@ -84,6 +97,8 @@ namespace e2d } private: engine& engine_; + render& render_; + window& window_; }; // @@ -91,7 +106,7 @@ namespace e2d // frame_system::frame_system() - : state_(new internal_state(the())) {} + : state_(new internal_state(the(), the(), the())) {} frame_system::~frame_system() noexcept = default; void frame_system::process( diff --git a/sources/enduro2d/high/systems/render_system_impl/render_system_drawer.cpp b/sources/enduro2d/high/systems/render_system_impl/render_system_drawer.cpp index 97ac41c2..e85d47ca 100644 --- a/sources/enduro2d/high/systems/render_system_impl/render_system_drawer.cpp +++ b/sources/enduro2d/high/systems/render_system_impl/render_system_drawer.cpp @@ -69,9 +69,20 @@ namespace e2d::render_system_impl .property(matrix_vp_property_hash, m_v * m_p) .property(time_property_hash, engine.time()); + const v2u target_size = cam.target() + ? cam.target()->size() + : window.framebuffer_size(); + + const b2f target_viewport = make_rect( + cam.viewport().position * target_size.cast_to(), + cam.viewport().size * target_size.cast_to()); + render.execute(render::command_block<3>() - .add_command(render::target_command(cam.target())) - .add_command(render::viewport_command(cam.viewport())) + .add_command(render::target_command( + cam.target())) + .add_command(render::viewport_command( + target_viewport.cast_to(), + target_viewport.cast_to())) .add_command(render::clear_command() .color_value(cam.background()))); }