summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/Assets/MaterialAsset.cpp
diff options
context:
space:
mode:
authorAdmiral H. Curtiss <pikachu025@gmail.com>2023-07-09 21:49:16 +0200
committerGitHub <noreply@github.com>2023-07-09 21:49:16 +0200
commitfe8a9ac70796498e8bc5b29770e9334ed187c35d (patch)
treed70210185ba889c5f45b055b29b351fa4b7c6d1a /Source/Core/VideoCommon/Assets/MaterialAsset.cpp
parentbd90f6be78ffa40c07542c43b74a17f0951f10eb (diff)
parent77511e8e7cc80cc82fa1edf206948f714413aac8 (diff)
Merge pull request #12024 from iwubcode/material_asset
VideoCommon: add material asset
Diffstat (limited to 'Source/Core/VideoCommon/Assets/MaterialAsset.cpp')
-rw-r--r--Source/Core/VideoCommon/Assets/MaterialAsset.cpp166
1 files changed, 166 insertions, 0 deletions
diff --git a/Source/Core/VideoCommon/Assets/MaterialAsset.cpp b/Source/Core/VideoCommon/Assets/MaterialAsset.cpp
new file mode 100644
index 0000000000..c5e5718492
--- /dev/null
+++ b/Source/Core/VideoCommon/Assets/MaterialAsset.cpp
@@ -0,0 +1,166 @@
+// Copyright 2023 Dolphin Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "VideoCommon/Assets/MaterialAsset.h"
+
+#include <vector>
+
+#include "Common/Logging/Log.h"
+#include "Common/StringUtil.h"
+#include "VideoCommon/Assets/CustomAssetLibrary.h"
+
+namespace VideoCommon
+{
+namespace
+{
+bool ParsePropertyValue(const CustomAssetLibrary::AssetID& asset_id, MaterialProperty::Type type,
+ const picojson::value& json_value,
+ std::optional<MaterialProperty::Value>* value)
+{
+ switch (type)
+ {
+ case MaterialProperty::Type::Type_TextureAsset:
+ {
+ if (json_value.is<std::string>())
+ {
+ *value = json_value.to_str();
+ return true;
+ }
+ }
+ break;
+ };
+
+ ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse the json, value is not valid for type '{}'",
+ asset_id, type);
+ return false;
+}
+
+bool ParseMaterialProperties(const CustomAssetLibrary::AssetID& asset_id,
+ const picojson::array& values_data,
+ std::vector<MaterialProperty>* material_property)
+{
+ for (const auto& value_data : values_data)
+ {
+ VideoCommon::MaterialProperty property;
+ if (!value_data.is<picojson::object>())
+ {
+ ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse the json, value is not the right json type",
+ asset_id);
+ return false;
+ }
+ const auto& value_data_obj = value_data.get<picojson::object>();
+
+ const auto type_iter = value_data_obj.find("type");
+ if (type_iter == value_data_obj.end())
+ {
+ ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse the json, value entry 'type' not found",
+ asset_id);
+ return false;
+ }
+ if (!type_iter->second.is<std::string>())
+ {
+ ERROR_LOG_FMT(VIDEO,
+ "Asset '{}' failed to parse the json, value entry 'type' is not "
+ "the right json type",
+ asset_id);
+ return false;
+ }
+ std::string type = type_iter->second.to_str();
+ Common::ToLower(&type);
+ if (type == "texture_asset")
+ {
+ property.m_type = MaterialProperty::Type::Type_TextureAsset;
+ }
+ else
+ {
+ ERROR_LOG_FMT(VIDEO,
+ "Asset '{}' failed to parse the json, value entry 'type' is "
+ "an invalid option",
+ asset_id);
+ return false;
+ }
+
+ const auto code_name_iter = value_data_obj.find("code_name");
+ if (code_name_iter == value_data_obj.end())
+ {
+ ERROR_LOG_FMT(VIDEO,
+ "Asset '{}' failed to parse the json, value entry "
+ "'code_name' not found",
+ asset_id);
+ return false;
+ }
+ if (!code_name_iter->second.is<std::string>())
+ {
+ ERROR_LOG_FMT(VIDEO,
+ "Asset '{}' failed to parse the json, value entry 'code_name' is not "
+ "the right json type",
+ asset_id);
+ return false;
+ }
+ property.m_code_name = code_name_iter->second.to_str();
+
+ const auto value_iter = value_data_obj.find("value");
+ if (value_iter != value_data_obj.end())
+ {
+ if (!ParsePropertyValue(asset_id, property.m_type, value_iter->second, &property.m_value))
+ return false;
+ }
+
+ material_property->push_back(std::move(property));
+ }
+
+ return true;
+}
+} // namespace
+bool MaterialData::FromJson(const CustomAssetLibrary::AssetID& asset_id,
+ const picojson::object& json, MaterialData* data)
+{
+ const auto values_iter = json.find("values");
+ if (values_iter == json.end())
+ {
+ ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, 'values' not found", asset_id);
+ return false;
+ }
+ if (!values_iter->second.is<picojson::array>())
+ {
+ ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, 'values' is not the right json type",
+ asset_id);
+ return false;
+ }
+ const auto& values_array = values_iter->second.get<picojson::array>();
+
+ if (!ParseMaterialProperties(asset_id, values_array, &data->properties))
+ return false;
+
+ const auto shader_asset_iter = json.find("shader_asset");
+ if (shader_asset_iter == json.end())
+ {
+ ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, 'shader_asset' not found", asset_id);
+ return false;
+ }
+ if (!shader_asset_iter->second.is<std::string>())
+ {
+ ERROR_LOG_FMT(VIDEO,
+ "Asset '{}' failed to parse json, 'shader_asset' is not the right json type",
+ asset_id);
+ return false;
+ }
+ data->shader_asset = shader_asset_iter->second.to_str();
+
+ return true;
+}
+
+CustomAssetLibrary::LoadInfo MaterialAsset::LoadImpl(const CustomAssetLibrary::AssetID& asset_id)
+{
+ auto potential_data = std::make_shared<MaterialData>();
+ const auto loaded_info = m_owning_library->LoadMaterial(asset_id, potential_data.get());
+ if (loaded_info.m_bytes_loaded == 0)
+ return {};
+ {
+ std::lock_guard lk(m_data_lock);
+ m_loaded = true;
+ m_data = std::move(potential_data);
+ }
+ return loaded_info;
+}
+} // namespace VideoCommon