readd Sprite Renderer render and panel edit; in renderer scene, add icon for camera and light; improve a user-friendly EditorCamera, is more like UE Editor Camera; fix woring build m_ProjectionMatrix for SceneCamera::Orthographic
This commit is contained in:
@ -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<KeyPressedEvent>(PM_BIND_EVENT_FN(EditorLayer::OnKeyPressedEvent));
|
||||
dispatcher.Dispatch<MouseButtonPressedEvent>(PM_BIND_EVENT_FN(EditorLayer::OnMouseButtonPressedEvent));
|
||||
if (Input::GetCursorMode() == CursorMode::Normal)
|
||||
{
|
||||
EventDispatcher dispatcher(e);
|
||||
dispatcher.Dispatch<KeyPressedEvent>(PM_BIND_EVENT_FN(EditorLayer::OnKeyPressedEvent));
|
||||
dispatcher.Dispatch<MouseButtonPressedEvent>(PM_BIND_EVENT_FN(EditorLayer::OnMouseButtonPressedEvent));
|
||||
}
|
||||
}
|
||||
|
||||
bool EditorLayer::OnKeyPressedEvent(KeyPressedEvent& e)
|
||||
{
|
||||
if (m_ViewportPanelHovered)
|
||||
if (m_ViewportPanelFocused)
|
||||
{
|
||||
switch (e.GetKeyCode())
|
||||
{
|
||||
|
||||
BIN
Editor/assets/editor/Camera.png
Normal file
BIN
Editor/assets/editor/Camera.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
BIN
Editor/assets/editor/light.png
Normal file
BIN
Editor/assets/editor/light.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 64 KiB |
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
|
||||
@ -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; // 阻尼系数(无输入时的减速速率)
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -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<CameraComponent>();
|
||||
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<CameraComponent>();
|
||||
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<DirectionalLightComponent>();
|
||||
isCreated = true;
|
||||
SetSelected(newEntity);
|
||||
}
|
||||
if (ImGui::MenuItem("Sky Light"))
|
||||
{
|
||||
auto newEntity = m_Context->CreateEntity("Sky Light");
|
||||
newEntity.AddComponent<SkyLightComponent>();
|
||||
isCreated = true;
|
||||
SetSelected(newEntity);
|
||||
if (ImGui::MenuItem("Sky Light"))
|
||||
{
|
||||
auto newEntity = m_Context->CreateEntity("Sky Light");
|
||||
newEntity.AddComponent<SkyLightComponent>();
|
||||
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<DirectionalLightComponent>();
|
||||
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<Mesh>::Create(file);
|
||||
}
|
||||
ImGui::Columns(1);
|
||||
*/
|
||||
});
|
||||
|
||||
DrawComponent<CameraComponent>("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<SpriteRendererComponent>("Sprite Renderer", entity, [](SpriteRendererComponent& mc)
|
||||
DrawComponent<SpriteRendererComponent>("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<ScriptComponent>("Script", entity, [=](ScriptComponent& scriptComponent) mutable {
|
||||
|
||||
@ -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<Texture2D>& 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<Texture2D>& 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++;
|
||||
}
|
||||
|
||||
@ -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<Texture2D>& 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<Texture2D>& 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<Texture2D>& texture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
#include <utility>
|
||||
|
||||
#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<Prism::Mesh> Mesh;
|
||||
Ref<Mesh> 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;
|
||||
};
|
||||
|
||||
|
||||
@ -19,8 +19,11 @@
|
||||
#define PX_PHYSX_STATIC_LIB
|
||||
#include <PxPhysicsAPI.h>
|
||||
|
||||
#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<Texture2D>("assets/editor/Camera.png");
|
||||
m_LightIcon = AssetsManager::GetAsset<Texture2D>("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<TransformComponent>(entt::get<SpriteRenderer>);
|
||||
for (auto entity : group)
|
||||
const auto entitiesGroup = m_Registry.group<TransformComponent>(entt::get<SpriteRendererComponent>);
|
||||
for (const auto entity : entitiesGroup)
|
||||
{
|
||||
auto [transformComponent, spriteRendererComponent] = group.get<TransformComponent, SpriteRenderer>(entity);
|
||||
auto [transformComponent, spriteRendererComponent] = entitiesGroup.get<TransformComponent, SpriteRendererComponent>(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<Environment>::Create();
|
||||
auto lights = m_Registry.group<SkyLightComponent>(entt::get<TransformComponent>);
|
||||
for (auto entity : lights)
|
||||
if (!lights.empty())
|
||||
{
|
||||
auto [transformComponent, skyLightComponent] = lights.get<TransformComponent, SkyLightComponent>(entity);
|
||||
m_Environment = skyLightComponent.SceneEnvironment;
|
||||
m_EnvironmentIntensity = skyLightComponent.Intensity;
|
||||
SetSkybox(m_Environment->RadianceMap);
|
||||
for (auto entity : lights)
|
||||
{
|
||||
auto [transformComponent, skyLightComponent] = lights.get<TransformComponent, SkyLightComponent>(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<MeshComponent>(entt::get<TransformComponent>);
|
||||
// SceneRenderer::BeginScene(this, { static_cast<Camera>(editorCamera), editorCamera.GetViewMatrix() });
|
||||
SceneRenderer::BeginScene(this, { static_cast<Camera>(editorCamera), editorCamera.GetViewMatrix(), 0.1f, 1000.0f, 45.0f }); // TODO: real values
|
||||
for (const auto entity : group)
|
||||
{
|
||||
const auto& [transformComponent, meshComponent] = group.get<TransformComponent, MeshComponent>(entity);
|
||||
if (meshComponent.Mesh)
|
||||
for (const auto entity : group)
|
||||
{
|
||||
meshComponent.Mesh->OnUpdate(ts);
|
||||
const auto& [transformComponent, meshComponent] = group.get<TransformComponent, MeshComponent>(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<BoxColliderComponent>();
|
||||
for (const auto entity : view)
|
||||
{
|
||||
Entity e = { entity, this };
|
||||
auto& collider = e.GetComponent<BoxColliderComponent>();
|
||||
glm::mat4 transform = GetTransformRelativeToParent(e);
|
||||
const auto view = m_Registry.view<BoxColliderComponent>();
|
||||
for (const auto entity : view)
|
||||
{
|
||||
Entity e = { entity, this };
|
||||
auto& collider = e.GetComponent<BoxColliderComponent>();
|
||||
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<SphereColliderComponent>();
|
||||
for (const auto entity : view)
|
||||
{
|
||||
Entity e = { entity, this };
|
||||
auto& collider = e.GetComponent<SphereColliderComponent>();
|
||||
glm::mat4 transform = GetTransformRelativeToParent(e);
|
||||
const auto view = m_Registry.view<SphereColliderComponent>();
|
||||
for (const auto entity : view)
|
||||
{
|
||||
Entity e = { entity, this };
|
||||
auto& collider = e.GetComponent<SphereColliderComponent>();
|
||||
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<CapsuleColliderComponent>();
|
||||
for (const auto entity : view)
|
||||
{
|
||||
Entity e = { entity, this };
|
||||
auto& collider = e.GetComponent<CapsuleColliderComponent>();
|
||||
glm::mat4 transform = GetTransformRelativeToParent(e);
|
||||
const auto view = m_Registry.view<CapsuleColliderComponent>();
|
||||
for (const auto entity : view)
|
||||
{
|
||||
Entity e = { entity, this };
|
||||
auto& collider = e.GetComponent<CapsuleColliderComponent>();
|
||||
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<MeshColliderComponent>();
|
||||
for (const auto entity : view)
|
||||
{
|
||||
Entity e = { entity, this };
|
||||
auto& collider = e.GetComponent<MeshColliderComponent>();
|
||||
glm::mat4 transform = GetTransformRelativeToParent(e);
|
||||
const auto view = m_Registry.view<MeshColliderComponent>();
|
||||
for (const auto entity : view)
|
||||
{
|
||||
Entity e = { entity, this };
|
||||
auto& collider = e.GetComponent<MeshColliderComponent>();
|
||||
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<TransformComponent>(entt::get<SpriteRenderer>);
|
||||
for (auto entity : group)
|
||||
const auto entitiesGroup = m_Registry.group<TransformComponent>(entt::get<SpriteRendererComponent>);
|
||||
for (const auto entity : entitiesGroup)
|
||||
{
|
||||
auto [transformComponent, spriteRendererComponent] = group.get<TransformComponent, SpriteRenderer>(entity);
|
||||
auto [transformComponent, spriteRendererComponent] = entitiesGroup.get<TransformComponent, SpriteRendererComponent>(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<CameraComponent>();
|
||||
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<SkyLightComponent>();
|
||||
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)
|
||||
|
||||
@ -137,6 +137,10 @@ namespace Prism
|
||||
|
||||
float m_SkyboxLod = 1.0f;
|
||||
|
||||
|
||||
Ref<Texture2D> m_CameraIcon;
|
||||
Ref<Texture2D> m_LightIcon;
|
||||
|
||||
private:
|
||||
friend class Entity;
|
||||
friend class SceneRenderer;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user