aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhnOsmium0001 <[email protected]>2022-04-18 20:59:57 -0700
committerhnOsmium0001 <[email protected]>2022-04-18 20:59:57 -0700
commit2a5234a512c19582d261a7ccb692fc634dcb74f0 (patch)
tree0f52925373115319a9ad7d03600e566c59a86566
parentf77e73c01a15426bcc6e3d7fe5826d2a741fed38 (diff)
Migrate Material to Ires
-rw-r--r--assets/Ires/M_BasicWall.json1
-rw-r--r--assets/Ires/M_Default.json1
-rw-r--r--assets/Ires/M_Player.json1
-rw-r--r--assets/Ires/SS_Player.json1
-rw-r--r--assets/Materials/M_BasicWalls.json1
-rw-r--r--assets/Materials/M_Default.json1
-rw-r--r--assets/Materials/M_Player.json1
-rw-r--r--source/EditorCore.cpp177
-rw-r--r--source/EditorCore.hpp2
-rw-r--r--source/EditorUtils.cpp7
-rw-r--r--source/EditorUtils.hpp2
-rw-r--r--source/Ires.cpp45
-rw-r--r--source/Ires.hpp4
-rw-r--r--source/Macros.hpp6
-rw-r--r--source/Material.cpp215
-rw-r--r--source/Material.hpp62
-rw-r--r--source/main.cpp3
17 files changed, 175 insertions, 355 deletions
diff --git a/assets/Ires/M_BasicWall.json b/assets/Ires/M_BasicWall.json
new file mode 100644
index 0000000..95cc7b9
--- /dev/null
+++ b/assets/Ires/M_BasicWall.json
@@ -0,0 +1 @@
+{"Type":"IresMaterial","Uid":[10768502134278852816,15014213992450765275],"Value":{"ShaderName":"S_Default","Fields":[{"Name":"taint","Type":"Vector","Value":[0.37144365906715393,0.5479920506477356,0.5784313678741455,1.0]}]}} \ No newline at end of file
diff --git a/assets/Ires/M_Default.json b/assets/Ires/M_Default.json
new file mode 100644
index 0000000..daa1a60
--- /dev/null
+++ b/assets/Ires/M_Default.json
@@ -0,0 +1 @@
+{"Type":"IresMaterial","Uid":[12204622401017240396,7687764162748902358],"Value":{"ShaderName":"S_Default","Fields":[{"Name":"taint","Type":"Vector","Value":[1.0,1.0,1.0,0.0]}]}} \ No newline at end of file
diff --git a/assets/Ires/M_Player.json b/assets/Ires/M_Player.json
new file mode 100644
index 0000000..4065cf8
--- /dev/null
+++ b/assets/Ires/M_Player.json
@@ -0,0 +1 @@
+{"Type":"IresMaterial","Uid":[9758347138487553657,17909177141494883507],"Value":{"ShaderName":"S_Default","Fields":[{"Name":"taint","Type":"Vector","Value":[1.0,1.0,1.0,0.0]}]}} \ No newline at end of file
diff --git a/assets/Ires/SS_Player.json b/assets/Ires/SS_Player.json
new file mode 100644
index 0000000..b413317
--- /dev/null
+++ b/assets/Ires/SS_Player.json
@@ -0,0 +1 @@
+{"Type":"IresSpritesheet","Uid":[15827420425478528881,8130926596581515031],"Value":{"SpriteSheet":"S_Player.png","WSplit":6,"HSplit":4}} \ No newline at end of file
diff --git a/assets/Materials/M_BasicWalls.json b/assets/Materials/M_BasicWalls.json
deleted file mode 100644
index 209dcf6..0000000
--- a/assets/Materials/M_BasicWalls.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Name":"M_BasicWalls","ShaderName":"S_Default","Fields":[{"Name":"taint","Type":"Vector","Value":[0.37144365906715393,0.5479920506477356,0.5784313678741455,1.0]}]} \ No newline at end of file
diff --git a/assets/Materials/M_Default.json b/assets/Materials/M_Default.json
deleted file mode 100644
index ad09830..0000000
--- a/assets/Materials/M_Default.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Name":"M_Default","ShaderName":"S_Default","Fields":[{"Name":"taint","Type":"Vector","Value":[1.0,1.0,1.0,1.0]}]} \ No newline at end of file
diff --git a/assets/Materials/M_Player.json b/assets/Materials/M_Player.json
deleted file mode 100644
index d2b126d..0000000
--- a/assets/Materials/M_Player.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Name":"M_Player","ShaderName":"S_Default","Fields":[{"Name":"taint","Type":"Vector","Value":[1.0,1.0,1.0,0.0]}]} \ No newline at end of file
diff --git a/source/EditorCore.cpp b/source/EditorCore.cpp
index 11eea8a..1be6418 100644
--- a/source/EditorCore.cpp
+++ b/source/EditorCore.cpp
@@ -69,9 +69,6 @@ void EditorContentBrowser::Show(bool* open) {
if (ImGui::Selectable("Shaders", mPane == P_Shader)) {
mPane = P_Shader;
}
- if (ImGui::Selectable("Materials", mPane == P_Material)) {
- mPane = P_Material;
- }
if (ImGui::Selectable("Ires", mPane == P_Ires)) {
mPane = P_Ires;
}
@@ -117,49 +114,6 @@ void EditorContentBrowser::Show(bool* open) {
}
} break;
- case P_Material: {
- if (ImGui::Button("New")) {
- int n = std::rand();
- auto mat = new Material("Unnamed Material " + std::to_string(n));
- auto guard = GuardDeletion(mat);
- auto [DISCARD, inserted] = MaterialManager::instance->SaveMaterial(mat);
- if (inserted) {
- guard.Dismiss();
- } else {
- ImGui::AddNotification(ImGuiToast(ImGuiToastType_Error, "Failed to create material."));
- }
- }
- ImGui::SameLine();
- if (ImGui::Button("Refresh")) {
- // TODO
- }
- ImGui::SameLine();
- if (ImGui::Button("Save all")) {
- auto& mats = MaterialManager::instance->GetMaterials();
- for (auto&& [DISCARD, mat] : mats) {
- mat->SaveToFile(mat->GetDesignatedPath());
- }
- }
-
- auto& mats = MaterialManager::instance->GetMaterials();
- for (auto it = mats.begin(); it != mats.end(); ++it) {
- auto mat = it->second.Get();
- auto& name = mat->GetName();
-
- bool selected = mInspector->selectedItPtr == mat;
- if (ImGui::Selectable(name.c_str(), selected)) {
- mInspector->SelectTarget(EditorInspector::ITT_Material, mat);
- }
-
- if (ImGui::BeginDragDropSource()) {
- // Reason: intentionally using pointer as payload
- ImGui::SetDragDropPayload(BRUSSEL_TAG_Material, &mat, sizeof(mat)); // NOLINT(bugprone-sizeof-expression)
- ImGui::Text("Material '%s'", name.c_str());
- ImGui::EndDragDropSource();
- }
- }
- } break;
-
case P_Ires: {
auto itt = mInspector->selectedItt;
auto itPtr = mInspector->selectedItPtr;
@@ -311,20 +265,6 @@ void ShowShaderName(const Shader* shader) {
ImGui::TextUnformatted("Shader: <null>");
}
}
-
-void ShowMaterialName(const Material* material) {
- if (material) {
- auto& name = material->GetName();
- bool isAnnoymous = name.empty();
- if (isAnnoymous) {
- ImGui::Text("Material: <annoymous at %p>", (void*)material);
- } else {
- ImGui::Text("Material: %s", name.c_str());
- }
- } else {
- ImGui::TextUnformatted("Material: <null>");
- }
-}
} // namespace ProjectBrussel_UNITY_ID
EditorInstance::EditorInstance(App* app, GameWorld* world)
@@ -361,10 +301,6 @@ void EditorInstance::Show() {
ShowInspector(static_cast<Shader*>(mEdInspector.selectedItPtr));
} break;
- case EditorInspector::ITT_Material: {
- ShowInspector(static_cast<Material*>(mEdInspector.selectedItPtr));
- } break;
-
case EditorInspector::ITT_Ires: {
auto ires = static_cast<IresObject*>(mEdInspector.selectedItPtr);
ShowInspector(ires);
@@ -433,119 +369,6 @@ void EditorInstance::ShowInspector(Shader* shader) {
}
}
-void EditorInstance::ShowInspector(Material* material) {
- using namespace Tags;
- using namespace ProjectBrussel_UNITY_ID;
-
- EaMaterial* attachment;
- if (auto ea = material->GetEditorAttachment()) {
- attachment = static_cast<EaMaterial*>(ea);
- } else {
- attachment = new EaMaterial();
- material->SetEditorAttachment(attachment);
- }
-
- auto& name = material->GetName();
- bool isAnnoymous = name.empty();
- if (isAnnoymous) {
- ImGui::Text("<Annoymous Material at %p>", (void*)(&material));
- } else {
- if (attachment->isEditingName) {
- bool save = false;
- save |= ImGui::InputText("##", &attachment->editingScratch, ImGuiInputTextFlags_EnterReturnsTrue);
- ImGui::SameLine();
- save |= ImGui::Button("Save");
- if (save) {
- bool success = MaterialManager::instance->RenameMaterial(material, attachment->editingScratch);
- if (success) {
- attachment->isEditingName = false;
- }
- }
- ImGui::SameLine();
- if (ImGui::Button("Cancel")) {
- attachment->isEditingName = false;
- }
- } else {
- // NOTE: ReadOnly shouldn't write any data into the buffer
- ImGui::InputText("##", material->mName.data(), name.size() + 1, ImGuiInputTextFlags_ReadOnly);
- ImGui::SameLine();
- if (ImGui::Button("Edit")) {
- attachment->editingScratch = name; // Copy
- attachment->isEditingName = true;
- }
- }
- }
-
- auto shader = material->GetShader();
- ShowShaderName(shader);
- if (ImGui::BeginDragDropTarget()) {
- if (auto payload = ImGui::AcceptDragDropPayload(BRUSSEL_TAG_Shader)) {
- auto shader = *static_cast<Shader* const*>(payload->Data);
- material->SetShader(shader);
- }
- ImGui::EndDragDropTarget();
- }
- ImGui::SameLine();
- if (ImGui::Button("GoTo", shader == nullptr)) {
- mEdInspector.SelectTarget(EditorInspector::ITT_Shader, shader);
- }
-
- if (!shader) return;
- auto& info = shader->GetInfo();
-
- if (ImGui::Button("Reload", isAnnoymous)) {
- material->LoadFromFile(material->GetDesignatedPath());
- }
- ImGui::SameLine();
- if (ImGui::Button("Save", isAnnoymous)) {
- material->SaveToFile(material->GetDesignatedPath());
- }
-
- for (auto& field : material->mBoundScalars) {
- auto& decl = static_cast<ShaderMathVariable&>(*info.uniforms[field.infoUniformIndex]);
- decl.ShowInfo();
-
- ImGui::Indent();
- switch (decl.scalarType) {
- case GL_FLOAT: ImGui::InputFloat("##", &field.floatValue); break;
- case GL_INT: ImGui::InputInt("##", &field.intValue); break;
- // TODO proper uint edit?
- case GL_UNSIGNED_INT: ImGui::InputInt("##", (int32_t*)(&field.uintValue), 0, std::numeric_limits<int32_t>::max()); break;
- default: ImGui::TextUnformatted("Unsupported scalar type"); break;
- }
- ImGui::Unindent();
- }
- for (auto& field : material->mBoundVectors) {
- auto& decl = static_cast<ShaderMathVariable&>(*info.uniforms[field.infoUniformIndex]);
- decl.ShowInfo();
-
- ImGui::Indent();
- switch (decl.semantic) {
- case VES_Color1:
- case VES_Color2: {
- ImGui::ColorEdit4("##", field.value);
- } break;
-
- default: {
- ImGui::InputFloat4("##", field.value);
- } break;
- }
- ImGui::Unindent();
- }
- for (auto& field : material->mBoundMatrices) {
- auto& decl = static_cast<ShaderMathVariable&>(*info.uniforms[field.infoUniformIndex]);
- decl.ShowInfo();
-
- // TODO
- }
- for (auto& field : material->mBoundTextures) {
- auto& decl = static_cast<ShaderSamplerVariable&>(*info.uniforms[field.infoUniformIndex]);
- decl.ShowInfo();
-
- // TODO
- }
-}
-
void EditorInstance::ShowInspector(IresObject* ires) {
ires->ShowEditor(*this);
}
diff --git a/source/EditorCore.hpp b/source/EditorCore.hpp
index 2216de5..84e42d0 100644
--- a/source/EditorCore.hpp
+++ b/source/EditorCore.hpp
@@ -14,7 +14,6 @@ struct EditorInspector {
enum TargetType {
ITT_GameObject,
ITT_Shader,
- ITT_Material,
ITT_Ires,
ITT_None,
};
@@ -32,7 +31,6 @@ private:
enum Pane {
P_Settings,
P_Shader,
- P_Material,
P_Ires,
};
diff --git a/source/EditorUtils.cpp b/source/EditorUtils.cpp
index 4863301..488d345 100644
--- a/source/EditorUtils.cpp
+++ b/source/EditorUtils.cpp
@@ -161,6 +161,13 @@ bool ImGui::Splitter(bool splitVertically, float thickness, float* size1, float*
return held;
}
+void ImGui ::AddUnderLine(ImColor col) {
+ auto min = ImGui::GetItemRectMin();
+ auto max = ImGui::GetItemRectMax();
+ min.y = max.y;
+ ImGui::GetWindowDrawList()->AddLine(min, max, col, 1.0f);
+}
+
float Utils::CalcImageHeight(glm::vec2 original, int targetWidth) {
// Xorig / Yorig = Xnew / Ynew
// Ynew = Xnew * Yorig / Xorig
diff --git a/source/EditorUtils.hpp b/source/EditorUtils.hpp
index d6483da..6e152f6 100644
--- a/source/EditorUtils.hpp
+++ b/source/EditorUtils.hpp
@@ -31,6 +31,8 @@ bool ColorPicker4(const char* label, RgbaColor* color, ImGuiColorEditFlags flags
bool Splitter(bool splitVertically, float thickness, float* size1, float* size2, float minSize1, float minSize2, float splitterLongAxisSize = -1.0f);
+void AddUnderLine(ImColor col);
+
} // namespace ImGui
namespace Utils {
diff --git a/source/Ires.cpp b/source/Ires.cpp
index dde4ace..6b161d4 100644
--- a/source/Ires.cpp
+++ b/source/Ires.cpp
@@ -1,7 +1,10 @@
#include "Ires.hpp"
#include "AppConfig.hpp"
+#include "EditorCore.hpp"
#include "EditorUtils.hpp"
+#include "Macros.hpp"
+#include "Material.hpp"
#include "RapidJsonHelper.hpp"
#include "ScopeGuard.hpp"
#include "Sprite.hpp"
@@ -26,6 +29,7 @@ IresObject::IresObject(Kind kind)
std::string_view IresObject::ToString(Kind kind) {
switch (kind) {
case KD_Texture: return BRUSSEL_TAG_PREFIX_Ires "Texture"sv;
+ case KD_Material: return BRUSSEL_TAG_PREFIX_Ires "Material"sv;
case KD_SpriteFiles: return BRUSSEL_TAG_PREFIX_Ires "SpriteFiles"sv;
case KD_Spritesheet: return BRUSSEL_TAG_PREFIX_Ires "Spritesheet"sv;
case KD_COUNT: break;
@@ -35,6 +39,7 @@ std::string_view IresObject::ToString(Kind kind) {
IresObject::Kind IresObject::FromString(std::string_view name) {
if (name == BRUSSEL_TAG_PREFIX_Ires "Texture"sv) return KD_Texture;
+ if (name == BRUSSEL_TAG_PREFIX_Ires "Material"sv) return KD_Material;
if (name == BRUSSEL_TAG_PREFIX_Ires "SpriteFiles"sv) return KD_SpriteFiles;
if (name == BRUSSEL_TAG_PREFIX_Ires "Spritesheet"sv) return KD_Spritesheet;
return KD_COUNT;
@@ -43,6 +48,7 @@ IresObject::Kind IresObject::FromString(std::string_view name) {
std::unique_ptr<IresObject> IresObject::Create(Kind kind) {
switch (kind) {
case KD_Texture: return std::make_unique<IresTexture>();
+ case KD_Material: return std::make_unique<IresMaterial>();
case KD_SpriteFiles: return std::make_unique<IresSpriteFiles>();
case KD_Spritesheet: return std::make_unique<IresSpritesheet>();
case KD_COUNT: break;
@@ -62,6 +68,40 @@ void IresObject::SetName(std::string name) {
}
}
+void IresObject::ShowName() const {
+ if (IsAnnoymous()) {
+ ImGui::Text("<annoymous %p>", (void*)this);
+ } else {
+ ImGui::Text("%s", mName.c_str());
+ }
+}
+
+void IresObject::ShowFullName() const {
+ if (IsAnnoymous()) {
+ ImGui::Text("<annoymous %p> (%lx-%lx)", (void*)this, mUid.upper, mUid.lower);
+ } else {
+ ImGui::Text("%s (%lx-%lx)", mName.c_str(), mUid.upper, mUid.lower);
+ }
+}
+
+void IresObject::ShowReference(EditorInstance& editor) {
+ ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_ButtonHovered]);
+ if (IsAnnoymous()) {
+ ImGui::Text("<annoymous %p>", (void*)this);
+ } else {
+ ImGui::Text("%s", mName.c_str());
+ }
+ ImGui::PopStyleColor();
+ if (ImGui::IsItemHovered()) {
+ if (ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
+ editor.GetInspector().SelectTarget(EditorInspector::ITT_Ires, this);
+ }
+ ImGui::AddUnderLine(ImGui::GetStyle().Colors[ImGuiCol_ButtonHovered]);
+ } else {
+ ImGui::AddUnderLine(ImGui::GetStyle().Colors[ImGuiCol_Button]);
+ }
+}
+
void IresObject::ShowEditor(EditorInstance& editor) {
ImGui::Text("%s", ToString(mKind).data());
@@ -135,7 +175,10 @@ void IresManager::DiscoverFiles(const fs::path& dir) {
continue;
}
- Load(item.path());
+ auto ires = Load(item.path());
+ if (!ires) {
+ fprintf(stderr, "Failed to load Ires at '" PLATFORM_PATH_STR "'.", item.path().c_str());
+ }
}
}
diff --git a/source/Ires.hpp b/source/Ires.hpp
index f821d87..b6e351c 100644
--- a/source/Ires.hpp
+++ b/source/Ires.hpp
@@ -21,6 +21,7 @@ class IresObject : public RefCounted {
public:
enum Kind {
KD_Texture,
+ KD_Material,
KD_SpriteFiles,
KD_Spritesheet,
KD_COUNT,
@@ -48,6 +49,9 @@ public:
void SetName(std::string name);
const Uid& GetUid() const { return mUid; }
+ void ShowName() const;
+ void ShowFullName() const;
+ virtual void ShowReference(EditorInstance& editor);
virtual void ShowEditor(EditorInstance& editor);
EditorAttachment* GetEditorAttachment() const { return mEditorAttachment.get(); }
diff --git a/source/Macros.hpp b/source/Macros.hpp
index 9f25cc4..b5d05fa 100644
--- a/source/Macros.hpp
+++ b/source/Macros.hpp
@@ -21,3 +21,9 @@
#else
# define UNREACHABLE
#endif
+
+#if _WIN32
+# define PLATFORM_PATH_STR "%ls"
+#else
+# define PLATFORM_PATH_STR "%s"
+#endif
diff --git a/source/Material.cpp b/source/Material.cpp
index 5e42b96..0031ef8 100644
--- a/source/Material.cpp
+++ b/source/Material.cpp
@@ -1,28 +1,23 @@
#include "Material.hpp"
#include "AppConfig.hpp"
+#include "EditorCore.hpp"
+#include "EditorUtils.hpp"
#include "RapidJsonHelper.hpp"
#include "ScopeGuard.hpp"
#include "Utils.hpp"
+#include <imgui.h>
#include <rapidjson/document.h>
-#include <rapidjson/filereadstream.h>
-#include <rapidjson/filewritestream.h>
-#include <rapidjson/writer.h>
#include <cstdlib>
#include <cstring>
#include <utility>
-namespace fs = std::filesystem;
using namespace std::literals;
Material::Material() {
}
-Material::Material(std::string name)
- : mName(std::move(name)) {
-}
-
namespace ProjectBrussel_UNITY_ID {
bool TryFindShaderId(Shader* shader, std::string_view name, int& out) {
auto& info = shader->GetInfo();
@@ -268,14 +263,6 @@ void Material::SetShader(Shader* shader) {
}
}
-const std::string& Material::GetName() const {
- return mName;
-}
-
-bool Material::IsAnnoymous() const {
- return mName.empty();
-}
-
bool Material::IsValid() const {
return mShader != nullptr;
}
@@ -332,31 +319,19 @@ void Material::UseUniforms() const {
}
}
-void Material::GetDesignatedPath(char* buffer, int bufferSize) {
- snprintf(buffer, bufferSize, "%s/Materials/%s.json", AppConfig::assetDir.c_str(), mName.c_str());
-}
-
-fs::path Material::GetDesignatedPath() {
- return AppConfig::assetDirPath / "Materials" / fs::path(mName).replace_extension(".json");
-}
-
-bool Material::SaveToFile(const fs::path& filePath) const {
+bool Material::Write(rapidjson::Value& value, rapidjson::Document& root) const {
using namespace ProjectBrussel_UNITY_ID;
- if (IsAnnoymous()) return false;
if (!IsValid()) return false;
- auto& info = mShader->GetInfo();
-
- rapidjson::Document root(rapidjson::kObjectType);
+ auto& shaderInfo = mShader->GetInfo();
- root.AddMember("Name", mName, root.GetAllocator());
- root.AddMember("ShaderName", mShader->GetName(), root.GetAllocator());
+ value.AddMember("ShaderName", mShader->GetName(), root.GetAllocator());
rapidjson::Value fields(rapidjson::kArrayType);
for (auto& scalar : mBoundScalars) {
rapidjson::Value rvField(rapidjson::kObjectType);
- rvField.AddMember("Name", info.uniforms[scalar.infoUniformIndex]->name, root.GetAllocator());
+ rvField.AddMember("Name", shaderInfo.uniforms[scalar.infoUniformIndex]->name, root.GetAllocator());
rvField.AddMember("Type", "Scalar", root.GetAllocator());
switch (scalar.actualType) {
case GL_FLOAT: rvField.AddMember("Value", scalar.floatValue, root.GetAllocator()); break;
@@ -367,14 +342,14 @@ bool Material::SaveToFile(const fs::path& filePath) const {
}
for (auto& vector : mBoundVectors) {
rapidjson::Value rvField(rapidjson::kObjectType);
- rvField.AddMember("Name", info.uniforms[vector.infoUniformIndex]->name, root.GetAllocator());
+ rvField.AddMember("Name", shaderInfo.uniforms[vector.infoUniformIndex]->name, root.GetAllocator());
rvField.AddMember("Type", "Vector", root.GetAllocator());
rvField.AddMember("Value", MakeVectorJson(vector, root).Move(), root.GetAllocator());
fields.PushBack(rvField, root.GetAllocator());
}
for (auto& matrix : mBoundMatrices) {
rapidjson::Value rvField(rapidjson::kObjectType);
- rvField.AddMember("Name", info.uniforms[matrix.infoUniformIndex]->name, root.GetAllocator());
+ rvField.AddMember("Name", shaderInfo.uniforms[matrix.infoUniformIndex]->name, root.GetAllocator());
rvField.AddMember("Type", "Matrix", root.GetAllocator());
rvField.AddMember("Value", MakeMatrixJson(matrix, root).Move(), root.GetAllocator());
fields.PushBack(rvField, root.GetAllocator());
@@ -382,45 +357,16 @@ bool Material::SaveToFile(const fs::path& filePath) const {
for (auto& texture : mBoundTextures) {
// TODO
}
- root.AddMember("Fields", fields, root.GetAllocator());
-
- auto file = Utils::OpenCstdioFile(filePath, Utils::WriteTruncate);
- if (!file) return false;
- DEFER { fclose(file); };
-
- char writerBuffer[65536];
- rapidjson::FileWriteStream stream(file, writerBuffer, sizeof(writerBuffer));
- rapidjson::Writer<rapidjson::FileWriteStream> writer(stream);
- root.Accept(writer);
+ value.AddMember("Fields", fields, root.GetAllocator());
return true;
}
-bool Material::LoadFromFile(const fs::path& filePath) {
+bool Material::Read(const rapidjson::Value& value) {
using namespace ProjectBrussel_UNITY_ID;
- auto file = Utils::OpenCstdioFile(filePath, Utils::Read);
- if (!file) return false;
- DEFER { fclose(file); };
-
- char readerBuffer[65536];
- rapidjson::FileReadStream stream(file, readerBuffer, sizeof(readerBuffer));
-
- rapidjson::Document root;
- root.ParseStream(stream);
-
- // TODO update reference in MaterialManager
{
- auto rvName = rapidjson::GetProperty(root, rapidjson::kStringType, "Name"sv);
- if (rvName) {
- mName = rapidjson::AsString(*rvName);
- } else {
- mName = "";
- }
- }
-
- {
- auto rvShaderName = rapidjson::GetProperty(root, rapidjson::kStringType, "ShaderName"sv);
+ auto rvShaderName = rapidjson::GetProperty(value, rapidjson::kStringType, "ShaderName"sv);
if (!rvShaderName) return false;
auto shader = ShaderManager::instance->FindShader(rapidjson::AsStringView(*rvShaderName));
@@ -430,7 +376,7 @@ bool Material::LoadFromFile(const fs::path& filePath) {
}
auto& shaderInfo = mShader->GetInfo();
- auto fields = rapidjson::GetProperty(root, rapidjson::kArrayType, "Fields"sv);
+ auto fields = rapidjson::GetProperty(value, rapidjson::kArrayType, "Fields"sv);
if (!fields) return false;
for (auto& rvField : fields->GetArray()) {
@@ -483,73 +429,104 @@ bool Material::LoadFromFile(const fs::path& filePath) {
return true;
}
-void MaterialManager::DiscoverMaterials() {
- mMaterials.clear();
-
- auto path = AppConfig::assetDirPath / "Materials";
- if (!fs::exists(path)) {
- return;
- }
+IresMaterial::IresMaterial()
+ : IresObject(KD_Material)
+ , mInstance(new Material()) {
+}
- for (auto& item : fs::directory_iterator(path)) {
- if (item.is_regular_file()) {
- RcPtr mat(new Material());
- if (!mat->LoadFromFile(item.path())) {
- continue;
- }
+Material* IresMaterial::GetInstance() const {
+ return mInstance.Get();
+}
- auto& matName = mat->GetName();
- mMaterials.try_emplace(matName, std::move(mat));
- }
- }
+void IresMaterial::InvalidateInstance() {
+ mInstance.Attach(new Material());
}
-std::pair<Material*, bool> MaterialManager::SaveMaterial(Material* mat) {
- // NOTE: we explicitly allow invalid materials (i.e. without a shader)
- if (mat->IsAnnoymous()) return { nullptr, false };
+void IresMaterial::ShowEditor(EditorInstance& editor) {
+ using namespace Tags;
- auto [iter, inserted] = mMaterials.try_emplace(mat->GetName(), mat);
- if (inserted) {
- mat->SaveToFile(mat->GetDesignatedPath());
- return { mat, true };
+ IresObject::ShowEditor(editor);
+
+ auto shader = mInstance->GetShader();
+ if (shader) {
+ auto& name = shader->GetName();
+ bool isAnnoymous = name.empty();
+ if (isAnnoymous) {
+ ImGui::Text("Shader <annoymous at %p>", (void*)shader);
+ } else {
+ ImGui::Text("Shader: %s", name.c_str());
+ }
} else {
- return { iter->second.Get(), false };
+ ImGui::TextUnformatted("Shader: <null>");
+ }
+ if (ImGui::BeginDragDropTarget()) {
+ if (auto payload = ImGui::AcceptDragDropPayload(BRUSSEL_TAG_Shader)) {
+ auto shader = *static_cast<Shader* const*>(payload->Data);
+ mInstance->SetShader(shader);
+ }
+ ImGui::EndDragDropTarget();
+ }
+ ImGui::SameLine();
+ if (ImGui::Button("GoTo", shader == nullptr)) {
+ editor.GetInspector().SelectTarget(EditorInspector::ITT_Shader, shader);
}
-}
-void MaterialManager::DeleteMaterial(Material* mat, bool onDisk) {
- // TODO
- assert(false && "unimplemented");
-}
+ if (!shader) return;
+ auto& info = shader->GetInfo();
-Material* MaterialManager::LoadMaterial(std::string_view name) {
- // TODO
- assert(false && "unimplemented");
-}
+ for (auto& field : mInstance->mBoundScalars) {
+ auto& decl = static_cast<ShaderMathVariable&>(*info.uniforms[field.infoUniformIndex]);
+ decl.ShowInfo();
-bool MaterialManager::RenameMaterial(Material* mat, std::string newName) {
- if (mMaterials.contains(newName)) {
- return false;
+ ImGui::Indent();
+ switch (decl.scalarType) {
+ case GL_FLOAT: ImGui::InputFloat("##", &field.floatValue); break;
+ case GL_INT: ImGui::InputInt("##", &field.intValue); break;
+ // TODO proper uint edit?
+ case GL_UNSIGNED_INT: ImGui::InputInt("##", (int32_t*)(&field.uintValue), 0, std::numeric_limits<int32_t>::max()); break;
+ default: ImGui::TextUnformatted("Unsupported scalar type"); break;
+ }
+ ImGui::Unindent();
}
+ for (auto& field : mInstance->mBoundVectors) {
+ auto& decl = static_cast<ShaderMathVariable&>(*info.uniforms[field.infoUniformIndex]);
+ decl.ShowInfo();
- // Keep the material from being deleted, in case the old entry in map is the only one existing
- RcPtr rc(mat);
+ ImGui::Indent();
+ switch (decl.semantic) {
+ case VES_Color1:
+ case VES_Color2: {
+ ImGui::ColorEdit4("##", field.value);
+ } break;
- // Remove old entry (must do before replacing Material::mName, because the std::string_view in the map is a reference to it)
- mMaterials.erase(mat->GetName());
+ default: {
+ ImGui::InputFloat4("##", field.value);
+ } break;
+ }
+ ImGui::Unindent();
+ }
+ for (auto& field : mInstance->mBoundMatrices) {
+ auto& decl = static_cast<ShaderMathVariable&>(*info.uniforms[field.infoUniformIndex]);
+ decl.ShowInfo();
- // Add new entry
- mat->mName = std::move(newName);
- mMaterials.try_emplace(mat->GetName(), mat);
+ // TODO
+ }
+ for (auto& field : mInstance->mBoundTextures) {
+ auto& decl = static_cast<ShaderSamplerVariable&>(*info.uniforms[field.infoUniformIndex]);
+ decl.ShowInfo();
- return true;
+ // TODO
+ }
}
-Material* MaterialManager::FindMaterial(std::string_view name) {
- auto iter = mMaterials.find(name);
- if (iter != mMaterials.end()) {
- return iter->second.Get();
- } else {
- return nullptr;
- }
+void IresMaterial::Write(rapidjson::Value& value, rapidjson::Document& root) const {
+ IresObject::Write(value, root);
+ mInstance->Write(value, root);
+}
+
+void IresMaterial::Read(const rapidjson::Value& value) {
+ InvalidateInstance();
+
+ IresObject::Read(value);
+ mInstance->Read(value);
}
diff --git a/source/Material.hpp b/source/Material.hpp
index 469cb7b..7cf5603 100644
--- a/source/Material.hpp
+++ b/source/Material.hpp
@@ -1,24 +1,20 @@
#pragma once
-#include "EditorAttachment.hpp"
+#include "Ires.hpp"
#include "RcPtr.hpp"
#include "Shader.hpp"
#include "Texture.hpp"
-// #include "Ires.hpp"
#include <glad/glad.h>
#include <robin_hood.h>
#include <cstddef>
#include <cstdint>
-#include <filesystem>
#include <glm/glm.hpp>
#include <memory>
#include <span>
#include <string_view>
#include <vector>
-// TODO migrate material editor to Ires
-class MaterialManager;
class Material : public RefCounted {
public: // NOTE: public for internal helpers and editor
// NOTE: specialize between scalar vs matrix vs vector to save memory
@@ -66,8 +62,6 @@ public: // NOTE: public for internal helpers and editor
/* Transient */ GLint location;
};
- std::string mName;
- std::unique_ptr<EditorAttachment> mEditorAttachment;
RcPtr<Shader> mShader;
std::vector<ScalarUniform> mBoundScalars;
std::vector<VectorUniform> mBoundVectors;
@@ -76,7 +70,6 @@ public: // NOTE: public for internal helpers and editor
public:
Material();
- Material(std::string name);
void SetFloat(const char* name, float value);
void SetInt(const char* name, int32_t value);
@@ -97,58 +90,27 @@ public:
std::span<const TextureUniform> GetTextures() const;
Shader* GetShader() const;
void SetShader(Shader* shader);
- const std::string& GetName() const;
- bool IsAnnoymous() const;
bool IsValid() const;
void UseUniforms() const;
- EditorAttachment* GetEditorAttachment() const { return mEditorAttachment.get(); }
- void SetEditorAttachment(EditorAttachment* attachment) { mEditorAttachment.reset(attachment); }
-
- void GetDesignatedPath(char* buffer, int bufferSize);
- std::filesystem::path GetDesignatedPath();
-
- bool SaveToFile(const std::filesystem::path& filePath) const;
- bool LoadFromFile(const std::filesystem::path& filePath);
+ bool Write(rapidjson::Value& value, rapidjson::Document& root) const;
+ bool Read(const rapidjson::Value& value);
};
-// class IresMaterial : public IresObject {
-// public:
-// RcPtr<Material> mInstance;
-
-// public:
-// IresMaterial()
-// : IresObject(KD_Spritesheet) {}
-
-// bool IsValid() const;
-
-// Material* CreateInstance() const;
-// Material* GetInstance();
-// void InvalidateInstance();
-
-// void ShowEditor() override;
-
-// void Write(rapidjson::Value& value, rapidjson::Document& root) const override;
-// void Read(const rapidjson::Value& value) override;
-// };
-
-class MaterialManager {
-public:
- static inline MaterialManager* instance = nullptr;
-
+class IresMaterial : public IresObject {
private:
- robin_hood::unordered_map<std::string_view, RcPtr<Material>> mMaterials;
+ RcPtr<Material> mInstance;
public:
- void DiscoverMaterials();
+ IresMaterial();
+
+ Material* GetInstance() const;
+ void InvalidateInstance();
- std::pair<Material*, bool> SaveMaterial(Material* mat);
- void DeleteMaterial(Material* mat, bool onDisk = false);
- Material* LoadMaterial(std::string_view name);
- bool RenameMaterial(Material* mat, std::string newName);
+ void ShowEditor(EditorInstance& editor) override;
- const auto& GetMaterials() const { return mMaterials; }
- Material* FindMaterial(std::string_view name);
+ void Write(rapidjson::Value& value, rapidjson::Document& root) const override;
+ void Read(const rapidjson::Value& value) override;
};
diff --git a/source/main.cpp b/source/main.cpp
index 3d02f8d..dc644ba 100644
--- a/source/main.cpp
+++ b/source/main.cpp
@@ -3,7 +3,6 @@
#include "AppConfig.hpp"
#include "EditorNotification.hpp"
#include "Ires.hpp"
-#include "Material.hpp"
#include "Mesh.hpp"
#include "Shader.hpp"
@@ -172,11 +171,9 @@ int main(int argc, char* argv[]) {
}
ShaderManager::instance = new ShaderManager();
- MaterialManager::instance = new MaterialManager();
IresManager::instance = new IresManager();
ShaderManager::instance->DiscoverShaders();
- MaterialManager::instance->DiscoverMaterials();
IresManager::instance->DiscoverFilesDesignatedLocation();
gVformatStandard.Attach(new VertexFormat());