From 7423dd765656cfecb1b16f8d4e41c972b3e1ff59 Mon Sep 17 00:00:00 2001 From: ouczbs Date: Fri, 22 Mar 2024 21:08:02 +0800 Subject: [PATCH] render pass --- engine/src/3rdparty/template/singleton.h | 4 +- engine/src/engine/app.cpp | 17 +---- engine/src/engine/asset/asset_manager.cpp | 25 ++++++- engine/src/engine/asset/asset_manager.h | 2 + engine/src/engine/object/mesh/static.h | 3 + engine/src/engine/object/scene/scene.cpp | 21 ++++++ engine/src/engine/object/scene/scene.h | 3 + engine/src/engine/render/asset/material.cpp | 3 +- engine/src/engine/render/asset/material.h | 1 + engine/src/engine/render/asset/mesh.h | 1 - engine/src/engine/render/asset/model.cpp | 14 ++++ engine/src/engine/render/asset/model.h | 4 + engine/src/engine/render/asset/shader.cpp | 5 ++ engine/src/engine/render/asset/shader.h | 3 +- engine/src/engine/render/pass/renderpass.h | 8 +- .../engine/render/pass/renderpass_forward.cpp | 6 +- .../engine/render/pass/renderpass_forward.h | 6 +- engine/src/engine/render/render_context.cpp | 0 engine/src/engine/render/render_context.h | 12 +++ engine/src/engine/render/renderapi.cpp | 8 +- engine/src/engine/render/renderapi.h | 19 ++++- engine/src/engine/vulkanapi/backend.cpp | 2 + engine/src/engine/vulkanapi/backend.h | 1 + .../src/engine/vulkanapi/pass/forwardpass.cpp | 14 ++-- .../src/engine/vulkanapi/pass/forwardpass.h | 11 ++- engine/src/engine/vulkanapi/pass/target.cpp | 0 engine/src/engine/vulkanapi/pass/target.h | 10 +++ engine/src/engine/vulkanapi/thread/worker.cpp | 11 +++ engine/src/engine/vulkanapi/thread/worker.h | 1 + .../src/engine/vulkanapi/vulkan_context.cpp | 9 +++ engine/src/engine/vulkanapi/vulkan_context.h | 11 +++ engine/src/engine/vulkanapi/vulkanapi.cpp | 74 ++++++++++++++++--- engine/src/engine/vulkanapi/vulkanapi.h | 10 +++ .../src/engine/vulkanapi/wrapper/buffer.cpp | 5 ++ engine/src/engine/vulkanapi/wrapper/buffer.h | 1 + .../vulkanapi/wrapper/commandbuffer.cpp | 13 +++- .../engine/vulkanapi/wrapper/commandbuffer.h | 3 + .../engine/vulkanapi/wrapper/renderpass.cpp | 19 +++++ .../src/engine/vulkanapi/wrapper/renderpass.h | 11 ++- 39 files changed, 311 insertions(+), 60 deletions(-) create mode 100644 engine/src/engine/render/render_context.cpp create mode 100644 engine/src/engine/render/render_context.h create mode 100644 engine/src/engine/vulkanapi/pass/target.cpp create mode 100644 engine/src/engine/vulkanapi/pass/target.h create mode 100644 engine/src/engine/vulkanapi/vulkan_context.cpp create mode 100644 engine/src/engine/vulkanapi/vulkan_context.h diff --git a/engine/src/3rdparty/template/singleton.h b/engine/src/3rdparty/template/singleton.h index 6532128..4087a92 100644 --- a/engine/src/3rdparty/template/singleton.h +++ b/engine/src/3rdparty/template/singleton.h @@ -11,10 +11,10 @@ public: ~Singleton() { ms_Singleton = nullptr; } - static T& GetSingleton(void) { + static constexpr T& GetSingleton(void) { return *ms_Singleton; } - static T* GetSingletonPtr(void) { + static constexpr T* GetSingletonPtr(void) { return ms_Singleton; } }; \ No newline at end of file diff --git a/engine/src/engine/app.cpp b/engine/src/engine/app.cpp index fb2757a..6f701ae 100644 --- a/engine/src/engine/app.cpp +++ b/engine/src/engine/app.cpp @@ -9,25 +9,12 @@ namespace engineapi { App::App(const string& path) { const char* name = "zengine"; + new AssetManager(); _RenderAPI = RenderAPI::MakeInstance(); + _RenderAPI->SetUpRenderPasses(); _Window = Window::MakeInstance(3, 640, 720, name); auto scene_manager = new SceneManager(); scene_manager->LoadScene(path); - new AssetManager(); - { - ActorProperty property; - property.id = 1; - property.flags = Asset::ASSET_SHARED_FLAG | Asset::ASSET_ASYNC_FLAG; - property.path = "assets/models/cube.obj"; - auto actor = ActorMesh::New(property); - } - { - ActorProperty property; - property.id = 1; - property.flags = Asset::ASSET_SHARED_FLAG | Asset::ASSET_ASYNC_FLAG; - property.path = "assets/models/box.ply"; - auto actor = ActorMesh::New(property); - } } App::~App() { diff --git a/engine/src/engine/asset/asset_manager.cpp b/engine/src/engine/asset/asset_manager.cpp index 767894d..10b225e 100644 --- a/engine/src/engine/asset/asset_manager.cpp +++ b/engine/src/engine/asset/asset_manager.cpp @@ -1,4 +1,6 @@ -#include "asset/asset_manager.h" +#include "asset_manager.h" +#include "zlog.h" +using namespace std; namespace engineapi { void AssetManager::ClearAsset(Asset* asset) { @@ -14,4 +16,25 @@ namespace engineapi { } } } + string AssetManager::LoadTextFile(const string& path) + { + string text = ""; + ifstream file; + file.exceptions(ifstream::failbit | ifstream::badbit); + + try + { + file.open(path); + stringstream stream; + stream << file.rdbuf(); + file.close(); + text = stream.str(); + } + catch (ifstream::failure e) + { + zlog::info("Failed to load text file: {}", path); + } + + return text; + } } diff --git a/engine/src/engine/asset/asset_manager.h b/engine/src/engine/asset/asset_manager.h index d403dc6..d1cd0f9 100644 --- a/engine/src/engine/asset/asset_manager.h +++ b/engine/src/engine/asset/asset_manager.h @@ -47,6 +47,8 @@ namespace engineapi } AssetManager() = default; + public: + static string LoadTextFile(const string& path); }; } template<> diff --git a/engine/src/engine/object/mesh/static.h b/engine/src/engine/object/mesh/static.h index 2c5f097..b7a6220 100644 --- a/engine/src/engine/object/mesh/static.h +++ b/engine/src/engine/object/mesh/static.h @@ -11,5 +11,8 @@ namespace engineapi { StaticMesh(Model& model); void LoadMesh(); + Model& Ptr() { + return mPtr; + } }; } \ 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 e12d1ab..7c9d333 100644 --- a/engine/src/engine/object/scene/scene.cpp +++ b/engine/src/engine/object/scene/scene.cpp @@ -1,10 +1,26 @@ #include "scene.h" #include "object/camera/camera.h" #include "render/renderapi.h" +#include "object/mesh/actor.h" +#include "data/property/actor_property.h" namespace engineapi { Scene::Scene() { mCamera = new Camera(); + { + ActorProperty property; + property.id = 1; + property.flags = Asset::ASSET_SHARED_FLAG | Asset::ASSET_ASYNC_FLAG; + property.path = "assets/models/cube.obj"; + actor1 = ActorMesh::New(property); + } + { + ActorProperty property; + property.id = 1; + property.flags = Asset::ASSET_SHARED_FLAG | Asset::ASSET_ASYNC_FLAG; + property.path = "assets/models/box.ply"; + actor2 = ActorMesh::New(property); + } } Scene::~Scene() { @@ -15,6 +31,11 @@ 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); } void Scene::AddGameObject(GameObject* gameObject) { diff --git a/engine/src/engine/object/scene/scene.h b/engine/src/engine/object/scene/scene.h index d8355dd..299ebb0 100644 --- a/engine/src/engine/object/scene/scene.h +++ b/engine/src/engine/object/scene/scene.h @@ -2,9 +2,12 @@ #include "../game_object.h" namespace engineapi { class Camera; + class ActorMesh; class Scene{ protected: Camera* mCamera; + ActorMesh* actor1; + ActorMesh* actor2; public: Scene(); ~Scene(); diff --git a/engine/src/engine/render/asset/material.cpp b/engine/src/engine/render/asset/material.cpp index 15cb773..2c03d26 100644 --- a/engine/src/engine/render/asset/material.cpp +++ b/engine/src/engine/render/asset/material.cpp @@ -1,4 +1,5 @@ #include "material.h" +#include "../renderapi.h" namespace engineapi { Material::Material(string name, uint32_t flags) :Asset(name, flags) @@ -10,6 +11,6 @@ namespace engineapi { } void Material::Use() { - + RenderAPI::GetSingletonPtr()->UseMaterial(mId); } } diff --git a/engine/src/engine/render/asset/material.h b/engine/src/engine/render/asset/material.h index 3965903..e056be0 100644 --- a/engine/src/engine/render/asset/material.h +++ b/engine/src/engine/render/asset/material.h @@ -4,6 +4,7 @@ namespace engineapi { class Material : public Asset { protected: + uint32_t mId; public: Material(string name, uint32_t flags); diff --git a/engine/src/engine/render/asset/mesh.h b/engine/src/engine/render/asset/mesh.h index 293695f..0a1eee2 100644 --- a/engine/src/engine/render/asset/mesh.h +++ b/engine/src/engine/render/asset/mesh.h @@ -9,7 +9,6 @@ namespace engineapi { uint32_t VAO = 0; vector mVertices; vector mIndices; - public: Mesh(string name, uint32_t flags, vector& vertices, vector& indices); void BeginLoad()override; diff --git a/engine/src/engine/render/asset/model.cpp b/engine/src/engine/render/asset/model.cpp index cd75b0c..e4628ef 100644 --- a/engine/src/engine/render/asset/model.cpp +++ b/engine/src/engine/render/asset/model.cpp @@ -96,8 +96,22 @@ namespace engineapi { 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]); + } + } Mesh* model = new Mesh(mesh->mName.C_Str(), mFlags, vertices, indices); return model; } + void Model::Use() + { + + } } diff --git a/engine/src/engine/render/asset/model.h b/engine/src/engine/render/asset/model.h index fc539eb..a3033af 100644 --- a/engine/src/engine/render/asset/model.h +++ b/engine/src/engine/render/asset/model.h @@ -13,5 +13,9 @@ namespace engineapi { void BeginLoad()override; void ProcessNode(const aiNode* pNode, const aiScene* pScene); Mesh* ProcessMesh(const aiMesh* mesh); + vector& GetMeshs() { + return mMeshes; + } + 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 ca5e86d..1512f7d 100644 --- a/engine/src/engine/render/asset/shader.cpp +++ b/engine/src/engine/render/asset/shader.cpp @@ -1,4 +1,5 @@ #include "shader.h" +#include "../renderapi.h" namespace engineapi { Shader::Shader(string name, uint32_t flags) :Asset(name, flags) @@ -12,4 +13,8 @@ namespace engineapi { { } + void Shader::Use() + { + RenderAPI::GetSingletonPtr()->UseShader(mId); + } } diff --git a/engine/src/engine/render/asset/shader.h b/engine/src/engine/render/asset/shader.h index 741ced1..f02d428 100644 --- a/engine/src/engine/render/asset/shader.h +++ b/engine/src/engine/render/asset/shader.h @@ -4,10 +4,11 @@ namespace engineapi { class Shader : public Asset { protected: - + uint32_t mId; public: Shader(string name, uint32_t flags); ~Shader(); void BeginLoad()override; + void Use(); }; }; \ No newline at end of file diff --git a/engine/src/engine/render/pass/renderpass.h b/engine/src/engine/render/pass/renderpass.h index b32fd61..dff6f45 100644 --- a/engine/src/engine/render/pass/renderpass.h +++ b/engine/src/engine/render/pass/renderpass.h @@ -15,11 +15,17 @@ namespace engineapi { class Camera; class RenderPass { + protected: + RenderPassType mType; public: - RenderPass() {}; + RenderPass(RenderPassType type) : mType(type){}; ~RenderPass() {}; virtual void Render(Camera& camera) = 0; + public: + RenderPassType GetType() { + return mType; + } }; class RenderStateSetting { diff --git a/engine/src/engine/render/pass/renderpass_forward.cpp b/engine/src/engine/render/pass/renderpass_forward.cpp index eb185e7..a76bee7 100644 --- a/engine/src/engine/render/pass/renderpass_forward.cpp +++ b/engine/src/engine/render/pass/renderpass_forward.cpp @@ -2,10 +2,13 @@ #include "../renderapi.h" #include "../window.h" #include "object/camera/camera.h" +#include "../asset/model.h" +#include "asset/asset_manager.h" namespace engineapi { RenderPassForwardRendering::RenderPassForwardRendering() { - skyBox = nullptr; + mID = 0; + mSky = AssetManager::GetSingletonPtr()->LoadAsset("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)); @@ -41,6 +44,7 @@ namespace engineapi { Matrix4 mat_V = Matrix4(Matrix3(camera.GetViewMatrix())); Matrix4 mat_P = camera.GetProjectionMatrix(); + mSky->Use(); //skyBoxMaterial->Use(); //skyBoxMaterial->SetMatrix("ENGINE_View", mat_V); //skyBoxMaterial->SetMatrix("ENGINE_Projection", mat_P); diff --git a/engine/src/engine/render/pass/renderpass_forward.h b/engine/src/engine/render/pass/renderpass_forward.h index 92ebae4..831a263 100644 --- a/engine/src/engine/render/pass/renderpass_forward.h +++ b/engine/src/engine/render/pass/renderpass_forward.h @@ -3,6 +3,7 @@ #include "object/render/mesh_render.h" namespace engineapi { class Camera; + class Model; class RenderPassForwardRendering : public RenderPass { public: @@ -12,9 +13,8 @@ namespace engineapi { virtual void Render(Camera& camera); private: - uint32_t drawCommandID = 0; - Mesh* skyBox; - Material* skyBoxMaterial; + uint32_t mID; + Model* mSky; RenderStateSetting* skyBoxRenderState; RenderStateSetting* opaqueRenderState; RenderStateSetting* transparentRenderState; diff --git a/engine/src/engine/render/render_context.cpp b/engine/src/engine/render/render_context.cpp new file mode 100644 index 0000000..e69de29 diff --git a/engine/src/engine/render/render_context.h b/engine/src/engine/render/render_context.h new file mode 100644 index 0000000..8657518 --- /dev/null +++ b/engine/src/engine/render/render_context.h @@ -0,0 +1,12 @@ + +#pragma once +#include "asset/asset_render.h" +namespace engineapi +{ + struct RenderContext { + uint32_t MaterialId; + uint32_t PassId; + uint32_t ShaderId; + virtual void UseContext(){}; + }; +} \ No newline at end of file diff --git a/engine/src/engine/render/renderapi.cpp b/engine/src/engine/render/renderapi.cpp index 6e0b113..7b1e25d 100644 --- a/engine/src/engine/render/renderapi.cpp +++ b/engine/src/engine/render/renderapi.cpp @@ -6,6 +6,10 @@ #endif // VULKAN_API namespace engineapi { RenderAPI::RenderAPI() + { + + } + void RenderAPI::SetUpRenderPasses() { mAllPasses.resize(ZX_RENDER_PASS_COUNT); @@ -15,10 +19,6 @@ namespace engineapi { //mAllPasses[ZX_RENDER_PASS_AFTER_EFFECT_RENDERING] = new RenderPassAfterEffectRendering(); //mAllPasses[ZX_RENDER_PASS_UI_RENDERING] = new RenderPassUIRendering(); - SetUpRenderPasses(); - } - void RenderAPI::SetUpRenderPasses() - { mCurPasses.clear(); //mCurPasses.push_back(mAllPasses[ZX_RENDER_PASS_SHADOW_GENERATION]); mCurPasses.push_back(mAllPasses[ZX_RENDER_PASS_FORWARD_RENDERING]); diff --git a/engine/src/engine/render/renderapi.h b/engine/src/engine/render/renderapi.h index 76f860a..3d85acc 100644 --- a/engine/src/engine/render/renderapi.h +++ b/engine/src/engine/render/renderapi.h @@ -1,5 +1,5 @@ #pragma once -#include "asset/asset_render.h" +#include "render_context.h" #include "singleton.h" namespace engineapi { @@ -11,19 +11,34 @@ namespace engineapi protected: ViewPortInfo mViewPortInfo; + RenderContext* mContext; vector mCurPasses; vector mAllPasses; public: RenderAPI(); virtual ~RenderAPI() {}; + public: virtual void SetUpRenderPasses(); + virtual void InitRenderPass() = 0; public: virtual void SetViewPort(uint32_t width, uint32_t height, uint32_t xOffset = 0, uint32_t yOffset = 0) = 0; - 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 SwitchContext() = 0; + + virtual void UseMaterial(uint32_t ID) { + mContext->MaterialId = ID; + }; + virtual void UseShader(uint32_t ID) { + mContext->PassId = ID; + }; + virtual void UsePass(uint32_t ID) { + mContext->ShaderId = ID; + }; public: static RenderAPI* MakeInstance(); }; diff --git a/engine/src/engine/vulkanapi/backend.cpp b/engine/src/engine/vulkanapi/backend.cpp index 2b20e90..203ffd5 100644 --- a/engine/src/engine/vulkanapi/backend.cpp +++ b/engine/src/engine/vulkanapi/backend.cpp @@ -5,6 +5,7 @@ #include "zlog.h" namespace vulkanapi { CommandWorker* Backend::TransferWorker = nullptr; + CommandWorker* Backend::RenderWorker = nullptr; Backend::Backend(const string appName) { auto instanceCreator = InstanceCreator(); @@ -24,6 +25,7 @@ namespace vulkanapi { InitWorker(Queue::PresentQueue, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT); Backend::TransferWorker = GetWorker(Queue::TransferQueue); + Backend::RenderWorker = GetWorker(Queue::RenderQueue); } Backend::~Backend() { diff --git a/engine/src/engine/vulkanapi/backend.h b/engine/src/engine/vulkanapi/backend.h index dca86b8..09fe1f7 100644 --- a/engine/src/engine/vulkanapi/backend.h +++ b/engine/src/engine/vulkanapi/backend.h @@ -26,5 +26,6 @@ namespace vulkanapi { public: static CommandWorker* TransferWorker; + static CommandWorker* RenderWorker; }; }; \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/pass/forwardpass.cpp b/engine/src/engine/vulkanapi/pass/forwardpass.cpp index 27d9a4f..bc74db5 100644 --- a/engine/src/engine/vulkanapi/pass/forwardpass.cpp +++ b/engine/src/engine/vulkanapi/pass/forwardpass.cpp @@ -2,7 +2,11 @@ #include "../wrapper/renderpass.h" #include "../wrapper/image.h" namespace vulkanapi { - ForwardPass::ForwardPass(Device& device, GeometryBuffer& gBuffer) + void ForwardPass::Record() + { + + } + ForwardPass* ForwardPass::MakePass(Device& device, GeometryBuffer& gBuffer) { VkAttachmentDescription positionAttachment{}; positionAttachment.samples = VK_SAMPLE_COUNT_1_BIT; @@ -33,13 +37,9 @@ namespace vulkanapi { subpass.colorAttachmentCount = 1; subpass.pColorAttachments = &colorAttachmentRef; - vector attachments = {positionAttachment , normalAttachment}; + vector attachments = { positionAttachment , normalAttachment }; vector subpasses = { subpass }; vector dependencies; - mPass = new RenderPass(device,"forward",attachments, subpasses, dependencies); - } - void ForwardPass::Record() - { - + return new ForwardPass(device, "forward", attachments, subpasses, dependencies); } } \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/pass/forwardpass.h b/engine/src/engine/vulkanapi/pass/forwardpass.h index fe48ce1..394e5f6 100644 --- a/engine/src/engine/vulkanapi/pass/forwardpass.h +++ b/engine/src/engine/vulkanapi/pass/forwardpass.h @@ -1,15 +1,14 @@ #pragma once +#include "../wrapper/renderpass.h" #include "gbuffer.h" namespace vulkanapi { - class RenderPass; //class MaterialCache; - class ForwardPass { - protected: - RenderPass* mPass; + class ForwardPass : public RenderPass { //MaterialCache mMaterials; public: - ForwardPass(Device& device, GeometryBuffer& gBuffer); - + using RenderPass::RenderPass; void Record(); + public: + static ForwardPass* MakePass(Device& device, GeometryBuffer& gBuffer); }; } \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/pass/target.cpp b/engine/src/engine/vulkanapi/pass/target.cpp new file mode 100644 index 0000000..e69de29 diff --git a/engine/src/engine/vulkanapi/pass/target.h b/engine/src/engine/vulkanapi/pass/target.h new file mode 100644 index 0000000..3deda21 --- /dev/null +++ b/engine/src/engine/vulkanapi/pass/target.h @@ -0,0 +1,10 @@ +#pragma once +#include "../vulkan.h" +namespace vulkanapi { + class Image; + class Device; + class RenderTarget { + public: + + }; +} \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/thread/worker.cpp b/engine/src/engine/vulkanapi/thread/worker.cpp index f99255b..731f70e 100644 --- a/engine/src/engine/vulkanapi/thread/worker.cpp +++ b/engine/src/engine/vulkanapi/thread/worker.cpp @@ -41,4 +41,15 @@ namespace vulkanapi { { mWork.SyncInvoke([]() {}); } + void CommandWorker::Draw(commandFn fn) + { + CommandBuffer cmd = mCommandPool.Pop(); + cmd.Reset(); + cmd.BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); + fn(cmd); + cmd.EndRecord(); + cmd.Submit(mQueue.Ptr()); + cmd.WaitFofFence(mDevice.Ptr()); + mCommandPool.Push(cmd); + } } diff --git a/engine/src/engine/vulkanapi/thread/worker.h b/engine/src/engine/vulkanapi/thread/worker.h index 36a8546..289fa98 100644 --- a/engine/src/engine/vulkanapi/thread/worker.h +++ b/engine/src/engine/vulkanapi/thread/worker.h @@ -24,5 +24,6 @@ namespace vulkanapi { void ImmediatelyExecute(commandFn fn, voidFn callback) { Buffer(mImmediateExeCmd, fn , callback); } + void Draw(commandFn fn); }; }; \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/vulkan_context.cpp b/engine/src/engine/vulkanapi/vulkan_context.cpp new file mode 100644 index 0000000..0960179 --- /dev/null +++ b/engine/src/engine/vulkanapi/vulkan_context.cpp @@ -0,0 +1,9 @@ +#include "vulkan_context.h" +#include "vulkanapi.h" +namespace engineapi { + void VulkanContext::UseContext() + { + Pass = API->VkPasses[PassId]; + + } +} \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/vulkan_context.h b/engine/src/engine/vulkanapi/vulkan_context.h new file mode 100644 index 0000000..af97074 --- /dev/null +++ b/engine/src/engine/vulkanapi/vulkan_context.h @@ -0,0 +1,11 @@ +#pragma once +#include "render/render_context.h" +#include "vulkanapi.h" +namespace engineapi { + struct VulkanContext : public RenderContext { + RenderVulkanAPI* API; + vulkanapi::RenderPass* Pass; + + virtual void UseContext()override; + }; +} \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/vulkanapi.cpp b/engine/src/engine/vulkanapi/vulkanapi.cpp index df4e854..457f576 100644 --- a/engine/src/engine/vulkanapi/vulkanapi.cpp +++ b/engine/src/engine/vulkanapi/vulkanapi.cpp @@ -5,16 +5,34 @@ #include "thread/worker.h" #include "render/asset/mesh.h" #include "object/camera/camera.h" +#include "render/pass/renderpass.h" +#include "pass/forwardpass.h" namespace engineapi { RenderVulkanAPI::RenderVulkanAPI() :backend("vulkan") { + mContext = &context; Buffer::MakeVmaAllocator(backend); } RenderVulkanAPI::~RenderVulkanAPI() { zlog::info("~RenderVulkanAPI"); } + void RenderVulkanAPI::SwitchContext() + { + + } + void RenderVulkanAPI::InitRenderPass() + { + VkPasses.resize(RenderPassType::ZX_RENDER_PASS_COUNT); + auto gbuffer = GeometryBuffer(backend.GetDevice(), 3, 640, 720); + for (auto pass : mAllPasses) { + auto type = pass->GetType(); + if (type == RenderPassType::ZX_RENDER_PASS_FORWARD_RENDERING) { + VkPasses[type] = ForwardPass::MakePass(backend.GetDevice(), gbuffer); + } + } + } void RenderVulkanAPI::SetViewPort(uint32_t width, uint32_t height, uint32_t xOffset, uint32_t yOffset) { mViewPortInfo.width = width; @@ -35,28 +53,41 @@ namespace engineapi { auto meshBuffer = GetNextVAO(mesh->VAO); meshBuffer->indexCount = mesh->mIndices.size(); meshBuffer->vertexCount = mesh->mVertices.size(); - + // ----------------------------------------------- Vertex Buffer ----------------------------------------------- VkDeviceSize vertexBufferSize = sizeof(Vertex) * mesh->mVertices.size(); - VmaAllocationCreateInfo vertexStagingAllocInfo = {}; - VkBufferCreateInfo vertexStagingBufferInfo = Buffer::MakeStageInfo(vertexStagingAllocInfo, vertexBufferSize); - - VmaAllocation vertexStagingBufferAlloc; - VkBuffer vertexStagingBuffer = Buffer::CreateBuffer(vertexStagingBufferInfo, vertexStagingAllocInfo, vertexStagingBufferAlloc); + VmaAllocationCreateInfo vertexVmaStagingInfo = {}; + VmaAllocation vertexVmaStagingAlloc; + VkBuffer vertexStagingBuffer = Buffer::CreateStageBuffer(vertexVmaStagingInfo, vertexVmaStagingAlloc, vertexBufferSize); // 拷贝数据到StagingBuffer - Buffer::CopyData(vertexStagingBufferAlloc, mesh->mVertices.data(), vertexBufferSize); + Buffer::CopyData(vertexVmaStagingAlloc, mesh->mVertices.data(), vertexBufferSize); + + 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); + + // ----------------------------------------------- Index Buffer ----------------------------------------------- + VkDeviceSize indexBufferSize = sizeof(uint32_t) * mesh->mIndices.size(); + VmaAllocationCreateInfo indexVmaStagingInfo = {}; + VmaAllocation indexVmaStagingAlloc; + VkBuffer indexStagingBuffer = Buffer::CreateStageBuffer(indexVmaStagingInfo, indexVmaStagingAlloc, vertexBufferSize); + // 拷贝数据到StagingBuffer + Buffer::CopyData(indexVmaStagingAlloc, mesh->mIndices.data(), indexBufferSize); + + VmaAllocationCreateInfo indexVmaCreateInfo = {}; + VkBufferCreateInfo indexCreateInfo = Buffer::MakeDeviceInfo(indexVmaCreateInfo, indexBufferSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); + meshBuffer->indexBuffer = Buffer::CreateBuffer(indexCreateInfo, indexVmaCreateInfo, meshBuffer->vertexBufferAlloc); - VkBufferUsageFlags flags = 0;//加入光线追踪 - VmaAllocationCreateInfo vertexBufferAllocInfo = {}; - VkBufferCreateInfo vertexBufferInfo = Buffer::MakeDeviceInfo(vertexBufferAllocInfo, vertexBufferSize, flags); - meshBuffer->vertexBuffer = Buffer::CreateBuffer(vertexBufferInfo, vertexBufferAllocInfo, meshBuffer->vertexBufferAlloc); auto fn = [=](CommandBuffer& cmd) { cmd.CmdCopyBuffer(vertexStagingBuffer, meshBuffer->vertexBuffer, vertexBufferSize); + cmd.CmdCopyBuffer(indexStagingBuffer, meshBuffer->indexBuffer, indexBufferSize); }; auto callback = [=]() { // 销毁StagingBuffer - Buffer::DestroyBuffer(vertexStagingBuffer, vertexStagingBufferAlloc); + Buffer::DestroyBuffer(vertexStagingBuffer, vertexVmaStagingAlloc); + Buffer::DestroyBuffer(indexStagingBuffer, indexVmaStagingAlloc); mesh->EndLoad(); }; if (mesh->IsAsync()) { @@ -66,6 +97,24 @@ namespace engineapi { Backend::TransferWorker->ImmediatelyExecute(fn, callback); } } + void RenderVulkanAPI::DrawStaticMesh(Mesh* mesh) + { + + } + void RenderVulkanAPI::DrawStaticMesh(Mesh* mesh) + { + auto vulkanVAO = VAOList[mesh->VAO]; + Backend::RenderWorker->Draw([=](CommandBuffer& cmd) { + VkCommandBuffer ptr = cmd.Ptr(); + context.Pass->BeginPass(cmd); + VkBuffer vertexBuffers[] = { vulkanVAO->vertexBuffer }; + VkDeviceSize offsets[] = { 0 }; + vkCmdBindVertexBuffers(ptr, 0, 1, vertexBuffers, offsets); + vkCmdBindIndexBuffer(ptr, vulkanVAO->indexBuffer, 0, VK_INDEX_TYPE_UINT32); + vkCmdDrawIndexed(ptr, vulkanVAO->indexCount, 1, 0, 0, 0); + context.Pass->EndPass(cmd); + }); + } VulkanVAO* RenderVulkanAPI::GetNextVAO(uint32_t& VAO_index) { uint32_t length = (uint32_t)VAOList.size(); @@ -81,5 +130,6 @@ namespace engineapi { VAOList.push_back(vao); return vao; } + } diff --git a/engine/src/engine/vulkanapi/vulkanapi.h b/engine/src/engine/vulkanapi/vulkanapi.h index 66ac967..7e1b8ef 100644 --- a/engine/src/engine/vulkanapi/vulkanapi.h +++ b/engine/src/engine/vulkanapi/vulkanapi.h @@ -1,6 +1,8 @@ #pragma once #include "backend.h" +#include "wrapper/renderpass.h" #include "render/renderapi.h" +#include "vulkan_context.h" #include "vulkan_struct.h" using namespace vulkanapi; namespace engineapi @@ -9,15 +11,23 @@ namespace engineapi { public: Backend backend; + VulkanContext context; vector VAOList; + vector VkPasses; public: RenderVulkanAPI(); virtual ~RenderVulkanAPI()override; + public: + virtual void SwitchContext()override; + public: + virtual void InitRenderPass()override; + public: virtual void SetViewPort(uint32_t width, uint32_t height, uint32_t xOffset = 0, uint32_t yOffset = 0)override; virtual void BeginFrame()override; virtual void EndFrame()override; virtual void SetStaticMesh(Mesh* mesh)override; + virtual void DrawStaticMesh(Mesh* mesh)override; public: VulkanVAO* GetNextVAO(uint32_t& VAO_index); public: diff --git a/engine/src/engine/vulkanapi/wrapper/buffer.cpp b/engine/src/engine/vulkanapi/wrapper/buffer.cpp index c48a813..f49faf7 100644 --- a/engine/src/engine/vulkanapi/wrapper/buffer.cpp +++ b/engine/src/engine/vulkanapi/wrapper/buffer.cpp @@ -51,6 +51,11 @@ namespace vulkanapi { vmaCreateBuffer(vmaAllocator, &bufferCreateInfo, &allocationCreateInfo, &buffer, &allocation, nullptr); return buffer; } + VkBuffer Buffer::CreateStageBuffer(VmaAllocationCreateInfo& allocationCreateInfo, VmaAllocation& allocation, VkDeviceSize bufferSize) + { + VkBufferCreateInfo bufferCreateInfo = MakeStageInfo(allocationCreateInfo, bufferSize); + return CreateBuffer(bufferCreateInfo, allocationCreateInfo, allocation); + } void Buffer::CopyData(VmaAllocation& allocation, void* data, VkDeviceSize size) { // 拷贝数据到StagingBuffer diff --git a/engine/src/engine/vulkanapi/wrapper/buffer.h b/engine/src/engine/vulkanapi/wrapper/buffer.h index 787b25d..06ec432 100644 --- a/engine/src/engine/vulkanapi/wrapper/buffer.h +++ b/engine/src/engine/vulkanapi/wrapper/buffer.h @@ -13,6 +13,7 @@ namespace vulkanapi { static VkBuffer CreateBuffer(VkBufferCreateInfo& bufferCreateInfo, VmaAllocationCreateInfo& allocationCreateInfo, VmaAllocation& allocation); + static VkBuffer CreateStageBuffer(VmaAllocationCreateInfo& allocationCreateInfo, VmaAllocation& allocation, VkDeviceSize vertexBufferSize); static void CopyData(VmaAllocation& allocation,void* data, VkDeviceSize size); static void DestroyBuffer(VkBuffer buffer, VmaAllocation bufferAlloc); }; diff --git a/engine/src/engine/vulkanapi/wrapper/commandbuffer.cpp b/engine/src/engine/vulkanapi/wrapper/commandbuffer.cpp index 297a98c..7eb6d2b 100644 --- a/engine/src/engine/vulkanapi/wrapper/commandbuffer.cpp +++ b/engine/src/engine/vulkanapi/wrapper/commandbuffer.cpp @@ -11,7 +11,7 @@ namespace vulkanapi { } CommandBuffer::~CommandBuffer() { - zlog::info("CommandBuffer Destruct {:#x} isNull = {}", (uint64_t)this, mPtr == nullptr || mFence == nullptr); + //zlog::info("CommandBuffer Destruct {:#x} isNull = {}", (uint64_t)this, mPtr == nullptr || mFence == nullptr); if (mPtr) { mPool.FreeBuffer(mPtr); } @@ -26,7 +26,7 @@ namespace vulkanapi { { other.mPtr = nullptr; other.mFence = nullptr; - zlog::info("CommandBuffer MoveConstruct {:#x} => {:#x}", (uint64_t)&other, (uint64_t)this); + //zlog::info("CommandBuffer MoveConstruct {:#x} => {:#x}", (uint64_t)&other, (uint64_t)this); } void CommandBuffer::Reset() { @@ -66,5 +66,14 @@ namespace vulkanapi { { vkWaitForFences(device, 1, &mFence, VK_TRUE, UINT64_MAX); } + void CommandBuffer::BindVertexBuffer(VkBuffer buffer, uint32_t offset) + { + VkDeviceSize offsets[] = { offset }; + vkCmdBindVertexBuffers(mPtr, 0, 1, &buffer, offsets); + } + void CommandBuffer::BindIndexBuffers(VkBuffer buffer, uint32_t offset, VkIndexType type) + { + vkCmdBindIndexBuffer(mPtr, buffer, offset, type); + } } diff --git a/engine/src/engine/vulkanapi/wrapper/commandbuffer.h b/engine/src/engine/vulkanapi/wrapper/commandbuffer.h index 3dfa78e..a11ff2e 100644 --- a/engine/src/engine/vulkanapi/wrapper/commandbuffer.h +++ b/engine/src/engine/vulkanapi/wrapper/commandbuffer.h @@ -25,5 +25,8 @@ namespace vulkanapi { void CmdCopyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size); void Submit(VkQueue& queue); void WaitFofFence(VkDevice& device); + + void BindVertexBuffer(VkBuffer buffer, uint32_t offset); + void BindIndexBuffers(VkBuffer buffer, uint32_t offset, VkIndexType type); }; } \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/wrapper/renderpass.cpp b/engine/src/engine/vulkanapi/wrapper/renderpass.cpp index f65519e..64b09c4 100644 --- a/engine/src/engine/vulkanapi/wrapper/renderpass.cpp +++ b/engine/src/engine/vulkanapi/wrapper/renderpass.cpp @@ -1,5 +1,6 @@ #include "renderpass.h" #include "device.h" +#include "commandbuffer.h" namespace vulkanapi { RenderPass::RenderPass(Device& device, const char* name, vector& attachments, @@ -19,5 +20,23 @@ namespace vulkanapi { dependencies.data() }; vkCreateRenderPass(device.Ptr(), &create_info, nullptr, &mPtr); + + mPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + mPassBeginInfo.renderPass = mPtr; + } + void RenderPass::BeginPass(CommandBuffer& cmd) + { + vkCmdBeginRenderPass(cmd.Ptr(), &mPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); + } + void RenderPass::EndPass(CommandBuffer& cmd) + { + vkCmdEndRenderPass(cmd.Ptr()); + } + void RenderPass::SetViewPort(uint32_t width, uint32_t height, int32_t xoffset, int32_t yoffset) + { + // 这个render area定义了shader将要加载和存储的位置 + mPassBeginInfo.renderArea.offset = { xoffset, yoffset }; + // 一般来说大小(extend)是和framebuffer的attachment一致的,如果小了会浪费,大了超出去的部分是一些未定义数值 + mPassBeginInfo.renderArea.extent = { width, height }; } } diff --git a/engine/src/engine/vulkanapi/wrapper/renderpass.h b/engine/src/engine/vulkanapi/wrapper/renderpass.h index 74c6a5a..5e73d37 100644 --- a/engine/src/engine/vulkanapi/wrapper/renderpass.h +++ b/engine/src/engine/vulkanapi/wrapper/renderpass.h @@ -4,14 +4,23 @@ namespace vulkanapi { class Device; + class CommandBuffer; class RenderPass { protected: VkRenderPass mPtr; + VkRenderPassBeginInfo mPassBeginInfo{}; + public: RenderPass(Device& device, const char* name, vector& attachments, vector& subpasses, vector& dependencies); - //colorAttachments, depthAttachment, subpasses, dependencies); + + public: + void BeginPass(CommandBuffer& cmd); + void EndPass(CommandBuffer& cmd); + + public: + void SetViewPort(uint32_t width, uint32_t height, int32_t xoffset, int32_t yoffset); }; }; \ No newline at end of file