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");
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -208,9 +208,12 @@ namespace Prism
|
||||
// Editor
|
||||
m_CheckerboardTex = Texture2D::Create("assets/editor/Checkerboard.tga");
|
||||
|
||||
// lights
|
||||
m_Light.Direction = {-0.5f, -0.5f, 1.0f};
|
||||
m_Light.Radiance = {1.0f, 1.0f, 1.0f};
|
||||
// set lights
|
||||
auto& light = m_Scene->GetLight();
|
||||
light.Direction = { -0.5f, -0.5f, 1.0f };
|
||||
light.Radiance = { 1.0f, 1.0f, 1.0f };
|
||||
|
||||
m_CurrentlySelectedTransform = &m_MeshEntity->Transform();
|
||||
}
|
||||
|
||||
void EditorLayer::OnDetach()
|
||||
@@ -228,7 +231,6 @@ namespace Prism
|
||||
m_MeshMaterial->Set("u_AlbedoColor", m_AlbedoInput.Color);
|
||||
m_MeshMaterial->Set("u_Metalness", m_MetalnessInput.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_NormalTexToggle", m_NormalInput.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_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_AlbedoTexToggle", m_AlbedoInput.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);
|
||||
auto viewProj = m_Scene->GetCamera().GetViewProjection();
|
||||
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());
|
||||
Renderer::DrawAABB(m_MeshEntity->GetMesh(), m_MeshEntity->Transform());
|
||||
|
||||
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();
|
||||
Renderer::EndRenderPass();
|
||||
}
|
||||
@@ -441,9 +455,10 @@ namespace Prism
|
||||
ImGui::Columns(2);
|
||||
ImGui::AlignTextToFramePadding();
|
||||
|
||||
Property("Light Direction", m_Light.Direction);
|
||||
Property("Light Radiance", m_Light.Radiance, PropertyFlag::ColorProperty);
|
||||
Property("Light Multiplier", m_LightMultiplier, 0.0f, 5.0f);
|
||||
auto& light = m_Scene->GetLight();
|
||||
Property("Light Direction", light.Direction);
|
||||
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("Radiance Prefiltering", m_RadiancePrefilter);
|
||||
@@ -642,6 +657,8 @@ namespace Prism
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
|
||||
ImGui::Begin("Viewport");
|
||||
|
||||
auto viewportOffset = ImGui::GetCursorPos(); // includes tab bar
|
||||
auto viewportSize = ImGui::GetContentRegionAvail();
|
||||
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));
|
||||
@@ -649,13 +666,19 @@ namespace Prism
|
||||
ImGui::Image((ImTextureRef)SceneRenderer::GetFinalColorBufferRendererID(), viewportSize, { 0, 1 }, { 1, 0 });
|
||||
|
||||
|
||||
static int counter = 0;
|
||||
auto windowSize = ImGui::GetWindowSize();
|
||||
ImVec2 minBound = ImGui::GetWindowPos();
|
||||
minBound.x += viewportOffset.x;
|
||||
minBound.y += viewportOffset.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);
|
||||
|
||||
// ImGuizmo
|
||||
if (m_GizmoType != -1)
|
||||
if (m_GizmoType != -1 && m_CurrentlySelectedTransform)
|
||||
{
|
||||
const auto rw = (float)ImGui::GetWindowWidth();
|
||||
const auto rh = (float)ImGui::GetWindowHeight();
|
||||
@@ -663,7 +686,15 @@ namespace Prism
|
||||
ImGuizmo::SetDrawlist();
|
||||
ImGuizmo::SetRect(ImGui::GetWindowPos().x, ImGui::GetWindowPos().y, rw, rh);
|
||||
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();
|
||||
@@ -678,6 +709,7 @@ namespace Prism
|
||||
|
||||
EventDispatcher dispatcher(e);
|
||||
dispatcher.Dispatch<KeyPressedEvent>(PM_BIND_EVENT_FN(EditorLayer::OnKeyPressedEvent));
|
||||
dispatcher.Dispatch<MouseButtonPressedEvent>(PM_BIND_EVENT_FN(EditorLayer::OnMouseButtonPressedEvent));
|
||||
}
|
||||
|
||||
bool EditorLayer::OnKeyPressedEvent(KeyPressedEvent& e)
|
||||
@@ -714,9 +746,85 @@ namespace Prism
|
||||
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)
|
||||
{
|
||||
SceneRenderer::GetOptions().ShowBoundingBoxes = 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:
|
||||
bool OnKeyPressedEvent(KeyPressedEvent& e);
|
||||
bool OnMouseButtonPressedEvent(MouseButtonPressedEvent& e);
|
||||
|
||||
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:
|
||||
Scope<SceneHierarchyPanel> m_SceneHierarchyPanel;
|
||||
|
||||
@@ -36,25 +41,27 @@ namespace Prism
|
||||
|
||||
Entity* m_MeshEntity = nullptr;
|
||||
|
||||
Ref<Shader> m_BrushShader;
|
||||
Ref<Mesh> m_PlaneMesh;
|
||||
Ref<Material> m_SphereBaseMaterial;
|
||||
|
||||
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_DielectricSphereMaterialInstances;
|
||||
|
||||
float m_GridScale = 16.025f, m_GridSize = 0.025f;
|
||||
float m_MeshScale = 1.0f;
|
||||
|
||||
|
||||
// Imguizmo
|
||||
glm::vec2 m_ViewportBounds[2];
|
||||
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
|
||||
bool m_AllowViewportCameraEvents = false;
|
||||
@@ -97,14 +104,6 @@ namespace Prism
|
||||
RoughnessInput m_RoughnessInput;
|
||||
|
||||
|
||||
struct Light
|
||||
{
|
||||
glm::vec3 Direction;
|
||||
glm::vec3 Radiance;
|
||||
};
|
||||
Light m_Light;
|
||||
float m_LightMultiplier = 0.3f;
|
||||
|
||||
// PBR params
|
||||
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);
|
||||
|
||||
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.WorldNormals = mat3(u_Transform) * mat3(a_Tangent, a_Binormal, a_Normal);
|
||||
vs_Output.Binormal = mat3(boneTransform) * a_Binormal;
|
||||
@@ -68,6 +68,7 @@ const vec3 Fdielectric = vec3(0.04);
|
||||
struct Light {
|
||||
vec3 Direction;
|
||||
vec3 Radiance;
|
||||
float Multiplier;
|
||||
};
|
||||
|
||||
in VertexOutput
|
||||
@@ -256,7 +257,7 @@ vec3 Lighting(vec3 F0)
|
||||
for(int i = 0; i < LightCount; i++)
|
||||
{
|
||||
vec3 Li = -lights.Direction;
|
||||
vec3 Lradiance = lights.Radiance;
|
||||
vec3 Lradiance = lights.Radiance * lights.Multiplier;
|
||||
vec3 Lh = normalize(Li + m_Params.View);
|
||||
|
||||
// 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);
|
||||
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 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
|
||||
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
|
||||
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);
|
||||
|
||||
color = vec4(lightContribution + iblContribution, 1.0);
|
||||
|
||||
@@ -57,6 +57,7 @@ const vec3 Fdielectric = vec3(0.04);
|
||||
struct Light {
|
||||
vec3 Direction;
|
||||
vec3 Radiance;
|
||||
float Multiplier;
|
||||
};
|
||||
|
||||
in VertexOutput
|
||||
@@ -246,7 +247,7 @@ vec3 Lighting(vec3 F0)
|
||||
for(int i = 0; i < LightCount; i++)
|
||||
{
|
||||
vec3 Li = -lights.Direction;
|
||||
vec3 Lradiance = lights.Radiance;
|
||||
vec3 Lradiance = lights.Radiance * lights.Multiplier;
|
||||
vec3 Lh = normalize(Li + m_Params.View);
|
||||
|
||||
// Calculate angles between surface normal and various light vectors.
|
||||
@@ -271,15 +272,15 @@ vec3 Lighting(vec3 F0)
|
||||
vec3 IBL(vec3 F0, vec3 Lr)
|
||||
{
|
||||
vec3 irradiance = texture(u_EnvIrradianceTex, m_Params.Normal).rgb;
|
||||
// vec3 F = fresnelSchlickRoughness(F0, m_Params.NdotV, m_Params.Roughness);
|
||||
vec3 F = fresnelSchlick(F0, m_Params.NdotV);
|
||||
vec3 F = fresnelSchlickRoughness(F0, m_Params.NdotV, m_Params.Roughness);
|
||||
// vec3 F = fresnelSchlickR(F0, m_Params.NdotV);
|
||||
vec3 kd = (1.0 - F) * (1.0 - m_Params.Metalness);
|
||||
vec3 diffuseIBL = m_Params.Albedo * irradiance;
|
||||
|
||||
int u_EnvRadianceTexLevels = textureQueryLevels(u_EnvRadianceTex);
|
||||
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 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
|
||||
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);
|
||||
|
||||
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/MouseEvent.h"
|
||||
|
||||
|
||||
#include "Prism/Core/Math/AABB.h"
|
||||
#include "Prism/Core/Math/Ray.h"
|
||||
|
||||
// ImGui
|
||||
#include "imgui.h"
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace Prism
|
||||
static bool IsMouseButtonPressed(int button);
|
||||
static float GetMouseX();
|
||||
static float GetMouseY();
|
||||
static std::pair<float, float> GetMousePosition();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -129,4 +129,7 @@
|
||||
#define PM_KEY_RIGHT_SUPER 347
|
||||
#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
|
||||
|
||||
@@ -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 SetEventCallback(const EventCallbackFn& callback) = 0;
|
||||
virtual unsigned int GetWidth() const = 0;
|
||||
virtual unsigned int GetHeight() const = 0;
|
||||
virtual uint32_t GetWidth() 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 void SetVSync(bool enable) = 0;
|
||||
|
||||
@@ -132,11 +132,13 @@ namespace Prism
|
||||
{
|
||||
glm::mat4 localTransform = Mat4FromAssimpMat4(node->mTransformation);
|
||||
glm::mat4 transform = parentTransform * localTransform;
|
||||
/*
|
||||
for (uint32_t i = 0; i < node->mNumMeshes; i++)
|
||||
{
|
||||
uint32_t meshIndex = node->mMeshes[i];
|
||||
mesh->m_Submeshes[meshIndex].Transform = transform;
|
||||
}
|
||||
*/
|
||||
|
||||
if (ImGui::TreeNode(node->mName.C_Str()))
|
||||
{
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Prism
|
||||
OpenGLFrameBuffer::OpenGLFrameBuffer(const FramebufferSpecification& 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;
|
||||
|
||||
m_Specification.Width = width;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Prism
|
||||
void Bind() 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;
|
||||
|
||||
|
||||
@@ -71,10 +71,7 @@ namespace Prism
|
||||
{
|
||||
case GL_DEBUG_SEVERITY_HIGH:
|
||||
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, "ERROR");
|
||||
}
|
||||
PM_CORE_ASSERT(false);
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SEVERITY_MEDIUM:
|
||||
|
||||
@@ -59,7 +59,8 @@ namespace Prism
|
||||
|
||||
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();
|
||||
vertexBuffer->Bind();
|
||||
|
||||
@@ -26,23 +26,21 @@ namespace Prism
|
||||
|
||||
float Input::GetMouseX()
|
||||
{
|
||||
const auto& window = dynamic_cast<WindowsWindow&>(Application::Get().GetWindow());
|
||||
|
||||
double xpos, ypos;
|
||||
glfwGetCursorPos(static_cast<GLFWwindow*>(window.GetNativeWindow()), &xpos, &ypos);
|
||||
|
||||
return static_cast<float>(xpos);
|
||||
return GetMousePosition().first;
|
||||
}
|
||||
|
||||
float Input::GetMouseY()
|
||||
{
|
||||
return GetMousePosition().second;
|
||||
}
|
||||
|
||||
std::pair<float, float> Input::GetMousePosition()
|
||||
{
|
||||
const auto& window = dynamic_cast<WindowsWindow&>(Application::Get().GetWindow());
|
||||
|
||||
double 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_ResizeNWSE] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); // FIXME: GLFW doesn't have this.
|
||||
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()
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace Prism
|
||||
inline void SetEventCallback(const EventCallbackFn& callback) override { m_Data.EventCallback = callback; }
|
||||
bool const IsVSync() const override { return m_Data.VSync; }
|
||||
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;
|
||||
|
||||
inline void* GetNativeWindow() const { return m_Window; }
|
||||
|
||||
@@ -24,14 +24,17 @@ namespace Prism
|
||||
Camera::Camera(const glm::mat4& projectionMatrix)
|
||||
: m_ProjectionMatrix(projectionMatrix)
|
||||
{
|
||||
m_Position = { 0, 0, 10 };
|
||||
m_Rotation = glm::vec3(90.0f, 0.0f, 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_Pitch = M_PI / 4.0f;
|
||||
|
||||
UpdateCameraView();
|
||||
}
|
||||
|
||||
void Camera::Focus()
|
||||
@@ -56,13 +59,7 @@ namespace Prism
|
||||
MouseZoom(delta.y);
|
||||
}
|
||||
|
||||
m_Position = CalculatePosition();
|
||||
|
||||
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);
|
||||
UpdateCameraView();
|
||||
}
|
||||
|
||||
void Camera::OnEvent(Event& e)
|
||||
@@ -86,6 +83,16 @@ namespace Prism
|
||||
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)
|
||||
{
|
||||
const float delta = e.GetOffsetY() * 0.1f;
|
||||
|
||||
@@ -43,6 +43,8 @@ namespace Prism
|
||||
public:
|
||||
inline void SetViewportSize(const uint32_t width, const uint32_t height) { m_ViewportWidth = width; m_ViewportHeight = height; }
|
||||
private:
|
||||
void UpdateCameraView();
|
||||
|
||||
bool OnMouseScroll(MouseScrolledEvent& e);
|
||||
void MousePan(const glm::vec2& delta);
|
||||
void MouseRotate(const glm::vec2& delta);
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace Prism
|
||||
virtual void Bind() 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;
|
||||
|
||||
|
||||
+109
-169
@@ -20,6 +20,13 @@
|
||||
|
||||
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 =
|
||||
aiProcess_CalcTangentSpace | // Create binormals/tangents just in case
|
||||
aiProcess_Triangulate | // Make sure we're triangles
|
||||
@@ -104,9 +111,7 @@ namespace Prism
|
||||
if (!scene || !scene->HasMeshes())
|
||||
PM_CORE_ERROR("Failed to load mesh file: {0}", filename);
|
||||
|
||||
//double factor;
|
||||
//scene->mMetaData->Get("UnitScaleFactor", factor);
|
||||
//PM_CORE_INFO("FBX Scene Scale: {0}", factor);
|
||||
m_Scene = scene;
|
||||
|
||||
m_IsAnimated = scene->mAnimations != nullptr;
|
||||
m_MeshShader = m_IsAnimated ? Renderer::GetShaderLibrary()->Get("PBRShader_Anim") : Renderer::GetShaderLibrary()->Get("PBRShader_Static");
|
||||
@@ -117,16 +122,17 @@ namespace Prism
|
||||
uint32_t indexCount = 0;
|
||||
|
||||
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];
|
||||
|
||||
Submesh submesh;
|
||||
Submesh& submesh = m_Submeshes.emplace_back();
|
||||
submesh.BaseVertex = vertexCount;
|
||||
submesh.BaseIndex = indexCount;
|
||||
submesh.MaterialIndex = mesh->mMaterialIndex;
|
||||
submesh.IndexCount = mesh->mNumFaces * 3;
|
||||
m_Submeshes.push_back(submesh);
|
||||
// m_Submeshes.push_back(submesh);
|
||||
submesh.MeshName = mesh->mName.C_Str();
|
||||
|
||||
vertexCount += mesh->mNumVertices;
|
||||
indexCount += submesh.IndexCount;
|
||||
@@ -155,8 +161,10 @@ namespace Prism
|
||||
}
|
||||
}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++)
|
||||
{
|
||||
@@ -164,12 +172,12 @@ namespace Prism
|
||||
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 };
|
||||
|
||||
submesh.Min.x = glm::min(vertex.Position.x, submesh.Min.x);
|
||||
submesh.Min.y = glm::min(vertex.Position.y, submesh.Min.y);
|
||||
submesh.Min.z = glm::min(vertex.Position.z, submesh.Min.z);
|
||||
submesh.Max.x = glm::max(vertex.Position.x, submesh.Max.x);
|
||||
submesh.Max.y = glm::max(vertex.Position.y, submesh.Max.y);
|
||||
submesh.Max.z = glm::max(vertex.Position.z, submesh.Max.z);
|
||||
aabb.Min.x = glm::min(vertex.Position.x, aabb.Min.x);
|
||||
aabb.Min.y = glm::min(vertex.Position.y, aabb.Min.y);
|
||||
aabb.Min.z = glm::min(vertex.Position.z, aabb.Min.z);
|
||||
aabb.Max.x = glm::max(vertex.Position.x, aabb.Max.x);
|
||||
aabb.Max.y = glm::max(vertex.Position.y, aabb.Max.y);
|
||||
aabb.Max.z = glm::max(vertex.Position.z, aabb.Max.z);
|
||||
|
||||
|
||||
if (mesh->HasTangentsAndBitangents())
|
||||
@@ -189,7 +197,11 @@ namespace Prism
|
||||
for (size_t i = 0; i < mesh->mNumFaces; i++)
|
||||
{
|
||||
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
|
||||
if (scene->HasMaterials())
|
||||
{
|
||||
PM_CORE_INFO("---- Materials - {0} ----", filename);
|
||||
|
||||
m_Textures.resize(scene->mNumMaterials);
|
||||
m_Materials.resize(scene->mNumMaterials);
|
||||
for (uint32_t i = 0; i < scene->mNumMaterials; i++)
|
||||
@@ -248,16 +262,26 @@ namespace Prism
|
||||
auto mi = CreateRef<MaterialInstance>(m_BaseMaterial);
|
||||
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;
|
||||
uint32_t textureCount = aiMaterial->GetTextureCount(aiTextureType_DIFFUSE);
|
||||
PM_CORE_TRACE(" TextureCount = {0}", textureCount);
|
||||
PM_MESH_LOG(" TextureCount = {0}", textureCount);
|
||||
|
||||
aiColor3D aiColor;
|
||||
aiMaterial->Get(AI_MATKEY_COLOR_DIFFUSE, aiColor);
|
||||
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
|
||||
std::filesystem::path path = filename;
|
||||
@@ -265,27 +289,25 @@ namespace Prism
|
||||
parentPath /= std::string(aiTexPath.data);
|
||||
std::string texturePath = parentPath.string();
|
||||
|
||||
PM_MESH_LOG(" Albedo map path = {0}", texturePath);
|
||||
auto texture = Texture2D::Create(texturePath, true);
|
||||
if (texture->Loaded())
|
||||
{
|
||||
m_Textures[i] = texture;
|
||||
PM_CORE_TRACE(" Texture Path = {0}", texturePath);
|
||||
mi->Set("u_AlbedoTexture", m_Textures[i]);
|
||||
mi->Set("u_AlbedoTexToggle", 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
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 });
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mi->Set("u_AlbedoTexToggle", 0.0f);
|
||||
mi->Set("u_AlbedoColor", glm::vec3 { aiColor.r, aiColor.g, aiColor.b });
|
||||
|
||||
PM_CORE_INFO("Mesh has no albedo map");
|
||||
PM_MESH_LOG(" No albedo map");
|
||||
}
|
||||
|
||||
// Normal Maps
|
||||
@@ -299,21 +321,21 @@ namespace Prism
|
||||
parentPath /= std::string(aiTexPath.data);
|
||||
std::string texturePath = parentPath.string();
|
||||
|
||||
PM_MESH_LOG(" Normal map path = {0}", texturePath);
|
||||
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);
|
||||
PM_CORE_ERROR(" Could not load texture: {0}", texturePath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PM_CORE_TRACE("Mesh has no normal map");
|
||||
PM_MESH_LOG(" no normal map");
|
||||
}
|
||||
|
||||
// Roughness map
|
||||
@@ -327,23 +349,27 @@ namespace Prism
|
||||
parentPath /= std::string(aiTexPath.data);
|
||||
std::string texturePath = parentPath.string();
|
||||
|
||||
PM_MESH_LOG(" Roughness map path = {0}", texturePath);
|
||||
auto texture = Texture2D::Create(texturePath);
|
||||
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_RoughnessTexToggle", 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
PM_CORE_ERROR("Could not load texture: {0}", texturePath);
|
||||
PM_CORE_ERROR(" Could not load texture: {0}", texturePath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PM_CORE_TRACE("Mesh has no roughness texture");
|
||||
PM_MESH_LOG(" no roughness texture");
|
||||
mi->Set("u_Roughness", roughness);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// Metalness map
|
||||
// mi->Set("u_Metalness", 0.0f);
|
||||
// mi->Set("u_MetalnessTexToggle", 0.0f);
|
||||
@@ -358,7 +384,7 @@ namespace Prism
|
||||
auto texture = Texture2D::Create(texturePath);
|
||||
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_MetalnessTexToggle", 1.0f);
|
||||
}
|
||||
@@ -369,169 +395,82 @@ namespace Prism
|
||||
}
|
||||
else
|
||||
{
|
||||
PM_CORE_TRACE("Mesh has no metalness texture");
|
||||
PM_MESH_LOG(" no metalness texture");
|
||||
mi->Set("u_Metalness", metalness);
|
||||
}
|
||||
continue;
|
||||
|
||||
|
||||
#endif
|
||||
bool metalnessTextureFound = false;
|
||||
|
||||
for (uint32_t i = 0; i < aiMaterial->mNumProperties; i++)
|
||||
{
|
||||
auto prop = aiMaterial->mProperties[i];
|
||||
PM_CORE_TRACE("Material Property:");
|
||||
PM_CORE_TRACE(" Name = {0}", prop->mKey.data);
|
||||
float data = *(float*)prop->mData;
|
||||
PM_MESH_LOG(" Value = {0}", data);
|
||||
|
||||
switch (prop->mSemantic)
|
||||
{
|
||||
case aiTextureType_NONE:
|
||||
PM_CORE_TRACE(" Semantic = aiTextureType_NONE");
|
||||
break;
|
||||
case aiTextureType_DIFFUSE:
|
||||
PM_CORE_TRACE(" Semantic = aiTextureType_DIFFUSE");
|
||||
break;
|
||||
case aiTextureType_SPECULAR:
|
||||
PM_CORE_TRACE(" Semantic = aiTextureType_SPECULAR");
|
||||
break;
|
||||
case aiTextureType_AMBIENT:
|
||||
PM_CORE_TRACE(" Semantic = aiTextureType_AMBIENT");
|
||||
break;
|
||||
case aiTextureType_EMISSIVE:
|
||||
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;
|
||||
case aiTextureType_NONE: PM_MESH_LOG(" Semantic = aiTextureType_NONE"); break;
|
||||
case aiTextureType_DIFFUSE: PM_MESH_LOG(" Semantic = aiTextureType_DIFFUSE"); break;
|
||||
case aiTextureType_SPECULAR: PM_MESH_LOG(" Semantic = aiTextureType_SPECULAR"); break;
|
||||
case aiTextureType_AMBIENT: PM_MESH_LOG(" Semantic = aiTextureType_AMBIENT"); break;
|
||||
case aiTextureType_EMISSIVE: PM_MESH_LOG(" Semantic = aiTextureType_EMISSIVE"); break;
|
||||
case aiTextureType_HEIGHT: PM_MESH_LOG(" Semantic = aiTextureType_HEIGHT"); break;
|
||||
case aiTextureType_NORMALS: PM_MESH_LOG(" Semantic = aiTextureType_NORMALS"); break;
|
||||
case aiTextureType_SHININESS: PM_MESH_LOG(" Semantic = aiTextureType_SHININESS"); break;
|
||||
case aiTextureType_OPACITY: PM_MESH_LOG(" Semantic = aiTextureType_OPACITY"); break;
|
||||
case aiTextureType_DISPLACEMENT:PM_MESH_LOG(" Semantic = aiTextureType_DISPLACEMENT"); break;
|
||||
case aiTextureType_LIGHTMAP: PM_MESH_LOG(" Semantic = aiTextureType_LIGHTMAP"); break;
|
||||
case aiTextureType_REFLECTION: PM_MESH_LOG(" Semantic = aiTextureType_REFLECTION"); break;
|
||||
case aiTextureType_UNKNOWN: PM_MESH_LOG(" Semantic = aiTextureType_UNKNOWN"); break;
|
||||
}
|
||||
|
||||
if (prop->mType == aiPTI_String)
|
||||
{
|
||||
uint32_t strLength = *(uint32_t*)prop->mData;
|
||||
std::string str(prop->mData + 4, strLength);
|
||||
PM_CORE_TRACE(" Value = {0}", str);
|
||||
|
||||
std::string key = prop->mKey.data;
|
||||
if (key == "$raw.ReflectionFactor|file")
|
||||
{
|
||||
metalnessTextureFound = true;
|
||||
|
||||
// TODO: Temp - this should be handled by Hazel's filesystem
|
||||
std::filesystem::path path = filename;
|
||||
auto parentPath = path.parent_path();
|
||||
parentPath /= str;
|
||||
std::string texturePath = parentPath.string();
|
||||
|
||||
|
||||
PM_MESH_LOG(" Metalness map path = {0}", texturePath);
|
||||
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_CORE_ERROR(" Could not load texture: {0}", texturePath);
|
||||
mi->Set("u_Metalness", metalness);
|
||||
mi->Set("u_MetalnessTexToggle", 0.0f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// Normal maps
|
||||
if (aiMaterial->GetTexture(aiTextureType_NORMALS, 0, &aiTexPath) == AI_SUCCESS)
|
||||
if (!metalnessTextureFound)
|
||||
{
|
||||
// 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();
|
||||
PM_MESH_LOG(" No metalness map");
|
||||
|
||||
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 });
|
||||
}
|
||||
mi->Set("u_Metalness", metalness);
|
||||
mi->Set("u_MetalnessTexToggle", 0.0f);
|
||||
}
|
||||
|
||||
// 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();
|
||||
@@ -564,7 +503,6 @@ namespace Prism
|
||||
|
||||
auto ib = IndexBuffer::Create(m_Indices.data(), (uint32_t)m_Indices.size() * sizeof(Index));
|
||||
m_VertexArray->SetIndexBuffer(ib);
|
||||
m_Scene = scene;
|
||||
}
|
||||
|
||||
Mesh::~Mesh() = default;
|
||||
@@ -591,37 +529,37 @@ namespace Prism
|
||||
void Mesh::DumpVertexBuffer()
|
||||
{
|
||||
// TODO: Convert to ImGui
|
||||
PM_CORE_TRACE("------------------------------------------------------");
|
||||
PM_CORE_TRACE("Vertex Buffer Dump");
|
||||
PM_CORE_TRACE("Mesh: {0}", m_FilePath);
|
||||
PM_MESH_LOG("------------------------------------------------------");
|
||||
PM_MESH_LOG("Vertex Buffer Dump");
|
||||
PM_MESH_LOG("Mesh: {0}", m_FilePath);
|
||||
if (m_IsAnimated)
|
||||
{
|
||||
for (size_t i = 0; i < m_AnimatedVertices.size(); i++)
|
||||
{
|
||||
auto& vertex = m_AnimatedVertices[i];
|
||||
PM_CORE_TRACE("Vertex: {0}", i);
|
||||
PM_CORE_TRACE("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_CORE_TRACE("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_CORE_TRACE("TexCoord: {0}, {1}", vertex.Texcoord.x, vertex.Texcoord.y);
|
||||
PM_CORE_TRACE("--");
|
||||
PM_MESH_LOG("Vertex: {0}", i);
|
||||
PM_MESH_LOG("Position: {0}, {1}, {2}", vertex.Position.x, vertex.Position.y, vertex.Position.z);
|
||||
PM_MESH_LOG("Normal: {0}, {1}, {2}", vertex.Normal.x, vertex.Normal.y, vertex.Normal.z);
|
||||
PM_MESH_LOG("Binormal: {0}, {1}, {2}", vertex.Binormal.x, vertex.Binormal.y, vertex.Binormal.z);
|
||||
PM_MESH_LOG("Tangent: {0}, {1}, {2}", vertex.Tangent.x, vertex.Tangent.y, vertex.Tangent.z);
|
||||
PM_MESH_LOG("TexCoord: {0}, {1}", vertex.Texcoord.x, vertex.Texcoord.y);
|
||||
PM_MESH_LOG("--");
|
||||
}
|
||||
}else
|
||||
{
|
||||
for (size_t i = 0; i < m_StaticVertices.size(); i++)
|
||||
{
|
||||
auto& vertex = m_StaticVertices[i];
|
||||
PM_CORE_TRACE("Vertex: {0}", i);
|
||||
PM_CORE_TRACE("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_CORE_TRACE("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_CORE_TRACE("TexCoord: {0}, {1}", vertex.Texcoord.x, vertex.Texcoord.y);
|
||||
PM_CORE_TRACE("--");
|
||||
PM_MESH_LOG("Vertex: {0}", i);
|
||||
PM_MESH_LOG("Position: {0}, {1}, {2}", vertex.Position.x, vertex.Position.y, vertex.Position.z);
|
||||
PM_MESH_LOG("Normal: {0}, {1}, {2}", vertex.Normal.x, vertex.Normal.y, vertex.Normal.z);
|
||||
PM_MESH_LOG("Binormal: {0}, {1}, {2}", vertex.Binormal.x, vertex.Binormal.y, vertex.Binormal.z);
|
||||
PM_MESH_LOG("Tangent: {0}, {1}, {2}", vertex.Tangent.x, vertex.Tangent.y, vertex.Tangent.z);
|
||||
PM_MESH_LOG("TexCoord: {0}, {1}", vertex.Texcoord.x, vertex.Texcoord.y);
|
||||
PM_MESH_LOG("--");
|
||||
}
|
||||
}
|
||||
PM_CORE_TRACE("------------------------------------------------------");
|
||||
PM_MESH_LOG("------------------------------------------------------");
|
||||
}
|
||||
|
||||
void Mesh::BoneTransform(float time)
|
||||
@@ -679,7 +617,9 @@ namespace Prism
|
||||
for (uint32_t i = 0; i < node->mNumMeshes; 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++)
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "Buffer.h"
|
||||
#include "Material.h"
|
||||
#include "Shader.h"
|
||||
#include "VertexArray.h"
|
||||
#include "Prism/Core/TimeStep.h"
|
||||
#include "Prism/Core/Math/AABB.h"
|
||||
|
||||
struct aiNode;
|
||||
struct aiAnimation;
|
||||
@@ -78,6 +78,14 @@ namespace Prism
|
||||
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
|
||||
{
|
||||
public:
|
||||
@@ -87,7 +95,9 @@ namespace Prism
|
||||
uint32_t IndexCount;
|
||||
|
||||
glm::mat4 Transform;
|
||||
glm::vec3 Min, Max; //TODO: AABB
|
||||
AABB BoundingBox;
|
||||
|
||||
std::string NodeName, MeshName;
|
||||
};
|
||||
|
||||
class PRISM_API Mesh
|
||||
@@ -101,11 +111,16 @@ namespace Prism
|
||||
void OnUpdate(TimeStep deltaTime);
|
||||
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<Material> GetMaterial() { return m_BaseMaterial; }
|
||||
std::vector<Ref<MaterialInstance>> GetMaterials() { return m_Materials; }
|
||||
const std::vector<Ref<Texture2D>>& GetTextures() const { return m_Textures; }
|
||||
const std::string& GetFilePath() const { return m_FilePath; }
|
||||
|
||||
const std::vector<Triangle> GetTriangleCache(uint32_t index) const { return m_TriangleCache.at(index); }
|
||||
private:
|
||||
void BoneTransform(float time);
|
||||
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<MaterialInstance>> m_Materials;
|
||||
|
||||
std::unordered_map<uint32_t, std::vector<Triangle>> m_TriangleCache;
|
||||
|
||||
// Animation
|
||||
bool m_IsAnimated = false;
|
||||
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 glm::vec4 corners[8] =
|
||||
{
|
||||
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);
|
||||
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] =
|
||||
{
|
||||
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()
|
||||
{
|
||||
return s_Data.m_CommandQueue;
|
||||
|
||||
@@ -56,7 +56,8 @@ namespace Prism
|
||||
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 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:
|
||||
static RenderCommandQueue& GetRenderCommandQueue();
|
||||
};
|
||||
|
||||
@@ -194,7 +194,7 @@ namespace Prism
|
||||
s_Data.LineShader->SetMat4("u_ViewProjection", s_Data.CameraViewProj);
|
||||
|
||||
s_Data.LineVertexArray->Bind();
|
||||
Renderer::SetLineThickness(2.0f);
|
||||
Renderer::SetLineThickness(1.0f);
|
||||
Renderer::DrawIndexed(s_Data.LineIndexCount, PrimitiveType::Lines, s_Data.DepthTest);
|
||||
s_Data.Stats.DrawCalls++;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ namespace Prism
|
||||
// Resources
|
||||
Ref<MaterialInstance> SkyboxMaterial;
|
||||
Environment SceneEnvironment;
|
||||
Light ActiveLight;
|
||||
} SceneData;
|
||||
|
||||
Ref<Texture2D> BRDFLUT;
|
||||
@@ -101,6 +102,7 @@ namespace Prism
|
||||
s_Data.SceneData.SceneCamera = scene->m_Camera;
|
||||
s_Data.SceneData.SkyboxMaterial = scene->m_SkyboxMaterial;
|
||||
s_Data.SceneData.SceneEnvironment = scene->m_Environment;
|
||||
s_Data.SceneData.ActiveLight = scene->m_Light;
|
||||
}
|
||||
|
||||
void SceneRenderer::EndScene()
|
||||
@@ -128,8 +130,8 @@ namespace Prism
|
||||
|
||||
std::pair<Ref<TextureCube>, Ref<TextureCube>> SceneRenderer::CreateEnvironmentMap(const std::string& filepath)
|
||||
{
|
||||
const uint32_t cubemapSize = 2048;
|
||||
const uint32_t irradianceMapSize = 32;
|
||||
constexpr uint32_t cubemapSize = 2048;
|
||||
constexpr uint32_t irradianceMapSize = 32;
|
||||
|
||||
Ref<TextureCube> envUnfiltered = TextureCube::Create(TextureFormat::Float16, cubemapSize, cubemapSize);
|
||||
if (!equirectangularConversionShader)
|
||||
@@ -245,6 +247,9 @@ namespace Prism
|
||||
baseMaterial->Set("u_EnvIrradianceTex", s_Data.SceneData.SceneEnvironment.IrradianceMap);
|
||||
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;
|
||||
Renderer::SubmitMesh(dc.mesh, dc.Transform, overrideMaterial);
|
||||
}
|
||||
@@ -261,7 +266,7 @@ namespace Prism
|
||||
{
|
||||
Renderer2D::BeginScene(viewProjection);
|
||||
for (auto& dc : s_Data.DrawList)
|
||||
Renderer::DrawAABB(dc.mesh);
|
||||
Renderer::DrawAABB(dc.mesh, dc.Transform);
|
||||
Renderer2D::EndScene();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,14 @@ namespace Prism
|
||||
static Environment Load(const std::string& filepath);
|
||||
};
|
||||
|
||||
struct Light
|
||||
{
|
||||
glm::vec3 Direction;
|
||||
glm::vec3 Radiance;
|
||||
|
||||
float Multiplier = 1.0f;
|
||||
};
|
||||
|
||||
class PRISM_API Scene{
|
||||
public:
|
||||
Scene(const std::string& debugName = "Scene");
|
||||
@@ -37,6 +45,7 @@ namespace Prism
|
||||
void SetEnvironment(const Environment& environment);
|
||||
void SetSkybox(const Ref<TextureCube>& skybox);
|
||||
|
||||
Light& GetLight() { return m_Light; }
|
||||
float& GetSkyboxLod() { return m_SkyboxLod; }
|
||||
|
||||
void AddEntity(Entity* entity);
|
||||
@@ -47,12 +56,16 @@ namespace Prism
|
||||
std::vector<Entity*> m_Entities;
|
||||
Camera m_Camera;
|
||||
|
||||
Light m_Light;
|
||||
float m_LightMultiplier = 0.3f;
|
||||
|
||||
Environment m_Environment;
|
||||
Ref<TextureCube> m_SkyboxTexture;
|
||||
Ref<MaterialInstance> m_SkyboxMaterial;
|
||||
|
||||
float m_SkyboxLod = 1.0f;
|
||||
|
||||
private:
|
||||
friend class SceneRenderer;
|
||||
friend class SceneHierarchyPanel;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user