From 7c52a524407aa8055938ec68efe135bf4162db34 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Thu, 24 Aug 2023 00:35:31 -0500 Subject: [PATCH] VideoCommon: add TextureData structure that contains the raw texture data, a sampler, and the type of texture information --- .../Core/VideoCommon/Assets/TextureAsset.cpp | 133 ++++++++++++++++++ Source/Core/VideoCommon/Assets/TextureAsset.h | 18 +++ 2 files changed, 151 insertions(+) diff --git a/Source/Core/VideoCommon/Assets/TextureAsset.cpp b/Source/Core/VideoCommon/Assets/TextureAsset.cpp index 3bf477a58a..759703a8a5 100644 --- a/Source/Core/VideoCommon/Assets/TextureAsset.cpp +++ b/Source/Core/VideoCommon/Assets/TextureAsset.cpp @@ -4,9 +4,99 @@ #include "VideoCommon/Assets/TextureAsset.h" #include "Common/Logging/Log.h" +#include "VideoCommon/BPMemory.h" namespace VideoCommon { +namespace +{ +bool ParseSampler(const VideoCommon::CustomAssetLibrary::AssetID& asset_id, + const picojson::object& json, SamplerState* sampler) +{ + if (!sampler) [[unlikely]] + return false; + + *sampler = RenderState::GetLinearSamplerState(); + + const auto sampler_state_mode_iter = json.find("texture_mode"); + if (sampler_state_mode_iter == json.end()) + { + ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, 'texture_mode' not found", asset_id); + return false; + } + if (!sampler_state_mode_iter->second.is()) + { + ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, 'texture_mode' is not the right type", + asset_id); + return false; + } + std::string sampler_state_mode = sampler_state_mode_iter->second.to_str(); + std::transform(sampler_state_mode.begin(), sampler_state_mode.end(), sampler_state_mode.begin(), + [](unsigned char c) { return std::tolower(c); }); + + if (sampler_state_mode == "clamp") + { + sampler->tm0.wrap_u = WrapMode::Clamp; + sampler->tm0.wrap_v = WrapMode::Clamp; + } + else if (sampler_state_mode == "repeat") + { + sampler->tm0.wrap_u = WrapMode::Repeat; + sampler->tm0.wrap_v = WrapMode::Repeat; + } + else if (sampler_state_mode == "mirrored_repeat") + { + 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; + } + + 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()) + { + ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, 'texture_filter' is not the right type", + asset_id); + return false; + } + std::string sampler_state_filter = sampler_state_filter_iter->second.to_str(); + std::transform(sampler_state_filter.begin(), sampler_state_filter.end(), + sampler_state_filter.begin(), [](unsigned char c) { return std::tolower(c); }); + 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 == "point") + { + sampler->tm0.min_filter = FilterMode::Linear; + sampler->tm0.mag_filter = FilterMode::Linear; + sampler->tm0.mipmap_filter = FilterMode::Linear; + } + else + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' failed to parse json, 'texture_filter' has an invalid " + "value '{}'", + asset_id, sampler_state_filter); + return false; + } + + return true; +} +} // namespace CustomAssetLibrary::LoadInfo RawTextureAsset::LoadImpl(const CustomAssetLibrary::AssetID& asset_id) { auto potential_data = std::make_shared(); @@ -21,6 +111,49 @@ CustomAssetLibrary::LoadInfo RawTextureAsset::LoadImpl(const CustomAssetLibrary: return loaded_info; } +bool TextureData::FromJson(const CustomAssetLibrary::AssetID& asset_id, + const picojson::object& json, TextureData* data) +{ + const auto type_iter = json.find("type"); + if (type_iter == json.end()) + { + ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, property entry 'type' not found", + asset_id); + return false; + } + if (!type_iter->second.is()) + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' failed to parse json, property entry 'type' is not " + "the right json type", + asset_id); + return false; + } + std::string type = type_iter->second.to_str(); + std::transform(type.begin(), type.end(), type.begin(), + [](unsigned char c) { return std::tolower(c); }); + + if (type == "texture2d") + { + data->m_type = TextureData::Type::Type_Texture2D; + } + else + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' failed to parse json, texture type '{}' " + "an invalid option", + asset_id, type); + return false; + } + + if (!ParseSampler(asset_id, json, &data->m_sampler)) + { + return false; + } + + return true; +} + CustomAssetLibrary::LoadInfo GameTextureAsset::LoadImpl(const CustomAssetLibrary::AssetID& asset_id) { auto potential_data = std::make_shared(); diff --git a/Source/Core/VideoCommon/Assets/TextureAsset.h b/Source/Core/VideoCommon/Assets/TextureAsset.h index 4cb0001a58..03b6a231d4 100644 --- a/Source/Core/VideoCommon/Assets/TextureAsset.h +++ b/Source/Core/VideoCommon/Assets/TextureAsset.h @@ -3,8 +3,11 @@ #pragma once +#include + #include "VideoCommon/Assets/CustomAsset.h" #include "VideoCommon/Assets/CustomTextureData.h" +#include "VideoCommon/RenderState.h" namespace VideoCommon { @@ -17,6 +20,21 @@ private: CustomAssetLibrary::LoadInfo LoadImpl(const CustomAssetLibrary::AssetID& asset_id) override; }; +struct TextureData +{ + static bool FromJson(const CustomAssetLibrary::AssetID& asset_id, const picojson::object& json, + TextureData* data); + enum class Type + { + Type_Undefined, + Type_Texture2D, + Type_Max = Type_Texture2D + }; + Type m_type; + CustomTextureData m_data; + SamplerState m_sampler; +}; + class GameTextureAsset final : public CustomLoadableAsset { public: