add MSAA, renderer2D, boundingbox
This commit is contained in:
@ -4,6 +4,8 @@
|
||||
|
||||
#include "EditorLayer.h"
|
||||
#include "ImGuizmo.h"
|
||||
#include "Prism/Core/Input.h"
|
||||
#include "Prism/Renderer/Renderer2D.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
@ -12,16 +14,18 @@ namespace Prism
|
||||
None = 0, ColorProperty = 1
|
||||
};
|
||||
|
||||
void Property(const std::string& name, bool& value)
|
||||
bool Property(const std::string& name, bool& value)
|
||||
{
|
||||
ImGui::Text(name.c_str());
|
||||
ImGui::NextColumn();
|
||||
ImGui::PushItemWidth(-1);
|
||||
std::string id = "##" + name;
|
||||
ImGui::Checkbox(id.c_str(), &value);
|
||||
const std::string id = "##" + name;
|
||||
const bool result = ImGui::Checkbox(id.c_str(), &value);
|
||||
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::NextColumn();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Property(const std::string& name, float& value, float min = -1.0f, float max = 1.0f,
|
||||
@ -137,14 +141,16 @@ namespace Prism
|
||||
|
||||
m_Scene->SetEnvironment(environment);
|
||||
|
||||
m_MeshEntity = m_Scene->CreateEntity();
|
||||
|
||||
const auto mesh = CreateRef<Mesh>("assets/models/m1911/m1911.fbx");
|
||||
//auto mesh = CreateRef<Mesh>("assets/meshes/cerberus/CerberusMaterials.fbx");
|
||||
// auto mesh = CreateRef<Mesh>("assets/models/m1911/M1911Materials.fbx");
|
||||
m_MeshEntity = m_Scene->CreateEntity("test Entity");
|
||||
auto mesh = CreateRef<Mesh>("assets/meshes/TestScene.fbx");
|
||||
m_MeshEntity->SetMesh(mesh);
|
||||
|
||||
m_MeshMaterial = mesh->GetMaterial();
|
||||
|
||||
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");
|
||||
secondEntity->SetMesh(mesh);
|
||||
}
|
||||
|
||||
// Sphere Scene
|
||||
@ -213,43 +219,55 @@ namespace Prism
|
||||
|
||||
void EditorLayer::OnUpdate(const TimeStep deltaTime)
|
||||
{
|
||||
// THINGS TO LOOK AT:
|
||||
// - BRDF LUT
|
||||
// - Tonemapping and proper HDR pipeline
|
||||
using namespace Prism;
|
||||
using namespace glm;
|
||||
|
||||
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);
|
||||
m_MeshMaterial->Set("u_RoughnessTexToggle", m_RoughnessInput.UseTexture ? 1.0f : 0.0f);
|
||||
m_MeshMaterial->Set("u_EnvMapRotation", m_EnvMapRotation);
|
||||
|
||||
m_SphereBaseMaterial->Set("u_AlbedoColor", m_AlbedoInput.Color);
|
||||
m_SphereBaseMaterial->Set("lights", m_Light);
|
||||
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);
|
||||
m_SphereBaseMaterial->Set("u_MetalnessTexToggle", m_MetalnessInput.UseTexture ? 1.0f : 0.0f);
|
||||
m_SphereBaseMaterial->Set("u_RoughnessTexToggle", m_RoughnessInput.UseTexture ? 1.0f : 0.0f);
|
||||
m_SphereBaseMaterial->Set("u_EnvMapRotation", m_EnvMapRotation);
|
||||
|
||||
|
||||
if (m_AlbedoInput.TextureMap)
|
||||
m_MeshMaterial->Set("u_AlbedoTexture", m_AlbedoInput.TextureMap);
|
||||
if (m_NormalInput.TextureMap)
|
||||
m_MeshMaterial->Set("u_NormalTexture", m_NormalInput.TextureMap);
|
||||
if (m_MetalnessInput.TextureMap)
|
||||
m_MeshMaterial->Set("u_MetalnessTexture", m_MetalnessInput.TextureMap);
|
||||
if (m_RoughnessInput.TextureMap)
|
||||
m_MeshMaterial->Set("u_RoughnessTexture", m_RoughnessInput.TextureMap);
|
||||
|
||||
if (m_AllowViewportCameraEvents)
|
||||
m_Scene->GetCamera().OnUpdate(deltaTime);
|
||||
|
||||
m_ActiveScene->OnUpdate(deltaTime);
|
||||
|
||||
if (m_DrawOnTopBoundingBoxes)
|
||||
{
|
||||
// THINGS TO LOOK AT:
|
||||
// - BRDF LUT
|
||||
// - Tonemapping and proper HDR pipeline
|
||||
using namespace Prism;
|
||||
using namespace glm;
|
||||
|
||||
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);
|
||||
m_MeshMaterial->Set("u_RoughnessTexToggle", m_RoughnessInput.UseTexture ? 1.0f : 0.0f);
|
||||
m_MeshMaterial->Set("u_EnvMapRotation", m_EnvMapRotation);
|
||||
|
||||
m_SphereBaseMaterial->Set("u_AlbedoColor", m_AlbedoInput.Color);
|
||||
m_SphereBaseMaterial->Set("lights", m_Light);
|
||||
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);
|
||||
m_SphereBaseMaterial->Set("u_MetalnessTexToggle", m_MetalnessInput.UseTexture ? 1.0f : 0.0f);
|
||||
m_SphereBaseMaterial->Set("u_RoughnessTexToggle", m_RoughnessInput.UseTexture ? 1.0f : 0.0f);
|
||||
m_SphereBaseMaterial->Set("u_EnvMapRotation", m_EnvMapRotation);
|
||||
|
||||
|
||||
if (m_AlbedoInput.TextureMap)
|
||||
m_MeshMaterial->Set("u_AlbedoTexture", m_AlbedoInput.TextureMap);
|
||||
if (m_NormalInput.TextureMap)
|
||||
m_MeshMaterial->Set("u_NormalTexture", m_NormalInput.TextureMap);
|
||||
if (m_MetalnessInput.TextureMap)
|
||||
m_MeshMaterial->Set("u_MetalnessTexture", m_MetalnessInput.TextureMap);
|
||||
if (m_RoughnessInput.TextureMap)
|
||||
m_MeshMaterial->Set("u_RoughnessTexture", m_RoughnessInput.TextureMap);
|
||||
|
||||
m_ActiveScene->OnUpdate(deltaTime);
|
||||
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());
|
||||
Renderer2D::EndScene();
|
||||
Renderer::EndRenderPass();
|
||||
}
|
||||
}
|
||||
|
||||
@ -431,6 +449,11 @@ namespace Prism
|
||||
Property("Radiance Prefiltering", m_RadiancePrefilter);
|
||||
Property("Env Map Rotation", m_EnvMapRotation, -360.0f, 360.0f);
|
||||
|
||||
if (Property("Show Bounding Boxes", m_UIShowBoundingBoxes))
|
||||
ShowBoundingBoxes(m_UIShowBoundingBoxes, m_UIShowBoundingBoxesOnTop);
|
||||
if (m_UIShowBoundingBoxes && Property("On Top", m_UIShowBoundingBoxesOnTop))
|
||||
ShowBoundingBoxes(m_UIShowBoundingBoxes, m_UIShowBoundingBoxesOnTop);
|
||||
|
||||
ImGui::Columns(1);
|
||||
|
||||
ImGui::End();
|
||||
@ -620,12 +643,17 @@ namespace Prism
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
|
||||
ImGui::Begin("Viewport");
|
||||
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));
|
||||
m_ActiveScene->GetCamera().SetViewportSize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
|
||||
ImGui::Image((ImTextureRef)SceneRenderer::GetFinalColorBufferRendererID(), viewportSize, { 0, 1 }, { 1, 0 });
|
||||
|
||||
|
||||
auto windowSize = ImGui::GetWindowSize();
|
||||
ImVec2 minBound = ImGui::GetWindowPos();
|
||||
ImVec2 maxBound = { minBound.x + windowSize.x, minBound.y + windowSize.y };
|
||||
m_AllowViewportCameraEvents = ImGui::IsMouseHoveringRect(minBound, maxBound);
|
||||
|
||||
// ImGuizmo
|
||||
if (m_GizmoType != -1)
|
||||
{
|
||||
@ -645,8 +673,11 @@ namespace Prism
|
||||
|
||||
void EditorLayer::OnEvent(Event& e)
|
||||
{
|
||||
if (m_AllowViewportCameraEvents)
|
||||
m_Scene->GetCamera().OnEvent(e);
|
||||
|
||||
EventDispatcher dispatcher(e);
|
||||
dispatcher.Dispatch<KeyPressedEvent>(HZ_BIND_EVENT_FN(EditorLayer::OnKeyPressedEvent));
|
||||
dispatcher.Dispatch<KeyPressedEvent>(PM_BIND_EVENT_FN(EditorLayer::OnKeyPressedEvent));
|
||||
}
|
||||
|
||||
bool EditorLayer::OnKeyPressedEvent(KeyPressedEvent& e)
|
||||
@ -665,7 +696,27 @@ namespace Prism
|
||||
case PM_KEY_R:
|
||||
m_GizmoType = ImGuizmo::OPERATION::SCALE;
|
||||
break;
|
||||
case PM_KEY_G:
|
||||
// Toggle grid
|
||||
if (Input::IsKeyPressed(PM_KEY_LEFT_CONTROL))
|
||||
SceneRenderer::GetOptions().ShowGrid = !SceneRenderer::GetOptions().ShowGrid;
|
||||
break;
|
||||
case PM_KEY_B:
|
||||
// Toggle bounding boxes
|
||||
if (Input::IsKeyPressed(PM_KEY_LEFT_CONTROL))
|
||||
{
|
||||
m_UIShowBoundingBoxes = !m_UIShowBoundingBoxes;
|
||||
ShowBoundingBoxes(m_UIShowBoundingBoxes, m_UIShowBoundingBoxesOnTop);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void EditorLayer::ShowBoundingBoxes(bool show, bool onTop)
|
||||
{
|
||||
SceneRenderer::GetOptions().ShowBoundingBoxes = show && !onTop;
|
||||
m_DrawOnTopBoundingBoxes = show && onTop;
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,6 +25,8 @@ namespace Prism
|
||||
private:
|
||||
bool OnKeyPressedEvent(KeyPressedEvent& e);
|
||||
|
||||
void ShowBoundingBoxes(bool show, bool onTop = false);
|
||||
|
||||
private:
|
||||
Scope<SceneHierarchyPanel> m_SceneHierarchyPanel;
|
||||
|
||||
@ -54,6 +56,13 @@ namespace Prism
|
||||
// Imguizmo
|
||||
int m_GizmoType = -1; // -1 = no gizmo
|
||||
|
||||
// configure button
|
||||
bool m_AllowViewportCameraEvents = false;
|
||||
bool m_DrawOnTopBoundingBoxes = false;
|
||||
|
||||
bool m_UIShowBoundingBoxes = false;
|
||||
bool m_UIShowBoundingBoxesOnTop = false;
|
||||
|
||||
|
||||
struct AlbedoInput
|
||||
{
|
||||
|
||||
BIN
Editor/assets/meshes/TestScene.fbx
Normal file
BIN
Editor/assets/meshes/TestScene.fbx
Normal file
Binary file not shown.
@ -34,7 +34,7 @@ out VertexOutput
|
||||
void main()
|
||||
{
|
||||
vs_Output.WorldPosition = vec3(u_Transform * vec4(a_Position, 1.0));
|
||||
vs_Output.Normal = a_Normal;
|
||||
vs_Output.Normal = mat3(u_Transform) * 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.WorldTransform = mat3(u_Transform);
|
||||
@ -271,7 +271,8 @@ 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 = fresnelSchlickRoughness(F0, m_Params.NdotV, m_Params.Roughness);
|
||||
vec3 F = fresnelSchlick(F0, m_Params.NdotV);
|
||||
vec3 kd = (1.0 - F) * (1.0 - m_Params.Metalness);
|
||||
vec3 diffuseIBL = m_Params.Albedo * irradiance;
|
||||
|
||||
@ -316,4 +317,5 @@ void main()
|
||||
vec3 iblContribution = IBL(F0, Lr);
|
||||
|
||||
color = vec4(lightContribution + iblContribution, 1.0);
|
||||
color = vec4(iblContribution, 1.0);
|
||||
}
|
||||
|
||||
43
Editor/assets/shaders/Renderer2D.glsl
Normal file
43
Editor/assets/shaders/Renderer2D.glsl
Normal file
@ -0,0 +1,43 @@
|
||||
// Basic Texture Shader
|
||||
|
||||
#type vertex
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec3 a_Position;
|
||||
layout(location = 1) in vec4 a_Color;
|
||||
layout(location = 2) in vec2 a_TexCoord;
|
||||
layout(location = 3) in float a_TexIndex;
|
||||
layout(location = 4) in float a_TilingFactor;
|
||||
|
||||
uniform mat4 u_ViewProjection;
|
||||
|
||||
out vec4 v_Color;
|
||||
out vec2 v_TexCoord;
|
||||
out float v_TexIndex;
|
||||
out float v_TilingFactor;
|
||||
|
||||
void main()
|
||||
{
|
||||
v_Color = a_Color;
|
||||
v_TexCoord = a_TexCoord;
|
||||
v_TexIndex = a_TexIndex;
|
||||
v_TilingFactor = a_TilingFactor;
|
||||
gl_Position = u_ViewProjection * vec4(a_Position, 1.0);
|
||||
}
|
||||
|
||||
#type fragment
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) out vec4 color;
|
||||
|
||||
in vec4 v_Color;
|
||||
in vec2 v_TexCoord;
|
||||
in float v_TexIndex;
|
||||
in float v_TilingFactor;
|
||||
|
||||
uniform sampler2D u_Textures[32];
|
||||
|
||||
void main()
|
||||
{
|
||||
color = texture(u_Textures[int(v_TexIndex)], v_TexCoord * v_TilingFactor) * v_Color;
|
||||
}
|
||||
29
Editor/assets/shaders/Renderer2D_Line.glsl
Normal file
29
Editor/assets/shaders/Renderer2D_Line.glsl
Normal file
@ -0,0 +1,29 @@
|
||||
// Basic Texture Shader
|
||||
|
||||
#type vertex
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec3 a_Position;
|
||||
layout(location = 1) in vec4 a_Color;
|
||||
|
||||
uniform mat4 u_ViewProjection;
|
||||
|
||||
out vec4 v_Color;
|
||||
|
||||
void main()
|
||||
{
|
||||
v_Color = a_Color;
|
||||
gl_Position = u_ViewProjection * vec4(a_Position, 1.0);
|
||||
}
|
||||
|
||||
#type fragment
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) out vec4 color;
|
||||
|
||||
in vec4 v_Color;
|
||||
|
||||
void main()
|
||||
{
|
||||
color = v_Color;
|
||||
}
|
||||
@ -16,20 +16,34 @@ void main()
|
||||
#type fragment
|
||||
#version 430
|
||||
|
||||
layout(location = 0) out vec4 o_Color;
|
||||
|
||||
in vec2 v_TexCoord;
|
||||
|
||||
uniform sampler2D u_Texture;
|
||||
|
||||
layout(location=0) out vec4 outColor;
|
||||
|
||||
uniform sampler2DMS u_Texture;
|
||||
uniform float u_Exposure;
|
||||
uniform int u_TextureSamples;
|
||||
|
||||
vec4 MultiSampleTexture(sampler2DMS tex, ivec2 texCoord, int samples)
|
||||
{
|
||||
vec4 result = vec4(0.0);
|
||||
for (int i = 0; i < samples; i++)
|
||||
result += texelFetch(tex, texCoord, i);
|
||||
|
||||
result /= float(samples);
|
||||
return result;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
const float gamma = 2.2;
|
||||
const float pureWhite = 1.0;
|
||||
|
||||
vec3 color = texture(u_Texture, v_TexCoord).rgb * u_Exposure;
|
||||
ivec2 texSize = textureSize(u_Texture);
|
||||
ivec2 texCoord = ivec2(v_TexCoord * texSize);
|
||||
vec4 msColor = MultiSampleTexture(u_Texture, texCoord, u_TextureSamples);
|
||||
vec3 color = msColor.rgb * u_Exposure;//texture(u_Texture, v_TexCoord).rgb * u_Exposure;
|
||||
|
||||
// Reinhard tonemapping operator.
|
||||
// see: "Photographic Tone Reproduction for Digital Images", eq. 4
|
||||
float luminance = dot(color, vec3(0.2126, 0.7152, 0.0722));
|
||||
@ -39,5 +53,5 @@ void main()
|
||||
vec3 mappedColor = (mappedLuminance / luminance) * color;
|
||||
|
||||
// Gamma correction.
|
||||
outColor = vec4(pow(mappedColor, vec3(1.0/gamma)), 1.0);
|
||||
o_Color = vec4(pow(mappedColor, vec3(1.0 / gamma)), 1.0);
|
||||
}
|
||||
@ -83,6 +83,7 @@ set(STATIC_LIBRARY ${PROJECT_NAME}-static)
|
||||
add_library(${STATIC_LIBRARY} STATIC ${SRC_SOURCE})
|
||||
|
||||
target_compile_definitions(${STATIC_LIBRARY} PRIVATE
|
||||
PUBLIC
|
||||
${DEBUG_DEFINITIONS}
|
||||
INTERFACE
|
||||
PRISM_STATIC
|
||||
|
||||
@ -69,9 +69,9 @@ namespace Prism
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define HZ_BIND_EVENT_FN(fn) std::bind(&##fn, this, std::placeholders::_1)
|
||||
#define PM_BIND_EVENT_FN(fn) std::bind(&##fn, this, std::placeholders::_1)
|
||||
#else
|
||||
#define HZ_BIND_EVENT_FN(fn) std::bind(&fn, this, std::placeholders::_1)
|
||||
#define PM_BIND_EVENT_FN(fn) std::bind(&fn, this, std::placeholders::_1)
|
||||
#endif
|
||||
|
||||
#endif //APPLICATION_H
|
||||
|
||||
@ -50,7 +50,7 @@ namespace Prism
|
||||
memset(Data, 0, Size);
|
||||
}
|
||||
|
||||
void Write(const byte* data, const uint32_t size, const uint32_t offset = 0) const
|
||||
void Write(const void* data, const uint32_t size, const uint32_t offset = 0) const
|
||||
{
|
||||
PM_CORE_ASSERT(offset + size <= Size, "Buffer overflow!");
|
||||
memcpy(Data + offset, data, size);
|
||||
|
||||
@ -29,18 +29,11 @@ namespace Prism
|
||||
{
|
||||
ImGui::Begin("Scene Hierarchy");
|
||||
|
||||
uint32_t entityCount = 0, meshCount = 0;
|
||||
auto& sceneEntities = m_Context->m_Entities;
|
||||
for (Entity* entity : sceneEntities)
|
||||
for (const auto& entity : sceneEntities)
|
||||
{
|
||||
auto mesh = entity->GetMesh();
|
||||
auto material = entity->GetMaterial();
|
||||
const auto& transform = entity->GetTransform();
|
||||
|
||||
if (mesh)
|
||||
{
|
||||
DrawMeshNode(mesh);
|
||||
}
|
||||
|
||||
DrawEntityNode(entity, entityCount, meshCount);
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
@ -89,7 +82,26 @@ namespace Prism
|
||||
|
||||
}
|
||||
|
||||
static std::tuple<glm::vec3, glm::quat, glm::vec3> GetTransformDecomposition(const glm::mat4& transform)
|
||||
void SceneHierarchyPanel::DrawEntityNode(Entity* entity, uint32_t& imguiEntityID, uint32_t& imguiMeshID)
|
||||
{
|
||||
const char* name = entity->GetName().c_str();
|
||||
static char imguiName[128];
|
||||
memset(imguiName, 0, 128);
|
||||
sprintf(imguiName, "%s##%d", name, imguiEntityID++);
|
||||
if (ImGui::TreeNode(imguiName))
|
||||
{
|
||||
auto mesh = entity->GetMesh();
|
||||
auto material = entity->GetMaterial();
|
||||
const auto& transform = entity->GetTransform();
|
||||
|
||||
if (mesh)
|
||||
DrawMeshNode(mesh, imguiMeshID);
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
static std::tuple<glm::vec3, glm::quat, glm::vec3> GetTransformDecomposition(const glm::mat4& transform)
|
||||
{
|
||||
glm::vec3 scale, translation, skew;
|
||||
glm::vec4 perspective;
|
||||
@ -99,13 +111,23 @@ namespace Prism
|
||||
return { translation, orientation, scale };
|
||||
}
|
||||
|
||||
void SceneHierarchyPanel::DrawMeshNode(const Ref<Mesh>& mesh)
|
||||
void SceneHierarchyPanel::DrawMeshNode(const Ref<Mesh>& mesh, uint32_t& imguiMeshID)
|
||||
{
|
||||
auto rootNode = mesh->m_Scene->mRootNode;
|
||||
MeshNodeHierarchy(mesh, rootNode);
|
||||
static char imguiName[128];
|
||||
memset(imguiName, 0, 128);
|
||||
sprintf(imguiName, "Mesh##%d", imguiMeshID++);
|
||||
|
||||
// Mesh Hierarchy
|
||||
if (ImGui::TreeNode(imguiName))
|
||||
{
|
||||
auto rootNode = mesh->m_Scene->mRootNode;
|
||||
MeshNodeHierarchy(mesh, rootNode);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SceneHierarchyPanel::MeshNodeHierarchy(const Ref<Mesh>& mesh, aiNode* node, const glm::mat4& parentTransform, uint32_t level)
|
||||
{
|
||||
glm::mat4 localTransform = Mat4FromAssimpMat4(node->mTransformation);
|
||||
|
||||
@ -18,7 +18,8 @@ namespace Prism
|
||||
|
||||
void OnImGuiRender();
|
||||
private:
|
||||
void DrawMeshNode(const Ref<Mesh>& mesh);
|
||||
void DrawEntityNode(Entity* entity, uint32_t& imguiEntityID, uint32_t& imguiMeshID);
|
||||
void DrawMeshNode(const Ref<Mesh>& mesh, uint32_t& imguiMeshID);
|
||||
void MeshNodeHierarchy(const Ref<Mesh>& mesh, aiNode* node, const glm::mat4& parentTransform = glm::mat4(1.0f), uint32_t level = 0);
|
||||
private:
|
||||
Ref<Scene> m_Context;
|
||||
|
||||
@ -26,7 +26,7 @@ namespace Prism
|
||||
|
||||
void OpenGLFrameBuffer::Bind() const
|
||||
{
|
||||
Renderer::Submit([this](){
|
||||
Renderer::Submit([=](){
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_RendererID);
|
||||
glViewport(0, 0, m_Specification.Width, m_Specification.Height);
|
||||
});
|
||||
@ -34,66 +34,116 @@ namespace Prism
|
||||
|
||||
void OpenGLFrameBuffer::Unbind() const
|
||||
{
|
||||
Renderer::Submit([this](){
|
||||
Renderer::Submit([=](){
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
});
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::Resize(const uint32_t width, const uint32_t height)
|
||||
{
|
||||
if (m_RendererID && m_Specification.Width == width && m_Specification.Height == height)
|
||||
return;
|
||||
if (m_Specification.Width == width && m_Specification.Height == height)
|
||||
return;
|
||||
|
||||
m_Specification.Width = width;
|
||||
m_Specification.Height = height;
|
||||
Renderer::Submit([this](){
|
||||
if (m_RendererID)
|
||||
{
|
||||
glDeleteFramebuffers(1, &m_RendererID);
|
||||
glDeleteTextures(1, &m_ColorAttachment);
|
||||
glDeleteTextures(1, &m_DepthAttachment);
|
||||
}
|
||||
m_Specification.Width = width;
|
||||
m_Specification.Height = height;
|
||||
Renderer::Submit([this]()
|
||||
{
|
||||
if (m_RendererID)
|
||||
{
|
||||
glDeleteFramebuffers(1, &m_RendererID);
|
||||
glDeleteTextures(1, &m_ColorAttachment);
|
||||
glDeleteTextures(1, &m_DepthAttachment);
|
||||
}
|
||||
|
||||
glGenFramebuffers(1, &m_RendererID);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_RendererID);
|
||||
glGenFramebuffers(1, &m_RendererID);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_RendererID);
|
||||
|
||||
glGenTextures(1, &m_ColorAttachment);
|
||||
glBindTexture(GL_TEXTURE_2D, m_ColorAttachment);
|
||||
bool multisample = m_Specification.Samples > 1;
|
||||
if (multisample)
|
||||
{
|
||||
glCreateTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &m_ColorAttachment);
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_ColorAttachment);
|
||||
|
||||
// TODO: Create Hazel texture object based on format here
|
||||
if (m_Specification.Format == FramebufferFormat::RGBA16F)
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, m_Specification.Width, m_Specification.Height, 0, GL_RGBA, GL_FLOAT, nullptr);
|
||||
}
|
||||
else if (m_Specification.Format == FramebufferFormat::RGBA8)
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_Specification.Width, m_Specification.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_ColorAttachment, 0);
|
||||
// TODO: Create Hazel texture object based on format here
|
||||
if (m_Specification.Format == FramebufferFormat::RGBA16F)
|
||||
{
|
||||
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, m_Specification.Samples, GL_RGBA16F, m_Specification.Width, m_Specification.Height, GL_FALSE);
|
||||
//glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, m_Specification.Samples, GL_RGBA16F, m_Specification.Width, m_Specification.Height, GL_FALSE);
|
||||
}
|
||||
else if (m_Specification.Format == FramebufferFormat::RGBA8)
|
||||
{
|
||||
// glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 8, GL_RGBA8, m_Specification.Width, m_Specification.Height, GL_TRUE);
|
||||
glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, m_Specification.Samples, GL_RGBA8, m_Specification.Width, m_Specification.Height, GL_FALSE);
|
||||
}
|
||||
// glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
// glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
// glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, m_ColorAttachment, 0);
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
glCreateTextures(GL_TEXTURE_2D, 1, &m_ColorAttachment);
|
||||
glBindTexture(GL_TEXTURE_2D, m_ColorAttachment);
|
||||
|
||||
glGenTextures(1, &m_DepthAttachment);
|
||||
glBindTexture(GL_TEXTURE_2D, m_DepthAttachment);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, m_Specification.Width, m_Specification.Height, 0,
|
||||
GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL
|
||||
);
|
||||
// TODO: Create Hazel texture object based on format here
|
||||
if (m_Specification.Format == FramebufferFormat::RGBA16F)
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, m_Specification.Width, m_Specification.Height, 0, GL_RGBA, GL_FLOAT, nullptr);
|
||||
}
|
||||
else if (m_Specification.Format == FramebufferFormat::RGBA8)
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_Specification.Width, m_Specification.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_ColorAttachment, 0);
|
||||
}
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_DepthAttachment, 0);
|
||||
if (multisample)
|
||||
{
|
||||
glCreateTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &m_DepthAttachment);
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_DepthAttachment);
|
||||
// glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 8, GL_DEPTH24_STENCIL8, m_Specification.Width, m_Specification.Height, GL_TRUE);
|
||||
glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, m_Specification.Samples, GL_DEPTH24_STENCIL8, m_Specification.Width, m_Specification.Height, GL_FALSE);
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
|
||||
// glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE, m_DepthAttachment, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
glCreateTextures(GL_TEXTURE_2D, 1, &m_DepthAttachment);
|
||||
glBindTexture(GL_TEXTURE_2D, m_DepthAttachment);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, m_Specification.Width, m_Specification.Height, 0,
|
||||
GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL
|
||||
);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_DepthAttachment, 0);
|
||||
}
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||
PM_CORE_ERROR("Framebuffer is incomplete!");
|
||||
// glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_ColorAttachment, 0);
|
||||
if (multisample)
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, m_ColorAttachment, 0);
|
||||
else
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_ColorAttachment, 0);
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, m_DepthAttachment, 0);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
});
|
||||
PM_CORE_ASSERT(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Framebuffer is incomplete!");
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
});
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::BindTexture(uint32_t slot) const
|
||||
void OpenGLFrameBuffer::BindTexture(const uint32_t slot) const
|
||||
{
|
||||
Renderer::Submit([this, slot](){
|
||||
Renderer::Submit([=](){
|
||||
glActiveTexture(GL_TEXTURE0 + slot);
|
||||
glBindTexture(GL_TEXTURE_2D, m_ColorAttachment);
|
||||
|
||||
if (m_Specification.Samples > 1) {
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_ColorAttachment);
|
||||
} else {
|
||||
glBindTexture(GL_TEXTURE_2D, m_ColorAttachment);
|
||||
}
|
||||
|
||||
// glBindTexture(GL_TEXTURE_2D, m_ColorAttachment);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,17 +12,6 @@ namespace Prism
|
||||
{
|
||||
static void OpenGLLogMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam)
|
||||
{
|
||||
/*
|
||||
if (severity != GL_DEBUG_SEVERITY_NOTIFICATION)
|
||||
{
|
||||
|
||||
PM_CORE_ERROR("{0}", message);
|
||||
PM_CORE_ASSERT(false, "");
|
||||
}else
|
||||
{
|
||||
PM_CORE_TRACE("{0}", message);
|
||||
}
|
||||
*/
|
||||
|
||||
if (severity == GL_DEBUG_SEVERITY_NOTIFICATION)
|
||||
{
|
||||
@ -81,11 +70,10 @@ namespace Prism
|
||||
switch (severity)
|
||||
{
|
||||
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_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, "OpenGL严重错误");
|
||||
PM_CORE_ASSERT(false, "ERROR");
|
||||
}
|
||||
break;
|
||||
|
||||
@ -134,6 +122,7 @@ namespace Prism
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
|
||||
auto& caps = GetCapabilities();
|
||||
|
||||
@ -143,6 +132,7 @@ namespace Prism
|
||||
|
||||
glGetIntegerv(GL_MAX_SAMPLES, &caps.MaxSamples);
|
||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &caps.MaxAnisotropy);
|
||||
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &caps.MaxTextureUnits);
|
||||
|
||||
|
||||
GLenum error = glGetError();
|
||||
@ -168,14 +158,30 @@ namespace Prism
|
||||
glClearColor(r, g, b, a);
|
||||
}
|
||||
|
||||
void RendererAPI::DrawIndexed(const unsigned int count, const bool depthTest)
|
||||
void RendererAPI::DrawIndexed(uint32_t count, PrimitiveType type, bool depthTest)
|
||||
{
|
||||
if (!depthTest)
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, nullptr);
|
||||
GLenum glPrimitiveType = 0;
|
||||
switch (type)
|
||||
{
|
||||
case PrimitiveType::Triangles:
|
||||
glPrimitiveType = GL_TRIANGLES;
|
||||
break;
|
||||
case PrimitiveType::Lines:
|
||||
glPrimitiveType = GL_LINES;
|
||||
break;
|
||||
}
|
||||
|
||||
glDrawElements(glPrimitiveType, count, GL_UNSIGNED_INT, nullptr);
|
||||
|
||||
if (!depthTest)
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
void RendererAPI::SetLineThickness(const float thickness)
|
||||
{
|
||||
glLineWidth(thickness);
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ namespace Prism
|
||||
if (!m_IsCompute)
|
||||
Parse();
|
||||
|
||||
Renderer::Submit([this](){
|
||||
Renderer::Submit([=](){
|
||||
auto &a = m_RendererID;
|
||||
if (m_RendererID)
|
||||
glDeleteProgram(m_RendererID);
|
||||
@ -125,6 +125,13 @@ namespace Prism
|
||||
});
|
||||
}
|
||||
|
||||
void OpenGLShader::SetInt(const std::string& name, int value)
|
||||
{
|
||||
Renderer::Submit([=]() {
|
||||
UploadUniformInt(name, value);
|
||||
});
|
||||
}
|
||||
|
||||
void OpenGLShader::SetMat4(const std::string& name, const glm::mat4& value)
|
||||
{
|
||||
Renderer::Submit([=]() {
|
||||
@ -132,6 +139,13 @@ namespace Prism
|
||||
});
|
||||
}
|
||||
|
||||
void OpenGLShader::SetIntArray(const std::string& name, int* values, uint32_t size)
|
||||
{
|
||||
Renderer::Submit([=]() {
|
||||
UploadUniformIntArray(name, values, size);
|
||||
});
|
||||
}
|
||||
|
||||
void OpenGLShader::SetVSMaterialUniformBuffer(Buffer buffer)
|
||||
{
|
||||
Renderer::Submit([this, buffer]() {
|
||||
@ -351,6 +365,7 @@ namespace Prism
|
||||
static bool IsTypeStringResource(const std::string& type)
|
||||
{
|
||||
if (type == "sampler2D") return true;
|
||||
if (type == "sampler2DMS") return true;
|
||||
if (type == "samplerCube") return true;
|
||||
if (type == "sampler2DShadow") return true;
|
||||
return false;
|
||||
@ -371,7 +386,7 @@ namespace Prism
|
||||
{
|
||||
int32_t result = glGetUniformLocation(m_RendererID, name.c_str());
|
||||
if (result == -1)
|
||||
PM_CORE_WARN("Could not find uniform '{0}' in shader", name);
|
||||
PM_CORE_WARN("Could not find uniform '{0}' in shader: {1}", name, m_Name);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -932,7 +947,7 @@ namespace Prism
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLShader::UploadUniformIntArray(const std::string& name, const int32_t* values, const int32_t count) const
|
||||
void OpenGLShader::UploadUniformIntArray(const std::string& name, const int32_t* values, const uint32_t count) const
|
||||
{
|
||||
int32_t location = GetUniformLocation(name);
|
||||
glUniform1iv(location, count, values);
|
||||
|
||||
@ -28,8 +28,11 @@ namespace Prism
|
||||
virtual void AddShaderReloadedCallback(const ShaderReloadedCallback& callback) override;
|
||||
|
||||
virtual void SetFloat(const std::string& name, float value) override;
|
||||
virtual void SetInt(const std::string& name, int value) override;
|
||||
virtual void SetMat4(const std::string& name, const glm::mat4& value) override;
|
||||
|
||||
virtual void SetIntArray(const std::string& name, int* values, uint32_t size) override;
|
||||
|
||||
virtual void SetVSMaterialUniformBuffer(Buffer buffer) override;
|
||||
virtual void SetPSMaterialUniformBuffer(Buffer buffer) override;
|
||||
|
||||
@ -81,7 +84,7 @@ namespace Prism
|
||||
void UploadUniformMat4Array(uint32_t location, const glm::mat4& values, uint32_t count);
|
||||
|
||||
void UploadUniformStruct(const OpenGLShaderUniformDeclaration* uniform, byte* buffer, uint32_t offset);
|
||||
void UploadUniformIntArray(const std::string& name, const int32_t* values, int32_t count) const;
|
||||
void UploadUniformIntArray(const std::string& name, const int32_t* values, uint32_t count) const;
|
||||
|
||||
virtual const ShaderUniformBufferList& GetVSRendererUniforms() const override { return m_VSRendererUniformBuffers; }
|
||||
virtual const ShaderUniformBufferList& GetPSRendererUniforms() const override { return m_PSRendererUniformBuffers; }
|
||||
|
||||
@ -48,6 +48,7 @@ namespace Prism
|
||||
|
||||
OpenGLShaderUniformDeclaration::Type OpenGLShaderUniformDeclaration::StringToType(const std::string& type)
|
||||
{
|
||||
if (type == "int") return Type::INT32;
|
||||
if (type == "int32") return Type::INT32;
|
||||
if (type == "float") return Type::FLOAT32;
|
||||
if (type == "vec2") return Type::VEC2;
|
||||
@ -112,6 +113,7 @@ namespace Prism
|
||||
OpenGLShaderResourceDeclaration::Type OpenGLShaderResourceDeclaration::StringToType(const std::string& type)
|
||||
{
|
||||
if (type == "sampler2D") return Type::TEXTURE2D;
|
||||
if (type == "sampler2DMS") return Type::TEXTURE2D;
|
||||
if (type == "samplerCube") return Type::TEXTURECUBE;
|
||||
|
||||
return Type::NONE;
|
||||
@ -121,7 +123,7 @@ namespace Prism
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Type::TEXTURE2D: return "sampler2D";
|
||||
case Type::TEXTURE2D: return "sampler2D";
|
||||
case Type::TEXTURECUBE: return "samplerCube";
|
||||
}
|
||||
return "Invalid Type";
|
||||
|
||||
@ -70,7 +70,7 @@ namespace Prism
|
||||
int32_t GetLocation() const { return m_Location; }
|
||||
inline Type GetType() const { return m_Type; }
|
||||
inline bool IsArray() const { return m_Count > 1; }
|
||||
inline const ShaderStruct& GetShaderUniformStruct() const { PM_CORE_ASSERT(m_Struct, ""); return *m_Struct; }
|
||||
inline const ShaderStruct& GetShaderUniformStruct() const { PM_CORE_ASSERT(m_Struct); return *m_Struct; }
|
||||
protected:
|
||||
void SetOffset(uint32_t offset) override;
|
||||
public:
|
||||
|
||||
@ -42,11 +42,12 @@ namespace Prism
|
||||
glTextureParameterf(m_RendererID, GL_TEXTURE_MAX_ANISOTROPY, RendererAPI::GetCapabilities().MaxAnisotropy);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, PrismToOpenGLTextureFormat(m_Format), (GLint)m_Width, (GLint)m_Height, 0, Prism::PrismToOpenGLTextureFormat(m_Format), GL_UNSIGNED_BYTE, nullptr);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
// glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
});
|
||||
|
||||
m_ImageData.Allocate(width * height * GetBPP(m_Format));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -38,6 +38,11 @@ namespace Prism
|
||||
virtual const std::string& GetPath() const override { return m_FilePath; }
|
||||
|
||||
virtual RendererID GetRendererID() const override { return m_RendererID; }
|
||||
|
||||
virtual bool operator==(const Texture& other) const override
|
||||
{
|
||||
return m_RendererID == ((OpenGLTexture2D&)other).m_RendererID;
|
||||
}
|
||||
private:
|
||||
RendererID m_RendererID;
|
||||
TextureFormat m_Format;
|
||||
@ -73,6 +78,10 @@ namespace Prism
|
||||
|
||||
virtual RendererID GetRendererID() const override { return m_RendererID; }
|
||||
|
||||
virtual bool operator==(const Texture& other) const override
|
||||
{
|
||||
return m_RendererID == ((OpenGLTextureCube&)other).m_RendererID;
|
||||
}
|
||||
private:
|
||||
RendererID m_RendererID;
|
||||
TextureFormat m_Format;
|
||||
|
||||
@ -21,8 +21,9 @@ namespace Prism
|
||||
virtual void AddVertexBuffer(const Ref<VertexBuffer>& vertexBuffer) override;
|
||||
virtual void SetIndexBuffer(const Ref<IndexBuffer>& indexBuffer) override;
|
||||
|
||||
virtual const std::vector<Ref<VertexBuffer>>& GetVertexBuffers() const { return m_VertexBuffers; }
|
||||
virtual const Ref<IndexBuffer>& GetIndexBuffer() const { return m_IndexBuffer; }
|
||||
virtual const std::vector<Ref<VertexBuffer>>& GetVertexBuffers() const override { return m_VertexBuffers; }
|
||||
virtual const Ref<IndexBuffer>& GetIndexBuffer() const override { return m_IndexBuffer; }
|
||||
virtual RendererID GetRendererID() const override { return m_RendererID; }
|
||||
private:
|
||||
RendererID m_RendererID = 0;
|
||||
uint32_t m_VertexBufferIndex = 0;
|
||||
|
||||
@ -10,7 +10,9 @@
|
||||
#include "glm/gtc/quaternion.hpp"
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include "glm/gtx/quaternion.hpp"
|
||||
#include "Prism/Core/Application.h"
|
||||
#include "Prism/Core/Input.h"
|
||||
#include "Prism/Core/Events/MouseEvent.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.1415926f
|
||||
@ -36,7 +38,7 @@ namespace Prism
|
||||
{
|
||||
}
|
||||
|
||||
void Camera::Update(TimeStep deltaTime)
|
||||
void Camera::OnUpdate(TimeStep deltaTime)
|
||||
{
|
||||
if (Input::IsKeyPressed(GLFW_KEY_LEFT_ALT))
|
||||
{
|
||||
@ -63,6 +65,12 @@ namespace Prism
|
||||
m_ViewMatrix = glm::inverse(m_ViewMatrix);
|
||||
}
|
||||
|
||||
void Camera::OnEvent(Event& e)
|
||||
{
|
||||
EventDispatcher dispatcher(e);
|
||||
dispatcher.Dispatch<MouseScrolledEvent>(PM_BIND_EVENT_FN(Camera::OnMouseScroll));
|
||||
}
|
||||
|
||||
glm::vec3 Camera::GetUpDirection()
|
||||
{
|
||||
return glm::rotate(GetOrientation(), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
@ -78,6 +86,13 @@ namespace Prism
|
||||
return glm::rotate(GetOrientation(), glm::vec3(0.0f, 0.0f, -1.0f));
|
||||
}
|
||||
|
||||
bool Camera::OnMouseScroll(MouseScrolledEvent& e)
|
||||
{
|
||||
const float delta = e.GetOffsetY() * 0.1f;
|
||||
MouseZoom(delta);
|
||||
return false;
|
||||
}
|
||||
|
||||
void Camera::MousePan(const glm::vec2& delta)
|
||||
{
|
||||
auto [xSpeed, ySpeed] = PanSpeed();
|
||||
|
||||
@ -6,11 +6,12 @@
|
||||
#define CAMERA_H
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "Prism/Core/TimeStep.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
class MouseScrolledEvent;
|
||||
class Event;
|
||||
|
||||
class PRISM_API Camera
|
||||
{
|
||||
@ -19,7 +20,8 @@ namespace Prism
|
||||
Camera(const glm::mat4& projectionMatrix);
|
||||
|
||||
void Focus();
|
||||
void Update(TimeStep deltaTime);
|
||||
void OnUpdate(TimeStep deltaTime);
|
||||
void OnEvent(Event& e);
|
||||
|
||||
inline float GetDistance() const { return m_Distance; }
|
||||
inline void SetDistance(float distance) { m_Distance = distance; }
|
||||
@ -28,6 +30,7 @@ namespace Prism
|
||||
|
||||
const glm::mat4& GetProjectionMatrix() const { return m_ProjectionMatrix; }
|
||||
const glm::mat4& GetViewMatrix() const { return m_ViewMatrix; }
|
||||
glm::mat4 GetViewProjection() const { return m_ProjectionMatrix * m_ViewMatrix; }
|
||||
|
||||
glm::vec3 GetUpDirection();
|
||||
glm::vec3 GetRightDirection();
|
||||
@ -40,6 +43,7 @@ namespace Prism
|
||||
public:
|
||||
inline void SetViewportSize(const uint32_t width, const uint32_t height) { m_ViewportWidth = width; m_ViewportHeight = height; }
|
||||
private:
|
||||
bool OnMouseScroll(MouseScrolledEvent& e);
|
||||
void MousePan(const glm::vec2& delta);
|
||||
void MouseRotate(const glm::vec2& delta);
|
||||
void MouseZoom(float delta);
|
||||
|
||||
@ -23,6 +23,7 @@ namespace Prism
|
||||
uint32_t Height = 720;
|
||||
glm::vec4 ClearColor;
|
||||
FramebufferFormat Format;
|
||||
uint32_t Samples = 1;
|
||||
|
||||
// SwapChainTarget = screen buffer (i.e. no framebuffer)
|
||||
bool SwapChainTarget = false;
|
||||
|
||||
@ -45,6 +45,7 @@ namespace Prism
|
||||
|
||||
void Material::OnShaderReloaded()
|
||||
{
|
||||
return;
|
||||
AllocateStorage();
|
||||
|
||||
for (auto mi : m_MaterialInstances)
|
||||
|
||||
@ -98,7 +98,7 @@ namespace Prism
|
||||
const auto decl = m_Material->FindUniformDeclaration(name);
|
||||
if (!decl) PM_CORE_WARN("Could not find uniform with name {0}", name);
|
||||
auto& buffer = GetUniformBufferTarget(decl);
|
||||
buffer.Write((byte*)& value, decl->GetSize(), decl->GetOffset());
|
||||
buffer.Write(&value, decl->GetSize(), decl->GetOffset());
|
||||
|
||||
m_OverriddenValues.insert(name);
|
||||
}
|
||||
@ -152,7 +152,7 @@ namespace Prism
|
||||
// HZ_CORE_ASSERT(decl, "Could not find uniform with name '{0}'", name);
|
||||
PM_CORE_ASSERT(decl, "Could not find uniform with name 'x'");
|
||||
auto& buffer = GetUniformBufferTarget(decl);
|
||||
buffer.Write((byte*)&value, decl->GetSize(), decl->GetOffset());
|
||||
buffer.Write(&value, decl->GetSize(), decl->GetOffset());
|
||||
|
||||
for (auto mi : m_MaterialInstances)
|
||||
mi->OnMaterialValueUpdated(decl);
|
||||
|
||||
@ -155,12 +155,23 @@ namespace Prism
|
||||
}
|
||||
}else
|
||||
{
|
||||
for (size_t i = 0; i < mesh->mNumVertices; i++)
|
||||
submesh.Min = { FLT_MAX, FLT_MAX, FLT_MAX };
|
||||
submesh.Max = { -FLT_MAX, -FLT_MAX, -FLT_MAX };
|
||||
|
||||
for (size_t i = 0; i < mesh->mNumVertices; i++)
|
||||
{
|
||||
Vertex vertex;
|
||||
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);
|
||||
|
||||
|
||||
if (mesh->HasTangentsAndBitangents())
|
||||
{
|
||||
vertex.Tangent = { mesh->mTangents[i].x, mesh->mTangents[i].y, mesh->mTangents[i].z };
|
||||
@ -273,8 +284,97 @@ namespace Prism
|
||||
{
|
||||
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");
|
||||
}
|
||||
|
||||
// Normal Maps
|
||||
mi->Set("u_NormalTexToggle", 0.0f);
|
||||
|
||||
if (aiMaterial->GetTexture(aiTextureType_NORMALS, 0, &aiTexPath) == AI_SUCCESS)
|
||||
{
|
||||
// TODO: Temp - this should be handled by Hazel's filesystem
|
||||
std::filesystem::path path = filename;
|
||||
auto parentPath = path.parent_path();
|
||||
parentPath /= std::string(aiTexPath.data);
|
||||
std::string texturePath = parentPath.string();
|
||||
|
||||
auto texture = Texture2D::Create(texturePath);
|
||||
if (texture->Loaded())
|
||||
{
|
||||
PM_CORE_TRACE(" Normal map path = {0}", texturePath);
|
||||
mi->Set("u_NormalTexture", texture);
|
||||
mi->Set("u_NormalTexToggle", 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
PM_CORE_ERROR("Could not load texture: {0}", texturePath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PM_CORE_TRACE("Mesh has no normal map");
|
||||
}
|
||||
|
||||
// Roughness map
|
||||
// mi->Set("u_Roughness", 1.0f);
|
||||
// mi->Set("u_RoughnessTexToggle", 0.0f);
|
||||
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);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PM_CORE_TRACE("Mesh has no roughness texture");
|
||||
}
|
||||
|
||||
// Metalness map
|
||||
// mi->Set("u_Metalness", 0.0f);
|
||||
// mi->Set("u_MetalnessTexToggle", 0.0f);
|
||||
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);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PM_CORE_TRACE("Mesh has no metalness texture");
|
||||
}
|
||||
continue;
|
||||
|
||||
|
||||
|
||||
for (uint32_t i = 0; i < aiMaterial->mNumProperties; i++)
|
||||
{
|
||||
auto prop = aiMaterial->mProperties[i];
|
||||
@ -357,6 +457,7 @@ namespace Prism
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// Normal maps
|
||||
if (aiMaterial->GetTexture(aiTextureType_NORMALS, 0, &aiTexPath) == AI_SUCCESS)
|
||||
{
|
||||
@ -428,6 +529,8 @@ namespace Prism
|
||||
mi->Set("u_MetalnessTexToggle", 1.0f);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -87,6 +87,7 @@ namespace Prism
|
||||
uint32_t IndexCount;
|
||||
|
||||
glm::mat4 Transform;
|
||||
glm::vec3 Min, Max; //TODO: AABB
|
||||
};
|
||||
|
||||
class PRISM_API Mesh
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
#include "Renderer.h"
|
||||
|
||||
#include "Renderer2D.h"
|
||||
#include "RendererAPI.h"
|
||||
#include "SceneRenderer.h"
|
||||
#include "glad/glad.h"
|
||||
@ -35,10 +36,10 @@ namespace Prism
|
||||
|
||||
// FullScreen Quad
|
||||
static float fullScreenQuadVertex[] = {
|
||||
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
|
||||
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
|
||||
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
|
||||
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f
|
||||
-1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
|
||||
1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
|
||||
1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
|
||||
-1.0f, 1.0f, 0.1f, 0.0f, 1.0f
|
||||
};
|
||||
static uint32_t fullScreenQuadIndices[] = {
|
||||
0, 1, 2, 2, 3, 0
|
||||
@ -55,6 +56,7 @@ namespace Prism
|
||||
s_Data.m_FullscreenQuadVertexArray->AddVertexBuffer(quadVB);
|
||||
s_Data.m_FullscreenQuadVertexArray->SetIndexBuffer(quadIB);
|
||||
|
||||
Renderer2D::Init();
|
||||
}
|
||||
|
||||
void Renderer::Clear()
|
||||
@ -76,10 +78,10 @@ namespace Prism
|
||||
{
|
||||
}
|
||||
|
||||
void Renderer::DrawIndexed(uint32_t count, bool depthTest)
|
||||
void Renderer::DrawIndexed(const uint32_t count, const PrimitiveType type, const bool depthTest)
|
||||
{
|
||||
Submit([=]() {
|
||||
RendererAPI::DrawIndexed(count, depthTest);
|
||||
RendererAPI::DrawIndexed(count, type, depthTest);
|
||||
});
|
||||
}
|
||||
|
||||
@ -90,12 +92,19 @@ namespace Prism
|
||||
return s_Data.m_ShaderLibrary;
|
||||
}
|
||||
|
||||
void Renderer::SetLineThickness(const float thickness)
|
||||
{
|
||||
Submit([=]() {
|
||||
RendererAPI::SetLineThickness(thickness);
|
||||
});
|
||||
}
|
||||
|
||||
void Renderer::WaitAndRender()
|
||||
{
|
||||
s_Data.m_CommandQueue.Execute();
|
||||
}
|
||||
|
||||
void Renderer::BeginRenderPass(const Ref<RenderPass>& renderPass)
|
||||
void Renderer::BeginRenderPass(const Ref<RenderPass>& renderPass, bool clear)
|
||||
{
|
||||
PM_CORE_ASSERT(renderPass, "Render pass cannot be null!");
|
||||
|
||||
@ -103,10 +112,14 @@ namespace Prism
|
||||
s_Data.m_ActiveRenderPass = renderPass;
|
||||
|
||||
renderPass->GetSpecification().TargetFramebuffer->Bind();
|
||||
const glm::vec4& clearColor = renderPass->GetSpecification().TargetFramebuffer->GetSpecification().ClearColor;
|
||||
Renderer::Submit([=]() {
|
||||
RendererAPI::Clear(clearColor.r, clearColor.g, clearColor.b, clearColor.a);
|
||||
});
|
||||
|
||||
if (clear)
|
||||
{
|
||||
const glm::vec4& clearColor = renderPass->GetSpecification().TargetFramebuffer->GetSpecification().ClearColor;
|
||||
Submit([=]() {
|
||||
RendererAPI::Clear(clearColor.r, clearColor.g, clearColor.b, clearColor.a);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::EndRenderPass()
|
||||
@ -129,7 +142,7 @@ namespace Prism
|
||||
}
|
||||
|
||||
s_Data.m_FullscreenQuadVertexArray->Bind();
|
||||
Renderer::DrawIndexed(6, depthTest);
|
||||
Renderer::DrawIndexed(6, PrimitiveType::Triangles, depthTest);
|
||||
}
|
||||
|
||||
void Renderer::SubmitFullscreenQuad(const Ref<MaterialInstance>& material)
|
||||
@ -142,7 +155,7 @@ namespace Prism
|
||||
}
|
||||
|
||||
s_Data.m_FullscreenQuadVertexArray->Bind();
|
||||
Renderer::DrawIndexed(6, depthTest);
|
||||
Renderer::DrawIndexed(6, PrimitiveType::Triangles, depthTest);
|
||||
}
|
||||
|
||||
void Renderer::SubmitMesh(const Ref<Mesh>& mesh, const glm::mat4& transform, const Ref<MaterialInstance>& overrideMaterial)
|
||||
@ -182,6 +195,36 @@ namespace Prism
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::DrawAABB(const Ref<Mesh>& mesh, const glm::vec4& color)
|
||||
{
|
||||
for (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);
|
||||
}
|
||||
}
|
||||
|
||||
RenderCommandQueue& Renderer::GetRenderCommandQueue()
|
||||
{
|
||||
return s_Data.m_CommandQueue;
|
||||
|
||||
@ -22,11 +22,13 @@ namespace Prism
|
||||
static void Clear();
|
||||
static void Clear(float r, float g, float b, float a = 1.0f);
|
||||
static void SetClearColor(float r, float g, float b, float a);
|
||||
static void DrawIndexed(uint32_t count, bool depthTest = true);
|
||||
|
||||
|
||||
static const Scope<ShaderLibrary>& GetShaderLibrary();
|
||||
|
||||
static void DrawIndexed(uint32_t count, PrimitiveType type, bool depthTest = true);
|
||||
// For OpenGL
|
||||
static void SetLineThickness(float thickness);
|
||||
|
||||
template<typename FuncT>
|
||||
static void Submit(FuncT&& func)
|
||||
{
|
||||
@ -47,13 +49,14 @@ namespace Prism
|
||||
|
||||
|
||||
public:
|
||||
static void BeginRenderPass(const Ref<RenderPass>& renderPass);
|
||||
static void BeginRenderPass(const Ref<RenderPass>& renderPass, bool clear = true);
|
||||
static void EndRenderPass();
|
||||
|
||||
static void SubmitQuad(const Ref<MaterialInstance>& material, const glm::mat4& transform = glm::mat4(1.0f));
|
||||
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));
|
||||
private:
|
||||
static RenderCommandQueue& GetRenderCommandQueue();
|
||||
};
|
||||
|
||||
418
Prism/src/Prism/Renderer/Renderer2D.cpp
Normal file
418
Prism/src/Prism/Renderer/Renderer2D.cpp
Normal file
@ -0,0 +1,418 @@
|
||||
//
|
||||
// Created by sfd on 25-12-1.
|
||||
//
|
||||
|
||||
#include "Renderer2D.h"
|
||||
|
||||
#include "Renderer.h"
|
||||
#include "Shader.h"
|
||||
#include "VertexArray.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
|
||||
struct QuadVertex
|
||||
{
|
||||
glm::vec3 Position;
|
||||
glm::vec4 Color;
|
||||
glm::vec2 TexCoord;
|
||||
float TexIndex;
|
||||
float TilingFactor;
|
||||
};
|
||||
|
||||
struct LineVertex
|
||||
{
|
||||
glm::vec3 Position;
|
||||
glm::vec4 Color;
|
||||
};
|
||||
|
||||
struct Renderer2DData
|
||||
{
|
||||
static constexpr uint32_t MaxQuads = 20000;
|
||||
static constexpr uint32_t MaxVertices = MaxQuads * 4;
|
||||
static constexpr uint32_t MaxIndices = MaxQuads * 6;
|
||||
static constexpr uint32_t MaxTextureSlots = 32; // TODO: RenderCaps
|
||||
|
||||
static constexpr uint32_t MaxLines = 10000;
|
||||
static constexpr uint32_t MaxLineVertices = MaxLines * 2;
|
||||
static constexpr uint32_t MaxLineIndices = MaxLines * 6;
|
||||
|
||||
// Quad
|
||||
Ref<VertexArray> QuadVertexArray;
|
||||
Ref<VertexBuffer> QuadVertexBuffer;
|
||||
Ref<Shader> TextureShader;
|
||||
Ref<Texture2D> WhiteTexture;
|
||||
|
||||
uint32_t QuadIndexCount = 0;
|
||||
QuadVertex* QuadVertexBufferBase = nullptr;
|
||||
QuadVertex* QuadVertexBufferPtr = nullptr;
|
||||
|
||||
std::array<Ref<Texture2D>, MaxTextureSlots> TextureSlots;
|
||||
uint32_t TextureSlotIndex = 1; // 0 = white texture
|
||||
|
||||
glm::vec4 QuadVertexPositions[4];
|
||||
|
||||
|
||||
// Lines
|
||||
Ref<VertexArray> LineVertexArray;
|
||||
Ref<VertexBuffer> LineVertexBuffer;
|
||||
Ref<Shader> LineShader;
|
||||
|
||||
uint32_t LineIndexCount = 0;
|
||||
LineVertex* LineVertexBufferBase = nullptr;
|
||||
LineVertex* LineVertexBufferPtr = nullptr;
|
||||
|
||||
glm::mat4 CameraViewProj;
|
||||
bool DepthTest = true;
|
||||
|
||||
Renderer2D::Statistics Stats;
|
||||
};
|
||||
|
||||
static Renderer2DData s_Data;
|
||||
static glm::vec2 defaultTexCoords[] = {{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}};
|
||||
|
||||
|
||||
void Renderer2D::Init()
|
||||
{
|
||||
s_Data.QuadVertexArray = VertexArray::Create();
|
||||
|
||||
s_Data.QuadVertexBuffer = VertexBuffer::Create(s_Data.MaxVertices * sizeof(QuadVertex));
|
||||
s_Data.QuadVertexBuffer->SetLayout({
|
||||
{ ShaderDataType::Float3, "a_Position" },
|
||||
{ ShaderDataType::Float4, "a_Color" },
|
||||
{ ShaderDataType::Float2, "a_TexCoord" },
|
||||
{ ShaderDataType::Float, "a_TexIndex" },
|
||||
{ ShaderDataType::Float, "a_TilingFactor" }
|
||||
});
|
||||
s_Data.QuadVertexArray->AddVertexBuffer(s_Data.QuadVertexBuffer);
|
||||
|
||||
s_Data.QuadVertexBufferBase = new QuadVertex[s_Data.MaxVertices];
|
||||
|
||||
uint32_t* quadIndices = new uint32_t[s_Data.MaxIndices];
|
||||
|
||||
uint32_t offset = 0;
|
||||
for (uint32_t i = 0; i < s_Data.MaxIndices; i += 6)
|
||||
{
|
||||
quadIndices[i + 0] = offset + 0;
|
||||
quadIndices[i + 1] = offset + 1;
|
||||
quadIndices[i + 2] = offset + 2;
|
||||
|
||||
quadIndices[i + 3] = offset + 2;
|
||||
quadIndices[i + 4] = offset + 3;
|
||||
quadIndices[i + 5] = offset + 0;
|
||||
|
||||
offset += 4;
|
||||
}
|
||||
|
||||
Ref<IndexBuffer> quadIB = IndexBuffer::Create(quadIndices, s_Data.MaxIndices);
|
||||
s_Data.QuadVertexArray->SetIndexBuffer(quadIB);
|
||||
delete[] quadIndices;
|
||||
|
||||
s_Data.WhiteTexture = Texture2D::Create(TextureFormat::RGBA, 1, 1);
|
||||
uint32_t whiteTextureData = 0xffffffff;
|
||||
s_Data.WhiteTexture->Lock();
|
||||
s_Data.WhiteTexture->GetWriteableBuffer().Write(&whiteTextureData, sizeof(uint32_t));
|
||||
s_Data.WhiteTexture->Unlock();
|
||||
|
||||
s_Data.TextureShader = Shader::Create("assets/shaders/Renderer2D.glsl");
|
||||
|
||||
// Set all texture slots to 0
|
||||
s_Data.TextureSlots[0] = s_Data.WhiteTexture;
|
||||
|
||||
s_Data.QuadVertexPositions[0] = { -0.5f, -0.5f, 0.0f, 1.0f };
|
||||
s_Data.QuadVertexPositions[1] = { 0.5f, -0.5f, 0.0f, 1.0f };
|
||||
s_Data.QuadVertexPositions[2] = { 0.5f, 0.5f, 0.0f, 1.0f };
|
||||
s_Data.QuadVertexPositions[3] = { -0.5f, 0.5f, 0.0f, 1.0f };
|
||||
|
||||
// Lines
|
||||
s_Data.LineShader = Shader::Create("assets/shaders/Renderer2D_Line.glsl");
|
||||
s_Data.LineVertexArray = VertexArray::Create();
|
||||
|
||||
s_Data.LineVertexBuffer = VertexBuffer::Create(s_Data.MaxLineVertices * sizeof(LineVertex));
|
||||
s_Data.LineVertexBuffer->SetLayout({
|
||||
{ ShaderDataType::Float3, "a_Position" },
|
||||
{ ShaderDataType::Float4, "a_Color" }
|
||||
});
|
||||
s_Data.LineVertexArray->AddVertexBuffer(s_Data.LineVertexBuffer);
|
||||
|
||||
s_Data.LineVertexBufferBase = new LineVertex[s_Data.MaxLineVertices];
|
||||
|
||||
uint32_t* lineIndices = new uint32_t[s_Data.MaxLineIndices];
|
||||
for (uint32_t i = 0; i < s_Data.MaxLineIndices; i++)
|
||||
lineIndices[i] = i;
|
||||
|
||||
Ref<IndexBuffer> lineIB = IndexBuffer::Create(lineIndices, s_Data.MaxLineIndices);
|
||||
s_Data.LineVertexArray->SetIndexBuffer(lineIB);
|
||||
delete[] lineIndices;
|
||||
}
|
||||
|
||||
void Renderer2D::Shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
void Renderer2D::BeginScene(const glm::mat4& viewProj, bool depthTest)
|
||||
{
|
||||
s_Data.CameraViewProj = viewProj;
|
||||
s_Data.DepthTest = depthTest;
|
||||
|
||||
s_Data.TextureShader->Bind();
|
||||
s_Data.TextureShader->SetMat4("u_ViewProjection", viewProj);
|
||||
|
||||
s_Data.QuadIndexCount = 0;
|
||||
s_Data.QuadVertexBufferPtr = s_Data.QuadVertexBufferBase;
|
||||
|
||||
s_Data.LineIndexCount = 0;
|
||||
s_Data.LineVertexBufferPtr = s_Data.LineVertexBufferBase;
|
||||
|
||||
s_Data.TextureSlotIndex = 1;
|
||||
}
|
||||
|
||||
void Renderer2D::EndScene()
|
||||
{
|
||||
uint32_t dataSize = (uint8_t*)s_Data.QuadVertexBufferPtr - (uint8_t*)s_Data.QuadVertexBufferBase;
|
||||
if (dataSize)
|
||||
{
|
||||
s_Data.QuadVertexBuffer->SetData(s_Data.QuadVertexBufferBase, dataSize);
|
||||
|
||||
s_Data.TextureShader->Bind();
|
||||
s_Data.TextureShader->SetMat4("u_ViewProjection", s_Data.CameraViewProj);
|
||||
|
||||
for (uint32_t i = 0; i < s_Data.TextureSlotIndex; i++)
|
||||
s_Data.TextureSlots[i]->Bind(i);
|
||||
|
||||
s_Data.QuadVertexArray->Bind();
|
||||
Renderer::DrawIndexed(s_Data.QuadIndexCount, PrimitiveType::Triangles, s_Data.DepthTest);
|
||||
s_Data.Stats.DrawCalls++;
|
||||
}
|
||||
|
||||
dataSize = (uint8_t*)s_Data.LineVertexBufferPtr - (uint8_t*)s_Data.LineVertexBufferBase;
|
||||
if (dataSize)
|
||||
{
|
||||
s_Data.LineVertexBuffer->SetData(s_Data.LineVertexBufferBase, dataSize);
|
||||
|
||||
s_Data.LineShader->Bind();
|
||||
s_Data.LineShader->SetMat4("u_ViewProjection", s_Data.CameraViewProj);
|
||||
|
||||
s_Data.LineVertexArray->Bind();
|
||||
Renderer::SetLineThickness(2.0f);
|
||||
Renderer::DrawIndexed(s_Data.LineIndexCount, PrimitiveType::Lines, s_Data.DepthTest);
|
||||
s_Data.Stats.DrawCalls++;
|
||||
}
|
||||
|
||||
#if OLD
|
||||
Flush();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Renderer2D::Flush()
|
||||
{
|
||||
#if OLD
|
||||
// Bind textures
|
||||
for (uint32_t i = 0; i < s_Data.TextureSlotIndex; i++)
|
||||
s_Data.TextureSlots[i]->Bind(i);
|
||||
|
||||
s_Data.QuadVertexArray->Bind();
|
||||
Renderer::DrawIndexed(s_Data.QuadIndexCount, false);
|
||||
s_Data.Stats.DrawCalls++;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Renderer2D::DrawQuad(const glm::vec2& position, const glm::vec2& size, const glm::vec4& color)
|
||||
{
|
||||
DrawQuad({ position.x, position.y, 0.0f }, size, color);
|
||||
}
|
||||
|
||||
void Renderer2D::DrawQuad(const glm::vec3& position, const glm::vec2& size, const glm::vec4& color)
|
||||
{
|
||||
if (s_Data.QuadIndexCount >= Renderer2DData::MaxIndices)
|
||||
FlushAndReset();
|
||||
|
||||
const float textureIndex = 0.0f; // White Texture
|
||||
const float tilingFactor = 1.0f;
|
||||
|
||||
glm::mat4 transform = glm::translate(glm::mat4(1.0f), position)
|
||||
* glm::scale(glm::mat4(1.0f), { size.x, size.y, 1.0f });
|
||||
|
||||
for (uint32_t i = 0; i < 4; i++)
|
||||
{
|
||||
s_Data.QuadVertexBufferPtr->Position = transform * s_Data.QuadVertexPositions[i];
|
||||
s_Data.QuadVertexBufferPtr->Color = color;
|
||||
s_Data.QuadVertexBufferPtr->TexCoord = defaultTexCoords[i];
|
||||
s_Data.QuadVertexBufferPtr->TexIndex = textureIndex;
|
||||
s_Data.QuadVertexBufferPtr->TilingFactor = tilingFactor;
|
||||
s_Data.QuadVertexBufferPtr++;
|
||||
}
|
||||
|
||||
s_Data.QuadIndexCount += 6;
|
||||
|
||||
s_Data.Stats.QuadCount++;
|
||||
}
|
||||
|
||||
void Renderer2D::DrawQuad(const glm::vec2& position, const glm::vec2& size, const Ref<Texture2D>& texture, float tilingFactor, const glm::vec4& tintColor)
|
||||
{
|
||||
DrawQuad({ position.x, position.y, 0.0f }, size, texture, tilingFactor, tintColor);
|
||||
}
|
||||
|
||||
void Renderer2D::DrawQuad(const glm::vec3& position, const glm::vec2& size, const Ref<Texture2D>& texture, float tilingFactor, const glm::vec4& tintColor)
|
||||
{
|
||||
if (s_Data.QuadIndexCount >= Renderer2DData::MaxIndices)
|
||||
FlushAndReset();
|
||||
|
||||
constexpr glm::vec4 color = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
|
||||
float textureIndex = 0.0f;
|
||||
for (uint32_t i = 1; i < s_Data.TextureSlotIndex; i++)
|
||||
{
|
||||
if (*s_Data.TextureSlots[i].get() == *texture.get())
|
||||
{
|
||||
textureIndex = (float)i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (textureIndex == 0.0f)
|
||||
{
|
||||
textureIndex = (float)s_Data.TextureSlotIndex;
|
||||
s_Data.TextureSlots[s_Data.TextureSlotIndex] = texture;
|
||||
s_Data.TextureSlotIndex++;
|
||||
}
|
||||
|
||||
glm::mat4 transform = glm::translate(glm::mat4(1.0f), position)
|
||||
* glm::scale(glm::mat4(1.0f), { size.x, size.y, 1.0f });
|
||||
for (uint32_t i = 0; i < 4; i++)
|
||||
{
|
||||
s_Data.QuadVertexBufferPtr->Position = transform * s_Data.QuadVertexPositions[i];
|
||||
s_Data.QuadVertexBufferPtr->Color = color;
|
||||
s_Data.QuadVertexBufferPtr->TexCoord = defaultTexCoords[i];
|
||||
s_Data.QuadVertexBufferPtr->TexIndex = textureIndex;
|
||||
s_Data.QuadVertexBufferPtr->TilingFactor = tilingFactor;
|
||||
s_Data.QuadVertexBufferPtr++;
|
||||
}
|
||||
|
||||
s_Data.QuadIndexCount += 6;
|
||||
|
||||
s_Data.Stats.QuadCount++;
|
||||
}
|
||||
|
||||
void Renderer2D::DrawRotatedQuad(const glm::vec2& position, const glm::vec2& size, float rotation, const glm::vec4& color)
|
||||
{
|
||||
DrawRotatedQuad({ position.x, position.y, 0.0f }, size, rotation, color);
|
||||
}
|
||||
|
||||
void Renderer2D::DrawRotatedQuad(const glm::vec3& position, const glm::vec2& size, float rotation, const glm::vec4& color)
|
||||
{
|
||||
if (s_Data.QuadIndexCount >= Renderer2DData::MaxIndices)
|
||||
FlushAndReset();
|
||||
|
||||
const float textureIndex = 0.0f; // White Texture
|
||||
const float tilingFactor = 1.0f;
|
||||
|
||||
glm::mat4 transform = glm::translate(glm::mat4(1.0f), position)
|
||||
* glm::rotate(glm::mat4(1.0f), glm::radians(rotation), { 0.0f, 0.0f, 1.0f })
|
||||
* glm::scale(glm::mat4(1.0f), { size.x, size.y, 1.0f });
|
||||
|
||||
for (uint32_t i = 1; i < 4; i++)
|
||||
{
|
||||
s_Data.QuadVertexBufferPtr->Position = transform * s_Data.QuadVertexPositions[i];
|
||||
s_Data.QuadVertexBufferPtr->Color = color;
|
||||
s_Data.QuadVertexBufferPtr->TexCoord = defaultTexCoords[i];
|
||||
s_Data.QuadVertexBufferPtr->TexIndex = textureIndex;
|
||||
s_Data.QuadVertexBufferPtr->TilingFactor = tilingFactor;
|
||||
s_Data.QuadVertexBufferPtr++;
|
||||
}
|
||||
|
||||
s_Data.QuadIndexCount += 6;
|
||||
|
||||
s_Data.Stats.QuadCount++;
|
||||
}
|
||||
|
||||
void Renderer2D::DrawRotatedQuad(const glm::vec2& position, const glm::vec2& size, float rotation, const Ref<Texture2D>& texture, float tilingFactor, const glm::vec4& tintColor)
|
||||
{
|
||||
DrawRotatedQuad({ position.x, position.y, 0.0f }, size, rotation, texture, tilingFactor, tintColor);
|
||||
}
|
||||
|
||||
void Renderer2D::DrawRotatedQuad(const glm::vec3& position, const glm::vec2& size, float rotation, const Ref<Texture2D>& texture, float tilingFactor, const glm::vec4& tintColor)
|
||||
{
|
||||
if (s_Data.QuadIndexCount >= Renderer2DData::MaxIndices)
|
||||
FlushAndReset();
|
||||
|
||||
constexpr glm::vec4 color = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
|
||||
float textureIndex = 0.0f;
|
||||
for (uint32_t i = 1; i < s_Data.TextureSlotIndex; i++)
|
||||
{
|
||||
if (*s_Data.TextureSlots[i].get() == *texture.get())
|
||||
{
|
||||
textureIndex = (float)i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (textureIndex == 0.0f)
|
||||
{
|
||||
textureIndex = (float)s_Data.TextureSlotIndex;
|
||||
s_Data.TextureSlots[s_Data.TextureSlotIndex] = texture;
|
||||
s_Data.TextureSlotIndex++;
|
||||
}
|
||||
|
||||
glm::mat4 transform = glm::translate(glm::mat4(1.0f), position)
|
||||
* glm::rotate(glm::mat4(1.0f), glm::radians(rotation), { 0.0f, 0.0f, 1.0f })
|
||||
* glm::scale(glm::mat4(1.0f), { size.x, size.y, 1.0f });
|
||||
|
||||
for (uint32_t i = 1; i < 4; i++)
|
||||
{
|
||||
s_Data.QuadVertexBufferPtr->Position = transform * s_Data.QuadVertexPositions[i];
|
||||
s_Data.QuadVertexBufferPtr->Color = color;
|
||||
s_Data.QuadVertexBufferPtr->TexCoord = defaultTexCoords[i];
|
||||
s_Data.QuadVertexBufferPtr->TexIndex = textureIndex;
|
||||
s_Data.QuadVertexBufferPtr->TilingFactor = tilingFactor;
|
||||
s_Data.QuadVertexBufferPtr++;
|
||||
}
|
||||
|
||||
s_Data.QuadIndexCount += 6;
|
||||
|
||||
s_Data.Stats.QuadCount++;
|
||||
}
|
||||
|
||||
void Renderer2D::DrawLine(const glm::vec3& p0, const glm::vec3& p1, const glm::vec4& color)
|
||||
{
|
||||
if (s_Data.LineIndexCount >= Renderer2DData::MaxLineIndices)
|
||||
FlushAndResetLines();
|
||||
|
||||
s_Data.LineVertexBufferPtr->Position = p0;
|
||||
s_Data.LineVertexBufferPtr->Color = color;
|
||||
s_Data.LineVertexBufferPtr++;
|
||||
|
||||
s_Data.LineVertexBufferPtr->Position = p1;
|
||||
s_Data.LineVertexBufferPtr->Color = color;
|
||||
s_Data.LineVertexBufferPtr++;
|
||||
|
||||
s_Data.LineIndexCount += 2;
|
||||
|
||||
s_Data.Stats.LineCount++;
|
||||
}
|
||||
|
||||
void Renderer2D::ResetStats()
|
||||
{
|
||||
memset(&s_Data.Stats, 0, sizeof(Statistics));
|
||||
}
|
||||
|
||||
Renderer2D::Statistics Renderer2D::GetStats()
|
||||
{
|
||||
return s_Data.Stats;
|
||||
}
|
||||
|
||||
void Renderer2D::FlushAndReset()
|
||||
{
|
||||
EndScene();
|
||||
|
||||
s_Data.QuadIndexCount = 0;
|
||||
s_Data.QuadVertexBufferPtr = s_Data.QuadVertexBufferBase;
|
||||
|
||||
s_Data.TextureSlotIndex = 1;
|
||||
}
|
||||
|
||||
void Renderer2D::FlushAndResetLines()
|
||||
{
|
||||
}
|
||||
}
|
||||
57
Prism/src/Prism/Renderer/Renderer2D.h
Normal file
57
Prism/src/Prism/Renderer/Renderer2D.h
Normal file
@ -0,0 +1,57 @@
|
||||
//
|
||||
// Created by sfd on 25-12-1.
|
||||
//
|
||||
|
||||
#ifndef RENDERER2D_H
|
||||
#define RENDERER2D_H
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "Texture.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
class PRISM_API Renderer2D
|
||||
{
|
||||
public:
|
||||
static void Init();
|
||||
static void Shutdown();
|
||||
|
||||
static void BeginScene(const glm::mat4& viewProj, bool depthTest = true);
|
||||
static void EndScene();
|
||||
static void Flush();
|
||||
|
||||
// Primitives
|
||||
static void DrawQuad(const glm::vec2& position, const glm::vec2& size, const glm::vec4& color);
|
||||
static void DrawQuad(const glm::vec3& position, const glm::vec2& size, const glm::vec4& color);
|
||||
static void DrawQuad(const glm::vec2& position, const glm::vec2& size, const Ref<Texture2D>& texture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));
|
||||
static void DrawQuad(const glm::vec3& position, const glm::vec2& size, const Ref<Texture2D>& texture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));
|
||||
|
||||
static void DrawRotatedQuad(const glm::vec2& position, const glm::vec2& size, float rotation, const glm::vec4& color);
|
||||
static void DrawRotatedQuad(const glm::vec3& position, const glm::vec2& size, float rotation, const glm::vec4& color);
|
||||
static void DrawRotatedQuad(const glm::vec2& position, const glm::vec2& size, float rotation, const Ref<Texture2D>& texture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));
|
||||
static void DrawRotatedQuad(const glm::vec3& position, const glm::vec2& size, float rotation, const Ref<Texture2D>& texture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));
|
||||
|
||||
static void DrawLine(const glm::vec3& p0, const glm::vec3& p1, const glm::vec4& color = glm::vec4(1.0f));
|
||||
// Stats
|
||||
struct Statistics
|
||||
{
|
||||
uint32_t DrawCalls = 0;
|
||||
uint32_t QuadCount = 0;
|
||||
uint32_t LineCount = 0;
|
||||
|
||||
uint32_t GetTotalVertexCount() { return QuadCount * 4 + LineCount * 2; }
|
||||
uint32_t GetTotalIndexCount() { return QuadCount * 6 + LineCount * 2; }
|
||||
};
|
||||
static void ResetStats();
|
||||
static Statistics GetStats();
|
||||
private:
|
||||
static void FlushAndReset();
|
||||
static void FlushAndResetLines();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif //RENDERER2D_H
|
||||
@ -16,14 +16,21 @@ namespace Prism
|
||||
OpenGL
|
||||
};
|
||||
|
||||
// TODO: move into separate header
|
||||
enum class PrimitiveType
|
||||
{
|
||||
None = 0, Triangles, Lines
|
||||
};
|
||||
|
||||
struct RenderAPICapabilities
|
||||
{
|
||||
std::string Vendor;
|
||||
std::string Renderer;
|
||||
std::string Version;
|
||||
|
||||
int MaxSamples;
|
||||
float MaxAnisotropy;
|
||||
int MaxSamples = 0;
|
||||
float MaxAnisotropy = 0.0f;
|
||||
int MaxTextureUnits = 0;
|
||||
};
|
||||
|
||||
class RendererAPI
|
||||
@ -35,7 +42,8 @@ namespace Prism
|
||||
static void Clear(float r, float g, float b, float a);
|
||||
static void SetClearColor(float r, float g, float b, float a);
|
||||
|
||||
static void DrawIndexed(unsigned int count, bool depthTest = true);
|
||||
static void DrawIndexed(uint32_t count,PrimitiveType type, bool depthTest = true);
|
||||
static void SetLineThickness(float thickness);
|
||||
static RendererAPIType Current() { return s_CurrentRendererAPI; }
|
||||
|
||||
static RenderAPICapabilities& GetCapabilities()
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
#include "Material.h"
|
||||
#include "Mesh.h"
|
||||
#include "Renderer.h"
|
||||
#include "Renderer2D.h"
|
||||
#include "RenderPass.h"
|
||||
#include "glad/glad.h"
|
||||
|
||||
@ -42,6 +43,8 @@ namespace Prism
|
||||
|
||||
// Grid
|
||||
Ref<MaterialInstance> GridMaterial;
|
||||
|
||||
SceneRendererOptions Options;
|
||||
};
|
||||
|
||||
static SceneRendererData s_Data;
|
||||
@ -52,6 +55,7 @@ namespace Prism
|
||||
geoFramebufferSpec.Width = 1280;
|
||||
geoFramebufferSpec.Height = 720;
|
||||
geoFramebufferSpec.Format = FramebufferFormat::RGBA16F;
|
||||
geoFramebufferSpec.Samples = 8;
|
||||
geoFramebufferSpec.ClearColor = { 0.1f, 0.1f, 0.1f, 1.0f };
|
||||
|
||||
RenderPassSpecification geoRenderPassSpec;
|
||||
@ -68,7 +72,8 @@ namespace Prism
|
||||
compRenderPassSpec.TargetFramebuffer = FrameBuffer::Create(compFramebufferSpec);
|
||||
s_Data.CompositePass = RenderPass::Create(compRenderPassSpec);
|
||||
|
||||
s_Data.CompositeShader = Shader::Create("assets/shaders/hdr.glsl");
|
||||
s_Data.CompositeShader = Shader::Create("assets/shaders/SceneComposite.glsl");
|
||||
// s_Data.CompositeShader = Shader::Create("assets/shaders/hdr.glsl");
|
||||
s_Data.BRDFLUT = Texture2D::Create("assets/textures/BRDF_LUT.tga");
|
||||
|
||||
|
||||
@ -178,11 +183,17 @@ namespace Prism
|
||||
{
|
||||
glBindImageTexture(0, irradianceMap->GetRendererID(), 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_RGBA16F);
|
||||
glDispatchCompute(irradianceMap->GetWidth() / 32, irradianceMap->GetHeight() / 32, 6);
|
||||
glGenerateTextureMipmap(irradianceMap->GetRendererID());
|
||||
});
|
||||
|
||||
return { envFiltered, irradianceMap };
|
||||
}
|
||||
|
||||
Ref<RenderPass> SceneRenderer::GetFinalRenderPass()
|
||||
{
|
||||
return s_Data.CompositePass;
|
||||
}
|
||||
|
||||
Ref<Texture2D> SceneRenderer::GetFinalColorBuffer()
|
||||
{
|
||||
PM_CORE_ASSERT(false, "Not implemented");
|
||||
@ -194,6 +205,11 @@ namespace Prism
|
||||
return s_Data.CompositePass->GetSpecification().TargetFramebuffer->GetColorAttachmentRendererID();
|
||||
}
|
||||
|
||||
SceneRendererOptions& SceneRenderer::GetOptions()
|
||||
{
|
||||
return s_Data.Options;
|
||||
}
|
||||
|
||||
void SceneRenderer::FlushDrawList()
|
||||
{
|
||||
PM_CORE_ASSERT(!s_Data.ActiveScene);
|
||||
@ -209,7 +225,7 @@ namespace Prism
|
||||
{
|
||||
Renderer::BeginRenderPass(s_Data.GeoPass);
|
||||
|
||||
auto viewProjection = s_Data.SceneData.SceneCamera.GetProjectionMatrix() * s_Data.SceneData.SceneCamera.GetViewMatrix();
|
||||
const auto viewProjection = s_Data.SceneData.SceneCamera.GetViewProjection();
|
||||
|
||||
// Skybox
|
||||
auto skyboxShader = s_Data.SceneData.SkyboxMaterial->GetShader();
|
||||
@ -234,8 +250,20 @@ namespace Prism
|
||||
}
|
||||
|
||||
// Grid
|
||||
s_Data.GridMaterial->Set("u_ViewProjection", viewProjection);
|
||||
Renderer::SubmitQuad(s_Data.GridMaterial, glm::rotate(glm::mat4(1.0f), glm::radians(90.0f), glm::vec3(1.0f, 0.0f, 0.0f)) * glm::scale(glm::mat4(1.0f), glm::vec3(16.0f)));
|
||||
const auto option = GetOptions();
|
||||
if (option.ShowGrid)
|
||||
{
|
||||
s_Data.GridMaterial->Set("u_ViewProjection", viewProjection);
|
||||
Renderer::SubmitQuad(s_Data.GridMaterial, glm::rotate(glm::mat4(1.0f), glm::radians(90.0f), glm::vec3(1.0f, 0.0f, 0.0f)) * glm::scale(glm::mat4(1.0f), glm::vec3(16.0f)));
|
||||
}
|
||||
|
||||
if (option.ShowBoundingBoxes)
|
||||
{
|
||||
Renderer2D::BeginScene(viewProjection);
|
||||
for (auto& dc : s_Data.DrawList)
|
||||
Renderer::DrawAABB(dc.mesh);
|
||||
Renderer2D::EndScene();
|
||||
}
|
||||
|
||||
Renderer::EndRenderPass();
|
||||
}
|
||||
@ -245,6 +273,7 @@ namespace Prism
|
||||
Renderer::BeginRenderPass(s_Data.CompositePass);
|
||||
s_Data.CompositeShader->Bind();
|
||||
s_Data.CompositeShader->SetFloat("u_Exposure", s_Data.SceneData.SceneCamera.GetExposure());
|
||||
s_Data.CompositeShader->SetInt("u_TextureSamples", s_Data.GeoPass->GetSpecification().TargetFramebuffer->GetSpecification().Samples);
|
||||
s_Data.GeoPass->GetSpecification().TargetFramebuffer->BindTexture();
|
||||
Renderer::SubmitFullscreenQuad(nullptr);
|
||||
Renderer::EndRenderPass();
|
||||
|
||||
@ -4,12 +4,19 @@
|
||||
|
||||
#ifndef SCENERENDERER_H
|
||||
#define SCENERENDERER_H
|
||||
#include "RenderPass.h"
|
||||
#include "Texture.h"
|
||||
#include "Prism/Scene/Scene.h"
|
||||
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
struct SceneRendererOptions
|
||||
{
|
||||
bool ShowGrid = true;
|
||||
bool ShowBoundingBoxes = false;
|
||||
};
|
||||
|
||||
class PRISM_API SceneRenderer
|
||||
{
|
||||
public:
|
||||
@ -24,11 +31,14 @@ namespace Prism
|
||||
|
||||
static std::pair<Ref<TextureCube>, Ref<TextureCube>> CreateEnvironmentMap(const std::string& filepath);
|
||||
|
||||
static Ref<RenderPass> GetFinalRenderPass();
|
||||
static Ref<Texture2D> GetFinalColorBuffer();
|
||||
|
||||
// TODO: Temp
|
||||
static uint32_t GetFinalColorBufferRendererID();
|
||||
|
||||
static SceneRendererOptions& GetOptions();
|
||||
|
||||
private:
|
||||
static void FlushDrawList();
|
||||
static void GeometryPass();
|
||||
|
||||
@ -110,9 +110,12 @@ namespace Prism
|
||||
virtual void UploadUniformBuffer(const UniformBufferBase& uniformBuffer) = 0;
|
||||
|
||||
virtual void SetFloat(const std::string& name, float value) = 0;
|
||||
virtual void SetInt(const std::string& name, int value) = 0;
|
||||
virtual void SetMat4(const std::string& name, const glm::mat4& value) = 0;
|
||||
virtual void SetMat4FromRenderThread(const std::string& name, const glm::mat4& value, bool bind = true) = 0;
|
||||
|
||||
virtual void SetIntArray(const std::string& name, int* values, uint32_t size) = 0;
|
||||
|
||||
virtual const std::string& GetName() const = 0;
|
||||
|
||||
virtual void SetVSMaterialUniformBuffer(Buffer buffer) = 0;
|
||||
|
||||
@ -43,6 +43,8 @@ namespace Prism
|
||||
|
||||
static uint32_t GetBPP(TextureFormat format);
|
||||
static uint32_t CalculateMipMapCount(uint32_t width, uint32_t height);
|
||||
|
||||
virtual bool operator==(const Texture& other) const = 0;
|
||||
};
|
||||
|
||||
class PRISM_API Texture2D : public Texture
|
||||
|
||||
@ -25,6 +25,7 @@ namespace Prism
|
||||
virtual const std::vector<Ref<VertexBuffer>>& GetVertexBuffers() const = 0;
|
||||
virtual const Ref<IndexBuffer>& GetIndexBuffer() const = 0;
|
||||
|
||||
virtual RendererID GetRendererID() const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -6,12 +6,12 @@
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
Entity::Entity()
|
||||
: m_Transform(glm::mat4(1.0f))
|
||||
{
|
||||
}
|
||||
|
||||
Entity::~Entity()
|
||||
{
|
||||
}
|
||||
|
||||
Entity::Entity(const std::string& name)
|
||||
: m_Name(name), m_Transform(glm::mat4(1.0f))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,7 +13,6 @@ namespace Prism
|
||||
class PRISM_API Entity
|
||||
{
|
||||
public:
|
||||
Entity();
|
||||
~Entity();
|
||||
|
||||
// TODO: Move to Component
|
||||
@ -25,12 +24,21 @@ namespace Prism
|
||||
|
||||
const glm::mat4& GetTransform() const { return m_Transform; }
|
||||
glm::mat4& Transform() { return m_Transform; }
|
||||
|
||||
|
||||
const std::string& GetName() const { return m_Name; }
|
||||
private:
|
||||
Entity(const std::string& name);
|
||||
private:
|
||||
std::string m_Name;
|
||||
glm::mat4 m_Transform;
|
||||
|
||||
// TODO: Temp
|
||||
Ref<Mesh> m_Mesh;
|
||||
Ref<MaterialInstance> m_Material;
|
||||
|
||||
private:
|
||||
friend class Scene;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -35,8 +35,6 @@ namespace Prism
|
||||
|
||||
void Scene::OnUpdate(TimeStep ts)
|
||||
{
|
||||
m_Camera.Update(ts);
|
||||
|
||||
m_SkyboxMaterial->Set("u_TextureLod", m_SkyboxLod);
|
||||
|
||||
// Update all entities
|
||||
@ -59,6 +57,11 @@ namespace Prism
|
||||
SceneRenderer::EndScene();
|
||||
}
|
||||
|
||||
void Scene::OnEvent(Event& e)
|
||||
{
|
||||
m_Camera.OnEvent(e);
|
||||
}
|
||||
|
||||
void Scene::SetCamera(const Camera& camera)
|
||||
{
|
||||
m_Camera = camera;
|
||||
@ -81,9 +84,12 @@ namespace Prism
|
||||
m_Entities.push_back(entity);
|
||||
}
|
||||
|
||||
Entity* Scene::CreateEntity()
|
||||
static const std::string DefaultEntityName = "Entity";
|
||||
|
||||
Entity* Scene::CreateEntity(const std::string& name)
|
||||
{
|
||||
const auto entity = new Entity();
|
||||
const std::string& entityName = name.empty() ? DefaultEntityName : name;
|
||||
const auto entity = new Entity(entityName);
|
||||
AddEntity(entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#ifndef SCENE_H
|
||||
#define SCENE_H
|
||||
#include "Entity.h"
|
||||
#include "Prism/Core/Events/Event.h"
|
||||
#include "Prism/Renderer/Camera.h"
|
||||
#include "Prism/Renderer/Material.h"
|
||||
|
||||
@ -28,6 +29,7 @@ namespace Prism
|
||||
void Init();
|
||||
|
||||
void OnUpdate(TimeStep ts);
|
||||
void OnEvent(Event& e);
|
||||
|
||||
void SetCamera(const Camera& camera);
|
||||
Camera& GetCamera() { return m_Camera; }
|
||||
@ -38,7 +40,7 @@ namespace Prism
|
||||
float& GetSkyboxLod() { return m_SkyboxLod; }
|
||||
|
||||
void AddEntity(Entity* entity);
|
||||
Entity* CreateEntity();
|
||||
Entity* CreateEntity(const std::string& name = "");
|
||||
|
||||
private:
|
||||
std::string m_DebugName;
|
||||
|
||||
@ -142,68 +142,24 @@ static void EnableDockSpace(const bool enable)
|
||||
|
||||
|
||||
TestLayer::TestLayer()
|
||||
:m_Camera(glm::perspectiveFov(glm::radians(45.0f), 1280.0f, 720.0f, 0.1f, 1000.0f))
|
||||
{
|
||||
}
|
||||
|
||||
void TestLayer::OnAttach()
|
||||
{
|
||||
Prism::FramebufferSpecification geoFramebufferspec;
|
||||
geoFramebufferspec.Width = 1280;
|
||||
geoFramebufferspec.Height = 720;
|
||||
geoFramebufferspec.Format = Prism::FramebufferFormat::RGBA16F;
|
||||
geoFramebufferspec.ClearColor = {0.1f, 0.1f, 0.1f, 1.0f};
|
||||
auto environment = Prism::Environment::Load("assets/env/birchwood_4k.hdr");
|
||||
{
|
||||
m_Scene = Prism::CreateRef<Prism::Scene>("test Scene");
|
||||
m_Scene->SetCamera(Prism::Camera(glm::perspectiveFov(glm::radians(45.0f), 1280.0f, 720.0f, 0.1f, 10000.0f)));
|
||||
m_Scene->SetEnvironment(environment);
|
||||
|
||||
Prism::RenderPassSpecification geoRenderPass;
|
||||
geoRenderPass.TargetFramebuffer = Prism::FrameBuffer::Create(geoFramebufferspec);
|
||||
m_GeoPass = Prism::RenderPass::Create(geoRenderPass);
|
||||
m_MeshEntity = m_Scene->CreateEntity("test Entity");
|
||||
|
||||
Prism::FramebufferSpecification finalFramebufferspec;
|
||||
finalFramebufferspec.Width = 1280;
|
||||
finalFramebufferspec.Height = 720;
|
||||
finalFramebufferspec.Format = Prism::FramebufferFormat::RGBA8;
|
||||
finalFramebufferspec.ClearColor = {0.1f, 0.1f, 0.1f, 1.0f};
|
||||
m_MeshEntity->SetMesh(Prism::CreateRef<Prism::Mesh>("assets/meshes/TestScene.fbx"));
|
||||
m_MeshMaterial = m_MeshEntity->GetMesh()->GetMaterial();
|
||||
|
||||
Prism::RenderPassSpecification finalRenderPass;
|
||||
finalRenderPass.TargetFramebuffer = Prism::FrameBuffer::Create(finalFramebufferspec);
|
||||
m_FinalPass = Prism::RenderPass::Create(finalRenderPass);
|
||||
}
|
||||
|
||||
|
||||
static float QuadVertex[] = {
|
||||
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
|
||||
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
|
||||
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
|
||||
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
static uint32_t QuadIndices[] = {
|
||||
0, 1, 2, 2, 3, 0
|
||||
};
|
||||
|
||||
m_VertexArray = Prism::VertexArray::Create();
|
||||
auto quadVB = Prism::VertexBuffer::Create(QuadVertex, sizeof(QuadVertex) * sizeof(float));
|
||||
quadVB->SetLayout({
|
||||
{ Prism::ShaderDataType::Float3, "a_Position" },
|
||||
{ Prism::ShaderDataType::Float2, "a_TexCoord" }
|
||||
});
|
||||
m_VertexArray->AddVertexBuffer(quadVB);
|
||||
|
||||
auto ib = Prism::IndexBuffer::Create(QuadIndices, 6 * sizeof(uint32_t));
|
||||
m_VertexArray->SetIndexBuffer(ib);
|
||||
|
||||
m_SkyBoxTextureCube.reset(Prism::TextureCube::Create("assets/textures/environments/Arches_E_PineTree_Radiance.tga"));
|
||||
m_EnvironmentIrradiance.reset(Prism::TextureCube::Create("assets/textures/environments/Arches_E_PineTree_Irradiance.tga"));
|
||||
|
||||
m_SkyBoxShader = Prism::Shader::Create("assets/shaders/quad.glsl");
|
||||
m_HDRShader = Prism::Shader::Create("assets/shaders/hdr.glsl");
|
||||
|
||||
m_Mesh = std::make_unique<Prism::Mesh>("assets/models/m1911/m1911.fbx");
|
||||
m_MeshMaterial = Prism::CreateRef<Prism::MaterialInstance>(m_Mesh->GetMaterial());
|
||||
|
||||
m_BRDFLUT.reset(Prism::Texture2D::Create("assets/textures/BRDF_LUT.tga"));
|
||||
|
||||
m_Light.Direction = {-0.5f, -0.5f, 1.0f};
|
||||
m_Light.Radiance = {1.0f, 1.0f, 1.0f};
|
||||
}
|
||||
|
||||
void TestLayer::OnDetach()
|
||||
@ -213,78 +169,48 @@ void TestLayer::OnDetach()
|
||||
void TestLayer::OnUpdate(Prism::TimeStep deltaTime)
|
||||
{
|
||||
|
||||
m_Camera.Update(deltaTime);
|
||||
auto viewProjection = m_Camera.GetProjectionMatrix() * m_Camera.GetViewMatrix();
|
||||
|
||||
Prism::Renderer::BeginRenderPass(m_GeoPass);
|
||||
Prism::Renderer::Clear(m_clearColor[0], m_clearColor[1], m_clearColor[2], m_clearColor[3]);
|
||||
|
||||
// SkyBox
|
||||
m_SkyBoxShader->Bind();
|
||||
m_SkyBoxShader->SetMat4("u_InverseVP", inverse(viewProjection));
|
||||
m_SkyBoxTextureCube->Bind(0);
|
||||
m_VertexArray->Bind();
|
||||
Prism::Renderer::DrawIndexed(m_VertexArray->GetIndexBuffer()->GetCount(), false);
|
||||
|
||||
|
||||
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("u_ViewProjectionMatrix", viewProjection);
|
||||
m_MeshMaterial->Set("u_ModelMatrix", glm::scale(glm::mat4(1.0f), glm::vec3(m_MeshScale)));
|
||||
m_MeshMaterial->Set("lights", m_Light);
|
||||
m_MeshMaterial->Set("u_CameraPosition", m_Camera.GetPosition());
|
||||
m_MeshMaterial->Set("u_RadiancePrefilter", m_RadiancePrefilter ? 1.0f : 0.0f);
|
||||
m_MeshMaterial->Set("u_AlbedoTexToggle", m_AlbedoInput.UseTexture ? 1.0f : 0.0f);
|
||||
m_MeshMaterial->Set("u_NormalTexToggle", m_NormalInput.UseTexture ? 1.0f : 0.0f);
|
||||
m_MeshMaterial->Set("u_MetalnessTexToggle", m_MetalnessInput.UseTexture ? 1.0f : 0.0f);
|
||||
m_MeshMaterial->Set("u_RoughnessTexToggle", m_RoughnessInput.UseTexture ? 1.0f : 0.0f);
|
||||
m_MeshMaterial->Set("u_EnvMapRotation", m_EnvMapRotation);
|
||||
m_MeshMaterial->Set("u_EnvRadianceTex", m_SkyBoxTextureCube);
|
||||
m_MeshMaterial->Set("u_EnvIrradianceTex", m_EnvironmentIrradiance);
|
||||
m_MeshMaterial->Set("u_BRDFLUTTexture", m_BRDFLUT);
|
||||
|
||||
m_Mesh->Render(deltaTime, glm::mat4(1.0f), m_MeshMaterial);
|
||||
if (m_AllowViewportCameraEvents)
|
||||
m_Scene->GetCamera().OnUpdate(deltaTime);
|
||||
|
||||
Prism::Renderer::EndRenderPass();
|
||||
|
||||
|
||||
// HDR
|
||||
Prism::Renderer::BeginRenderPass(m_FinalPass);
|
||||
m_HDRShader->Bind();
|
||||
m_HDRShader->SetFloat("u_Exposure", m_Exposure);
|
||||
m_GeoPass->GetSpecification().TargetFramebuffer->BindTexture();
|
||||
m_VertexArray->Bind();
|
||||
Prism::Renderer::DrawIndexed(m_VertexArray->GetIndexBuffer()->GetCount(), false);
|
||||
Prism::Renderer::EndRenderPass();
|
||||
m_Scene->OnUpdate(deltaTime);
|
||||
}
|
||||
|
||||
void TestLayer::OnImGuiRender()
|
||||
{
|
||||
EnableDockSpace(true);
|
||||
|
||||
ImGui::Begin("Settings");
|
||||
ImGui::ColorEdit4("ClearColor", glm::value_ptr(m_clearColor));
|
||||
ImGui::ColorEdit4("TriangleClearColor", glm::value_ptr(m_TriangleColor));
|
||||
ImGui::DragFloat("Exposure", &m_Exposure, 0.01f, 0.0f);
|
||||
const auto& position = m_Camera.GetPosition();
|
||||
ImGui::Text("Camera: (%.2f, %.2f, %.2f)", position.x, position.y, position.z);
|
||||
|
||||
|
||||
ImGui::End();
|
||||
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||
ImGui::Begin("Viewport");
|
||||
auto viewportSize = ImGui::GetContentRegionAvail();
|
||||
m_GeoPass->GetSpecification().TargetFramebuffer->Resize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
|
||||
m_FinalPass->GetSpecification().TargetFramebuffer->Resize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
|
||||
m_Camera.SetProjectionMatrix(glm::perspectiveFov(glm::radians(45.0f), viewportSize.x, viewportSize.y, 0.1f, 10000.0f));
|
||||
ImGui::Image((ImTextureRef)m_FinalPass->GetSpecification().TargetFramebuffer->GetColorAttachmentRendererID(), viewportSize, {0, 1}, {1, 0});
|
||||
Prism::SceneRenderer::SetViewportSize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
|
||||
m_Scene->GetCamera().SetProjectionMatrix(glm::perspectiveFov(glm::radians(45.0f), viewportSize.x, viewportSize.y, 0.1f, 10000.0f));
|
||||
m_Scene->GetCamera().SetViewportSize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
|
||||
ImGui::Image((ImTextureRef)Prism::SceneRenderer::GetFinalColorBufferRendererID(), viewportSize, { 0, 1 }, { 1, 0 });
|
||||
|
||||
|
||||
auto windowSize = ImGui::GetWindowSize();
|
||||
ImVec2 minBound = ImGui::GetWindowPos();
|
||||
ImVec2 maxBound = { minBound.x + windowSize.x, minBound.y + windowSize.y };
|
||||
m_AllowViewportCameraEvents = ImGui::IsMouseHoveringRect(minBound, maxBound);
|
||||
|
||||
ImGui::End();
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
|
||||
void TestLayer::OnEvent(Prism::Event& e)
|
||||
{
|
||||
if (m_AllowViewportCameraEvents)
|
||||
m_Scene->GetCamera().OnEvent(e);
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
#include "Prism/Renderer/RenderPass.h"
|
||||
#include "Prism/Renderer/Shader.h"
|
||||
#include "Prism/Renderer/Texture.h"
|
||||
#include "Prism/Scene/Scene.h"
|
||||
|
||||
|
||||
class TestLayer : public Prism::Layer
|
||||
@ -29,16 +30,11 @@ private:
|
||||
glm::vec4 m_clearColor = glm::vec4(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
glm::vec4 m_TriangleColor = glm::vec4(1.0f);
|
||||
|
||||
Prism::Ref<Prism::RenderPass> m_GeoPass, m_FinalPass;
|
||||
Prism::Ref<Prism::Scene> m_Scene;
|
||||
Prism::Entity* m_MeshEntity;
|
||||
Prism::Ref<Prism::Material> m_MeshMaterial;
|
||||
|
||||
Prism::Ref<Prism::VertexArray> m_VertexArray;
|
||||
Prism::Ref<Prism::TextureCube> m_SkyBoxTextureCube, m_EnvironmentIrradiance;
|
||||
Prism::Ref<Prism::Shader> m_HDRShader, m_SkyBoxShader;
|
||||
Prism::Ref<Prism::Mesh> m_Mesh;
|
||||
Prism::Ref<Prism::MaterialInstance> m_MeshMaterial;
|
||||
Prism::Ref<Prism::Texture2D> m_BRDFLUT;
|
||||
|
||||
Prism::Camera m_Camera;
|
||||
bool m_AllowViewportCameraEvents = false;
|
||||
|
||||
float m_Exposure = 1.0f;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user