Skip to content

Commit fd1453b

Browse files
author
Pier-Olivier Boulianne
committed
WIP: making SceneRenderer work and the Panel
1 parent 8460615 commit fd1453b

11 files changed

Lines changed: 494 additions & 59 deletions

File tree

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#pragma once
2+
3+
#include "Lux/Core/Ref.h"
4+
#include "Lux/Scene/Scene.h"
5+
#include "Lux/Project/Project.h"
6+
#include "Lux/Core/Events/Event.h"
7+
8+
namespace Lux {
9+
10+
class EditorPanel : public RefCounted
11+
{
12+
public:
13+
virtual ~EditorPanel() = default;
14+
15+
virtual void OnImGuiRender(bool& isOpen) = 0;
16+
virtual void OnEvent(Event& e) {}
17+
virtual void OnProjectChanged(const Ref<Project>& project){}
18+
virtual void SetSceneContext(const Ref<Scene>& context){}
19+
virtual void OnClose() {}
20+
};
21+
22+
}
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
#include "lpch.h"
2+
#include "PanelManager.h"
3+
#include "Lux/Utilities/FileSystem.h"
4+
5+
#include <yaml-cpp/yaml.h>
6+
7+
namespace Lux {
8+
9+
PanelManager::~PanelManager()
10+
{
11+
for (auto& map : m_Panels)
12+
map.clear();
13+
}
14+
15+
PanelData* PanelManager::GetPanelData(uint32_t panelID)
16+
{
17+
for (auto& panelMap : m_Panels)
18+
{
19+
if (panelMap.find(panelID) == panelMap.end())
20+
continue;
21+
22+
return &panelMap.at(panelID);
23+
}
24+
25+
return nullptr;
26+
}
27+
28+
const PanelData* PanelManager::GetPanelData(uint32_t panelID) const
29+
{
30+
for (auto& panelMap : m_Panels)
31+
{
32+
if (panelMap.find(panelID) == panelMap.end())
33+
continue;
34+
35+
return &panelMap.at(panelID);
36+
}
37+
38+
return nullptr;
39+
}
40+
41+
void PanelManager::RemovePanel(const char* strID)
42+
{
43+
uint32_t id = Hash::GenerateFNVHash(strID);
44+
for (auto& panelMap : m_Panels)
45+
{
46+
if (panelMap.find(id) == panelMap.end())
47+
continue;
48+
49+
panelMap.erase(id);
50+
return;
51+
}
52+
53+
LUX_CORE_ERROR_TAG("PanelManager", "Couldn't find panel with id '{0}'", strID);
54+
}
55+
56+
void PanelManager::OnImGuiRender()
57+
{
58+
for (auto& panelMap : m_Panels)
59+
{
60+
for (auto& [id, panelData] : panelMap)
61+
{
62+
bool closedThisFrame = false;
63+
64+
if (panelData.IsOpen)
65+
{
66+
panelData.Panel->OnImGuiRender(panelData.IsOpen);
67+
closedThisFrame = !panelData.IsOpen;
68+
}
69+
70+
if (closedThisFrame)
71+
{
72+
panelData.Panel->OnClose();
73+
Serialize();
74+
}
75+
}
76+
}
77+
}
78+
79+
void PanelManager::OnEvent(Event& e)
80+
{
81+
for (auto& panelMap : m_Panels)
82+
{
83+
for (auto& [id, panelData] : panelMap)
84+
panelData.Panel->OnEvent(e);
85+
}
86+
}
87+
88+
void PanelManager::SetSceneContext(const Ref<Scene>& context)
89+
{
90+
for (auto& panelMap : m_Panels)
91+
{
92+
for (auto& [id, panelData] : panelMap)
93+
panelData.Panel->SetSceneContext(context);
94+
}
95+
}
96+
97+
void PanelManager::OnProjectChanged(const Ref<Project>& project)
98+
{
99+
for (auto& panelMap : m_Panels)
100+
{
101+
for (auto& [id, panelData] : panelMap)
102+
panelData.Panel->OnProjectChanged(project);
103+
}
104+
105+
Deserialize();
106+
}
107+
108+
void PanelManager::Serialize() const
109+
{
110+
YAML::Emitter out;
111+
out << YAML::BeginMap;
112+
113+
out << YAML::Key << "Panels" << YAML::Value << YAML::BeginSeq;
114+
{
115+
for (size_t category = 0; category < m_Panels.size(); category++)
116+
{
117+
for (const auto& [panelID, panel] : m_Panels[category])
118+
{
119+
out << YAML::BeginMap;
120+
out << YAML::Key << "ID" << YAML::Value << panelID;
121+
out << YAML::Key << "Name" << YAML::Value << panel.Name;
122+
out << YAML::Key << "IsOpen" << YAML::Value << panel.IsOpen;
123+
out << YAML::EndMap;
124+
}
125+
}
126+
}
127+
out << YAML::EndSeq;
128+
129+
out << YAML::EndMap;
130+
131+
std::ofstream fout(FileSystem::GetPersistentStoragePath() / "EditorLayout.yaml");
132+
fout << out.c_str();
133+
fout.close();
134+
}
135+
136+
void PanelManager::Deserialize()
137+
{
138+
std::filesystem::path layoutPath = FileSystem::GetPersistentStoragePath() / "EditorLayout.yaml";
139+
if (!FileSystem::Exists(layoutPath))
140+
return;
141+
142+
std::ifstream stream(layoutPath);
143+
LUX_CORE_VERIFY(stream);
144+
std::stringstream ss;
145+
ss << stream.rdbuf();
146+
147+
YAML::Node data = YAML::Load(ss.str());
148+
if (!data["Panels"])
149+
{
150+
LUX_CONSOLE_LOG_ERROR("Failed to load EditorLayout.yaml from {} because the file appears to be corrupted!", layoutPath.parent_path().string());
151+
return;
152+
}
153+
154+
for (auto panelNode : data["Panels"])
155+
{
156+
PanelData* panelData = GetPanelData(panelNode["ID"].as<uint32_t>(0));
157+
158+
if (panelData == nullptr)
159+
continue;
160+
161+
panelData->IsOpen = panelNode["IsOpen"].as<bool>(panelData->IsOpen);
162+
}
163+
}
164+
165+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
#pragma once
2+
3+
#include "Lux/Core/Base.h"
4+
#include "Lux/Core/Log.h"
5+
#include "Lux/Core/Hash.h"
6+
7+
#include "EditorPanel.h"
8+
9+
#include <unordered_map>
10+
#include <utility>
11+
12+
namespace Lux {
13+
14+
struct PanelData
15+
{
16+
const char* ID = "";
17+
const char* Name = "";
18+
Ref<EditorPanel> Panel = nullptr;
19+
bool IsOpen = false;
20+
};
21+
22+
// NOTE(Peter): For now this just corresponds to what menu the panel will be listed in (in Hazelnut)
23+
enum class PanelCategory
24+
{
25+
Edit, View, _COUNT
26+
};
27+
28+
class PanelManager
29+
{
30+
public:
31+
PanelManager() = default;
32+
~PanelManager();
33+
34+
PanelData* GetPanelData(uint32_t panelID);
35+
const PanelData* GetPanelData(uint32_t panelID) const;
36+
37+
void RemovePanel(const char* strID);
38+
39+
void OnImGuiRender();
40+
41+
void OnEvent(Event& e);
42+
43+
void SetSceneContext(const Ref<Scene>& context);
44+
void OnProjectChanged(const Ref<Project>& project);
45+
46+
void Serialize() const;
47+
void Deserialize();
48+
49+
std::unordered_map<uint32_t, PanelData>& GetPanels(PanelCategory category) { return m_Panels[(size_t)category]; }
50+
const std::unordered_map<uint32_t, PanelData>& GetPanels(PanelCategory category) const { return m_Panels[(size_t)category]; }
51+
52+
public:
53+
template<typename TPanel>
54+
Ref<TPanel> AddPanel(PanelCategory category, const PanelData& panelData)
55+
{
56+
static_assert(std::is_base_of<EditorPanel, TPanel>::value, "PanelManager::AddPanel requires TPanel to inherit from EditorPanel");
57+
58+
auto& panelMap = m_Panels[(size_t)category];
59+
60+
uint32_t id = Hash::GenerateFNVHash(panelData.ID);
61+
if (panelMap.find(id) != panelMap.end())
62+
{
63+
LUX_CORE_ERROR_TAG("PanelManager", "A panel with the id '{0}' has already been added.", panelData.ID);
64+
return nullptr;
65+
}
66+
67+
panelMap[id] = panelData;
68+
return panelData.Panel.As<TPanel>();
69+
}
70+
71+
template<typename TPanel, typename... TArgs>
72+
Ref<TPanel> AddPanel(PanelCategory category, const char* strID, bool isOpenByDefault, TArgs&&... args)
73+
{
74+
return AddPanel<TPanel>(category, PanelData{ strID, strID, Ref<TPanel>::Create(std::forward<TArgs>(args)...), isOpenByDefault });
75+
}
76+
77+
template<typename TPanel, typename... TArgs>
78+
Ref<TPanel> AddPanel(PanelCategory category, const char* strID, const char* displayName, bool isOpenByDefault, TArgs&&... args)
79+
{
80+
return AddPanel<TPanel>(category, PanelData{ strID, displayName, Ref<TPanel>::Create(std::forward<TArgs>(args)...), isOpenByDefault });
81+
}
82+
83+
template<typename TPanel>
84+
Ref<TPanel> GetPanel(const char* strID)
85+
{
86+
static_assert(std::is_base_of<EditorPanel, TPanel>::value, "PanelManager::AddPanel requires TPanel to inherit from EditorPanel");
87+
88+
uint32_t id = Hash::GenerateFNVHash(strID);
89+
90+
for (const auto& panelMap : m_Panels)
91+
{
92+
if (panelMap.find(id) == panelMap.end())
93+
continue;
94+
95+
return panelMap.at(id).Panel.As<TPanel>();
96+
}
97+
98+
LUX_CORE_ERROR_TAG("PanelManager", "Couldn't find panel with id '{0}'", strID);
99+
return nullptr;
100+
}
101+
102+
private:
103+
std::array<std::unordered_map<uint32_t, PanelData>, (size_t)PanelCategory::_COUNT> m_Panels;
104+
};
105+
106+
}

Core/Source/Lux/Renderer/Renderer.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,8 @@ namespace Lux {
364364
Renderer::GetShaderLibrary()->Load("Resources/Shaders/HazelPBR_Static.glsl");
365365
Renderer::GetShaderLibrary()->Load("Resources/Shaders/HazelPBR_Transparent.glsl");
366366
Renderer::GetShaderLibrary()->Load("Resources/Shaders/HazelPBR_Anim.glsl");
367+
Renderer::GetShaderLibrary()->Load("Resources/Shaders/LuxPBR_Static.glsl");
368+
Renderer::GetShaderLibrary()->Load("Resources/Shaders/LuxPBR_Transparent.glsl");
367369
Renderer::GetShaderLibrary()->Load("Resources/Shaders/Grid.glsl");
368370
Renderer::GetShaderLibrary()->Load("Resources/Shaders/Wireframe.glsl");
369371
Renderer::GetShaderLibrary()->Load("Resources/Shaders/Wireframe_Anim.glsl");

Core/Source/Lux/Renderer/SceneRenderer.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ namespace Lux {
133133
FramebufferSpecification fbSpec;
134134
fbSpec.Width = m_ViewportWidth;
135135
fbSpec.Height = m_ViewportHeight;
136-
fbSpec.Attachments = { ImageFormat::Depth };
136+
fbSpec.Attachments = { ImageFormat::DEPTH32FSTENCIL8UINT };
137137
fbSpec.DepthClearValue = 0.0f;
138138
fbSpec.ClearDepthOnLoad = true;
139139
fbSpec.DebugName = "PreDepth";
@@ -190,7 +190,7 @@ namespace Lux {
190190
// Opaque PBR pipeline
191191
PipelineSpecification pipelineSpec;
192192
pipelineSpec.DebugName = "PBR-Static";
193-
pipelineSpec.Shader = Renderer::GetShaderLibrary()->Get("HazelPBR_Static");
193+
pipelineSpec.Shader = Renderer::GetShaderLibrary()->Get("LuxPBR_Static");
194194
pipelineSpec.TargetFramebuffer = loadFB;
195195
pipelineSpec.Layout = vertexLayout;
196196
pipelineSpec.DepthOperator = DepthCompareOperator::Equal; // rely on pre-depth
@@ -199,7 +199,7 @@ namespace Lux {
199199

200200
// Transparent PBR pipeline (alpha-blend, depth-test but no pre-depth Equal trick)
201201
pipelineSpec.DebugName = "PBR-Transparent";
202-
pipelineSpec.Shader = Renderer::GetShaderLibrary()->Get("HazelPBR_Transparent");
202+
pipelineSpec.Shader = Renderer::GetShaderLibrary()->Get("LuxPBR_Transparent");
203203
pipelineSpec.DepthOperator = DepthCompareOperator::GreaterOrEqual;
204204
pipelineSpec.DepthWrite = false;
205205
m_TransparentGeometryPipeline = Pipeline::Create(pipelineSpec);

Core/Source/Lux/Renderer/SceneRenderer.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ namespace Lux {
157157
Ref<Image2D> GetFinalPassImage();
158158
Ref<RenderPass> GetFinalRenderPass();
159159
Ref<Framebuffer> GetExternalCompositeFramebuffer() { return m_CompositingFramebuffer; }
160+
Ref<RenderCommandBuffer> GetCommandBuffer() { return m_CommandBuffer; }
160161

161162
Ref<Renderer2D> GetRenderer2D() { return m_Renderer2D; }
162163
Ref<DebugRenderer> GetDebugRenderer() { return m_DebugRenderer; }
@@ -281,6 +282,13 @@ namespace Lux {
281282
glm::mat4 ViewProjection[4];
282283
} m_ShadowUB;
283284

285+
struct UBSpotShadow
286+
{
287+
glm::mat4 ViewProjection[16];
288+
uint32_t Count = 0;
289+
glm::vec3 Padding{};
290+
};
291+
284292
struct UBRendererData
285293
{
286294
glm::vec4 CascadeSplits;
@@ -303,6 +311,30 @@ namespace Lux {
303311
PointLight PointLights[256]{};
304312
} m_PointLightsUB;
305313

314+
struct SpotLight
315+
{
316+
glm::vec3 Position = { 0.0f, 0.0f, 0.0f };
317+
float Intensity = 0.0f;
318+
319+
glm::vec3 Direction = { 0.0f, -1.0f, 0.0f };
320+
float Range = 25.0f;
321+
322+
glm::vec3 Radiance = { 1.0f, 1.0f, 1.0f };
323+
float Angle = 45.0f;
324+
325+
float AngleAttenuation = 1.0f;
326+
float Falloff = 1.0f;
327+
bool CastsShadows = false;
328+
char Padding[3] = { 0, 0, 0 };
329+
};
330+
331+
struct UBSpotLights
332+
{
333+
uint32_t Count = 0;
334+
glm::vec3 Padding{};
335+
SpotLight SpotLights[256]{};
336+
} m_SpotLightsUB;
337+
306338
// ── Private data ──────────────────────────────────────────────────────
307339

308340
Ref<Scene> m_Scene;
@@ -328,8 +360,10 @@ namespace Lux {
328360
Ref<UniformBufferSet> m_UBSCamera;
329361
Ref<UniformBufferSet> m_UBSScene;
330362
Ref<UniformBufferSet> m_UBSShadow;
363+
Ref<UniformBufferSet> m_UBSSpotShadow;
331364
Ref<UniformBufferSet> m_UBSRendererData;
332365
Ref<UniformBufferSet> m_UBSPointLights;
366+
Ref<UniformBufferSet> m_UBSSpotLights;
333367

334368
Ref<StorageBufferSet> m_SBSInstanceTransforms; // TransformVertexData[]
335369
Ref<StorageBufferSet> m_SBSObjectIndexes; // uint32_t[] – maps draw → transform

0 commit comments

Comments
 (0)