From 2e53b48fffd824a2b97ea05f5635a7746a1dce69 Mon Sep 17 00:00:00 2001 From: hyzboy Date: Sat, 25 Jan 2025 17:17:55 +0800 Subject: [PATCH] [BIG MILESTONE] render framework first test ok! can draw! --- example/Basic/rf_test.cpp | 88 ++++++++++++++----- example/common/WorkObject.h | 31 ++++++- inc/hgl/graph/RenderFramework.h | 4 + inc/hgl/graph/module/RenderTargetManager.h | 4 +- inc/hgl/graph/module/SwapchainModule.h | 8 +- src/SceneGraph/RenderFramework.cpp | 6 +- .../Vulkan/VKSwapchainRenderTarget.cpp | 2 +- src/SceneGraph/module/SwapchainModule.cpp | 19 ++-- 8 files changed, 125 insertions(+), 37 deletions(-) diff --git a/example/Basic/rf_test.cpp b/example/Basic/rf_test.cpp index 18cfa50e..b2bbcc64 100644 --- a/example/Basic/rf_test.cpp +++ b/example/Basic/rf_test.cpp @@ -5,6 +5,7 @@ #include #include #include +#include using namespace hgl; using namespace hgl::graph; @@ -37,6 +38,8 @@ class TestApp:public WorkObject { private: + Color4f clear_color =Color4f(0.2f,0.2f,0.2f,1.0f); + MaterialInstance * material_instance =nullptr; Renderable * render_obj =nullptr; @@ -46,29 +49,31 @@ private: bool InitAutoMaterial() { - mtl::Material2DCreateConfig cfg(device->GetDeviceAttribute(),"VertexColor2d",Prim::Triangles); + mtl::Material2DCreateConfig cfg(GetDeviceAttribute(),"VertexColor2d",Prim::Triangles); cfg.coordinate_system=CoordinateSystem2D::NDC; cfg.local_to_world=false; AutoDelete mci=mtl::CreateVertexColor2D(&cfg); - material_instance=db->CreateMaterialInstance(mci,&vil_config); + material_instance=db->CreateMaterialInstance(mci); return material_instance; } bool InitPipeline() { -// pipeline=db->CreatePipeline(material_instance,sc_render_target,OS_TEXT("res/pipeline/solid2d")); - pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::Triangles); //等同上一行,为Framework重载,默认使用swapchain的render target + RenderPass *sc_render_pass=GetRenderFramework()->GetSwapchainModule()->GetRenderPass(); - return pipeline; +// pipeline=db->CreatePipeline(material_instance,sc_render_target,OS_TEXT("res/pipeline/solid2d")); + pipeline=sc_render_pass->CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::Triangles); //等同上一行,为Framework重载,默认使用swapchain的render target + + return pipeline; } bool InitVBO() { - PrimitiveCreater rpc(device,material_instance->GetVIL()); + PrimitiveCreater rpc(GetDevice(),material_instance->GetVIL()); rpc.Init("Triangle",VERTEX_COUNT); @@ -81,11 +86,11 @@ private: public: - bool Init(uint w,uint h) - { - if(!VulkanApplicationFramework::Init(w,h)) - return(false); + TestApp(RenderFramework *rf):WorkObject(rf) + {} + bool Init() + { if(!InitAutoMaterial()) return(false); @@ -95,34 +100,77 @@ public: if(!InitVBO()) return(false); - if(!BuildCommandBuffer(render_obj)) - return(false); +// if(!BuildCommandBuffer(render_obj)) +// return(false); return(true); } - void Resize(uint w,uint h)override - { - VulkanApplicationFramework::Resize(w,h); + //void Resize(uint w,uint h)override + //{ + // VulkanApplicationFramework::Resize(w,h); - BuildCommandBuffer(render_obj); - } + // BuildCommandBuffer(render_obj); + //} void Tick(double)override {} + void Render(RenderCmdBuffer *cb,Renderable *ri) + { + if(!ri)return; + + cb->BeginRenderPass(); + cb->BindPipeline(ri->GetPipeline()); + cb->BindDescriptorSets(ri->GetMaterial()); + cb->BindDataBuffer(ri->GetDataBuffer()); + cb->Draw(ri->GetDataBuffer(),ri->GetRenderData()); + cb->EndRenderPass(); + } + void Render(double) - {} + { + //WorkObject是工作对象,不是渲染对象,所以不应该直接自动指定RenderTarget,更不能直接指定RenderCmdBuffer + + //目前这里只是为了测试,所以这样写 + + RenderFramework *rf=GetRenderFramework(); + SwapchainModule *sm=rf->GetSwapchainModule(); + + sm->BeginFrame(); //这里会有AcquireNextImage操作 + + //这个使用完全不合理,录制CMD和推送swapchain是两回事,需要分开操作。 + //比如场景有的物件分静态和动态 + + //可能静态物件就全部一次性录制好,而动态物件则是每帧录制 + + RenderCmdBuffer *cb=sm->RecordCmdBuffer(); //这里会获取当前帧的RenderCmdBuffer、开启cmd录制、绑定FBO + + if(cb) + { + cb->SetClearColor(0,clear_color); + + Render(cb,render_obj); + + cb->End(); //结束cmd录制 + } + sm->EndFrame(); //这里会Submit和PresentBackbuffer + } };//class TestApp:public VulkanApplicationFramework int main(int,char **) { RenderFramework rf(OS_TEXT("RenderFramework Test")); - if(rf.Init(SCREEN_WIDTH,SCREEN_HEIGHT)) + if(!rf.Init(SCREEN_WIDTH,SCREEN_HEIGHT)) return(-1); WorkManager wm(&rf); - wm.Start(new TestApp); + AutoDelete app=new TestApp(&rf); + + if(!app->Init()) + return(-2); + + wm.Start(app); } diff --git a/example/common/WorkObject.h b/example/common/WorkObject.h index 93096987..463d0557 100644 --- a/example/common/WorkObject.h +++ b/example/common/WorkObject.h @@ -1,19 +1,30 @@ #pragma once #include #include +#include #include namespace hgl { class WorkObject { - RenderFramework *render_framework; + graph::RenderFramework *render_framework=nullptr; bool destroy_flag=false; bool tickable=true; bool renderable=true; + protected: + + graph::RenderResource *db=nullptr; //暂时的,未来会被更好的机制替代 + + public: + + graph::RenderFramework * GetRenderFramework (){return render_framework;} + graph::GPUDevice * GetDevice (){return render_framework->GetDevice();} + graph::GPUDeviceAttribute * GetDeviceAttribute (){return render_framework->GetDeviceAttribute();} + public: const bool IsDestroy()const{return destroy_flag;} @@ -26,11 +37,19 @@ namespace hgl public: + WorkObject(graph::RenderFramework *rf) + { + Join(rf); + } virtual ~WorkObject()=default; - virtual void Join(RenderFramework *rf) + virtual void Join(graph::RenderFramework *rf) { + if(!rf)return; + if(render_framework==rf)return; + render_framework=rf; + db=rf->GetRenderResource(); } virtual void Tick(double delta_time)=0; @@ -56,6 +75,11 @@ namespace hgl render_framework=rf; } + virtual ~WorkManager() + { + SAFE_CLEAR(cur_work_object); + } + void SetFPS(uint f) { fps=f; @@ -98,6 +122,9 @@ namespace hgl while(!cur_work_object->IsDestroy()) { Update(cur_work_object); + + render_framework->GetWindow()->Update(); + render_framework->GetDevice()->WaitIdle(); } } diff --git a/inc/hgl/graph/RenderFramework.h b/inc/hgl/graph/RenderFramework.h index 70bf04a9..73afb506 100644 --- a/inc/hgl/graph/RenderFramework.h +++ b/inc/hgl/graph/RenderFramework.h @@ -24,6 +24,8 @@ class RenderFramework:public io::WindowEvent GPUDevice * device =nullptr; + RenderResource * render_resource =nullptr; + private: double last_time =0; @@ -47,6 +49,8 @@ public: GPUDevice * GetDevice (){return device;} GPUDeviceAttribute * GetDeviceAttribute (){return device->GetDeviceAttribute();} + RenderResource * GetRenderResource (){return render_resource;} + public: GraphModuleManager * GetModuleManager (){return module_manager;} diff --git a/inc/hgl/graph/module/RenderTargetManager.h b/inc/hgl/graph/module/RenderTargetManager.h index fecf121d..8c7aac5b 100644 --- a/inc/hgl/graph/module/RenderTargetManager.h +++ b/inc/hgl/graph/module/RenderTargetManager.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include @@ -15,7 +15,7 @@ GRAPH_MODULE_CLASS(RenderTargetManager) public: RenderTargetManager(GPUDevice *,TextureManager *tm,RenderPassManager *rpm); - virtual ~RenderTargetManager(); + virtual ~RenderTargetManager()=default; public: //FrameBuffer相关 diff --git a/inc/hgl/graph/module/SwapchainModule.h b/inc/hgl/graph/module/SwapchainModule.h index 2a30e7ef..968c2c23 100644 --- a/inc/hgl/graph/module/SwapchainModule.h +++ b/inc/hgl/graph/module/SwapchainModule.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include @@ -37,9 +37,11 @@ public: public: - const VkExtent2D & GetSwapchainSize()const {return swapchain_rt->GetExtent();} + RenderPass * GetRenderPass ()const{return swapchain_rt->GetRenderPass();} - RenderCmdBuffer *Use(); + const VkExtent2D & GetSwapchainSize()const{return swapchain_rt->GetExtent();} + + RenderCmdBuffer *RecordCmdBuffer(int frame_index=-1); };//class SwapchainModule:public GraphModule diff --git a/src/SceneGraph/RenderFramework.cpp b/src/SceneGraph/RenderFramework.cpp index a44bc3ec..b5ea977a 100644 --- a/src/SceneGraph/RenderFramework.cpp +++ b/src/SceneGraph/RenderFramework.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,7 @@ RenderFramework::RenderFramework(const OSString &an) RenderFramework::~RenderFramework() { + SAFE_CLEAR(render_resource) SAFE_CLEAR(module_manager) --RENDER_FRAMEWORK_COUNT; @@ -109,6 +111,8 @@ bool RenderFramework::Init(uint w,uint h) OnResize(w,h); + render_resource=new RenderResource(device); + return(true); } @@ -175,7 +179,7 @@ bool RenderFramework::RunFrame(RenderModule *rm) swapchain_module->BeginFrame(); { - RenderCmdBuffer *rcb=swapchain_module->Use(); + RenderCmdBuffer *rcb=swapchain_module->RecordCmdBuffer(); if(rcb) { diff --git a/src/SceneGraph/Vulkan/VKSwapchainRenderTarget.cpp b/src/SceneGraph/Vulkan/VKSwapchainRenderTarget.cpp index 924326bc..eb0442cc 100644 --- a/src/SceneGraph/Vulkan/VKSwapchainRenderTarget.cpp +++ b/src/SceneGraph/Vulkan/VKSwapchainRenderTarget.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/src/SceneGraph/module/SwapchainModule.cpp b/src/SceneGraph/module/SwapchainModule.cpp index 45617e5d..fb0d08e6 100644 --- a/src/SceneGraph/module/SwapchainModule.cpp +++ b/src/SceneGraph/module/SwapchainModule.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -175,6 +175,9 @@ bool SwapchainModule::CreateSwapchain() bool SwapchainModule::CreateSwapchainRenderTarget() { + if(!CreateSwapchain()) + return(false); + GPUDevice *device=GetDevice(); DeviceQueue *q=device->CreateQueue(swapchain->image_count,false); @@ -195,16 +198,14 @@ bool SwapchainModule::CreateSwapchainRenderTarget() SwapchainModule::~SwapchainModule() { SAFE_CLEAR(swapchain_rt); - SAFE_CLEAR(swapchain); } SwapchainModule::SwapchainModule(GPUDevice *dev,TextureManager *tm,RenderTargetManager *rtm,RenderPassManager *rpm):GraphModuleInherit(dev,"SwapchainModule") { tex_manager=tm; rt_manager=rtm; + rp_manager=rpm; - if(!CreateSwapchain()) - return; //#ifdef _DEBUG // if(dev_attr->debug_utils) @@ -218,6 +219,7 @@ SwapchainModule::SwapchainModule(GPUDevice *dev,TextureManager *tm,RenderTargetM void SwapchainModule::OnResize(const VkExtent2D &extent) { SAFE_CLEAR(swapchain_rt) + swapchain=nullptr; GetDeviceAttribute()->RefreshSurfaceCaps(); @@ -246,14 +248,15 @@ void SwapchainModule::EndFrame() swapchain_rt->WaitFence(); } -RenderCmdBuffer *SwapchainModule::Use() +RenderCmdBuffer *SwapchainModule::RecordCmdBuffer(int frame_index) { - uint32_t index=swapchain_rt->GetCurrentFrameIndices(); + if(frame_index<0) + frame_index=swapchain_rt->GetCurrentFrameIndices(); - if(index>=swapchain->image_count) + if(frame_index>=swapchain->image_count) return(nullptr); - RenderCmdBuffer *rcb=swapchain->sc_image[index].cmd_buf; + RenderCmdBuffer *rcb=swapchain->sc_image[frame_index].cmd_buf; rcb->Begin(); rcb->BindFramebuffer(swapchain->render_pass,swapchain_rt->GetFramebuffer());