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:
2026-03-08 19:27:00 +08:00
parent 79f56b60a0
commit c1bb8f9fba
15 changed files with 380 additions and 159 deletions

View File

@ -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())
{

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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();
}

View File

@ -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; // 阻尼系数(无输入时的减速速率)
};
}

View File

@ -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 {

View File

@ -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++;
}

View File

@ -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));

View File

@ -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;
};

View File

@ -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)

View File

@ -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;

View File

@ -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;
}
}