From 0c77bdb5a48343005dfdf1509d004b36022efb32 Mon Sep 17 00:00:00 2001 From: hachem Date: Mon, 18 Aug 2025 05:02:13 +0200 Subject: fix: improvements, bump to C++20 and fix bugs --- src/states/world_builder_state.cpp | 206 ++++++++++++++++++++----------------- src/states/world_builder_state.h | 8 ++ 2 files changed, 121 insertions(+), 93 deletions(-) (limited to 'src/states') diff --git a/src/states/world_builder_state.cpp b/src/states/world_builder_state.cpp index 16b7866..ad0e57b 100644 --- a/src/states/world_builder_state.cpp +++ b/src/states/world_builder_state.cpp @@ -17,15 +17,11 @@ #include #include +#include #include #include #include -#define _USE_MATH_DEFINES -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - namespace Donut { void WorldBuilderState::on_enter() @@ -41,7 +37,7 @@ namespace Donut m_camera.set_orbital_speed(0.01f); m_camera.set_zoom_speed(2.0f); m_camera.set_azimuth(0.0f); - m_camera.set_elevation(static_cast(M_PI) / 3.0f); + m_camera.set_elevation(static_cast(std::numbers::pi) / 3.0f); m_camera.update_orbital(); Material default_material(glm::vec3(0.8f, 0.2f, 0.2f), 0.5f, 0.0f); @@ -56,6 +52,9 @@ namespace Donut Object sphere3(glm::vec3(0.0f, 2.0f, 0.0f), 0.8f, material3); m_scene.objs.push_back(sphere3); + m_sphere_shader = Ref(Shader::create("assets/shaders/sphere.glsl")); + initialize_sphere_geometry(); + m_initialized = true; } @@ -83,7 +82,7 @@ namespace Donut float new_azimuth = m_camera.get_azimuth() + azimuth_delta; float new_elevation = m_camera.get_elevation() + elevation_delta; - new_elevation = glm::clamp(new_elevation, 0.01f, static_cast(M_PI) - 0.01f); + new_elevation = glm::clamp(new_elevation, 0.01f, static_cast(std::numbers::pi) - 0.01f); m_camera.set_azimuth(new_azimuth); m_camera.set_elevation(new_elevation); @@ -95,7 +94,7 @@ namespace Donut void WorldBuilderState::on_render() { - RenderCommand::set_clear_color(glm::vec4(0.1f, 0.1f, 0.1f, 1.0f)); + RenderCommand::set_clear_color(glm::vec4(0.05f, 0.05f, 0.05f, 1.0f)); RenderCommand::clear(); render_scene(); } @@ -119,8 +118,8 @@ namespace Donut int width, height; glfwGetFramebufferSize(window, &width, &height); - float ndc_x = (2.0f * xpos) / width - 1.0f; - float ndc_y = 1.0f - (2.0f * ypos) / height; + float ndc_x = (2.0f * static_cast(xpos)) / static_cast(width) - 1.0f; + float ndc_y = 1.0f - (2.0f * static_cast(ypos)) / static_cast(height); glm::vec4 ray_start_ndc(ndc_x, ndc_y, -1.0f, 1.0f); glm::vec4 ray_end_ndc(ndc_x, ndc_y, 0.0f, 1.0f); @@ -174,8 +173,9 @@ namespace Donut } else { - m_camera_dragging = true; - m_last_mouse_pos = glm::vec2(xpos, ypos); + m_selected_object_index = -1; + m_camera_dragging = true; + m_last_mouse_pos = glm::vec2(xpos, ypos); } return true; @@ -288,7 +288,7 @@ namespace Donut { m_camera.set_orbital_radius(15.0f); m_camera.set_azimuth(0.0f); - m_camera.set_elevation(static_cast(M_PI) / 3.0f); + m_camera.set_elevation(static_cast(std::numbers::pi) / 3.0f); m_camera.set_orbital_target(glm::vec3(0.0f, 0.0f, 0.0f)); m_camera.update_orbital(); } @@ -377,6 +377,8 @@ namespace Donut } } } + + ImGui::Spacing(); if (ImGui::CollapsingHeader("Gizmo Controls", &m_show_gizmo_controls)) { @@ -395,6 +397,22 @@ namespace Donut ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "Hotkeys:"); ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "W = Translate, E = Rotate, R = Scale"); } + + ImGui::Spacing(); + + if (ImGui::CollapsingHeader("Selection Outline", &m_show_outline_controls)) + { + ImGui::TextColored(ImVec4(0.9f, 0.9f, 1.0f, 1.0f), "Outline Settings:"); + + ImGui::Text("Outline Color:"); + ImGui::ColorEdit3("##OutlineColor", &m_outline_color.x); + + ImGui::Text("Outline Width:"); + ImGui::SliderFloat("##OutlineWidth", &m_outline_width, 0.01f, 0.9f, "%.2f"); + + ImGui::Spacing(); + ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "White rim around sphere silhouette"); + } ImGui::Spacing(); ImGui::Separator(); @@ -550,85 +568,82 @@ namespace Donut DONUT_ERROR("Failed to load scene"); } - void WorldBuilderState::render_scene() + void WorldBuilderState::initialize_sphere_geometry() { - GLFWwindow* window = static_cast(Application::get().get_window().get_native_window()); - int width, height; - glfwGetFramebufferSize(window, &width, &height); - - RenderCommand::set_viewport(0, 0, width, height); - RenderCommand::enable_depth_test(); + std::vector vertices; + std::vector indices; - static Ref sphere_vao = nullptr; - static Ref sphere_shader = Ref(Shader::create("assets/shaders/sphere.glsl")); + const int segments = 32; + const int rings = 16; - if (!sphere_vao) + for (int ring = 0; ring <= rings; ++ring) { - std::vector vertices; - std::vector indices; - - const int segments = 32; - const int rings = 16; + float phi = static_cast(std::numbers::pi) * ring / rings; + float sin_phi = sin(phi); + float cos_phi = cos(phi); - for (int ring = 0; ring <= rings; ++ring) + for (int segment = 0; segment <= segments; ++segment) { - float phi = static_cast(M_PI) * ring / rings; - float sin_phi = sin(phi); - float cos_phi = cos(phi); + float theta = 2.0f * static_cast(std::numbers::pi) * segment / segments; + float sin_theta = sin(theta); + float cos_theta = cos(theta); - for (int segment = 0; segment <= segments; ++segment) - { - float theta = 2.0f * static_cast(M_PI) * segment / segments; - float sin_theta = sin(theta); - float cos_theta = cos(theta); - - float x = cos_theta * sin_phi; - float y = cos_phi; - float z = sin_theta * sin_phi; - - float nx = x; - float ny = y; - float nz = z; - - vertices.push_back(x); - vertices.push_back(y); - vertices.push_back(z); - vertices.push_back(nx); - vertices.push_back(ny); - vertices.push_back(nz); - } + float x = cos_theta * sin_phi; + float y = cos_phi; + float z = sin_theta * sin_phi; + + float nx = x; + float ny = y; + float nz = z; + + vertices.push_back(x); + vertices.push_back(y); + vertices.push_back(z); + vertices.push_back(nx); + vertices.push_back(ny); + vertices.push_back(nz); } - - for (int ring = 0; ring < rings; ++ring) + } + + for (int ring = 0; ring < rings; ++ring) + { + for (int segment = 0; segment < segments; ++segment) { - for (int segment = 0; segment < segments; ++segment) - { - uint32_t first = ring * (segments + 1) + segment; - uint32_t second = first + segments + 1; - - indices.push_back(first); - indices.push_back(second); - indices.push_back(first + 1); - - indices.push_back(second); - indices.push_back(second + 1); - indices.push_back(first + 1); - } + uint32_t first = ring * (segments + 1) + segment; + uint32_t second = first + segments + 1; + + indices.push_back(first); + indices.push_back(second); + indices.push_back(first + 1); + + indices.push_back(second); + indices.push_back(second + 1); + indices.push_back(first + 1); } - - auto vertex_buffer = Ref(VertexBuffer::create(vertices.data(), static_cast(vertices.size() * sizeof(float)))); - VertexBufferLayout layout; - layout.push(3); - layout.push(3); - vertex_buffer->set_layout(layout); - - auto index_buffer = Ref(IndexBuffer::create(indices.data(), static_cast(indices.size()))); - - sphere_vao = Ref(VertexArray::create()); - sphere_vao->add_vertex_buffer(vertex_buffer); - sphere_vao->set_index_buffer(index_buffer); } + auto vertex_buffer = Ref(VertexBuffer::create(vertices.data(), static_cast(vertices.size() * sizeof(float)))); + VertexBufferLayout layout; + layout.push(3); + layout.push(3); + vertex_buffer->set_layout(layout); + + auto index_buffer = Ref(IndexBuffer::create(indices.data(), static_cast(indices.size()))); + + m_sphere_vao = Ref(VertexArray::create()); + m_sphere_vao->add_vertex_buffer(vertex_buffer); + m_sphere_vao->set_index_buffer(index_buffer); + } + + void WorldBuilderState::render_scene() + { + GLFWwindow* window = static_cast(Application::get().get_window().get_native_window()); + int width, height; + glfwGetFramebufferSize(window, &width, &height); + + RenderCommand::set_viewport(0, 0, width, height); + RenderCommand::enable_depth_test(); + glm::mat4 view = m_camera.get_view_matrix(); glm::mat4 projection = m_camera.get_projection_matrix(); glm::mat4 view_projection = projection * view; @@ -636,10 +651,13 @@ namespace Donut glm::vec3 light_pos = m_scene.m_light_pos; glm::vec3 camera_pos = m_camera.get_orbital_position(); - sphere_shader->bind(); - sphere_shader->set_mat4("u_ViewProjection", view_projection); - sphere_shader->set_float3("u_LightPos", light_pos); - sphere_shader->set_float3("u_CameraPos", camera_pos); + m_sphere_shader->bind(); + m_sphere_shader->set_mat4("u_ViewProjection", view_projection); + m_sphere_shader->set_float3("u_LightPos", light_pos); + m_sphere_shader->set_float3("u_CameraPos", camera_pos); + + m_sphere_shader->set_float3("u_OutlineColor", m_outline_color); + m_sphere_shader->set_float("u_OutlineWidth", m_outline_width); for (size_t i = 0; i < m_scene.objs.size(); ++i) { @@ -648,25 +666,27 @@ namespace Donut glm::mat4 transform = glm::translate(glm::mat4(1.0f), obj.m_centre); transform = glm::scale(transform, glm::vec3(obj.m_radius)); - sphere_shader->set_mat4("u_Transform", transform); + m_sphere_shader->set_mat4("u_Transform", transform); - if (m_selected_object_index == static_cast(i)) + bool is_selected = (m_selected_object_index == static_cast(i)); + m_sphere_shader->set_int("u_IsSelected", is_selected ? 1 : 0); + if (is_selected) { glm::vec3 highlight_color = obj.m_material.m_color * 1.5f; highlight_color = glm::clamp(highlight_color, 0.0f, 1.0f); - sphere_shader->set_float3("u_Color", highlight_color); - sphere_shader->set_float("u_Emission", 0.2f); + m_sphere_shader->set_float3("u_Color", highlight_color); + m_sphere_shader->set_float("u_Emission", 0.2f); } else { - sphere_shader->set_float3("u_Color", obj.m_material.m_color); - sphere_shader->set_float("u_Emission", obj.m_material.m_emission); + m_sphere_shader->set_float3("u_Color", obj.m_material.m_color); + m_sphere_shader->set_float("u_Emission", obj.m_material.m_emission); } - sphere_shader->set_float("u_Specular", obj.m_material.m_specular); + m_sphere_shader->set_float("u_Specular", obj.m_material.m_specular); - sphere_vao->bind(); - RenderCommand::draw_indexed(sphere_vao); + m_sphere_vao->bind(); + RenderCommand::draw_indexed(m_sphere_vao); } RenderCommand::disable_depth_test(); diff --git a/src/states/world_builder_state.h b/src/states/world_builder_state.h index c587fbe..4cbe987 100644 --- a/src/states/world_builder_state.h +++ b/src/states/world_builder_state.h @@ -39,11 +39,15 @@ namespace Donut void save_scene(); void load_scene(); void render_scene(); + void initialize_sphere_geometry(); private: Scene m_scene; Camera m_camera; bool m_initialized = false; + Ref m_sphere_shader; + Ref m_sphere_vao; + glm::vec3 m_new_object_position = glm::vec3(0.0f, 0.0f, 0.0f); float m_new_object_radius = 1.0f; glm::vec3 m_new_object_color = glm::vec3(1.0f, 1.0f, 1.0f); @@ -61,5 +65,9 @@ namespace Donut bool m_show_object_creator = true; bool m_show_scene_info = true; bool m_show_gizmo_controls = true; + bool m_show_outline_controls = true; + + glm::vec3 m_outline_color = glm::vec3(1.0f, 1.0f, 1.0f); + float m_outline_width = 0.25f; }; }; -- cgit v1.3