diff --git a/engine/3rdparty/zlib/include/refl/macro.h b/engine/3rdparty/zlib/include/refl/macro.h index 9e7cc7f..1a852ce 100644 --- a/engine/3rdparty/zlib/include/refl/macro.h +++ b/engine/3rdparty/zlib/include/refl/macro.h @@ -28,6 +28,9 @@ #define USING_OVERLOAD_CLASS_FUNC(R, Class, ...) using USING_FUNC_NAME = R(Class::*)(__VA_ARGS__); #define REGISTER_META_TABLE(Class) refl::UClass::MetaTable.emplace(type_name().View(), &refl::TypeInfo::StaticClass); + +#define REFL_FRIEND(Class) friend class refl_impl::_Static;\ +friend class refl_impl::_Meta; /* struct vec3{ USING_OVERLOAD_CTOR(vec3) diff --git a/engine/assets/file_flag.meta b/engine/assets/file_flag.meta new file mode 100644 index 0000000..e69de29 diff --git a/engine/assets/models/.asset b/engine/assets/models/.asset new file mode 100644 index 0000000..117b300 --- /dev/null +++ b/engine/assets/models/.asset @@ -0,0 +1,2 @@ +- name: engineapi::Mesh + data: "" \ No newline at end of file diff --git a/engine/assets/models/box.ply.asset b/engine/assets/models/box.ply.asset new file mode 100644 index 0000000..c67e139 --- /dev/null +++ b/engine/assets/models/box.ply.asset @@ -0,0 +1,2 @@ +- name: engineapi::Mesh + data: "mMaterial:\n guid: 00000000-0000-0000-0000-000000000000" \ No newline at end of file diff --git a/engine/assets/models/box.ply.meta b/engine/assets/models/box.ply.meta new file mode 100644 index 0000000..f8ae790 --- /dev/null +++ b/engine/assets/models/box.ply.meta @@ -0,0 +1,9 @@ +metadatas: + - guid: a5943c25-1ce8-44dc-ae99-4071d07ecb63 + name: "" + t_hash: engineapi::Model + t_meta: "" + - guid: 77b7a000-ed3c-4271-ae30-5e91346e09f4 + name: "" + t_hash: engineapi::Asset + t_meta: engineapi::Mesh \ No newline at end of file diff --git a/engine/assets/models/cube.obj.asset b/engine/assets/models/cube.obj.asset new file mode 100644 index 0000000..117b300 --- /dev/null +++ b/engine/assets/models/cube.obj.asset @@ -0,0 +1,2 @@ +- name: engineapi::Mesh + data: "" \ No newline at end of file diff --git a/engine/assets/models/cube.obj.meta b/engine/assets/models/cube.obj.meta new file mode 100644 index 0000000..ab8bf58 --- /dev/null +++ b/engine/assets/models/cube.obj.meta @@ -0,0 +1,9 @@ +metadatas: + - guid: 80671c54-88f9-41c7-948a-a72cdf3727d3 + name: "" + t_hash: engineapi::Model + t_meta: "" + - guid: 54e69c4b-16ea-4fb8-87d6-0e2383d093b0 + name: defaultobject + t_hash: engineapi::Asset + t_meta: engineapi::Mesh \ No newline at end of file diff --git a/engine/assets/shader/simple.frag.meta b/engine/assets/shader/simple.frag.meta new file mode 100644 index 0000000..f024419 --- /dev/null +++ b/engine/assets/shader/simple.frag.meta @@ -0,0 +1,5 @@ +metadatas: + - guid: eb1c9b43-a86b-40cb-9b3d-a3296d168c70 + name: "" + t_hash: engineapi::ShaderProgram + metadata: "" \ No newline at end of file diff --git a/engine/assets/shader/simple.vert.meta b/engine/assets/shader/simple.vert.meta new file mode 100644 index 0000000..7a9d7c0 --- /dev/null +++ b/engine/assets/shader/simple.vert.meta @@ -0,0 +1,5 @@ +metadatas: + - guid: 9419e2a5-ddc4-414f-aa76-d08e9b162492 + name: "" + t_hash: engineapi::ShaderProgram + metadata: "" \ No newline at end of file diff --git a/engine/cpp_input.h b/engine/cpp_input.h new file mode 100644 index 0000000..f3e817e --- /dev/null +++ b/engine/cpp_input.h @@ -0,0 +1,22 @@ + +#pragma once +//#include "meta/variant.inl" +//#include "meta/tuple.inl" +//#include "meta/comparable.inl" +//#include "meta/hash.h" +//#include "zstd/span.h" +//#include "zstd/table.h" +//#include +//#include +namespace engineapi { + using namespace meta; + using zstd::span; + using std::vector; + using std::array; + using zstd::table; + using zstd::hash_table; + template + using opt = std::optional; + template + using sfinae = std::enable_if_t; +} diff --git a/engine/src/engine/app.cpp b/engine/src/engine/app.cpp index a8cb0ef..f01fb19 100644 --- a/engine/src/engine/app.cpp +++ b/engine/src/engine/app.cpp @@ -28,6 +28,9 @@ namespace engineapi { for (auto system : SystemList) { system->Init(); } + for (auto system : SystemList) { + system->LateInit(); + } } void App::Shutdown() { diff --git a/engine/src/engine/asset/asset.cpp b/engine/src/engine/asset/asset.cpp index b6bc00a..d036b98 100644 --- a/engine/src/engine/asset/asset.cpp +++ b/engine/src/engine/asset/asset.cpp @@ -1,6 +1,10 @@ #include "assert.h" +#include "asset_loader.h" #include "render/asset/shader.h" +#include "render/asset/model.h" #include "resource_manager.h" +#include "object/loader/assimp_loader.h" +#include "yaml/yaml.h" namespace engineapi { MetaBundle ResourceManager::GetVisitMeta(const ResourceBundle& bundle) { @@ -9,4 +13,10 @@ namespace engineapi { std::visit([&](auto& handle) { new_meta.Add(handle); }, elem); return new_meta; } + void Asset::__Init__() + { + YAML::TextArchive::Register(); + AssimpLoader::Init(); + AssetLoader::Init(); + } } \ No newline at end of file diff --git a/engine/src/engine/asset/asset.h b/engine/src/engine/asset/asset.h index d5211ff..153f28a 100644 --- a/engine/src/engine/asset/asset.h +++ b/engine/src/engine/asset/asset.h @@ -1,11 +1,22 @@ #pragma once #include "render/asset_struct.h" -#include "res/resource_handle.h" -#include "res/package_path.h" +#include "resource_manager.h" namespace engineapi { class Asset : public Resource { + private: + static void __Init__(); + friend class FileManager; public: using Base = Resource; - using Base::Base; + const refl::UClass* meta; + Asset(const refl::UClass* meta): Base(), meta(meta){} }; + template<> + inline void MetaBundle::Add(RscHandle h) + { + if (h) + { + metadatas.emplace_back(SerializedMeta{ h.guid, string(h->Name()), string(type_name().View()), string(h->meta->name)}); + } + } } \ No newline at end of file diff --git a/engine/src/engine/asset/asset_loader.cpp b/engine/src/engine/asset/asset_loader.cpp new file mode 100644 index 0000000..a4c5f93 --- /dev/null +++ b/engine/src/engine/asset/asset_loader.cpp @@ -0,0 +1,25 @@ +#include "asset_loader.h" +#include "file_manager.h" +#include "yaml/yaml.h" +#include +namespace engineapi { + void AssetLoader::Init() { + ResourceManager::GetSingleton().RegisterLoader(".asset"); + } + ResourceBundle AssetLoader::LoadFile(PackagePath handle, const MetaBundle& meta) + { + return ResourceBundle(); + } + void AssetLoader::SaveFile(PackagePath handle, const ResourceBundle& bundle) + { + YAML::Node result; + for (auto& elem : bundle.GetAll()) { + RscHandle handle = elem.AsHandle(); + YAML::Node meta; + meta["name"] = string(handle->meta->name); + meta["data"] = YAML::Text_Serialize(refl::Any{handle.res, handle->meta}); + result.push_back(meta); + } + FileManager::SaveTextFile(handle, YAML::Dump(result)); + } +} diff --git a/engine/src/engine/asset/asset_loader.h b/engine/src/engine/asset/asset_loader.h new file mode 100644 index 0000000..732e506 --- /dev/null +++ b/engine/src/engine/asset/asset_loader.h @@ -0,0 +1,10 @@ +#pragma once +#include "asset.h" +namespace engineapi { + class AssetLoader :public IFileLoader{ + public: + static void Init(); + ResourceBundle LoadFile(PackagePath handle, const MetaBundle& meta) override; + void SaveFile(PackagePath handle, const ResourceBundle& bundle) override; + }; +} \ No newline at end of file diff --git a/engine/src/engine/asset/file_manager.cpp b/engine/src/engine/asset/file_manager.cpp index 17655cb..ccea8a5 100644 --- a/engine/src/engine/asset/file_manager.cpp +++ b/engine/src/engine/asset/file_manager.cpp @@ -7,12 +7,13 @@ namespace engineapi { { std::filesystem::path path = std::filesystem::current_path(); Mount("engine", path.string()); + Asset::__Init__(); } void FileManager::Shutdown() { } - string FileManager::real_path(const PackagePath& pack_path) + string FileManager::RealPath(const PackagePath& pack_path) { string_view name = pack_path.ParsePackage(); string_view pre_path = FindMountPath(name); @@ -40,7 +41,7 @@ namespace engineapi { file.exceptions(ifstream::failbit | ifstream::badbit); try { - string path = real_path(pack_path); + string path = RealPath(pack_path); file.open(path); stringstream stream; stream << file.rdbuf(); @@ -54,7 +55,7 @@ namespace engineapi { } result,FileFlag> FileManager::LoadBinaryFile(const PackagePath& pack_path) { - string path = real_path(pack_path); + string path = RealPath(pack_path); // ate:在文件末尾开始读取,从文件末尾开始读取的优点是我们可以使用读取位置来确定文件的大小并分配缓冲区 ifstream file(path, std::ios::ate | std::ios::binary); if (!file.is_open()) { @@ -74,7 +75,7 @@ namespace engineapi { } result FileManager::LoadJsonFile(const PackagePath& pack_path) { - string path = real_path(pack_path); + string path = RealPath(pack_path); std::ifstream f(path); if (!f.is_open()) { @@ -96,7 +97,7 @@ namespace engineapi { } void FileManager::SaveTextFile(const PackagePath& pack_path,const string& value) { - string path = real_path(pack_path); + string path = RealPath(pack_path); std::ofstream of(path); of.write(value.data(), value.size()); } diff --git a/engine/src/engine/asset/file_manager.h b/engine/src/engine/asset/file_manager.h index c9a080e..8d0e8cb 100644 --- a/engine/src/engine/asset/file_manager.h +++ b/engine/src/engine/asset/file_manager.h @@ -63,9 +63,10 @@ namespace engineapi private: inline static table> MountMap; inline static table FileMap; - //外界不应该使用绝对路径 - static string real_path(const PackagePath& pack_path); public: + //外界不应该使用绝对路径 + static string RealPath(const PackagePath& pack_path); + static FileFlag LoadErrorFlag(const PackagePath& pack_path); static result LoadTextFile(const PackagePath& pack_path); diff --git a/engine/src/engine/asset/res/meta_bundle.h b/engine/src/engine/asset/res/meta_bundle.h index bc30c85..abaf1c3 100644 --- a/engine/src/engine/asset/res/meta_bundle.h +++ b/engine/src/engine/asset/res/meta_bundle.h @@ -13,9 +13,9 @@ namespace engineapi UPROPERTY({}) string t_hash{}; UPROPERTY({}) - string metadata; + string t_meta; bool operator==(const SerializedMeta& other)const{ - return guid == other.guid && name == other.name && t_hash == other.t_hash && metadata == other.metadata; + return guid == other.guid && name == other.name && t_hash == other.t_hash && t_meta == other.t_meta; } }; struct ResourceBundle; @@ -29,6 +29,8 @@ namespace engineapi template const SerializedMeta* FetchMeta() const; template + const SerializedMeta* FetchMeta(const string_view& asset_name) const; + template void Add(RscHandle); bool operator==(const MetaBundle& other)const; bool operator!=(const MetaBundle& other)const; diff --git a/engine/src/engine/asset/res/meta_bundle.inl b/engine/src/engine/asset/res/meta_bundle.inl index 9eba3a7..7a33bdb 100644 --- a/engine/src/engine/asset/res/meta_bundle.inl +++ b/engine/src/engine/asset/res/meta_bundle.inl @@ -4,10 +4,21 @@ namespace engineapi template inline const SerializedMeta* MetaBundle::FetchMeta() const { - string_view name = type_name().View(); + string_view name = type_name().View(); for (auto& elem : metadatas) { - if (string_view(elem.t_hash) == name) + if (elem.t_hash == name) + return &elem; + } + return nullptr; + } + template + inline const SerializedMeta* MetaBundle::FetchMeta(const string_view& asset_name) const + { + string_view name = type_name().View(); + for (auto& elem : metadatas) + { + if (elem.t_hash == name && asset_name == elem.name) return &elem; } return nullptr; @@ -17,7 +28,7 @@ namespace engineapi { if (h) { - metadatas.emplace_back(SerializedMeta{ h.guid, string{h->Name()}, string{type_name().View()}}); + metadatas.emplace_back(SerializedMeta{ h.guid, string(h->Name()), string(type_name().View()) }); } } } \ No newline at end of file diff --git a/engine/src/engine/asset/res/package_path.cpp b/engine/src/engine/asset/res/package_path.cpp index d71217c..d53ff38 100644 --- a/engine/src/engine/asset/res/package_path.cpp +++ b/engine/src/engine/asset/res/package_path.cpp @@ -17,5 +17,9 @@ namespace engineapi { { return PackagePath{ FileManager::FindPathView(path) }; } + string PackagePath::RealPath() const + { + return FileManager::RealPath(*this); + } } diff --git a/engine/src/engine/asset/res/package_path.h b/engine/src/engine/asset/res/package_path.h index 5c9a59c..e999283 100644 --- a/engine/src/engine/asset/res/package_path.h +++ b/engine/src/engine/asset/res/package_path.h @@ -23,6 +23,7 @@ namespace engineapi PackagePath() {}; PackagePath(const char* path) : path(path) {} PackagePath(const string_view& path) : path(path) {} + PackagePath(const string& path) : path(path) {} PackagePath(const string&& path) : path(path) {} size_t size() const{ return path.size(); @@ -54,5 +55,6 @@ namespace engineapi } PackagePath ToSuffixPath(const string_view& suffix)const; PackagePath SafePath()const; + string RealPath()const; }; } \ No newline at end of file diff --git a/engine/src/engine/asset/res/resource_bundle.h b/engine/src/engine/asset/res/resource_bundle.h index 1fde3ac..8118340 100644 --- a/engine/src/engine/asset/res/resource_bundle.h +++ b/engine/src/engine/asset/res/resource_bundle.h @@ -3,7 +3,6 @@ namespace engineapi { struct GenericResourceHandle; - struct ResourceBundle { ResourceBundle() = default; @@ -13,6 +12,7 @@ namespace engineapi template void Add(RscHandle handle); template RscHandle Get() const; // get a resource from the bundle span GetAll() const; // gets absolutely all resources + template span GetAll() const; // get all resources of one type private: struct sub_array { short index = 0, count = 0; }; diff --git a/engine/src/engine/asset/res/resource_bundle.inl b/engine/src/engine/asset/res/resource_bundle.inl index 7132eec..ecd5565 100644 --- a/engine/src/engine/asset/res/resource_bundle.inl +++ b/engine/src/engine/asset/res/resource_bundle.inl @@ -1,5 +1,4 @@ #pragma once -#include "resource_bundle.h" namespace engineapi { template @@ -31,9 +30,13 @@ namespace engineapi } template - inline RscHandle engineapi::ResourceBundle::Get() const + inline RscHandle ResourceBundle::Get() const { auto& subarray = subarrays[ResourceID]; return subarray.count > 0 ? handles[subarray.index].template AsHandle() : RscHandle(); } + template span ResourceBundle::GetAll() const { + auto& subarray = subarrays[ResourceID]; + return span{handles.data() + subarray.index, handles.data() + subarray.index + subarray.count}; + } } \ No newline at end of file diff --git a/engine/src/engine/asset/res/resource_config.h b/engine/src/engine/asset/res/resource_config.h index e89af7a..c1932c3 100644 --- a/engine/src/engine/asset/res/resource_config.h +++ b/engine/src/engine/asset/res/resource_config.h @@ -1,6 +1,7 @@ #pragma once #include "type.h" namespace engineapi { + class Guid; template struct RscHandle; template @@ -8,7 +9,7 @@ namespace engineapi { { public: using BaseResource = Res; - + Guid GetGuid()const; RscHandle GetHandle() const { return mHandle; } Resource() = default; @@ -21,6 +22,7 @@ namespace engineapi { }; using Resources = std::tuple< class ShaderProgram + , class Model , class Asset >; template diff --git a/engine/src/engine/asset/res/resource_handle.h b/engine/src/engine/asset/res/resource_handle.h index f09c38e..0b20fff 100644 --- a/engine/src/engine/asset/res/resource_handle.h +++ b/engine/src/engine/asset/res/resource_handle.h @@ -4,18 +4,21 @@ namespace engineapi { + struct RscHandleBase { + UPROPERTY({}) + Guid guid; + void* res; + }; template - struct RscHandle + struct RscHandle : public RscHandleBase { - Guid guid{}; - void* res{}; constexpr size_t RscID()const { return ResourceID; } constexpr RscHandle() noexcept = default; template - constexpr RscHandle(const RscHandle& other) noexcept : guid{ other.guid }, res(other.res) {}; - constexpr RscHandle(const Guid& guid, Res* res) noexcept : guid{ guid }, res(res) { ((Resource*)res)->mHandle = *this; } + constexpr RscHandle(const RscHandle& other) noexcept : RscHandleBase(other.guid, other.res) {}; + constexpr RscHandle(const Guid& guid, Res* res) noexcept : RscHandleBase(guid, res) { ((Resource*)res)->mHandle = *this; } void Init(); - void Clear(){ res = nullptr; }; + void Clear() { res = nullptr; }; Res* operator->() { if (!res && guid) Init(); return (Res*)res; } Res& operator*() { if (!res && guid) Init(); return *(Res*)res; } operator bool() { if (!res && guid) Init(); return res; } @@ -23,34 +26,6 @@ namespace engineapi Res& operator*()const { return *(Res*)res; } operator bool() const { return res; } }; - - struct GenericResourceHandle - : variant_wrap_t, RscHandle> - { - private: - using Base = variant_wrap_t, RscHandle>; - public: - using Base::Base; - using Base::operator=; - template - GenericResourceHandle(RscHandle handle) : Base(RscHandle{handle}) {} - GenericResourceHandle(string_view type_name, Guid guid); - template RscHandle AsHandle() const { - return std::get>(*this); - } - Guid guid() const; - size_t resource_id() const; - }; } -// hashtable support -namespace std -{ - template - struct hash > - { - size_t operator()(const engineapi::RscHandle& res) const noexcept - { - return std::hash()(res.guid); - } - }; -} \ No newline at end of file +#include "resource_handle.inl" +#include "resource_handle_gen.inl" \ No newline at end of file diff --git a/engine/src/engine/asset/res/resource_handle.inl b/engine/src/engine/asset/res/resource_handle.inl new file mode 100644 index 0000000..bf89b14 --- /dev/null +++ b/engine/src/engine/asset/res/resource_handle.inl @@ -0,0 +1,43 @@ +#pragma once +namespace engineapi{ + template + inline Guid Resource::GetGuid() const + { + return GetHandle().guid; + } + struct GenericResourceHandle + : variant_wrap_t, RscHandle> + { + private: + using Base = variant_wrap_t, RscHandle>; + public: + using Base::Base; + using Base::operator=; + template + GenericResourceHandle(RscHandle handle) : Base(RscHandle{handle}) {} + GenericResourceHandle(string_view type_name, Guid guid); + template RscHandle AsHandle() const { + return std::get>(*this); + } + Guid guid() const; + size_t resource_id() const; + }; +} +// hashtable support +namespace std +{ + template + struct hash > + { + size_t operator()(const engineapi::RscHandle& res) const noexcept + { + return std::hash()(res.guid); + } + }; +} +namespace refl { + template + struct real_type> { + using type = engineapi::RscHandleBase; + }; +} \ No newline at end of file diff --git a/engine/src/engine/asset/resource_manager.cpp b/engine/src/engine/asset/resource_manager.cpp index 3cd0512..d7af3c5 100644 --- a/engine/src/engine/asset/resource_manager.cpp +++ b/engine/src/engine/asset/resource_manager.cpp @@ -7,6 +7,11 @@ namespace engineapi { mResourceTable = detail::ResourceHelper::GenResourceTables(); LoadFileFlag(); } + void ResourceManager::LateInit() + { + SaveFileFlag(); + SaveDirtyFiles(); + } void ResourceManager::Shutdown() { constexpr static auto release_tables = detail::ResourceHelper::ReleaseTableResources(); @@ -30,23 +35,26 @@ namespace engineapi { return it->second.bundle; } } + auto& res = mFileTable[path.path]; Name ext = path.GetExtension(); IFileLoader* loader = GetLoader(ext); MetaBundle meta = GetMeta(path); ResourceBundle bundle = loader->LoadFile(path, meta); MetaBundle new_meta = GetVisitMeta(bundle); bool is_dirty_meta = meta != new_meta; - mFileTable[path.path] = {bundle, path.SafePath(), false, is_dirty_meta}; - auto& res = mFileTable[path.path]; for (auto& elem : bundle.GetAll()) { std::visit([&](auto& handle) { using T = std::decay_t; GetControlBlock(handle)->file = &res; }, elem); } - if (is_dirty_meta) { + if (is_dirty_meta || res.is_dirty) { mDirtyBlocks.push_back(&res); } + res.path = path.SafePath(); + res.bundle = bundle; + res.is_meta_dirty = is_dirty_meta; + res.bundle = bundle; return res.bundle; } @@ -74,7 +82,7 @@ namespace engineapi { } else { string text = YAML::Text_Serialize(bundle); - FileManager::SaveTextFile(path, text); + FileManager::SaveTextFile(path + ".meta", text); } } void ResourceManager::SaveDirtyFiles() diff --git a/engine/src/engine/asset/resource_manager.h b/engine/src/engine/asset/resource_manager.h index 8cf9ed0..1807f59 100644 --- a/engine/src/engine/asset/resource_manager.h +++ b/engine/src/engine/asset/resource_manager.h @@ -37,6 +37,7 @@ namespace engineapi { vector mDirtyBlocks; public: void Init() override; + void LateInit()override; void Shutdown() override; public: @@ -47,8 +48,9 @@ namespace engineapi { auto& GetTable() { return *reinterpret_cast*> (mResourceTable[ResourceID].get()); } - template + template ResourceControlBlock* GetControlBlock(RscHandle handle); + FileControlBlock& GetFileBlock(PackagePath path); template [[nodiscard]] RscHandle LoaderEmplaceResource(Args&& ... args) { diff --git a/engine/src/engine/asset/resource_manager.inl b/engine/src/engine/asset/resource_manager.inl index 4f67c82..09936c9 100644 --- a/engine/src/engine/asset/resource_manager.inl +++ b/engine/src/engine/asset/resource_manager.inl @@ -1,4 +1,3 @@ -#include "resource_manager.h" #pragma once namespace engineapi { class IFileLoader @@ -97,6 +96,9 @@ namespace engineapi { auto& table = GetTable(); return &table[handle.guid]; } + inline ResourceManager::FileControlBlock& ResourceManager::GetFileBlock(PackagePath path) { + return mFileTable[NameID(path.path)]; + } template inline void RscHandle::Init() { diff --git a/engine/src/engine/object/loader/assimp_loader.cpp b/engine/src/engine/object/loader/assimp_loader.cpp new file mode 100644 index 0000000..0f478e3 --- /dev/null +++ b/engine/src/engine/object/loader/assimp_loader.cpp @@ -0,0 +1,149 @@ +#include "zlog.h" +#include "assimp_loader.h" +#include "asset/file_manager.h" +#include "asset/resource_manager.h" +#include "assimp/Importer.hpp" +#include "assimp/scene.h" +#include "assimp/postprocess.h" +#include +namespace engineapi { + void AssimpLoader::Init() + { + ResourceManager::GetSingleton().RegisterLoader(".obj"); + ResourceManager::GetSingleton().RegisterLoader(".ply"); + } + ResourceBundle AssimpLoader::LoadFile(PackagePath handle, const MetaBundle& meta) + { + auto m = meta.FetchMeta(); + auto asset = m ? ResourceManager::GetSingleton().LoaderEmplaceResource(m->guid) + : ResourceManager::GetSingleton().LoaderEmplaceResource(); + uint32_t flag = FileManager::FindPathFlag(handle); + if (flag & FileFlag::File_Http) { + return {}; + } + LoadModel(handle, *asset, meta); + ResourceBundle bundle{ asset }; + for (auto& mesh : asset->GetMeshs()) { + bundle.Add(mesh); + } + PackagePath asset_handle(handle + ".asset"); + std::ifstream file(asset_handle.RealPath()); + if (!file.good()) { + auto& block = ResourceManager::GetSingleton().GetFileBlock(handle); + block.is_dirty = true; + } + return bundle; + } + void AssimpLoader::SaveFile(PackagePath handle, const ResourceBundle& bundle) + { + auto loader = ResourceManager::GetSingleton().GetLoader(".asset"); + if(loader) + loader->SaveFile(handle + ".asset", bundle); + } + void AssimpLoader::LoadModel(PackagePath handle, Model& model, const MetaBundle& meta) + { + // 用ASSIMP加载模型文件 + Assimp::Importer importer; + const aiScene* scene = importer.ReadFile(handle.RealPath(), aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_CalcTangentSpace + | aiProcess_FixInfacingNormals | aiProcess_FlipWindingOrder | aiProcess_LimitBoneWeights); + + // 检查异常 + if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) + { + zlog::error("ASSIMP: {}", importer.GetErrorString()); + return; + } + ProcessNode(model, meta, scene->mRootNode, scene); + } + void AssimpLoader::ProcessNode(Model& model, const MetaBundle& meta, const aiNode* pNode, const aiScene* pScene) + { + // 处理Mesh数据 + auto& meshs = model.GetMeshs(); + for (unsigned int i = 0; i < pNode->mNumMeshes; i++) + { + // aiNode仅包含索引来获取aiScene中的实际对象 + // aiScene包含所有数据,aiNode只是为了让数据组织起来(比如记录节点之间的关系) + aiMesh* mesh = pScene->mMeshes[pNode->mMeshes[i]]; + auto m = meta.FetchMeta(mesh->mName.C_Str()); + meshs.push_back(ProcessMesh(m, mesh)); + } + + // 加载骨骼数据 + //pBoneNode->name = pNode->mName.C_Str(); + //pBoneNode->transform = aiMatrix4x4ToMatrix4(pNode->mTransformation); + + // 递归处理子节点 + for (unsigned int i = 0; i < pNode->mNumChildren; i++) + { + //pBoneNode->children.push_back(new BoneNode()); + ProcessNode(model, meta, pNode->mChildren[i], pScene); + } + } + RscHandle AssimpLoader::ProcessMesh(const SerializedMeta* m, const aiMesh* mesh) + { + // data to fill + vector vertices; + vector indices; + // Walk through each of the mesh's vertices + for (unsigned int i = 0; i < mesh->mNumVertices; i++) + { + BoneVertex vertex; + Vector3 vector; // we declare a placeholder vector since assimp uses its own vector class that doesn't directly convert to Vector3 class so we transfer the data to this placeholder Vector3 first. + + // positions + vector.x = mesh->mVertices[i].x; + vector.y = mesh->mVertices[i].y; + vector.z = mesh->mVertices[i].z; + vertex.Position = vector; + + // normals + vector.x = mesh->mNormals[i].x; + vector.y = mesh->mNormals[i].y; + vector.z = mesh->mNormals[i].z; + vertex.Normal = vector; + + // texture coordinates + if (mesh->mTextureCoords[0]) // does the mesh contain texture coordinates? + { + Vector2 vec; + // a vertex can contain up to 8 different texture coordinates. We thus make the assumption that we won't + // use models where a vertex can have multiple texture coordinates so we always take the first set (0). + vec.x = mesh->mTextureCoords[0][i].x; + vec.y = mesh->mTextureCoords[0][i].y; + vertex.TexCoords = vec; + } + else + { + vertex.TexCoords = Vector2(0.0f, 0.0f); + } + + // tangent and bitangent + if (mesh->HasTangentsAndBitangents()) + { + vector.x = mesh->mTangents[i].x; + vector.y = mesh->mTangents[i].y; + vector.z = mesh->mTangents[i].z; + vertex.Tangent = vector; + } + else + { + vertex.Tangent = Vector3(0.0f, 0.0f, 0.0f); + } + vertices.push_back(vertex); + } + // now wak through each of the mesh's faces (a face is a mesh its triangle) and retrieve the corresponding vertex indices. + for (unsigned int i = 0; i < mesh->mNumFaces; i++) + { + const aiFace& face = mesh->mFaces[i]; + // retrieve all indices of the face and store them in the indices vector + for (unsigned int j = 0; j < face.mNumIndices; j++) + { + indices.push_back(face.mIndices[j]); + } + } + auto asset = m ? ResourceManager::GetSingleton().LoaderEmplaceResource(m->guid, vertices, indices) + : ResourceManager::GetSingleton().LoaderEmplaceResource(vertices, indices); + asset->Name(mesh->mName.C_Str()); + return asset; + } +} diff --git a/engine/src/engine/object/loader/assimp_loader.h b/engine/src/engine/object/loader/assimp_loader.h new file mode 100644 index 0000000..ac15c55 --- /dev/null +++ b/engine/src/engine/object/loader/assimp_loader.h @@ -0,0 +1,20 @@ +#pragma once +#include "render/asset/model.h" +#include "asset/resource_manager.h" +class aiNode; +class aiMesh; +class aiScene; +namespace engineapi { + class AssimpLoader : public IFileLoader + { + inline static table ShaderTable; + public: + static void Init(); + ResourceBundle LoadFile(PackagePath handle, const MetaBundle& meta) override; + void SaveFile(PackagePath handle, const ResourceBundle& bundle) override; + + void LoadModel(PackagePath handle, Model& model, const MetaBundle& meta); + void ProcessNode(Model& model, const MetaBundle& meta, const aiNode* pNode, const aiScene* pScene); + RscHandle ProcessMesh(const SerializedMeta* m, const aiMesh* mesh); + }; +} \ No newline at end of file diff --git a/engine/src/engine/object/mesh/actor.cpp b/engine/src/engine/object/mesh/actor.cpp index c7a445b..cb83b08 100644 --- a/engine/src/engine/object/mesh/actor.cpp +++ b/engine/src/engine/object/mesh/actor.cpp @@ -1,4 +1,5 @@ #include "actor.h" +#include "asset/resource_manager.h" #include "data/property/actor_property.h" namespace engineapi { ActorMesh::ActorMesh(Model& model, ActorProperty& property) @@ -9,9 +10,8 @@ namespace engineapi { } ActorMesh* ActorMesh::New(ActorProperty& property) { - //Model* model = AssetManager::GetSingletonPtr()->LoadAsset(property.path, property.flags); - //return new ActorMesh(*model, property); - return nullptr; + auto res = ResourceManager::GetSingleton().Load(property.path); + return new ActorMesh(*res, property); } ActorMesh* ActorMesh::New(uint32_t id) { diff --git a/engine/src/engine/object/mesh/static.cpp b/engine/src/engine/object/mesh/static.cpp index 28b0131..d36fe73 100644 --- a/engine/src/engine/object/mesh/static.cpp +++ b/engine/src/engine/object/mesh/static.cpp @@ -8,6 +8,6 @@ namespace engineapi { } void StaticMesh::LoadMesh() { - + mPtr.BeginLoad(); } } \ No newline at end of file diff --git a/engine/src/engine/object/scene/scene.cpp b/engine/src/engine/object/scene/scene.cpp index c69b0c9..24d0517 100644 --- a/engine/src/engine/object/scene/scene.cpp +++ b/engine/src/engine/object/scene/scene.cpp @@ -12,18 +12,19 @@ namespace engineapi { mCamera = new Camera(); int flags = 1; auto shader = ResourceManager::GetSingleton().LoaderEmplaceResource(); - shader->mVertexName = type_name().View(); + shader->Name(type_name().View()); shader->mVert = ResourceManager::GetSingleton().Load("/engine/assets/shader/simple.vert"); shader->mFrag = ResourceManager::GetSingleton().Load("/engine/assets/shader/simple.frag"); - RenderAPI::GetSingleton().LoadShader(&*shader); - Material* material = new Material("/engine/assets/shader/simple.shader", flags); + RenderAPI::GetSingleton().LoadShader(*shader); + //Material* material = new Material("/engine/assets/shader/simple.shader", flags); { ActorProperty property; property.id = 1; property.flags = flags; property.path = "/engine/assets/models/cube.obj"; actor1 = ActorMesh::New(property); - actor1->Ptr().SetMaterial(material); + actor1->LoadMesh(); + //actor1->Ptr().SetMaterial(material); } { ActorProperty property; @@ -31,7 +32,7 @@ namespace engineapi { property.flags = flags; property.path = "/engine/assets/models/box.ply"; actor2 = ActorMesh::New(property); - actor2->Ptr().SetMaterial(material); + //actor2->Ptr().SetMaterial(material); } } Scene::~Scene() @@ -43,11 +44,10 @@ namespace engineapi { void Scene::Render() { RenderAPI::GetSingletonPtr()->Render(*mCamera); - auto meshs = actor1->Ptr().GetMeshs(); - for (auto it : meshs) { - RenderAPI::GetSingletonPtr()->DrawStaticMesh(it); - } - //RenderAPI::GetSingletonPtr()->DrawStaticMesh(actor2); + //auto meshs = actor1->Ptr().GetMeshs(); + //for (auto it : meshs) { + //RenderAPI::GetSingletonPtr()->DrawStaticMesh(*it); + //} } void Scene::AddGameObject(GameObject* gameObject) { diff --git a/engine/src/engine/render/asset/material.cpp b/engine/src/engine/render/asset/material.cpp index ea1bcb6..b1c0a10 100644 --- a/engine/src/engine/render/asset/material.cpp +++ b/engine/src/engine/render/asset/material.cpp @@ -2,9 +2,9 @@ #include "shader.h" #include "../renderapi.h" namespace engineapi { - Material::Material(string_view name, uint32_t flags) + Material::Material() : Asset(&refl::TypeInfo::StaticClass) { - //mShader = new Shader(name, flags); + } Material::~Material() { diff --git a/engine/src/engine/render/asset/material.h b/engine/src/engine/render/asset/material.h index 5cd432f..f6179e6 100644 --- a/engine/src/engine/render/asset/material.h +++ b/engine/src/engine/render/asset/material.h @@ -1,15 +1,18 @@ #pragma once #include "asset/asset.h" - +#include "shader.h" namespace engineapi { - class Shader; class Material : public Asset { protected: - uint32_t mId{0}; - Shader* mShader; + REFL_FRIEND(Material) + UPROPERTY() + RscHandle mShader; public: - Material(string_view name, uint32_t flags); + Material(); ~Material(); - + RscHandle GetShader() { + return mShader; + } }; -}; \ No newline at end of file +}; +#include "material_gen.inl" \ No newline at end of file diff --git a/engine/src/engine/render/asset/mesh.cpp b/engine/src/engine/render/asset/mesh.cpp index 82f2110..7694350 100644 --- a/engine/src/engine/render/asset/mesh.cpp +++ b/engine/src/engine/render/asset/mesh.cpp @@ -3,6 +3,6 @@ namespace engineapi { void Mesh::BeginLoad() { - RenderAPI::GetSingletonPtr()->SetStaticMesh(this); + RenderAPI::GetSingletonPtr()->SetStaticMesh(*this); } } diff --git a/engine/src/engine/render/asset/mesh.h b/engine/src/engine/render/asset/mesh.h index 64a066c..6c4a941 100644 --- a/engine/src/engine/render/asset/mesh.h +++ b/engine/src/engine/render/asset/mesh.h @@ -1,30 +1,28 @@ #pragma once +#include "material.h" +#include "vertex.h" #include "refl/std/parray.h" -#include "asset/asset.h" -#include "../meta/vertex.h" namespace engineapi { using refl::parray; - class Texture; - class Material; - class Mesh : public Asset { + class Mesh : public Asset{ protected: - uint32_t VAO = 0; + REFL_FRIEND(Mesh) + UPROPERTY() + RscHandle mMaterial; parray mVertices; vector mIndices; public: template requires std::is_base_of_v - Mesh(vector& vertices, vector& indices) - : mVertices(vertices) - , mIndices(indices) - { - BeginLoad(); - } + Mesh(vector& vertices, vector& indices); void BeginLoad(); public: - uint32_t& GetVAO() { - return VAO; + Guid GetShaderGuid() { + return mMaterial->GetShader().guid; + } + RscHandle GetMaterial() { + return mMaterial; } parray& GetVertices() { return mVertices; @@ -33,4 +31,14 @@ namespace engineapi { return mIndices; } }; -}; \ No newline at end of file +}; +#include "mesh_gen.inl" +namespace engineapi { + template + requires std::is_base_of_v + inline Mesh::Mesh(vector& vertices, vector& indices) + : Asset(&refl::TypeInfo::StaticClass), mVertices(vertices), mIndices(indices) + { + auto cls = &refl::TypeInfo::StaticClass; + } +} \ No newline at end of file diff --git a/engine/src/engine/render/asset/model.cpp b/engine/src/engine/render/asset/model.cpp index b104756..5c9ea4c 100644 --- a/engine/src/engine/render/asset/model.cpp +++ b/engine/src/engine/render/asset/model.cpp @@ -1,109 +1,10 @@ #include "model.h" -#include "zlog.h" -#include "assimp/Importer.hpp" -#include "assimp/scene.h" -#include "assimp/postprocess.h" namespace engineapi { void Model::BeginLoad() { - string mName = ""; - // 用ASSIMP加载模型文件 - Assimp::Importer importer; - const aiScene* scene = importer.ReadFile(mName, aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_CalcTangentSpace - | aiProcess_FixInfacingNormals | aiProcess_FlipWindingOrder | aiProcess_LimitBoneWeights); - - // 检查异常 - if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) - { - zlog::error("ASSIMP: {}", importer.GetErrorString()); - return; + for (auto mesh : mMeshes) { + mesh->BeginLoad(); } - ProcessNode(scene->mRootNode, scene); - } - void Model::ProcessNode(const aiNode* pNode, const aiScene* pScene) - { - // 处理Mesh数据 - for (unsigned int i = 0; i < pNode->mNumMeshes; i++) - { - // aiNode仅包含索引来获取aiScene中的实际对象 - // aiScene包含所有数据,aiNode只是为了让数据组织起来(比如记录节点之间的关系) - aiMesh* mesh = pScene->mMeshes[pNode->mMeshes[i]]; - mMeshes.push_back(ProcessMesh(mesh)); - } - - // 加载骨骼数据 - //pBoneNode->name = pNode->mName.C_Str(); - //pBoneNode->transform = aiMatrix4x4ToMatrix4(pNode->mTransformation); - - // 递归处理子节点 - for (unsigned int i = 0; i < pNode->mNumChildren; i++) - { - //pBoneNode->children.push_back(new BoneNode()); - ProcessNode(pNode->mChildren[i], pScene); - } - } - Mesh* Model::ProcessMesh(const aiMesh* mesh) { - // data to fill - vector vertices; - vector indices; - // Walk through each of the mesh's vertices - for (unsigned int i = 0; i < mesh->mNumVertices; i++) - { - BoneVertex vertex; - Vector3 vector; // we declare a placeholder vector since assimp uses its own vector class that doesn't directly convert to Vector3 class so we transfer the data to this placeholder Vector3 first. - - // positions - vector.x = mesh->mVertices[i].x; - vector.y = mesh->mVertices[i].y; - vector.z = mesh->mVertices[i].z; - vertex.Position = vector; - - // normals - vector.x = mesh->mNormals[i].x; - vector.y = mesh->mNormals[i].y; - vector.z = mesh->mNormals[i].z; - vertex.Normal = vector; - - // texture coordinates - if (mesh->mTextureCoords[0]) // does the mesh contain texture coordinates? - { - Vector2 vec; - // a vertex can contain up to 8 different texture coordinates. We thus make the assumption that we won't - // use models where a vertex can have multiple texture coordinates so we always take the first set (0). - vec.x = mesh->mTextureCoords[0][i].x; - vec.y = mesh->mTextureCoords[0][i].y; - vertex.TexCoords = vec; - } - else - { - vertex.TexCoords = Vector2(0.0f, 0.0f); - } - - // tangent and bitangent - if (mesh->HasTangentsAndBitangents()) - { - vector.x = mesh->mTangents[i].x; - vector.y = mesh->mTangents[i].y; - vector.z = mesh->mTangents[i].z; - vertex.Tangent = vector; - } - else - { - vertex.Tangent = Vector3(0.0f, 0.0f, 0.0f); - } - vertices.push_back(vertex); - } - // now wak through each of the mesh's faces (a face is a mesh its triangle) and retrieve the corresponding vertex indices. - for (unsigned int i = 0; i < mesh->mNumFaces; i++) - { - const aiFace& face = mesh->mFaces[i]; - // retrieve all indices of the face and store them in the indices vector - for (unsigned int j = 0; j < face.mNumIndices; j++) - { - indices.push_back(face.mIndices[j]); - } - } - return new Mesh(vertices, indices); } void Model::Use() { diff --git a/engine/src/engine/render/asset/model.h b/engine/src/engine/render/asset/model.h index 19de237..528c9b4 100644 --- a/engine/src/engine/render/asset/model.h +++ b/engine/src/engine/render/asset/model.h @@ -1,26 +1,14 @@ #pragma once -#include "asset/asset.h" #include "mesh.h" -#include "material.h" -class aiNode; -class aiMesh; -class aiScene; namespace engineapi { - class Model : public Asset { + class Model : public Resource { protected: - vector mMeshes; - Material* mMaterial; + vector> mMeshes; public: - using Asset::Asset; void BeginLoad(); - void ProcessNode(const aiNode* pNode, const aiScene* pScene); - Mesh* ProcessMesh(const aiMesh* mesh); - vector& GetMeshs() { + vector>& GetMeshs() { return mMeshes; } - void SetMaterial(Material* material) { - mMaterial = material; - } void Use(); }; }; \ No newline at end of file diff --git a/engine/src/engine/render/asset/shader.cpp b/engine/src/engine/render/asset/shader.cpp index 5d18283..1af8964 100644 --- a/engine/src/engine/render/asset/shader.cpp +++ b/engine/src/engine/render/asset/shader.cpp @@ -1,8 +1,6 @@ #include "shader.h" -#include "asset/file_manager.h" -#include "../renderapi.h" namespace engineapi { - Shader::Shader() + Shader::Shader() : Asset(&refl::TypeInfo::StaticClass) { } diff --git a/engine/src/engine/render/asset/shader.h b/engine/src/engine/render/asset/shader.h index ef38acc..0b1de30 100644 --- a/engine/src/engine/render/asset/shader.h +++ b/engine/src/engine/render/asset/shader.h @@ -5,10 +5,12 @@ namespace engineapi { class ShaderProgram : public Resource {}; class Shader : public Asset { private: + REFL_FRIEND(Shader) uint32_t mId; ShaderInfo mInfo; - string mVertexName; + UPROPERTY() RscHandle mVert; + UPROPERTY() RscHandle mFrag; friend class Scene; public: @@ -20,9 +22,6 @@ namespace engineapi { ShaderInfo& GetInfo() { return mInfo; } - string_view GetVertexName() { - return mVertexName; - } template RscHandle GetVertHandle() { return mVert; @@ -32,4 +31,5 @@ namespace engineapi { return mFrag; } }; -}; \ No newline at end of file +}; +#include "shader_gen.inl" \ No newline at end of file diff --git a/engine/src/engine/render/asset/texture.cpp b/engine/src/engine/render/asset/texture.cpp index e69de29..76610bc 100644 --- a/engine/src/engine/render/asset/texture.cpp +++ b/engine/src/engine/render/asset/texture.cpp @@ -0,0 +1,7 @@ +#include "texture.h" +namespace engineapi { + Texture::Texture() : Asset(&refl::TypeInfo::StaticClass) + { + + } +} diff --git a/engine/src/engine/render/asset/texture.h b/engine/src/engine/render/asset/texture.h index afe1af7..ca25331 100644 --- a/engine/src/engine/render/asset/texture.h +++ b/engine/src/engine/render/asset/texture.h @@ -3,6 +3,6 @@ namespace engineapi { class Texture : public Asset { - + Texture(); }; }; \ No newline at end of file diff --git a/engine/src/engine/render/meta/vertex.cpp b/engine/src/engine/render/asset/vertex.cpp similarity index 100% rename from engine/src/engine/render/meta/vertex.cpp rename to engine/src/engine/render/asset/vertex.cpp diff --git a/engine/src/engine/render/meta/vertex.h b/engine/src/engine/render/asset/vertex.h similarity index 100% rename from engine/src/engine/render/meta/vertex.h rename to engine/src/engine/render/asset/vertex.h diff --git a/engine/src/engine/render/node/rendernode.h b/engine/src/engine/render/node/rendernode.h index f263eca..4809d44 100644 --- a/engine/src/engine/render/node/rendernode.h +++ b/engine/src/engine/render/node/rendernode.h @@ -1,6 +1,5 @@ #pragma once #include "../asset/material.h" -#include "../asset/mesh.h" #include "../asset/texture.h" #include "../render_context.h" namespace engineapi { diff --git a/engine/src/engine/render/renderapi.h b/engine/src/engine/render/renderapi.h index bd6af82..cd6631c 100644 --- a/engine/src/engine/render/renderapi.h +++ b/engine/src/engine/render/renderapi.h @@ -31,10 +31,10 @@ namespace engineapi virtual void BeginFrame() = 0; virtual void Render(Camera& camera); virtual void EndFrame() = 0; - virtual void SetStaticMesh(Mesh* mesh) = 0; - virtual void DrawStaticMesh(Mesh* mesh) = 0; + virtual void SetStaticMesh(Mesh& mesh) = 0; + virtual void DrawStaticMesh(Mesh& mesh) = 0; - virtual void LoadShader(Shader* shader) = 0; + virtual void LoadShader(Shader& shader) = 0; virtual void SwitchContext() = 0; diff --git a/engine/src/engine/vulkanapi/loader/vulkan_glsl_loader.cpp b/engine/src/engine/vulkanapi/loader/vulkan_glsl_loader.cpp index 74be068..454985d 100644 --- a/engine/src/engine/vulkanapi/loader/vulkan_glsl_loader.cpp +++ b/engine/src/engine/vulkanapi/loader/vulkan_glsl_loader.cpp @@ -2,7 +2,7 @@ #include "vulkanapi/tool/glsl_to_spirv.h" #include "vulkanapi/vulkanapi.h" #include "asset/file_manager.h" -#include "render/meta/vertex.h" +#include "render/asset/vertex.h" #include "vkmeta_vertex_gen.inl" #include using namespace engineapi; @@ -56,7 +56,7 @@ namespace vulkanapi { auto spirv = GlslToSpirv::spirv(glsl, shader_enum, handle.GetFileName()); if (spirv) { program->Load(*spirv); - LoadShaderInfo(program->GetHandle().guid, *spirv); + LoadShaderInfo(program->GetGuid(), *spirv); } } } diff --git a/engine/src/engine/vulkanapi/vulkanapi.cpp b/engine/src/engine/vulkanapi/vulkanapi.cpp index 91ac2c1..c852731 100644 --- a/engine/src/engine/vulkanapi/vulkanapi.cpp +++ b/engine/src/engine/vulkanapi/vulkanapi.cpp @@ -64,13 +64,13 @@ namespace vulkanapi { { swapchain->Present(context); } - void RenderVulkanAPI::SetStaticMesh(Mesh* mesh) + void RenderVulkanAPI::SetStaticMesh(Mesh& mesh) { - auto Indices = mesh->GetIndices(); - auto Vertices = mesh->GetVertices(); - auto meshBuffer = GetNextVAO(mesh->GetVAO()); - meshBuffer->indexCount = Indices.size(); - meshBuffer->vertexCount = Vertices.size(); + auto Indices = mesh.GetIndices(); + auto Vertices = mesh.GetVertices(); + VulkanVAO& meshBuffer = VAOTable[mesh.GetGuid()]; + meshBuffer.indexCount = Indices.size(); + meshBuffer.vertexCount = Vertices.size(); // ----------------------------------------------- Vertex Buffer ----------------------------------------------- VkDeviceSize vertexBufferSize = Vertices.capicty(); @@ -84,7 +84,7 @@ namespace vulkanapi { VkBufferUsageFlags vertexFlags = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;//加入光线追踪 VmaAllocationCreateInfo vertexVmaCreateInfo = {}; VkBufferCreateInfo vertexCreateInfo = Buffer::MakeDeviceInfo(vertexVmaCreateInfo, vertexBufferSize, vertexFlags); - meshBuffer->vertexBuffer = Buffer::CreateBuffer(vertexCreateInfo, vertexVmaCreateInfo, meshBuffer->vertexBufferAlloc); + meshBuffer.vertexBuffer = Buffer::CreateBuffer(vertexCreateInfo, vertexVmaCreateInfo, meshBuffer.vertexBufferAlloc); // ----------------------------------------------- Index Buffer ----------------------------------------------- VkDeviceSize indexBufferSize = sizeof(uint32_t) * Indices.size(); @@ -96,11 +96,11 @@ namespace vulkanapi { VmaAllocationCreateInfo indexVmaCreateInfo = {}; VkBufferCreateInfo indexCreateInfo = Buffer::MakeDeviceInfo(indexVmaCreateInfo, indexBufferSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); - meshBuffer->indexBuffer = Buffer::CreateBuffer(indexCreateInfo, indexVmaCreateInfo, meshBuffer->vertexBufferAlloc); + meshBuffer.indexBuffer = Buffer::CreateBuffer(indexCreateInfo, indexVmaCreateInfo, meshBuffer.vertexBufferAlloc); auto fn = [=](CommandBuffer& cmd) { - cmd.CmdCopyBuffer(vertexStagingBuffer, meshBuffer->vertexBuffer, vertexBufferSize); - cmd.CmdCopyBuffer(indexStagingBuffer, meshBuffer->indexBuffer, indexBufferSize); + cmd.CmdCopyBuffer(vertexStagingBuffer, meshBuffer.vertexBuffer, vertexBufferSize); + cmd.CmdCopyBuffer(indexStagingBuffer, meshBuffer.indexBuffer, indexBufferSize); }; auto callback = [=]() { // 销毁StagingBuffer @@ -115,16 +115,16 @@ namespace vulkanapi { Backend::TransferWorker->ImmediatelyExecute(fn, callback); } } - void RenderVulkanAPI::DrawStaticMesh(Mesh* mesh) + void RenderVulkanAPI::DrawStaticMesh(Mesh& mesh) { - auto vulkanVAO = VAOList[mesh->GetVAO()]; - auto pipeline = PiPelineList[0]; + VulkanVAO& vulkanVAO = VAOTable[mesh.GetGuid()]; + VulkanPipeline& pipeline = PipelineTable[mesh.GetShaderGuid()]; uint32_t frame = context.frame; context.Pass->SetViewPort(mViewPortInfo.width, mViewPortInfo.height, mViewPortInfo.xOffset, mViewPortInfo.yOffset); Backend::RenderWorker->Draw([=](CommandBuffer& cmd) { VkCommandBuffer ptr = cmd.Ptr(); context.Pass->BeginPass(cmd, frame); - VkBuffer vertexBuffers[] = { vulkanVAO->vertexBuffer }; + VkBuffer vertexBuffers[] = { vulkanVAO.vertexBuffer }; VkDeviceSize offsets[] = { 0 }; VkViewport viewport = {}; viewport.x = static_cast(mViewPortInfo.xOffset); @@ -141,22 +141,22 @@ namespace vulkanapi { vkCmdSetScissor(ptr, 0, 1, &scissor); vkCmdBindVertexBuffers(ptr, 0, 1, vertexBuffers, offsets); - vkCmdBindIndexBuffer(ptr, vulkanVAO->indexBuffer, 0, VK_INDEX_TYPE_UINT32); - vkCmdBindPipeline(ptr, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->pipeline); - vkCmdBindDescriptorSets(ptr, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->pipelineLayout, 0, 1, &pipeline->descriptorSet, 0, VK_NULL_HANDLE); + vkCmdBindIndexBuffer(ptr, vulkanVAO.indexBuffer, 0, VK_INDEX_TYPE_UINT32); + vkCmdBindPipeline(ptr, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipeline); + vkCmdBindDescriptorSets(ptr, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipelineLayout, 0, 1, &pipeline.descriptorSet, 0, VK_NULL_HANDLE); vkCmdDrawIndexed(ptr, 3, 1, 0, 0, 0); context.Pass->EndPass(cmd); }); Backend::RenderWorker->Flush(); } - void RenderVulkanAPI::LoadShader(Shader* shader) + void RenderVulkanAPI::LoadShader(Shader& shader) { vector shaderStages; std::map shaderModules; auto device = backend.GetDevice(); - auto vertModule = shader->GetVertHandle()->Ptr(); + auto vertModule = shader.GetVertHandle()->Ptr(); shaderModules.insert(make_pair(VK_SHADER_STAGE_VERTEX_BIT, vertModule)); - auto fragModule = shader->GetVertHandle()->Ptr(); + auto fragModule = shader.GetFragHandle()->Ptr(); shaderModules.insert(make_pair(VK_SHADER_STAGE_FRAGMENT_BIT, fragModule)); for (auto& shaderModule : shaderModules) { @@ -167,7 +167,7 @@ namespace vulkanapi { shaderStageInfo.pName = "main"; shaderStages.push_back(shaderStageInfo); } - auto it = refl::UClass::MetaTable.find(shader->GetVertexName()); + auto it = refl::UClass::MetaTable.find(shader.Name()); auto meta = it->second->vtable.GetMeta("vkMeta"); // 设置顶点输入格式 VkPipelineVertexInputStateCreateInfo vertexInputInfo = {}; @@ -277,7 +277,7 @@ namespace vulkanapi { depthStencilInfo.front = {}; depthStencilInfo.back = {}; - auto descriptorSetLayout = VulkanContext::CreateDescriptorSetLayout(shader->GetInfo()); + auto descriptorSetLayout = VulkanContext::CreateDescriptorSetLayout(shader.GetInfo()); auto pipelineLayout = VulkanContext::CreatePipelineLayout({ descriptorSetLayout }, {}); VkGraphicsPipelineCreateInfo pipelineInfo{}; @@ -302,48 +302,16 @@ namespace vulkanapi { if (vkCreateGraphicsPipelines(device.Ptr(), VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &pipeLine) != VK_SUCCESS) throw std::runtime_error("failed to create graphics pipeline!"); - //for (auto& shaderModule : shaderModules) - //vkDestroyShaderModule(device.Ptr(), shaderModule.second, nullptr); + for (auto& shaderModule : shaderModules) + vkDestroyShaderModule(device.Ptr(), shaderModule.second, nullptr); - auto vulkan_pipeline = GetNextPipeline(shader->GetID()); - vulkan_pipeline->name = "";//shader->GetName(); - vulkan_pipeline->pipeline = pipeLine; - vulkan_pipeline->inUse = true; - vulkan_pipeline->pipelineLayout = pipelineLayout; - vulkan_pipeline->descriptorSetLayout = descriptorSetLayout; - vulkan_pipeline->descriptorSet = backend.GetPool().Allocate(descriptorSetLayout); + VulkanPipeline& vulkan_pipeline = PipelineTable[shader.GetGuid()]; + vulkan_pipeline.name = shader.Name(); + vulkan_pipeline.pipeline = pipeLine; + vulkan_pipeline.inUse = true; + vulkan_pipeline.pipelineLayout = pipelineLayout; + vulkan_pipeline.descriptorSetLayout = descriptorSetLayout; + vulkan_pipeline.descriptorSet = backend.GetPool().Allocate(descriptorSetLayout); } - VulkanVAO* RenderVulkanAPI::GetNextVAO(uint32_t& index) - { - uint32_t length = (uint32_t)VAOList.size(); - for (uint32_t i = 0; i < length; i++) - { - if (!VAOList[i]->inUse) { - index = i; - return VAOList[i]; - } - } - index = length; - auto vao = new VulkanVAO(); - VAOList.push_back(vao); - return vao; - } - - VulkanPipeline* RenderVulkanAPI::GetNextPipeline(uint32_t& index) - { - uint32_t length = (uint32_t)PiPelineList.size(); - for (uint32_t i = 0; i < length; i++) - { - if (!PiPelineList[i]->inUse) { - index = i; - return PiPelineList[i]; - } - } - index = length; - auto info = new VulkanPipeline(); - PiPelineList.push_back(info); - return info; - } - } diff --git a/engine/src/engine/vulkanapi/vulkanapi.h b/engine/src/engine/vulkanapi/vulkanapi.h index 4f6928f..e4a1ef1 100644 --- a/engine/src/engine/vulkanapi/vulkanapi.h +++ b/engine/src/engine/vulkanapi/vulkanapi.h @@ -4,8 +4,10 @@ #include "render/renderapi.h" #include "vulkan_struct.h" #include "vulkan_context.h" +#include "asset/res/guid.h" namespace vulkanapi { + using engineapi::Guid; class RenderTarget; class Swapchain; class RenderVulkanAPI : public RenderAPI @@ -15,10 +17,9 @@ namespace vulkanapi VulkanContext context; Swapchain* swapchain{nullptr}; vector TargetList; - vector VAOList; vector PassList; - vector PiPelineList; - hash_table ShaderInfoList; + hash_table PipelineTable; + hash_table VAOTable; public: RenderVulkanAPI(); ~RenderVulkanAPI()override; @@ -36,13 +37,10 @@ namespace vulkanapi void BeginFrame()override; void EndFrame()override; - void SetStaticMesh(Mesh* mesh)override; - void DrawStaticMesh(Mesh* mesh)override; + void SetStaticMesh(Mesh& mesh)override; + void DrawStaticMesh(Mesh& mesh)override; - void LoadShader(Shader* shader)override; - public: - VulkanVAO* GetNextVAO(uint32_t& index); - VulkanPipeline* GetNextPipeline(uint32_t& index); + void LoadShader(Shader& shader)override; public: static RenderVulkanAPI* GetSingletonPtr() { return (RenderVulkanAPI*)RenderAPI::GetSingletonPtr(); diff --git a/engine/xmake.lua b/engine/xmake.lua index 66f354a..55c3119 100644 --- a/engine/xmake.lua +++ b/engine/xmake.lua @@ -7,9 +7,8 @@ target("zengine") set_rundir(".") add_rules("volk.env", "glsl.env") add_rules("c++.codegen",{ - files = {"src/engine/render/meta/*.h", - "src/engine/asset/res/guid.h", - "src/engine/asset/res/meta_bundle.h",} + files = {"src/engine/render/asset/*.h", + "src/engine/asset/res/*.h"} }) add_deps("zlog","zlib") add_defines("VULKAN_API")