diff options
Diffstat (limited to 'Source/Core/VideoCommon/Assets/TextureAsset.cpp')
| -rw-r--r-- | Source/Core/VideoCommon/Assets/TextureAsset.cpp | 183 |
1 files changed, 120 insertions, 63 deletions
diff --git a/Source/Core/VideoCommon/Assets/TextureAsset.cpp b/Source/Core/VideoCommon/Assets/TextureAsset.cpp index b7781d4667..425b84207c 100644 --- a/Source/Core/VideoCommon/Assets/TextureAsset.cpp +++ b/Source/Core/VideoCommon/Assets/TextureAsset.cpp @@ -3,6 +3,9 @@ #include "VideoCommon/Assets/TextureAsset.h" +#include <optional> + +#include "Common/JsonUtil.h" #include "Common/Logging/Log.h" #include "Common/StringUtil.h" #include "VideoCommon/BPMemory.h" @@ -11,86 +14,140 @@ namespace VideoCommon { namespace { -bool ParseSampler(const VideoCommon::CustomAssetLibrary::AssetID& asset_id, - const picojson::object& json, SamplerState* sampler) +std::optional<WrapMode> ReadWrapModeFromJSON(const picojson::object& json, const std::string& uv) { - if (!sampler) [[unlikely]] - return false; + auto uv_mode = ReadStringFromJson(json, uv).value_or(""); + Common::ToLower(&uv_mode); - *sampler = RenderState::GetLinearSamplerState(); - - const auto sampler_state_mode_iter = json.find("texture_mode"); - if (sampler_state_mode_iter == json.end()) + if (uv_mode == "clamp") { - ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, 'texture_mode' not found", asset_id); - return false; + return WrapMode::Clamp; } - if (!sampler_state_mode_iter->second.is<std::string>()) + else if (uv_mode == "repeat") { - ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, 'texture_mode' is not the right type", - asset_id); - return false; + return WrapMode::Repeat; } - std::string sampler_state_mode = sampler_state_mode_iter->second.to_str(); - Common::ToLower(&sampler_state_mode); - - if (sampler_state_mode == "clamp") + else if (uv_mode == "mirror") { - sampler->tm0.wrap_u = WrapMode::Clamp; - sampler->tm0.wrap_v = WrapMode::Clamp; + return WrapMode::Mirror; } - else if (sampler_state_mode == "repeat") + + return std::nullopt; +} + +std::optional<FilterMode> ReadFilterModeFromJSON(const picojson::object& json, + const std::string& filter) +{ + auto filter_mode = ReadStringFromJson(json, filter).value_or(""); + Common::ToLower(&filter_mode); + + if (filter_mode == "linear") { - sampler->tm0.wrap_u = WrapMode::Repeat; - sampler->tm0.wrap_v = WrapMode::Repeat; + return FilterMode::Linear; } - else if (sampler_state_mode == "mirrored_repeat") + else if (filter_mode == "near") { - sampler->tm0.wrap_u = WrapMode::Mirror; - sampler->tm0.wrap_v = WrapMode::Mirror; - } - else - { - ERROR_LOG_FMT(VIDEO, - "Asset '{}' failed to parse json, 'texture_mode' has an invalid " - "value '{}'", - asset_id, sampler_state_mode); - return false; + return FilterMode::Near; } - const auto sampler_state_filter_iter = json.find("texture_filter"); - if (sampler_state_filter_iter == json.end()) - { - ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, 'texture_filter' not found", asset_id); - return false; - } - if (!sampler_state_filter_iter->second.is<std::string>()) - { - ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, 'texture_filter' is not the right type", - asset_id); + return std::nullopt; +} + +bool ParseSampler(const VideoCommon::CustomAssetLibrary::AssetID& asset_id, + const picojson::object& json, SamplerState* sampler) +{ + if (!sampler) [[unlikely]] return false; - } - std::string sampler_state_filter = sampler_state_filter_iter->second.to_str(); - Common::ToLower(&sampler_state_filter); - if (sampler_state_filter == "linear") - { - sampler->tm0.min_filter = FilterMode::Linear; - sampler->tm0.mag_filter = FilterMode::Linear; - sampler->tm0.mipmap_filter = FilterMode::Linear; - } - else if (sampler_state_filter == "near") + + *sampler = RenderState::GetLinearSamplerState(); + + const auto sampler_state_wrap_iter = json.find("wrap_mode"); + if (sampler_state_wrap_iter != json.end()) { - sampler->tm0.min_filter = FilterMode::Near; - sampler->tm0.mag_filter = FilterMode::Near; - sampler->tm0.mipmap_filter = FilterMode::Near; + if (!sampler_state_wrap_iter->second.is<picojson::object>()) + { + ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, 'wrap_mode' is not the right type", + asset_id); + return false; + } + const auto sampler_state_wrap_obj = sampler_state_wrap_iter->second.get<picojson::object>(); + + if (const auto mode = ReadWrapModeFromJSON(sampler_state_wrap_obj, "u")) + { + sampler->tm0.wrap_u = *mode; + } + else + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' failed to parse json, 'wrap_mode[u]' has an invalid " + "value", + asset_id); + return false; + } + + if (const auto mode = ReadWrapModeFromJSON(sampler_state_wrap_obj, "v")) + { + sampler->tm0.wrap_v = *mode; + } + else + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' failed to parse json, 'wrap_mode[v]' has an invalid " + "value", + asset_id); + return false; + } } - else + + const auto sampler_state_filter_iter = json.find("filter_mode"); + if (sampler_state_filter_iter != json.end()) { - ERROR_LOG_FMT(VIDEO, - "Asset '{}' failed to parse json, 'texture_filter' has an invalid " - "value '{}'", - asset_id, sampler_state_filter); - return false; + if (!sampler_state_filter_iter->second.is<picojson::object>()) + { + ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, 'filter_mode' is not the right type", + asset_id); + return false; + } + const auto sampler_state_filter_obj = sampler_state_filter_iter->second.get<picojson::object>(); + + if (const auto mode = ReadFilterModeFromJSON(sampler_state_filter_obj, "min")) + { + sampler->tm0.min_filter = *mode; + } + else + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' failed to parse json, 'filter_mode[min]' has an invalid " + "value", + asset_id); + return false; + } + + if (const auto mode = ReadFilterModeFromJSON(sampler_state_filter_obj, "mag")) + { + sampler->tm0.mag_filter = *mode; + } + else + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' failed to parse json, 'filter_mode[mag]' has an invalid " + "value", + asset_id); + return false; + } + + if (const auto mode = ReadFilterModeFromJSON(sampler_state_filter_obj, "mipmap")) + { + sampler->tm0.mipmap_filter = *mode; + } + else + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' failed to parse json, 'filter_mode[mipmap]' has an invalid " + "value", + asset_id); + return false; + } } return true; |
