normalized camera viewport property

This commit is contained in:
2020-01-27 04:51:30 +07:00
parent 3c58d83d8c
commit ff415be341
6 changed files with 109 additions and 18 deletions

View File

@@ -21,19 +21,19 @@ namespace e2d
camera() = default; camera() = default;
camera& depth(i32 value) noexcept; camera& depth(i32 value) noexcept;
camera& viewport(const b2u& value) noexcept; camera& viewport(const b2f& value) noexcept;
camera& projection(const m4f& value) noexcept; camera& projection(const m4f& value) noexcept;
camera& target(const render_target_ptr& value) noexcept; camera& target(const render_target_ptr& value) noexcept;
camera& background(const color& value) noexcept; camera& background(const color& value) noexcept;
[[nodiscard]] i32 depth() const 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 m4f& projection() const noexcept;
[[nodiscard]] const render_target_ptr& target() const noexcept; [[nodiscard]] const render_target_ptr& target() const noexcept;
[[nodiscard]] const color& background() const noexcept; [[nodiscard]] const color& background() const noexcept;
private: private:
i32 depth_ = 0; i32 depth_ = 0;
b2u viewport_ = b2u::zero(); b2f viewport_ = b2f::unit();
m4f projection_ = m4f::identity(); m4f projection_ = m4f::identity();
render_target_ptr target_ = nullptr; render_target_ptr target_ = nullptr;
color background_ = color::clear(); color background_ = color::clear();
@@ -89,7 +89,7 @@ namespace e2d
return *this; return *this;
} }
inline camera& camera::viewport(const b2u& value) noexcept { inline camera& camera::viewport(const b2f& value) noexcept {
viewport_ = value; viewport_ = value;
return *this; return *this;
} }
@@ -113,7 +113,7 @@ namespace e2d
return depth_; return depth_;
} }
inline const b2u& camera::viewport() const noexcept { inline const b2f& camera::viewport() const noexcept {
return viewport_; return viewport_;
} }

View File

