add mouse picking, add more hdr environment maps
This commit is contained in:
@ -149,7 +149,7 @@ namespace Prism
|
|||||||
|
|
||||||
auto secondEntity = m_Scene->CreateEntity("Gun Entity");
|
auto secondEntity = m_Scene->CreateEntity("Gun Entity");
|
||||||
secondEntity->Transform() = glm::translate(glm::mat4(1.0f), { 5, 5, 5 }) * glm::scale(glm::mat4(1.0f), {10, 10, 10});
|
secondEntity->Transform() = glm::translate(glm::mat4(1.0f), { 5, 5, 5 }) * glm::scale(glm::mat4(1.0f), {10, 10, 10});
|
||||||
mesh = CreateRef<Mesh>("assets/models/m1911/m1911.fbx");
|
mesh = CreateRef<Mesh>("assets/models/m1911/m1911Materials.fbx");
|
||||||
secondEntity->SetMesh(mesh);
|
secondEntity->SetMesh(mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,9 +208,12 @@ namespace Prism
|
|||||||
// Editor
|
// Editor
|
||||||
m_CheckerboardTex = Texture2D::Create("assets/editor/Checkerboard.tga");
|
m_CheckerboardTex = Texture2D::Create("assets/editor/Checkerboard.tga");
|
||||||
|
|
||||||
// lights
|
// set lights
|
||||||
m_Light.Direction = {-0.5f, -0.5f, 1.0f};
|
auto& light = m_Scene->GetLight();
|
||||||
m_Light.Radiance = {1.0f, 1.0f, 1.0f};
|
light.Direction = { -0.5f, -0.5f, 1.0f };
|
||||||
|
light.Radiance = { 1.0f, 1.0f, 1.0f };
|
||||||
|
|
||||||
|
m_CurrentlySelectedTransform = &m_MeshEntity->Transform();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorLayer::OnDetach()
|
void EditorLayer::OnDetach()
|
||||||
@ -228,7 +231,6 @@ namespace Prism
|
|||||||
m_MeshMaterial->Set("u_AlbedoColor", m_AlbedoInput.Color);
|
m_MeshMaterial->Set("u_AlbedoColor", m_AlbedoInput.Color);
|
||||||
m_MeshMaterial->Set("u_Metalness", m_MetalnessInput.Value);
|
m_MeshMaterial->Set("u_Metalness", m_MetalnessInput.Value);
|
||||||
m_MeshMaterial->Set("u_Roughness", m_RoughnessInput.Value);
|
m_MeshMaterial->Set("u_Roughness", m_RoughnessInput.Value);
|
||||||
m_MeshMaterial->Set("lights", m_Light);
|
|
||||||
m_MeshMaterial->Set("u_AlbedoTexToggle", m_AlbedoInput.UseTexture ? 1.0f : 0.0f);
|
m_MeshMaterial->Set("u_AlbedoTexToggle", m_AlbedoInput.UseTexture ? 1.0f : 0.0f);
|
||||||
m_MeshMaterial->Set("u_NormalTexToggle", m_NormalInput.UseTexture ? 1.0f : 0.0f);
|
m_MeshMaterial->Set("u_NormalTexToggle", m_NormalInput.UseTexture ? 1.0f : 0.0f);
|
||||||
m_MeshMaterial->Set("u_MetalnessTexToggle", m_MetalnessInput.UseTexture ? 1.0f : 0.0f);
|
m_MeshMaterial->Set("u_MetalnessTexToggle", m_MetalnessInput.UseTexture ? 1.0f : 0.0f);
|
||||||
@ -236,7 +238,8 @@ namespace Prism
|
|||||||
m_MeshMaterial->Set("u_EnvMapRotation", m_EnvMapRotation);
|
m_MeshMaterial->Set("u_EnvMapRotation", m_EnvMapRotation);
|
||||||
|
|
||||||
m_SphereBaseMaterial->Set("u_AlbedoColor", m_AlbedoInput.Color);
|
m_SphereBaseMaterial->Set("u_AlbedoColor", m_AlbedoInput.Color);
|
||||||
m_SphereBaseMaterial->Set("lights", m_Light);
|
// m_SphereBaseMaterial->Set("lights", m_Light);
|
||||||
|
m_SphereBaseMaterial->Set("lights", m_Scene->GetLight());
|
||||||
m_SphereBaseMaterial->Set("u_RadiancePrefilter", m_RadiancePrefilter ? 1.0f : 0.0f);
|
m_SphereBaseMaterial->Set("u_RadiancePrefilter", m_RadiancePrefilter ? 1.0f : 0.0f);
|
||||||
m_SphereBaseMaterial->Set("u_AlbedoTexToggle", m_AlbedoInput.UseTexture ? 1.0f : 0.0f);
|
m_SphereBaseMaterial->Set("u_AlbedoTexToggle", m_AlbedoInput.UseTexture ? 1.0f : 0.0f);
|
||||||
m_SphereBaseMaterial->Set("u_NormalTexToggle", m_NormalInput.UseTexture ? 1.0f : 0.0f);
|
m_SphereBaseMaterial->Set("u_NormalTexToggle", m_NormalInput.UseTexture ? 1.0f : 0.0f);
|
||||||
@ -264,8 +267,19 @@ namespace Prism
|
|||||||
Renderer::BeginRenderPass(SceneRenderer::GetFinalRenderPass(), false);
|
Renderer::BeginRenderPass(SceneRenderer::GetFinalRenderPass(), false);
|
||||||
auto viewProj = m_Scene->GetCamera().GetViewProjection();
|
auto viewProj = m_Scene->GetCamera().GetViewProjection();
|
||||||
Renderer2D::BeginScene(viewProj, false);
|
Renderer2D::BeginScene(viewProj, false);
|
||||||
// Prism::Renderer2D::DrawQuad({ 0, 0, 0 }, { 4.0f, 5.0f }, { 1.0f, 1.0f, 0.5f, 1.0f });
|
Renderer::DrawAABB(m_MeshEntity->GetMesh(), m_MeshEntity->Transform());
|
||||||
Renderer::DrawAABB(m_MeshEntity->GetMesh());
|
|
||||||
|
Renderer2D::EndScene();
|
||||||
|
Renderer::EndRenderPass();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_SelectedSubmeshes.empty())
|
||||||
|
{
|
||||||
|
Renderer::BeginRenderPass(SceneRenderer::GetFinalRenderPass(), false);
|
||||||
|
const auto viewProj = m_Scene->GetCamera().GetViewProjection();
|
||||||
|
Renderer2D::BeginScene(viewProj, false);
|
||||||
|
const auto& submesh = m_SelectedSubmeshes[0];
|
||||||
|
Renderer::DrawAABB(submesh.Mesh->BoundingBox, m_MeshEntity->GetTransform() * submesh.Mesh->Transform);
|
||||||
Renderer2D::EndScene();
|
Renderer2D::EndScene();
|
||||||
Renderer::EndRenderPass();
|
Renderer::EndRenderPass();
|
||||||
}
|
}
|
||||||
@ -441,9 +455,10 @@ namespace Prism
|
|||||||
ImGui::Columns(2);
|
ImGui::Columns(2);
|
||||||
ImGui::AlignTextToFramePadding();
|
ImGui::AlignTextToFramePadding();
|
||||||
|
|
||||||
Property("Light Direction", m_Light.Direction);
|
auto& light = m_Scene->GetLight();
|
||||||
Property("Light Radiance", m_Light.Radiance, PropertyFlag::ColorProperty);
|
Property("Light Direction", light.Direction);
|
||||||
Property("Light Multiplier", m_LightMultiplier, 0.0f, 5.0f);
|
Property("Light Radiance", light.Radiance, PropertyFlag::ColorProperty);
|
||||||
|
Property("Light Multiplier", light.Multiplier, 0.0f, 5.0f);
|
||||||
Property("Exposure", m_ActiveScene->GetCamera().GetExposure(), 0.0f, 5.0f);
|
Property("Exposure", m_ActiveScene->GetCamera().GetExposure(), 0.0f, 5.0f);
|
||||||
|
|
||||||
Property("Radiance Prefiltering", m_RadiancePrefilter);
|
Property("Radiance Prefiltering", m_RadiancePrefilter);
|
||||||
@ -642,6 +657,8 @@ namespace Prism
|
|||||||
|
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
|
||||||
ImGui::Begin("Viewport");
|
ImGui::Begin("Viewport");
|
||||||
|
|
||||||
|
auto viewportOffset = ImGui::GetCursorPos(); // includes tab bar
|
||||||
auto viewportSize = ImGui::GetContentRegionAvail();
|
auto viewportSize = ImGui::GetContentRegionAvail();
|
||||||
SceneRenderer::SetViewportSize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
|
SceneRenderer::SetViewportSize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
|
||||||
m_ActiveScene->GetCamera().SetProjectionMatrix(glm::perspectiveFov(glm::radians(45.0f), viewportSize.x, viewportSize.y, 0.1f, 10000.0f));
|
m_ActiveScene->GetCamera().SetProjectionMatrix(glm::perspectiveFov(glm::radians(45.0f), viewportSize.x, viewportSize.y, 0.1f, 10000.0f));
|
||||||
@ -649,13 +666,19 @@ namespace Prism
|
|||||||
ImGui::Image((ImTextureRef)SceneRenderer::GetFinalColorBufferRendererID(), viewportSize, { 0, 1 }, { 1, 0 });
|
ImGui::Image((ImTextureRef)SceneRenderer::GetFinalColorBufferRendererID(), viewportSize, { 0, 1 }, { 1, 0 });
|
||||||
|
|
||||||
|
|
||||||
|
static int counter = 0;
|
||||||
auto windowSize = ImGui::GetWindowSize();
|
auto windowSize = ImGui::GetWindowSize();
|
||||||
ImVec2 minBound = ImGui::GetWindowPos();
|
ImVec2 minBound = ImGui::GetWindowPos();
|
||||||
|
minBound.x += viewportOffset.x;
|
||||||
|
minBound.y += viewportOffset.y;
|
||||||
|
|
||||||
ImVec2 maxBound = { minBound.x + windowSize.x, minBound.y + windowSize.y };
|
ImVec2 maxBound = { minBound.x + windowSize.x, minBound.y + windowSize.y };
|
||||||
|
m_ViewportBounds[0] = { minBound.x, minBound.y };
|
||||||
|
m_ViewportBounds[1] = { maxBound.x, maxBound.y };
|
||||||
m_AllowViewportCameraEvents = ImGui::IsMouseHoveringRect(minBound, maxBound);
|
m_AllowViewportCameraEvents = ImGui::IsMouseHoveringRect(minBound, maxBound);
|
||||||
|
|
||||||
// ImGuizmo
|
// ImGuizmo
|
||||||
if (m_GizmoType != -1)
|
if (m_GizmoType != -1 && m_CurrentlySelectedTransform)
|
||||||
{
|
{
|
||||||
const auto rw = (float)ImGui::GetWindowWidth();
|
const auto rw = (float)ImGui::GetWindowWidth();
|
||||||
const auto rh = (float)ImGui::GetWindowHeight();
|
const auto rh = (float)ImGui::GetWindowHeight();
|
||||||
@ -663,7 +686,15 @@ namespace Prism
|
|||||||
ImGuizmo::SetDrawlist();
|
ImGuizmo::SetDrawlist();
|
||||||
ImGuizmo::SetRect(ImGui::GetWindowPos().x, ImGui::GetWindowPos().y, rw, rh);
|
ImGuizmo::SetRect(ImGui::GetWindowPos().x, ImGui::GetWindowPos().y, rw, rh);
|
||||||
const auto& camera = m_ActiveScene->GetCamera();
|
const auto& camera = m_ActiveScene->GetCamera();
|
||||||
ImGuizmo::Manipulate(glm::value_ptr(camera.GetViewMatrix()), glm::value_ptr(camera.GetProjectionMatrix()), (ImGuizmo::OPERATION)m_GizmoType, ImGuizmo::LOCAL, glm::value_ptr(m_MeshEntity->Transform()));
|
|
||||||
|
bool snap = Input::IsKeyPressed(PM_KEY_LEFT_CONTROL);
|
||||||
|
ImGuizmo::Manipulate(glm::value_ptr(camera.GetViewMatrix()),
|
||||||
|
glm::value_ptr(camera.GetProjectionMatrix()),
|
||||||
|
(ImGuizmo::OPERATION)m_GizmoType,
|
||||||
|
ImGuizmo::LOCAL,
|
||||||
|
glm::value_ptr(m_MeshEntity->Transform()),
|
||||||
|
nullptr,
|
||||||
|
snap ? &m_SnapValue : nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
@ -678,6 +709,7 @@ namespace Prism
|
|||||||
|
|
||||||
EventDispatcher dispatcher(e);
|
EventDispatcher dispatcher(e);
|
||||||
dispatcher.Dispatch<KeyPressedEvent>(PM_BIND_EVENT_FN(EditorLayer::OnKeyPressedEvent));
|
dispatcher.Dispatch<KeyPressedEvent>(PM_BIND_EVENT_FN(EditorLayer::OnKeyPressedEvent));
|
||||||
|
dispatcher.Dispatch<MouseButtonPressedEvent>(PM_BIND_EVENT_FN(EditorLayer::OnMouseButtonPressedEvent));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EditorLayer::OnKeyPressedEvent(KeyPressedEvent& e)
|
bool EditorLayer::OnKeyPressedEvent(KeyPressedEvent& e)
|
||||||
@ -714,9 +746,85 @@ namespace Prism
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EditorLayer::OnMouseButtonPressedEvent(MouseButtonPressedEvent& e)
|
||||||
|
{
|
||||||
|
auto [mx, my] = Input::GetMousePosition();
|
||||||
|
if (e.GetMouseButton() == PM_MOUSE_BUTTON_LEFT && !Input::IsKeyPressed(PM_KEY_LEFT_ALT) && !ImGuizmo::IsOver())
|
||||||
|
{
|
||||||
|
auto [mouseX, mouseY] = GetMouseViewportSpace();
|
||||||
|
if (mouseX > -1.0f && mouseX < 1.0f && mouseY > -1.0f && mouseY < 1.0f)
|
||||||
|
{
|
||||||
|
auto [origin, direction] = CastRay(mouseX, mouseY);
|
||||||
|
|
||||||
|
m_SelectedSubmeshes.clear();
|
||||||
|
const auto mesh = m_MeshEntity->GetMesh();
|
||||||
|
auto& submeshes = mesh->GetSubmeshes();
|
||||||
|
float lastT = std::numeric_limits<float>::max();
|
||||||
|
for (uint32_t i = 0; i < submeshes.size(); i++)
|
||||||
|
{
|
||||||
|
auto& submesh = submeshes[i];
|
||||||
|
Ray ray = {
|
||||||
|
glm::inverse(m_MeshEntity->GetTransform() * submesh.Transform) * glm::vec4(origin, 1.0f),
|
||||||
|
glm::inverse(glm::mat3(m_MeshEntity->GetTransform()) * glm::mat3(submesh.Transform)) * direction
|
||||||
|
};
|
||||||
|
|
||||||
|
float t;
|
||||||
|
bool intersects = ray.IntersectsAABB(submesh.BoundingBox, t);
|
||||||
|
if (intersects)
|
||||||
|
{
|
||||||
|
const auto& triangleCache = mesh->GetTriangleCache(i);
|
||||||
|
for (const auto& triangle : triangleCache)
|
||||||
|
{
|
||||||
|
if (ray.IntersectsTriangle(triangle.V0.Position, triangle.V1.Position, triangle.V2.Position, t))
|
||||||
|
{
|
||||||
|
PM_CLIENT_WARN("INTERSECTION: {0}, t={1}", submesh.NodeName, t);
|
||||||
|
m_SelectedSubmeshes.push_back({ &submesh, t });
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::sort(m_SelectedSubmeshes.begin(), m_SelectedSubmeshes.end(), [](auto& a, auto& b) { return a.Distance < b.Distance; });
|
||||||
|
|
||||||
|
// TODO: Handle mesh being deleted, etc.
|
||||||
|
if (!m_SelectedSubmeshes.empty())
|
||||||
|
m_CurrentlySelectedTransform = &m_SelectedSubmeshes[0].Mesh->Transform;
|
||||||
|
else
|
||||||
|
m_CurrentlySelectedTransform = &m_MeshEntity->Transform();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void EditorLayer::ShowBoundingBoxes(bool show, bool onTop)
|
void EditorLayer::ShowBoundingBoxes(bool show, bool onTop)
|
||||||
{
|
{
|
||||||
SceneRenderer::GetOptions().ShowBoundingBoxes = show && !onTop;
|
SceneRenderer::GetOptions().ShowBoundingBoxes = show && !onTop;
|
||||||
m_DrawOnTopBoundingBoxes = show && onTop;
|
m_DrawOnTopBoundingBoxes = show && onTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<float, float> EditorLayer::GetMouseViewportSpace() const
|
||||||
|
{
|
||||||
|
auto [mx, my] = ImGui::GetMousePos(); // Input::GetMousePosition();
|
||||||
|
mx -= m_ViewportBounds[0].x;
|
||||||
|
my -= m_ViewportBounds[0].y;
|
||||||
|
const auto viewportWidth = m_ViewportBounds[1].x - m_ViewportBounds[0].x;
|
||||||
|
const auto viewportHeight = m_ViewportBounds[1].y - m_ViewportBounds[0].y;
|
||||||
|
|
||||||
|
return { (mx / viewportWidth) * 2.0f - 1.0f, ((my / viewportHeight) * 2.0f - 1.0f) * -1.0f };
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<glm::vec3, glm::vec3> EditorLayer::CastRay(const float mx, const float my) const
|
||||||
|
{
|
||||||
|
glm::vec4 mouseClipPos = { mx, my, -1.0f, 1.0f };
|
||||||
|
|
||||||
|
const auto inverseProj = glm::inverse(m_Scene->GetCamera().GetProjectionMatrix());
|
||||||
|
const auto inverseView = glm::inverse(glm::mat3(m_Scene->GetCamera().GetViewMatrix()));
|
||||||
|
|
||||||
|
const glm::vec4 ray = inverseProj * mouseClipPos;
|
||||||
|
glm::vec3 rayPos = m_Scene->GetCamera().GetPosition();
|
||||||
|
glm::vec3 rayDir = inverseView * glm::vec3(ray);
|
||||||
|
|
||||||
|
return { rayPos, rayDir };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,9 +24,14 @@ namespace Prism
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool OnKeyPressedEvent(KeyPressedEvent& e);
|
bool OnKeyPressedEvent(KeyPressedEvent& e);
|
||||||
|
bool OnMouseButtonPressedEvent(MouseButtonPressedEvent& e);
|
||||||
|
|
||||||
void ShowBoundingBoxes(bool show, bool onTop = false);
|
void ShowBoundingBoxes(bool show, bool onTop = false);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::pair<float, float> GetMouseViewportSpace() const;
|
||||||
|
std::pair<glm::vec3, glm::vec3> CastRay(float mx, float my) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Scope<SceneHierarchyPanel> m_SceneHierarchyPanel;
|
Scope<SceneHierarchyPanel> m_SceneHierarchyPanel;
|
||||||
|
|
||||||
@ -36,25 +41,27 @@ namespace Prism
|
|||||||
|
|
||||||
Entity* m_MeshEntity = nullptr;
|
Entity* m_MeshEntity = nullptr;
|
||||||
|
|
||||||
Ref<Shader> m_BrushShader;
|
|
||||||
Ref<Mesh> m_PlaneMesh;
|
Ref<Mesh> m_PlaneMesh;
|
||||||
Ref<Material> m_SphereBaseMaterial;
|
Ref<Material> m_SphereBaseMaterial;
|
||||||
|
|
||||||
Ref<Material> m_MeshMaterial;
|
Ref<Material> m_MeshMaterial;
|
||||||
|
|
||||||
Ref<RenderPass> m_GeoPass, m_CompositePass;
|
|
||||||
|
|
||||||
Ref<MaterialInstance> m_GridMaterial;
|
|
||||||
|
|
||||||
std::vector<Ref<MaterialInstance>> m_MetalSphereMaterialInstances;
|
std::vector<Ref<MaterialInstance>> m_MetalSphereMaterialInstances;
|
||||||
std::vector<Ref<MaterialInstance>> m_DielectricSphereMaterialInstances;
|
std::vector<Ref<MaterialInstance>> m_DielectricSphereMaterialInstances;
|
||||||
|
|
||||||
float m_GridScale = 16.025f, m_GridSize = 0.025f;
|
|
||||||
float m_MeshScale = 1.0f;
|
|
||||||
|
|
||||||
|
|
||||||
// Imguizmo
|
// Imguizmo
|
||||||
|
glm::vec2 m_ViewportBounds[2];
|
||||||
int m_GizmoType = -1; // -1 = no gizmo
|
int m_GizmoType = -1; // -1 = no gizmo
|
||||||
|
float m_SnapValue = 0.5f;
|
||||||
|
|
||||||
|
struct SelectedSubmesh
|
||||||
|
{
|
||||||
|
Submesh* Mesh;
|
||||||
|
float Distance;
|
||||||
|
};
|
||||||
|
std::vector<SelectedSubmesh> m_SelectedSubmeshes;
|
||||||
|
glm::mat4* m_CurrentlySelectedTransform = nullptr;
|
||||||
|
|
||||||
// configure button
|
// configure button
|
||||||
bool m_AllowViewportCameraEvents = false;
|
bool m_AllowViewportCameraEvents = false;
|
||||||
@ -97,14 +104,6 @@ namespace Prism
|
|||||||
RoughnessInput m_RoughnessInput;
|
RoughnessInput m_RoughnessInput;
|
||||||
|
|
||||||
|
|
||||||
struct Light
|
|
||||||
{
|
|
||||||
glm::vec3 Direction;
|
|
||||||
glm::vec3 Radiance;
|
|
||||||
};
|
|
||||||
Light m_Light;
|
|
||||||
float m_LightMultiplier = 0.3f;
|
|
||||||
|
|
||||||
// PBR params
|
// PBR params
|
||||||
bool m_RadiancePrefilter = false;
|
bool m_RadiancePrefilter = false;
|
||||||
|
|
||||||
|
|||||||
BIN
Editor/assets/env/pink_sunrise_4k.hdr
vendored
Normal file
BIN
Editor/assets/env/pink_sunrise_4k.hdr
vendored
Normal file
Binary file not shown.
BIN
Editor/assets/env/rooitou_park_4k.hdr
vendored
Normal file
BIN
Editor/assets/env/rooitou_park_4k.hdr
vendored
Normal file
Binary file not shown.
BIN
Editor/assets/env/venice_dawn_1_4k.hdr
vendored
Normal file
BIN
Editor/assets/env/venice_dawn_1_4k.hdr
vendored
Normal file
Binary file not shown.
BIN
Editor/assets/meshes/TestScene.blend
Normal file
BIN
Editor/assets/meshes/TestScene.blend
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -46,7 +46,7 @@ void main()
|
|||||||
vec4 localPosition = boneTransform * vec4(a_Position, 1.0);
|
vec4 localPosition = boneTransform * vec4(a_Position, 1.0);
|
||||||
|
|
||||||
vs_Output.WorldPosition = vec3(u_Transform * boneTransform * vec4(a_Position, 1.0));
|
vs_Output.WorldPosition = vec3(u_Transform * boneTransform * vec4(a_Position, 1.0));
|
||||||
vs_Output.Normal = mat3(boneTransform) * a_Normal;
|
vs_Output.Normal = mat3(u_Transform) * mat3(boneTransform) * a_Normal;
|
||||||
vs_Output.TexCoord = vec2(a_TexCoord.x, 1.0 - a_TexCoord.y);
|
vs_Output.TexCoord = vec2(a_TexCoord.x, 1.0 - a_TexCoord.y);
|
||||||
vs_Output.WorldNormals = mat3(u_Transform) * mat3(a_Tangent, a_Binormal, a_Normal);
|
vs_Output.WorldNormals = mat3(u_Transform) * mat3(a_Tangent, a_Binormal, a_Normal);
|
||||||
vs_Output.Binormal = mat3(boneTransform) * a_Binormal;
|
vs_Output.Binormal = mat3(boneTransform) * a_Binormal;
|
||||||
@ -68,6 +68,7 @@ const vec3 Fdielectric = vec3(0.04);
|
|||||||
struct Light {
|
struct Light {
|
||||||
vec3 Direction;
|
vec3 Direction;
|
||||||
vec3 Radiance;
|
vec3 Radiance;
|
||||||
|
float Multiplier;
|
||||||
};
|
};
|
||||||
|
|
||||||
in VertexOutput
|
in VertexOutput
|
||||||
@ -256,7 +257,7 @@ vec3 Lighting(vec3 F0)
|
|||||||
for(int i = 0; i < LightCount; i++)
|
for(int i = 0; i < LightCount; i++)
|
||||||
{
|
{
|
||||||
vec3 Li = -lights.Direction;
|
vec3 Li = -lights.Direction;
|
||||||
vec3 Lradiance = lights.Radiance;
|
vec3 Lradiance = lights.Radiance * lights.Multiplier;
|
||||||
vec3 Lh = normalize(Li + m_Params.View);
|
vec3 Lh = normalize(Li + m_Params.View);
|
||||||
|
|
||||||
// Calculate angles between surface normal and various light vectors.
|
// Calculate angles between surface normal and various light vectors.
|
||||||
@ -288,7 +289,7 @@ vec3 IBL(vec3 F0, vec3 Lr)
|
|||||||
int u_EnvRadianceTexLevels = textureQueryLevels(u_EnvRadianceTex);
|
int u_EnvRadianceTexLevels = textureQueryLevels(u_EnvRadianceTex);
|
||||||
float NoV = clamp(m_Params.NdotV, 0.0, 1.0);
|
float NoV = clamp(m_Params.NdotV, 0.0, 1.0);
|
||||||
vec3 R = 2.0 * dot(m_Params.View, m_Params.Normal) * m_Params.Normal - m_Params.View;
|
vec3 R = 2.0 * dot(m_Params.View, m_Params.Normal) * m_Params.Normal - m_Params.View;
|
||||||
vec3 specularIrradiance = textureLod(u_EnvRadianceTex, RotateVectorAboutY(u_EnvMapRotation, Lr), (m_Params.Roughness * m_Params.Roughness) * u_EnvRadianceTexLevels).rgb;
|
vec3 specularIrradiance = textureLod(u_EnvRadianceTex, RotateVectorAboutY(u_EnvMapRotation, Lr), (m_Params.Roughness) * u_EnvRadianceTexLevels).rgb;
|
||||||
|
|
||||||
// Sample BRDF Lut, 1.0 - roughness for y-coord because texture was generated (in Sparky) for gloss model
|
// Sample BRDF Lut, 1.0 - roughness for y-coord because texture was generated (in Sparky) for gloss model
|
||||||
vec2 specularBRDF = texture(u_BRDFLUTTexture, vec2(m_Params.NdotV, 1.0 - m_Params.Roughness)).rg;
|
vec2 specularBRDF = texture(u_BRDFLUTTexture, vec2(m_Params.NdotV, 1.0 - m_Params.Roughness)).rg;
|
||||||
@ -322,7 +323,7 @@ void main()
|
|||||||
// Fresnel reflectance, metals use albedo
|
// Fresnel reflectance, metals use albedo
|
||||||
vec3 F0 = mix(Fdielectric, m_Params.Albedo, m_Params.Metalness);
|
vec3 F0 = mix(Fdielectric, m_Params.Albedo, m_Params.Metalness);
|
||||||
|
|
||||||
vec3 lightContribution = vec3(0.0);//Lighting(F0);
|
vec3 lightContribution = Lighting(F0);
|
||||||
vec3 iblContribution = IBL(F0, Lr);
|
vec3 iblContribution = IBL(F0, Lr);
|
||||||
|
|
||||||
color = vec4(lightContribution + iblContribution, 1.0);
|
color = vec4(lightContribution + iblContribution, 1.0);
|
||||||
|
|||||||
@ -57,6 +57,7 @@ const vec3 Fdielectric = vec3(0.04);
|
|||||||
struct Light {
|
struct Light {
|
||||||
vec3 Direction;
|
vec3 Direction;
|
||||||
vec3 Radiance;
|
vec3 Radiance;
|
||||||
|
float Multiplier;
|
||||||
};
|
};
|
||||||
|
|
||||||
in VertexOutput
|
in VertexOutput
|
||||||
@ -246,7 +247,7 @@ vec3 Lighting(vec3 F0)
|
|||||||
for(int i = 0; i < LightCount; i++)
|
for(int i = 0; i < LightCount; i++)
|
||||||
{
|
{
|
||||||
vec3 Li = -lights.Direction;
|
vec3 Li = -lights.Direction;
|
||||||
vec3 Lradiance = lights.Radiance;
|
vec3 Lradiance = lights.Radiance * lights.Multiplier;
|
||||||
vec3 Lh = normalize(Li + m_Params.View);
|
vec3 Lh = normalize(Li + m_Params.View);
|
||||||
|
|
||||||
// Calculate angles between surface normal and various light vectors.
|
// Calculate angles between surface normal and various light vectors.
|
||||||
@ -271,15 +272,15 @@ vec3 Lighting(vec3 F0)
|
|||||||
vec3 IBL(vec3 F0, vec3 Lr)
|
vec3 IBL(vec3 F0, vec3 Lr)
|
||||||
{
|
{
|
||||||
vec3 irradiance = texture(u_EnvIrradianceTex, m_Params.Normal).rgb;
|
vec3 irradiance = texture(u_EnvIrradianceTex, m_Params.Normal).rgb;
|
||||||
// vec3 F = fresnelSchlickRoughness(F0, m_Params.NdotV, m_Params.Roughness);
|
vec3 F = fresnelSchlickRoughness(F0, m_Params.NdotV, m_Params.Roughness);
|
||||||
vec3 F = fresnelSchlick(F0, m_Params.NdotV);
|
// vec3 F = fresnelSchlickR(F0, m_Params.NdotV);
|
||||||
vec3 kd = (1.0 - F) * (1.0 - m_Params.Metalness);
|
vec3 kd = (1.0 - F) * (1.0 - m_Params.Metalness);
|
||||||
vec3 diffuseIBL = m_Params.Albedo * irradiance;
|
vec3 diffuseIBL = m_Params.Albedo * irradiance;
|
||||||
|
|
||||||
int u_EnvRadianceTexLevels = textureQueryLevels(u_EnvRadianceTex);
|
int u_EnvRadianceTexLevels = textureQueryLevels(u_EnvRadianceTex);
|
||||||
float NoV = clamp(m_Params.NdotV, 0.0, 1.0);
|
float NoV = clamp(m_Params.NdotV, 0.0, 1.0);
|
||||||
vec3 R = 2.0 * dot(m_Params.View, m_Params.Normal) * m_Params.Normal - m_Params.View;
|
vec3 R = 2.0 * dot(m_Params.View, m_Params.Normal) * m_Params.Normal - m_Params.View;
|
||||||
vec3 specularIrradiance = textureLod(u_EnvRadianceTex, RotateVectorAboutY(u_EnvMapRotation, Lr), (m_Params.Roughness * m_Params.Roughness) * u_EnvRadianceTexLevels).rgb;
|
vec3 specularIrradiance = textureLod(u_EnvRadianceTex, RotateVectorAboutY(u_EnvMapRotation, Lr), (m_Params.Roughness) * u_EnvRadianceTexLevels).rgb;
|
||||||
|
|
||||||
// Sample BRDF Lut, 1.0 - roughness for y-coord because texture was generated (in Sparky) for gloss model
|
// Sample BRDF Lut, 1.0 - roughness for y-coord because texture was generated (in Sparky) for gloss model
|
||||||
vec2 specularBRDF = texture(u_BRDFLUTTexture, vec2(m_Params.NdotV, 1.0 - m_Params.Roughness)).rg;
|
vec2 specularBRDF = texture(u_BRDFLUTTexture, vec2(m_Params.NdotV, 1.0 - m_Params.Roughness)).rg;
|
||||||
@ -317,5 +318,5 @@ void main()
|
|||||||
vec3 iblContribution = IBL(F0, Lr);
|
vec3 iblContribution = IBL(F0, Lr);
|
||||||
|
|
||||||
color = vec4(lightContribution + iblContribution, 1.0);
|
color = vec4(lightContribution + iblContribution, 1.0);
|
||||||
color = vec4(iblContribution, 1.0);
|
// color = vec4(iblContribution, 1.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,10 @@
|
|||||||
#include "Prism/Core/Events/KeyEvent.h"
|
#include "Prism/Core/Events/KeyEvent.h"
|
||||||
#include "Prism/Core/Events/MouseEvent.h"
|
#include "Prism/Core/Events/MouseEvent.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "Prism/Core/Math/AABB.h"
|
||||||
|
#include "Prism/Core/Math/Ray.h"
|
||||||
|
|
||||||
// ImGui
|
// ImGui
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,7 @@ namespace Prism
|
|||||||
static bool IsMouseButtonPressed(int button);
|
static bool IsMouseButtonPressed(int button);
|
||||||
static float GetMouseX();
|
static float GetMouseX();
|
||||||
static float GetMouseY();
|
static float GetMouseY();
|
||||||
|
static std::pair<float, float> GetMousePosition();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -129,4 +129,7 @@
|
|||||||
#define PM_KEY_RIGHT_SUPER 347
|
#define PM_KEY_RIGHT_SUPER 347
|
||||||
#define PM_KEY_MENU 348
|
#define PM_KEY_MENU 348
|
||||||
|
|
||||||
|
#define PM_MOUSE_BUTTON_LEFT 0
|
||||||
|
#define PM_MOUSE_BUTTON_RIGHT 1
|
||||||
|
#define PM_MOUSE_BUTTON_MIDDLE 2
|
||||||
#endif //KEYCODES_H
|
#endif //KEYCODES_H
|
||||||
|
|||||||
25
Prism/src/Prism/Core/Math/AABB.h
Normal file
25
Prism/src/Prism/Core/Math/AABB.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// Created by sfd on 25-12-2.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef PRISM_AABB_H
|
||||||
|
#define PRISM_AABB_H
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
namespace Prism
|
||||||
|
{
|
||||||
|
struct AABB
|
||||||
|
{
|
||||||
|
glm::vec3 Min, Max;
|
||||||
|
|
||||||
|
AABB()
|
||||||
|
: Min(0.0f), Max(0.0f) {}
|
||||||
|
|
||||||
|
AABB(const glm::vec3& min, const glm::vec3& max)
|
||||||
|
: Min(min), Max(max) {}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //PRISM_AABB_H
|
||||||
76
Prism/src/Prism/Core/Math/Ray.h
Normal file
76
Prism/src/Prism/Core/Math/Ray.h
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
//
|
||||||
|
// Created by sfd on 25-12-2.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef RAY_H
|
||||||
|
#define RAY_H
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
#include "AABB.h"
|
||||||
|
|
||||||
|
namespace Prism
|
||||||
|
{
|
||||||
|
struct PRISM_API Ray
|
||||||
|
{
|
||||||
|
glm::vec3 Origin, Direction;
|
||||||
|
|
||||||
|
bool IntersectsAABB(const AABB& aabb, float& t) const
|
||||||
|
{
|
||||||
|
glm::vec3 dirfrac;
|
||||||
|
// r.dir is unit direction vector of ray
|
||||||
|
dirfrac.x = 1.0f / Direction.x;
|
||||||
|
dirfrac.y = 1.0f / Direction.y;
|
||||||
|
dirfrac.z = 1.0f / Direction.z;
|
||||||
|
// lb is the corner of AABB with minimal coordinates - left bottom, rt is maximal corner
|
||||||
|
// r.org is origin of ray
|
||||||
|
const glm::vec3& lb = aabb.Min;
|
||||||
|
const glm::vec3& rt = aabb.Max;
|
||||||
|
const float t1 = (lb.x - Origin.x) * dirfrac.x;
|
||||||
|
const float t2 = (rt.x - Origin.x) * dirfrac.x;
|
||||||
|
const float t3 = (lb.y - Origin.y) * dirfrac.y;
|
||||||
|
const float t4 = (rt.y - Origin.y) * dirfrac.y;
|
||||||
|
const float t5 = (lb.z - Origin.z) * dirfrac.z;
|
||||||
|
const float t6 = (rt.z - Origin.z) * dirfrac.z;
|
||||||
|
|
||||||
|
const float tmin = glm::max(glm::max(glm::min(t1, t2), glm::min(t3, t4)), glm::min(t5, t6));
|
||||||
|
const float tmax = glm::min(glm::min(glm::max(t1, t2), glm::max(t3, t4)), glm::max(t5, t6));
|
||||||
|
|
||||||
|
// if tmax < 0, ray (line) is intersecting AABB, but the whole AABB is behind us
|
||||||
|
if (tmax < 0)
|
||||||
|
{
|
||||||
|
t = tmax;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if tmin > tmax, ray doesn't intersect AABB
|
||||||
|
if (tmin > tmax)
|
||||||
|
{
|
||||||
|
t = tmax;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
t = tmin;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IntersectsTriangle(const glm::vec3& A, const glm::vec3& B, const glm::vec3& C, float& t) const
|
||||||
|
{
|
||||||
|
const glm::vec3 E1 = B - A;
|
||||||
|
const glm::vec3 E2 = C - A;
|
||||||
|
const glm::vec3 N = cross(E1, E2);
|
||||||
|
const float det = -glm::dot(Direction, N);
|
||||||
|
const float invdet = 1.0f / det;
|
||||||
|
const glm::vec3 AO = Origin - A;
|
||||||
|
const glm::vec3 DAO = glm::cross(AO, Direction);
|
||||||
|
const float u = glm::dot(E2, DAO) * invdet;
|
||||||
|
const float v = -glm::dot(E1, DAO) * invdet;
|
||||||
|
t = glm::dot(AO, N) * invdet;
|
||||||
|
return (det >= 1e-6 && t >= 0.0 && u >= 0.0 && v >= 0.0 && (u + v) <= 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //RAY_H
|
||||||
@ -36,8 +36,9 @@ namespace Prism
|
|||||||
|
|
||||||
virtual void OnUpdate() = 0;
|
virtual void OnUpdate() = 0;
|
||||||
virtual void SetEventCallback(const EventCallbackFn& callback) = 0;
|
virtual void SetEventCallback(const EventCallbackFn& callback) = 0;
|
||||||
virtual unsigned int GetWidth() const = 0;
|
virtual uint32_t GetWidth() const = 0;
|
||||||
virtual unsigned int GetHeight() const = 0;
|
virtual uint32_t GetHeight() const = 0;
|
||||||
|
virtual std::pair<uint32_t, uint32_t> GetSize() const = 0;
|
||||||
virtual std::pair<float, float> GetWindowPos() const = 0;
|
virtual std::pair<float, float> GetWindowPos() const = 0;
|
||||||
|
|
||||||
virtual void SetVSync(bool enable) = 0;
|
virtual void SetVSync(bool enable) = 0;
|
||||||
|
|||||||
@ -132,11 +132,13 @@ namespace Prism
|
|||||||
{
|
{
|
||||||
glm::mat4 localTransform = Mat4FromAssimpMat4(node->mTransformation);
|
glm::mat4 localTransform = Mat4FromAssimpMat4(node->mTransformation);
|
||||||
glm::mat4 transform = parentTransform * localTransform;
|
glm::mat4 transform = parentTransform * localTransform;
|
||||||
|
/*
|
||||||
for (uint32_t i = 0; i < node->mNumMeshes; i++)
|
for (uint32_t i = 0; i < node->mNumMeshes; i++)
|
||||||
{
|
{
|
||||||
uint32_t meshIndex = node->mMeshes[i];
|
uint32_t meshIndex = node->mMeshes[i];
|
||||||
mesh->m_Submeshes[meshIndex].Transform = transform;
|
mesh->m_Submeshes[meshIndex].Transform = transform;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if (ImGui::TreeNode(node->mName.C_Str()))
|
if (ImGui::TreeNode(node->mName.C_Str()))
|
||||||
{
|
{
|
||||||
|
|||||||
@ -13,7 +13,7 @@ namespace Prism
|
|||||||
OpenGLFrameBuffer::OpenGLFrameBuffer(const FramebufferSpecification& spec)
|
OpenGLFrameBuffer::OpenGLFrameBuffer(const FramebufferSpecification& spec)
|
||||||
: m_Specification(spec)
|
: m_Specification(spec)
|
||||||
{
|
{
|
||||||
OpenGLFrameBuffer::Resize(spec.Width, spec.Height);
|
OpenGLFrameBuffer::Resize(spec.Width, spec.Height, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -39,9 +39,9 @@ namespace Prism
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLFrameBuffer::Resize(const uint32_t width, const uint32_t height)
|
void OpenGLFrameBuffer::Resize(const uint32_t width, const uint32_t height, const bool forceReCreate)
|
||||||
{
|
{
|
||||||
if (m_Specification.Width == width && m_Specification.Height == height)
|
if (!forceReCreate && (m_Specification.Width == width && m_Specification.Height == height))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_Specification.Width = width;
|
m_Specification.Width = width;
|
||||||
|
|||||||
@ -18,7 +18,7 @@ namespace Prism
|
|||||||
void Bind() const override;
|
void Bind() const override;
|
||||||
void Unbind() const override;
|
void Unbind() const override;
|
||||||
|
|
||||||
void Resize(uint32_t width, uint32_t height) override;
|
void Resize(uint32_t width, uint32_t height, bool forceReCreate) override;
|
||||||
|
|
||||||
void BindTexture(uint32_t slot) const override;
|
void BindTexture(uint32_t slot) const override;
|
||||||
|
|
||||||
|
|||||||
@ -71,10 +71,7 @@ namespace Prism
|
|||||||
{
|
{
|
||||||
case GL_DEBUG_SEVERITY_HIGH:
|
case GL_DEBUG_SEVERITY_HIGH:
|
||||||
PM_CORE_ERROR("[OpenGL HIGH] Source: {0}, Type: {1}, ID: {2}\nMessage: {3}", sourceStr, typeStr, id, message);
|
PM_CORE_ERROR("[OpenGL HIGH] Source: {0}, Type: {1}, ID: {2}\nMessage: {3}", sourceStr, typeStr, id, message);
|
||||||
if(type == GL_DEBUG_TYPE_ERROR)
|
PM_CORE_ASSERT(false);
|
||||||
{
|
|
||||||
PM_CORE_ASSERT(false, "ERROR");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_DEBUG_SEVERITY_MEDIUM:
|
case GL_DEBUG_SEVERITY_MEDIUM:
|
||||||
|
|||||||
@ -59,7 +59,8 @@ namespace Prism
|
|||||||
|
|
||||||
void OpenGLVertexArray::AddVertexBuffer(const Ref<VertexBuffer>& vertexBuffer)
|
void OpenGLVertexArray::AddVertexBuffer(const Ref<VertexBuffer>& vertexBuffer)
|
||||||
{
|
{
|
||||||
PM_CORE_ASSERT(vertexBuffer->GetLayout().GetElements().size(), "Vertex Buffer has no layout!");
|
const auto size = vertexBuffer->GetLayout().GetElements().size();
|
||||||
|
PM_CORE_ASSERT(size, "Vertex Buffer has no layout!");
|
||||||
|
|
||||||
Bind();
|
Bind();
|
||||||
vertexBuffer->Bind();
|
vertexBuffer->Bind();
|
||||||
|
|||||||
@ -26,23 +26,21 @@ namespace Prism
|
|||||||
|
|
||||||
float Input::GetMouseX()
|
float Input::GetMouseX()
|
||||||
{
|
{
|
||||||
const auto& window = dynamic_cast<WindowsWindow&>(Application::Get().GetWindow());
|
return GetMousePosition().first;
|
||||||
|
|
||||||
double xpos, ypos;
|
|
||||||
glfwGetCursorPos(static_cast<GLFWwindow*>(window.GetNativeWindow()), &xpos, &ypos);
|
|
||||||
|
|
||||||
return static_cast<float>(xpos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float Input::GetMouseY()
|
float Input::GetMouseY()
|
||||||
|
{
|
||||||
|
return GetMousePosition().second;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<float, float> Input::GetMousePosition()
|
||||||
{
|
{
|
||||||
const auto& window = dynamic_cast<WindowsWindow&>(Application::Get().GetWindow());
|
const auto& window = dynamic_cast<WindowsWindow&>(Application::Get().GetWindow());
|
||||||
|
|
||||||
double xpos, ypos;
|
double xpos, ypos;
|
||||||
glfwGetCursorPos(static_cast<GLFWwindow*>(window.GetNativeWindow()), &xpos, &ypos);
|
glfwGetCursorPos(static_cast<GLFWwindow*>(window.GetNativeWindow()), &xpos, &ypos);
|
||||||
|
|
||||||
return static_cast<float>(ypos);
|
return {xpos, ypos};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -197,6 +197,14 @@ namespace Prism
|
|||||||
m_ImGuiMouseCursors[ImGuiMouseCursor_ResizeNESW] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); // FIXME: GLFW doesn't have this.
|
m_ImGuiMouseCursors[ImGuiMouseCursor_ResizeNESW] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); // FIXME: GLFW doesn't have this.
|
||||||
m_ImGuiMouseCursors[ImGuiMouseCursor_ResizeNWSE] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); // FIXME: GLFW doesn't have this.
|
m_ImGuiMouseCursors[ImGuiMouseCursor_ResizeNWSE] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); // FIXME: GLFW doesn't have this.
|
||||||
m_ImGuiMouseCursors[ImGuiMouseCursor_Hand] = glfwCreateStandardCursor(GLFW_HAND_CURSOR);
|
m_ImGuiMouseCursors[ImGuiMouseCursor_Hand] = glfwCreateStandardCursor(GLFW_HAND_CURSOR);
|
||||||
|
|
||||||
|
// Update window size to actual size
|
||||||
|
{
|
||||||
|
int width, height;
|
||||||
|
glfwGetWindowSize(m_Window, &width, &height);
|
||||||
|
m_Data.Width = width;
|
||||||
|
m_Data.Height= height;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowsWindow::Shutdown()
|
void WindowsWindow::Shutdown()
|
||||||
|
|||||||
@ -24,6 +24,7 @@ namespace Prism
|
|||||||
inline void SetEventCallback(const EventCallbackFn& callback) override { m_Data.EventCallback = callback; }
|
inline void SetEventCallback(const EventCallbackFn& callback) override { m_Data.EventCallback = callback; }
|
||||||
bool const IsVSync() const override { return m_Data.VSync; }
|
bool const IsVSync() const override { return m_Data.VSync; }
|
||||||
void SetVSync(bool enable) override;
|
void SetVSync(bool enable) override;
|
||||||
|
virtual std::pair<uint32_t, uint32_t> GetSize() const override { return { m_Data.Width, m_Data.Height }; }
|
||||||
virtual std::pair<float, float> GetWindowPos() const override;
|
virtual std::pair<float, float> GetWindowPos() const override;
|
||||||
|
|
||||||
inline void* GetNativeWindow() const { return m_Window; }
|
inline void* GetNativeWindow() const { return m_Window; }
|
||||||
|
|||||||
@ -24,14 +24,17 @@ namespace Prism
|
|||||||
Camera::Camera(const glm::mat4& projectionMatrix)
|
Camera::Camera(const glm::mat4& projectionMatrix)
|
||||||
: m_ProjectionMatrix(projectionMatrix)
|
: m_ProjectionMatrix(projectionMatrix)
|
||||||
{
|
{
|
||||||
m_Position = { 0, 0, 10 };
|
|
||||||
m_Rotation = glm::vec3(90.0f, 0.0f, 0.0f);
|
m_Rotation = glm::vec3(90.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
m_FocalPoint = glm::vec3(0.0f);
|
m_FocalPoint = glm::vec3(0.0f);
|
||||||
m_Distance = glm::distance(m_Position, m_FocalPoint);
|
|
||||||
|
glm::vec3 position = { -5, 5, 5};
|
||||||
|
m_Distance = glm::distance(position, m_FocalPoint);
|
||||||
|
|
||||||
m_Yaw = 3.0f * (float)M_PI / 4.0f;
|
m_Yaw = 3.0f * (float)M_PI / 4.0f;
|
||||||
m_Pitch = M_PI / 4.0f;
|
m_Pitch = M_PI / 4.0f;
|
||||||
|
|
||||||
|
UpdateCameraView();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::Focus()
|
void Camera::Focus()
|
||||||
@ -56,13 +59,7 @@ namespace Prism
|
|||||||
MouseZoom(delta.y);
|
MouseZoom(delta.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Position = CalculatePosition();
|
UpdateCameraView();
|
||||||
|
|
||||||
glm::quat orientation = GetOrientation();
|
|
||||||
m_Rotation = glm::eulerAngles(orientation) * (180.0f / (float)M_PI);
|
|
||||||
m_ViewMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(0, 0, 1)) * glm::toMat4(glm::conjugate(orientation)) * glm::translate(glm::mat4(1.0f), -m_Position);
|
|
||||||
m_ViewMatrix = glm::translate(glm::mat4(1.0f), m_Position) * glm::toMat4(orientation);
|
|
||||||
m_ViewMatrix = glm::inverse(m_ViewMatrix);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::OnEvent(Event& e)
|
void Camera::OnEvent(Event& e)
|
||||||
@ -86,6 +83,16 @@ namespace Prism
|
|||||||
return glm::rotate(GetOrientation(), glm::vec3(0.0f, 0.0f, -1.0f));
|
return glm::rotate(GetOrientation(), glm::vec3(0.0f, 0.0f, -1.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Camera::UpdateCameraView()
|
||||||
|
{
|
||||||
|
m_Position = CalculatePosition();
|
||||||
|
|
||||||
|
const glm::quat orientation = GetOrientation();
|
||||||
|
m_Rotation = glm::eulerAngles(orientation) * (180.0f / (float)M_PI);
|
||||||
|
m_ViewMatrix = glm::translate(glm::mat4(1.0f), m_Position) * glm::toMat4(orientation);
|
||||||
|
m_ViewMatrix = glm::inverse(m_ViewMatrix);
|
||||||
|
}
|
||||||
|
|
||||||
bool Camera::OnMouseScroll(MouseScrolledEvent& e)
|
bool Camera::OnMouseScroll(MouseScrolledEvent& e)
|
||||||
{
|
{
|
||||||
const float delta = e.GetOffsetY() * 0.1f;
|
const float delta = e.GetOffsetY() * 0.1f;
|
||||||
|
|||||||
@ -43,6 +43,8 @@ namespace Prism
|
|||||||
public:
|
public:
|
||||||
inline void SetViewportSize(const uint32_t width, const uint32_t height) { m_ViewportWidth = width; m_ViewportHeight = height; }
|
inline void SetViewportSize(const uint32_t width, const uint32_t height) { m_ViewportWidth = width; m_ViewportHeight = height; }
|
||||||
private:
|
private:
|
||||||
|
void UpdateCameraView();
|
||||||
|
|
||||||
bool OnMouseScroll(MouseScrolledEvent& e);
|
bool OnMouseScroll(MouseScrolledEvent& e);
|
||||||
void MousePan(const glm::vec2& delta);
|
void MousePan(const glm::vec2& delta);
|
||||||
void MouseRotate(const glm::vec2& delta);
|
void MouseRotate(const glm::vec2& delta);
|
||||||
|
|||||||
@ -40,7 +40,7 @@ namespace Prism
|
|||||||
virtual void Bind() const = 0;
|
virtual void Bind() const = 0;
|
||||||
virtual void Unbind() const = 0;
|
virtual void Unbind() const = 0;
|
||||||
|
|
||||||
virtual void Resize(uint32_t width, uint32_t height) = 0;
|
virtual void Resize(uint32_t width, uint32_t height, bool forceReCreate = false) = 0;
|
||||||
|
|
||||||
virtual void BindTexture(uint32_t slot = 0) const = 0;
|
virtual void BindTexture(uint32_t slot = 0) const = 0;
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,13 @@
|
|||||||
|
|
||||||
namespace Prism
|
namespace Prism
|
||||||
{
|
{
|
||||||
|
#define MESH_DEBUG_LOG 1
|
||||||
|
#ifdef MESH_DEBUG_LOG
|
||||||
|
#define PM_MESH_LOG(...) PM_CORE_TRACE(__VA_ARGS__)
|
||||||
|
#elif
|
||||||
|
#define PM_MESH_LOG(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
constexpr unsigned int s_ImportFlags =
|
constexpr unsigned int s_ImportFlags =
|
||||||
aiProcess_CalcTangentSpace | // Create binormals/tangents just in case
|
aiProcess_CalcTangentSpace | // Create binormals/tangents just in case
|
||||||
aiProcess_Triangulate | // Make sure we're triangles
|
aiProcess_Triangulate | // Make sure we're triangles
|
||||||
@ -104,9 +111,7 @@ namespace Prism
|
|||||||
if (!scene || !scene->HasMeshes())
|
if (!scene || !scene->HasMeshes())
|
||||||
PM_CORE_ERROR("Failed to load mesh file: {0}", filename);
|
PM_CORE_ERROR("Failed to load mesh file: {0}", filename);
|
||||||
|
|
||||||
//double factor;
|
m_Scene = scene;
|
||||||
//scene->mMetaData->Get("UnitScaleFactor", factor);
|
|
||||||
//PM_CORE_INFO("FBX Scene Scale: {0}", factor);
|
|
||||||
|
|
||||||
m_IsAnimated = scene->mAnimations != nullptr;
|
m_IsAnimated = scene->mAnimations != nullptr;
|
||||||
m_MeshShader = m_IsAnimated ? Renderer::GetShaderLibrary()->Get("PBRShader_Anim") : Renderer::GetShaderLibrary()->Get("PBRShader_Static");
|
m_MeshShader = m_IsAnimated ? Renderer::GetShaderLibrary()->Get("PBRShader_Anim") : Renderer::GetShaderLibrary()->Get("PBRShader_Static");
|
||||||
@ -117,16 +122,17 @@ namespace Prism
|
|||||||
uint32_t indexCount = 0;
|
uint32_t indexCount = 0;
|
||||||
|
|
||||||
m_Submeshes.reserve(scene->mNumMeshes);
|
m_Submeshes.reserve(scene->mNumMeshes);
|
||||||
for (size_t m = 0; m < scene->mNumMeshes; m++)
|
for (uint32_t m = 0; m < scene->mNumMeshes; m++)
|
||||||
{
|
{
|
||||||
aiMesh* mesh = scene->mMeshes[m];
|
aiMesh* mesh = scene->mMeshes[m];
|
||||||
|
|
||||||
Submesh submesh;
|
Submesh& submesh = m_Submeshes.emplace_back();
|
||||||
submesh.BaseVertex = vertexCount;
|
submesh.BaseVertex = vertexCount;
|
||||||
submesh.BaseIndex = indexCount;
|
submesh.BaseIndex = indexCount;
|
||||||
submesh.MaterialIndex = mesh->mMaterialIndex;
|
submesh.MaterialIndex = mesh->mMaterialIndex;
|
||||||
submesh.IndexCount = mesh->mNumFaces * 3;
|
submesh.IndexCount = mesh->mNumFaces * 3;
|
||||||
m_Submeshes.push_back(submesh);
|
// m_Submeshes.push_back(submesh);
|
||||||
|
submesh.MeshName = mesh->mName.C_Str();
|
||||||
|
|
||||||
vertexCount += mesh->mNumVertices;
|
vertexCount += mesh->mNumVertices;
|
||||||
indexCount += submesh.IndexCount;
|
indexCount += submesh.IndexCount;
|
||||||
@ -155,8 +161,10 @@ namespace Prism
|
|||||||
}
|
}
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
submesh.Min = { FLT_MAX, FLT_MAX, FLT_MAX };
|
|
||||||
submesh.Max = { -FLT_MAX, -FLT_MAX, -FLT_MAX };
|
auto& aabb = submesh.BoundingBox;
|
||||||
|
aabb.Min = { FLT_MAX, FLT_MAX, FLT_MAX };
|
||||||
|
aabb.Max = { -FLT_MAX, -FLT_MAX, -FLT_MAX };
|
||||||
|
|
||||||
for (size_t i = 0; i < mesh->mNumVertices; i++)
|
for (size_t i = 0; i < mesh->mNumVertices; i++)
|
||||||
{
|
{
|
||||||
@ -164,12 +172,12 @@ namespace Prism
|
|||||||
vertex.Position = { mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z };
|
vertex.Position = { mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z };
|
||||||
vertex.Normal = { mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z };
|
vertex.Normal = { mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z };
|
||||||
|
|
||||||
submesh.Min.x = glm::min(vertex.Position.x, submesh.Min.x);
|
aabb.Min.x = glm::min(vertex.Position.x, aabb.Min.x);
|
||||||
submesh.Min.y = glm::min(vertex.Position.y, submesh.Min.y);
|
aabb.Min.y = glm::min(vertex.Position.y, aabb.Min.y);
|
||||||
submesh.Min.z = glm::min(vertex.Position.z, submesh.Min.z);
|
aabb.Min.z = glm::min(vertex.Position.z, aabb.Min.z);
|
||||||
submesh.Max.x = glm::max(vertex.Position.x, submesh.Max.x);
|
aabb.Max.x = glm::max(vertex.Position.x, aabb.Max.x);
|
||||||
submesh.Max.y = glm::max(vertex.Position.y, submesh.Max.y);
|
aabb.Max.y = glm::max(vertex.Position.y, aabb.Max.y);
|
||||||
submesh.Max.z = glm::max(vertex.Position.z, submesh.Max.z);
|
aabb.Max.z = glm::max(vertex.Position.z, aabb.Max.z);
|
||||||
|
|
||||||
|
|
||||||
if (mesh->HasTangentsAndBitangents())
|
if (mesh->HasTangentsAndBitangents())
|
||||||
@ -189,7 +197,11 @@ namespace Prism
|
|||||||
for (size_t i = 0; i < mesh->mNumFaces; i++)
|
for (size_t i = 0; i < mesh->mNumFaces; i++)
|
||||||
{
|
{
|
||||||
PM_CORE_ASSERT(mesh->mFaces[i].mNumIndices == 3, "Must have 3 indices.");
|
PM_CORE_ASSERT(mesh->mFaces[i].mNumIndices == 3, "Must have 3 indices.");
|
||||||
m_Indices.push_back({ mesh->mFaces[i].mIndices[0], mesh->mFaces[i].mIndices[1], mesh->mFaces[i].mIndices[2] });
|
Index index = { mesh->mFaces[i].mIndices[0], mesh->mFaces[i].mIndices[1], mesh->mFaces[i].mIndices[2] };
|
||||||
|
m_Indices.push_back(index);
|
||||||
|
|
||||||
|
if (!m_IsAnimated)
|
||||||
|
m_TriangleCache[m].emplace_back(m_StaticVertices[index.V1 + submesh.BaseVertex], m_StaticVertices[index.V2 + submesh.BaseVertex], m_StaticVertices[index.V3 + submesh.BaseVertex]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,6 +250,8 @@ namespace Prism
|
|||||||
// Material
|
// Material
|
||||||
if (scene->HasMaterials())
|
if (scene->HasMaterials())
|
||||||
{
|
{
|
||||||
|
PM_CORE_INFO("---- Materials - {0} ----", filename);
|
||||||
|
|
||||||
m_Textures.resize(scene->mNumMaterials);
|
m_Textures.resize(scene->mNumMaterials);
|
||||||
m_Materials.resize(scene->mNumMaterials);
|
m_Materials.resize(scene->mNumMaterials);
|
||||||
for (uint32_t i = 0; i < scene->mNumMaterials; i++)
|
for (uint32_t i = 0; i < scene->mNumMaterials; i++)
|
||||||
@ -248,16 +262,26 @@ namespace Prism
|
|||||||
auto mi = CreateRef<MaterialInstance>(m_BaseMaterial);
|
auto mi = CreateRef<MaterialInstance>(m_BaseMaterial);
|
||||||
m_Materials[i] = mi;
|
m_Materials[i] = mi;
|
||||||
|
|
||||||
PM_CORE_INFO("Material Name = {0}; Index = {1}", aiMaterialName.data, i);
|
PM_MESH_LOG(" {0} (Index = {1})", aiMaterialName.data, i);
|
||||||
aiString aiTexPath;
|
aiString aiTexPath;
|
||||||
uint32_t textureCount = aiMaterial->GetTextureCount(aiTextureType_DIFFUSE);
|
uint32_t textureCount = aiMaterial->GetTextureCount(aiTextureType_DIFFUSE);
|
||||||
PM_CORE_TRACE(" TextureCount = {0}", textureCount);
|
PM_MESH_LOG(" TextureCount = {0}", textureCount);
|
||||||
|
|
||||||
aiColor3D aiColor;
|
aiColor3D aiColor;
|
||||||
aiMaterial->Get(AI_MATKEY_COLOR_DIFFUSE, aiColor);
|
aiMaterial->Get(AI_MATKEY_COLOR_DIFFUSE, aiColor);
|
||||||
PM_CORE_TRACE("COLOR = {0}, {1}, {2}", aiColor.r, aiColor.g, aiColor.b);
|
PM_CORE_TRACE("COLOR = {0}, {1}, {2}", aiColor.r, aiColor.g, aiColor.b);
|
||||||
|
|
||||||
if (aiMaterial->GetTexture(aiTextureType_DIFFUSE, 0, &aiTexPath) == AI_SUCCESS)
|
float shininess, metalness;
|
||||||
|
aiMaterial->Get(AI_MATKEY_SHININESS, shininess);
|
||||||
|
aiMaterial->Get(AI_MATKEY_REFLECTIVITY, metalness);
|
||||||
|
|
||||||
|
// float roughness = 1.0f - shininess * 0.01f;
|
||||||
|
// roughness *= roughness;
|
||||||
|
float roughness = 1.0f - glm::sqrt(shininess / 100.0f);
|
||||||
|
PM_MESH_LOG(" COLOR = {0}, {1}, {2}", aiColor.r, aiColor.g, aiColor.b);
|
||||||
|
PM_MESH_LOG(" ROUGHNESS = {0}", roughness);
|
||||||
|
bool hasAlbedoMap = aiMaterial->GetTexture(aiTextureType_DIFFUSE, 0, &aiTexPath) == AI_SUCCESS;
|
||||||
|
if (hasAlbedoMap)
|
||||||
{
|
{
|
||||||
// TODO: Temp - this should be handled by Hazel's filesystem
|
// TODO: Temp - this should be handled by Hazel's filesystem
|
||||||
std::filesystem::path path = filename;
|
std::filesystem::path path = filename;
|
||||||
@ -265,27 +289,25 @@ namespace Prism
|
|||||||
parentPath /= std::string(aiTexPath.data);
|
parentPath /= std::string(aiTexPath.data);
|
||||||
std::string texturePath = parentPath.string();
|
std::string texturePath = parentPath.string();
|
||||||
|
|
||||||
|
PM_MESH_LOG(" Albedo map path = {0}", texturePath);
|
||||||
auto texture = Texture2D::Create(texturePath, true);
|
auto texture = Texture2D::Create(texturePath, true);
|
||||||
if (texture->Loaded())
|
if (texture->Loaded())
|
||||||
{
|
{
|
||||||
m_Textures[i] = texture;
|
m_Textures[i] = texture;
|
||||||
PM_CORE_TRACE(" Texture Path = {0}", texturePath);
|
|
||||||
mi->Set("u_AlbedoTexture", m_Textures[i]);
|
mi->Set("u_AlbedoTexture", m_Textures[i]);
|
||||||
mi->Set("u_AlbedoTexToggle", 1.0f);
|
mi->Set("u_AlbedoTexToggle", 1.0f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PM_CORE_ERROR("Could not load texture: {0}", texturePath);
|
PM_CORE_ERROR("Could not load texture: {0}", texturePath);
|
||||||
//mi->Set("u_AlbedoTexToggle", 0.0f);
|
// fallback to u_AlbedoColor
|
||||||
mi->Set("u_AlbedoColor", glm::vec3{ aiColor.r, aiColor.g, aiColor.b });
|
mi->Set("u_AlbedoColor", glm::vec3{ aiColor.r, aiColor.g, aiColor.b });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mi->Set("u_AlbedoTexToggle", 0.0f);
|
|
||||||
mi->Set("u_AlbedoColor", glm::vec3 { aiColor.r, aiColor.g, aiColor.b });
|
mi->Set("u_AlbedoColor", glm::vec3 { aiColor.r, aiColor.g, aiColor.b });
|
||||||
|
PM_MESH_LOG(" No albedo map");
|
||||||
PM_CORE_INFO("Mesh has no albedo map");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normal Maps
|
// Normal Maps
|
||||||
@ -299,21 +321,21 @@ namespace Prism
|
|||||||
parentPath /= std::string(aiTexPath.data);
|
parentPath /= std::string(aiTexPath.data);
|
||||||
std::string texturePath = parentPath.string();
|
std::string texturePath = parentPath.string();
|
||||||
|
|
||||||
|
PM_MESH_LOG(" Normal map path = {0}", texturePath);
|
||||||
auto texture = Texture2D::Create(texturePath);
|
auto texture = Texture2D::Create(texturePath);
|
||||||
if (texture->Loaded())
|
if (texture->Loaded())
|
||||||
{
|
{
|
||||||
PM_CORE_TRACE(" Normal map path = {0}", texturePath);
|
|
||||||
mi->Set("u_NormalTexture", texture);
|
mi->Set("u_NormalTexture", texture);
|
||||||
mi->Set("u_NormalTexToggle", 1.0f);
|
mi->Set("u_NormalTexToggle", 1.0f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PM_CORE_ERROR("Could not load texture: {0}", texturePath);
|
PM_CORE_ERROR(" Could not load texture: {0}", texturePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PM_CORE_TRACE("Mesh has no normal map");
|
PM_MESH_LOG(" no normal map");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Roughness map
|
// Roughness map
|
||||||
@ -327,6 +349,7 @@ namespace Prism
|
|||||||
parentPath /= std::string(aiTexPath.data);
|
parentPath /= std::string(aiTexPath.data);
|
||||||
std::string texturePath = parentPath.string();
|
std::string texturePath = parentPath.string();
|
||||||
|
|
||||||
|
PM_MESH_LOG(" Roughness map path = {0}", texturePath);
|
||||||
auto texture = Texture2D::Create(texturePath);
|
auto texture = Texture2D::Create(texturePath);
|
||||||
if (texture->Loaded())
|
if (texture->Loaded())
|
||||||
{
|
{
|
||||||
@ -336,14 +359,17 @@ namespace Prism
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PM_CORE_ERROR("Could not load texture: {0}", texturePath);
|
PM_CORE_ERROR(" Could not load texture: {0}", texturePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PM_CORE_TRACE("Mesh has no roughness texture");
|
PM_MESH_LOG(" no roughness texture");
|
||||||
|
mi->Set("u_Roughness", roughness);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
// Metalness map
|
// Metalness map
|
||||||
// mi->Set("u_Metalness", 0.0f);
|
// mi->Set("u_Metalness", 0.0f);
|
||||||
// mi->Set("u_MetalnessTexToggle", 0.0f);
|
// mi->Set("u_MetalnessTexToggle", 0.0f);
|
||||||
@ -358,7 +384,7 @@ namespace Prism
|
|||||||
auto texture = Texture2D::Create(texturePath);
|
auto texture = Texture2D::Create(texturePath);
|
||||||
if (texture->Loaded())
|
if (texture->Loaded())
|
||||||
{
|
{
|
||||||
PM_CORE_TRACE(" Metalness map path = {0}", texturePath);
|
PM_MESH_LOG(" Metalness map path = {0}", texturePath);
|
||||||
mi->Set("u_MetalnessTexture", texture);
|
mi->Set("u_MetalnessTexture", texture);
|
||||||
mi->Set("u_MetalnessTexToggle", 1.0f);
|
mi->Set("u_MetalnessTexToggle", 1.0f);
|
||||||
}
|
}
|
||||||
@ -369,169 +395,82 @@ namespace Prism
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PM_CORE_TRACE("Mesh has no metalness texture");
|
PM_MESH_LOG(" no metalness texture");
|
||||||
|
mi->Set("u_Metalness", metalness);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
#endif
|
||||||
|
bool metalnessTextureFound = false;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < aiMaterial->mNumProperties; i++)
|
for (uint32_t i = 0; i < aiMaterial->mNumProperties; i++)
|
||||||
{
|
{
|
||||||
auto prop = aiMaterial->mProperties[i];
|
auto prop = aiMaterial->mProperties[i];
|
||||||
PM_CORE_TRACE("Material Property:");
|
PM_CORE_TRACE("Material Property:");
|
||||||
PM_CORE_TRACE(" Name = {0}", prop->mKey.data);
|
PM_CORE_TRACE(" Name = {0}", prop->mKey.data);
|
||||||
|
float data = *(float*)prop->mData;
|
||||||
|
PM_MESH_LOG(" Value = {0}", data);
|
||||||
|
|
||||||
switch (prop->mSemantic)
|
switch (prop->mSemantic)
|
||||||
{
|
{
|
||||||
case aiTextureType_NONE:
|
case aiTextureType_NONE: PM_MESH_LOG(" Semantic = aiTextureType_NONE"); break;
|
||||||
PM_CORE_TRACE(" Semantic = aiTextureType_NONE");
|
case aiTextureType_DIFFUSE: PM_MESH_LOG(" Semantic = aiTextureType_DIFFUSE"); break;
|
||||||
break;
|
case aiTextureType_SPECULAR: PM_MESH_LOG(" Semantic = aiTextureType_SPECULAR"); break;
|
||||||
case aiTextureType_DIFFUSE:
|
case aiTextureType_AMBIENT: PM_MESH_LOG(" Semantic = aiTextureType_AMBIENT"); break;
|
||||||
PM_CORE_TRACE(" Semantic = aiTextureType_DIFFUSE");
|
case aiTextureType_EMISSIVE: PM_MESH_LOG(" Semantic = aiTextureType_EMISSIVE"); break;
|
||||||
break;
|
case aiTextureType_HEIGHT: PM_MESH_LOG(" Semantic = aiTextureType_HEIGHT"); break;
|
||||||
case aiTextureType_SPECULAR:
|
case aiTextureType_NORMALS: PM_MESH_LOG(" Semantic = aiTextureType_NORMALS"); break;
|
||||||
PM_CORE_TRACE(" Semantic = aiTextureType_SPECULAR");
|
case aiTextureType_SHININESS: PM_MESH_LOG(" Semantic = aiTextureType_SHININESS"); break;
|
||||||
break;
|
case aiTextureType_OPACITY: PM_MESH_LOG(" Semantic = aiTextureType_OPACITY"); break;
|
||||||
case aiTextureType_AMBIENT:
|
case aiTextureType_DISPLACEMENT:PM_MESH_LOG(" Semantic = aiTextureType_DISPLACEMENT"); break;
|
||||||
PM_CORE_TRACE(" Semantic = aiTextureType_AMBIENT");
|
case aiTextureType_LIGHTMAP: PM_MESH_LOG(" Semantic = aiTextureType_LIGHTMAP"); break;
|
||||||
break;
|
case aiTextureType_REFLECTION: PM_MESH_LOG(" Semantic = aiTextureType_REFLECTION"); break;
|
||||||
case aiTextureType_EMISSIVE:
|
case aiTextureType_UNKNOWN: PM_MESH_LOG(" Semantic = aiTextureType_UNKNOWN"); break;
|
||||||
PM_CORE_TRACE(" Semantic = aiTextureType_EMISSIVE");
|
|
||||||
break;
|
|
||||||
case aiTextureType_HEIGHT:
|
|
||||||
PM_CORE_TRACE(" Semantic = aiTextureType_HEIGHT");
|
|
||||||
break;
|
|
||||||
case aiTextureType_NORMALS:
|
|
||||||
PM_CORE_TRACE(" Semantic = aiTextureType_NORMALS");
|
|
||||||
break;
|
|
||||||
case aiTextureType_SHININESS:
|
|
||||||
PM_CORE_TRACE(" Semantic = aiTextureType_SHININESS");
|
|
||||||
break;
|
|
||||||
case aiTextureType_OPACITY:
|
|
||||||
PM_CORE_TRACE(" Semantic = aiTextureType_OPACITY");
|
|
||||||
break;
|
|
||||||
case aiTextureType_DISPLACEMENT:
|
|
||||||
PM_CORE_TRACE(" Semantic = aiTextureType_DISPLACEMENT");
|
|
||||||
break;
|
|
||||||
case aiTextureType_LIGHTMAP:
|
|
||||||
PM_CORE_TRACE(" Semantic = aiTextureType_LIGHTMAP");
|
|
||||||
break;
|
|
||||||
case aiTextureType_REFLECTION:
|
|
||||||
PM_CORE_TRACE(" Semantic = aiTextureType_REFLECTION");
|
|
||||||
break;
|
|
||||||
case aiTextureType_UNKNOWN:
|
|
||||||
PM_CORE_TRACE(" Semantic = aiTextureType_UNKNOWN");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prop->mType == aiPTI_String)
|
if (prop->mType == aiPTI_String)
|
||||||
{
|
{
|
||||||
uint32_t strLength = *(uint32_t*)prop->mData;
|
uint32_t strLength = *(uint32_t*)prop->mData;
|
||||||
std::string str(prop->mData + 4, strLength);
|
std::string str(prop->mData + 4, strLength);
|
||||||
PM_CORE_TRACE(" Value = {0}", str);
|
|
||||||
|
|
||||||
std::string key = prop->mKey.data;
|
std::string key = prop->mKey.data;
|
||||||
if (key == "$raw.ReflectionFactor|file")
|
if (key == "$raw.ReflectionFactor|file")
|
||||||
{
|
{
|
||||||
|
metalnessTextureFound = true;
|
||||||
|
|
||||||
// TODO: Temp - this should be handled by Hazel's filesystem
|
// TODO: Temp - this should be handled by Hazel's filesystem
|
||||||
std::filesystem::path path = filename;
|
std::filesystem::path path = filename;
|
||||||
auto parentPath = path.parent_path();
|
auto parentPath = path.parent_path();
|
||||||
parentPath /= str;
|
parentPath /= str;
|
||||||
std::string texturePath = parentPath.string();
|
std::string texturePath = parentPath.string();
|
||||||
|
|
||||||
|
|
||||||
|
PM_MESH_LOG(" Metalness map path = {0}", texturePath);
|
||||||
auto texture = Texture2D::Create(texturePath);
|
auto texture = Texture2D::Create(texturePath);
|
||||||
if (texture->Loaded())
|
if (texture->Loaded())
|
||||||
{
|
{
|
||||||
PM_CORE_TRACE(" Metalness map path = {0}", texturePath);
|
|
||||||
mi->Set("u_MetalnessTexture", texture);
|
mi->Set("u_MetalnessTexture", texture);
|
||||||
mi->Set("u_MetalnessTexToggle", 1.0f);
|
mi->Set("u_MetalnessTexToggle", 1.0f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PM_CORE_ERROR("Could not load texture: {0}", texturePath);
|
PM_CORE_ERROR(" Could not load texture: {0}", texturePath);
|
||||||
mi->Set("u_Metalness", 0.5f);
|
mi->Set("u_Metalness", metalness);
|
||||||
mi->Set("u_MetalnessTexToggle", 1.0f);
|
mi->Set("u_MetalnessTexToggle", 0.0f);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!metalnessTextureFound)
|
||||||
|
{
|
||||||
|
PM_MESH_LOG(" No metalness map");
|
||||||
|
|
||||||
/*
|
mi->Set("u_Metalness", metalness);
|
||||||
// Normal maps
|
mi->Set("u_MetalnessTexToggle", 0.0f);
|
||||||
if (aiMaterial->GetTexture(aiTextureType_NORMALS, 0, &aiTexPath) == AI_SUCCESS)
|
|
||||||
{
|
|
||||||
// TODO: Temp - this should be handled by Hazel's filesystem
|
|
||||||
std::filesystem::path path = filename;
|
|
||||||
auto parentPath = path.parent_path();
|
|
||||||
parentPath /= std::string(aiTexPath.data);
|
|
||||||
std::string texturePath = parentPath.string();
|
|
||||||
|
|
||||||
auto texture = Texture2D::Create(texturePath);
|
|
||||||
if (texture->Loaded())
|
|
||||||
{
|
|
||||||
PM_CORE_TRACE(" Normal map path = {0}", texturePath);
|
|
||||||
mi->Set("u_NormalTexture", texture);
|
|
||||||
mi->Set("u_NormalTexToggle", 1.0f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PM_CORE_ERROR("Could not load texture: {0}", texturePath);
|
|
||||||
//mi->Set("u_AlbedoTexToggle", 0.0f);
|
|
||||||
// mi->Set("u_AlbedoColor", glm::vec3{ color.r, color.g, color.b });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
PM_MESH_LOG("------------------------");
|
||||||
// Roughness map
|
|
||||||
if (aiMaterial->GetTexture(aiTextureType_SHININESS, 0, &aiTexPath) == AI_SUCCESS)
|
|
||||||
{
|
|
||||||
// TODO: Temp - this should be handled by Hazel's filesystem
|
|
||||||
std::filesystem::path path = filename;
|
|
||||||
auto parentPath = path.parent_path();
|
|
||||||
parentPath /= std::string(aiTexPath.data);
|
|
||||||
std::string texturePath = parentPath.string();
|
|
||||||
|
|
||||||
auto texture = Texture2D::Create(texturePath);
|
|
||||||
if (texture->Loaded())
|
|
||||||
{
|
|
||||||
PM_CORE_TRACE(" Roughness map path = {0}", texturePath);
|
|
||||||
mi->Set("u_RoughnessTexture", texture);
|
|
||||||
mi->Set("u_RoughnessTexToggle", 1.0f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PM_CORE_ERROR("Could not load texture: {0}", texturePath);
|
|
||||||
mi->Set("u_RoughnessTexToggle", 1.0f);
|
|
||||||
mi->Set("u_Roughness", 0.5f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Metalness map
|
|
||||||
if (aiMaterial->Get("$raw.ReflectionFactor|file", aiPTI_String, 0, aiTexPath) == AI_SUCCESS)
|
|
||||||
{
|
|
||||||
// TODO: Temp - this should be handled by Hazel's filesystem
|
|
||||||
std::filesystem::path path = filename;
|
|
||||||
auto parentPath = path.parent_path();
|
|
||||||
parentPath /= std::string(aiTexPath.data);
|
|
||||||
std::string texturePath = parentPath.string();
|
|
||||||
|
|
||||||
auto texture = Texture2D::Create(texturePath);
|
|
||||||
if (texture->Loaded())
|
|
||||||
{
|
|
||||||
PM_CORE_TRACE(" Metalness map path = {0}", texturePath);
|
|
||||||
mi->Set("u_MetalnessTexture", texture);
|
|
||||||
mi->Set("u_MetalnessTexToggle", 1.0f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PM_CORE_ERROR("Could not load texture: {0}", texturePath);
|
|
||||||
mi->Set("u_Metalness", 0.5f);
|
|
||||||
mi->Set("u_MetalnessTexToggle", 1.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_VertexArray = VertexArray::Create();
|
m_VertexArray = VertexArray::Create();
|
||||||
@ -564,7 +503,6 @@ namespace Prism
|
|||||||
|
|
||||||
auto ib = IndexBuffer::Create(m_Indices.data(), (uint32_t)m_Indices.size() * sizeof(Index));
|
auto ib = IndexBuffer::Create(m_Indices.data(), (uint32_t)m_Indices.size() * sizeof(Index));
|
||||||
m_VertexArray->SetIndexBuffer(ib);
|
m_VertexArray->SetIndexBuffer(ib);
|
||||||
m_Scene = scene;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Mesh::~Mesh() = default;
|
Mesh::~Mesh() = default;
|
||||||
@ -591,37 +529,37 @@ namespace Prism
|
|||||||
void Mesh::DumpVertexBuffer()
|
void Mesh::DumpVertexBuffer()
|
||||||
{
|
{
|
||||||
// TODO: Convert to ImGui
|
// TODO: Convert to ImGui
|
||||||
PM_CORE_TRACE("------------------------------------------------------");
|
PM_MESH_LOG("------------------------------------------------------");
|
||||||
PM_CORE_TRACE("Vertex Buffer Dump");
|
PM_MESH_LOG("Vertex Buffer Dump");
|
||||||
PM_CORE_TRACE("Mesh: {0}", m_FilePath);
|
PM_MESH_LOG("Mesh: {0}", m_FilePath);
|
||||||
if (m_IsAnimated)
|
if (m_IsAnimated)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < m_AnimatedVertices.size(); i++)
|
for (size_t i = 0; i < m_AnimatedVertices.size(); i++)
|
||||||
{
|
{
|
||||||
auto& vertex = m_AnimatedVertices[i];
|
auto& vertex = m_AnimatedVertices[i];
|
||||||
PM_CORE_TRACE("Vertex: {0}", i);
|
PM_MESH_LOG("Vertex: {0}", i);
|
||||||
PM_CORE_TRACE("Position: {0}, {1}, {2}", vertex.Position.x, vertex.Position.y, vertex.Position.z);
|
PM_MESH_LOG("Position: {0}, {1}, {2}", vertex.Position.x, vertex.Position.y, vertex.Position.z);
|
||||||
PM_CORE_TRACE("Normal: {0}, {1}, {2}", vertex.Normal.x, vertex.Normal.y, vertex.Normal.z);
|
PM_MESH_LOG("Normal: {0}, {1}, {2}", vertex.Normal.x, vertex.Normal.y, vertex.Normal.z);
|
||||||
PM_CORE_TRACE("Binormal: {0}, {1}, {2}", vertex.Binormal.x, vertex.Binormal.y, vertex.Binormal.z);
|
PM_MESH_LOG("Binormal: {0}, {1}, {2}", vertex.Binormal.x, vertex.Binormal.y, vertex.Binormal.z);
|
||||||
PM_CORE_TRACE("Tangent: {0}, {1}, {2}", vertex.Tangent.x, vertex.Tangent.y, vertex.Tangent.z);
|
PM_MESH_LOG("Tangent: {0}, {1}, {2}", vertex.Tangent.x, vertex.Tangent.y, vertex.Tangent.z);
|
||||||
PM_CORE_TRACE("TexCoord: {0}, {1}", vertex.Texcoord.x, vertex.Texcoord.y);
|
PM_MESH_LOG("TexCoord: {0}, {1}", vertex.Texcoord.x, vertex.Texcoord.y);
|
||||||
PM_CORE_TRACE("--");
|
PM_MESH_LOG("--");
|
||||||
}
|
}
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < m_StaticVertices.size(); i++)
|
for (size_t i = 0; i < m_StaticVertices.size(); i++)
|
||||||
{
|
{
|
||||||
auto& vertex = m_StaticVertices[i];
|
auto& vertex = m_StaticVertices[i];
|
||||||
PM_CORE_TRACE("Vertex: {0}", i);
|
PM_MESH_LOG("Vertex: {0}", i);
|
||||||
PM_CORE_TRACE("Position: {0}, {1}, {2}", vertex.Position.x, vertex.Position.y, vertex.Position.z);
|
PM_MESH_LOG("Position: {0}, {1}, {2}", vertex.Position.x, vertex.Position.y, vertex.Position.z);
|
||||||
PM_CORE_TRACE("Normal: {0}, {1}, {2}", vertex.Normal.x, vertex.Normal.y, vertex.Normal.z);
|
PM_MESH_LOG("Normal: {0}, {1}, {2}", vertex.Normal.x, vertex.Normal.y, vertex.Normal.z);
|
||||||
PM_CORE_TRACE("Binormal: {0}, {1}, {2}", vertex.Binormal.x, vertex.Binormal.y, vertex.Binormal.z);
|
PM_MESH_LOG("Binormal: {0}, {1}, {2}", vertex.Binormal.x, vertex.Binormal.y, vertex.Binormal.z);
|
||||||
PM_CORE_TRACE("Tangent: {0}, {1}, {2}", vertex.Tangent.x, vertex.Tangent.y, vertex.Tangent.z);
|
PM_MESH_LOG("Tangent: {0}, {1}, {2}", vertex.Tangent.x, vertex.Tangent.y, vertex.Tangent.z);
|
||||||
PM_CORE_TRACE("TexCoord: {0}, {1}", vertex.Texcoord.x, vertex.Texcoord.y);
|
PM_MESH_LOG("TexCoord: {0}, {1}", vertex.Texcoord.x, vertex.Texcoord.y);
|
||||||
PM_CORE_TRACE("--");
|
PM_MESH_LOG("--");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PM_CORE_TRACE("------------------------------------------------------");
|
PM_MESH_LOG("------------------------------------------------------");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::BoneTransform(float time)
|
void Mesh::BoneTransform(float time)
|
||||||
@ -679,7 +617,9 @@ namespace Prism
|
|||||||
for (uint32_t i = 0; i < node->mNumMeshes; i++)
|
for (uint32_t i = 0; i < node->mNumMeshes; i++)
|
||||||
{
|
{
|
||||||
const uint32_t mesh = node->mMeshes[i];
|
const uint32_t mesh = node->mMeshes[i];
|
||||||
m_Submeshes[mesh].Transform = transform;
|
auto& submesh = m_Submeshes[mesh];
|
||||||
|
submesh.NodeName = node->mName.C_Str();
|
||||||
|
submesh.Transform = transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < node->mNumChildren; i++)
|
for (uint32_t i = 0; i < node->mNumChildren; i++)
|
||||||
|
|||||||
@ -7,11 +7,11 @@
|
|||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
#include "Buffer.h"
|
|
||||||
#include "Material.h"
|
#include "Material.h"
|
||||||
#include "Shader.h"
|
#include "Shader.h"
|
||||||
#include "VertexArray.h"
|
#include "VertexArray.h"
|
||||||
#include "Prism/Core/TimeStep.h"
|
#include "Prism/Core/TimeStep.h"
|
||||||
|
#include "Prism/Core/Math/AABB.h"
|
||||||
|
|
||||||
struct aiNode;
|
struct aiNode;
|
||||||
struct aiAnimation;
|
struct aiAnimation;
|
||||||
@ -78,6 +78,14 @@ namespace Prism
|
|||||||
void AddBoneData(uint32_t BoneID, float Weight);
|
void AddBoneData(uint32_t BoneID, float Weight);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Triangle
|
||||||
|
{
|
||||||
|
Vertex V0, V1, V2;
|
||||||
|
|
||||||
|
Triangle(const Vertex& v0, const Vertex& v1, const Vertex& v2)
|
||||||
|
: V0(v0), V1(v1), V2(v2) {}
|
||||||
|
};
|
||||||
|
|
||||||
class Submesh
|
class Submesh
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -87,7 +95,9 @@ namespace Prism
|
|||||||
uint32_t IndexCount;
|
uint32_t IndexCount;
|
||||||
|
|
||||||
glm::mat4 Transform;
|
glm::mat4 Transform;
|
||||||
glm::vec3 Min, Max; //TODO: AABB
|
AABB BoundingBox;
|
||||||
|
|
||||||
|
std::string NodeName, MeshName;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PRISM_API Mesh
|
class PRISM_API Mesh
|
||||||
@ -101,11 +111,16 @@ namespace Prism
|
|||||||
void OnUpdate(TimeStep deltaTime);
|
void OnUpdate(TimeStep deltaTime);
|
||||||
void DumpVertexBuffer();
|
void DumpVertexBuffer();
|
||||||
|
|
||||||
|
std::vector<Submesh>& GetSubmeshes() { return m_Submeshes; }
|
||||||
|
const std::vector<Submesh>& GetSubmeshes() const { return m_Submeshes; }
|
||||||
|
|
||||||
inline Ref<Shader> GetMeshShader() { return m_MeshShader; }
|
inline Ref<Shader> GetMeshShader() { return m_MeshShader; }
|
||||||
inline Ref<Material> GetMaterial() { return m_BaseMaterial; }
|
inline Ref<Material> GetMaterial() { return m_BaseMaterial; }
|
||||||
std::vector<Ref<MaterialInstance>> GetMaterials() { return m_Materials; }
|
std::vector<Ref<MaterialInstance>> GetMaterials() { return m_Materials; }
|
||||||
const std::vector<Ref<Texture2D>>& GetTextures() const { return m_Textures; }
|
const std::vector<Ref<Texture2D>>& GetTextures() const { return m_Textures; }
|
||||||
const std::string& GetFilePath() const { return m_FilePath; }
|
const std::string& GetFilePath() const { return m_FilePath; }
|
||||||
|
|
||||||
|
const std::vector<Triangle> GetTriangleCache(uint32_t index) const { return m_TriangleCache.at(index); }
|
||||||
private:
|
private:
|
||||||
void BoneTransform(float time);
|
void BoneTransform(float time);
|
||||||
void ReadNodeHierarchy(float AnimationTime, const aiNode* pNode, const glm::mat4& ParentTransform);
|
void ReadNodeHierarchy(float AnimationTime, const aiNode* pNode, const glm::mat4& ParentTransform);
|
||||||
@ -146,6 +161,8 @@ namespace Prism
|
|||||||
std::vector<Ref<Texture2D>> m_NormalMaps;
|
std::vector<Ref<Texture2D>> m_NormalMaps;
|
||||||
std::vector<Ref<MaterialInstance>> m_Materials;
|
std::vector<Ref<MaterialInstance>> m_Materials;
|
||||||
|
|
||||||
|
std::unordered_map<uint32_t, std::vector<Triangle>> m_TriangleCache;
|
||||||
|
|
||||||
// Animation
|
// Animation
|
||||||
bool m_IsAnimated = false;
|
bool m_IsAnimated = false;
|
||||||
float m_AnimationTime = 0.0f;
|
float m_AnimationTime = 0.0f;
|
||||||
|
|||||||
@ -195,23 +195,32 @@ namespace Prism
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::DrawAABB(const Ref<Mesh>& mesh, const glm::vec4& color)
|
void Renderer::DrawAABB(const Ref<Mesh>& mesh, const glm::mat4& transform, const glm::vec4& color)
|
||||||
{
|
{
|
||||||
for (Submesh& submesh : mesh->m_Submeshes)
|
for (const Submesh& submesh : mesh->m_Submeshes)
|
||||||
{
|
{
|
||||||
const auto& transform = submesh.Transform;
|
const auto& aabb = submesh.BoundingBox;
|
||||||
|
auto aabbTransform = transform * submesh.Transform;
|
||||||
|
DrawAABB(aabb, aabbTransform, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::DrawAABB(const AABB& aabb, const glm::mat4& transform, const glm::vec4& color)
|
||||||
|
{
|
||||||
|
glm::vec4 min = { aabb.Min.x, aabb.Min.y, aabb.Min.z, 1.0f };
|
||||||
|
glm::vec4 max = { aabb.Max.x, aabb.Max.y, aabb.Max.z, 1.0f };
|
||||||
|
|
||||||
const glm::vec4 corners[8] =
|
const glm::vec4 corners[8] =
|
||||||
{
|
{
|
||||||
transform * glm::vec4 { submesh.Min.x, submesh.Min.y, submesh.Max.z, 1.0f },
|
transform * glm::vec4 { aabb.Min.x, aabb.Min.y, aabb.Max.z, 1.0f },
|
||||||
transform * glm::vec4 { submesh.Min.x, submesh.Max.y, submesh.Max.z, 1.0f },
|
transform * glm::vec4 { aabb.Min.x, aabb.Max.y, aabb.Max.z, 1.0f },
|
||||||
transform * glm::vec4 { submesh.Max.x, submesh.Max.y, submesh.Max.z, 1.0f },
|
transform * glm::vec4 { aabb.Max.x, aabb.Max.y, aabb.Max.z, 1.0f },
|
||||||
transform * glm::vec4 { submesh.Max.x, submesh.Min.y, submesh.Max.z, 1.0f },
|
transform * glm::vec4 { aabb.Max.x, aabb.Min.y, aabb.Max.z, 1.0f },
|
||||||
|
|
||||||
transform * glm::vec4 { submesh.Min.x, submesh.Min.y, submesh.Min.z, 1.0f },
|
transform * glm::vec4 { aabb.Min.x, aabb.Min.y, aabb.Min.z, 1.0f },
|
||||||
transform * glm::vec4 { submesh.Min.x, submesh.Max.y, submesh.Min.z, 1.0f },
|
transform * glm::vec4 { aabb.Min.x, aabb.Max.y, aabb.Min.z, 1.0f },
|
||||||
transform * glm::vec4 { submesh.Max.x, submesh.Max.y, submesh.Min.z, 1.0f },
|
transform * glm::vec4 { aabb.Max.x, aabb.Max.y, aabb.Min.z, 1.0f },
|
||||||
transform * glm::vec4 { submesh.Max.x, submesh.Min.y, submesh.Min.z, 1.0f }
|
transform * glm::vec4 { aabb.Max.x, aabb.Min.y, aabb.Min.z, 1.0f }
|
||||||
};
|
};
|
||||||
|
|
||||||
for (uint32_t i = 0; i < 4; i++)
|
for (uint32_t i = 0; i < 4; i++)
|
||||||
@ -223,7 +232,6 @@ namespace Prism
|
|||||||
for (uint32_t i = 0; i < 4; i++)
|
for (uint32_t i = 0; i < 4; i++)
|
||||||
Renderer2D::DrawLine(corners[i], corners[i + 4], color);
|
Renderer2D::DrawLine(corners[i], corners[i + 4], color);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
RenderCommandQueue& Renderer::GetRenderCommandQueue()
|
RenderCommandQueue& Renderer::GetRenderCommandQueue()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -56,7 +56,8 @@ namespace Prism
|
|||||||
static void SubmitFullscreenQuad(const Ref<MaterialInstance>& material);
|
static void SubmitFullscreenQuad(const Ref<MaterialInstance>& material);
|
||||||
static void SubmitMesh(const Ref<Mesh>& mesh, const glm::mat4& transform, const Ref<MaterialInstance>& overrideMaterial = nullptr);
|
static void SubmitMesh(const Ref<Mesh>& mesh, const glm::mat4& transform, const Ref<MaterialInstance>& overrideMaterial = nullptr);
|
||||||
|
|
||||||
static void DrawAABB(const Ref<Mesh>& mesh, const glm::vec4& color = glm::vec4(1.0f));
|
static void DrawAABB(const AABB& aabb, const glm::mat4& transform, const glm::vec4& color = glm::vec4(1.0f));
|
||||||
|
static void DrawAABB(const Ref<Mesh>& mesh,const glm::mat4& transform, const glm::vec4& color = glm::vec4(1.0f));
|
||||||
private:
|
private:
|
||||||
static RenderCommandQueue& GetRenderCommandQueue();
|
static RenderCommandQueue& GetRenderCommandQueue();
|
||||||
};
|
};
|
||||||
|
|||||||
@ -194,7 +194,7 @@ namespace Prism
|
|||||||
s_Data.LineShader->SetMat4("u_ViewProjection", s_Data.CameraViewProj);
|
s_Data.LineShader->SetMat4("u_ViewProjection", s_Data.CameraViewProj);
|
||||||
|
|
||||||
s_Data.LineVertexArray->Bind();
|
s_Data.LineVertexArray->Bind();
|
||||||
Renderer::SetLineThickness(2.0f);
|
Renderer::SetLineThickness(1.0f);
|
||||||
Renderer::DrawIndexed(s_Data.LineIndexCount, PrimitiveType::Lines, s_Data.DepthTest);
|
Renderer::DrawIndexed(s_Data.LineIndexCount, PrimitiveType::Lines, s_Data.DepthTest);
|
||||||
s_Data.Stats.DrawCalls++;
|
s_Data.Stats.DrawCalls++;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,6 +25,7 @@ namespace Prism
|
|||||||
// Resources
|
// Resources
|
||||||
Ref<MaterialInstance> SkyboxMaterial;
|
Ref<MaterialInstance> SkyboxMaterial;
|
||||||
Environment SceneEnvironment;
|
Environment SceneEnvironment;
|
||||||
|
Light ActiveLight;
|
||||||
} SceneData;
|
} SceneData;
|
||||||
|
|
||||||
Ref<Texture2D> BRDFLUT;
|
Ref<Texture2D> BRDFLUT;
|
||||||
@ -101,6 +102,7 @@ namespace Prism
|
|||||||
s_Data.SceneData.SceneCamera = scene->m_Camera;
|
s_Data.SceneData.SceneCamera = scene->m_Camera;
|
||||||
s_Data.SceneData.SkyboxMaterial = scene->m_SkyboxMaterial;
|
s_Data.SceneData.SkyboxMaterial = scene->m_SkyboxMaterial;
|
||||||
s_Data.SceneData.SceneEnvironment = scene->m_Environment;
|
s_Data.SceneData.SceneEnvironment = scene->m_Environment;
|
||||||
|
s_Data.SceneData.ActiveLight = scene->m_Light;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneRenderer::EndScene()
|
void SceneRenderer::EndScene()
|
||||||
@ -128,8 +130,8 @@ namespace Prism
|
|||||||
|
|
||||||
std::pair<Ref<TextureCube>, Ref<TextureCube>> SceneRenderer::CreateEnvironmentMap(const std::string& filepath)
|
std::pair<Ref<TextureCube>, Ref<TextureCube>> SceneRenderer::CreateEnvironmentMap(const std::string& filepath)
|
||||||
{
|
{
|
||||||
const uint32_t cubemapSize = 2048;
|
constexpr uint32_t cubemapSize = 2048;
|
||||||
const uint32_t irradianceMapSize = 32;
|
constexpr uint32_t irradianceMapSize = 32;
|
||||||
|
|
||||||
Ref<TextureCube> envUnfiltered = TextureCube::Create(TextureFormat::Float16, cubemapSize, cubemapSize);
|
Ref<TextureCube> envUnfiltered = TextureCube::Create(TextureFormat::Float16, cubemapSize, cubemapSize);
|
||||||
if (!equirectangularConversionShader)
|
if (!equirectangularConversionShader)
|
||||||
@ -245,6 +247,9 @@ namespace Prism
|
|||||||
baseMaterial->Set("u_EnvIrradianceTex", s_Data.SceneData.SceneEnvironment.IrradianceMap);
|
baseMaterial->Set("u_EnvIrradianceTex", s_Data.SceneData.SceneEnvironment.IrradianceMap);
|
||||||
baseMaterial->Set("u_BRDFLUTTexture", s_Data.BRDFLUT);
|
baseMaterial->Set("u_BRDFLUTTexture", s_Data.BRDFLUT);
|
||||||
|
|
||||||
|
// Set lights (TODO: move to light environment and don't do per mesh)
|
||||||
|
baseMaterial->Set("lights", s_Data.SceneData.ActiveLight);
|
||||||
|
|
||||||
auto overrideMaterial = nullptr; // dc.Material;
|
auto overrideMaterial = nullptr; // dc.Material;
|
||||||
Renderer::SubmitMesh(dc.mesh, dc.Transform, overrideMaterial);
|
Renderer::SubmitMesh(dc.mesh, dc.Transform, overrideMaterial);
|
||||||
}
|
}
|
||||||
@ -261,7 +266,7 @@ namespace Prism
|
|||||||
{
|
{
|
||||||
Renderer2D::BeginScene(viewProjection);
|
Renderer2D::BeginScene(viewProjection);
|
||||||
for (auto& dc : s_Data.DrawList)
|
for (auto& dc : s_Data.DrawList)
|
||||||
Renderer::DrawAABB(dc.mesh);
|
Renderer::DrawAABB(dc.mesh, dc.Transform);
|
||||||
Renderer2D::EndScene();
|
Renderer2D::EndScene();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,6 +21,14 @@ namespace Prism
|
|||||||
static Environment Load(const std::string& filepath);
|
static Environment Load(const std::string& filepath);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Light
|
||||||
|
{
|
||||||
|
glm::vec3 Direction;
|
||||||
|
glm::vec3 Radiance;
|
||||||
|
|
||||||
|
float Multiplier = 1.0f;
|
||||||
|
};
|
||||||
|
|
||||||
class PRISM_API Scene{
|
class PRISM_API Scene{
|
||||||
public:
|
public:
|
||||||
Scene(const std::string& debugName = "Scene");
|
Scene(const std::string& debugName = "Scene");
|
||||||
@ -37,6 +45,7 @@ namespace Prism
|
|||||||
void SetEnvironment(const Environment& environment);
|
void SetEnvironment(const Environment& environment);
|
||||||
void SetSkybox(const Ref<TextureCube>& skybox);
|
void SetSkybox(const Ref<TextureCube>& skybox);
|
||||||
|
|
||||||
|
Light& GetLight() { return m_Light; }
|
||||||
float& GetSkyboxLod() { return m_SkyboxLod; }
|
float& GetSkyboxLod() { return m_SkyboxLod; }
|
||||||
|
|
||||||
void AddEntity(Entity* entity);
|
void AddEntity(Entity* entity);
|
||||||
@ -47,12 +56,16 @@ namespace Prism
|
|||||||
std::vector<Entity*> m_Entities;
|
std::vector<Entity*> m_Entities;
|
||||||
Camera m_Camera;
|
Camera m_Camera;
|
||||||
|
|
||||||
|
Light m_Light;
|
||||||
|
float m_LightMultiplier = 0.3f;
|
||||||
|
|
||||||
Environment m_Environment;
|
Environment m_Environment;
|
||||||
Ref<TextureCube> m_SkyboxTexture;
|
Ref<TextureCube> m_SkyboxTexture;
|
||||||
Ref<MaterialInstance> m_SkyboxMaterial;
|
Ref<MaterialInstance> m_SkyboxMaterial;
|
||||||
|
|
||||||
float m_SkyboxLod = 1.0f;
|
float m_SkyboxLod = 1.0f;
|
||||||
|
|
||||||
|
private:
|
||||||
friend class SceneRenderer;
|
friend class SceneRenderer;
|
||||||
friend class SceneHierarchyPanel;
|
friend class SceneHierarchyPanel;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user