aboutsummaryrefslogtreecommitdiff
path: root/source/Material.cpp
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 /source/Material.cpp
parentf77e73c01a15426bcc6e3d7fe5826d2a741fed38 (diff)
Migrate Material to Ires
Diffstat (limited to 'source/Material.cpp')
-rw-r--r--source/Material.cpp215
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);
}