rebuild asset

This commit is contained in:
ouczbs 2024-06-30 21:46:26 +08:00
parent 26ac7f246a
commit b67411cb43
46 changed files with 258 additions and 257 deletions

12
engine/3rdparty/zlib/include/meta/pad.h vendored Normal file
View File

@ -0,0 +1,12 @@
#include <vector>
namespace meta {
template<typename T>
void padding_vector(std::vector<T>& vec, size_t multiple, const T& paddingValue = T()) {
if (multiple == 0) return; // 避免除以零
size_t remainder = vec.size() % multiple;
if (remainder != 0) {
size_t padding = multiple - remainder;
vec.insert(vec.end(), padding, paddingValue);
}
}
}

View File

@ -45,6 +45,7 @@ namespace refl {
uint32_t flag{0}; uint32_t flag{0};
const UClass* parent; const UClass* parent;
vtable_uclass vtable{}; vtable_uclass vtable{};
inline static std::unordered_map<Name, const UClass*> MetaTable;
public: public:
constexpr UClass(std::string_view name, uint32_t size, const UClass* parent = nullptr) constexpr UClass(std::string_view name, uint32_t size, const UClass* parent = nullptr)
:name(name), size(size), parent(parent){} :name(name), size(size), parent(parent){}

View File

@ -0,0 +1,27 @@
#version 450
#extension GL_GOOGLE_include_directive : enable
// 顶点位置输入变量
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texture;
layout (location = 2) in vec3 normal;
layout (location = 3) in vec3 tangent;
layout (location = 4) in vec4 weights;
layout (location = 5) in uvec4 bones;
// 顶点位置输出变量
//out vec4 outPosition;
out gl_PerVertex {
vec4 gl_Position;
};
vec2 positions[3] = vec2[](
vec2(0.0, -0.5),
vec2(0.5, 0.5),
vec2(-0.5, 0.5)
);
void main() {
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
}

View File

@ -4,7 +4,6 @@
#include "object/mesh/actor.h" #include "object/mesh/actor.h"
#include "data/property/actor_property.h" #include "data/property/actor_property.h"
#include "asset/file_manager.h" #include "asset/file_manager.h"
#include "asset/asset_manager.h"
#include "asset/resource_manager.h" #include "asset/resource_manager.h"
#include "object/scene/scene_manager.h" #include "object/scene/scene_manager.h"
namespace engineapi { namespace engineapi {
@ -12,7 +11,6 @@ namespace engineapi {
{ {
const char* name = "zengine"; const char* name = "zengine";
SystemList.push_back(new FileManager()); SystemList.push_back(new FileManager());
SystemList.push_back(new AssetManager());
SystemList.push_back(new ResourceManager()); SystemList.push_back(new ResourceManager());
SystemList.push_back(RenderAPI::MakeInstance()); SystemList.push_back(RenderAPI::MakeInstance());
SystemList.push_back(Window::MakeInstance(3, 640, 720, name)); SystemList.push_back(Window::MakeInstance(3, 640, 720, name));

View File

@ -1,9 +0,0 @@
#include "asset/asset.h"
#include "asset_manager.h"
namespace engineapi
{
Asset::~Asset()
{
}
}

View File

@ -1,50 +1,11 @@
#pragma once #pragma once
#include "res/guid.h" #include "render/asset_struct.h"
#include "res/resource_handle.h"
#include "res/package_path.h" #include "res/package_path.h"
#include <cstdint> namespace engineapi {
#include <vector> class Asset : public Resource<Asset> {
#include <map>
namespace engineapi
{
using std::vector;
using std::map;
class Asset {
public: public:
friend class AssetManager; using Base = Resource<Asset>;
enum :uint32_t { using Base::Base;
ASSET_NONE_FLAG = 0,
ASSET_SHARED_FLAG = 1 << 0,
ASSET_COPY_FLAG = 1 << 1,
ASSET_ASYNC_FLAG = 1 << 2,
ASSET_LOADING_FLAG = 1 << 3,
ASSET_LOADED_FLAG = 1 << 4,
ASSET_ANIM_FLAG = 1 << 5,
};
protected:
uint32_t mFlags;
string_view mName;
public:
Asset(string_view name, uint32_t flags):mName(name),mFlags(flags) {};
~Asset();
virtual void BeginLoad() {
mFlags |= ASSET_LOADING_FLAG;
};
virtual void EndLoad() {
mFlags &= ~ASSET_LOADING_FLAG;
mFlags |= ASSET_LOADED_FLAG;
};
string_view& GetName() {
return mName;
}
public:
inline bool IsShared() {
return mFlags & ASSET_SHARED_FLAG;
}
inline bool IsCopyed() {
return mFlags & ASSET_COPY_FLAG;
}
inline bool IsAsync() {
return mFlags & ASSET_ASYNC_FLAG;
}
}; };
} }

View File

@ -1,25 +0,0 @@
#include "asset_manager.h"
#include "zlog.h"
using namespace std;
namespace engineapi {
void AssetManager::Init()
{
}
void AssetManager::Shutdown()
{
}
void AssetManager::ClearAsset(Asset* asset)
{
auto it = AssetMap.find(asset->mName);
if (!asset->IsShared()) {
delete asset;
}
if (it != AssetMap.end()) {
it->second.count--;
if (it->second.count < 1) {
delete it->second.asset;
AssetMap.erase(it);
}
}
}
}

View File

@ -1,50 +0,0 @@
#pragma once
#include "asset.h"
#include "singleton.h"
namespace engineapi
{
class AssetManager : public ISingleton<AssetManager>
{
public:
struct AssetWrap {
Asset* asset;
uint32_t count;
AssetWrap(Asset* asset): asset(asset),count(1) {
}
};
public:
void Init() override;
void Shutdown() override;
public:
void ClearAsset(Asset* asset);
template<typename TAsset>
TAsset* LoadAsset(const string& name, uint32_t flags)
{
string_view view = PackagePath::StringView(name);
auto it = AssetMap.find(view);
bool isFind = it != AssetMap.end();
if (isFind) {
it->second.count++;
if (it->second.asset->IsShared()) {
return (TAsset*)(it->second.asset);
}
if (it->second.asset->IsCopyed()) {
TAsset* asset = new TAsset(name, flags);
*asset = *(TAsset*)(it->second.asset);
return asset;
}
}
TAsset* asset = new TAsset(name, flags);
if (!isFind && (asset->IsShared() || asset->IsCopyed())) {
AssetMap.emplace(name, asset);
}
asset->BeginLoad();
return asset;
}
AssetManager() = default;
private:
inline static table<string_view, AssetWrap> AssetMap;
};
}

View File

@ -6,7 +6,7 @@ namespace engineapi {
void FileManager::Init() void FileManager::Init()
{ {
std::filesystem::path path = std::filesystem::current_path(); std::filesystem::path path = std::filesystem::current_path();
Mount(string_view("engine"), path.string()); Mount("engine", path.string());
} }
void FileManager::Shutdown() void FileManager::Shutdown()
{ {

View File

@ -11,17 +11,25 @@ namespace engineapi
void Init() override; void Init() override;
void Shutdown() override; void Shutdown() override;
public: public:
static void Mount(NameID id, const string& path) { static void Mount(const string& name, const string& path) {
MountMap.emplace(id, path); MountMap.emplace(NameID(name), std::make_pair(name,path));
} }
static string FindMount(NameID id) { static std::pair<string, string> FindMount(NameID id) {
auto it = MountMap.find(id); auto it = MountMap.find(id);
if (it != MountMap.end()) { if (it != MountMap.end()) {
return it->second; return it->second;
} }
return ""; return {};
} }
inline static table<NameID, string> MountMap; static string FindMountName(NameID id) {
auto pair = FindMount(id);
return pair.first;
}
static string FindMountPath(NameID id) {
auto pair = FindMount(id);
return pair.second;
}
inline static table<NameID, std::pair<string, string>> MountMap;
public: public:
static string LoadTextFile(const string& path); static string LoadTextFile(const string& path);
static vector<char> LoadBinaryFile(const string& path); static vector<char> LoadBinaryFile(const string& path);

View File

@ -1,8 +1,8 @@
#pragma once #pragma once
#include "../asset.h"
#include "math/math.h" #include "math/math.h"
#include "asset_enum.h" #include "asset_enum.h"
#include <vector>
#include <string>
using std::string; using std::string;
using std::vector; using std::vector;

View File

@ -1,10 +1,17 @@
#include "package_path.h" #include "package_path.h"
#include "asset/file_manager.h" #include "asset/file_manager.h"
namespace engineapi { namespace engineapi {
PackagePath PackagePath::ToSuffixPath(const string_view& suffix)
{
if (CheckPackage()) {
return { FileManager::FindMountName(name) + string(suffix) , path};
}
return *this;
}
string PackagePath::AbsolutePath() string PackagePath::AbsolutePath()
{ {
if (CheckPackage()) { if (CheckPackage()) {
return FileManager::FindMount(name) + string(path); return FileManager::FindMountPath(name) + string(path);
} }
return string(path); return string(path);
} }

View File

@ -11,14 +11,15 @@ namespace engineapi
using Ubpa::Name; using Ubpa::Name;
using Ubpa::NameID; using Ubpa::NameID;
struct PackagePath { struct PackagePath {
string_view name; NameID name;
string_view path; string_view path;
PackagePath(const string& name,const string_view& path) : name(name), path(path) {}
PackagePath(const char* path) : path(path) {} PackagePath(const char* path) : path(path) {}
PackagePath(const string_view& path) : path(path) {} PackagePath(const string_view& path) : path(path) {}
PackagePath(const string& path) : path(StringView(path)) {}; PackagePath(const string& path) : path(StringView(path)) {};
PackagePath(const string&& path) : path(path) {} PackagePath(const string&& path) : path(path) {}
bool CheckPackage() { bool CheckPackage() {
if (!name.empty()) { if (name.Valid()) {
return true; return true;
} }
if (path[0] == '/') { if (path[0] == '/') {
@ -37,6 +38,7 @@ namespace engineapi
return path.substr(pos); return path.substr(pos);
return ""; return "";
} }
PackagePath ToSuffixPath(const string_view& suffix);
string AbsolutePath(); string AbsolutePath();
static string AbsolutePath(string_view path) { static string AbsolutePath(string_view path) {
return PackagePath(path).AbsolutePath(); return PackagePath(path).AbsolutePath();

View File

@ -11,7 +11,7 @@ namespace engineapi
ResourceBundle(const RscHandle<Res>& handle); ResourceBundle(const RscHandle<Res>& handle);
// will reshuffle vector and invalidate span, but you shouldn't be accessing vector directly anyway so this is ok // will reshuffle vector and invalidate span, but you shouldn't be accessing vector directly anyway so this is ok
template<typename T> void Add(RscHandle<T> handle); template<typename T> void Add(RscHandle<T> handle);
template<typename T> RscHandle<T> Get() const; // get a resource from the bundle
private: private:
struct sub_array { short index = 0, count = 0; }; struct sub_array { short index = 0, count = 0; };

View File

@ -1,3 +1,4 @@
#include "resource_bundle.h"
#pragma once #pragma once
namespace engineapi namespace engineapi
{ {
@ -24,4 +25,10 @@ namespace engineapi
for (auto& elem : span<sub_array>{ &sub_arr + 1, subarrays.data() + subarrays.size() }) for (auto& elem : span<sub_array>{ &sub_arr + 1, subarrays.data() + subarrays.size() })
++elem.index; ++elem.index;
} }
template<typename T>
inline RscHandle<T> engineapi::ResourceBundle::Get() const
{
auto& subarray = subarrays[ResourceID<T>];
return subarray.count > 0 ? handles[subarray.index].template AsHandle<T>() : RscHandle<T>();
}
} }

View File

@ -13,12 +13,11 @@ namespace engineapi {
Resource() = default; Resource() = default;
private: private:
RscHandle<Res> mHandle; RscHandle<Res> mHandle;
friend class RscHandle<Res>;
friend class ResourceManager;
}; };
using Resources = std::tuple< using Resources = std::tuple<
class Scene class ShaderProgram
, class Shader , class Asset
>; >;
template<typename Resource> template<typename Resource>
concept is_resource_v = requires { typename Resource::BaseResource; }; concept is_resource_v = requires { typename Resource::BaseResource; };

View File

@ -1,7 +1,6 @@
#include "resource_handle.h" #include "resource_handle.h"
namespace engineapi namespace engineapi
{ {
GenericResourceHandle::GenericResourceHandle(string_view type_name, Guid guid) GenericResourceHandle::GenericResourceHandle(string_view type_name, Guid guid)
{ {

View File

@ -8,9 +8,15 @@ namespace engineapi
struct RscHandle struct RscHandle
{ {
Guid guid{}; Guid guid{};
void* res{};
constexpr size_t RscID()const { return ResourceID<Res>; } constexpr size_t RscID()const { return ResourceID<Res>; }
constexpr RscHandle() noexcept = default; constexpr RscHandle() noexcept = default;
constexpr RscHandle(const Guid& guid) noexcept : guid{ guid } {} template<typename T>
constexpr RscHandle(const RscHandle<T>& other) noexcept : guid{ other.guid }, res(other.res) {};
constexpr RscHandle(const Guid& guid, Res* res) noexcept : guid{ guid }, res(res) { ((Resource<Res>*)res)->mHandle = *this; }
void init();
Res* operator->() { if (!res && guid) init(); return (Res*)res; }
Res& operator*() { if (!res && guid) init(); return *(Res*)res; }
}; };
struct GenericResourceHandle struct GenericResourceHandle
@ -21,8 +27,12 @@ namespace engineapi
public: public:
using Base::Base; using Base::Base;
using Base::operator=; using Base::operator=;
template<typename T>
GenericResourceHandle(RscHandle<T> handle) : Base(RscHandle<typename T::BaseResource>{handle}) {}
GenericResourceHandle(string_view type_name, Guid guid); GenericResourceHandle(string_view type_name, Guid guid);
template<typename T> RscHandle<T> AsHandle() const {
return std::get<ResourceID<T>>(*this);
}
Guid guid() const; Guid guid() const;
size_t resource_id() const; size_t resource_id() const;
}; };

View File

@ -24,8 +24,7 @@ namespace engineapi {
auto ext = path.GetExtension(); auto ext = path.GetExtension();
auto* loader = GetLoader(ext); auto* loader = GetLoader(ext);
MetaBundle meta = GetMeta(path); MetaBundle meta = GetMeta(path);
auto res = loader->LoadFile(path, meta); return loader->LoadFile(path, meta);
return res;
} }
MetaBundle ResourceManager::GetMeta(PackagePath path) MetaBundle ResourceManager::GetMeta(PackagePath path)

View File

@ -35,6 +35,9 @@ namespace engineapi {
void Shutdown() override; void Shutdown() override;
public: public:
template<typename Res>
Res* Get(const RscHandle<Res>&);
template<typename Res> template<typename Res>
auto& GetTable() { auto& GetTable() {
return *reinterpret_cast<ResourceStorage<Res>*> (mResourceTable[ResourceID<Res>].get()); return *reinterpret_cast<ResourceStorage<Res>*> (mResourceTable[ResourceID<Res>].get());
@ -51,7 +54,7 @@ namespace engineapi {
FLoader& RegisterLoader(Name ext, Args&& ... args); FLoader& RegisterLoader(Name ext, Args&& ... args);
template<typename Res> template<typename Res>
LoadResult<Res> Load(PackagePath path, bool reload_resource = true); RscHandle<Res> Load(PackagePath path, bool reload_resource = true);
LoadResult<ResourceBundle> Load(PackagePath path, bool reload_resource = true); LoadResult<ResourceBundle> Load(PackagePath path, bool reload_resource = true);
MetaBundle GetMeta(PackagePath path); MetaBundle GetMeta(PackagePath path);
}; };

View File

@ -1,3 +1,4 @@
#include "resource_manager.h"
#pragma once #pragma once
namespace engineapi { namespace engineapi {
class IFileLoader class IFileLoader
@ -39,11 +40,9 @@ namespace engineapi {
auto& table = GetTable<Res>(); auto& table = GetTable<Res>();
auto& control_block = table[guid]; // don't care just replace auto& control_block = table[guid]; // don't care just replace
// attempt to put on other thread // attempt to put on other thread
{ Res* res = new Res(std::forward<Args>(args)...);
control_block.resource = new Res(std::forward<Args>(args)...); control_block.resource = res;
control_block.resource->mHandle = RscHandle<Res>{ guid }; return RscHandle<Res>{guid, res};
}
return RscHandle<Res>{guid};
} }
template<typename FLoader, typename ...Args> template<typename FLoader, typename ...Args>
inline FLoader& ResourceManager::RegisterLoader(Name ext, Args&& ...args) inline FLoader& ResourceManager::RegisterLoader(Name ext, Args&& ...args)
@ -53,12 +52,26 @@ namespace engineapi {
return *ptr; return *ptr;
} }
template<typename Res> template<typename Res>
inline LoadResult<Res> ResourceManager::Load(PackagePath path, bool reload_resource) inline RscHandle<Res> ResourceManager::Load(PackagePath path, bool reload_resource)
{ {
auto res = Load(path, reload_resource); auto res = Load(path, reload_resource);
if (!res) if (!res)
return nullptr; return {};
return res.value().Get<Res>();
}
template<typename Res>
inline Res* ResourceManager::Get(const RscHandle<Res>& handle)
{
auto& table = GetTable<Res>();
auto itr = table.find(handle.guid);
if (itr == table.end())
return nullptr; return nullptr;
return itr->second.resource;
}
template<typename Res>
inline void RscHandle<Res>::init()
{
res = ResourceManager::GetSingleton().Get(*this);
} }
} }

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <map>
#include "component.h"
#include "asset/asset.h" #include "asset/asset.h"
#include "component.h"
#include <map>
namespace engineapi { namespace engineapi {
class GameObject { class GameObject {
protected: protected:

View File

@ -1,5 +1,4 @@
#include "actor.h" #include "actor.h"
#include "asset/asset_manager.h"
#include "data/property/actor_property.h" #include "data/property/actor_property.h"
namespace engineapi { namespace engineapi {
ActorMesh::ActorMesh(Model& model, ActorProperty& property) ActorMesh::ActorMesh(Model& model, ActorProperty& property)
@ -10,8 +9,9 @@ namespace engineapi {
} }
ActorMesh* ActorMesh::New(ActorProperty& property) ActorMesh* ActorMesh::New(ActorProperty& property)
{ {
Model* model = AssetManager::GetSingletonPtr()->LoadAsset<Model>(property.path, property.flags); //Model* model = AssetManager::GetSingletonPtr()->LoadAsset<Model>(property.path, property.flags);
return new ActorMesh(*model, property); //return new ActorMesh(*model, property);
return nullptr;
} }
ActorMesh* ActorMesh::New(uint32_t id) ActorMesh* ActorMesh::New(uint32_t id)
{ {

View File

@ -2,13 +2,21 @@
#include "object/camera/camera.h" #include "object/camera/camera.h"
#include "render/renderapi.h" #include "render/renderapi.h"
#include "object/mesh/actor.h" #include "object/mesh/actor.h"
#include "render/asset/shader.h"
#include "data/property/actor_property.h" #include "data/property/actor_property.h"
#include "asset/resource_manager.h"
#include "asset/file_manager.h"
namespace engineapi { namespace engineapi {
Scene::Scene() Scene::Scene()
{ {
mCamera = new Camera(); mCamera = new Camera();
auto flags = Asset::ASSET_SHARED_FLAG | Asset::ASSET_ASYNC_FLAG; int flags = 1;
Material* material = new Material("/engine/assets/shader/simple", flags); auto shader = ResourceManager::GetSingleton().LoaderEmplaceResource<Shader>();
shader->mVertexName = type_name<BoneVertex>().View();
//shader->mVert = ResourceManager::GetSingleton().Load<ShaderProgram>("/engine/assets/shader/simple.vert");
shader->mFrag = ResourceManager::GetSingleton().Load<ShaderProgram>("/engine/assets/shader/simple.frag");
RenderAPI::GetSingleton().LoadShader(&*shader);
Material* material = new Material("/engine/assets/shader/simple.shader", flags);
{ {
ActorProperty property; ActorProperty property;
property.id = 1; property.id = 1;

View File

@ -1,5 +1,4 @@
#pragma once #pragma once
#include "asset/asset.h"
#include "scene.h" #include "scene.h"
#include "singleton.h" #include "singleton.h"
namespace engineapi { namespace engineapi {

View File

@ -1,3 +0,0 @@
#pragma once
#include "asset/render/asset_struct.h"
#include "asset/res/resource_handle.h"

View File

@ -1,10 +1,8 @@
#include "material.h" #include "material.h"
#include "shader.h" #include "shader.h"
#include "asset/asset_manager.h"
#include "../renderapi.h" #include "../renderapi.h"
namespace engineapi { namespace engineapi {
Material::Material(string_view name, uint32_t flags) Material::Material(string_view name, uint32_t flags)
:Asset(name, flags)
{ {
//mShader = new Shader(name, flags); //mShader = new Shader(name, flags);
} }

View File

@ -1,5 +1,5 @@
#pragma once #pragma once
#include "asset_render.h" #include "asset/asset.h"
namespace engineapi { namespace engineapi {
class Shader; class Shader;

View File

@ -3,7 +3,6 @@
namespace engineapi { namespace engineapi {
void Mesh::BeginLoad() void Mesh::BeginLoad()
{ {
Asset::BeginLoad();
RenderAPI::GetSingletonPtr()->SetStaticMesh(this); RenderAPI::GetSingletonPtr()->SetStaticMesh(this);
} }
} }

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "refl/std/parray.h" #include "refl/std/parray.h"
#include "asset_render.h" #include "asset/asset.h"
#include "../meta/vertex.h" #include "../meta/vertex.h"
namespace engineapi { namespace engineapi {
using refl::parray; using refl::parray;
@ -14,14 +14,13 @@ namespace engineapi {
public: public:
template<typename T> template<typename T>
requires std::is_base_of_v<Vertex, T> requires std::is_base_of_v<Vertex, T>
Mesh(string_view name, uint32_t flags,vector<T>& vertices, vector<uint32_t>& indices) Mesh(vector<T>& vertices, vector<uint32_t>& indices)
:Asset(name, flags) : mVertices(vertices)
, mVertices(vertices)
, mIndices(indices) , mIndices(indices)
{ {
BeginLoad(); BeginLoad();
} }
void BeginLoad()override; void BeginLoad();
public: public:
uint32_t& GetVAO() { uint32_t& GetVAO() {

View File

@ -3,11 +3,10 @@
#include "assimp/Importer.hpp" #include "assimp/Importer.hpp"
#include "assimp/scene.h" #include "assimp/scene.h"
#include "assimp/postprocess.h" #include "assimp/postprocess.h"
#include "asset/asset_manager.h"
namespace engineapi { namespace engineapi {
void Model::BeginLoad() void Model::BeginLoad()
{ {
Asset::BeginLoad(); string mName = "";
// 用ASSIMP加载模型文件 // 用ASSIMP加载模型文件
Assimp::Importer importer; Assimp::Importer importer;
const aiScene* scene = importer.ReadFile(PackagePath::AbsolutePath(mName), aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_CalcTangentSpace const aiScene* scene = importer.ReadFile(PackagePath::AbsolutePath(mName), aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_CalcTangentSpace
@ -104,7 +103,7 @@ namespace engineapi {
indices.push_back(face.mIndices[j]); indices.push_back(face.mIndices[j]);
} }
} }
return new Mesh(mesh->mName.C_Str(), mFlags, vertices, indices); return new Mesh(vertices, indices);
} }
void Model::Use() void Model::Use()
{ {

View File

@ -1,5 +1,5 @@
#pragma once #pragma once
#include "asset_render.h" #include "asset/asset.h"
#include "mesh.h" #include "mesh.h"
#include "material.h" #include "material.h"
class aiNode; class aiNode;
@ -12,7 +12,7 @@ namespace engineapi {
Material* mMaterial; Material* mMaterial;
public: public:
using Asset::Asset; using Asset::Asset;
void BeginLoad()override; void BeginLoad();
void ProcessNode(const aiNode* pNode, const aiScene* pScene); void ProcessNode(const aiNode* pNode, const aiScene* pScene);
Mesh* ProcessMesh(const aiMesh* mesh); Mesh* ProcessMesh(const aiMesh* mesh);
vector<Mesh*>& GetMeshs() { vector<Mesh*>& GetMeshs() {

View File

@ -9,12 +9,4 @@ namespace engineapi {
Shader::~Shader() Shader::~Shader()
{ {
} }
vector<char> Shader::GetVertData()
{
return FileManager::LoadBinaryFile(PackagePath::AbsolutePath("") + ".vert.spv");
}
vector<char> Shader::GetFragData()
{
return FileManager::LoadBinaryFile(PackagePath::AbsolutePath("") + ".frag.spv");
}
} }

View File

@ -1,10 +1,16 @@
#pragma once #pragma once
#include "asset_render.h" #include "asset/asset.h"
namespace engineapi { namespace engineapi {
class Shader : public Resource<Shader> { class ShaderProgram : public Resource<ShaderProgram> {};
class Shader : public Asset {
private:
uint32_t mId; uint32_t mId;
ShaderInfo mInfo; ShaderInfo mInfo;
string mVertexName;
RscHandle<ShaderProgram> mVert;
RscHandle<ShaderProgram> mFrag;
friend class Scene;
public: public:
Shader(); Shader();
~Shader(); ~Shader();
@ -14,7 +20,16 @@ namespace engineapi {
ShaderInfo& GetInfo() { ShaderInfo& GetInfo() {
return mInfo; return mInfo;
} }
vector<char> GetVertData(); string_view GetVertexName() {
vector<char> GetFragData(); return mVertexName;
}
template<typename T = ShaderProgram>
RscHandle<T> GetVertHandle() {
return mVert;
}
template<typename T = ShaderProgram>
RscHandle<T> GetFragHandle() {
return mFrag;
}
}; };
}; };

View File

@ -1,5 +1,5 @@
#pragma once #pragma once
#include "asset_render.h" #include "asset/asset.h"
namespace engineapi { namespace engineapi {
class Texture : public Asset { class Texture : public Asset {

View File

@ -3,12 +3,11 @@
#include "../window.h" #include "../window.h"
#include "object/camera/camera.h" #include "object/camera/camera.h"
#include "../asset/model.h" #include "../asset/model.h"
#include "asset/asset_manager.h"
namespace engineapi { namespace engineapi {
RenderNodeForwardRendering::RenderNodeForwardRendering() RenderNodeForwardRendering::RenderNodeForwardRendering()
:RenderNode(RENDER_FORWARD_RENDERING) :RenderNode(RENDER_FORWARD_RENDERING)
{ {
mSky = AssetManager::GetSingletonPtr()->LoadAsset<Model>("assets/models/SkyBoxMesh.ply", Asset::ASSET_SHARED_FLAG | Asset::ASSET_ASYNC_FLAG); //mSky = AssetManager::GetSingletonPtr()->LoadAsset<Model>("assets/models/SkyBoxMesh.ply", Asset::ASSET_SHARED_FLAG | Asset::ASSET_ASYNC_FLAG);
//skyBoxMaterial = new Material(new Shader(Resources::GetAssetFullPath("Shaders/SkyBox.zxshader", true), FrameBufferType::Normal)); //skyBoxMaterial = new Material(new Shader(Resources::GetAssetFullPath("Shaders/SkyBox.zxshader", true), FrameBufferType::Normal));

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "asset/asset_render.h" #include "asset/asset.h"
namespace engineapi namespace engineapi
{ {
class RenderContext { class RenderContext {

View File

@ -1,8 +1,11 @@
#include "vulkan_glsl_loader.h" #include "vulkan_glsl_loader.h"
#include "vulkanapi/tool/glsl_to_spirv.h" #include "vulkanapi/tool/glsl_to_spirv.h"
#include "vulkanapi/vulkanapi.h"
#include "asset/file_manager.h" #include "asset/file_manager.h"
#include "render/asset/shader.h" #include "render/meta/vertex.h"
namespace engineapi { #include "vkmeta_vertex_gen.inl"
using namespace engineapi;
namespace vulkanapi {
vk::ShaderStageFlagBits GetShaderType(string_view ext) vk::ShaderStageFlagBits GetShaderType(string_view ext)
{ {
switch (string_hash(ext)) switch (string_hash(ext))
@ -16,19 +19,38 @@ namespace engineapi {
default: return vk::ShaderStageFlagBits::eAll; default: return vk::ShaderStageFlagBits::eAll;
} }
} }
void VulkanGlslLoader::Init()
{
ResourceManager::GetSingleton().RegisterLoader<VulkanGlslLoader>(".geom");
ResourceManager::GetSingleton().RegisterLoader<VulkanGlslLoader>(".frag");
ResourceManager::GetSingleton().RegisterLoader<VulkanGlslLoader>(".vert");
}
void VulkanGlslLoader::LoadShaderInfo(const std::string_view& name)
{
auto it = refl::UClass::MetaTable.find(Name(name));
auto meta = it->second->vtable.GetMeta("vkMeta");
int x = 1;
int y = 2;
}
//string PreprocessGlsl(string glsl); //string PreprocessGlsl(string glsl);
ResourceBundle VulkanGlslLoader::LoadFile(PackagePath handle, const MetaBundle& meta) ResourceBundle VulkanGlslLoader::LoadFile(PackagePath handle, const MetaBundle& meta)
{ {
auto m = meta.FetchMeta<Shader>(); auto m = meta.FetchMeta<ShaderProgram>();
auto program = m ? ResourceManager::GetSingleton().LoaderEmplaceResource<Shader>(m->guid) auto program = m ? ResourceManager::GetSingleton().LoaderEmplaceResource<vkShaderProgram>(m->guid)
: ResourceManager::GetSingleton().LoaderEmplaceResource<Shader>(); : ResourceManager::GetSingleton().LoaderEmplaceResource<vkShaderProgram>();
string glsl = FileManager::LoadTextFile(handle.AbsolutePath()); string glsl = FileManager::LoadTextFile(handle.AbsolutePath());
auto shader_enum = GetShaderType(handle.GetExtension()); auto shader_enum = GetShaderType(handle.GetExtension());
glsl = vulkanapi::GlslToSpirv::PreprocessGlsl(glsl); glsl = GlslToSpirv::PreprocessGlsl(glsl);
auto spirv = vulkanapi::GlslToSpirv::spirv(glsl, shader_enum); auto spirv = GlslToSpirv::spirv(glsl, shader_enum);
//if (spirv) if (spirv) {
//program->Load(shader_enum, {}, string_view{ r_cast<const char*>(spirv->data()),hlp::buffer_size(*spirv) }, glsl); program->Load(*spirv);
}
return program; return program;
} }
void vkShaderProgram::Load(const std::vector<unsigned int>& spirv)
{
RenderVulkanAPI* renderApi = RenderVulkanAPI::GetSingletonPtr();
mPtr = renderApi->backend.GetDevice().CreateShaderModule(spirv);
}
} }

View File

@ -1,8 +1,22 @@
#pragma once #pragma once
#include "render/asset/shader.h"
#include "asset/resource_manager.h" #include "asset/resource_manager.h"
namespace engineapi { #include "vulkanapi/vulkan.h"
class VulkanGlslLoader : public IFileLoader namespace vulkanapi {
class vkShaderProgram : public engineapi::ShaderProgram {
private:
VkShaderModule mPtr;
public:
VkShaderModule Ptr() {
return mPtr;
}
void Load(const std::vector<unsigned int>& spirv);
};
class VulkanGlslLoader : public engineapi::IFileLoader
{ {
ResourceBundle LoadFile(PackagePath handle, const MetaBundle& meta) override; public:
static void Init();
static void LoadShaderInfo(const std::string_view& name);
engineapi::ResourceBundle LoadFile(engineapi::PackagePath handle, const engineapi::MetaBundle& meta) override;
}; };
} }

View File

@ -1,5 +1,6 @@
#include "glsl_to_spirv.h" #include "glsl_to_spirv.h"
#include "zstd/table.h" #include "zstd/table.h"
#include "meta/pad.h"
#include "meta/hash.h" #include "meta/hash.h"
#include "yaml/yaml.h" #include "yaml/yaml.h"
#include <shaderc/shaderc.hpp> #include <shaderc/shaderc.hpp>
@ -53,22 +54,10 @@ namespace vulkanapi
shaderc::CompileOptions opt; shaderc::CompileOptions opt;
opt.SetTargetEnvironment(shaderc_target_env::shaderc_target_env_vulkan, 0); opt.SetTargetEnvironment(shaderc_target_env::shaderc_target_env_vulkan, 0);
auto result = compiler.CompileGlslToSpv(val, ConvertStageSC(v_stage), code_id.data(), opt); auto result = compiler.CompileGlslToSpv(val, ConvertStageSC(v_stage), code_id.data(), opt);
if (result.GetCompilationStatus() == shaderc_compilation_status::shaderc_compilation_status_success) if (result.GetCompilationStatus() != shaderc_compilation_status::shaderc_compilation_status_success)
return spirv_out;
spirv_out = vector<unsigned int>{ result.begin(),result.end() }; spirv_out = vector<unsigned int>{ result.begin(),result.end() };
else //meta::padding_vector(*spirv_out, (unsigned int)4, (unsigned int)0);
{
string filename = "/" + string{ code_id } + YAML::Text_Serialize(meta::string_hash(glsl));
auto err_m = result.GetErrorMessage();
auto err_msg = err_m.c_str();
//LOG_TO(LogPool::GFX, "%s", err_msg);
try
{
}
catch (...)
{
//LOG_TO(LogPool::GFX, "Failed to output glsl [%s] that generated the above error.", filename.c_str());
}
}
} }
return spirv_out; return spirv_out;
} }

View File

@ -3,7 +3,7 @@
// AMD写的Vulkan内存分配器 // AMD写的Vulkan内存分配器
#include "vk_mem_alloc.h" #include "vk_mem_alloc.h"
#include "math/matrix4.h" #include "math/matrix4.h"
#include "render/asset/asset_render.h" #include "asset/asset.h"
using engineapi::Matrix4; using engineapi::Matrix4;
using engineapi::FrameBufferType; using engineapi::FrameBufferType;
using engineapi::ClearInfo; using engineapi::ClearInfo;

View File

@ -12,7 +12,7 @@
#include "wrapper/descriptorpool.h" #include "wrapper/descriptorpool.h"
#include "window.h" #include "window.h"
#include "zlog.h" #include "zlog.h"
#include "vkmeta_vertex_gen.inl" #include "loader/vulkan_glsl_loader.h"
namespace vulkanapi { namespace vulkanapi {
RenderVulkanAPI::RenderVulkanAPI() RenderVulkanAPI::RenderVulkanAPI()
:backend("vulkan") :backend("vulkan")
@ -27,6 +27,11 @@ namespace vulkanapi {
void RenderVulkanAPI::SwitchContext() void RenderVulkanAPI::SwitchContext()
{ {
}
void RenderVulkanAPI::Init()
{
VulkanGlslLoader::Init();
RenderAPI::Init();
} }
void RenderVulkanAPI::InitRenderPass() void RenderVulkanAPI::InitRenderPass()
{ {
@ -101,9 +106,9 @@ namespace vulkanapi {
// 销毁StagingBuffer // 销毁StagingBuffer
Buffer::DestroyBuffer(vertexStagingBuffer, vertexVmaStagingAlloc); Buffer::DestroyBuffer(vertexStagingBuffer, vertexVmaStagingAlloc);
Buffer::DestroyBuffer(indexStagingBuffer, indexVmaStagingAlloc); Buffer::DestroyBuffer(indexStagingBuffer, indexVmaStagingAlloc);
mesh->EndLoad(); //mesh->EndLoad();
}; };
if (mesh->IsAsync()) { if (true) {
Backend::TransferWorker->InvokeBuffer(fn, callback); Backend::TransferWorker->InvokeBuffer(fn, callback);
} }
else { else {
@ -146,14 +151,13 @@ namespace vulkanapi {
} }
void RenderVulkanAPI::LoadShader(Shader* shader) void RenderVulkanAPI::LoadShader(Shader* shader)
{ {
VulkanGlslLoader::LoadShaderInfo(shader->GetVertexName());
vector<VkPipelineShaderStageCreateInfo> shaderStages; vector<VkPipelineShaderStageCreateInfo> shaderStages;
map<VkShaderStageFlagBits, VkShaderModule> shaderModules; std::map<VkShaderStageFlagBits, VkShaderModule> shaderModules;
auto device = backend.GetDevice(); auto device = backend.GetDevice();
auto vertData = shader->GetVertData(); auto vertModule = shader->GetVertHandle<vkShaderProgram>()->Ptr();
auto vertModule = device.CreateShaderModule(vertData);
shaderModules.insert(make_pair(VK_SHADER_STAGE_VERTEX_BIT, vertModule)); shaderModules.insert(make_pair(VK_SHADER_STAGE_VERTEX_BIT, vertModule));
auto fragData = shader->GetFragData(); auto fragModule = shader->GetVertHandle<vkShaderProgram>()->Ptr();
auto fragModule = device.CreateShaderModule(fragData);
shaderModules.insert(make_pair(VK_SHADER_STAGE_FRAGMENT_BIT, fragModule)); shaderModules.insert(make_pair(VK_SHADER_STAGE_FRAGMENT_BIT, fragModule));
for (auto& shaderModule : shaderModules) for (auto& shaderModule : shaderModules)
{ {

View File

@ -18,6 +18,7 @@ namespace vulkanapi
vector<VulkanVAO*> VAOList; vector<VulkanVAO*> VAOList;
vector<RenderPass*> PassList; vector<RenderPass*> PassList;
vector<VulkanPipeline*> PiPelineList; vector<VulkanPipeline*> PiPelineList;
hash_table<Guid, void*> ShaderInfoList;
public: public:
RenderVulkanAPI(); RenderVulkanAPI();
~RenderVulkanAPI()override; ~RenderVulkanAPI()override;
@ -28,6 +29,7 @@ namespace vulkanapi
public: public:
void SwitchContext()override; void SwitchContext()override;
public: public:
void Init() override;
void InitRenderPass()override; void InitRenderPass()override;
public: public:
void SetViewPort(uint32_t width, uint32_t height, uint32_t xOffset = 0, uint32_t yOffset = 0)override; void SetViewPort(uint32_t width, uint32_t height, uint32_t xOffset = 0, uint32_t yOffset = 0)override;

View File

@ -91,5 +91,17 @@ namespace vulkanapi {
VkResult result = vkCreateShaderModule(mPtr, &createInfo, nullptr, &module); VkResult result = vkCreateShaderModule(mPtr, &createInfo, nullptr, &module);
return module; return module;
} }
VkShaderModule Device::CreateShaderModule(vector<unsigned int> code)
{
VkShaderModuleCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
// 这里需要确保数据满足uint32_t的对齐要求,存储在vector中默认分配器已经确保数据满足最差情况下的对齐要求
createInfo.codeSize = code.size();
// 转换为Vulkan要求的uint32_t指针
createInfo.pCode = reinterpret_cast<const uint32_t*>(code.data());
VkShaderModule module;
VkResult result = vkCreateShaderModule(mPtr, &createInfo, nullptr, &module);
return module;
}
} }

View File

@ -25,5 +25,6 @@ namespace vulkanapi {
VkFence CreateFence(); VkFence CreateFence();
VkSemaphore CreateSemaphore(); VkSemaphore CreateSemaphore();
VkShaderModule CreateShaderModule(vector<char> code); VkShaderModule CreateShaderModule(vector<char> code);
VkShaderModule CreateShaderModule(vector<unsigned int> code);
}; };
}; };

View File

@ -1,22 +1,12 @@
#include <iostream> #include <iostream>
#include <thread> #include <thread>
#include "asset/file_manager.h" #include "app.h"
#include "asset/resource_manager.h" #include "zlog.h"
#include "vulkanapi/loader/vulkan_glsl_loader.h"
using namespace engineapi; using namespace engineapi;
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
vector<ISystem*> SystemList; const char* name = "zengine";
SystemList.push_back(new FileManager()); App game(name);
SystemList.push_back(new ResourceManager()); game.Launch();
for (auto system : SystemList) {
system->Init();
}
for (auto system : SystemList) {
system->LateInit();
}
ResourceManager::GetSingleton().RegisterLoader<VulkanGlslLoader>(FName(".frag"));
ResourceManager::GetSingleton().Load("/engine/assets/shader/simple.frag", true);
return 0; return 0;
} }