diff options
author | hnOsmium0001 <[email protected]> | 2022-04-18 20:59:57 -0700 |
---|---|---|
committer | hnOsmium0001 <[email protected]> | 2022-04-18 20:59:57 -0700 |
commit | 2a5234a512c19582d261a7ccb692fc634dcb74f0 (patch) | |
tree | 0f52925373115319a9ad7d03600e566c59a86566 /source | |
parent | f77e73c01a15426bcc6e3d7fe5826d2a741fed38 (diff) |
Migrate Material to Ires
Diffstat (limited to 'source')
-rw-r--r-- | source/EditorCore.cpp | 177 | ||||
-rw-r--r-- | source/EditorCore.hpp | 2 | ||||
-rw-r--r-- | source/EditorUtils.cpp | 7 | ||||
-rw-r--r-- | source/EditorUtils.hpp | 2 | ||||
-rw-r--r-- | source/Ires.cpp | 45 | ||||
-rw-r--r-- | source/Ires.hpp | 4 | ||||
-rw-r--r-- | source/Macros.hpp | 6 | ||||
-rw-r--r-- | source/Material.cpp | 215 | ||||
-rw-r--r-- | source/Material.hpp | 62 | ||||
-rw-r--r-- | source/main.cpp | 3 |
10 files changed, 171 insertions, 352 deletions
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()); |