diff --git a/example/Vulkan/Geometry2D.cpp b/example/Vulkan/Geometry2D.cpp index ffb8040a..ab0eceab 100644 --- a/example/Vulkan/Geometry2D.cpp +++ b/example/Vulkan/Geometry2D.cpp @@ -7,7 +7,8 @@ #include #include #include -#include +#include +#include using namespace hgl; using namespace hgl::graph; @@ -30,12 +31,13 @@ private: uint swap_chain_count=0; SceneDB * db =nullptr; + SceneNode * render_root =nullptr; + RenderList * render_list =nullptr; vulkan::Material * material =nullptr; vulkan::DescriptorSets * descriptor_sets =nullptr; vulkan::Renderable * render_obj =nullptr; - RenderableNode * render_node =nullptr; vulkan::Buffer * ubo_mvp =nullptr; @@ -46,7 +48,8 @@ public: ~TestApp() { - SAFE_CLEAR(render_node); + SAFE_CLEAR(render_list); + SAFE_CLEAR(render_root); SAFE_CLEAR(db); SAFE_CLEAR_OBJECT_ARRAY(cmd_buf,swap_chain_count); @@ -70,20 +73,6 @@ private: bool CreateRenderObject() { - //struct RectangleCreateInfo rci; - - //rci.scope.Set(10,10,10,10); - - //render_obj=CreateRectangle(device,material,&rci); - - //struct RoundRectangleCreateInfo rrci; - - //rrci.scope.Set(10,10,SCREEN_WIDTH-20,SCREEN_HEIGHT-20); - //rrci.radius=8; //半径为8 - //rrci.round_per=8; //圆角切分成8段 - - //render_obj=CreateRoundRectangle(device,material,&rrci); - struct CircleCreateInfo cci; cci.center.x=SCREEN_WIDTH/2; @@ -136,25 +125,20 @@ private: return pipeline; } - void Draw(vulkan::CommandBuffer *cb,RenderableNode *ri) + bool InitScene() { - cb->Bind(ri->GetPipeline()); - cb->Bind(ri->GetDescriptorSets()); + RenderableInstance *ri=db->CreateRenderableInstance(pipeline,descriptor_sets,render_obj); - vulkan::Renderable *obj=ri->GetRenderable(); + if(!ri) + return(false); - cb->Bind(obj); + render_root=new SceneNode(); + render_list=new RenderList(); - const vulkan::IndexBuffer *ib=obj->GetIndexBuffer(); + render_root->Add(ri); + render_root->ExpendToList(render_list); - if(ib) - { - cb->DrawIndexed(ib->GetCount()); - } - else - { - cb->Draw(obj->GetDrawCount()); - } + return(true); } bool InitCommandBuffer() @@ -170,7 +154,7 @@ private: cmd_buf[i]->Begin(); cmd_buf[i]->BeginRenderPass(device->GetRenderPass(),device->GetFramebuffer(i)); - Draw(cmd_buf[i],render_node); + render_list->Render(cmd_buf[i]); cmd_buf[i]->EndRenderPass(); cmd_buf[i]->End(); } @@ -201,7 +185,8 @@ public: if(!InitPipeline()) return(false); - render_node=new RenderableNode(pipeline,descriptor_sets,render_obj); + if(!InitScene()) + return(false); if(!InitCommandBuffer()) return(false); diff --git a/inc/hgl/graph/RenderList.h b/inc/hgl/graph/RenderList.h index 241e184c..cbac3aeb 100644 --- a/inc/hgl/graph/RenderList.h +++ b/inc/hgl/graph/RenderList.h @@ -3,12 +3,13 @@ #include #include +#include #include namespace hgl { namespace graph { - class RenderableNode; + class RenderableInstance; struct UBOMatrixData { @@ -41,13 +42,14 @@ namespace hgl private: - List renderable_node_list; + List scene_node_list; vulkan::Pipeline * last_pipeline; vulkan::DescriptorSets *last_desc_sets; vulkan::Renderable * last_renderable; - void Render(RenderableNode *,const Matrix4f &); + void Render(RenderableInstance *); + void Render(List &); public: @@ -61,17 +63,19 @@ namespace hgl ~RenderList()=default; - void Add (RenderableNode *node) {if(node)renderable_node_list.Add(node);} - void Clear () {renderable_node_list.ClearData();} + void Add (SceneNode *node) {if(node)scene_node_list.Add(node);} + void Clear () {scene_node_list.ClearData();} void SetCamera(const Camera &); + void SetMVP(const Matrix4f &proj,const Matrix4f &mv); + void SetSkyLightColor(const Color4f &c,const Vector4f &d) { ubo_skylight.sun_color=c; ubo_skylight.sun_direction=d; } - bool Render(); + bool Render(vulkan::CommandBuffer *); };//class RenderList }//namespace graph }//namespace hgl diff --git a/inc/hgl/graph/RenderableNode.h b/inc/hgl/graph/RenderableInstance.h similarity index 77% rename from inc/hgl/graph/RenderableNode.h rename to inc/hgl/graph/RenderableInstance.h index 127dbf70..011b3872 100644 --- a/inc/hgl/graph/RenderableNode.h +++ b/inc/hgl/graph/RenderableInstance.h @@ -1,10 +1,9 @@ -#ifndef HGL_GRAPH_RENDERABLE_NODE_INCLUDE -#define HGL_GRAPH_RENDERABLE_NODE_INCLUDE +#ifndef HGL_GRAPH_RENDERABLE_INSTANCE_INCLUDE +#define HGL_GRAPH_RENDERABLE_INSTANCE_INCLUDE #include #include #include -#include namespace hgl { namespace graph @@ -12,7 +11,7 @@ namespace hgl /** * 可渲染对象节点 */ - class RenderableNode:public SceneNode + class RenderableInstance { vulkan::Pipeline * pipeline; vulkan::DescriptorSets * desc_sets; @@ -20,8 +19,8 @@ namespace hgl public: - RenderableNode(vulkan::Pipeline *p,vulkan::DescriptorSets *ds,vulkan::Renderable *r):pipeline(p),desc_sets(ds),render_obj(r){} - virtual ~RenderableNode() + RenderableInstance(vulkan::Pipeline *p,vulkan::DescriptorSets *ds,vulkan::Renderable *r):pipeline(p),desc_sets(ds),render_obj(r){} + virtual ~RenderableInstance() { //需要在这里添加删除pipeline/desc_sets/render_obj引用计数的代码 } @@ -31,9 +30,7 @@ namespace hgl vulkan::Renderable * GetRenderable (){return render_obj;} const AABB & GetBoundingBox ()const{return render_obj->GetBoundingBox();} - const bool CanRenderable ()const override{return true;} ///<是否可以渲染 - - const int Comp(const RenderableNode *ri)const + const int Comp(const RenderableInstance *ri)const { //绘制顺序: @@ -72,8 +69,8 @@ namespace hgl return render_obj-ri->render_obj; } - CompOperator(const RenderableNode *,Comp) + CompOperator(const RenderableInstance *,Comp) };//class RenderableNode }//namespace graph }//namespace hgl -#endif//HGL_GRAPH_RENDERABLE_NODE_INCLUDE +#endif//HGL_GRAPH_RENDERABLE_INSTANCE_INCLUDE diff --git a/inc/hgl/graph/SceneDB.h b/inc/hgl/graph/SceneDB.h index df16f804..d4dba686 100644 --- a/inc/hgl/graph/SceneDB.h +++ b/inc/hgl/graph/SceneDB.h @@ -7,6 +7,7 @@ #include #include #include +#include #include namespace hgl { @@ -14,9 +15,10 @@ namespace hgl { using MaterialID =int; using PipelineID =int; - using DescriptorSetsID =int; - using RenderableID =int; using BufferID =int; + using DescriptorSetsID =int; + using RenderableID =int; + using RenderableInstanceID =int; class VertexBufferCreater; @@ -27,22 +29,24 @@ namespace hgl { vulkan::Device *device; - IDResManage rm_material; ///<材质合集 - IDResManage rm_pipeline; ///<管线合集 - IDResManage rm_desc_sets; ///<描述符合集 - IDResManage rm_renderables; ///<可渲染对象合集 - IDResManage rm_buffers; ///<顶点缓冲区集合 + IDResManage rm_material; ///<材质合集 + IDResManage rm_pipeline; ///<管线合集 + IDResManage rm_desc_sets; ///<描述符合集 + IDResManage rm_renderables; ///<可渲染对象合集 + IDResManage rm_buffers; ///<顶点缓冲区合集 + IDResManage rm_renderable_instances; ///<渲染实例集合集 public: SceneDB(vulkan::Device *dev):device(dev){} virtual ~SceneDB()=default; - MaterialID Add(vulkan::Material * mtl ){return rm_material.Add(mtl);} - PipelineID Add(vulkan::Pipeline * p ){return rm_pipeline.Add(p);} - DescriptorSetsID Add(vulkan::DescriptorSets *ds ){return rm_desc_sets.Add(ds);} - RenderableID Add(vulkan::Renderable * r ){return rm_renderables.Add(r);} - BufferID Add(vulkan::Buffer * buf ){return rm_buffers.Add(buf);} + MaterialID Add(vulkan::Material * mtl ){return rm_material.Add(mtl);} + PipelineID Add(vulkan::Pipeline * p ){return rm_pipeline.Add(p);} + DescriptorSetsID Add(vulkan::DescriptorSets *ds ){return rm_desc_sets.Add(ds);} + RenderableID Add(vulkan::Renderable * r ){return rm_renderables.Add(r);} + BufferID Add(vulkan::Buffer * buf ){return rm_buffers.Add(buf);} + RenderableInstanceID Add(RenderableInstance * ri ){return rm_renderable_instances.Add(ri);} vulkan::VertexBuffer *CreateVBO(VkFormat format,uint32_t count,const void *data,VkSharingMode sharing_mode=VK_SHARING_MODE_EXCLUSIVE); vulkan::VertexBuffer *CreateVBO(VkFormat format,uint32_t count,VkSharingMode sharing_mode=VK_SHARING_MODE_EXCLUSIVE){return CreateVBO(format,count,nullptr,sharing_mode);} @@ -57,11 +61,14 @@ namespace hgl #undef SCENE_DB_CREATE_FUNC - vulkan::Material * GetMaterial (const MaterialID &id){return rm_material.Get(id);} - vulkan::Pipeline * GetPipeline (const PipelineID &id){return rm_pipeline.Get(id);} - vulkan::DescriptorSets *GetDescSets (const DescriptorSetsID &id){return rm_desc_sets.Get(id);} - vulkan::Renderable * GetRenderable (const RenderableID &id){return rm_renderables.Get(id);} - vulkan::Buffer * GetBuffer (const BufferID &id){return rm_buffers.Get(id);} + RenderableInstance * CreateRenderableInstance(vulkan::Pipeline *p,vulkan::DescriptorSets *ds,vulkan::Renderable *r); + + vulkan::Material * GetMaterial (const MaterialID &id){return rm_material.Get(id);} + vulkan::Pipeline * GetPipeline (const PipelineID &id){return rm_pipeline.Get(id);} + vulkan::DescriptorSets *GetDescSets (const DescriptorSetsID &id){return rm_desc_sets.Get(id);} + vulkan::Renderable * GetRenderable (const RenderableID &id){return rm_renderables.Get(id);} + vulkan::Buffer * GetBuffer (const BufferID &id){return rm_buffers.Get(id);} + RenderableInstance * GetRenderableInstance (const RenderableInstanceID &id){return rm_renderable_instances.Get(id);} };//class SceneDB }//namespace graph }//namespace hgl diff --git a/inc/hgl/graph/SceneNode.h b/inc/hgl/graph/SceneNode.h index be8658f1..97d559d4 100644 --- a/inc/hgl/graph/SceneNode.h +++ b/inc/hgl/graph/SceneNode.h @@ -11,6 +11,7 @@ namespace hgl class SceneNode; struct Camera; class RenderList; + class RenderableInstance; using RenderListCompFunc=float (*)(Camera *,SceneNode *,SceneNode *); ///<渲染列表排序比较函数 @@ -40,6 +41,8 @@ namespace hgl ObjectList SubNode; ///<子节点 + List renderable_instances; ///<可渲染实例 + public: SceneNode()=default; @@ -48,21 +51,11 @@ namespace hgl ClearSubNode(); } - void AddSubNode(SceneNode *n){if(n)SubNode.Add(n);} ///<增加一个子节点 - SceneNode * CreateSubNode() ///<创建一个子节点 - { - SceneNode *sn=new SceneNode(); - SubNode.Add(sn); - return sn; - } + void Add(SceneNode *n){if(n)SubNode.Add(n);} ///<增加一个子节点 + void ClearSubNode(){SubNode.ClearData();} ///<清除子节点 - void ClearSubNode(){SubNode.Clear();} ///<清除子节点 - - public: - - virtual const bool IsCamera()const{return false;} ///<是否是摄像机 - virtual const bool IsLight()const{return false;} ///<是否是灯光 - virtual const bool CanRenderable()const{return false;} ///<是否可以渲染 + void Add(RenderableInstance *ri){if(ri)renderable_instances.Add(ri);} ///<增加渲染实例 + void ClearRenderableInstance(){renderable_instances.ClearData();} ///<清除渲染实例 public: //坐标相关方法 @@ -81,12 +74,12 @@ namespace hgl public: //渲染列表相关方法 - virtual bool ExpendToList(RenderList *,FilterSceneNodeFunc func=nullptr,void *func_data=nullptr)const; ///<展开到渲染列表 - bool ExpendToList(RenderList *rl,Frustum *f)const ///<展开到渲染列表(使用平截头裁剪) + virtual bool ExpendToList(RenderList *,FilterSceneNodeFunc func=nullptr,void *func_data=nullptr); ///<展开到渲染列表 + bool ExpendToList(RenderList *rl,Frustum *f) ///<展开到渲染列表(使用平截头裁剪) {return ExpendToList(rl,FrustumClipFilter,f);} -// bool ExpendToList(RenderList *,const Matrix4f &,const Matrix4f &,RenderListCompFunc=nullptr)const; ///<展开到渲染列表(使用平截头裁剪并排序) - bool ExpendToList(RenderList *,Camera *,RenderListCompFunc=nullptr)const; ///<展开到渲染列表(使用摄像机平截头裁剪并排序) +// bool ExpendToList(RenderList *,const Matrix4f &,const Matrix4f &,RenderListCompFunc=nullptr); ///<展开到渲染列表(使用平截头裁剪并排序) + bool ExpendToList(RenderList *,Camera *,RenderListCompFunc=nullptr); ///<展开到渲染列表(使用摄像机平截头裁剪并排序) };//class SceneNode }//namespace graph }//namespace hgl diff --git a/src/SceneGraph/CMakeLists.txt b/src/SceneGraph/CMakeLists.txt index cb93304d..c77b934e 100644 --- a/src/SceneGraph/CMakeLists.txt +++ b/src/SceneGraph/CMakeLists.txt @@ -4,7 +4,8 @@ ${ROOT_INCLUDE_PATH}/hgl/graph/SceneDB.h ${ROOT_INCLUDE_PATH}/hgl/graph/SceneNode.h ${ROOT_INCLUDE_PATH}/hgl/graph/SceneOrient.h - ${ROOT_INCLUDE_PATH}/hgl/graph/RenderableNode.h + ${ROOT_INCLUDE_PATH}/hgl/graph/RenderableInstance.h + ${ROOT_INCLUDE_PATH}/hgl/graph/RenderList.h ${ROOT_INCLUDE_PATH}/hgl/graph/VertexBufferCreater.h ${ROOT_INCLUDE_PATH}/hgl/graph/VertexBuffer.h ${ROOT_INCLUDE_PATH}/hgl/graph/InlineGeometry.h) diff --git a/src/SceneGraph/RenderList.cpp b/src/SceneGraph/RenderList.cpp index 123a2996..f0c6a006 100644 --- a/src/SceneGraph/RenderList.cpp +++ b/src/SceneGraph/RenderList.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include namespace hgl { @@ -41,7 +41,15 @@ namespace hgl &camera); } - void RenderList::Render(RenderableNode *ri,const Matrix4f &fin_mvp) + void RenderList::SetMVP(const Matrix4f &proj,const Matrix4f &mv) + { + ubo_matrix.projection =proj; + ubo_matrix.modelview =mv; + ubo_matrix.mvp =proj*mv; + ubo_matrix.normal =ubo_matrix.modelview.Float3x3Part(); //法线矩阵为3x3 + } + + void RenderList::Render(RenderableInstance *ri) { if(last_pipeline!=ri->GetPipeline()) { @@ -84,25 +92,36 @@ namespace hgl } } - bool RenderList::Render() + void RenderList::Render(List &ri_list) { - if(!cmd_buf) + const int count=ri_list.GetCount(); + RenderableInstance **ri=ri_list.GetData(); + + for(int i=0;iGetLocalToWorldMatrix(); - - Render(*node,ubo_matrix.projection*fin_mv); - - node++; + Render((*node)->renderable_instances); + ++node; } return(true); diff --git a/src/SceneGraph/SceneDB.cpp b/src/SceneGraph/SceneDB.cpp index 9428708b..b84f8017 100644 --- a/src/SceneGraph/SceneDB.cpp +++ b/src/SceneGraph/SceneDB.cpp @@ -1,5 +1,6 @@ #include #include +#include namespace hgl { @@ -40,5 +41,17 @@ namespace hgl SCENE_DB_CREATE_BUFFER(INBO) #undef SCENE_DB_CREATE_BUFFER + + RenderableInstance *SceneDB::CreateRenderableInstance(vulkan::Pipeline *p,vulkan::DescriptorSets *ds,vulkan::Renderable *r) + { + if(!p||!ds||!r) + return(nullptr); + + RenderableInstance *ri=new RenderableInstance(p,ds,r); + + Add(ri); + + return ri; + } }//namespace graph }//namespace hgl diff --git a/src/SceneGraph/SceneNode.cpp b/src/SceneGraph/SceneNode.cpp index 5ae01016..39b0cbd4 100644 --- a/src/SceneGraph/SceneNode.cpp +++ b/src/SceneGraph/SceneNode.cpp @@ -62,7 +62,7 @@ namespace hgl * @param func_data 过滤函数用辅助数据 * @return 成功与否 */ - bool SceneNode::ExpendToList(RenderList *rl,FilterSceneNodeFunc func,void *func_data)const + bool SceneNode::ExpendToList(RenderList *rl,FilterSceneNodeFunc func,void *func_data) { if(!rl)return(false); @@ -70,17 +70,23 @@ namespace hgl if(!func(this,func_data)) return(false); - if(CanRenderable()) - rl->Add((RenderableNode *)this); //增加当前节点 - - int count=SubNode.GetCount(); - SceneNode **sub=SubNode.GetData(); - - for(int i=0;iExpendToList(rl,func,func_data); //展开子节点 + int count=renderable_instances.GetCount(); - sub++; + if(count>0) + rl->Add(this); + } + + { + int count=SubNode.GetCount(); + SceneNode **sub=SubNode.GetData(); + + for(int i=0;iExpendToList(rl,func,func_data); //展开子节点 + + ++sub; + } } return(true); @@ -99,7 +105,7 @@ namespace hgl * @param cam 摄像机 * @param comp_func 渲染列表远近比较函数 */ - bool SceneNode::ExpendToList(RenderList *rl,Camera *cam,RenderListCompFunc comp_func)const + bool SceneNode::ExpendToList(RenderList *rl,Camera *cam,RenderListCompFunc comp_func) { if(!rl||!cam)return(false);