diff --git a/Editor/Editor/EditorLayer.cpp b/Editor/Editor/EditorLayer.cpp index 61ef8b1..8bc513e 100644 --- a/Editor/Editor/EditorLayer.cpp +++ b/Editor/Editor/EditorLayer.cpp @@ -102,6 +102,7 @@ namespace Prism } } + // Draw Colliders if (!m_SelectionContext.empty()) { auto& selection = m_SelectionContext[0]; @@ -492,6 +493,7 @@ namespace Prism m_ObjectsPanel->OnImGuiRender(); m_SceneHierarchyPanel->OnImGuiRender(); + m_EditorCamera.OnImGuiRender(); // Editor Panel ------------------------------------------------------------------------------ ImGui::Begin("Environment"); @@ -880,14 +882,17 @@ namespace Prism m_RuntimeScene->OnEvent(e); } - EventDispatcher dispatcher(e); - dispatcher.Dispatch(PM_BIND_EVENT_FN(EditorLayer::OnKeyPressedEvent)); - dispatcher.Dispatch(PM_BIND_EVENT_FN(EditorLayer::OnMouseButtonPressedEvent)); + if (Input::GetCursorMode() == CursorMode::Normal) + { + EventDispatcher dispatcher(e); + dispatcher.Dispatch(PM_BIND_EVENT_FN(EditorLayer::OnKeyPressedEvent)); + dispatcher.Dispatch(PM_BIND_EVENT_FN(EditorLayer::OnMouseButtonPressedEvent)); + } } bool EditorLayer::OnKeyPressedEvent(KeyPressedEvent& e) { - if (m_ViewportPanelHovered) + if (m_ViewportPanelFocused) { switch (e.GetKeyCode()) { diff --git a/Editor/assets/editor/Camera.png b/Editor/assets/editor/Camera.png new file mode 100644 index 0000000..11c8163 Binary files /dev/null and b/Editor/assets/editor/Camera.png differ diff --git a/Editor/assets/editor/light.png b/Editor/assets/editor/light.png new file mode 100644 index 0000000..6f235b0 Binary files /dev/null and b/Editor/assets/editor/light.png differ diff --git a/Editor/assets/shaders/Renderer2D.glsl b/Editor/assets/shaders/Renderer2D.glsl index 203cc89..26c7206 100644 --- a/Editor/assets/shaders/Renderer2D.glsl +++ b/Editor/assets/shaders/Renderer2D.glsl @@ -6,14 +6,14 @@ layout(location = 0) in vec3 a_Position; layout(location = 1) in vec4 a_Color; layout(location = 2) in vec2 a_TexCoord; -layout(location = 3) in float a_TexIndex; +layout(location = 3) in int a_TexIndex; layout(location = 4) in float a_TilingFactor; uniform mat4 u_ViewProjection; out vec4 v_Color; out vec2 v_TexCoord; -out float v_TexIndex; +flat out int v_TexIndex; out float v_TilingFactor; void main() @@ -32,12 +32,17 @@ layout(location = 0) out vec4 color; in vec4 v_Color; in vec2 v_TexCoord; -in float v_TexIndex; +flat in int v_TexIndex; in float v_TilingFactor; uniform sampler2D u_Textures[32]; void main() { - color = texture(u_Textures[int(v_TexIndex)], v_TexCoord * v_TilingFactor) * v_Color; + vec4 texColor = texture(u_Textures[v_TexIndex], v_TexCoord * v_TilingFactor) * v_Color; + + if(texColor.a < 0.1) + discard; + + color = texColor; } diff --git a/Prism/src/Prism/Core/ImGui/ImGui.h b/Prism/src/Prism/Core/ImGui/ImGui.h index 6b6e462..b90a53a 100644 --- a/Prism/src/Prism/Core/ImGui/ImGui.h +++ b/Prism/src/Prism/Core/ImGui/ImGui.h @@ -41,6 +41,11 @@ namespace Prism::UI { ImGui::Columns(2); } + static void Separator() + { + ImGui::Separator(); + } + static bool Property(const char* label, std::string& value, const bool error = false) { bool modified = false; diff --git a/Prism/src/Prism/Core/KeyCodes.h b/Prism/src/Prism/Core/KeyCodes.h index c2ac9f5..9278538 100644 --- a/Prism/src/Prism/Core/KeyCodes.h +++ b/Prism/src/Prism/Core/KeyCodes.h @@ -9,9 +9,10 @@ namespace Prism { enum class CursorMode { - Normal = 0, - Hidden = 1, - Locked = 2 + Normal = 0, + Hidden = 1, + Disable = 2, + Capture = 3 }; typedef enum class MouseButton : uint16_t diff --git a/Prism/src/Prism/Editor/EditorCamera.cpp b/Prism/src/Prism/Editor/EditorCamera.cpp index d8f477f..0d974d8 100644 --- a/Prism/src/Prism/Editor/EditorCamera.cpp +++ b/Prism/src/Prism/Editor/EditorCamera.cpp @@ -46,11 +46,93 @@ namespace Prism void EditorCamera::OnUpdate(TimeStep deltaTime) { - if (Input::IsKeyPressed(Key::LEFT_ALT)) + const bool altPressed = Input::IsKeyPressed(Key::LEFT_ALT); + + if (Input::IsMouseButtonPressed(MouseButton::Right) && !altPressed) { + Input::SetCursorMode(CursorMode::Disable); + + if (!m_IsRightButtonDownState) + { + m_InitialMousePosition = { Input::GetMouseX(), Input::GetMouseY() }; + m_IsRightButtonDownState = true; + m_FreeLookActive = true; + m_FreeLookPosition = m_Position; + m_Velocity = glm::vec3(0.0f); + } + + const glm::vec2& mouse{ Input::GetMouseX(), Input::GetMouseY() }; + glm::vec2 delta = (mouse - m_InitialMousePosition) * 0.002f; + m_InitialMousePosition = mouse; + m_Yaw += delta.x; + m_Pitch += delta.y; + m_Pitch = glm::clamp(m_Pitch, -1.5f, 1.5f); + + glm::vec3 desiredDir(0.0f); + if (Input::IsKeyPressed(Key::W)) desiredDir += GetForwardDirection(); + if (Input::IsKeyPressed(Key::S)) desiredDir -= GetForwardDirection(); + if (Input::IsKeyPressed(Key::A)) desiredDir -= GetRightDirection(); + if (Input::IsKeyPressed(Key::D)) desiredDir += GetRightDirection(); + + if (Input::IsKeyPressed(Key::Q)) desiredDir -= GetUpDirection(); + if (Input::IsKeyPressed(Key::E)) desiredDir += GetUpDirection(); + + if (glm::length(desiredDir) > 0.001f) + desiredDir = glm::normalize(desiredDir) * m_MaxSpeed; + else + desiredDir = glm::vec3(0.0f); + + // (desiredDir - m_Velocity) + const glm::vec3 accel = (desiredDir - m_Velocity) * m_Acceleration; + m_Velocity += accel * deltaTime.GetSeconds(); + + // m_Velocity *= (1.0f - m_Damping * deltaTime); + + m_FreeLookPosition += m_Velocity * deltaTime.GetSeconds(); + // --------------------------------- + + glm::quat orientation = GetOrientation(); + m_ViewMatrix = glm::translate(glm::mat4(1.0f), m_FreeLookPosition) * glm::toMat4(orientation); + m_ViewMatrix = glm::inverse(m_ViewMatrix); + m_Rotation = glm::eulerAngles(orientation) * (180.0f / (float)M_PI); + return; + } + else + { + if (m_IsRightButtonDownState) + { + Input::SetCursorMode(CursorMode::Normal); + m_IsRightButtonDownState = false; + if (m_FreeLookActive) + { + m_Position = m_FreeLookPosition; + m_FocalPoint = m_Position + GetForwardDirection() * m_Distance; + m_FreeLookActive = false; + } + } + } + + + // for alt process + + const bool anyMouseButtonPressed = Input::IsMouseButtonPressed(MouseButton::Left) || + Input::IsMouseButtonPressed(MouseButton::Middle) || + Input::IsMouseButtonPressed(MouseButton::Right); + + if (altPressed && anyMouseButtonPressed) + { + if (!m_IsAltKeyDownState) + { + Input::SetCursorMode(CursorMode::Disable); + m_IsAltKeyDownState = true; + + m_InitialMousePosition = { Input::GetMouseX(), Input::GetMouseY() }; + } + const glm::vec2& mouse{ Input::GetMouseX(), Input::GetMouseY() }; const glm::vec2 delta = (mouse - m_InitialMousePosition) * 0.003f; m_InitialMousePosition = mouse; + if (delta.x != 0.0f || delta.y != 0.0f) { if (Input::IsMouseButtonPressed(MouseButton::Middle)) @@ -60,6 +142,11 @@ namespace Prism else if (Input::IsMouseButtonPressed(MouseButton::Right)) MouseZoom(delta.y); } + }else if (m_IsAltKeyDownState) + { + Input::SetCursorMode(CursorMode::Normal); + m_IsAltKeyDownState = false; + return; } UpdateCameraView(); @@ -88,7 +175,8 @@ namespace Prism void EditorCamera::OnImGuiRender() { - ImGui::Begin("Camera Info"); + ImGui::Begin("Debug Camera Info"); + UI::BeginPropertyGrid(); UI::Property("yaw", m_Yaw); UI::Property("pitch", m_Pitch); UI::Property("focus", m_FocalPoint); @@ -96,6 +184,9 @@ namespace Prism UI::Property("rotation", m_Rotation); UI::Property("focus", m_FocalPoint); UI::Property("position", m_Position); + UI::Separator(); + UI::Property("Current Speed", m_Velocity); + UI::EndPropertyGrid(); ImGui::End(); } diff --git a/Prism/src/Prism/Editor/EditorCamera.h b/Prism/src/Prism/Editor/EditorCamera.h index e8b9c9d..b7abd22 100644 --- a/Prism/src/Prism/Editor/EditorCamera.h +++ b/Prism/src/Prism/Editor/EditorCamera.h @@ -79,6 +79,17 @@ namespace Prism float m_Pitch, m_Yaw; + + bool m_IsRightButtonDownState = false; + + bool m_IsAltKeyDownState = false; + bool m_FreeLookActive; + glm::vec3 m_FreeLookPosition; + + glm::vec3 m_Velocity = glm::vec3(0.0f); // 当前速度 + float m_MaxSpeed = 20.0f; // 最大移动速度(单位/秒) + float m_Acceleration = 10.0f; // 加速度系数(决定响应快慢) + float m_Damping = 5.0f; // 阻尼系数(无输入时的减速速率) }; } diff --git a/Prism/src/Prism/Editor/SceneHierachyPanel.cpp b/Prism/src/Prism/Editor/SceneHierachyPanel.cpp index 51534da..ac9474e 100644 --- a/Prism/src/Prism/Editor/SceneHierachyPanel.cpp +++ b/Prism/src/Prism/Editor/SceneHierachyPanel.cpp @@ -232,6 +232,30 @@ namespace Prism isCreated = true; SetSelected(newEntity); } + + if (ImGui::BeginMenu("Camera")) + { + if (ImGui::MenuItem("Orthographic Camera")) + { + auto newEntity = m_Context->CreateEntity("Camera"); + auto& component = newEntity.AddComponent(); + component.Camera.SetProjectionType(SceneCamera::ProjectionType::Orthographic); + + isCreated = true; + SetSelected(newEntity); + } + if (ImGui::MenuItem("Perspective Camera")) + { + auto newEntity = m_Context->CreateEntity("Camera"); + auto& component = newEntity.AddComponent(); + component.Camera.SetProjectionType(SceneCamera::ProjectionType::Perspective); + + isCreated = true; + SetSelected(newEntity); + } + ImGui::EndMenu(); + } + if (ImGui::MenuItem("Mesh")) { auto newEntity = m_Context->CreateEntity("Mesh"); @@ -239,23 +263,34 @@ namespace Prism isCreated = true; SetSelected(newEntity); } + ImGui::Separator(); - if (ImGui::MenuItem("Directional Light")) + + if (ImGui::BeginMenu("Light")) { - auto newEntity = m_Context->CreateEntity("Directional Light"); - newEntity.AddComponent(); - isCreated = true; - SetSelected(newEntity); - } - if (ImGui::MenuItem("Sky Light")) - { - auto newEntity = m_Context->CreateEntity("Sky Light"); - newEntity.AddComponent(); - isCreated = true; - SetSelected(newEntity); + if (ImGui::MenuItem("Sky Light")) + { + auto newEntity = m_Context->CreateEntity("Sky Light"); + newEntity.AddComponent(); + isCreated = true; + SetSelected(newEntity); + } + if (ImGui::MenuItem("Spot Light")) + { + PM_CORE_WARN("not impl"); + } + if (ImGui::MenuItem("Directional Light")) + { + auto newEntity = m_Context->CreateEntity("Directional Light"); + newEntity.AddComponent(); + isCreated = true; + SetSelected(newEntity); + } + ImGui::EndMenu(); } ImGui::EndMenu(); + if (isCreated) { if (m_SelectionChangedCallback) @@ -602,31 +637,6 @@ namespace Prism UI::BeginPropertyGrid(); UI::PropertyAssetReference("Mesh", meshComponent.Mesh, AssetType::Mesh); UI::EndPropertyGrid(); - - /* - ImGui::Columns(3); - ImGui::SetColumnWidth(0, 100); - ImGui::SetColumnWidth(1, 300); - ImGui::SetColumnWidth(2, 40); - ImGui::Text("File Path"); - ImGui::NextColumn(); - ImGui::PushItemWidth(-1); - - if (meshComponent.Mesh) - ImGui::InputText("##meshFilePath", (char*)meshComponent.Mesh->GetFilePath().c_str(), 256, ImGuiInputTextFlags_ReadOnly); - else - ImGui::InputText("##meshFilePath", (char*)"Null", 256, ImGuiInputTextFlags_ReadOnly); - - ImGui::PopItemWidth(); - ImGui::NextColumn(); - if (ImGui::Button("...##openmesh")) - { - const std::string file = Application::Get().OpenFile(); - if (!file.empty()) - meshComponent.Mesh = Ref::Create(file); - } - ImGui::Columns(1); - */ }); DrawComponent("Camera", entity, [](CameraComponent& cameraComponent) { @@ -660,7 +670,7 @@ namespace Prism float nearClip = cameraComponent.Camera.GetPerspectiveNearClip(); if (UI::Property("Near Clip", nearClip)) cameraComponent.Camera.SetPerspectiveNearClip(nearClip); - ImGui::SameLine(); + float farClip = cameraComponent.Camera.GetPerspectiveFarClip(); if (UI::Property("Far Clip", farClip)) cameraComponent.Camera.SetPerspectiveFarClip(farClip); @@ -676,7 +686,7 @@ namespace Prism float nearClip = cameraComponent.Camera.GetOrthographicNearClip(); if (UI::Property("Near Clip", nearClip)) cameraComponent.Camera.SetOrthographicNearClip(nearClip); - ImGui::SameLine(); + float farClip = cameraComponent.Camera.GetOrthographicFarClip(); if (UI::Property("Far Clip", farClip)) cameraComponent.Camera.SetOrthographicFarClip(farClip); @@ -704,8 +714,13 @@ namespace Prism UI::EndPropertyGrid(); }); - DrawComponent("Sprite Renderer", entity, [](SpriteRendererComponent& mc) + DrawComponent("Sprite Renderer", entity, [](SpriteRendererComponent& sc) { + UI::BeginPropertyGrid(); + UI::PropertyColor("Color", sc.Color); + UI::Property("Tiling Factor", sc.TilingFactor, 0.01f, 0.0f, 5.0f); + UI::PropertyAssetReference("Texture", sc.Texture, AssetType::Texture); + UI::EndPropertyGrid(); }); DrawComponent("Script", entity, [=](ScriptComponent& scriptComponent) mutable { diff --git a/Prism/src/Prism/Renderer/Renderer2D.cpp b/Prism/src/Prism/Renderer/Renderer2D.cpp index d2b564f..54b15e1 100644 --- a/Prism/src/Prism/Renderer/Renderer2D.cpp +++ b/Prism/src/Prism/Renderer/Renderer2D.cpp @@ -16,7 +16,7 @@ namespace Prism glm::vec3 Position; glm::vec4 Color; glm::vec2 TexCoord; - float TexIndex; + int TexIndex; float TilingFactor; }; @@ -99,7 +99,7 @@ namespace Prism { ShaderDataType::Float3, "a_Position" }, { ShaderDataType::Float4, "a_Color" }, { ShaderDataType::Float2, "a_TexCoord" }, - { ShaderDataType::Float, "a_TexIndex" }, + { ShaderDataType::Int, "a_TexIndex" }, { ShaderDataType::Float, "a_TilingFactor" } }; s_Data.QuadPipeline = Pipeline::Create(pipelineSpecification); @@ -278,8 +278,6 @@ namespace Prism void Renderer2D::DrawQuad(const glm::mat4& transform, const glm::vec4& color) { constexpr size_t quadVertexCount = 4; - const float textureIndex = 0.0f; // White Texture - constexpr float tilingFactor = 1.0f; if (s_Data.QuadIndexCount >= Renderer2DData::MaxIndices) FlushAndReset(); @@ -289,8 +287,8 @@ namespace Prism s_Data.QuadVertexBufferPtr->Position = transform * s_Data.QuadVertexPositions[i]; s_Data.QuadVertexBufferPtr->Color = color; s_Data.QuadVertexBufferPtr->TexCoord = defaultTexCoords[i]; - s_Data.QuadVertexBufferPtr->TexIndex = textureIndex; - s_Data.QuadVertexBufferPtr->TilingFactor = tilingFactor; + s_Data.QuadVertexBufferPtr->TexIndex = 0; + s_Data.QuadVertexBufferPtr->TilingFactor = 1.0f; s_Data.QuadVertexBufferPtr++; } @@ -302,27 +300,26 @@ namespace Prism void Renderer2D::DrawQuad(const glm::mat4& transform, const Ref& texture, float tilingFactor, const glm::vec4& tintColor) { constexpr size_t quadVertexCount = 4; - constexpr glm::vec4 color = { 1.0f, 1.0f, 1.0f, 1.0f }; if (s_Data.QuadIndexCount >= Renderer2DData::MaxIndices) FlushAndReset(); - float textureIndex = 0.0f; + int textureIndex = 0; for (uint32_t i = 1; i < s_Data.TextureSlotIndex; i++) { if (*s_Data.TextureSlots[i].Raw() == *texture.Raw()) { - textureIndex = (float)i; + textureIndex = i; break; } } - if (textureIndex == 0.0f) + if (textureIndex == 0) { if (s_Data.TextureSlotIndex >= Renderer2DData::MaxTextureSlots) FlushAndReset(); - textureIndex = (float)s_Data.TextureSlotIndex; + textureIndex = s_Data.TextureSlotIndex; s_Data.TextureSlots[s_Data.TextureSlotIndex] = texture; s_Data.TextureSlotIndex++; } @@ -330,7 +327,7 @@ namespace Prism for (size_t i = 0; i < quadVertexCount; i++) { s_Data.QuadVertexBufferPtr->Position = transform * s_Data.QuadVertexPositions[i]; - s_Data.QuadVertexBufferPtr->Color = color; + s_Data.QuadVertexBufferPtr->Color = tintColor; s_Data.QuadVertexBufferPtr->TexCoord = defaultTexCoords[i]; s_Data.QuadVertexBufferPtr->TexIndex = textureIndex; s_Data.QuadVertexBufferPtr->TilingFactor = tilingFactor; @@ -342,6 +339,27 @@ namespace Prism s_Data.Stats.QuadCount++; } + void Renderer2D::DrawBillBoardQuad(const glm::vec3& position, const Ref& texture, + const glm::vec3& cameraPos, const glm::vec3& upDirection, const float tilingFactor, const glm::vec4& tintColor) + { + const glm::vec3 forward = glm::normalize(cameraPos - position); + glm::vec3 up = upDirection; + if (glm::abs(glm::dot(forward, up)) > 0.999f) + up = glm::vec3(0.0f, 0.0f, 1.0f); // 备选上方向 + + const glm::vec3 right = glm::normalize(glm::cross(up, forward)); + const glm::vec3 correctedUp = glm::cross(forward, right); + + glm::mat4 rotation(1.0f); + rotation[0] = glm::vec4(right, 0.0f); + rotation[1] = glm::vec4(correctedUp, 0.0f); + rotation[2] = glm::vec4(forward, 0.0f); + + const glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) * rotation; + + DrawQuad(transform, texture, tilingFactor, tintColor); + } + void Renderer2D::DrawQuad(const glm::vec2& position, const glm::vec2& size, const glm::vec4& color) { DrawQuad({ position.x, position.y, 0.0f }, size, color); @@ -352,9 +370,6 @@ namespace Prism if (s_Data.QuadIndexCount >= Renderer2DData::MaxIndices) FlushAndReset(); - const float textureIndex = 0.0f; // White Texture - const float tilingFactor = 1.0f; - glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) * glm::scale(glm::mat4(1.0f), { size.x, size.y, 1.0f }); @@ -363,8 +378,8 @@ namespace Prism s_Data.QuadVertexBufferPtr->Position = transform * s_Data.QuadVertexPositions[i]; s_Data.QuadVertexBufferPtr->Color = color; s_Data.QuadVertexBufferPtr->TexCoord = defaultTexCoords[i]; - s_Data.QuadVertexBufferPtr->TexIndex = textureIndex; - s_Data.QuadVertexBufferPtr->TilingFactor = tilingFactor; + s_Data.QuadVertexBufferPtr->TexIndex = 0; + s_Data.QuadVertexBufferPtr->TilingFactor = 1.0f; s_Data.QuadVertexBufferPtr++; } @@ -385,25 +400,26 @@ namespace Prism constexpr glm::vec4 color = { 1.0f, 1.0f, 1.0f, 1.0f }; - float textureIndex = 0.0f; + int textureIndex = 0; for (uint32_t i = 1; i < s_Data.TextureSlotIndex; i++) { if (*s_Data.TextureSlots[i].Raw() == *texture.Raw()) { - textureIndex = (float)i; + textureIndex = i; break; } } if (textureIndex == 0.0f) { - textureIndex = (float)s_Data.TextureSlotIndex; + textureIndex = s_Data.TextureSlotIndex; s_Data.TextureSlots[s_Data.TextureSlotIndex] = texture; s_Data.TextureSlotIndex++; } - glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) - * glm::scale(glm::mat4(1.0f), { size.x, size.y, 1.0f }); + const glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) * + glm::scale(glm::mat4(1.0f), { size.x, size.y, 1.0f }); + for (uint32_t i = 0; i < 4; i++) { s_Data.QuadVertexBufferPtr->Position = transform * s_Data.QuadVertexPositions[i]; @@ -429,9 +445,6 @@ namespace Prism if (s_Data.QuadIndexCount >= Renderer2DData::MaxIndices) FlushAndReset(); - const float textureIndex = 0.0f; // White Texture - const float tilingFactor = 1.0f; - glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) * glm::rotate(glm::mat4(1.0f), rotation, { 0.0f, 0.0f, 1.0f }) * glm::scale(glm::mat4(1.0f), { size.x, size.y, 1.0f }); @@ -441,8 +454,8 @@ namespace Prism s_Data.QuadVertexBufferPtr->Position = transform * s_Data.QuadVertexPositions[i]; s_Data.QuadVertexBufferPtr->Color = color; s_Data.QuadVertexBufferPtr->TexCoord = defaultTexCoords[i]; - s_Data.QuadVertexBufferPtr->TexIndex = textureIndex; - s_Data.QuadVertexBufferPtr->TilingFactor = tilingFactor; + s_Data.QuadVertexBufferPtr->TexIndex = 0; + s_Data.QuadVertexBufferPtr->TilingFactor = 1.0f; s_Data.QuadVertexBufferPtr++; } @@ -463,19 +476,19 @@ namespace Prism constexpr glm::vec4 color = { 1.0f, 1.0f, 1.0f, 1.0f }; - float textureIndex = 0.0f; + int textureIndex = 0; for (uint32_t i = 1; i < s_Data.TextureSlotIndex; i++) { if (*s_Data.TextureSlots[i].Raw() == *texture.Raw()) { - textureIndex = (float)i; + textureIndex = i; break; } } if (textureIndex == 0.0f) { - textureIndex = (float)s_Data.TextureSlotIndex; + textureIndex = s_Data.TextureSlotIndex; s_Data.TextureSlots[s_Data.TextureSlotIndex] = texture; s_Data.TextureSlotIndex++; } diff --git a/Prism/src/Prism/Renderer/Renderer2D.h b/Prism/src/Prism/Renderer/Renderer2D.h index 3bf9fe4..418524e 100644 --- a/Prism/src/Prism/Renderer/Renderer2D.h +++ b/Prism/src/Prism/Renderer/Renderer2D.h @@ -25,6 +25,17 @@ namespace Prism static void DrawQuad(const glm::mat4& transform, const glm::vec4& color); static void DrawQuad(const glm::mat4& transform, const Ref& texture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f)); + /** + * draw a Billboard's texture + * @param position entity position + * @param texture entity texture + * @param cameraPos editcamera or camera postion + * @param upDirection default (0.0f, 1.0f, 0.0f) + * @param tilingFactor default 0 + * @param tintColor default (1.0f, 1.0f, 1.0f) + */ + static void DrawBillBoardQuad(const glm::vec3& position, const Ref& texture, const glm::vec3& cameraPos, const glm::vec3& upDirection = glm::vec3(0.0f, 1.0f, 0.0f), float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f)); + static void DrawQuad(const glm::vec2& position, const glm::vec2& size, const glm::vec4& color); static void DrawQuad(const glm::vec3& position, const glm::vec2& size, const glm::vec4& color); static void DrawQuad(const glm::vec2& position, const glm::vec2& size, const Ref& texture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f)); diff --git a/Prism/src/Prism/Scene/Components.h b/Prism/src/Prism/Scene/Components.h index 5818fa6..2e3d10c 100644 --- a/Prism/src/Prism/Scene/Components.h +++ b/Prism/src/Prism/Scene/Components.h @@ -19,6 +19,7 @@ #include #include +#include "Prism/Core/Math/Math.h" #include "Prism/Renderer/SceneEnvironment.h" namespace Prism @@ -53,6 +54,10 @@ namespace Prism }; + /** + * to storage entity Translation Rotation Scale info + * this Rotation is Euler angle + */ struct TransformComponent { @@ -69,6 +74,10 @@ namespace Prism TransformComponent(const glm::vec3& translation) : Translation(translation) {} + void SetTransform(const glm::mat4 &transform) + { + Math::DecomposeTransform(transform, Translation, Rotation, Scale); + } glm::mat4 GetTransform() const { return glm::translate(glm::mat4(1.0f), Translation) @@ -80,7 +89,7 @@ namespace Prism struct MeshComponent { - Ref Mesh; + Ref Mesh; MeshComponent() = default; MeshComponent(const MeshComponent& other) = default; @@ -122,6 +131,7 @@ namespace Prism float TilingFactor = 1.0f; SpriteRendererComponent() = default; + SpriteRendererComponent(const glm::vec4 &color) : Color(color){} SpriteRendererComponent(const SpriteRendererComponent& other) = default; }; diff --git a/Prism/src/Prism/Scene/Scene.cpp b/Prism/src/Prism/Scene/Scene.cpp index b3bd442..c5729fd 100644 --- a/Prism/src/Prism/Scene/Scene.cpp +++ b/Prism/src/Prism/Scene/Scene.cpp @@ -19,8 +19,11 @@ #define PX_PHYSX_STATIC_LIB #include +#include "Prism/Asset/AssetsManager.h" #include "Prism/Core/Input.h" #include "Prism/Core/Math/Math.h" +#include "Prism/Renderer/Renderer.h" +#include "Prism/Renderer/Renderer2D.h" namespace Prism { @@ -147,6 +150,9 @@ namespace Prism const auto skyboxShader = Shader::Create("assets/shaders/Skybox.glsl"); m_SkyboxMaterial = MaterialInstance::Create(Material::Create(skyboxShader)); m_SkyboxMaterial->SetFlag(MaterialFlag::DepthTest, false); + + m_CameraIcon = AssetsManager::GetAsset("assets/editor/Camera.png"); + m_LightIcon = AssetsManager::GetAsset("assets/editor/light.png"); } void Scene::OnShutdown() @@ -225,7 +231,7 @@ namespace Prism } } - void Scene::OnRenderRuntime(TimeStep ts) + void Scene::OnRenderRuntime(const TimeStep ts) { ///////////////////////////////////////////////////////////////////// // RENDER 3D SCENE // @@ -294,26 +300,33 @@ namespace Prism ///////////////////////////////////////////////////////////////////// -#if 0 - // Render all sprites - Renderer2D::BeginScene(*camera); + ///////////////////////////////////////////////////////////////////// + // RENDER 2D SCENE // + ///////////////////////////////////////////////////////////////////// + + Renderer::BeginRenderPass(SceneRenderer::GetFinalRenderPass(), false); + const glm::mat4 cameraViewProjection = cameraViewMatrix * camera.GetProjectionMatrix(); + Renderer2D::BeginScene(cameraViewProjection, false); + + // render sprite { - auto group = m_Registry.group(entt::get); - for (auto entity : group) + const auto entitiesGroup = m_Registry.group(entt::get); + for (const auto entity : entitiesGroup) { - auto [transformComponent, spriteRendererComponent] = group.get(entity); + auto [transformComponent, spriteRendererComponent] = entitiesGroup.get(entity); if (spriteRendererComponent.Texture) - Renderer2D::DrawQuad(transformComponent.Transform, spriteRendererComponent.Texture, spriteRendererComponent.TilingFactor); + Renderer2D::DrawQuad(transformComponent.GetTransform(), spriteRendererComponent.Texture, spriteRendererComponent.TilingFactor, spriteRendererComponent.Color); else - Renderer2D::DrawQuad(transformComponent.Transform, spriteRendererComponent.Color); + Renderer2D::DrawQuad(transformComponent.GetTransform(), spriteRendererComponent.Color); } } + Renderer2D::EndScene(); -#endif + Renderer::EndRenderPass(); } - void Scene::OnRenderEditor(TimeStep ts, const EditorCamera& editorCamera) + void Scene::OnRenderEditor(const TimeStep ts, const EditorCamera& editorCamera) { ///////////////////////////////////////////////////////////////////// // RENDER 3D SCENE // @@ -340,111 +353,148 @@ namespace Prism // TODO: only one sky light at the moment! { - m_Environment = Ref::Create(); auto lights = m_Registry.group(entt::get); - for (auto entity : lights) + if (!lights.empty()) { - auto [transformComponent, skyLightComponent] = lights.get(entity); - m_Environment = skyLightComponent.SceneEnvironment; - m_EnvironmentIntensity = skyLightComponent.Intensity; - SetSkybox(m_Environment->RadianceMap); + for (auto entity : lights) + { + auto [transformComponent, skyLightComponent] = lights.get(entity); + m_Environment = skyLightComponent.SceneEnvironment; + m_EnvironmentIntensity = skyLightComponent.Intensity; + SetSkybox(m_Environment->RadianceMap); + } + }else + { + // TODO: } } m_SkyboxMaterial->Set("u_TextureLod", m_SkyboxLod); auto group = m_Registry.group(entt::get); - // SceneRenderer::BeginScene(this, { static_cast(editorCamera), editorCamera.GetViewMatrix() }); SceneRenderer::BeginScene(this, { static_cast(editorCamera), editorCamera.GetViewMatrix(), 0.1f, 1000.0f, 45.0f }); // TODO: real values - for (const auto entity : group) { - const auto& [transformComponent, meshComponent] = group.get(entity); - if (meshComponent.Mesh) + for (const auto entity : group) { - meshComponent.Mesh->OnUpdate(ts); + const auto& [transformComponent, meshComponent] = group.get(entity); + if (meshComponent.Mesh) + { + meshComponent.Mesh->OnUpdate(ts); - glm::mat4 transform = GetTransformRelativeToParent(Entity{ entity, this }); + glm::mat4 transform = GetTransformRelativeToParent(Entity{ entity, this }); - // TODO: Should we render (logically) - if (m_SelectedEntity == entity) - SceneRenderer::SubmitSelectedMesh(meshComponent, transform); - else - SceneRenderer::SubmitMesh(meshComponent, transform); + // TODO: Should we render (logically) + if (m_SelectedEntity == entity) + SceneRenderer::SubmitSelectedMesh(meshComponent, transform); + else + SceneRenderer::SubmitMesh(meshComponent, transform); + } } - } - { - const auto view = m_Registry.view(); - for (const auto entity : view) { - Entity e = { entity, this }; - auto& collider = e.GetComponent(); - glm::mat4 transform = GetTransformRelativeToParent(e); + const auto view = m_Registry.view(); + for (const auto entity : view) + { + Entity e = { entity, this }; + auto& collider = e.GetComponent(); + glm::mat4 transform = GetTransformRelativeToParent(e); - if (m_SelectedEntity == entity) - SceneRenderer::SubmitColliderMesh(collider, transform); + if (m_SelectedEntity == entity) + SceneRenderer::SubmitColliderMesh(collider, transform); + } } - } - { - const auto view = m_Registry.view(); - for (const auto entity : view) { - Entity e = { entity, this }; - auto& collider = e.GetComponent(); - glm::mat4 transform = GetTransformRelativeToParent(e); + const auto view = m_Registry.view(); + for (const auto entity : view) + { + Entity e = { entity, this }; + auto& collider = e.GetComponent(); + glm::mat4 transform = GetTransformRelativeToParent(e); - if (m_SelectedEntity == entity) - SceneRenderer::SubmitColliderMesh(collider, transform); + if (m_SelectedEntity == entity) + SceneRenderer::SubmitColliderMesh(collider, transform); + } } - } - { - const auto view = m_Registry.view(); - for (const auto entity : view) { - Entity e = { entity, this }; - auto& collider = e.GetComponent(); - glm::mat4 transform = GetTransformRelativeToParent(e); + const auto view = m_Registry.view(); + for (const auto entity : view) + { + Entity e = { entity, this }; + auto& collider = e.GetComponent(); + glm::mat4 transform = GetTransformRelativeToParent(e); - if (m_SelectedEntity == entity) - SceneRenderer::SubmitColliderMesh(collider, transform); + if (m_SelectedEntity == entity) + SceneRenderer::SubmitColliderMesh(collider, transform); + } } - } - { - const auto view = m_Registry.view(); - for (const auto entity : view) { - Entity e = { entity, this }; - auto& collider = e.GetComponent(); - glm::mat4 transform = GetTransformRelativeToParent(e); + const auto view = m_Registry.view(); + for (const auto entity : view) + { + Entity e = { entity, this }; + auto& collider = e.GetComponent(); + glm::mat4 transform = GetTransformRelativeToParent(e); - if (m_SelectedEntity == entity) - SceneRenderer::SubmitColliderMesh(collider, transform); + if (m_SelectedEntity == entity) + SceneRenderer::SubmitColliderMesh(collider, transform); + } } } SceneRenderer::EndScene(); ///////////////////////////////////////////////////////////////////// -#if 0 - // Render all sprites - Renderer2D::BeginScene(*camera); + + ///////////////////////////////////////////////////////////////////// + // RENDER 2D SCENE // + ///////////////////////////////////////////////////////////////////// + + Renderer::BeginRenderPass(SceneRenderer::GetFinalRenderPass(), false); + const auto viewProj = editorCamera.GetViewProjection(); + Renderer2D::BeginScene(viewProj, false); + + // render sprite { - auto group = m_Registry.group(entt::get); - for (auto entity : group) + const auto entitiesGroup = m_Registry.group(entt::get); + for (const auto entity : entitiesGroup) { - auto [transformComponent, spriteRendererComponent] = group.get(entity); + auto [transformComponent, spriteRendererComponent] = entitiesGroup.get(entity); if (spriteRendererComponent.Texture) - Renderer2D::DrawQuad(transformComponent.Transform, spriteRendererComponent.Texture, spriteRendererComponent.TilingFactor); + Renderer2D::DrawQuad(transformComponent.GetTransform(), spriteRendererComponent.Texture, spriteRendererComponent.TilingFactor, spriteRendererComponent.Color); else - Renderer2D::DrawQuad(transformComponent.Transform, spriteRendererComponent.Color); + Renderer2D::DrawQuad(transformComponent.GetTransform(), spriteRendererComponent.Color); } } - Renderer2D::EndScene(); -#endif + + // render camera icon + { + const auto cameras = m_Registry.view(); + if (!cameras.empty()) + { + for (auto& entity : cameras) + { + Entity e = { entity, this }; + Renderer2D::DrawBillBoardQuad(e.Transform().Translation, m_CameraIcon, editorCamera.GetPosition(), editorCamera.GetUpDirection()); + } + } + + const auto lights = m_Registry.view(); + if (!lights.empty()) + { + for (auto& entity : lights) + { + Entity e = { entity, this }; + Renderer2D::DrawBillBoardQuad(e.Transform().Translation, m_LightIcon, editorCamera.GetPosition(), editorCamera.GetUpDirection()); + } + } + } + + Renderer2D::EndScene(); + Renderer::EndRenderPass(); } void Scene::OnEvent(Event& e) diff --git a/Prism/src/Prism/Scene/Scene.h b/Prism/src/Prism/Scene/Scene.h index 73051e4..2926c54 100644 --- a/Prism/src/Prism/Scene/Scene.h +++ b/Prism/src/Prism/Scene/Scene.h @@ -137,6 +137,10 @@ namespace Prism float m_SkyboxLod = 1.0f; + + Ref m_CameraIcon; + Ref m_LightIcon; + private: friend class Entity; friend class SceneRenderer; diff --git a/Prism/src/Prism/Scene/SceneCamera.cpp b/Prism/src/Prism/Scene/SceneCamera.cpp index 6ee8c03..570e598 100644 --- a/Prism/src/Prism/Scene/SceneCamera.cpp +++ b/Prism/src/Prism/Scene/SceneCamera.cpp @@ -43,7 +43,7 @@ namespace Prism const float aspect = (float)width / (float)height; const float w = m_OrthographicSize * aspect; const float h = m_OrthographicSize; - m_ProjectionMatrix = glm::ortho(-w * 0.5f, w * 0.5f, -h * 0.5f, h * 0.5f); + m_ProjectionMatrix = glm::ortho(-w * 0.5f, w * 0.5f, -h * 0.5f, h * 0.5f, m_OrthographicNear, m_OrthographicFar); break; } }