add mouse picking, add more hdr environment maps
This commit is contained in:
+121
-13
@@ -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 };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-16
@@ -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
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
+109
-169
@@ -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,23 +349,27 @@ 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())
|
||||||
{
|
{
|
||||||
PM_CORE_TRACE(" Roughness map path = {0}", texturePath);
|
PM_CORE_TRACE(" Roughness map path = {0}", texturePath);
|
||||||
mi->Set("u_RoughnessTexture", texture);
|
mi->Set("u_RoughnessTexture", texture);
|
||||||
mi->Set("u_RoughnessTexToggle", 1.0f);
|
mi->Set("u_RoughnessTexToggle", 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 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)
|
||||||
/*
|
|
||||||
// Normal maps
|
|
||||||
if (aiMaterial->GetTexture(aiTextureType_NORMALS, 0, &aiTexPath) == AI_SUCCESS)
|
|
||||||
{
|
{
|
||||||
// TODO: Temp - this should be handled by Hazel's filesystem
|
PM_MESH_LOG(" No metalness map");
|
||||||
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);
|
mi->Set("u_Metalness", metalness);
|
||||||
if (texture->Loaded())
|
mi->Set("u_MetalnessTexToggle", 0.0f);
|
||||||
{
|
|
||||||
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 });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
PM_MESH_LOG("------------------------");
|
||||||
}
|
}
|
||||||
|
|
||||||
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,36 +195,44 @@ 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;
|
||||||
const glm::vec4 corners[8] =
|
DrawAABB(aabb, aabbTransform, color);
|
||||||
{
|
|
||||||
transform * glm::vec4 { submesh.Min.x, submesh.Min.y, submesh.Max.z, 1.0f },
|
|
||||||
transform * glm::vec4 { submesh.Min.x, submesh.Max.y, submesh.Max.z, 1.0f },
|
|
||||||
transform * glm::vec4 { submesh.Max.x, submesh.Max.y, submesh.Max.z, 1.0f },
|
|
||||||
transform * glm::vec4 { submesh.Max.x, submesh.Min.y, submesh.Max.z, 1.0f },
|
|
||||||
|
|
||||||
transform * glm::vec4 { submesh.Min.x, submesh.Min.y, submesh.Min.z, 1.0f },
|
|
||||||
transform * glm::vec4 { submesh.Min.x, submesh.Max.y, submesh.Min.z, 1.0f },
|
|
||||||
transform * glm::vec4 { submesh.Max.x, submesh.Max.y, submesh.Min.z, 1.0f },
|
|
||||||
transform * glm::vec4 { submesh.Max.x, submesh.Min.y, submesh.Min.z, 1.0f }
|
|
||||||
};
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < 4; i++)
|
|
||||||
Renderer2D::DrawLine(corners[i], corners[(i + 1) % 4], color);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < 4; i++)
|
|
||||||
Renderer2D::DrawLine(corners[i + 4], corners[((i + 1) % 4) + 4], color);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < 4; i++)
|
|
||||||
Renderer2D::DrawLine(corners[i], corners[i + 4], 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] =
|
||||||
|
{
|
||||||
|
transform * glm::vec4 { aabb.Min.x, aabb.Min.y, aabb.Max.z, 1.0f },
|
||||||
|
transform * glm::vec4 { aabb.Min.x, aabb.Max.y, aabb.Max.z, 1.0f },
|
||||||
|
transform * glm::vec4 { aabb.Max.x, aabb.Max.y, aabb.Max.z, 1.0f },
|
||||||
|
transform * glm::vec4 { aabb.Max.x, aabb.Min.y, aabb.Max.z, 1.0f },
|
||||||
|
|
||||||
|
transform * glm::vec4 { aabb.Min.x, aabb.Min.y, aabb.Min.z, 1.0f },
|
||||||
|
transform * glm::vec4 { aabb.Min.x, aabb.Max.y, aabb.Min.z, 1.0f },
|
||||||
|
transform * glm::vec4 { aabb.Max.x, aabb.Max.y, aabb.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++)
|
||||||
|
Renderer2D::DrawLine(corners[i], corners[(i + 1) % 4], color);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < 4; i++)
|
||||||
|
Renderer2D::DrawLine(corners[i + 4], corners[((i + 1) % 4) + 4], color);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < 4; i++)
|
||||||
|
Renderer2D::DrawLine(corners[i], corners[i + 4], color);
|
||||||
|
}
|
||||||
|
|
||||||
RenderCommandQueue& Renderer::GetRenderCommandQueue()
|
RenderCommandQueue& Renderer::GetRenderCommandQueue()
|
||||||
{
|
{
|
||||||
return s_Data.m_CommandQueue;
|
return s_Data.m_CommandQueue;
|
||||||
|
|||||||
@@ -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