@@ -3,7 +3,57 @@
"scene" : {} "scene" : {}
}, },
"children" : [{ "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", "prototype" : "../prefabs/gnome_prefab.json",
"components" : { "components" : {

View File

@@ -60,10 +60,10 @@ namespace e2d::bindings::high
"viewport", sol::property( "viewport", sol::property(
[](const gcomponent<camera>& c) -> b2f { [](const gcomponent<camera>& c) -> b2f {
return c->viewport().cast_to<f32>(); return c->viewport();
}, },
[](gcomponent<camera>& c, const b2f& v){ [](gcomponent<camera>& c, const b2f& v){
c->viewport(v.cast_to<u32>()); c->viewport(v);
}), }),
"projection", sol::property( "projection", sol::property(

View File

@@ -25,7 +25,7 @@ namespace e2d
const fill_context& ctx) const const fill_context& ctx) const
{ {
if ( ctx.root.HasMember("depth") ) { if ( ctx.root.HasMember("depth") ) {
auto depth = component.depth(); i32 depth = component.depth();
if ( !json_utils::try_parse_value(ctx.root["depth"], depth) ) { if ( !json_utils::try_parse_value(ctx.root["depth"], depth) ) {
the<debug>().error("CAMERA: Incorrect formatting of 'depth' property"); the<debug>().error("CAMERA: Incorrect formatting of 'depth' property");
return false; return false;
@@ -34,7 +34,7 @@ namespace e2d
} }
if ( ctx.root.HasMember("viewport") ) { if ( ctx.root.HasMember("viewport") ) {
auto viewport = component.viewport(); b2f viewport = component.viewport();
if ( !json_utils::try_parse_value(ctx.root["viewport"], viewport) ) { if ( !json_utils::try_parse_value(ctx.root["viewport"], viewport) ) {
the<debug>().error("CAMERA: Incorrect formatting of 'viewport' property"); the<debug>().error("CAMERA: Incorrect formatting of 'viewport' property");
return false; return false;
@@ -43,7 +43,7 @@ namespace e2d
} }
if ( ctx.root.HasMember("projection") ) { if ( ctx.root.HasMember("projection") ) {
auto projection = component.projection(); m4f projection = component.projection();
if ( !json_utils::try_parse_value(ctx.root["projection"], projection) ) { if ( !json_utils::try_parse_value(ctx.root["projection"], projection) ) {
the<debug>().error("CAMERA: Incorrect formatting of 'projection' property"); the<debug>().error("CAMERA: Incorrect formatting of 'projection' property");
return false; return false;
@@ -56,7 +56,7 @@ namespace e2d
} }
if ( ctx.root.HasMember("background") ) { if ( ctx.root.HasMember("background") ) {
auto background = component.background(); color background = component.background();
if ( !json_utils::try_parse_value(ctx.root["background"], background) ) { if ( !json_utils::try_parse_value(ctx.root["background"], background) ) {
the<debug>().error("CAMERA: Incorrect formatting of 'background' property"); the<debug>().error("CAMERA: Incorrect formatting of 'background' property");
return false; return false;
@@ -123,7 +123,22 @@ namespace e2d
c->depth(depth); 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 'projection' inspector
///TODO(BlackMat): add 'target' inspector ///TODO(BlackMat): add 'target' inspector

View File

@@ -13,6 +13,15 @@ namespace
{ {
using namespace e2d; 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<i32>()))
.add_command(render::clear_command()
.color_value(color::black())));
}
template < typename Event > template < typename Event >
void for_all_cameras(ecs::registry& owner) { void for_all_cameras(ecs::registry& owner) {
const auto comp = [](const auto& l, const auto& r) noexcept { const auto comp = [](const auto& l, const auto& r) noexcept {
@@ -42,8 +51,10 @@ namespace e2d
class frame_system::internal_state final : private noncopyable { class frame_system::internal_state final : private noncopyable {
public: public:
internal_state(engine& e) internal_state(engine& e, render& r, window& w)
: engine_(e) {} : engine_(e)
, render_(r)
, window_(w) {}
~internal_state() noexcept = default; ~internal_state() noexcept = default;
void process_frame_update(ecs::registry& owner) { void process_frame_update(ecs::registry& owner) {
@@ -67,6 +78,8 @@ namespace e2d
} }
void process_frame_render(ecs::registry& owner) { void process_frame_render(ecs::registry& owner) {
clear_framebuffer(render_, window_);
{ {
E2D_PROFILER_SCOPE("ecs.pre_render"); E2D_PROFILER_SCOPE("ecs.pre_render");
for_all_cameras<systems::pre_render_event>(owner); for_all_cameras<systems::pre_render_event>(owner);
@@ -84,6 +97,8 @@ namespace e2d
} }
private: private:
engine& engine_; engine& engine_;
render& render_;
window& window_;
}; };
// //
@@ -91,7 +106,7 @@ namespace e2d
// //
frame_system::frame_system() frame_system::frame_system()
: state_(new internal_state(the<engine>())) {} : state_(new internal_state(the<engine>(), the<render>(), the<window>())) {}
frame_system::~frame_system() noexcept = default; frame_system::~frame_system() noexcept = default;
void frame_system::process( void frame_system::process(

View File

@@ -69,9 +69,20 @@ namespace e2d::render_system_impl
.property(matrix_vp_property_hash, m_v * m_p) .property(matrix_vp_property_hash, m_v * m_p)
.property(time_property_hash, engine.time()); .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<f32>(),
cam.viewport().size * target_size.cast_to<f32>());
render.execute(render::command_block<3>() render.execute(render::command_block<3>()
.add_command(render::target_command(cam.target())) .add_command(render::target_command(
.add_command(render::viewport_command(cam.viewport())) cam.target()))
.add_command(render::viewport_command(
target_viewport.cast_to<i32>(),
target_viewport.cast_to<i32>()))
.add_command(render::clear_command() .add_command(render::clear_command()
.color_value(cam.background()))); .color_value(cam.background())));
} }