From 5b361d81dbd2af0d0e99b9eb1adebea76ff05db0 Mon Sep 17 00:00:00 2001 From: hachem Date: Thu, 20 Aug 2026 02:27:02 +0200 Subject: [chore]: MASSIVE refactor + more vulkan bs --- src/Engine/Engine.cpp | 530 +++++++++++++++++++++++++------------------------- src/Engine/Engine.h | 228 +++++++++++----------- src/Engine/Object.h | 73 +++---- src/Engine/Scene.h | 71 +++---- 4 files changed, 453 insertions(+), 449 deletions(-) (limited to 'src/Engine') diff --git a/src/Engine/Engine.cpp b/src/Engine/Engine.cpp index e436f4c..059fdda 100644 --- a/src/Engine/Engine.cpp +++ b/src/Engine/Engine.cpp @@ -8,68 +8,68 @@ #define STB_IMAGE_WRITE_IMPLEMENTATION #include "stb_image_write.h" -#include "Engine.h" -#include "Core/Log.h" -#include "Core/HDRIManager.h" -#include "Rendering/VertexBuffer.h" -#include "Rendering/IndexBuffer.h" +#include "engine.h" +#include "core/log.h" +#include "core/hdri_manager.h" +#include "rendering/vertex_buffer.h" +#include "rendering/index_buffer.h" namespace Donut { Engine::Engine() - : m_SagA(glm::vec3(0.0f, 0.0f, 0.0f), 8.54e36f) + : m_sag_a(glm::vec3(0.0f, 0.0f, 0.0f), 8.54e36f) { - m_Width = 1280; - m_Height = 720; + m_width = 1280; + m_height = 720; - m_Camera.SetCameraMode(CameraMode::Orbital); - m_Camera.SetOrbitalRadius(1e11); - m_Camera.SetOrbitalLimits(1e9, 1e13); - m_Camera.SetOrbitalSpeed(0.01f); - m_Camera.SetZoomSpeed(1e10f); + m_camera.set_camera_mode(CameraMode::Orbital); + m_camera.set_orbital_radius(1e11); + m_camera.set_orbital_limits(1e9, 1e13); + m_camera.set_orbital_speed(0.01f); + m_camera.set_zoom_speed(1e10f); - m_Objects = + m_objects = { - { glm::vec4(0.00f, 0.00f, 0.00f, m_SagA.m_Rs), glm::vec4(0, 0, 0, 1), static_cast(m_SagA.m_Mass) } + { glm::vec4(0.00f, 0.00f, 0.00f, m_sag_a.m_rs), glm::vec4(0, 0, 0, 1), static_cast(m_sag_a.m_mass) } }; // The geodesic ray tracer used to be a compute shader; it is now a - // fullscreen vertex+fragment pass (see DispatchCompute) so it runs on + // fullscreen vertex+fragment pass (see dispatch_compute) so it runs on // macOS OpenGL 4.1, which has no compute shaders. - m_ComputeProgram = Ref(Shader::Create("Assets/Shaders/Geodesic.glsl")); - m_ShaderProgram = Ref(Shader::Create("Assets/Shaders/TexturedQuad.glsl")); - m_BlurShader = Ref(Shader::Create("Assets/Shaders/Blur.glsl")); + m_compute_program = Ref(Shader::create("assets/shaders/Geodesic.glsl")); + m_shader_program = Ref(Shader::create("assets/shaders/TexturedQuad.glsl")); + m_blur_shader = Ref(Shader::create("assets/shaders/Blur.glsl")); - auto& hdriManager = HDRIManager::Get(); - m_HDRIEnvironment = hdriManager.GetCurrentHDRI(); - if (!m_HDRIEnvironment) + auto& hdri_manager = HDRIManager::get(); + m_hdri_environment = hdri_manager.get_current_hdri(); + if (!m_hdri_environment) { - hdriManager.SetCurrentHDRI("Assets/HDRI/HDR_blue_nebulae-1.hdr"); - m_HDRIEnvironment = hdriManager.GetCurrentHDRI(); - if (!m_HDRIEnvironment) + hdri_manager.set_current_hdri("assets/hdri/HDR_blue_nebulae-1.hdr"); + m_hdri_environment = hdri_manager.get_current_hdri(); + if (!m_hdri_environment) DONUT_WARN("Failed to load default HDRI, using fallback"); } - m_CameraUBO = UniformBuffer::Create(128, 1); - m_DiskUBO = UniformBuffer::Create(sizeof(float) * 5, 2); + m_camera_ubo = UniformBuffer::create(128, 1); + m_disk_ubo = UniformBuffer::create(sizeof(float) * 5, 2); - uint32_t objUBOSize = sizeof(int) + 3 * sizeof(float) + uint32_t obj_ubo_size = sizeof(int) + 3 * sizeof(float) + 16 * (sizeof(glm::vec4) + sizeof(glm::vec4)) + 16 * sizeof(float); - m_ObjectsUBO = UniformBuffer::Create(objUBOSize, 3); + m_objects_ubo = UniformBuffer::create(obj_ubo_size, 3); - m_SimulationUBO = UniformBuffer::Create(sizeof(int) * 2 + sizeof(float) * 2, 4); + m_simulation_ubo = UniformBuffer::create(sizeof(int) * 2 + sizeof(float) * 2, 4); auto result = QuadVAO(); - m_QuadVAO = result.first; - m_Texture = result.second; + m_quad_vao = result.first; + m_texture = result.second; // GLSL 4.10 forbids explicit binding qualifiers on uniform blocks, so // associate the geodesic shader's blocks with their UBO binding points // from the host side instead. - if (m_ComputeProgram) + if (m_compute_program) { - uint32_t prog = m_ComputeProgram->GetRendererID(); + uint32_t prog = m_compute_program->get_renderer_id(); struct { const char* name; uint32_t point; } blocks[] = { { "Camera", 1 }, { "Disk", 2 }, { "Objects", 3 }, { "Simulation", 4 } @@ -82,77 +82,77 @@ namespace Donut } } - glGenFramebuffers(1, &m_GeodesicFBO); + glGenFramebuffers(1, &m_geodesic_fbo); } - void Engine::UpdateWindowDimensions() + auto Engine::update_window_dimensions() -> void { - UpdateComputeDimensions(); + update_compute_dimensions(); } - void Engine::SetWindowDimensions(int width, int height) + auto Engine::set_window_dimensions(int width, int height) -> void { - int oldWidth = m_Width; - int oldHeight = m_Height; - int oldComputeHeight = m_ComputeHeight; + int old_width = m_width; + int old_height = m_height; + int old_compute_height = m_compute_height; - m_Width = width; - m_Height = height; + m_width = width; + m_height = height; - if (oldWidth != m_Width || - oldHeight != m_Height || - oldComputeHeight != m_ComputeHeight) - UpdateComputeDimensions(); + if (old_width != m_width || + old_height != m_height || + old_compute_height != m_compute_height) + update_compute_dimensions(); } - void Engine::UpdatePerformance(float deltaTime) + auto Engine::update_performance(float delta_time) -> void { - if (deltaTime > 0.0f) - m_CurrentFPS = 1.0f / deltaTime; + if (delta_time > 0.0f) + m_current_fps = 1.0f / delta_time; } - void Engine::UpdateComputeDimensions() + auto Engine::update_compute_dimensions() -> void { - m_Texture = Texture2D::Create(GetComputeWidth(), m_ComputeHeight); + m_texture = Texture2D::create(get_compute_width(), m_compute_height); } - void Engine::DrawFullScreenQuad() + auto Engine::draw_full_screen_quad() -> void { - RenderCommand::SetViewport(0, 0, m_Width, m_Height); + RenderCommand::set_viewport(0, 0, m_width, m_height); - m_ShaderProgram->Bind(); - m_QuadVAO->Bind(); + m_shader_program->bind(); + m_quad_vao->bind(); - m_Texture->Bind(0); - m_ShaderProgram->SetInt("u_ScreenTexture", 0); + m_texture->bind(0); + m_shader_program->set_int("u_ScreenTexture", 0); - RenderCommand::DisableDepthTest(); - RenderCommand::DrawArrays(6); - RenderCommand::EnableDepthTest(); + RenderCommand::disable_depth_test(); + RenderCommand::draw_arrays(6); + RenderCommand::enable_depth_test(); } - void Engine::DrawBlurPass() + auto Engine::draw_blur_pass() -> void { - RenderCommand::SetViewport(0, 0, m_Width, m_Height); + RenderCommand::set_viewport(0, 0, m_width, m_height); - m_BlurShader->Bind(); - m_QuadVAO->Bind(); + m_blur_shader->bind(); + m_quad_vao->bind(); - m_Texture->Bind(0); - m_BlurShader->SetInt("u_ScreenTexture", 0); - m_BlurShader->SetFloat2("u_Resolution", glm::vec2(m_Width, m_Height)); - m_BlurShader->SetFloat("u_BlurStrength", m_BlurStrength); - m_BlurShader->SetFloat("u_GlowIntensity", m_GlowIntensity); + m_texture->bind(0); + m_blur_shader->set_int("u_ScreenTexture", 0); + m_blur_shader->set_float2("u_Resolution", glm::vec2(m_width, m_height)); + m_blur_shader->set_float("u_BlurStrength", m_blur_strength); + m_blur_shader->set_float("u_GlowIntensity", m_glow_intensity); - RenderCommand::DisableDepthTest(); - RenderCommand::DrawArrays(6); - RenderCommand::EnableDepthTest(); + RenderCommand::disable_depth_test(); + RenderCommand::draw_arrays(6); + RenderCommand::enable_depth_test(); } - void Engine::DrawGeodesicPass(int cw, int ch) + auto Engine::draw_geodesic_pass(int cw, int ch) -> void { - m_QuadVAO->Bind(); - RenderCommand::DisableDepthTest(); + m_quad_vao->bind(); + RenderCommand::disable_depth_test(); #ifdef __APPLE__ // macOS aborts any GPU submission that runs longer than a couple of @@ -160,7 +160,7 @@ namespace Donut // a single fullscreen draw, so render it in scissored tiles and flush // after each, keeping every submission short enough to survive the // watchdog. Compute-capable platforms draw it in one pass. - // Largest tile that keeps a tile's worst-case work (tile^2 * stepCap) + // Largest tile that keeps a tile's worst-case work (tile^2 * step_cap) // inside the safe watchdog zone measured on this GPU (~25M pixel-steps // per submission); bigger tiles mean fewer glFinish stalls. const int tile = 64; @@ -172,52 +172,52 @@ namespace Donut { int tw = std::min(tile, cw - x); glScissor(x, y, tw, th); - RenderCommand::DrawArrays(6); + RenderCommand::draw_arrays(6); glFinish(); } } glDisable(GL_SCISSOR_TEST); #else - RenderCommand::DrawArrays(6); + RenderCommand::draw_arrays(6); #endif - RenderCommand::EnableDepthTest(); + RenderCommand::enable_depth_test(); } - void Engine::DispatchCompute(const Camera& cam) + auto Engine::dispatch_compute(const Camera& cam) -> void { - auto& hdriManager = HDRIManager::Get(); - m_HDRIEnvironment = hdriManager.GetCurrentHDRI(); + auto& hdri_manager = HDRIManager::get(); + m_hdri_environment = hdri_manager.get_current_hdri(); - int cw = GetComputeWidth(); - int ch = m_ComputeHeight; + int cw = get_compute_width(); + int ch = m_compute_height; - // Render the geodesic pass into m_Texture through an FBO. This replaces - // the old compute dispatch + imageStore path, which relied on OpenGL + // Render the geodesic pass into m_texture through an FBO. This replaces + // the old compute dispatch + image_store path, which relied on OpenGL // 4.3 compute and 4.2 image load/store that macOS does not provide. - glBindFramebuffer(GL_FRAMEBUFFER, m_GeodesicFBO); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_Texture->GetRendererID(), 0); + glBindFramebuffer(GL_FRAMEBUFFER, m_geodesic_fbo); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture->get_renderer_id(), 0); glViewport(0, 0, cw, ch); - m_ComputeProgram->Bind(); - UploadCameraUBO(cam); - UploadDiskUBO(); - UploadObjectsUBO(m_Objects); - UploadSimulationUBO(); - m_ComputeProgram->SetFloat2("u_Resolution", glm::vec2(static_cast(cw), static_cast(ch))); + m_compute_program->bind(); + upload_camera_ubo(cam); + upload_disk_ubo(); + upload_objects_ubo(m_objects); + upload_simulation_ubo(); + m_compute_program->set_float2("u_Resolution", glm::vec2(static_cast(cw), static_cast(ch))); - if (m_HDRIEnvironment) + if (m_hdri_environment) { - m_HDRIEnvironment->Bind(5); - m_ComputeProgram->SetInt("u_HDRIEnvironment", 5); + m_hdri_environment->bind(5); + m_compute_program->set_int("u_HDRIEnvironment", 5); } - DrawGeodesicPass(cw, ch); + draw_geodesic_pass(cw, ch); glBindFramebuffer(GL_FRAMEBUFFER, 0); } - void Engine::UploadCameraUBO(const Camera& cam) + auto Engine::upload_camera_ubo(const Camera& cam) -> void { struct UBOData { @@ -225,80 +225,80 @@ namespace Donut glm::vec3 right; float _pad1; glm::vec3 up; float _pad2; glm::vec3 forward; float _pad3; - float tanHalfFov; + float tan_half_fov; float aspect; bool moving; int _pad4; } data; - glm::vec3 fwd = glm::normalize(cam.GetOrbitalTarget() - cam.GetOrbitalPosition()); + glm::vec3 fwd = glm::normalize(cam.get_orbital_target() - cam.get_orbital_position()); glm::vec3 up = glm::vec3(0, 1, 0); glm::vec3 right = glm::normalize(glm::cross(fwd, up)); up = glm::cross(right, fwd); - data.pos = cam.GetOrbitalPosition(); + data.pos = cam.get_orbital_position(); data.right = right; data.up = up; data.forward = fwd; - data.tanHalfFov = static_cast(tan(glm::radians(60.0f * 0.5f))); - data.aspect = static_cast(GetComputeWidth()) / static_cast(m_ComputeHeight); - data.moving = cam.IsDragging() || cam.IsPanning(); + data.tan_half_fov = static_cast(tan(glm::radians(60.0f * 0.5f))); + data.aspect = static_cast(get_compute_width()) / static_cast(m_compute_height); + data.moving = cam.is_dragging() || cam.is_panning(); - m_CameraUBO->SetData(&data, sizeof(UBOData)); - m_CameraUBO->Bind(1); + m_camera_ubo->set_data(&data, sizeof(UBOData)); + m_camera_ubo->bind(1); } - void Engine::UploadObjectsUBO(const std::vector& objs) + auto Engine::upload_objects_ubo(const std::vector& objs) -> void { struct UBOData { - int numObjects; + int num_objects; float _pad0, _pad1, _pad2; - glm::vec4 posRadius[16]; + glm::vec4 pos_radius[16]; glm::vec4 color[16]; float mass[16]; } data; size_t count = std::min(objs.size(), size_t(16)); - data.numObjects = static_cast(count); + data.num_objects = static_cast(count); for (size_t i = 0; i < count; ++i) { - data.posRadius[i] = objs[i].m_PosRadius; - data.color[i] = objs[i].m_Color; - data.mass[i] = objs[i].m_Mass; + data.pos_radius[i] = objs[i].m_pos_radius; + data.color[i] = objs[i].m_color; + data.mass[i] = objs[i].m_mass; } - m_ObjectsUBO->SetData(&data, sizeof(data)); - m_ObjectsUBO->Bind(3); + m_objects_ubo->set_data(&data, sizeof(data)); + m_objects_ubo->bind(3); } - void Engine::UploadDiskUBO() + auto Engine::upload_disk_ubo() -> void { - float r1 = static_cast(m_SagA.m_Rs * 2.2); - float r2 = static_cast(m_SagA.m_Rs * 5.2); + float r1 = static_cast(m_sag_a.m_rs * 2.2); + float r2 = static_cast(m_sag_a.m_rs * 5.2); float num = 2.0f; - float thickness = static_cast(m_SagA.m_Rs * m_DiskThickness); - float diskData[5] = { r1, r2, num, thickness, m_DiskDensity }; + float thickness = static_cast(m_sag_a.m_rs * m_disk_thickness); + float disk_data[5] = { r1, r2, num, thickness, m_disk_density }; - m_DiskUBO->SetData(diskData, sizeof(diskData)); - m_DiskUBO->Bind(2); + m_disk_ubo->set_data(disk_data, sizeof(disk_data)); + m_disk_ubo->bind(2); } - void Engine::UploadSimulationUBO() + auto Engine::upload_simulation_ubo() -> void { struct UBOData { - int maxStepsMoving; - int maxStepsStatic; - float earlyExitDistance; + int max_steps_moving; + int max_steps_static; + float early_exit_distance; float time; } data; - data.maxStepsMoving = m_MaxStepsMoving; - data.maxStepsStatic = m_MaxStepsStatic; - data.earlyExitDistance = m_EarlyExitDistance; - data.time = static_cast(glfwGetTime()) * m_RotationSpeed; + data.max_steps_moving = m_max_steps_moving; + data.max_steps_static = m_max_steps_static; + data.early_exit_distance = m_early_exit_distance; + data.time = static_cast(glfwGetTime()) * m_rotation_speed; #ifdef __APPLE__ // macOS has no compute shaders, so the geodesic pass runs as a tiled @@ -307,58 +307,58 @@ namespace Donut // GPU, so cap them here. Windows/Linux keep the full step count. // While the camera moves, render cheaply so interaction stays smooth; // when it settles, spend more steps for a cleaner image. Both stay well - // under the per-tile GPU-watchdog budget (see DrawGeodesicPass). - data.maxStepsMoving = std::min(data.maxStepsMoving, 4000); - data.maxStepsStatic = std::min(data.maxStepsStatic, 6000); + // under the per-tile GPU-watchdog budget (see draw_geodesic_pass). + data.max_steps_moving = std::min(data.max_steps_moving, 4000); + data.max_steps_static = std::min(data.max_steps_static, 6000); #endif - m_SimulationUBO->SetData(&data, sizeof(data)); - m_SimulationUBO->Bind(4); + m_simulation_ubo->set_data(&data, sizeof(data)); + m_simulation_ubo->bind(4); } - void Engine::UpdatePhysics(float deltaTime) + auto Engine::update_physics(float delta_time) -> void { - for (auto& obj : m_Objects) + for (auto& obj : m_objects) { - for (auto& obj2 : m_Objects) + for (auto& obj2 : m_objects) { if (&obj == &obj2) continue; - float dx = obj2.m_PosRadius.x - obj.m_PosRadius.x; - float dy = obj2.m_PosRadius.y - obj.m_PosRadius.y; - float dz = obj2.m_PosRadius.z - obj.m_PosRadius.z; + float dx = obj2.m_pos_radius.x - obj.m_pos_radius.x; + float dy = obj2.m_pos_radius.y - obj.m_pos_radius.y; + float dz = obj2.m_pos_radius.z - obj.m_pos_radius.z; float distance = sqrt(dx * dx + dy * dy + dz * dz); if (distance > 0) { std::vector direction = {dx / distance, dy / distance, dz / distance}; - double Gforce = (G * obj.m_Mass * obj2.m_Mass) / (distance * distance); - double acc1 = Gforce / obj.m_Mass; + double Gforce = (G * obj.m_mass * obj2.m_mass) / (distance * distance); + double acc1 = Gforce / obj.m_mass; std::vector acc = {direction[0] * acc1, direction[1] * acc1, direction[2] * acc1}; - if (m_Gravity) + if (m_gravity) { - obj.m_Velocity.x += static_cast(acc[0]); - obj.m_Velocity.y += static_cast(acc[1]); - obj.m_Velocity.z += static_cast(acc[2]); + obj.m_velocity.x += static_cast(acc[0]); + obj.m_velocity.y += static_cast(acc[1]); + obj.m_velocity.z += static_cast(acc[2]); - obj.m_PosRadius.x += static_cast(obj.m_Velocity.x); - obj.m_PosRadius.y += static_cast(obj.m_Velocity.y); - obj.m_PosRadius.z += static_cast(obj.m_Velocity.z); + obj.m_pos_radius.x += static_cast(obj.m_velocity.x); + obj.m_pos_radius.y += static_cast(obj.m_velocity.y); + obj.m_pos_radius.z += static_cast(obj.m_velocity.z); } } } } } - void Engine::RenderScene() + auto Engine::render_scene() -> void { - RenderCommand::Clear(); - m_ShaderProgram->Bind(); - m_QuadVAO->Bind(); - m_Texture->Bind(0); - RenderCommand::DrawArrays(6); + RenderCommand::clear(); + m_shader_program->bind(); + m_quad_vao->bind(); + m_texture->bind(0); + RenderCommand::draw_arrays(6); } - Ref Engine::CreateComputeProgram(const char* path) + auto Engine::create_compute_program(const char* path) -> Ref { std::ifstream in(path); if(!in.is_open()) @@ -368,13 +368,13 @@ namespace Donut } std::stringstream ss; ss << in.rdbuf(); - std::string srcStr = ss.str(); - return Ref(Shader::CreateCompute("ComputeShader", srcStr)); + std::string src_str = ss.str(); + return Ref(Shader::create_compute("ComputeShader", src_str)); } - std::pair, Ref> Engine::QuadVAO() + auto Engine::QuadVAO() -> std::pair, Ref> { - float quadVertices[] = + float quad_vertices[] = { // Positions // TexCoords -1.0f, 1.0f, 0.0f, 1.0f, @@ -385,82 +385,82 @@ namespace Donut 1.0f, 1.0f, 1.0f, 1.0f }; - auto vertexBuffer = Ref(VertexBuffer::Create(quadVertices, static_cast(sizeof(quadVertices)))); + auto vertex_buffer = Ref(VertexBuffer::create(quad_vertices, static_cast(sizeof(quad_vertices)))); VertexBufferLayout layout; - layout.Push(2); // Position (x, y) - layout.Push(2); // TexCoord (u, v) - vertexBuffer->SetLayout(layout); + layout.push(2); // Position (x, y) + layout.push(2); // TexCoord (u, v) + vertex_buffer->set_layout(layout); - auto vertexArray = Ref(VertexArray::Create()); - vertexArray->AddVertexBuffer(vertexBuffer); - auto texture = Texture2D::Create(GetComputeWidth(), m_ComputeHeight); + auto vertex_array = Ref(VertexArray::create()); + vertex_array->add_vertex_buffer(vertex_buffer); + auto texture = Texture2D::create(get_compute_width(), m_compute_height); - return { vertexArray, texture }; + return { vertex_array, texture }; } - void Engine::LoadObjectsFromScene(const std::vector& objects) + auto Engine::load_objects_from_scene(const std::vector& objects) -> void { - m_Objects.clear(); - m_Objects.push_back( + m_objects.clear(); + m_objects.push_back( { - glm::vec4(0.00f, 0.00f, 0.00f, m_SagA.m_Rs), + glm::vec4(0.00f, 0.00f, 0.00f, m_sag_a.m_rs), glm::vec4(0, 0, 0, 1), - static_cast(m_SagA.m_Mass) + static_cast(m_sag_a.m_mass) }); for (const auto& obj : objects) { - ObjectData engineObj; + ObjectData engine_obj; - float scaleFactor = 1e10f; - engineObj.m_PosRadius = glm::vec4 + float scale_factor = 1e10f; + engine_obj.m_pos_radius = glm::vec4 ( - obj.m_Centre.x * scaleFactor, - obj.m_Centre.y * scaleFactor, - obj.m_Centre.z * scaleFactor, - obj.m_Radius * scaleFactor + obj.m_centre.x * scale_factor, + obj.m_centre.y * scale_factor, + obj.m_centre.z * scale_factor, + obj.m_radius * scale_factor ); - engineObj.m_Color = glm::vec4(obj.m_Material.m_Color, 1.0f); + engine_obj.m_color = glm::vec4(obj.m_material.m_color, 1.0f); - float volume = (4.0f / 3.0f) * 3.14159f * engineObj.m_PosRadius.w * engineObj.m_PosRadius.w * engineObj.m_PosRadius.w; + float volume = (4.0f / 3.0f) * 3.14159f * engine_obj.m_pos_radius.w * engine_obj.m_pos_radius.w * engine_obj.m_pos_radius.w; float density = 1e12f; - engineObj.m_Mass = volume * density; - engineObj.m_Velocity = glm::vec3(0.0f, 0.0f, 0.0f); + engine_obj.m_mass = volume * density; + engine_obj.m_velocity = glm::vec3(0.0f, 0.0f, 0.0f); - m_Objects.push_back(engineObj); + m_objects.push_back(engine_obj); } DONUT_INFO("Loaded {} objects from WorldBuilder scene (scaled up by {})", objects.size(), 1e10f); - PrintObjectInfo(); + print_object_info(); } - void Engine::PrintObjectInfo() const + auto Engine::print_object_info() const -> void { DONUT_INFO("=== Object Information ==="); - DONUT_INFO("Total objects: {}", m_Objects.size()); + DONUT_INFO("Total objects: {}", m_objects.size()); - for (size_t i = 0; i < m_Objects.size(); ++i) + for (size_t i = 0; i < m_objects.size(); ++i) { - const auto& obj = m_Objects[i]; + const auto& obj = m_objects[i]; DONUT_INFO("Object {}: Pos=({}, {}, {}), Radius={}, Mass={}, Color=({}, {}, {})", i, - obj.m_PosRadius.x, obj.m_PosRadius.y, obj.m_PosRadius.z, - obj.m_PosRadius.w, - obj.m_Mass, - obj.m_Color.x, obj.m_Color.y, obj.m_Color.z + obj.m_pos_radius.x, obj.m_pos_radius.y, obj.m_pos_radius.z, + obj.m_pos_radius.w, + obj.m_mass, + obj.m_color.x, obj.m_color.y, obj.m_color.z ); } DONUT_INFO("Camera position: ({}, {}, {})", - m_Camera.GetOrbitalPosition().x, - m_Camera.GetOrbitalPosition().y, - m_Camera.GetOrbitalPosition().z + m_camera.get_orbital_position().x, + m_camera.get_orbital_position().y, + m_camera.get_orbital_position().z ); - DONUT_INFO("Camera radius: {}", m_Camera.GetOrbitalRadius()); + DONUT_INFO("Camera radius: {}", m_camera.get_orbital_radius()); DONUT_INFO("========================"); } - void Engine::ExportHighResFrame(const std::string& filename, int width, int height) + auto Engine::export_high_res_frame(const std::string& filename, int width, int height) -> void { DONUT_INFO("Exporting high-resolution frame: {}x{} to {}", width, height, filename); @@ -476,48 +476,48 @@ namespace Donut return; } - int originalWidth = m_Width; - int originalHeight = m_Height; - int originalComputeHeight = m_ComputeHeight; + int original_width = m_width; + int original_height = m_height; + int original_compute_height = m_compute_height; - m_Width = width; - m_Height = height; - m_ComputeHeight = height; + m_width = width; + m_height = height; + m_compute_height = height; - int computeHeight = height; - int computeWidth = (width * computeHeight) / height; + int compute_height = height; + int compute_width = (width * compute_height) / height; - if (computeWidth <= 0 || computeHeight <= 0) + if (compute_width <= 0 || compute_height <= 0) { - DONUT_ERROR("Invalid compute dimensions: {}x{}", computeWidth, computeHeight); + DONUT_ERROR("Invalid compute dimensions: {}x{}", compute_width, compute_height); return; } - FramebufferSpecification fbSpec; - fbSpec.Width = width; - fbSpec.Height = height; - fbSpec.Attachments = { FramebufferTextureFormat::RGBA8 }; + FramebufferSpecification fb_spec; + fb_spec.Width = width; + fb_spec.Height = height; + fb_spec.attachments = { FramebufferTextureFormat::RGBA8 }; - auto highResFramebuffer = Framebuffer::Create(fbSpec); - if (!highResFramebuffer) + auto high_res_framebuffer = Framebuffer::create(fb_spec); + if (!high_res_framebuffer) { DONUT_ERROR("Failed to create high-resolution framebuffer"); return; } - auto highResTexture = Texture2D::Create(computeWidth, computeHeight); - if (!highResTexture) + auto high_res_texture = Texture2D::create(compute_width, compute_height); + if (!high_res_texture) { DONUT_ERROR("Failed to create high-resolution texture"); return; } - // Render the geodesic pass into highResTexture through the geodesic FBO. - glBindFramebuffer(GL_FRAMEBUFFER, m_GeodesicFBO); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, highResTexture->GetRendererID(), 0); - glViewport(0, 0, computeWidth, computeHeight); + // Render the geodesic pass into high_res_texture through the geodesic FBO. + glBindFramebuffer(GL_FRAMEBUFFER, m_geodesic_fbo); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, high_res_texture->get_renderer_id(), 0); + glViewport(0, 0, compute_width, compute_height); - m_ComputeProgram->Bind(); + m_compute_program->bind(); struct UBOData { @@ -525,90 +525,90 @@ namespace Donut glm::vec3 right; float _pad1; glm::vec3 up; float _pad2; glm::vec3 forward; float _pad3; - float tanHalfFov; + float tan_half_fov; float aspect; bool moving; int _pad4; } data; - glm::vec3 fwd = glm::normalize(m_Camera.GetOrbitalTarget() - m_Camera.GetOrbitalPosition()); + glm::vec3 fwd = glm::normalize(m_camera.get_orbital_target() - m_camera.get_orbital_position()); glm::vec3 up = glm::vec3(0, 1, 0); glm::vec3 right = glm::normalize(glm::cross(fwd, up)); up = glm::cross(right, fwd); - data.pos = m_Camera.GetOrbitalPosition(); + data.pos = m_camera.get_orbital_position(); data.right = right; data.up = up; data.forward = fwd; - data.tanHalfFov = static_cast(tan(glm::radians(60.0f * 0.5f))); - data.aspect = static_cast(computeWidth) / static_cast(computeHeight); - data.moving = m_Camera.IsDragging() || m_Camera.IsPanning(); + data.tan_half_fov = static_cast(tan(glm::radians(60.0f * 0.5f))); + data.aspect = static_cast(compute_width) / static_cast(compute_height); + data.moving = m_camera.is_dragging() || m_camera.is_panning(); - m_CameraUBO->SetData(&data, sizeof(UBOData)); - m_CameraUBO->Bind(1); + m_camera_ubo->set_data(&data, sizeof(UBOData)); + m_camera_ubo->bind(1); - UploadDiskUBO(); - UploadObjectsUBO(m_Objects); - UploadSimulationUBO(); - m_ComputeProgram->SetFloat2("u_Resolution", glm::vec2(static_cast(computeWidth), static_cast(computeHeight))); + upload_disk_ubo(); + upload_objects_ubo(m_objects); + upload_simulation_ubo(); + m_compute_program->set_float2("u_Resolution", glm::vec2(static_cast(compute_width), static_cast(compute_height))); - if (m_HDRIEnvironment) + if (m_hdri_environment) { - m_HDRIEnvironment->Bind(5); - m_ComputeProgram->SetInt("u_HDRIEnvironment", 5); + m_hdri_environment->bind(5); + m_compute_program->set_int("u_HDRIEnvironment", 5); } - DrawGeodesicPass(computeWidth, computeHeight); + draw_geodesic_pass(compute_width, compute_height); // Display the rendered frame into the high-res framebuffer for read-back. - highResFramebuffer->Bind(); - RenderCommand::SetViewport(0, 0, width, height); - RenderCommand::Clear(); + high_res_framebuffer->bind(); + RenderCommand::set_viewport(0, 0, width, height); + RenderCommand::clear(); - m_ShaderProgram->Bind(); - m_QuadVAO->Bind(); + m_shader_program->bind(); + m_quad_vao->bind(); - highResTexture->Bind(0); - m_ShaderProgram->SetInt("u_ScreenTexture", 0); + high_res_texture->bind(0); + m_shader_program->set_int("u_ScreenTexture", 0); - RenderCommand::DisableDepthTest(); - RenderCommand::DrawArrays(6); - RenderCommand::EnableDepthTest(); + RenderCommand::disable_depth_test(); + RenderCommand::draw_arrays(6); + RenderCommand::enable_depth_test(); std::vector pixels(width * height * 4); DONUT_INFO("Reading {} pixels from framebuffer...", width * height); - RenderCommand::ReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data()); + RenderCommand::read_pixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data()); DONUT_INFO("Flipping image vertically..."); - std::vector flippedPixels(width * height * 4); + std::vector flipped_pixels(width * height * 4); for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { - int srcIndex = (y * width + x) * 4; - int dstIndex = ((height - 1 - y) * width + x) * 4; - flippedPixels[dstIndex + 0] = pixels[srcIndex + 0]; // R - flippedPixels[dstIndex + 1] = pixels[srcIndex + 1]; // G - flippedPixels[dstIndex + 2] = pixels[srcIndex + 2]; // B - flippedPixels[dstIndex + 3] = pixels[srcIndex + 3]; // A + int src_index = (y * width + x) * 4; + int dst_index = ((height - 1 - y) * width + x) * 4; + flipped_pixels[dst_index + 0] = pixels[src_index + 0]; // R + flipped_pixels[dst_index + 1] = pixels[src_index + 1]; // G + flipped_pixels[dst_index + 2] = pixels[src_index + 2]; // B + flipped_pixels[dst_index + 3] = pixels[src_index + 3]; // A } } DONUT_INFO("Saving PNG file: {}...", filename); - int result = stbi_write_png(filename.c_str(), width, height, 4, flippedPixels.data(), width * 4); + int result = stbi_write_png(filename.c_str(), width, height, 4, flipped_pixels.data(), width * 4); if (result) DONUT_INFO("Successfully exported high-resolution frame to: {}", filename); else DONUT_ERROR("Failed to export high-resolution frame to: {}", filename); - highResFramebuffer->Unbind(); + high_res_framebuffer->unbind(); - m_Width = originalWidth; - m_Height = originalHeight; - m_ComputeHeight = originalComputeHeight; + m_width = original_width; + m_height = original_height; + m_compute_height = original_compute_height; - RenderCommand::SetViewport(0, 0, originalWidth, originalHeight); + RenderCommand::set_viewport(0, 0, original_width, original_height); } } diff --git a/src/Engine/Engine.h b/src/Engine/Engine.h index a4cbdc7..c7d02b5 100644 --- a/src/Engine/Engine.h +++ b/src/Engine/Engine.h @@ -8,15 +8,15 @@ #include #include -#include "Core/Camera.h" -#include "Object.h" +#include "core/camera.h" +#include "object.h" -#include "Rendering/Renderer.h" -#include "Rendering/Shader.h" -#include "Rendering/VertexArray.h" -#include "Rendering/Texture.h" -#include "Rendering/UniformBuffer.h" -#include "Rendering/TextureManager.h" +#include "rendering/renderer.h" +#include "rendering/shader.h" +#include "rendering/vertex_array.h" +#include "rendering/texture.h" +#include "rendering/uniform_buffer.h" +#include "rendering/texture_manager.h" #include #include @@ -30,33 +30,33 @@ namespace Donut struct BlackHole { - glm::vec3 m_Position; - double m_Mass; - double m_Radius; - double m_Rs; + glm::vec3 m_position; + double m_mass; + double m_radius; + double m_rs; BlackHole(glm::vec3 pos, float mass) - : m_Position(pos), m_Mass(mass) + : m_position(pos), m_mass(mass) { - m_Rs = 2.0 * G * m_Mass / (c * c); + m_rs = 2.0 * G * m_mass / (c * c); } - bool Intercept(float px, float py, float pz) const + bool intercept(float px, float py, float pz) const { - double dx = double(px) - double(m_Position.x); - double dy = double(py) - double(m_Position.y); - double dz = double(pz) - double(m_Position.z); + double dx = double(px) - double(m_position.x); + double dy = double(py) - double(m_position.y); + double dz = double(pz) - double(m_position.z); double dist2 = dx * dx + dy * dy + dz * dz; - return dist2 < m_Rs * m_Rs; + return dist2 < m_rs * m_rs; } }; struct ObjectData { - glm::vec4 m_PosRadius; - glm::vec4 m_Color; - float m_Mass; - glm::vec3 m_Velocity = glm::vec3(0.0f, 0.0f, 0.0f); + glm::vec4 m_pos_radius; + glm::vec4 m_color; + float m_mass; + glm::vec3 m_velocity = glm::vec3(0.0f, 0.0f, 0.0f); }; class Engine @@ -65,120 +65,120 @@ namespace Donut Engine(); ~Engine() = default; - void DrawFullScreenQuad(); - void DrawBlurPass(); - void DispatchCompute(const Camera& cam); - void UploadCameraUBO(const Camera& cam); - void UploadObjectsUBO(const std::vector& objs); - void UploadDiskUBO(); - void UploadSimulationUBO(); - void RenderScene(); - void UpdatePhysics(float deltaTime); - void UpdateWindowDimensions(); - void SetWindowDimensions(int width, int height); - - int GetWidth() const { return m_Width; } - int GetHeight() const { return m_Height; } - - std::vector& GetObjects() { return m_Objects; } - BlackHole& GetSagA() { return m_SagA; } - Camera& GetCamera() { return m_Camera; } - bool& GetGravity() { return m_Gravity; } - - void UpdatePerformance(float deltaTime); - void SetTargetFPS(int fps) { m_TargetFPS = fps; } - int GetTargetFPS() const { return m_TargetFPS; } - float GetCurrentFPS() const { return m_CurrentFPS; } - void SetComputeHeight(int height) + auto draw_full_screen_quad() -> void; + auto draw_blur_pass() -> void; + auto dispatch_compute(const Camera& cam) -> void; + auto upload_camera_ubo(const Camera& cam) -> void; + auto upload_objects_ubo(const std::vector& objs) -> void; + auto upload_disk_ubo() -> void; + auto upload_simulation_ubo() -> void; + auto render_scene() -> void; + auto update_physics(float delta_time) -> void; + auto update_window_dimensions() -> void; + auto set_window_dimensions(int width, int height) -> void; + + auto get_width() const -> int { return m_width; } + auto get_height() const -> int { return m_height; } + + auto get_objects() -> std::vector& { return m_objects; } + auto get_sag_a() -> BlackHole& { return m_sag_a; } + auto get_camera() -> Camera& { return m_camera; } + auto get_gravity() -> bool& { return m_gravity; } + + auto update_performance(float delta_time) -> void; + auto set_target_fps(int fps) -> void { m_target_fps = fps; } + auto get_target_fps() const -> int { return m_target_fps; } + auto get_current_fps() const -> float { return m_current_fps; } + void set_compute_height(int height) { #ifdef __APPLE__ // Without compute shaders the geodesic pass runs as a tiled - // fragment shader (see DrawGeodesicPass), so very high working + // fragment shader (see draw_geodesic_pass), so very high working // resolutions make each frame take many seconds. Cap it on macOS. if (height > 256) height = 256; #endif - m_ComputeHeight = height; + m_compute_height = height; } - int GetComputeHeight() const { return m_ComputeHeight; } - int GetComputeWidth() const { return (m_Width * m_ComputeHeight) / m_Height; } - void UpdateComputeDimensions(); + auto get_compute_height() const -> int { return m_compute_height; } + auto get_compute_width() const -> int { return (m_width * m_compute_height) / m_height; } + auto update_compute_dimensions() -> void; - int GetMaxStepsMoving() const { return m_MaxStepsMoving; } - int GetMaxStepsStatic() const { return m_MaxStepsStatic; } - float GetEarlyExitDistance() const { return m_EarlyExitDistance; } - void SetMaxStepsMoving(int steps) { m_MaxStepsMoving = steps; } - void SetMaxStepsStatic(int steps) { m_MaxStepsStatic = steps; } - void SetEarlyExitDistance(float distance) { m_EarlyExitDistance = distance; } + auto get_max_steps_moving() const -> int { return m_max_steps_moving; } + auto get_max_steps_static() const -> int { return m_max_steps_static; } + auto get_early_exit_distance() const -> float { return m_early_exit_distance; } + auto set_max_steps_moving(int steps) -> void { m_max_steps_moving = steps; } + auto set_max_steps_static(int steps) -> void { m_max_steps_static = steps; } + auto set_early_exit_distance(float distance) -> void { m_early_exit_distance = distance; } - float GetDiskThickness() const { return m_DiskThickness; } - void SetDiskThickness(float thickness) { m_DiskThickness = thickness; } + auto get_disk_thickness() const -> float { return m_disk_thickness; } + auto set_disk_thickness(float thickness) -> void { m_disk_thickness = thickness; } - float GetDiskDensity() const { return m_DiskDensity; } - void SetDiskDensity(float density) { m_DiskDensity = density; } + auto get_disk_density() const -> float { return m_disk_density; } + auto set_disk_density(float density) -> void { m_disk_density = density; } - float GetRotationSpeed() const { return m_RotationSpeed; } - void SetRotationSpeed(float speed) { m_RotationSpeed = speed; } + auto get_rotation_speed() const -> float { return m_rotation_speed; } + auto set_rotation_speed(float speed) -> void { m_rotation_speed = speed; } - float GetBlurStrength() const { return m_BlurStrength; } - void SetBlurStrength(float strength) { m_BlurStrength = strength; } + auto get_blur_strength() const -> float { return m_blur_strength; } + auto set_blur_strength(float strength) -> void { m_blur_strength = strength; } - float GetGlowIntensity() const { return m_GlowIntensity; } - void SetGlowIntensity(float intensity) { m_GlowIntensity = intensity; } + auto get_glow_intensity() const -> float { return m_glow_intensity; } + auto set_glow_intensity(float intensity) -> void { m_glow_intensity = intensity; } - void LoadObjectsFromScene(const std::vector& objects); - void ExportHighResFrame(const std::string& filename, int width = 4096, int height = 3072); - void PrintObjectInfo() const; + auto load_objects_from_scene(const std::vector& objects) -> void; + auto export_high_res_frame(const std::string& filename, int width = 4096, int height = 3072) -> void; + auto print_object_info() const -> void; - void SetHDRIEnvironment(Ref hdri) { m_HDRIEnvironment = hdri; } - Ref GetHDRIEnvironment() const { return m_HDRIEnvironment; } + auto set_hdri_environment(Ref hdri) -> void { m_hdri_environment = hdri; } + auto get_hdri_environment() const -> Ref { return m_hdri_environment; } private: - Ref CreateComputeProgram(const char* path); + auto create_compute_program(const char* path) -> Ref; std::pair, Ref> QuadVAO(); // Draws the bound geodesic shader over a cw x ch target. On macOS this // is split into scissored tiles (with a flush each) so no single GPU // submission trips the OS watchdog; elsewhere it is one fast draw. - void DrawGeodesicPass(int cw, int ch); + auto draw_geodesic_pass(int cw, int ch) -> void; private: - Ref m_QuadVAO; - Ref m_Texture; - Ref m_HDRIEnvironment; - Ref m_ShaderProgram; - Ref m_ComputeProgram; - Ref m_BlurShader; - Ref m_CameraUBO; - Ref m_DiskUBO; - Ref m_ObjectsUBO; - Ref m_SimulationUBO; - - // FBO used to render the geodesic pass into m_Texture. The geodesic + Ref m_quad_vao; + Ref m_texture; + Ref m_hdri_environment; + Ref m_shader_program; + Ref m_compute_program; + Ref m_blur_shader; + Ref m_camera_ubo; + Ref m_disk_ubo; + Ref m_objects_ubo; + Ref m_simulation_ubo; + + // FBO used to render the geodesic pass into m_texture. The geodesic // shader is a fragment shader (macOS has no compute), so it draws a // fullscreen quad into this framebuffer instead of dispatching compute. - uint32_t m_GeodesicFBO = 0; - - int m_Width; - int m_Height; - float m_Width_f = 100.0f*1e10f; - float m_Height_f = 75.0f*1e10f; - - int m_TargetFPS = 60; - float m_CurrentFPS = 60.0f; - float m_LastFrameTime = 0.0f; - int m_ComputeHeight = 150; - - std::vector m_Objects; - BlackHole m_SagA; - Camera m_Camera; - bool m_Gravity = false; - - int m_MaxStepsMoving = 60000; - int m_MaxStepsStatic = 30000; - float m_EarlyExitDistance = 5.0e11f; - - float m_DiskThickness = 0.1f; - float m_DiskDensity = 0.1f; - float m_RotationSpeed = 1.0f; - float m_BlurStrength = 2.0f; - float m_GlowIntensity = 0.1f; + uint32_t m_geodesic_fbo = 0; + + int m_width; + int m_height; + float m_width_f = 100.0f*1e10f; + float m_height_f = 75.0f*1e10f; + + int m_target_fps = 60; + float m_current_fps = 60.0f; + float m_last_frame_time = 0.0f; + int m_compute_height = 150; + + std::vector m_objects; + BlackHole m_sag_a; + Camera m_camera; + bool m_gravity = false; + + int m_max_steps_moving = 60000; + int m_max_steps_static = 30000; + float m_early_exit_distance = 5.0e11f; + + float m_disk_thickness = 0.1f; + float m_disk_density = 0.1f; + float m_rotation_speed = 1.0f; + float m_blur_strength = 2.0f; + float m_glow_intensity = 0.1f; }; }; diff --git a/src/Engine/Object.h b/src/Engine/Object.h index 842708e..8101540 100644 --- a/src/Engine/Object.h +++ b/src/Engine/Object.h @@ -7,67 +7,70 @@ namespace Donut class Ray { public: - glm::vec3 m_Direction; - glm::vec3 m_Origin; + Ray(glm::vec3 o, glm::vec3 d) + : m_origin(o), + m_direction(glm::normalize(d)) { } - Ray(glm::vec3 o, glm::vec3 d) - : m_Origin(o), - m_Direction(glm::normalize(d)) { } + public: + glm::vec3 m_direction; + glm::vec3 m_origin; }; class Material { public: - glm::vec3 m_Color; - float m_Specular; - float m_Emission; - - Material() : m_Color(1.0f, 1.0f, 1.0f), m_Specular(0.5f), m_Emission(0.0f) { } + Material() : m_color(1.0f, 1.0f, 1.0f), m_specular(0.5f), m_emission(0.0f) { } Material(glm::vec3 c, float s, float e) - : m_Color(c), - m_Specular(s), - m_Emission(e) { } + : m_color(c), + m_specular(s), + m_emission(e) { } + + public: + glm::vec3 m_color; + float m_specular; + float m_emission; }; class Object { public: - glm::vec3 m_Centre; - float m_Radius; - Material m_Material; - - Object() : m_Centre(0.0f, 0.0f, 0.0f), m_Radius(1.0f), m_Material() { } - Object(glm::vec3 c, float r, Material m) - : m_Centre(c), - m_Radius(r), - m_Material(m) { } - - bool Intersect(Ray &ray, float &t) + Object() : m_centre(0.0f, 0.0f, 0.0f), m_radius(1.0f), m_material() { } + Object(glm::vec3 c, float r, Material m) + : m_centre(c), + m_radius(r), + m_material(m) { } + + auto intersect(Ray& ray, float& t) -> bool { - glm::vec3 oc = ray.m_Origin - m_Centre; - float a = glm::dot(ray.m_Direction, ray.m_Direction); - float b = 2.0f * glm::dot(oc, ray.m_Direction); - float c = glm::dot(oc, oc) - m_Radius * m_Radius; + glm::vec3 oc = ray.m_origin - m_centre; + float a = glm::dot(ray.m_direction, ray.m_direction); + float b = 2.0f * glm::dot(oc, ray.m_direction); + float c = glm::dot(oc, oc) - m_radius * m_radius; float discriminant = static_cast(b*b - 4*a*c); - if(discriminant < 0) + if (discriminant < 0) return false; - + float intercept = (-b - sqrt(discriminant)) / (2.0f*a); - if(intercept < 0) + if (intercept < 0) { intercept = (-b + sqrt(discriminant)) / (2.0f*a); - if(intercept<0) + if (intercept < 0) return false; } t = intercept; return true; } - - glm::vec3 GetNormal(glm::vec3 &point) const + + auto get_normal(glm::vec3& point) const -> glm::vec3 { - return glm::normalize(point - m_Centre); + return glm::normalize(point - m_centre); } + + public: + glm::vec3 m_centre; + float m_radius; + Material m_material; }; }; diff --git a/src/Engine/Scene.h b/src/Engine/Scene.h index f85fc13..4b41203 100644 --- a/src/Engine/Scene.h +++ b/src/Engine/Scene.h @@ -3,67 +3,68 @@ #include #include -#include "Object.h" +#include "object.h" namespace Donut { - class Scene + class Scene { public: - std::vector objs; - glm::vec3 m_LightPos; + Scene() + : m_light_pos(5.0f, 5.0f, 5.0f) { } - Scene() - : m_LightPos(5.0f, 5.0f, 5.0f) { } - - glm::vec3 Trace(Ray &ray) + auto trace(Ray& ray) -> glm::vec3 { float closest = std::numeric_limits::infinity(); - const Object* hitObj = nullptr; - - for(auto& obj : objs) + const Object* hit_obj = nullptr; + + for (auto& obj : objs) { float t; - if(obj.Intersect(ray, t)) - if(t < closest) + if (obj.intersect(ray, t)) + if (t < closest) { closest = t; - hitObj = &obj; + hit_obj = &obj; } } - - if(hitObj) + + if (hit_obj) { - glm::vec3 hitPoint = ray.m_Origin + ray.m_Direction * closest; - glm::vec3 normal = hitObj->GetNormal(hitPoint); - glm::vec3 lightDir = glm::normalize(m_LightPos - hitPoint); - - float diff = std::max(glm::dot(normal, lightDir), 0.0f); - - Ray shadowRay(hitPoint + normal * 0.001f, lightDir); - bool inShadow = false; - - for(auto& obj : objs) + glm::vec3 hit_point = ray.m_origin + ray.m_direction * closest; + glm::vec3 normal = hit_obj->get_normal(hit_point); + glm::vec3 light_dir = glm::normalize(m_light_pos - hit_point); + + float diff = std::max(glm::dot(normal, light_dir), 0.0f); + + Ray shadow_ray(hit_point + normal * 0.001f, light_dir); + bool in_shadow = false; + + for (auto& obj : objs) { float t; - if(obj.Intersect(shadowRay, t)) + if (obj.intersect(shadow_ray, t)) { - inShadow = true; + in_shadow = true; break; } } - - glm::vec3 color = hitObj->m_Material.m_Color; + + glm::vec3 color = hit_obj->m_material.m_color; float ambient = 0.1f; - - if (inShadow) + + if (in_shadow) return color * ambient; return color * (ambient + diff * 0.9f); } - - return glm::vec3(0.0f, 0.0f, 0.1f); + + return glm::vec3(0.0f, 0.0f, 0.1f); } + + public: + std::vector objs; + glm::vec3 m_light_pos; }; -}; \ No newline at end of file +}; -- cgit v1.3