Loading...
Searching...
No Matches
Application.cpp
Go to the documentation of this file.
1#include "Application.h"
2
3#include "Time.h"
4#include "hellfire/utilities/ServiceLocator.h"
5#include "../platform/windows_linux/GLFWWindow.h"
6#include "hellfire/scene/Scene.h"
7
8namespace hellfire {
9 Application::Application(int width, int height, std::string title) : shader_registry_(&shader_manager_) {
10 window_info_.width = width;
11 window_info_.height = height;
12 window_info_.aspect_ratio = static_cast<float>(width) / height;
13 window_info_.title = title;
14 }
15
17 }
18
20 try {
21 Shader *shader = shader_registry_.load_and_get_shader(
22 "assets/shaders/standard.vert",
23 "assets/shaders/phong.frag"
24 );
25
26 if (shader && shader->is_valid()) {
27 return shader;
28 }
29 } catch (const std::exception &e) {
30 std::cerr << "Warning: Could not load default shaders: " << e.what() << std::endl;
31 }
32
33 std::cerr << "Using minimal fallback shader" << std::endl;
34
35 // Try to create a basic hardcoded shader as fallback
36 uint32_t fallback_id = create_minimal_fallback_shader();
37 if (fallback_id != 0) {
38 return shader_registry_.get_shader_from_id(fallback_id);
39 }
40
41 return nullptr;
42 }
43
45 const char *vertex_source = R"(
46 #version 330 core
47 layout (location = 0) in vec3 aPos;
48 uniform mat4 MVP;
49 void main() {
50 gl_Position = MVP * vec4(aPos, 1.0);
51 }
52 )";
53
54 const char *fragment_source = R"(
55 #version 330 core
56 out vec4 FragColor;
57 void main() {
58 FragColor = vec4(1.0, 0.0, 1.0, 1.0); // Magenta to indicate fallback
59 }
60 )";
61
62 try {
63 return shader_manager_.compile_shader_program(vertex_source, fragment_source);
64 } catch (const std::exception &e) {
65 std::cerr << "Failed to create minimal fallback shader: " << e.what() << std::endl;
66 return 0;
67 }
68 }
70
71 void Application::initialize() {
72 input_manager_ = std::make_unique<InputManager>();
73
74 window_ = std::make_unique<GLFWWindow>();
75 if (!window_->create(window_info_.width, window_info_.height, window_info_.title)) {
76 throw std::runtime_error("Failed to create window");
77 }
78
79 window_->set_event_handler(this);
80
81 window_->make_current();
82 if (glewInit() != GLEW_OK) {
83 throw std::runtime_error("Failed to initialize GLEW");
84 }
85
86 // Register services
87 ServiceLocator::register_service<InputManager>(input_manager_.get());
88 ServiceLocator::register_service<ShaderManager>(&shader_manager_);
89 ServiceLocator::register_service<IWindow>(window_.get());
90
91 // Initialize engine systems
93 // renderer_.init();
94
95 // Create fallback shader
96 // Shader *fallback = ensure_fallback_shader();
97 // renderer_.set_fallback_shader(*fallback);
98
99 call_plugins([this](IApplicationPlugin &plugin) {
100 plugin.on_initialize(*this);
101 });
103
104 void Application::run() {
105 // while (!should_exit()) {
106 while (!window_->should_close()) {
108 window_->wait_for_events();
109 continue;
110 }
111
112 // Poll the window for events (mouse inputs, keys, window stuff, etc.)
113 window_->poll_events();
114 // Make sure the timer is updated
116
117 input_manager_->update();
118
119 // Update scene
120 if (auto sm = ServiceLocator::get_service<SceneManager>()) {
121 sm->update(Time::delta_time);
122 }
123
125 }
126 // }
127 }
129
130 void Application::on_render() {
131 // Plugin begin_frame
132 call_plugins([](IApplicationPlugin &plugin) {
133 plugin.on_begin_frame();
134 });
135 if (auto renderer = ServiceLocator::get_service<Renderer>()) {
136 renderer->begin_frame();
137
138 if (auto sm = ServiceLocator::get_service<SceneManager>()) {
139 if (auto *active_scene = sm->get_active_scene()) {
140 Entity *camera_override = nullptr;
141
142 call_plugins([&camera_override](IApplicationPlugin &plugin) {
143 if (!camera_override) {
144 camera_override = plugin.get_render_camera_override();
145 }
146 });
147
148 renderer->render(*active_scene, camera_override);
149 }
150 }
151 }
152
153
154 // Plugin render
155 call_plugins([](IApplicationPlugin &plugin) {
156 plugin.on_render();
157 });
158
159 if (auto renderer = ServiceLocator::get_service<Renderer>()) {
160 renderer->end_frame();
161 }
162 // Plugin end_frame
163 call_plugins([](IApplicationPlugin &plugin) {
164 plugin.on_end_frame();
165 });
166 window_->swap_buffers();
168
169 void Application::on_key_down(int key) {
170 bool consumed = call_plugins_until_consumed([key](IApplicationPlugin &plugin) {
171 return plugin.on_key_down(key);
172 });
173
174 if (!consumed) {
175 input_manager_->on_key_down(key);
176 }
178
179 void Application::on_key_up(int key) {
180 input_manager_->on_key_up(key);
182
183 void Application::on_mouse_button(int button, bool pressed) {
184 bool consumed = call_plugins_until_consumed([button, pressed](IApplicationPlugin &plugin) {
185 return plugin.on_mouse_button(button, pressed);
186 });
187
188 if (!consumed) {
190 }
192
193 bool Application::handle_first_mouse_movement(float x, float y) {
198 return true;
199 }
200 return false;
202
203 void Application::handle_cursor_warping(float x, float y) const {
205 if (x < 100 || x > static_cast<float>(window_info_.width - 100) || y < 100 || y > static_cast<float>(
206 window_info_.height - 100)) {
207 window_->warp_cursor(static_cast<double>(window_info_.width) / 2,
208 static_cast<double>(window_info_.height) / 2);
209 }
210 }
212
213 void Application::on_mouse_move(float x, float y) {
214 input_manager_->on_mouse_move(x, y);
215
216 if (handle_first_mouse_movement(x, y)) return;
217
218 const float x_offset = x - window_info_.mouse_pos.x;
219 const float y_offset = window_info_.mouse_pos.y - y;
220
223
224 // Skip large jumps (window focus, etc)
225 // if (abs(x_offset) > 100 || abs(y_offset) > 100) return;
226
227 bool consumed = call_plugins_until_consumed([x, y, x_offset, y_offset](IApplicationPlugin &plugin) {
228 return plugin.on_mouse_move(x, y, x_offset, y_offset);
229 });
230
231 if (consumed) return;
232
233 // Warp when getting close to edges
236
237 void Application::on_window_resize(const int width, const int height) {
238 if (width == 0 || height == 0) {
239 return;
240 }
241
242 window_info_.width = width;
243 window_info_.height = height;
244 window_info_.aspect_ratio = static_cast<float>(width) / static_cast<float>(height);
245
246
247 glViewport(0, 0, width, height);
248
249 // Update cameras
250 if (auto sm = ServiceLocator::get_service<SceneManager>()) {
251 if (Scene *active_scene = sm->get_active_scene()) {
252 for (const EntityID camera_id: sm->get_camera_entities()) {
253 if (const Entity *camera_entity = active_scene->get_entity(camera_id)) {
254 if (auto *camera_comp = camera_entity->get_component<CameraComponent>()) {
255 camera_comp->set_aspect_ratio(window_info_.aspect_ratio);
256 }
257 }
258 }
259 }
260 }
261
262 call_plugins([width, height](IApplicationPlugin &plugin) {
263 plugin.on_window_resize(width, height);
264 });
266
267 void Application::on_window_minimize(bool minimized) {
268 window_info_.minimized = minimized;
270
271 void Application::set_exit_condition(std::function<bool()> condition) {
272 exit_condition_ = std::move(condition);
274
275 void Application::request_exit() {
276 should_exit_ = true;
278
279 bool Application::should_exit() const {
280 if (should_exit_) return true;
281 if (exit_condition_ && exit_condition_()) return true;
282 return false;
283 }
284}
bool is_valid() const
Definition Shader.h:46
void on_mouse_move(float x, float y) override
void set_exit_condition(std::function< bool()> condition)
void on_render() override
Application(int width=800, int height=600, std::string title="hellfire Application")
void handle_cursor_warping(float x, float y) const
bool handle_first_mouse_movement(float x, float y)
void on_key_up(int key) override
void on_key_down(int key) override
void on_window_minimize(bool minimized) override
Shader * ensure_fallback_shader()
void on_mouse_button(int button, bool pressed) override
uint32_t create_minimal_fallback_shader()
virtual bool on_mouse_move(float x, float y, float x_offset, float y_offset)
virtual bool on_mouse_button(int button, bool pressed)
virtual bool on_key_down(int key)
virtual Entity * get_render_camera_override()
virtual void on_initialize(Application &app)
virtual void on_window_resize(int width, int height)
virtual void on_mouse_button(int button, bool pressed)
Definition IWindow.h:34
Manages a collection of entities and their hierarchical relationships.
Definition Scene.h:24
static float delta_time
Definition Time.h:9
static void update()
Definition Time.h:20
static void init()
Definition Time.h:16