Implement initial Unity-style asset library cache
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Components/Component.h>
|
||||
#include <XCEngine/Core/Asset/AssetRef.h>
|
||||
#include <XCEngine/Core/Asset/ResourceHandle.h>
|
||||
#include <XCEngine/Resources/Mesh/Mesh.h>
|
||||
|
||||
@@ -16,6 +17,7 @@ public:
|
||||
Resources::Mesh* GetMesh() const { return m_mesh.Get(); }
|
||||
const Resources::ResourceHandle<Resources::Mesh>& GetMeshHandle() const { return m_mesh; }
|
||||
const std::string& GetMeshPath() const { return m_meshPath; }
|
||||
const Resources::AssetRef& GetMeshAssetRef() const { return m_meshRef; }
|
||||
|
||||
void SetMeshPath(const std::string& meshPath);
|
||||
void SetMesh(const Resources::ResourceHandle<Resources::Mesh>& mesh);
|
||||
@@ -28,6 +30,7 @@ public:
|
||||
private:
|
||||
Resources::ResourceHandle<Resources::Mesh> m_mesh;
|
||||
std::string m_meshPath;
|
||||
Resources::AssetRef m_meshRef;
|
||||
};
|
||||
|
||||
} // namespace Components
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Components/Component.h>
|
||||
#include <XCEngine/Core/Asset/AssetRef.h>
|
||||
#include <XCEngine/Core/Asset/ResourceHandle.h>
|
||||
#include <XCEngine/Resources/Material/Material.h>
|
||||
|
||||
@@ -20,6 +21,7 @@ public:
|
||||
const Resources::ResourceHandle<Resources::Material>& GetMaterialHandle(size_t index) const;
|
||||
const std::string& GetMaterialPath(size_t index) const;
|
||||
const std::vector<std::string>& GetMaterialPaths() const { return m_materialPaths; }
|
||||
const std::vector<Resources::AssetRef>& GetMaterialAssetRefs() const { return m_materialRefs; }
|
||||
|
||||
void SetMaterialPath(size_t index, const std::string& materialPath);
|
||||
void SetMaterial(size_t index, const Resources::ResourceHandle<Resources::Material>& material);
|
||||
@@ -45,6 +47,7 @@ private:
|
||||
|
||||
std::vector<Resources::ResourceHandle<Resources::Material>> m_materials;
|
||||
std::vector<std::string> m_materialPaths;
|
||||
std::vector<Resources::AssetRef> m_materialRefs;
|
||||
bool m_castShadows = true;
|
||||
bool m_receiveShadows = true;
|
||||
uint32_t m_renderLayer = 0;
|
||||
|
||||
59
engine/include/XCEngine/Core/Asset/ArtifactFormats.h
Normal file
59
engine/include/XCEngine/Core/Asset/ArtifactFormats.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Core/Math/Bounds.h>
|
||||
#include <XCEngine/Core/Types.h>
|
||||
#include <XCEngine/Resources/Material/Material.h>
|
||||
#include <XCEngine/Resources/Mesh/Mesh.h>
|
||||
#include <XCEngine/Resources/Texture/Texture.h>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Resources {
|
||||
|
||||
constexpr Core::uint32 kTextureArtifactSchemaVersion = 1;
|
||||
constexpr Core::uint32 kMeshArtifactSchemaVersion = 1;
|
||||
|
||||
struct TextureArtifactHeader {
|
||||
char magic[8] = { 'X', 'C', 'T', 'E', 'X', '0', '1', '\0' };
|
||||
Core::uint32 schemaVersion = kTextureArtifactSchemaVersion;
|
||||
Core::uint32 textureType = 0;
|
||||
Core::uint32 textureFormat = 0;
|
||||
Core::uint32 width = 0;
|
||||
Core::uint32 height = 0;
|
||||
Core::uint32 depth = 0;
|
||||
Core::uint32 mipLevels = 0;
|
||||
Core::uint32 arraySize = 0;
|
||||
Core::uint64 pixelDataSize = 0;
|
||||
};
|
||||
|
||||
struct MeshArtifactHeader {
|
||||
char magic[8] = { 'X', 'C', 'M', 'E', 'S', 'H', '1', '\0' };
|
||||
Core::uint32 schemaVersion = kMeshArtifactSchemaVersion;
|
||||
Core::uint32 vertexCount = 0;
|
||||
Core::uint32 vertexStride = 0;
|
||||
Core::uint32 vertexAttributes = 0;
|
||||
Core::uint32 indexCount = 0;
|
||||
Core::uint32 use32BitIndex = 0;
|
||||
Core::uint32 sectionCount = 0;
|
||||
Core::uint32 materialCount = 0;
|
||||
Core::uint32 textureCount = 0;
|
||||
Math::Vector3 boundsMin = Math::Vector3::Zero();
|
||||
Math::Vector3 boundsMax = Math::Vector3::Zero();
|
||||
Core::uint64 vertexDataSize = 0;
|
||||
Core::uint64 indexDataSize = 0;
|
||||
};
|
||||
|
||||
struct MaterialArtifactHeader {
|
||||
Core::int32 renderQueue = static_cast<Core::int32>(MaterialRenderQueue::Geometry);
|
||||
MaterialRenderState renderState = {};
|
||||
Core::uint32 tagCount = 0;
|
||||
Core::uint32 propertyCount = 0;
|
||||
Core::uint32 textureBindingCount = 0;
|
||||
};
|
||||
|
||||
struct MaterialPropertyArtifact {
|
||||
Core::uint32 propertyType = 0;
|
||||
MaterialProperty::Value value = {};
|
||||
};
|
||||
|
||||
} // namespace Resources
|
||||
} // namespace XCEngine
|
||||
130
engine/include/XCEngine/Core/Asset/AssetDatabase.h
Normal file
130
engine/include/XCEngine/Core/Asset/AssetDatabase.h
Normal file
@@ -0,0 +1,130 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Core/Asset/AssetRef.h>
|
||||
#include <XCEngine/Core/Containers/String.h>
|
||||
#include <XCEngine/Core/Types.h>
|
||||
|
||||
#include <filesystem>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Resources {
|
||||
|
||||
class AssetDatabase {
|
||||
public:
|
||||
struct SourceAssetRecord {
|
||||
AssetGUID guid;
|
||||
Containers::String relativePath;
|
||||
Containers::String metaPath;
|
||||
bool isFolder = false;
|
||||
Containers::String importerName;
|
||||
Core::uint32 importerVersion = 0;
|
||||
Containers::String metaHash;
|
||||
Containers::String sourceHash;
|
||||
Core::uint64 sourceFileSize = 0;
|
||||
Core::uint64 sourceWriteTime = 0;
|
||||
Containers::String lastKnownArtifactKey;
|
||||
};
|
||||
|
||||
struct ArtifactRecord {
|
||||
Containers::String artifactKey;
|
||||
AssetGUID assetGuid;
|
||||
Containers::String importerName;
|
||||
Core::uint32 importerVersion = 0;
|
||||
ResourceType resourceType = ResourceType::Unknown;
|
||||
Containers::String artifactDirectory;
|
||||
Containers::String mainArtifactPath;
|
||||
Containers::String sourceHash;
|
||||
Containers::String metaHash;
|
||||
Core::uint64 sourceFileSize = 0;
|
||||
Core::uint64 sourceWriteTime = 0;
|
||||
LocalID mainLocalID = kMainAssetLocalID;
|
||||
};
|
||||
|
||||
struct ResolvedAsset {
|
||||
bool exists = false;
|
||||
bool artifactReady = false;
|
||||
Containers::String absolutePath;
|
||||
Containers::String relativePath;
|
||||
AssetGUID assetGuid;
|
||||
ResourceType resourceType = ResourceType::Unknown;
|
||||
Containers::String artifactMainPath;
|
||||
Containers::String artifactDirectory;
|
||||
LocalID mainLocalID = kMainAssetLocalID;
|
||||
};
|
||||
|
||||
void Initialize(const Containers::String& projectRoot);
|
||||
void Shutdown();
|
||||
void Refresh();
|
||||
|
||||
bool ResolvePath(const Containers::String& requestPath,
|
||||
Containers::String& outAbsolutePath,
|
||||
Containers::String& outRelativePath) const;
|
||||
bool TryGetAssetGuid(const Containers::String& requestPath, AssetGUID& outGuid) const;
|
||||
bool TryGetAssetRef(const Containers::String& requestPath, ResourceType resourceType, AssetRef& outRef) const;
|
||||
bool EnsureArtifact(const Containers::String& requestPath,
|
||||
ResourceType requestedType,
|
||||
ResolvedAsset& outAsset);
|
||||
bool TryGetPrimaryAssetPath(const AssetGUID& guid, Containers::String& outRelativePath) const;
|
||||
|
||||
const Containers::String& GetProjectRoot() const { return m_projectRoot; }
|
||||
const Containers::String& GetAssetsRoot() const { return m_assetsRoot; }
|
||||
const Containers::String& GetLibraryRoot() const { return m_libraryRoot; }
|
||||
|
||||
private:
|
||||
static constexpr Core::uint32 kCurrentImporterVersion = 1;
|
||||
|
||||
void EnsureProjectLayout();
|
||||
void LoadSourceAssetDB();
|
||||
void SaveSourceAssetDB() const;
|
||||
void LoadArtifactDB();
|
||||
void SaveArtifactDB() const;
|
||||
void ScanAssets();
|
||||
void ScanAssetPath(const std::filesystem::path& path,
|
||||
std::unordered_map<std::string, bool>& seenPaths);
|
||||
void RemoveMissingRecords(const std::unordered_map<std::string, bool>& seenPaths);
|
||||
|
||||
bool EnsureMetaForPath(const std::filesystem::path& sourcePath,
|
||||
bool isFolder,
|
||||
SourceAssetRecord& outRecord);
|
||||
bool ReadMetaFile(const std::filesystem::path& metaPath,
|
||||
SourceAssetRecord& inOutRecord) const;
|
||||
void WriteMetaFile(const std::filesystem::path& metaPath,
|
||||
const SourceAssetRecord& record) const;
|
||||
|
||||
Containers::String NormalizeRelativePath(const std::filesystem::path& sourcePath) const;
|
||||
static Containers::String NormalizePathString(const std::filesystem::path& path);
|
||||
static Containers::String NormalizePathString(const Containers::String& path);
|
||||
static Containers::String MakeKey(const Containers::String& path);
|
||||
static Containers::String GetImporterNameForPath(const Containers::String& relativePath, bool isFolder);
|
||||
static ResourceType GetPrimaryResourceTypeForImporter(const Containers::String& importerName);
|
||||
|
||||
bool ShouldReimport(const SourceAssetRecord& sourceRecord,
|
||||
const ArtifactRecord* artifactRecord) const;
|
||||
bool ImportAsset(const SourceAssetRecord& sourceRecord,
|
||||
ArtifactRecord& outRecord);
|
||||
bool ImportTextureAsset(const SourceAssetRecord& sourceRecord,
|
||||
ArtifactRecord& outRecord);
|
||||
bool ImportModelAsset(const SourceAssetRecord& sourceRecord,
|
||||
ArtifactRecord& outRecord);
|
||||
|
||||
Containers::String BuildArtifactKey(const SourceAssetRecord& sourceRecord) const;
|
||||
Containers::String BuildArtifactDirectory(const Containers::String& artifactKey) const;
|
||||
static Containers::String ReadWholeFileText(const std::filesystem::path& path);
|
||||
static Containers::String ComputeFileHash(const std::filesystem::path& path);
|
||||
static Core::uint64 GetFileSizeValue(const std::filesystem::path& path);
|
||||
static Core::uint64 GetFileWriteTimeValue(const std::filesystem::path& path);
|
||||
|
||||
Containers::String m_projectRoot;
|
||||
Containers::String m_assetsRoot;
|
||||
Containers::String m_libraryRoot;
|
||||
Containers::String m_sourceDbPath;
|
||||
Containers::String m_artifactDbPath;
|
||||
|
||||
std::unordered_map<std::string, SourceAssetRecord> m_sourcesByPathKey;
|
||||
std::unordered_map<AssetGUID, SourceAssetRecord> m_sourcesByGuid;
|
||||
std::unordered_map<AssetGUID, ArtifactRecord> m_artifactsByGuid;
|
||||
};
|
||||
|
||||
} // namespace Resources
|
||||
} // namespace XCEngine
|
||||
54
engine/include/XCEngine/Core/Asset/AssetGUID.h
Normal file
54
engine/include/XCEngine/Core/Asset/AssetGUID.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Core/Containers/String.h>
|
||||
#include <XCEngine/Core/Types.h>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Resources {
|
||||
|
||||
struct AssetGUID {
|
||||
Core::uint64 high = 0;
|
||||
Core::uint64 low = 0;
|
||||
|
||||
AssetGUID() = default;
|
||||
AssetGUID(Core::uint64 inHigh, Core::uint64 inLow)
|
||||
: high(inHigh), low(inLow) {}
|
||||
|
||||
bool IsValid() const {
|
||||
return high != 0 || low != 0;
|
||||
}
|
||||
|
||||
bool operator==(const AssetGUID& other) const {
|
||||
return high == other.high && low == other.low;
|
||||
}
|
||||
|
||||
bool operator!=(const AssetGUID& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
static AssetGUID Generate();
|
||||
static bool TryParse(const Containers::String& text, AssetGUID& outGuid);
|
||||
static AssetGUID ParseOrDefault(const Containers::String& text);
|
||||
|
||||
Containers::String ToString() const;
|
||||
};
|
||||
|
||||
using LocalID = Core::uint64;
|
||||
|
||||
constexpr LocalID kInvalidLocalID = 0;
|
||||
constexpr LocalID kMainAssetLocalID = 1;
|
||||
|
||||
AssetGUID HashBytesToAssetGUID(const void* data, size_t size);
|
||||
AssetGUID HashStringToAssetGUID(const Containers::String& text);
|
||||
|
||||
} // namespace Resources
|
||||
} // namespace XCEngine
|
||||
|
||||
namespace std {
|
||||
template<>
|
||||
struct hash<XCEngine::Resources::AssetGUID> {
|
||||
size_t operator()(const XCEngine::Resources::AssetGUID& guid) const noexcept {
|
||||
return static_cast<size_t>(guid.high ^ (guid.low * 0x9e3779b97f4a7c15ULL));
|
||||
}
|
||||
};
|
||||
}
|
||||
46
engine/include/XCEngine/Core/Asset/AssetRef.h
Normal file
46
engine/include/XCEngine/Core/Asset/AssetRef.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Core/Asset/AssetGUID.h>
|
||||
#include <XCEngine/Core/Asset/ResourceTypes.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Resources {
|
||||
|
||||
struct AssetRef {
|
||||
AssetGUID assetGuid;
|
||||
LocalID localID = kInvalidLocalID;
|
||||
ResourceType resourceType = ResourceType::Unknown;
|
||||
|
||||
bool IsValid() const {
|
||||
return assetGuid.IsValid() && localID != kInvalidLocalID && resourceType != ResourceType::Unknown;
|
||||
}
|
||||
|
||||
void Reset() {
|
||||
assetGuid = AssetGUID();
|
||||
localID = kInvalidLocalID;
|
||||
resourceType = ResourceType::Unknown;
|
||||
}
|
||||
|
||||
Containers::String ToString() const {
|
||||
if (!IsValid()) {
|
||||
return Containers::String();
|
||||
}
|
||||
|
||||
return assetGuid.ToString() + ":" + Containers::String(std::to_string(localID).c_str()) +
|
||||
":" + Containers::String(GetResourceTypeName(resourceType));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
AssetRef MakeMainAssetRef(const AssetGUID& assetGuid) {
|
||||
AssetRef ref;
|
||||
ref.assetGuid = assetGuid;
|
||||
ref.localID = kMainAssetLocalID;
|
||||
ref.resourceType = GetResourceType<T>();
|
||||
return ref;
|
||||
}
|
||||
|
||||
} // namespace Resources
|
||||
} // namespace XCEngine
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Core/IO/IResourceLoader.h>
|
||||
#include "AssetDatabase.h"
|
||||
#include "ResourceCache.h"
|
||||
#include "AsyncLoader.h"
|
||||
#include "ResourceHandle.h"
|
||||
@@ -28,33 +29,26 @@ public:
|
||||
template<typename T>
|
||||
ResourceHandle<T> Load(const Containers::String& path, ImportSettings* settings = nullptr) {
|
||||
static_assert(std::is_base_of_v<IResource, T>, "T must derive from IResource");
|
||||
|
||||
ResourceGUID guid = ResourceGUID::Generate(path);
|
||||
|
||||
IResource* cached = FindInCache(guid);
|
||||
if (cached) {
|
||||
return ResourceHandle<T>(static_cast<T*>(cached));
|
||||
}
|
||||
|
||||
IResourceLoader* loader = FindLoader(GetResourceType<T>());
|
||||
if (!loader) {
|
||||
Debug::Logger::Get().Warning(Debug::LogCategory::FileSystem,
|
||||
Containers::String("No loader found for resource type: ") +
|
||||
GetResourceTypeName(GetResourceType<T>()));
|
||||
|
||||
LoadResult result = LoadResource(path, GetResourceType<T>(), settings);
|
||||
if (!result || result.resource == nullptr) {
|
||||
return ResourceHandle<T>();
|
||||
}
|
||||
|
||||
LoadResult result = loader->Load(path, settings);
|
||||
if (!result) {
|
||||
Debug::Logger::Get().Error(Debug::LogCategory::FileSystem,
|
||||
Containers::String("Failed to load resource: ") + path + " - " + result.errorMessage);
|
||||
return ResourceHandle<T>();
|
||||
}
|
||||
|
||||
AddToCache(guid, result.resource);
|
||||
|
||||
|
||||
return ResourceHandle<T>(static_cast<T*>(result.resource));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
ResourceHandle<T> Load(const AssetRef& assetRef, ImportSettings* settings = nullptr) {
|
||||
static_assert(std::is_base_of_v<IResource, T>, "T must derive from IResource");
|
||||
|
||||
Containers::String path;
|
||||
if (!assetRef.IsValid() || !m_assetDatabase.TryGetPrimaryAssetPath(assetRef.assetGuid, path)) {
|
||||
return ResourceHandle<T>();
|
||||
}
|
||||
|
||||
return Load<T>(path, settings);
|
||||
}
|
||||
|
||||
void LoadAsync(const Containers::String& path, ResourceType type,
|
||||
std::function<void(LoadResult)> callback);
|
||||
@@ -102,6 +96,8 @@ public:
|
||||
|
||||
Containers::Array<Containers::String> GetResourcePaths() const;
|
||||
void UnloadGroup(const Containers::Array<ResourceGUID>& guids);
|
||||
void RefreshAssetDatabase();
|
||||
bool TryGetAssetRef(const Containers::String& path, ResourceType resourceType, AssetRef& outRef) const;
|
||||
|
||||
private:
|
||||
ResourceManager() = default;
|
||||
@@ -111,6 +107,7 @@ private:
|
||||
void AddToCache(ResourceGUID guid, IResource* resource);
|
||||
IResourceLoader* FindLoader(ResourceType type);
|
||||
void ReloadResource(ResourceGUID guid);
|
||||
LoadResult LoadResource(const Containers::String& path, ResourceType type, ImportSettings* settings);
|
||||
|
||||
Containers::String m_resourceRoot;
|
||||
Containers::HashMap<ResourceGUID, IResource*> m_resourceCache;
|
||||
@@ -121,6 +118,7 @@ private:
|
||||
size_t m_memoryUsage = 0;
|
||||
size_t m_memoryBudget = 512 * 1024 * 1024;
|
||||
|
||||
AssetDatabase m_assetDatabase;
|
||||
ResourceCache m_cache;
|
||||
Core::UniqueRef<AsyncLoader> m_asyncLoader;
|
||||
Threading::Mutex m_mutex;
|
||||
|
||||
@@ -38,6 +38,7 @@ public:
|
||||
bool Insert(Pair&& pair);
|
||||
bool Erase(const Key& key);
|
||||
void Clear();
|
||||
Array<Pair> GetPairs() const;
|
||||
|
||||
size_t Size() const { return m_size; }
|
||||
bool Empty() const { return m_size == 0; }
|
||||
@@ -274,6 +275,19 @@ void HashMap<Key, Value>::Clear() {
|
||||
m_size = 0;
|
||||
}
|
||||
|
||||
template<typename Key, typename Value>
|
||||
Array<typename HashMap<Key, Value>::Pair> HashMap<Key, Value>::GetPairs() const {
|
||||
Array<Pair> pairs;
|
||||
pairs.Reserve(m_size);
|
||||
for (size_t bucketIndex = 0; bucketIndex < m_buckets.Size(); ++bucketIndex) {
|
||||
const Bucket& bucket = m_buckets[bucketIndex];
|
||||
for (size_t pairIndex = 0; pairIndex < bucket.pairs.Size(); ++pairIndex) {
|
||||
pairs.PushBack(bucket.pairs[pairIndex]);
|
||||
}
|
||||
}
|
||||
return pairs;
|
||||
}
|
||||
|
||||
template<typename Key, typename Value>
|
||||
size_t HashMap<Key, Value>::GetBucketIndex(const Key& key) const {
|
||||
if (m_bucketCount == 0) {
|
||||
|
||||
34
engine/include/XCEngine/Resources/BuiltinResources.h
Normal file
34
engine/include/XCEngine/Resources/BuiltinResources.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Core/IO/IResourceLoader.h>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Resources {
|
||||
|
||||
enum class BuiltinPrimitiveType {
|
||||
Cube,
|
||||
Sphere,
|
||||
Capsule,
|
||||
Cylinder,
|
||||
Plane,
|
||||
Quad
|
||||
};
|
||||
|
||||
bool IsBuiltinResourcePath(const Containers::String& path);
|
||||
bool IsBuiltinMeshPath(const Containers::String& path);
|
||||
bool IsBuiltinMaterialPath(const Containers::String& path);
|
||||
bool IsBuiltinTexturePath(const Containers::String& path);
|
||||
|
||||
const char* GetBuiltinPrimitiveDisplayName(BuiltinPrimitiveType primitiveType);
|
||||
Containers::String GetBuiltinPrimitiveMeshPath(BuiltinPrimitiveType primitiveType);
|
||||
Containers::String GetBuiltinDefaultPrimitiveMaterialPath();
|
||||
Containers::String GetBuiltinDefaultPrimitiveTexturePath();
|
||||
|
||||
bool TryParseBuiltinPrimitiveType(const Containers::String& path, BuiltinPrimitiveType& outPrimitiveType);
|
||||
|
||||
LoadResult CreateBuiltinMeshResource(const Containers::String& path);
|
||||
LoadResult CreateBuiltinMaterialResource(const Containers::String& path);
|
||||
LoadResult CreateBuiltinTextureResource(const Containers::String& path);
|
||||
|
||||
} // namespace Resources
|
||||
} // namespace XCEngine
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <XCEngine/Core/Math/Vector3.h>
|
||||
#include <XCEngine/Core/Math/Vector4.h>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Resources {
|
||||
@@ -126,6 +127,17 @@ struct MaterialProperty {
|
||||
MaterialProperty() : type(MaterialPropertyType::Float), refCount(0) {}
|
||||
};
|
||||
|
||||
struct MaterialTagEntry {
|
||||
Containers::String name;
|
||||
Containers::String value;
|
||||
};
|
||||
|
||||
struct MaterialTextureBinding {
|
||||
Containers::String name;
|
||||
Core::uint32 slot = 0;
|
||||
ResourceHandle<Texture> texture;
|
||||
};
|
||||
|
||||
class Material : public IResource {
|
||||
public:
|
||||
Material();
|
||||
@@ -158,6 +170,9 @@ public:
|
||||
void RemoveTag(const Containers::String& name);
|
||||
void ClearTags();
|
||||
Core::uint32 GetTagCount() const { return static_cast<Core::uint32>(m_tags.Size()); }
|
||||
Containers::String GetTagName(Core::uint32 index) const;
|
||||
Containers::String GetTagValue(Core::uint32 index) const;
|
||||
const Containers::Array<MaterialTagEntry>& GetTags() const { return m_tags; }
|
||||
|
||||
void SetFloat(const Containers::String& name, float value);
|
||||
void SetFloat2(const Containers::String& name, const Math::Vector2& value);
|
||||
@@ -175,7 +190,11 @@ public:
|
||||
bool GetBool(const Containers::String& name) const;
|
||||
ResourceHandle<Texture> GetTexture(const Containers::String& name) const;
|
||||
Core::uint32 GetTextureBindingCount() const { return static_cast<Core::uint32>(m_textureBindings.Size()); }
|
||||
|
||||
Containers::String GetTextureBindingName(Core::uint32 index) const;
|
||||
ResourceHandle<Texture> GetTextureBindingTexture(Core::uint32 index) const;
|
||||
const Containers::Array<MaterialTextureBinding>& GetTextureBindings() const { return m_textureBindings; }
|
||||
std::vector<MaterialProperty> GetProperties() const;
|
||||
|
||||
const Containers::Array<Core::uint8>& GetConstantBufferData() const { return m_constantBufferData; }
|
||||
void UpdateConstantBuffer();
|
||||
void RecalculateMemorySize();
|
||||
@@ -191,20 +210,10 @@ private:
|
||||
Core::int32 m_renderQueue = static_cast<Core::int32>(MaterialRenderQueue::Geometry);
|
||||
MaterialRenderState m_renderState;
|
||||
Containers::String m_shaderPass;
|
||||
struct TagEntry {
|
||||
Containers::String name;
|
||||
Containers::String value;
|
||||
};
|
||||
Containers::Array<TagEntry> m_tags;
|
||||
Containers::Array<MaterialTagEntry> m_tags;
|
||||
Containers::HashMap<Containers::String, MaterialProperty> m_properties;
|
||||
Containers::Array<Core::uint8> m_constantBufferData;
|
||||
|
||||
struct TextureBinding {
|
||||
Containers::String name;
|
||||
Core::uint32 slot;
|
||||
ResourceHandle<Texture> texture;
|
||||
};
|
||||
Containers::Array<TextureBinding> m_textureBindings;
|
||||
Containers::Array<MaterialTextureBinding> m_textureBindings;
|
||||
};
|
||||
|
||||
} // namespace Resources
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <XCEngine/Resources/Texture/Texture.h>
|
||||
#include <XCEngine/Resources/Texture/TextureLoader.h>
|
||||
#include <XCEngine/Resources/Texture/TextureImportSettings.h>
|
||||
#include <XCEngine/Resources/BuiltinResources.h>
|
||||
#include <XCEngine/Resources/Mesh/Mesh.h>
|
||||
#include <XCEngine/Resources/Mesh/MeshLoader.h>
|
||||
#include <XCEngine/Resources/Mesh/MeshImportSettings.h>
|
||||
|
||||
Reference in New Issue
Block a user