Loading...
Searching...
No Matches
Renderer.cpp
Go to the documentation of this file.
1//
2// Simplified Renderer.cpp
3//
4#include "Renderer.h"
5#include "GL/glew.h"
6#include <algorithm>
7
8
9#include "hellfire/core/Application.h"
10#include "hellfire/core/Time.h"
11#include "hellfire/ecs/CameraComponent.h"
12#include "hellfire/ecs/InstancedRenderableComponent.h"
13#include "hellfire/ecs/LightComponent.h"
14#include "hellfire/ecs/components/MeshComponent.h"
15#include "hellfire/graphics/renderer/SkyboxRenderer.h"
16#include "hellfire/scene/Scene.h"
17
18namespace hellfire {
22 context_ = std::make_unique<OGLRendererContext>();
23 context_->shader_handle = 0;
24 }
25
26 void Renderer::init() {
27 // Enable debugging for OpenGL
28 glEnable(GL_DEBUG_OUTPUT);
29 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); // Makes errors appear immediately
30 glDebugMessageCallback([](GLenum source, GLenum type, GLuint id,
31 GLenum severity, GLsizei length,
32 const GLchar *message, const void *userParam) {
33 if (type == GL_DEBUG_TYPE_ERROR) {
34 std::cerr << "GL ERROR: " << message << std::endl;
35 __debugbreak();
36 }
37 }, nullptr);
38
39
40 // Setup shadow pass shader
41 shadow_material_ = MaterialBuilder::create_custom("Shadow Material", "assets/shaders/shadow.vert",
42 "assets/shaders/shadow.frag");
43
44 skybox_renderer_.initialize();
45 }
46
47 void Renderer::render(Scene &scene, const Entity *camera_override = nullptr) {
48 const Entity *camera_entity = camera_override;
49 if (!camera_entity) {
50 const EntityID camera_id = scene.get_default_camera_entity_id();
51 camera_entity = scene.get_entity(camera_id);
52 }
53
54 if (!camera_entity) {
55 std::cerr << "No active camera in scene!" << std::endl;
56 return;
57 }
58
59 const auto camera_comp = camera_entity->get_component<CameraComponent>();
60
61 if (!camera_comp) {
62 std::cerr << "Camera entity missing CameraComponent" << std::endl;
63 }
64
65 render_frame(scene, *camera_comp);
66 }
67
69 glClearColor(0.1f, 0.2f, 0.3f, 1.0f);
70 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
71 }
72
74 if (!opaque_objects_.empty()) opaque_objects_.clear();
75 if (!transparent_objects_.empty()) transparent_objects_.clear();
76 if (!opaque_instanced_objects_.empty()) opaque_instanced_objects_.clear();
77 if (!transparent_instanced_objects_.empty()) transparent_instanced_objects_.clear();
78 }
79
82
83 glEnable(GL_DEPTH_TEST);
84 glDepthMask(GL_TRUE);
85 glDepthFunc(GL_LESS);
86
88 }
89
91 glFlush();
92 }
93
94 void Renderer::store_lights_in_context(const std::vector<Entity *> &light_entities, CameraComponent &camera) {
95 if (!context_) return;
96
97 // Separate lights by type
98 std::vector<Entity *> directional_lights;
99 std::vector<Entity *> point_lights;
100
101 for (Entity *entity: light_entities) {
102 const auto *light = entity->get_component<LightComponent>();
103 if (!light) continue;
104
105 // Sort lights into their respective vectors
106 switch (light->get_light_type()) {
107 case LightComponent::LightType::DIRECTIONAL:
108 if (directional_lights.size() < 4) {
109 directional_lights.push_back(entity);
110 }
111 break;
112 case LightComponent::LightType::POINT:
113 if (point_lights.size() < 8) {
114 point_lights.push_back(entity);
115 }
116 break;
117 case LightComponent::LightType::SPOT:
118 // TODO: Handle spot lights
119 break;
120 }
121 }
122
123 // Store light counts
124 context_->num_directional_lights = static_cast<int>(directional_lights.size());
125 context_->num_point_lights = static_cast<int>(point_lights.size());
126
127 // Store light entities
128 for (int i = 0; i < context_->num_directional_lights; i++) {
129 context_->directional_light_entities[i] = directional_lights[i];
130 }
131
132 for (int i = 0; i < context_->num_point_lights; i++) {
133 context_->point_light_entities[i] = point_lights[i];
134 }
135
136 // Store camera component
137 context_->camera_component = &camera;
138 }
139
140 void Renderer::collect_geometry_from_scene(Scene &scene, const glm::vec3 camera_pos) {
141 for (const EntityID root_id: scene.get_root_entities()) {
142 collect_render_commands_recursive(root_id, camera_pos);
143 }
144 }
145
146 void Renderer::collect_render_commands_recursive(EntityID entity_id, const glm::vec3 &camera_pos) {
147 const Entity *entity = scene_->get_entity(entity_id);
148 if (!entity) return;
149
150 // Check for renderable + mesh components
151 const auto *renderable = entity->get_component<RenderableComponent>();
152 const auto *mesh_comp = entity->get_component<MeshComponent>();
153 const auto *transform = entity->get_component<TransformComponent>();
154
155 // Need all three to render
156 if (renderable && mesh_comp && transform) {
157 const auto mesh = mesh_comp->get_mesh();
158 const auto material = renderable->get_material();
159
160 if (mesh && material) {
161 const glm::vec3 object_pos = transform->get_world_position();
162 const float distance = glm::length(camera_pos - object_pos);
163 const bool is_transparent = material->is_transparent();
164
165 const RenderCommand cmd = {entity_id, mesh, material, distance, is_transparent};
166
167 if (is_transparent) {
168 transparent_objects_.push_back(cmd);
169 } else {
170 opaque_objects_.push_back(cmd);
171 }
172 }
173 }
174
175 // If the entity has an Instancing component setup the render commands
176 if (auto *instanced = entity->get_component<InstancedRenderableComponent>()) {
177 if (transform && instanced->has_mesh() && instanced->get_instance_count() > 0) {
178 if (const auto material = instanced->get_material()) {
179 const glm::vec3 object_pos = transform->get_world_position();
180 const float distance = glm::length(camera_pos - object_pos);
181 const bool is_transparent = material->is_transparent();
182
183 const InstancedRenderCommand cmd = {entity_id, instanced, material, distance, is_transparent};
184
185 if (is_transparent) {
186 transparent_instanced_objects_.push_back(cmd);
187 } else {
188 opaque_instanced_objects_.push_back(cmd);
189 }
190 }
191 }
192 }
193
194 // Recurse through children using scene hierarchy
195 for (const EntityID child_id: scene_->get_children(entity_id)) {
196 collect_render_commands_recursive(child_id, camera_pos);
197 }
198 }
199
200 void Renderer::ensure_shadow_map(Entity *light_entity, const LightComponent &light) {
201 if (!shadow_maps_.contains(light_entity)) {
202 auto shadow_map = std::make_unique<Framebuffer>();
204 settings.width = 4096;
205 settings.height = 4096;
206
207 settings.min_filter = GL_NEAREST;
208 settings.mag_filter = GL_NEAREST;
209 settings.wrap_s = GL_CLAMP_TO_BORDER;
210 settings.wrap_t = GL_CLAMP_TO_BORDER;
211 shadow_map->attach_depth_texture(settings);
212
213 glBindTexture(GL_TEXTURE_2D, shadow_map->get_depth_attachment());
214 const float border_color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
215 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color);
216 glBindTexture(GL_TEXTURE_2D, 0);
217 shadow_maps_[light_entity] = {std::move(shadow_map), glm::mat4(1.0f)};
218 }
219 }
220
221 void Renderer::draw_render_command(const RenderCommand &cmd, const glm::mat4 &view, const glm::mat4 &projection) {
222 const Entity *entity = scene_->get_entity(cmd.entity_id);
223 if (!entity) return;
224
225 const auto *transform = entity->get_component<TransformComponent>();
226 if (!transform) return;
227
228 Shader &shader = get_shader_for_material(cmd.material);
229 shader.use();
230
231 // Upload lights
232 if (context_) {
233 RenderingUtils::upload_lights_to_shader(shader, *context_);
234
235 // Bind shadow maps for directional lights
236 for (int i = 0; i < context_->num_directional_lights; i++) {
237 Entity* light_entity = context_->directional_light_entities[i];
238
239 if (shadow_maps_.contains(light_entity)) {
240 auto& shadow_data = shadow_maps_[light_entity];
241
242 // Bind depth texture to texture unit
243 const int texture_unit = 10 + i; // Start at unit 10 to avoid conflicts
244 glActiveTexture(GL_TEXTURE0 + texture_unit);
245 glBindTexture(GL_TEXTURE_2D, shadow_data.framebuffer->get_depth_attachment());
246
247 // Set shader uniforms
248 shader.set_int("uShadowMap[" + std::to_string(i) + "]", texture_unit);
249 shader.set_mat4("uLightSpaceMatrix[" + std::to_string(i) + "]", shadow_data.light_view_proj);
250 shader.set_float("uShadowBias", shadow_settings_.bias);
251 }
252 }
253 }
254
255 shader.set_vec3("uAmbientLight", scene_->environment()->get_ambient_light());
256
257 shader.set_uint("uObjectID", cmd.entity_id);
258
259 // Upload default uniforms
260 RenderingUtils::set_standard_uniforms(shader, transform->get_world_matrix(), view, projection);
261
262 // Bind material and draw mesh
263 cmd.material->bind();
264 cmd.mesh->draw();
265 cmd.material->unbind();
266 }
267
268 void Renderer::draw_instanced_command(const InstancedRenderCommand &cmd, const glm::mat4 &view,
269 const glm::mat4 &projection) {
270 if (const Entity *entity = scene_->get_entity(cmd.entity_id); !entity) return;
271
272 Shader &shader = get_shader_for_material(cmd.material);
273 shader.use();
274
275 // Upload light data as uniforms to shader
276 if (context_) {
277 RenderingUtils::upload_lights_to_shader(shader, *context_);
278 }
279
280 // Upload the standard uniform data to the shader (Model, View, Projection, Time)
281 RenderingUtils::set_standard_uniforms(shader, glm::mat4(1.0f), view, projection, Time::current_time);
282
283 // Prepare instanced data
285
286 // Bind material and draw
287 cmd.material->bind();
288
289 const auto mesh = cmd.instanced_renderable->get_mesh();
290 if (mesh) {
291 mesh->bind();
293 mesh->draw_instanced(cmd.instanced_renderable->get_instance_count());
294 mesh->unbind();
295 }
296
297 cmd.material->unbind();
298 }
299
300 void Renderer::execute_skybox_pass(Scene *scene, const glm::mat4 &view, const glm::mat4 &projection,
301 CameraComponent *camera_comp) const {
302 if (!scene || !scene->environment()->has_skybox()) return;
303
304 glDisable(GL_CULL_FACE);
305
306 if (camera_comp) {
307 skybox_renderer_.render(*scene->environment()->get_skybox(), camera_comp);
308 }
309 }
310
311
313 const std::vector<EntityID> light_entity_ids = scene.find_entities_with_component<LightComponent>();
314 std::vector<Entity *> light_entities;
315 for (const EntityID id: light_entity_ids) {
316 if (Entity *e = scene.get_entity(id)) {
317 light_entities.push_back(e);
318 }
319 }
320 store_lights_in_context(light_entities, camera);
321 }
322
325 scene_ = &scene;
326
327 // Gather lights and geometry
329 collect_geometry_from_scene(scene, camera.get_owner().transform()->get_position());
330
331 // Execute rendering passes
332 const glm::mat4 view = camera.get_view_matrix();
333 const glm::mat4 projection = camera.get_projection_matrix();
334
335 execute_geometry_pass(view, projection);
336 execute_skybox_pass(&scene, view, projection, &camera);
337 execute_transparency_pass(view, projection);
338 }
339
340
341
343 // Gather all lights that cast shadows
344 const std::vector<EntityID> light_entity_ids = scene.find_entities_with_component<LightComponent>();
345
346 std::vector<Entity*> shadow_casting_lights;
347 for (const EntityID id : light_entity_ids) {
348 Entity* entity = scene.get_entity(id);
349 if (!entity) continue;
350
351 const auto* light = entity->get_component<LightComponent>();
352 if (light && light->should_cast_shadows()) {
353 shadow_casting_lights.push_back(entity);
354 }
355 }
356
358 scene_ = &scene;
359 const glm::vec3 dummy_camera_pos(0.0f); // Distance doesn't matter for shadows
360 for (const EntityID root_id : scene.get_root_entities()) {
361 collect_render_commands_recursive(root_id, dummy_camera_pos);
362 }
363
364 // Render each light's shadow map
365 for (Entity* light_entity : shadow_casting_lights) {
366 auto* light = light_entity->get_component<LightComponent>();
367 if (!light) continue;
368
369 ensure_shadow_map(light_entity, *light);
370
371 auto& shadow_data = shadow_maps_[light_entity];
372 shadow_data.framebuffer->bind();
373
374 glViewport(0, 0, 4096, 4096);
375 glClear(GL_DEPTH_BUFFER_BIT);
376 glEnable(GL_DEPTH_TEST);
377 glDepthFunc(GL_LESS);
378
379 glEnable(GL_CULL_FACE);
380 glCullFace(GL_FRONT);
381
382 // Use light's view-projection matrix
383 shadow_data.light_view_proj = calculate_light_view_proj(light_entity, light, camera); // Store for main pass
384
385 // glEnable(GL_POLYGON_OFFSET_FILL);
386 // glPolygonOffset(1.5f, 2.0f);
387
388 // Render geometry to depth texture
389 draw_shadow_geometry(shadow_data.light_view_proj);
390
391 shadow_data.framebuffer->unbind();
392 }
393 // glDisable(GL_POLYGON_OFFSET_FILL);
394 glCullFace(GL_BACK);
395 glViewport(0, 0, framebuffer_width_, framebuffer_height_);
396 }
397
398 void Renderer::draw_shadow_geometry(const glm::mat4 &light_view_proj) {
399 const Shader& shadow_shader = get_shader_for_material(shadow_material_);
400 shadow_shader.use();
401 shadow_shader.set_mat4("uLightViewProjMatrix", light_view_proj);
402
403 shadow_material_->bind();
404
405 for (const auto &cmd : opaque_objects_) {
406 const Entity *entity = scene_->get_entity(cmd.entity_id);
407 if (!entity) continue;
408
409 const auto* transform = entity->get_component<TransformComponent>();
410 if (!transform) continue;
411
412 // Set model matrix for this object
413 shadow_shader.set_mat4("uModelMatrix", transform->get_world_matrix());
414
415 cmd.mesh->draw();
416 }
417
418 shadow_material_->unbind();
419 }
420
422 const glm::vec3 light_dir = glm::normalize(light->get_direction());
423
424 // Center shadow map on camera position
425 const glm::vec3 camera_pos = camera.get_owner().transform()->get_position();
426
427 const float ortho_size = 100.0f;
428 const float texel_size = (ortho_size * 2.0f) / 4096.0f;
429
430 glm::vec3 look_at;
431 look_at.x = floor(camera_pos.x / texel_size) * texel_size;
432 look_at.y = 0.0f;
433 look_at.z = float(camera_pos.z / texel_size) * texel_size;
434
435 const glm::vec3 light_pos = look_at - light_dir * 100.0f;
436
437 glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f);
438 if (glm::abs(glm::dot(light_dir, up)) > 0.99f) {
439 up = glm::vec3(1.0f, 0.0f, 0.0f);
440 }
441
442 const glm::mat4 light_projection = glm::ortho(
443 -ortho_size, ortho_size,
444 -ortho_size, ortho_size,
445 1.0f, 1000.0f);
446
447 const glm::mat4 light_view = glm::lookAt(light_pos, look_at, up);
448
449 return light_projection * light_view;
450 }
451
452 void Renderer::execute_geometry_pass(const glm::mat4 &view, const glm::mat4 &proj) {
453 glEnable(GL_DEPTH_TEST);
454 glDepthMask(GL_TRUE);
455 glDepthFunc(GL_LESS);
456 glDisable(GL_BLEND);
457
458
459 glEnable(GL_CULL_FACE);
460 glCullFace(GL_BACK);
461 glFrontFace(GL_CCW);
462
463 glEnable(GL_STENCIL_TEST);
464 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
465
466 std::ranges::sort(opaque_objects_,
467 [](const RenderCommand &a, const RenderCommand &b) {
468 return a.distance_to_camera < b.distance_to_camera;
469 });
470
471 for (const auto &cmd: opaque_objects_) {
472 draw_render_command(cmd, view, proj);
473 }
474
475 for (const auto &cmd: opaque_instanced_objects_) {
476 draw_instanced_command(cmd, view, proj);
477 }
478 }
479
480 void Renderer::execute_transparency_pass(const glm::mat4 &view, const glm::mat4 &proj) {
481 // Configure blending: enable for color input, disable for object ID output
482 glEnablei(GL_BLEND, 0); // Enable blending for fragColor (location 0)
483 glDisablei(GL_BLEND, 1); // Disable blending for objectID (location 1)
484 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
485
486 // Sort the transparent objects from back-to-front relative to camera
487 // This ensures proper blending order between different objects
488 std::ranges::sort(transparent_objects_,
489 [](const RenderCommand &a, const RenderCommand &b) {
490 return a.distance_to_camera > b.distance_to_camera;
491 });
492
493 // Render non-instanced transparent objects with two-pass rendering
494 glDisable(GL_CULL_FACE);
495 for (const auto &cmd: transparent_objects_) {
496 // Pass 1: Draw back faces, to depth buffer
497 glCullFace(GL_FRONT);
498 glDepthMask(GL_TRUE);
499 glEnable(GL_POLYGON_OFFSET_FILL);
500 glPolygonOffset(2.0f, 2.0f);
501 draw_render_command(cmd, view, proj);
502 glDisable(GL_POLYGON_OFFSET_FILL);
503
504 // Pass 2: Draw front faces, don't write to depth buffer
505 glCullFace(GL_BACK);
506 glDepthMask(GL_FALSE);
507 draw_render_command(cmd, view, proj);
508 }
509
510 // Render instanced transparent objects with two-pass rendering
511 for (const auto &cmd: transparent_instanced_objects_) {
512 // Pass 1: Draw back faces, to depth buffer
513 glCullFace(GL_FRONT);
514 glDepthMask(GL_TRUE);
515 draw_instanced_command(cmd, view, proj);
516
517 // Pass 2: Draw front faces, don't write to depth buffer
518 glCullFace(GL_BACK);
519 glDepthMask(GL_FALSE);
520 draw_instanced_command(cmd, view, proj);
521 }
522
523 // Restore depth writing
524 glDepthMask(GL_TRUE);
525 }
526
527 void Renderer::create_main_framebuffer(uint32_t width, uint32_t height) {
528 framebuffer_width_ = width;
529 framebuffer_height_ = height;
530
531 // General Settings
533 settings.width = width;
534 settings.height = height;
535
536 // ObjectId specific settings
537 FrameBufferAttachmentSettings object_id_attachment_settings = settings;
538 object_id_attachment_settings.format = GL_RED_INTEGER;
539 object_id_attachment_settings.internal_format = GL_R32UI;
540 object_id_attachment_settings.type = GL_UNSIGNED_INT;
541 scene_framebuffers_[SCREEN_TEXTURE_1] = std::make_unique<Framebuffer>();
542 scene_framebuffers_[SCREEN_TEXTURE_1]->attach_color_texture(settings);
543 scene_framebuffers_[SCREEN_TEXTURE_1]->attach_color_texture(object_id_attachment_settings);
544 scene_framebuffers_[SCREEN_TEXTURE_1]->attach_depth_texture(settings);
545
546 scene_framebuffers_[SCREEN_TEXTURE_2] = std::make_unique<Framebuffer>();
547 scene_framebuffers_[SCREEN_TEXTURE_2]->attach_color_texture(settings);
548 scene_framebuffers_[SCREEN_TEXTURE_2]->attach_color_texture(object_id_attachment_settings);
549 scene_framebuffers_[SCREEN_TEXTURE_2]->attach_depth_texture(settings);
550 }
551
552 void Renderer::resize_main_framebuffer(uint32_t width, uint32_t height) {
553 framebuffer_width_ = width;
554 framebuffer_height_ = height;
555
556 // Resize only the current render buffer immediately.
557 // The display buffer will be lazily resized on the next frame
558 // to avoid showing cleared/incomplete frames during a window resize.
559 if (scene_framebuffers_[0]) {
560 scene_framebuffers_[current_fb_index_]->resize(width, height);
561 }
562 }
563
565 const int display_index = 1 - current_fb_index_;
566 if (scene_framebuffers_[display_index]) {
567 return scene_framebuffers_[display_index]->get_color_attachment(0);
568 }
569 return 0;
570 }
571
572 uint32_t Renderer::get_object_id_texture() const {
573 const int display_index = 1 - current_fb_index_;
574 if (scene_framebuffers_[display_index]->get_color_attachment(1) != 0) {
575 return scene_framebuffers_[display_index]->get_color_attachment(1);
576 }
577 return 0;
578 }
579
581 if (!scene_framebuffers_[SCREEN_TEXTURE_1]) {
583 }
584
585 // Check if the OTHER buffer (display buffer) needs resizing
586 const int display_index = 1 - current_fb_index_;
587 if (scene_framebuffers_[display_index] &&
588 (scene_framebuffers_[display_index]->get_width() != framebuffer_width_ ||
589 scene_framebuffers_[display_index]->get_height() != framebuffer_height_)) {
590 scene_framebuffers_[display_index]->resize(framebuffer_width_, framebuffer_height_);
591 }
592
593 execute_shadow_passes(scene, camera);
594
595 scene_framebuffers_[current_fb_index_]->bind();
597
598 // Clear the object ID buffer (color attachment 1) to 0
599 constexpr GLuint clear_value = 0;
600 glClearBufferuiv(GL_COLOR, 1, &clear_value);
601
602 execute_main_pass(scene, camera);
603 scene_framebuffers_[current_fb_index_]->unbind();
604 glFlush();
605
606 // Swap for next frame
608 }
609
610 void Renderer::set_fallback_shader(Shader &fallback_shader) {
611 fallback_shader_ = &fallback_shader;
612
613 if (context_) {
614 context_->shader_handle = fallback_shader.get_program_id();
615 }
616 }
617
618 Shader &Renderer::get_shader_for_material(const std::shared_ptr<Material> &material) {
619 if (!material) {
620 return *fallback_shader_;
621 }
622
623 // Check if material has a compiled shader ID
624 if (const uint32_t material_shader_id = material->get_compiled_shader_id(); material_shader_id != 0) {
625 // Get shader wrapper from the ID
626 if (Shader *material_shader = shader_registry_.get_shader_from_id(material_shader_id)) {
627 return *material_shader;
628 }
629 }
630
631 // Check if material needs compilation
632 if (material->has_custom_shader()) {
633 // Try to compile the material's shader
634 if (const uint32_t compiled_id = compile_material_shader(material); compiled_id != 0) {
635 material->set_compiled_shader_id(compiled_id);
636 const auto shader = shader_registry_.get_shader_from_id(compiled_id);
637 return *shader;
638 }
639 }
640
641 // Fall back to default shader
642 return *fallback_shader_;
643 }
644
645 uint32_t Renderer::compile_material_shader(std::shared_ptr<Material> material) {
646 if (!material || !material->has_custom_shader()) {
647 return 0;
648 }
649
650 const Material::ShaderInfo *shader_info = material->get_shader_info();
651 if (!shader_info) {
652 return 0;
653 }
654
655 // Create shader variant with material's settings
657 variant.vertex_path = shader_info->vertex_path;
658 variant.fragment_path = shader_info->fragment_path;
659 variant.defines = shader_info->defines;
660
661 // Add automatic defines based on material properties
662 shader_manager_.add_automatic_defines(*material, variant.defines);
663
664 // Compile using shader manager
665 return shader_manager_.load_shader(variant);
666 }
667}
void use() const
Definition Shader.h:39
void set_float(const std::string &name, const float value) const
Definition Shader.h:61
void set_int(const std::string &name, const int value) const
Definition Shader.h:53
void set_vec3(const std::string &name, const float x, const float y, const float z) const
Definition Shader.h:78
void set_uint(const std::string &name, const uint32_t value) const
Definition Shader.h:57
void draw_render_command(const RenderCommand &cmd, const glm::mat4 &view, const glm::mat4 &projection)
Definition Renderer.cpp:221
void ensure_shadow_map(Entity *light_entity, const LightComponent &light)
Definition Renderer.cpp:200
Shader & get_shader_for_material(const std::shared_ptr< Material > &material)
Definition Renderer.cpp:618
ShadowSettings shadow_settings_
Definition Renderer.h:134
bool render_to_framebuffer_
Definition Renderer.h:124
void execute_skybox_pass(Scene *scene, const glm::mat4 &view, const glm::mat4 &projection, CameraComponent *camera_comp) const
Definition Renderer.cpp:300
uint32_t get_object_id_texture() const
Definition Renderer.cpp:572
glm::mat4 calculate_light_view_proj(Entity *light_entity, LightComponent *light, const CameraComponent &camera)
Definition Renderer.cpp:421
void draw_instanced_command(const InstancedRenderCommand &cmd, const glm::mat4 &view, const glm::mat4 &projection)
Definition Renderer.cpp:268
void render(Scene &scene, const Entity *camera_override)
Definition Renderer.cpp:47
void collect_geometry_from_scene(Scene &scene, const glm::vec3 camera_pos)
Definition Renderer.cpp:140
void execute_shadow_passes(Scene &scene, CameraComponent &camera)
Definition Renderer.cpp:342
Shader * fallback_shader_
Definition Renderer.h:116
uint32_t fallback_program_
Definition Renderer.h:117
uint32_t get_main_output_texture() const
Definition Renderer.cpp:564
void resize_main_framebuffer(uint32_t width, uint32_t height)
Definition Renderer.cpp:552
void execute_transparency_pass(const glm::mat4 &view, const glm::mat4 &proj)
Definition Renderer.cpp:480
void reset_framebuffer_data()
Definition Renderer.cpp:68
void execute_main_pass(Scene &scene, CameraComponent &camera)
Definition Renderer.cpp:323
uint32_t framebuffer_width_
Definition Renderer.h:125
void render_frame(Scene &scene, CameraComponent &camera)
Definition Renderer.cpp:580
void execute_geometry_pass(const glm::mat4 &view, const glm::mat4 &proj)
Definition Renderer.cpp:452
void collect_lights_from_scene(Scene &scene, CameraComponent &camera)
Definition Renderer.cpp:312
void store_lights_in_context(const std::vector< Entity * > &light_entities, CameraComponent &camera)
Definition Renderer.cpp:94
uint32_t framebuffer_height_
Definition Renderer.h:126
void draw_shadow_geometry(const glm::mat4 &light_view_proj)
Definition Renderer.cpp:398
void set_fallback_shader(Shader &fallback_shader)
Definition Renderer.cpp:610
void collect_render_commands_recursive(EntityID entity_id, const glm::vec3 &camera_pos)
Definition Renderer.cpp:146
void create_main_framebuffer(uint32_t width, uint32_t height)
Definition Renderer.cpp:527
uint32_t compile_material_shader(std::shared_ptr< Material > material)
Definition Renderer.cpp:645
Manages a collection of entities and their hierarchical relationships.
Definition Scene.h:24
Entity * get_entity(EntityID id)
Retrieves an entity by its ID.
Definition Scene.cpp:90
EntityID get_default_camera_entity_id() const
Definition Scene.h:159
SceneEnvironment * environment() const
Definition Scene.h:181
InstancedRenderableComponent * instanced_renderable
Definition Renderer.h:39