Unravel Engine C++ Reference
Loading...
Searching...
No Matches
game_panel.cpp
Go to the documentation of this file.
1#include "game_panel.h"
2#include "../panels_defs.h"
3#include "../../hub.h"
4#include "imgui/imgui.h"
5#include "imgui_widgets/utils.h"
6
7#include <algorithm>
8#include <engine/ecs/ecs.h>
9#include <engine/events.h>
10#include <engine/input/input.h>
16
17
18namespace unravel
19{
20
24
28
30{
31 auto& path = ctx.get_cached<rendering_system>();
32 auto& ec = ctx.get_cached<ecs>();
33 auto& scene = ec.get_scene();
34
35 path.on_frame_update(scene, dt);
36}
37
39{
40 auto& path = ctx.get_cached<rendering_system>();
41 auto& ec = ctx.get_cached<ecs>();
42 auto& scene = ec.get_scene();
43
45}
46
48{
49 if(!is_visible_ && !is_visible_force_)
50 {
51 return;
52 }
53 auto& ec = ctx.get_cached<ecs>();
54 auto& scene = ec.get_scene();
55 auto& path = ctx.get_cached<rendering_system>();
56
57 auto output = path.render_scene(scene, dt);
58 ctx.get_cached<ui_system>().on_frame_render(output, dt);
59
60 is_visible_force_ = false;
61}
62
64{
65 auto& input = ctx.get_cached<input_system>();
66
67 bool allowed = true;
68 if(ImGui::Begin(name, nullptr, ImGuiWindowFlags_MenuBar))
69 {
70 // ImGui::WindowTimeBlock block(ImGui::GetFont(ImGui::Font::Mono));
71
72 set_visible(true);
73 draw_ui(ctx);
74
75 allowed &= ImGui::IsWindowFocused();
76 }
77 else
78 {
79 allowed = false;
80 set_visible(false);
81 }
82 ImGui::End();
83
84 input.manager.set_is_input_allowed(allowed);
85}
86
87void game_panel::set_visible(bool visible)
88{
89 is_visible_ = visible;
90}
91
93{
94 is_visible_force_ = visible;
95}
96
97void game_panel::apply_resolution_to_camera(camera_component& camera_comp, const settings::resolution_settings::resolution& res, ImVec2 avail_size)
98{
99 ImVec2 viewport = avail_size;
100 if(res.aspect == 0.0f)
101 {
102 // Free aspect
103 viewport = avail_size;
104 }
105 else if(res.width > 0 && res.height > 0)
106 {
107 // Fixed resolution
108 viewport.x = static_cast<float>(res.width);
109 viewport.y = static_cast<float>(res.height);
110 }
111 else if(res.aspect > 0.0f)
112 {
113 float avail_aspect = avail_size.x / std::max(avail_size.y, 1.0f);
114 if(avail_aspect > res.aspect)
115 {
116 viewport.y = avail_size.y;
117 viewport.x = avail_size.y * res.aspect;
118 }
119 else
120 {
121 viewport.x = avail_size.x;
122 viewport.y = avail_size.x / res.aspect;
123 }
124 }
125 camera_comp.set_viewport_size({static_cast<std::uint32_t>(viewport.x), static_cast<std::uint32_t>(viewport.y)});
126}
127
128void game_panel::draw_ui(rtti::context& ctx)
129{
130 if(!ctx.has<unravel::settings>())
131 {
132 return;
133 }
134
135 draw_menubar(ctx);
136 auto& ec = ctx.get_cached<ecs>();
137 auto& ev = ctx.get_cached<events>();
138 auto size = ImGui::GetContentRegionAvail();
139 auto& settings = ctx.get<unravel::settings>();
140 if(settings.resolution.resolutions.empty())
141 {
142 return;
143 }
144 const auto& resolutions = settings.resolution.resolutions;
145 current_resolution_index_ = settings.resolution.get_current_resolution_index();
146 if(size.x > 0 && size.y > 0)
147 {
148 bool rendered = false;
149 ec.get_scene().registry->view<camera_component>().each(
150 [&](auto e, auto&& camera_comp)
151 {
152 apply_resolution_to_camera(camera_comp, resolutions[std::clamp(current_resolution_index_, 0, (int)resolutions.size()-1)], size);
153
154 const auto& camera = camera_comp.get_camera();
155 const auto& rview = camera_comp.get_render_view();
156 const auto& obuffer = rview.fbo_safe_get("OBUFFER");
157
158 if(obuffer)
159 {
160 auto tex = obuffer->get_texture(0);
161 auto tex_size = obuffer->get_size();
162 ImVec2 tex_size_v(tex_size.width, tex_size.height);
163 ImGui::ImageWithAspect(ImGui::ToId(tex), tex_size_v, size, ImVec2(0.5f, 0.5f));
164
165 ImVec2 min = ImGui::GetItemRectMin();
166 ImVec2 max = ImGui::GetItemRectMax();
167
168 input::zone work_zone{};
169 work_zone.x = min.x;
170 work_zone.y = min.y;
171 work_zone.w = max.x - min.x;
172 work_zone.h = max.y - min.y;
173
174
175 ctx.get_cached<input_system>().manager.set_work_zone(work_zone);
176 ctx.get_cached<input_system>().manager.set_reference_size({tex_size_v.x, tex_size_v.y});
177
178 if(ev.is_playing)
179 {
180 ImVec2 padding(2.0f, 2.0f);
181 ImGui::RenderFocusFrame(ImGui::GetItemRectMin() - padding, ImGui::GetItemRectMax() + padding);
182 }
183 rendered = true;
184
185 camera_comp.get_pipeline_data().get_pipeline()->set_debug_pass(visualize_passes_);
186 }
187 });
188
189 if(!rendered)
190 {
191 static const auto text = "No cameras rendering";
192 ImGui::SetCursorPosY(size.y * 0.5f);
193 ImGui::AlignedItem(0.5f,
194 size.x,
195 ImGui::CalcTextSize(text).x,
196 []()
197 {
198 ImGui::TextUnformatted(text);
199 });
200 }
201 }
202}
203
204void game_panel::draw_menubar(rtti::context& ctx)
205{
206 auto& pm = ctx.get_cached<project_manager>();
207 auto& settings = pm.get_settings();
208 if(settings.resolution.resolutions.empty())
209 {
210 return;
211 }
212 const auto& resolutions = settings.resolution.resolutions;
213 current_resolution_index_ = settings.resolution.get_current_resolution_index();
214 if(ImGui::BeginMenuBar())
215 {
217 {
218 ImGui::RadioButton("Full", &visualize_passes_, -1);
219 ImGui::RadioButton("Base Color", &visualize_passes_, 0);
220 ImGui::RadioButton("Diffuse Color", &visualize_passes_, 1);
221 ImGui::RadioButton("Specular Color", &visualize_passes_, 2);
222 ImGui::RadioButton("Indirect Specular Color", &visualize_passes_, 3);
223 ImGui::RadioButton("Ambient Occlusion", &visualize_passes_, 4);
224 ImGui::RadioButton("Normals (World Space)", &visualize_passes_, 5);
225 ImGui::RadioButton("Roughness", &visualize_passes_, 6);
226 ImGui::RadioButton("Metalness", &visualize_passes_, 7);
227 ImGui::RadioButton("Emissive Color", &visualize_passes_, 8);
228 ImGui::RadioButton("Subsurface Color", &visualize_passes_, 9);
229 ImGui::RadioButton("Depth", &visualize_passes_, 10);
230 ImGui::EndMenu();
231 }
232 ImGui::SetItemTooltipEx("%s", "Visualize Render Passes");
233 if(ImGui::BeginMenu(fmt::format("{} {}", resolutions[std::clamp(current_resolution_index_, 0, (int)resolutions.size()-1)].name, ICON_MDI_ARROW_DOWN_BOLD).c_str()))
234 {
235 for(int i = 0; i < (int)resolutions.size(); ++i)
236 {
237 if(ImGui::RadioButton(resolutions[i].name.c_str(), &current_resolution_index_, i))
238 {
239 settings.resolution.set_current_resolution_index(i);
240 pm.save_project_settings(ctx);
241 }
242 }
243
244 if(ImGui::MenuItem("Edit ...", "", false))
245 {
246 ctx.get_cached<hub>().open_project_settings(ctx, "Resolution");
247 }
248 ImGui::EndMenu();
249 }
250 ImGui::SetItemTooltipEx("%s", "Resolution Presets");
251
253 auto& io = ImGui::GetIO();
254
255 auto fps_size = ImGui::CalcTextSize(fmt::format("{:.1f}", io.Framerate).c_str()).x;
256 ImGui::PopFont();
257
258 ImGui::SameLine();
259
260 ImGui::AlignedItem(1.0f,
261 ImGui::GetContentRegionAvail().x,
262 fps_size,
263 [&]()
264 {
266 ImGui::Text("%.1f", io.Framerate);
267 ImGui::PopFont();
268 });
269
270 ImGui::EndMenuBar();
271 }
272}
273
274} // namespace unravel
Class that contains core camera data, used for rendering and other purposes.
auto get_pipeline_data() -> pipeline_camera &
void set_viewport_size(const usize32_t &size)
Sets the viewport size.
auto get_render_view() -> gfx::render_view &
Gets the render view.
auto get_camera() -> camera &
Gets the camera object.
void deinit(rtti::context &ctx)
void init(rtti::context &ctx)
void on_frame_update(rtti::context &ctx, delta_t dt)
void on_frame_ui_render(rtti::context &ctx, const char *name)
void set_visible(bool visible)
void on_frame_render(rtti::context &ctx, delta_t dt)
void set_visible_force(bool visible)
void on_frame_before_render(rtti::context &ctx, delta_t dt)
Base class for different rendering paths in the ACE framework.
void on_frame_update(scene &scn, delta_t dt)
Prepares the scene for rendering.
void on_frame_before_render(scene &scn, delta_t dt)
auto render_scene(scene &scn, delta_t dt) -> gfx::frame_buffer::ptr
Renders the scene and returns the frame buffer.
std::chrono::duration< float > delta_t
std::string name
Definition hub.cpp:27
#define ICON_MDI_ARROW_DOWN_BOLD
#define ICON_MDI_DRAWING_BOX
void PushFont(Font::Enum _font)
Definition imgui.cpp:617
ImTextureID ToId(gfx::texture_handle _handle, uint8_t _mip=0, uint8_t _flags=IMGUI_FLAGS_ALPHA_BLEND)
Definition imgui.h:102
float x
auto get_cached() -> T &
Definition context.hpp:49
auto has() const -> bool
Definition context.hpp:28
auto get() -> T &
Definition context.hpp:35
Manages the entity-component-system (ECS) operations for the ACE framework.
Definition ecs.h:12
Represents a scene in the ACE framework, managing entities and their relationships.
Definition scene.h:21
std::vector< resolution > resolutions
Definition settings.h:83
struct unravel::settings::resolution_settings resolution
System responsible for managing user interface components and rendering.
Definition ui_system.h:34