aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2025-08-18 05:09:57 +0200
committerhachem <im@hachem.wtf>2025-08-18 05:09:57 +0200
commit137a13e6f9a2b039b486b74747dfa83da30413aa (patch)
tree751ebe1e62db399a40da37003fdeb52c562fa8c9
parentd34925777dd4fac709096f1c18b7d886b43c15b2 (diff)
[add]: Load scenes from json
-rw-r--r--.gitignore1
-rw-r--r--.gitmodules3
m---------Vendor/json0
-rw-r--r--premake5.lua14
-rw-r--r--src/States/WorldBuilderState.cpp106
5 files changed, 75 insertions, 49 deletions
diff --git a/.gitignore b/.gitignore
index 8758a27..dace220 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@ config/
*.log
imgui.ini
+Scene.json
bin/
bin-int/
diff --git a/.gitmodules b/.gitmodules
index 09f0a03..5aa96f8 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -14,3 +14,6 @@
[submodule "Vendor/ImGuizmo"]
path = Vendor/ImGuizmo
url = https://github.com/CedricGuillemet/ImGuizmo.git
+[submodule "Vendor/json"]
+ path = Vendor/json
+ url = https://github.com/nlohmann/json.git
diff --git a/Vendor/json b/Vendor/json
new file mode 160000
+Subproject 52d3f6e034504b4097741b2da5b644a38ee273f
diff --git a/premake5.lua b/premake5.lua
index 3c245a9..bd10630 100644
--- a/premake5.lua
+++ b/premake5.lua
@@ -24,13 +24,14 @@ workspace "Donut"
outputdir = "%{cfg.buildcfg}-%{cfg.system}/%{prj.name}"
IncludeDir = {}
-IncludeDir["glm"] = "Vendor/glm"
-IncludeDir["glfw"] = "Vendor/glfw/include"
-IncludeDir["glad"] = "Vendor/glad/include"
-IncludeDir["imgui"] = "Vendor/imgui"
+IncludeDir["glm"] = "Vendor/glm"
+IncludeDir["glfw"] = "Vendor/glfw/include"
+IncludeDir["glad"] = "Vendor/glad/include"
+IncludeDir["imgui"] = "Vendor/imgui"
IncludeDir["imgui_backends"] = "Vendor/imgui/backends"
-IncludeDir["imguizmo"] = "Vendor/ImGuizmo"
-IncludeDir["toml11"] = "Vendor/toml11/include"
+IncludeDir["imguizmo"] = "Vendor/ImGuizmo"
+IncludeDir["toml11"] = "Vendor/toml11/include"
+IncludeDir["nlohmann"] = "Vendor/json/single_include"
group "Dependencies"
@@ -331,6 +332,7 @@ project "Donut"
"%{IncludeDir.imgui_backends}",
"%{IncludeDir.imguizmo}",
"%{IncludeDir.toml11}",
+ "%{IncludeDir.nlohmann}",
}
links
diff --git a/src/States/WorldBuilderState.cpp b/src/States/WorldBuilderState.cpp
index c5ed174..5fc25e8 100644
--- a/src/States/WorldBuilderState.cpp
+++ b/src/States/WorldBuilderState.cpp
@@ -17,13 +17,13 @@
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
+#include <nlohmann/json.hpp>
+
#include <numbers>
#include <fstream>
#include <sstream>
#include <limits>
-// TODO(Hachem): JSON Scene saving and loading
-
namespace Donut
{
void WorldBuilderState::OnEnter()
@@ -42,18 +42,7 @@ namespace Donut
m_Camera.SetElevation(static_cast<float>(std::numbers::pi) / 3.0f);
m_Camera.UpdateOrbital();
- Material defaultMaterial(glm::vec3(0.8f, 0.2f, 0.2f), 0.5f, 0.0f);
- Object sphere1(glm::vec3(-3.0f, 0.0f, 0.0f), 1.0f, defaultMaterial);
- m_Scene.objs.push_back(sphere1);
-
- Material material2(glm::vec3(0.2f, 0.8f, 0.2f), 0.3f, 0.0f);
- Object sphere2(glm::vec3(3.0f, 0.0f, 0.0f), 1.5f, material2);
- m_Scene.objs.push_back(sphere2);
-
- Material material3(glm::vec3(0.2f, 0.2f, 0.8f), 0.7f, 0.0f);
- Object sphere3(glm::vec3(0.0f, 2.0f, 0.0f), 0.8f, material3);
- m_Scene.objs.push_back(sphere3);
-
+ // Initialize rendering resources once
m_SphereShader = Ref<Shader>(Shader::Create("Assets/Shaders/Sphere.glsl"));
InitializeSphereGeometry();
@@ -516,20 +505,38 @@ namespace Donut
void WorldBuilderState::SaveScene()
{
- std::ofstream file("scene.txt");
+ nlohmann::json sceneData;
+ sceneData["objects"] = nlohmann::json::array();
- if (file.is_open())
+ for (const auto& obj : m_Scene.objs)
{
- file << m_Scene.objs.size() << std::endl;
- for (const auto& obj : m_Scene.objs)
+ nlohmann::json sphereData;
+ sphereData["position"] =
+ {
+ obj.m_Centre.x,
+ obj.m_Centre.y,
+ obj.m_Centre.z
+ };
+
+ sphereData["color"] =
{
- file << obj.m_Centre.x << " " << obj.m_Centre.y << " " << obj.m_Centre.z << " ";
- file << obj.m_Radius << " ";
- file << obj.m_Material.m_Color.x << " " << obj.m_Material.m_Color.y << " " << obj.m_Material.m_Color.z << " ";
- file << obj.m_Material.m_Specular << " " << obj.m_Material.m_Emission << std::endl;
- }
+ obj.m_Material.m_Color.x,
+ obj.m_Material.m_Color.y,
+ obj.m_Material.m_Color.z
+ };
+
+ sphereData["radius"] = obj.m_Radius;
+ sphereData["specular"] = obj.m_Material.m_Specular;
+ sphereData["emission"] = obj.m_Material.m_Emission;
+ sceneData["objects"].push_back(sphereData);
+ }
+
+ std::ofstream file("Scene.json");
+ if (file.is_open())
+ {
+ file << sceneData.dump(4);
file.close();
- DONUT_INFO("Scene saved to scene.txt");
+ DONUT_INFO("Scene saved to Scene.json");
}
else
DONUT_ERROR("Failed to save scene");
@@ -537,34 +544,47 @@ namespace Donut
void WorldBuilderState::LoadScene()
{
- std::ifstream file("scene.txt");
+ std::ifstream file("Scene.json");
if (file.is_open())
{
m_Scene.objs.clear();
m_SelectedObjectIndex = -1;
- size_t objectCount;
- file >> objectCount;
-
- for (size_t i = 0; i < objectCount; ++i)
+ nlohmann::json sceneData;
+ file >> sceneData;
+
+ if (sceneData.contains("objects"))
{
- glm::vec3 position;
- float radius;
- glm::vec3 color;
- float specular, emission;
-
- file >> position.x >> position.y >> position.z;
- file >> radius;
- file >> color.x >> color.y >> color.z;
- file >> specular >> emission;
-
- Material material(color, specular, emission);
- Object sphere(position, radius, material);
- m_Scene.objs.push_back(sphere);
+ for (const auto& sphereData : sceneData["objects"])
+ {
+ glm::vec3 position;
+ glm::vec3 color;
+ float radius;
+ float specular;
+ float emission;
+
+ auto posArray = sphereData["position"];
+ position.x = posArray[0].get<float>();
+ position.y = posArray[1].get<float>();
+ position.z = posArray[2].get<float>();
+
+ auto colorArray = sphereData["color"];
+ color.x = colorArray[0].get<float>();
+ color.y = colorArray[1].get<float>();
+ color.z = colorArray[2].get<float>();
+
+ radius = sphereData["radius"].get<float>();
+ specular = sphereData["specular"].get<float>();
+ emission = sphereData["emission"].get<float>();
+
+ Material material(color, specular, emission);
+ Object sphere(position, radius, material);
+ m_Scene.objs.push_back(sphere);
+ }
}
file.close();
- DONUT_INFO("Scene loaded from scene.txt");
+ DONUT_INFO("Scene loaded from Scene.json");
}
else
DONUT_ERROR("Failed to load scene");