diff options
author | rtk0c <[email protected]> | 2022-04-18 20:59:57 -0700 |
---|---|---|
committer | rtk0c <[email protected]> | 2022-04-18 20:59:57 -0700 |
commit | 07e8754e4d799e44678b595177e79e6eaa621268 (patch) | |
tree | 6d9d4470259776ef01e814191ba0440f83505933 /source/Material.cpp | |
parent | 7f871b04470766f0f5266cf949b65a54b7a6f79e (diff) |
Changeset: 11 Migrate Material to Ires
Diffstat (limited to 'source/Material.cpp')
-rw-r--r-- | source/Material.cpp | 215 |
1 files changed, 96 insertions, 119 deletions
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); } |