add mouse picking, add more hdr environment maps
This commit is contained in:
@ -149,7 +149,7 @@ namespace Prism
|
||||
|
||||
auto secondEntity = m_Scene->CreateEntity("Gun Entity");
|
||||
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 };
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
Editor/assets/env/pink_sunrise_4k.hdr
vendored
Normal file
BIN
Editor/assets/env/pink_sunrise_4k.hdr
vendored
Normal file
Binary file not shown.
BIN
Editor/assets/env/rooitou_park_4k.hdr
vendored
Normal file
BIN
Editor/assets/env/rooitou_park_4k.hdr
vendored
Normal file
Binary file not shown.
BIN
Editor/assets/env/venice_dawn_1_4k.hdr
vendored
Normal file
BIN
Editor/assets/env/venice_dawn_1_4k.hdr
vendored
Normal file
Binary file not shown.
BIN
Editor/assets/meshes/TestScene.blend
Normal file
BIN
Editor/assets/meshes/TestScene.blend
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -46,7 +46,7 @@ void main()
|
||||
vec4 localPosition = boneTransform * vec4(a_Position, 1.0);
|
||||
|
||||
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
|
||||
|
||||
25
Prism/src/Prism/Core/Math/AABB.h
Normal file
25
Prism/src/Prism/Core/Math/AABB.h
Normal file
@ -0,0 +1,25 @@
|
||||
//
|
||||
// Created by sfd on 25-12-2.
|
||||
//
|
||||
|
||||
#ifndef PRISM_AABB_H
|
||||
#define PRISM_AABB_H
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
struct AABB
|
||||
{
|
||||
glm::vec3 Min, Max;
|
||||
|
||||
AABB()
|
||||
: Min(0.0f), Max(0.0f) {}
|
||||
|
||||
AABB(const glm::vec3& min, const glm::vec3& max)
|
||||
: Min(min), Max(max) {}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif //PRISM_AABB_H
|
||||
76
Prism/src/Prism/Core/Math/Ray.h
Normal file
76
Prism/src/Prism/Core/Math/Ray.h
Normal file
@ -0,0 +1,76 @@
|
||||
//
|
||||
// Created by sfd on 25-12-2.
|
||||
//
|
||||
|
||||
#ifndef RAY_H
|
||||
#define RAY_H
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "AABB.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
struct PRISM_API Ray
|
||||
{
|
||||
glm::vec3 Origin, Direction;
|
||||
|
||||
bool IntersectsAABB(const AABB& aabb, float& t) const
|
||||
{
|
||||
glm::vec3 dirfrac;
|
||||
// r.dir is unit direction vector of ray
|
||||
dirfrac.x = 1.0f / Direction.x;
|
||||
dirfrac.y = 1.0f / Direction.y;
|
||||
dirfrac.z = 1.0f / Direction.z;
|
||||
// lb is the corner of AABB with minimal coordinates - left bottom, rt is maximal corner
|
||||
// r.org is origin of ray
|
||||
const glm::vec3& lb = aabb.Min;
|
||||
const glm::vec3& rt = aabb.Max;
|
||||
const float t1 = (lb.x - Origin.x) * dirfrac.x;
|
||||
const float t2 = (rt.x - Origin.x) * dirfrac.x;
|
||||
const float t3 = (lb.y - Origin.y) * dirfrac.y;
|
||||
const float t4 = (rt.y - Origin.y) * dirfrac.y;
|
||||
const float t5 = (lb.z - Origin.z) * dirfrac.z;
|
||||
const float t6 = (rt.z - Origin.z) * dirfrac.z;
|
||||
|
||||
const float tmin = glm::max(glm::max(glm::min(t1, t2), glm::min(t3, t4)), glm::min(t5, t6));
|
||||
const float tmax = glm::min(glm::min(glm::max(t1, t2), glm::max(t3, t4)), glm::max(t5, t6));
|
||||
|
||||
// if tmax < 0, ray (line) is intersecting AABB, but the whole AABB is behind us
|
||||
if (tmax < 0)
|
||||
{
|
||||
t = tmax;
|
||||
return false;
|
||||
}
|
||||
|
||||
// if tmin > tmax, ray doesn't intersect AABB
|
||||
if (tmin > tmax)
|
||||
{
|
||||
t = tmax;
|
||||
return false;
|
||||
}
|
||||
|
||||
t = tmin;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IntersectsTriangle(const glm::vec3& A, const glm::vec3& B, const glm::vec3& C, float& t) const
|
||||
{
|
||||
const glm::vec3 E1 = B - A;
|
||||
const glm::vec3 E2 = C - A;
|
||||
const glm::vec3 N = cross(E1, E2);
|
||||
const float det = -glm::dot(Direction, N);
|
||||
const float invdet = 1.0f / det;
|
||||
const glm::vec3 AO = Origin - A;
|
||||
const glm::vec3 DAO = glm::cross(AO, Direction);
|
||||
const float u = glm::dot(E2, DAO) * invdet;
|
||||
const float v = -glm::dot(E1, DAO) * invdet;
|
||||
t = glm::dot(AO, N) * invdet;
|
||||
return (det >= 1e-6 && t >= 0.0 && u >= 0.0 && v >= 0.0 && (u + v) <= 1.0);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //RAY_H
|
||||
@ -36,8 +36,9 @@ namespace Prism
|
||||
|
||||
virtual void OnUpdate() = 0;
|
||||
virtual void 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;
|
||||
|
||||
|
||||
@ -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