Commit c14f126a authored by Florian Oetke's avatar Florian Oetke
Browse files

separated animation and GI test; added renderer debug menus

parent 77b39707
......@@ -10,7 +10,6 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${MIRRAGE_ROOT_DIR}/modules")
enable_language(C CXX ASM GLSL)
# add_definitions(-DHPC_HISTOGRAM_DEBUG_VIEW)
add_definitions(-DGSL_TERMINATE_ON_CONTRACT_VIOLATION)
# LTO
......
......@@ -13,6 +13,7 @@ add_executable(demo ${HEADER_FILES}
src/main.cpp
src/meta_system.cpp
src/test_screen.cpp
src/test_animation_screen.cpp
${BACKWARD_ENABLE}
)
add_backward(demo)
......
......@@ -8,6 +8,7 @@
#define DOCTEST_CONFIG_IMPLEMENT
#include "game_engine.hpp"
#include "test_animation_screen.hpp"
#include "test_screen.hpp"
#include <mirrage/info.hpp>
......@@ -137,9 +138,13 @@ namespace {
global_commands->add("screen.enter.test | Enters the test screen",
[&]() { engine->screens().enter<Test_screen>(); });
global_commands->add("screen.enter.animation_test | Enters the animation test screen",
[&]() { engine->screens().enter<Test_animation_screen>(); });
if(argc > 1 && argv[1] == "test"s)
engine->screens().enter<Test_screen>();
else if(argc > 1 && argv[1] == "animation_test"s)
engine->screens().enter<Test_animation_screen>();
else
engine->screens().enter<Test_screen>();
}
......
#include "test_animation_screen.hpp"
#include <mirrage/ecs/components/transform_comp.hpp>
#include <mirrage/renderer/animation_comp.hpp>
namespace mirrage {
using namespace ecs::components;
using namespace util::unit_literals;
using namespace graphic;
Test_animation_screen::Test_animation_screen(Engine& engine) : Test_screen(engine)
{
_animation_test_dqs = _meta_system.entities().emplace("monk");
_animation_test_dqs.get<Transform_comp>().process([](auto& transform) {
transform.position = {-8, 0, -0.5f - 1.f};
transform.orientation = glm::quatLookAt(glm::vec3{-1, 0, 0}, glm::vec3{0, 1, 0});
});
_animation_test_lbs = _meta_system.entities().emplace("monk_lbs");
_animation_test_lbs.get<Transform_comp>().process([](auto& transform) {
transform.position = {-8, 0, -0.5f + 1.f};
transform.orientation = glm::quatLookAt(glm::vec3{-1, 0, 0}, glm::vec3{0, 1, 0});
});
_animation_test2_dqs = _meta_system.entities().emplace("rotation_test");
_animation_test2_dqs.get<Transform_comp>().process([](auto& transform) {
transform.position = {-4, 0, -0.5f - 1.f};
});
_animation_test2_lbs = _meta_system.entities().emplace("rotation_test_lbs");
_animation_test2_lbs.get<Transform_comp>().process([](auto& transform) {
transform.position = {-4, 0, -0.5f + 1.f};
});
}
void Test_animation_screen::_draw()
{
auto anim_mb = _animation_test_dqs.get<renderer::Simple_animation_controller_comp>();
auto anim_lbs_mb = _animation_test_lbs.get<renderer::Simple_animation_controller_comp>();
if(anim_mb.is_nothing())
return;
auto& anim = anim_mb.get_or_throw();
auto ctx = _gui.ctx();
if(nk_begin_titled(ctx,
"Animation",
"Animation",
_gui.centered_right(300, 500),
NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_TITLE | NK_WINDOW_MINIMIZABLE)) {
nk_layout_row_dynamic(ctx, 20, 1);
nk_label(ctx, "Animation", NK_TEXT_LEFT);
auto animations_strs = std::array<const char*, 9>{
{"[None]", "Attack", "Dance", "Die", "Flee", "Idle", "Sad", "Sleep", "Walk"}};
auto animations_ids = std::array<util::Str_id, 9>{{""_strid,
"attack"_strid,
"dance"_strid,
"die"_strid,
"flee"_strid,
"idle"_strid,
"sad"_strid,
"sleep"_strid,
"walk"_strid}};
(void) animations_ids;
auto curr_animation_id = anim.animation_id().get_or(""_strid);
auto curr_idx =
std::distance(animations_ids.begin(),
std::find(animations_ids.begin(), animations_ids.end(), curr_animation_id));
auto new_idx = nk_combo(ctx,
animations_strs.data(),
animations_strs.size(),
int(curr_idx),
14,
nk_vec2(100.f, 200));
if(new_idx != curr_idx) {
anim.play(animations_ids.at(std::size_t(new_idx)));
anim_lbs_mb.process([&](auto& anim) { anim.play(animations_ids.at(std::size_t(new_idx))); });
}
anim.animation().process([&](auto& curr_animation) {
auto& dqs_anim = _animation_test_dqs.get<renderer::Animation_comp>().get_or_throw();
auto& dqs_states = dqs_anim.states();
auto& lbs_anim = _animation_test_lbs.get<renderer::Animation_comp>().get_or_throw();
auto& lbs_states = lbs_anim.states();
auto time = 0.f;
auto curr_dqs_state = std::find_if(dqs_states.begin(), dqs_states.end(), [&](auto& s) {
return &*s.animation == &*curr_animation;
});
auto curr_lbs_state = std::find_if(lbs_states.begin(), lbs_states.end(), [&](auto& s) {
return &*s.animation == &*curr_animation;
});
if(curr_dqs_state != dqs_states.end()) {
time = curr_dqs_state->time;
} else if(curr_lbs_state != lbs_states.end()) {
time = curr_dqs_state->time;
}
auto duration = curr_animation->duration();
nk_label(ctx, "Time", NK_TEXT_LEFT);
auto new_time = nk_slide_float(ctx, 0.f, time, duration, 0.01f);
if(std::abs(new_time - time) > 0.00001f) {
dqs_anim.mark_dirty();
lbs_anim.mark_dirty();
if(curr_dqs_state != dqs_states.end())
curr_dqs_state->time = new_time;
if(curr_lbs_state != lbs_states.end())
curr_lbs_state->time = new_time;
}
nk_label(ctx,
(util::to_string(new_time) + " / " + util::to_string(duration)).c_str(),
NK_TEXT_LEFT);
auto speed = anim.speed();
nk_property_float(ctx, "Speed", 0.f, &speed, 5.f, 0.1f, 0.05f);
anim.speed(speed);
if(anim.paused())
anim.pause(!nk_button_label(ctx, "Continue"));
else
anim.pause(nk_button_label(ctx, "Pause"));
if(anim.reversed())
anim.reverse(!nk_button_label(ctx, "Reverse (->)"));
else
anim.reverse(nk_button_label(ctx, "Reverse (<-)"));
if(anim.looped())
anim.loop(!nk_button_label(ctx, "Once"));
else
anim.loop(nk_button_label(ctx, "Repeat"));
anim_lbs_mb.process([&](auto& anim_lbs) {
anim_lbs.speed(anim.speed());
anim_lbs.pause(anim.paused());
anim_lbs.reverse(anim.reversed());
anim_lbs.loop(anim.looped());
});
});
}
nk_label(ctx, "Rotation Test", NK_TEXT_LEFT);
_animation_test2_dqs.get<renderer::Simple_animation_controller_comp>().process([&](auto& anim) {
if(anim.paused())
anim.pause(!nk_button_label(ctx, "Continue"));
else
anim.pause(nk_button_label(ctx, "Pause"));
_animation_test2_lbs.get<renderer::Simple_animation_controller_comp>().process(
[&](auto& anim_lbs) { anim_lbs.pause(anim.paused()); });
});
nk_end(ctx);
Test_screen::_draw();
}
} // namespace mirrage
/** The main menu ************************************************************
* *
* Copyright (c) 2016 Florian Oetke *
* This file is distributed under the MIT License *
* See LICENSE file for details. *
\*****************************************************************************/
#pragma once
#include "test_screen.hpp"
#include <mirrage/engine.hpp>
#include <mirrage/gui/gui.hpp>
#include <mirrage/renderer/deferred_renderer.hpp>
#include <mirrage/utils/maybe.hpp>
namespace mirrage {
class Test_animation_screen : public Test_screen {
public:
Test_animation_screen(Engine& engine);
auto name() const -> std::string override { return "Test_animation"; }
protected:
void _draw() override;
auto _prev_screen_policy() const noexcept -> Prev_screen_policy override
{
return Prev_screen_policy::discard;
}
private:
ecs::Entity_facet _animation_test_dqs;
ecs::Entity_facet _animation_test_lbs;
ecs::Entity_facet _animation_test2_dqs;
ecs::Entity_facet _animation_test2_lbs;
};
} // namespace mirrage
......@@ -9,10 +9,6 @@
#include <mirrage/renderer/model_comp.hpp>
#include <mirrage/renderer/pass/gui_pass.hpp>
#ifdef HPC_HISTOGRAM_DEBUG_VIEW
#include <mirrage/renderer/pass/tone_mapping_pass.hpp>
#endif
#include <mirrage/ecs/components/transform_comp.hpp>
#include <mirrage/graphic/window.hpp>
#include <mirrage/gui/gui.hpp>
......@@ -82,36 +78,7 @@ namespace mirrage {
, _meta_system(static_cast<Game_engine&>(engine))
, _gui(engine.gui())
, _performance_log(util::nothing)
, _window_width(engine.window().width())
, _window_height(engine.window().height())
, _window_fullscreen(engine.window().fullscreen() != graphic::Fullscreen::no)
{
_animation_test_dqs = _meta_system.entities().emplace("monk");
_animation_test_dqs.get<Transform_comp>().process([](auto& transform) {
transform.position = {-8, 0, -0.5f - 1.f};
transform.orientation = glm::quatLookAt(glm::vec3{-1, 0, 0}, glm::vec3{0, 1, 0});
});
_animation_test_lbs = _meta_system.entities().emplace("monk_lbs");
_animation_test_lbs.get<Transform_comp>().process([](auto& transform) {
transform.position = {-8, 0, -0.5f + 1.f};
transform.orientation = glm::quatLookAt(glm::vec3{-1, 0, 0}, glm::vec3{0, 1, 0});
});
_animation_test2_dqs = _meta_system.entities().emplace("rotation_test");
_animation_test2_dqs.get<Transform_comp>().process([](auto& transform) {
transform.position = {-4, 0, -0.5f - 1.f};
});
_animation_test2_lbs = _meta_system.entities().emplace("rotation_test_lbs");
_animation_test2_lbs.get<Transform_comp>().process([](auto& transform) {
transform.position = {-4, 0, -0.5f + 1.f};
});
_camera = _meta_system.entities().emplace("camera");
auto cornell = _meta_system.entities().emplace("cornell");
......@@ -348,8 +315,6 @@ namespace mirrage {
{
if(_show_ui) {
_draw_settings_window();
_draw_histogram_window();
_draw_animation_window();
}
_meta_system.renderer().debug_draw({renderer::Debug_geometry{{0, 1, 0}, {0, 5, 0}, {1, 0, 0}},
......@@ -363,7 +328,7 @@ namespace mirrage {
if(nk_begin_titled(ctx,
"debug_controls",
"Debug Controls",
_gui.centered_left(250, 720),
_gui.centered_left(250, 220),
NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_TITLE | NK_WINDOW_MINIMIZABLE)) {
nk_layout_row_dynamic(ctx, 20, 2);
......@@ -431,313 +396,10 @@ namespace mirrage {
nk_layout_row_dynamic(ctx, 10, 1);
nk_label(ctx, "", NK_TEXT_LEFT);
nk_layout_row_dynamic(ctx, 20, 1);
nk_label(ctx, "Graphic Settings", NK_TEXT_LEFT);
auto renderer_settings = _meta_system.renderer().settings();
auto bool_nk_wrapper = 0;
nk_property_int(ctx, "Window Width", 640, &_window_width, 7680, 1, 1);
nk_property_int(ctx, "Window Height", 360, &_window_height, 4320, 1, 1);
bool_nk_wrapper = _window_fullscreen ? 1 : 0;
nk_checkbox_label(ctx, "Fullscreen", &bool_nk_wrapper);
_window_fullscreen = bool_nk_wrapper == 1;
if(nk_button_label(ctx, "Apply")) {
if(_window_width != _engine.window().width() || _window_height != _engine.window().height()
|| _window_fullscreen != (_engine.window().fullscreen() != graphic::Fullscreen::no)) {
_engine.window().dimensions(_window_width,
_window_height,
_window_fullscreen ? graphic::Fullscreen::yes_borderless
: graphic::Fullscreen::no);
}
}
nk_layout_row_dynamic(ctx, 10, 1);
nk_label(ctx, "", NK_TEXT_LEFT);
nk_layout_row_dynamic(ctx, 20, 1);
nk_label(ctx, "Renderer Settings", NK_TEXT_LEFT);
nk_layout_row_dynamic(ctx, 20, 1);
nk_property_int(ctx, "Debug Layer", -1, &renderer_settings.debug_gi_layer, 10, 1, 1);
bool_nk_wrapper = renderer_settings.gi ? 1 : 0;
nk_checkbox_label(ctx, "Indirect Illumination", &bool_nk_wrapper);
renderer_settings.gi = bool_nk_wrapper == 1;
bool_nk_wrapper = renderer_settings.gi_shadows ? 1 : 0;
nk_checkbox_label(ctx, "Indirect Shadows", &bool_nk_wrapper);
renderer_settings.gi_shadows = bool_nk_wrapper == 1;
bool_nk_wrapper = renderer_settings.gi_highres ? 1 : 0;
nk_checkbox_label(ctx, "High-Resolution GI", &bool_nk_wrapper);
renderer_settings.gi_highres = bool_nk_wrapper == 1;
nk_property_int(ctx, "Minimum GI MIP", 0, &renderer_settings.gi_min_mip_level, 4, 1, 1);
nk_property_int(ctx, "Diffuse GI MIP", 0, &renderer_settings.gi_diffuse_mip_level, 4, 1, 1);
nk_property_int(ctx, "Low-Res Sample Count", 8, &renderer_settings.gi_lowres_samples, 1024, 1, 1);
nk_property_int(ctx, "Sample Count", 8, &renderer_settings.gi_samples, 1024, 1, 1);
nk_property_float(
ctx, "Exposure", 0.f, &renderer_settings.exposure_override, 50.f, 0.001f, 0.01f);
nk_property_float(
ctx, "Background Brightness", 0.f, &renderer_settings.background_intensity, 10.f, 1, 0.1f);
bool_nk_wrapper = renderer_settings.ssao ? 1 : 0;
nk_checkbox_label(ctx, "Ambient Occlusion", &bool_nk_wrapper);
renderer_settings.ssao = bool_nk_wrapper == 1;
bool_nk_wrapper = renderer_settings.bloom ? 1 : 0;
nk_checkbox_label(ctx, "Bloom", &bool_nk_wrapper);
renderer_settings.bloom = bool_nk_wrapper == 1;
bool_nk_wrapper = renderer_settings.tonemapping ? 1 : 0;
nk_checkbox_label(ctx, "Tonemapping", &bool_nk_wrapper);
renderer_settings.tonemapping = bool_nk_wrapper == 1;
nk_layout_row_dynamic(ctx, 20, 2);
if(nk_button_label(ctx, "Apply")) {
if(_window_width != _engine.window().width() || _window_height != _engine.window().height()
|| _window_fullscreen != (_engine.window().fullscreen() != graphic::Fullscreen::no)) {
_engine.window().dimensions(_window_width,
_window_height,
_window_fullscreen ? graphic::Fullscreen::yes_borderless
: graphic::Fullscreen::no);
}
_meta_system.renderer().settings(renderer_settings, true);
} else {
_meta_system.renderer().settings(renderer_settings, false);
}
if(nk_button_label(ctx, "Reset")) {
_meta_system.renderer().settings(renderer::Renderer_settings{}, true);
}
}
nk_end(ctx);
}
void Test_screen::_draw_histogram_window()
{
#ifdef HPC_HISTOGRAM_DEBUG_VIEW
auto tone_mapping_pass = _meta_system.renderer().find_pass<renderer::Tone_mapping_pass>();
if(tone_mapping_pass) {
auto&& histogram = tone_mapping_pass->last_histogram();
auto histogram_sum = std::accumulate(begin(histogram), end(histogram) - 2, 0.0);
auto max_histogram = std::max_element(begin(histogram), end(histogram) - 2);
auto ctx = _gui.ctx();
if(nk_begin_titled(
ctx,
"Histogram",
"Histogram",
_gui.centered_right(400, 600),
NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_TITLE | NK_WINDOW_MINIMIZABLE)) {
nk_layout_row_dynamic(ctx, 400, 1);
nk_chart_begin(
ctx, NK_CHART_COLUMN, static_cast<int>(histogram.size() - 2), 0, *max_histogram);
for(auto i : util::range(histogram.size() - 1)) {
auto state = nk_chart_push(ctx, histogram[i]);
if(state & NK_CHART_HOVERING) {
_last_selected_histogram = i;
}
}
nk_chart_end(ctx);
nk_layout_row_dynamic(ctx, 25, 2);
nk_label(ctx, "Luminance", NK_TEXT_CENTERED);
auto log_lum_range = std::log(_meta_system.renderer().gbuffer().max_luminance)
- std::log(_meta_system.renderer().gbuffer().min_luminance);
auto log_lum = float(_last_selected_histogram) / float(histogram.size() - 1) * log_lum_range
+ std::log(_meta_system.renderer().gbuffer().min_luminance);
auto lum = std::exp(log_lum);
nk_label(ctx, to_fixed_str(lum, 5).c_str(), NK_TEXT_CENTERED);
auto percentage = static_cast<double>(histogram[_last_selected_histogram])
/ std::max(1.0, histogram_sum);
nk_label(ctx, "Percentage", NK_TEXT_CENTERED);
nk_label(ctx, (to_fixed_str(percentage * 100, 4) + " %").c_str(), NK_TEXT_CENTERED);
nk_label(ctx, "La", NK_TEXT_CENTERED);
nk_label(ctx, (to_fixed_str(histogram[histogram.size() - 2], 4)).c_str(), NK_TEXT_CENTERED);
nk_label(ctx, "p(La)", NK_TEXT_CENTERED);
nk_label(ctx,
(to_fixed_str(1.f - histogram[histogram.size() - 1], 4)).c_str(),
NK_TEXT_CENTERED);
nk_label(ctx, "Trimmings", NK_TEXT_CENTERED);
nk_label(ctx,
std::to_string(
static_cast<int>(tone_mapping_pass->max_histogram_size() - histogram_sum))
.c_str(),
NK_TEXT_CENTERED);
auto renderer_settings = _meta_system.renderer().settings();
nk_property_float(ctx,
"Min Display Lum.",
1.f / 255.f / 4.f,
&renderer_settings.min_display_luminance,
500.f,
0.001f,
0.01f);
nk_property_float(ctx,
"Max Display Lum.",
1.f / 255.f / 4.f,
&renderer_settings.max_display_luminance,
500.f,
0.001f,
0.01f);
_meta_system.renderer().settings(renderer_settings, false);
}
nk_end(ctx);
}
#endif
}
void Test_screen::_draw_animation_window()
{
auto anim_mb = _animation_test_dqs.get<renderer::Simple_animation_controller_comp>();
auto anim_lbs_mb = _animation_test_lbs.get<renderer::Simple_animation_controller_comp>();
if(anim_mb.is_nothing())
return;
auto& anim = anim_mb.get_or_throw();
auto ctx = _gui.ctx();
if(nk_begin_titled(ctx,
"Animation",
"Animation",
_gui.centered_right(300, 500),
NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_TITLE | NK_WINDOW_MINIMIZABLE)) {
nk_layout_row_dynamic(ctx, 20, 1);
nk_label(ctx, "Animation", NK_TEXT_LEFT);
auto animations_strs = std::array<const char*, 9>{
{"[None]", "Attack", "Dance", "Die", "Flee", "Idle", "Sad", "Sleep", "Walk"}};
auto animations_ids = std::array<util::Str_id, 9>{{""_strid,
"attack"_strid,
"dance"_strid,
"die"_strid,
"flee"_strid,
"idle"_strid,
"sad"_strid,
"sleep"_strid,
"walk"_strid}};
(void) animations_ids;
auto curr_animation_id = anim.animation_id().get_or(""_strid);
auto curr_idx =
std::distance(animations_ids.begin(),
std::find(animations_ids.begin(), animations_ids.end(), curr_animation_id));
auto new_idx = nk_combo(ctx,
animations_strs.data(),
animations_strs.size(),
int(curr_idx),
14,
nk_vec2(100.f, 200));
if(new_idx != curr_idx) {
anim.play(animations_ids.at(std::size_t(new_idx)));
anim_lbs_mb.process([&](auto& anim) { anim.play(animations_ids.at(std::size_t(new_idx))); });
}
anim.animation().process([&](auto& curr_animation) {
auto& dqs_anim = _animation_test_dqs.get<renderer::Animation_comp>().get_or_throw();
auto& dqs_states = dqs_anim.states();
auto& lbs_anim = _animation_test_lbs.get<renderer::Animation_comp>().get_or_throw();
auto& lbs_states = lbs_anim.states();
auto time = 0.f;
auto curr_dqs_state = std::find_if(dqs_states.begin(), dqs_states.end(), [&](auto& s) {
return &*s.animation == &*curr_animation;
});
auto curr_lbs_state = std::find_if(lbs_states.begin(), lbs_states.end(), [&](auto& s) {
return &*s.animation == &*curr_animation;
});
if(curr_dqs_state != dqs_states.end()) {
time = curr_dqs_state->time;
} else if(curr_lbs_state != lbs_states.end()) {
time = curr_dqs_state->time;
}
auto duration = curr_animation->duration();
nk_label(ctx, "Time", NK_TEXT_LEFT);
auto new_time = nk_slide_float(ctx, 0.f, time, duration, 0.01f);
if(std::abs(new_time - time) > 0.00001f) {
dqs_anim.mark_dirty();
lbs_anim.mark_dirty();
if(curr_dqs_state != dqs_states.end())
curr_dqs_state->time = new_time;
if(curr_lbs_state != lbs_states.end())
curr_lbs_state->time = new_time;
}
nk_label(ctx,
(util::to_string(new_time) + " / " + util::to_string(duration)).c_str(),
NK_TEXT_LEFT);
auto speed = anim.speed();
nk_property_float(ctx, "Speed", 0.f, &speed, 5.f, 0.1f, 0.05f);
anim.speed(speed);
if(anim.paused())
anim.pause(!nk_button_label(ctx, "Continue"));
else
anim.pause(nk_button_label