aboutsummaryrefslogtreecommitdiff
path: root/source/Material.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Material.cpp')
-rw-r--r--source/Material.cpp250
1 files changed, 121 insertions, 129 deletions
diff --git a/source/Material.cpp b/source/Material.cpp
index 0031ef8..abb2f57 100644
--- a/source/Material.cpp
+++ b/source/Material.cpp
@@ -319,17 +319,107 @@ void Material::UseUniforms() const {
}
}
-bool Material::Write(rapidjson::Value& value, rapidjson::Document& root) const {
+IresMaterial::IresMaterial()
+ : IresObject(KD_Material)
+ , mInstance(new Material()) {
+ mInstance->mIres = this;
+}
+
+Material* IresMaterial::GetInstance() const {
+ return mInstance.Get();
+}
+
+void IresMaterial::InvalidateInstance() {
+ if (mInstance != nullptr) {
+ mInstance->mIres = nullptr;
+ }
+ mInstance.Attach(new Material());
+ mInstance->mIres = this;
+}
+
+void IresMaterial::ShowEditor(EditorInstance& editor) {
+ using namespace Tags;
+
+ IresObject::ShowEditor(editor);
+
+ auto shader = mInstance->GetShader();
+ if (shader) {
+ shader->GetIres()->ShowReference(editor);
+ } else {
+ IresObject::ShowNullReference(editor, KD_Shader);
+ }
+ if (ImGui::BeginDragDropTarget()) {
+ if (auto payload = ImGui::AcceptDragDropPayload(ToString(KD_Shader).data())) {
+ auto shader = *static_cast<IresShader* const*>(payload->Data);
+ mInstance->SetShader(shader->GetInstance());
+ }
+ ImGui::EndDragDropTarget();
+ }
+
+ if (!shader) return;
+ auto& shaderInfo = shader->GetInfo();
+ auto shaderIres = shader->GetIres();
+
+ for (auto& field : mInstance->mBoundScalars) {
+ auto& decl = static_cast<ShaderMathVariable&>(*shaderInfo.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 : mInstance->mBoundVectors) {
+ auto& decl = static_cast<ShaderMathVariable&>(*shaderInfo.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 : mInstance->mBoundMatrices) {
+ auto& decl = static_cast<ShaderMathVariable&>(*shaderInfo.uniforms[field.infoUniformIndex]);
+ decl.ShowInfo();
+
+ // TODO
+ }
+ for (auto& field : mInstance->mBoundTextures) {
+ auto& decl = static_cast<ShaderSamplerVariable&>(*shaderInfo.uniforms[field.infoUniformIndex]);
+ decl.ShowInfo();
+
+ // TODO
+ }
+}
+
+void IresMaterial::Write(IresWritingContext& ctx, rapidjson::Value& value, rapidjson::Document& root) const {
using namespace ProjectBrussel_UNITY_ID;
- if (!IsValid()) return false;
+ IresObject::Write(ctx, value, root);
- auto& shaderInfo = mShader->GetInfo();
+ if (!mInstance->IsValid()) {
+ return;
+ }
- value.AddMember("ShaderName", mShader->GetName(), root.GetAllocator());
+ auto& shaderInfo = mInstance->mShader->GetInfo();
+ auto shaderUid = mInstance->mShader->GetIres()->GetUid();
+ value.AddMember("Shader", shaderUid.Write(root), root.GetAllocator());
rapidjson::Value fields(rapidjson::kArrayType);
- for (auto& scalar : mBoundScalars) {
+ for (auto& scalar : mInstance->mBoundScalars) {
rapidjson::Value rvField(rapidjson::kObjectType);
rvField.AddMember("Name", shaderInfo.uniforms[scalar.infoUniformIndex]->name, root.GetAllocator());
rvField.AddMember("Type", "Scalar", root.GetAllocator());
@@ -340,44 +430,50 @@ bool Material::Write(rapidjson::Value& value, rapidjson::Document& root) const {
}
fields.PushBack(rvField, root.GetAllocator());
}
- for (auto& vector : mBoundVectors) {
+ for (auto& vector : mInstance->mBoundVectors) {
rapidjson::Value rvField(rapidjson::kObjectType);
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) {
+ for (auto& matrix : mInstance->mBoundMatrices) {
rapidjson::Value rvField(rapidjson::kObjectType);
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());
}
- for (auto& texture : mBoundTextures) {
+ for (auto& texture : mInstance->mBoundTextures) {
// TODO
}
value.AddMember("Fields", fields, root.GetAllocator());
-
- return true;
}
-bool Material::Read(const rapidjson::Value& value) {
+void IresMaterial::Read(IresLoadingContext& ctx, const rapidjson::Value& value) {
using namespace ProjectBrussel_UNITY_ID;
+ IresObject::Read(ctx, value);
+
{
- auto rvShaderName = rapidjson::GetProperty(value, rapidjson::kStringType, "ShaderName"sv);
- if (!rvShaderName) return false;
+ auto rvShader = rapidjson::GetProperty(value, "Shader"sv);
+ if (!rvShader) return;
+
+ Uid uid;
+ uid.Read(*rvShader);
- auto shader = ShaderManager::instance->FindShader(rapidjson::AsStringView(*rvShaderName));
- if (!shader) return false;
+ auto ires = ctx.FindIres(uid);
+ if (!ires) return;
+ if (ires->GetKind() != KD_Shader) return;
+ auto shader = static_cast<IresShader*>(ires);
- mShader.Attach(shader);
+ mInstance->mShader.Attach(shader->GetInstance());
}
- auto& shaderInfo = mShader->GetInfo();
+ auto shader = mInstance->mShader.Get();
+ auto& shaderInfo = shader->GetInfo();
auto fields = rapidjson::GetProperty(value, rapidjson::kArrayType, "Fields"sv);
- if (!fields) return false;
+ if (!fields) return;
for (auto& rvField : fields->GetArray()) {
if (!rvField.IsObject()) continue;
@@ -391,9 +487,9 @@ bool Material::Read(const rapidjson::Value& value) {
auto rvValue = rapidjson::GetProperty(rvField, "Value"sv);
if (type == "Scalar"sv) {
- ScalarUniform uniform;
+ Material::ScalarUniform uniform;
if (rvName) {
- TryFindShaderId(mShader.Get(), rapidjson::AsStringView(*rvName), uniform.infoUniformIndex);
+ TryFindShaderId(shader, rapidjson::AsStringView(*rvName), uniform.infoUniformIndex);
uniform.location = shaderInfo.uniforms[uniform.infoUniformIndex]->location;
}
if (rvValue->IsFloat()) {
@@ -406,127 +502,23 @@ bool Material::Read(const rapidjson::Value& value) {
uniform.actualType = GL_UNSIGNED_INT;
uniform.uintValue = rvValue->GetUint();
}
- mBoundScalars.push_back(std::move(uniform));
+ mInstance->mBoundScalars.push_back(std::move(uniform));
} else if (type == "Vector"sv) {
auto uniform = ReadVectorFromJson(*rvValue);
if (rvName) {
- TryFindShaderId(mShader.Get(), rapidjson::AsStringView(*rvName), uniform.infoUniformIndex);
+ TryFindShaderId(shader, rapidjson::AsStringView(*rvName), uniform.infoUniformIndex);
uniform.location = shaderInfo.uniforms[uniform.infoUniformIndex]->location;
}
- mBoundVectors.push_back(std::move(uniform));
+ mInstance->mBoundVectors.push_back(std::move(uniform));
} else if (type == "Matrix"sv) {
auto uniform = ReadMatrixFromjson(*rvValue);
if (rvName) {
- TryFindShaderId(mShader.Get(), rapidjson::AsStringView(*rvName), uniform.infoUniformIndex);
+ TryFindShaderId(shader, rapidjson::AsStringView(*rvName), uniform.infoUniformIndex);
uniform.location = shaderInfo.uniforms[uniform.infoUniformIndex]->location;
}
- mBoundMatrices.push_back(uniform);
+ mInstance->mBoundMatrices.push_back(uniform);
} else if (type == "Texture"sv) {
// TODO
}
}
-
- return true;
-}
-
-IresMaterial::IresMaterial()
- : IresObject(KD_Material)
- , mInstance(new Material()) {
-}
-
-Material* IresMaterial::GetInstance() const {
- return mInstance.Get();
-}
-
-void IresMaterial::InvalidateInstance() {
- mInstance.Attach(new Material());
-}
-
-void IresMaterial::ShowEditor(EditorInstance& editor) {
- using namespace Tags;
-
- 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 {
- 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);
- }
-
- if (!shader) return;
- auto& info = shader->GetInfo();
-
- for (auto& field : mInstance->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 : mInstance->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 : mInstance->mBoundMatrices) {
- auto& decl = static_cast<ShaderMathVariable&>(*info.uniforms[field.infoUniformIndex]);
- decl.ShowInfo();
-
- // TODO
- }
- for (auto& field : mInstance->mBoundTextures) {
- auto& decl = static_cast<ShaderSamplerVariable&>(*info.uniforms[field.infoUniformIndex]);
- decl.ShowInfo();
-
- // TODO
- }
-}
-
-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);
}