diff --git a/assets/shaders/color3d.glsl b/assets/shaders/color3d.glsl new file mode 100644 index 0000000..8bdf313 --- /dev/null +++ b/assets/shaders/color3d.glsl @@ -0,0 +1,93 @@ +#type vertex +#version 450 core + +layout(location = 0) in vec3 a_Position; +layout(location = 1) in vec4 a_Color; +layout(location = 2) in vec3 a_Normal; +layout(location = 3) in vec2 a_TexCoord; +layout(location = 4) in int a_EntityID; + +layout(std140, binding = 0) uniform Camera +{ + mat4 u_ViewProjection; + vec3 u_ViewPosition; +}; + +layout(std140, binding = 1) uniform Transform +{ + mat4 u_Transform; +}; + +struct VertexOutput +{ + vec4 Color; + vec2 TexCoord; + vec3 Normal; + vec3 ViewPos; +}; + +layout (location = 0) out VertexOutput Output; +layout (location = 4) out flat int v_EntityID; +layout (location = 5) out vec4 v_Pos; + +void main() +{ + Output.Color = a_Color; + Output.TexCoord = a_TexCoord; + Output.Normal = mat3(transpose(inverse(u_Transform))) * a_Normal; + Output.ViewPos = u_ViewPosition; + + v_EntityID = a_EntityID; + + v_Pos = u_Transform * vec4(a_Position, 1.0); + gl_Position = u_ViewProjection * v_Pos; +} + +#type fragment +#version 450 core + +layout (location = 0) out vec4 color; +layout (location = 1) out int color2; + +struct VertexOutput +{ + vec4 Color; + vec2 TexCoord; + vec3 Normal; + vec3 ViewPos; +}; + +layout (location = 0) in VertexOutput Input; +layout (location = 4) in flat int v_EntityID; +layout (location = 5) in vec4 v_Pos; + +void main() +{ + vec3 lightPos = vec3(0.0f, 1.0f, 0.0f); + vec3 lightColor = vec3(1.0f, 1.0f, 1.0f); + + // Ambiant lighting + float ambientStrength = 0.8; + vec3 ambient = ambientStrength * lightColor; + + // Diffuse lighting + vec3 norm = normalize(Input.Normal); + vec3 lightDir = normalize(lightPos - v_Pos.xyz); + + float diff = max(dot(norm, lightDir), 0.0); + vec3 diffuse = diff * lightColor; + + // Specular highlight + float specularStrength = 0.5; + vec3 viewDir = normalize(Input.ViewPos - v_Pos.xyz); // .xyz here too + vec3 reflectDir = reflect(-lightDir, norm); + + float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32); + vec3 specular = specularStrength * spec * lightColor; + + vec3 result = (ambient + diffuse + specular) * Input.Color.rgb; // objectColor → Input.Color.rgb + + // Output + color = vec4(result, 1.0); // vec3 → vec4 + color2 = v_EntityID; +} diff --git a/conanfile.txt b/conanfile.txt index f26bc0b..b7fcf28 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -3,6 +3,7 @@ imgui/1.92.5-docking spdlog/1.16.0 entt/3.16.0 yaml-cpp/0.8.0 +joltphysics/5.2.0 [generators] CMakeDeps diff --git a/editor/include/editor.hpp b/editor/include/editor.hpp index 54d7780..edf230b 100755 --- a/editor/include/editor.hpp +++ b/editor/include/editor.hpp @@ -306,12 +306,16 @@ namespace OpenEngine { void DrawViewport() { ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 0, 0 }); - ImGui::Begin("Viewport"); + + bool was_focused = viewport_focused; viewport_focused = ImGui::IsWindowFocused(ImGuiFocusedFlags_RootWindow); viewport_hovered = ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow); Application::Get().GetImGuiLayer()->SetBlockEvents((!viewport_focused && !viewport_hovered) || ImGui::IsAnyItemActive()); + if (viewport_focused && !was_focused) + editor_camera.ResetMousePosition(); + ImVec2 viewport_panel_size = ImGui::GetContentRegionAvail(); viewport_size = { viewport_panel_size.x, viewport_panel_size.y }; diff --git a/open_engine/include/open_engine/renderer/editor_camera.hpp b/open_engine/include/open_engine/renderer/editor_camera.hpp index aaa242e..6c4d959 100644 --- a/open_engine/include/open_engine/renderer/editor_camera.hpp +++ b/open_engine/include/open_engine/renderer/editor_camera.hpp @@ -31,6 +31,7 @@ namespace OpenEngine { glm::vec3 GetForwardDirection() const; const glm::vec3& GetPosition() const { return position; } glm::quat GetOrientation() const; + void ResetMousePosition(); float GetPitch() const { return pitch; } float GetYaw() const { return yaw; } @@ -61,6 +62,7 @@ namespace OpenEngine { glm::vec3 focal_point = { 0.0f, 0.0f, 0.0f }; glm::vec2 initial_mouse_position = { 0.0f, 0.0f }; + bool mouse_button_was_pressed = false; float distance = 10.0f; float pitch = 0.0f, yaw = 0.0f; diff --git a/open_engine/src/open_engine/renderer/editor_camera.cpp b/open_engine/src/open_engine/renderer/editor_camera.cpp index 9017b10..de34503 100644 --- a/open_engine/src/open_engine/renderer/editor_camera.cpp +++ b/open_engine/src/open_engine/renderer/editor_camera.cpp @@ -1,4 +1,3 @@ -#include "logging.hpp" #include #include @@ -63,10 +62,11 @@ namespace OpenEngine { void EditorCamera::OnUpdate() { + if (Input::IsKeyPressed(Key::LeftAlt)) { - const glm::vec2& mouse{ Input::GetMouseX(), Input::GetMouseY() }; - glm::vec2 delta = (mouse - initial_mouse_position) * 0.003f; - initial_mouse_position = mouse; + const glm::vec2& mouse{ Input::GetMouseX(), Input::GetMouseY() }; + glm::vec2 delta = (mouse - initial_mouse_position) * 0.003f; + initial_mouse_position = mouse; if (Input::IsMouseButtonPressed(Mouse::ButtonMiddle)) { MousePan(delta); @@ -151,4 +151,10 @@ namespace OpenEngine { return glm::quat(glm::vec3(-pitch, -yaw, 0.0f)); } + void EditorCamera::ResetMousePosition() + { + initial_mouse_position = { Input::GetMouseX(), Input::GetMouseY() }; + mouse_button_was_pressed = false; + } + } diff --git a/open_engine/src/open_engine/renderer/renderer3d.cpp b/open_engine/src/open_engine/renderer/renderer3d.cpp index d314cf3..5b5e1a4 100644 --- a/open_engine/src/open_engine/renderer/renderer3d.cpp +++ b/open_engine/src/open_engine/renderer/renderer3d.cpp @@ -93,12 +93,19 @@ namespace OpenEngine { }; std::vector indices = { - 0, 1, 2, 0, 2, 3, // back - 4, 6, 5, 4, 7, 6, // front - 8, 9, 10, 8, 10, 11, // left - 12, 14, 13, 12, 15, 14, // right - 16, 17, 18, 16, 18, 19, // top - 20, 23, 22, 20, 22, 21, // bottom + // Back face (z=-0.5) + 0, 1, 2, 0, 2, 3, + // Front face (z=0.5) + 4, 6, 5, 4, 7, 6, + // Right face + 12, 13, 14, 12, 14, 15, + // Left face + 8, 10, 9, 8, 11, 10, + // Top face + 18, 16, 17, 18, 19, 16, + // Bottom face + 20, 22, 21, 20, 23, 22 + // TODO: Missing backface }; return CreateMesh(vertices, indices); @@ -112,6 +119,7 @@ namespace OpenEngine { struct CameraData { glm::mat4 view_projection; + glm::vec3 view_position; }; CameraData camera_buffer; Ref camera_uniform_buffer; @@ -130,6 +138,9 @@ namespace OpenEngine { { OE_PROFILE_FUNCTION(); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + renderer_data.color_shader_3d = Shader::Create("assets/shaders/color3d.glsl"); renderer_data.camera_uniform_buffer = UniformBuffer::Create(sizeof(Renderer3DData::CameraData), 0); renderer_data.transform_uniform_buffer = UniformBuffer::Create(sizeof(Renderer3DData::TransformData), 1); @@ -153,6 +164,8 @@ namespace OpenEngine { OE_PROFILE_FUNCTION(); renderer_data.camera_buffer.view_projection = camera.GetProjection() * glm::inverse(transform); + renderer_data.camera_buffer.view_position = transform[3]; + renderer_data.camera_uniform_buffer->SetData(&renderer_data.camera_buffer, sizeof(Renderer3DData::CameraData)); } @@ -161,6 +174,8 @@ namespace OpenEngine { OE_PROFILE_FUNCTION(); renderer_data.camera_buffer.view_projection = camera.GetViewProjection(); + renderer_data.camera_buffer.view_position = camera.GetPosition(); + renderer_data.camera_uniform_buffer->SetData(&renderer_data.camera_buffer, sizeof(Renderer3DData::CameraData)); }