diff --git a/CMSceneGraph b/CMSceneGraph index ba9b1936..eaa42e6c 160000 --- a/CMSceneGraph +++ b/CMSceneGraph @@ -1 +1 @@ -Subproject commit ba9b1936f65e37c4852f2c59e6adb5d694a4a573 +Subproject commit eaa42e6c967b605c78e959cd5db6d10e3f443205 diff --git a/inc/hgl/graph/RenderList.h b/inc/hgl/graph/RenderList.h index e2bc838d..e28a34d8 100644 --- a/inc/hgl/graph/RenderList.h +++ b/inc/hgl/graph/RenderList.h @@ -31,7 +31,7 @@ namespace hgl RenderNodeList render_node_list; ///<场景节点列表 MaterialSets material_sets; ///<材质合集 - RenderNodeComparator render_node_comparator; + RenderNodeComparator *render_node_comparator; private: @@ -69,6 +69,19 @@ namespace hgl class RenderList2D:public RenderList { + + protected: + + virtual bool Begin() override; + virtual bool Expend(SceneNode *) override; + virtual void End() override; + + public: + + RenderList2D(); + virtual ~RenderList2D() override; + + virtual bool Expend(SceneNode *); }; class RenderList3D:public RenderList @@ -88,6 +101,8 @@ namespace hgl RenderList3D(); virtual ~RenderList3D() override; + + bool Expend(const CameraInfo &,SceneNode *); }; }//namespace graph }//namespace hgl diff --git a/inc/hgl/graph/RenderList2D.h b/inc/hgl/graph/RenderList2D.h new file mode 100644 index 00000000..e28a34d8 --- /dev/null +++ b/inc/hgl/graph/RenderList2D.h @@ -0,0 +1,109 @@ +#ifndef HGL_GRAPH_RENDER_LIST_INCLUDE +#define HGL_GRAPH_RENDER_LIST_INCLUDE + +#include +#include +#include +#include +#include +#include +#include +#include +namespace hgl +{ + namespace graph + { + using MaterialSets=SortedSets; + + /** + * 渲染对象列表
+ * 已经展开的渲染对象列表,产生mvp用UBO/SSBO等数据,最终创建RenderCommandBuffer + */ + class RenderList + { + protected: + + GPUDevice * device; + RenderCmdBuffer *cmd_buf; + + private: + + RenderNodeList render_node_list; ///<场景节点列表 + MaterialSets material_sets; ///<材质合集 + + RenderNodeComparator *render_node_comparator; + + private: + + List ri_list; + + VkDescriptorSet ds_list[DESCRIPTOR_SET_TYPE_COUNT]; + DescriptorSet *renderable_desc_sets; + + uint32_t ubo_offset; + uint32_t ubo_align; + + protected: + + virtual bool Begin(); + virtual bool Expend(SceneNode *); + virtual void End(); + + private: + + Pipeline * last_pipeline; + MaterialParameters *last_mp[DESCRIPTOR_SET_TYPE_COUNT]; + uint32_t last_vbo; + + void Render(Renderable *); + + public: + + RenderList(GPUDevice *); + virtual ~RenderList(); + + virtual bool Expend(const CameraInfo &,SceneNode *); + + virtual bool Render(RenderCmdBuffer *); + };//class RenderList + + class RenderList2D:public RenderList + { + + protected: + + virtual bool Begin() override; + virtual bool Expend(SceneNode *) override; + virtual void End() override; + + public: + + RenderList2D(); + virtual ~RenderList2D() override; + + virtual bool Expend(SceneNode *); + }; + + class RenderList3D:public RenderList + { + protected: + + CameraInfo camera_info; + GPUArrayBuffer *mvp_array; + + protected: + + virtual bool Begin() override; + virtual bool Expend(SceneNode *) override; + virtual void End() override; + + public: + + RenderList3D(); + virtual ~RenderList3D() override; + + bool Expend(const CameraInfo &,SceneNode *); + }; + }//namespace graph +}//namespace hgl +#endif//HGL_GRAPH_RENDER_LIST_INCLUDE diff --git a/inc/hgl/graph/RenderNode.h b/inc/hgl/graph/RenderNode.h index 93b05c88..0ada9607 100644 --- a/inc/hgl/graph/RenderNode.h +++ b/inc/hgl/graph/RenderNode.h @@ -10,14 +10,17 @@ namespace hgl { class Renderable; - struct RenderNode + constexpr double RenderNode3DDistanceFactor=100.0; + + struct RenderNode3D { MVPMatrix matrix; Vector3f WorldCenter; - float distance_to_camera_square; -// float distance_to_camera; + double distance_to_camera_square; + + double distance_to_camera; Renderable *ri; @@ -29,11 +32,10 @@ namespace hgl virtual const uint32 GetUBOBytes()const{return sizeof(MVPMatrix);} };//struct RenderNode - using RenderNodeList=List; + using RenderNode3DList=List; }//namespace graph }//namespace hgl -using RenderNodePointer=hgl::graph::RenderNode *; -using RenderNodeComparator=Comparator; - +using RenderNode3DPointer=hgl::graph::RenderNode3D *; +using RenderNode3DComparator=Comparator; #endif//HGL_GRAPH_RENDER_NODE_INCLUDE diff --git a/inc/hgl/graph/RenderNode2D.h b/inc/hgl/graph/RenderNode2D.h new file mode 100644 index 00000000..40efcee2 --- /dev/null +++ b/inc/hgl/graph/RenderNode2D.h @@ -0,0 +1,38 @@ +#ifndef HGL_GRAPH_RENDER_NODE_2D_INCLUDE +#define HGL_GRAPH_RENDER_NODE_2D_INCLUDE + +#include +#include +#include +namespace hgl +{ + namespace graph + { + class Renderable; + + struct Transiton2D + { + Vector2f move; + Vector2f center; //中心点 + + //下方的不管是缩放还是旋转,均以上面的center为中心变换 + + Vector2f scale; + float rotate; + float z; + }; + + struct RenderNode2D + { + Transiton2D trans; + + Renderable *ri; + }; + + using RenderNode2DList=List; + }//namespace graph +}//namespace hgl + +using RenderNode2DPointer=hgl::graph::RenderNode2D *; +using RenderNode2DComparator=Comparator; +#endif//HGL_GRAPH_RENDER_NODE_2D_INCLUDE diff --git a/inc/hgl/graph/VKMaterialParameters.h b/inc/hgl/graph/VKMaterialParameters.h index c3e754f9..23002f31 100644 --- a/inc/hgl/graph/VKMaterialParameters.h +++ b/inc/hgl/graph/VKMaterialParameters.h @@ -32,11 +32,9 @@ public: const uint32_t GetDescriptorCount ()const{return desc_manager->GetBindCount(set_type);} ///<获取总共需要绑定的描述符数量 - const uint32_t GetDynamicCount ()const + const uint32_t GetDynamicCount ()const //返回动态ubo/ssbo总量 { - //返回动态ubo/ssbo总量 - //考虑将 } const uint32_t GetBoundCount ()const{return descriptor_set->GetCount();} ///<获取已经绑好的数量 diff --git a/src/SceneGraph/CMakeLists.txt b/src/SceneGraph/CMakeLists.txt index bca7eabc..cb4e35f6 100644 --- a/src/SceneGraph/CMakeLists.txt +++ b/src/SceneGraph/CMakeLists.txt @@ -18,32 +18,36 @@ SET(TILE_SOURCE ${SG_INCLUDE_PATH}/TileData.h SOURCE_GROUP("Tile" FILES ${TILE_SOURCE}) -SET(SCENE_GRAPH_HEADER ${SG_INCLUDE_PATH}/Light.h - ${SG_INCLUDE_PATH}/SceneInfo.h +SET(GEOMETRY_FILES ${SG_INCLUDE_PATH}/InlineGeometry.h + #${SG_INCLUDE_PATH}/Mesh.h + #${SG_INCLUDE_PATH}/Spline.h + InlineGeometry.cpp + #Mesh.cpp + ${SG_INCLUDE_PATH}/PrimitiveCreater.h + PrimitiveCreater.cpp +) + +SOURCE_GROUP("Geometry" FILES ${GEOMETRY_FILES}) + +SET(LIGHT_FILES ${SG_INCLUDE_PATH}/Light.h) + +source_group("Light" FILES ${LIGHT_FILES}) + +SET(SCENE_GRAPH_HEADER ${SG_INCLUDE_PATH}/SceneInfo.h ${SG_INCLUDE_PATH}/SceneNode.h ${SG_INCLUDE_PATH}/RenderNode.h ${SG_INCLUDE_PATH}/SceneOrient.h ${SG_INCLUDE_PATH}/RenderList.h - ${SG_INCLUDE_PATH}/InlineGeometry.h - #${SG_INCLUDE_PATH}/Mesh.h - #${SG_INCLUDE_PATH}/Material.h - #${SG_INCLUDE_PATH}/Spline.h + ${SG_INCLUDE_PATH}/RenderList2D.h ) SET(SCENE_GRAPH_SOURCE RenderList.cpp + RenderList2D.cpp + RenderList3D.cpp SceneNode.cpp - SceneOrient.cpp - InlineGeometry.cpp - #InlinePipeline.cpp - #Material.cpp - #Mesh.cpp - #SceneFile.cpp - ) + SceneOrient.cpp) -SET(PRIMITIVE_CREATER_FILES ${SG_INCLUDE_PATH}/PrimitiveCreater.h - PrimitiveCreater.cpp) - -SOURCE_GROUP("PrimitiveCreater" FILES ${PRIMITIVE_CREATER_FILES}) +SOURCE_GROUP("Scene Graph" FILES ${SCENE_GRAPH_HEADER} ${SCENE_GRAPH_SOURCE}) SET(FONT_MANAGE_SOURCE ${SG_INCLUDE_PATH}/font/Font.h ${SG_INCLUDE_PATH}/font/FontManage.h @@ -79,9 +83,6 @@ IF(WIN32) SOURCE_GROUP("Font\\Source\\Windows" FILES ${FONT_SOURCE_OS}) ENDIF(WIN32) -SOURCE_GROUP("Header Files" FILES ${SCENE_GRAPH_HEADER}) -SOURCE_GROUP("Source Files" FILES ${SCENE_GRAPH_SOURCE}) - SET(VK_RR_SOURCE ${SG_INCLUDE_PATH}/VKRenderResource.h ${SG_INCLUDE_PATH}/VKRenderablePrimitiveCreater.h Vulkan/VKRenderResource.cpp @@ -263,13 +264,13 @@ SET(VULKAN_RENDER_SOURCE ${VK_RR_SOURCE} add_cm_library(ULRE.SceneGraph "ULRE" ${SCENE_GRAPH_HEADER} ${SCENE_GRAPH_SOURCE} + ${GEOMETRY_FILES} + ${LIGHT_FILES} ${SG_TEXTURE_SOURCE} ${TILE_SOURCE} ${SG_VAD_SOURCE} - ${PRIMITIVE_CREATER_FILES} - ${FONT_MANAGE_SOURCE} ${FONT_SOURCE} ${FONT_SOURCE_OS} diff --git a/src/SceneGraph/RenderList.cpp b/src/SceneGraph/RenderList.cpp index 6d1953cb..45d69787 100644 --- a/src/SceneGraph/RenderList.cpp +++ b/src/SceneGraph/RenderList.cpp @@ -19,7 +19,7 @@ */ template<> -int Comparator::compare(const RenderNodePointer &obj_one,const RenderNodePointer &obj_two) const +int Comparator::compare(const RenderNode3DPointer &obj_one,const RenderNode3DPointer &obj_two) const { int off; @@ -91,7 +91,7 @@ namespace hgl RenderList::~RenderList() { - } + } bool RenderList::Begin() { diff --git a/src/SceneGraph/RenderList2D.cpp b/src/SceneGraph/RenderList2D.cpp new file mode 100644 index 00000000..45d69787 --- /dev/null +++ b/src/SceneGraph/RenderList2D.cpp @@ -0,0 +1,297 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** +* 理论上讲,我们需要按以下顺序排序 +* +* for(pipeline) +* for(material_instance) +* for(vbo) +* for(distance) +*/ + +template<> +int Comparator::compare(const RenderNode3DPointer &obj_one,const RenderNode3DPointer &obj_two) const +{ + int off; + + hgl::graph::Renderable *ri_one=obj_one->ri; + hgl::graph::Renderable *ri_two=obj_two->ri; + + //比较管线 + { + off=ri_one->GetPipeline() + -ri_two->GetPipeline(); + + if(off) + return off; + } + + //比较材质实例 + { + for(int i =(int)hgl::graph::DescriptorSetType::BEGIN_RANGE; + i<=(int)hgl::graph::DescriptorSetType::END_RANGE; + i++) + { + off=ri_one->GetMP((hgl::graph::DescriptorSetType)i) + -ri_two->GetMP((hgl::graph::DescriptorSetType)i); + + if(off) + return off; + } + } + + //比较vbo+ebo + { + off=ri_one->GetBufferHash() + -ri_two->GetBufferHash(); + + if(off) + return off; + } + + //比较距离 + { + const double dist=obj_one->distance_to_camera_square- + obj_two->distance_to_camera_square; + + //由于距离差距可能会小于1,但又返回int,所以需要做如此处理 + + if(dist>0)return 1;else + if(dist<0)return -1; + } + + return 0; +} + +namespace hgl +{ + namespace graph + { + RenderList::RenderList(GPUDevice *dev) + { + device =dev; + cmd_buf =nullptr; + + ubo_offset =0; + ubo_align =0; + + last_pipeline =nullptr; + hgl_zero(last_mp); + last_vbo =0; + } + + RenderList::~RenderList() + { + } + + bool RenderList::Begin() + { + render_node_list.ClearData(); + ri_list.ClearData(); + + material_sets.ClearData(); + + return(true); + } + + void RenderList::End() + { + if(render_node_list.GetCount()<=0)return; + + //排序 + Sort(render_node_list,&render_node_comparator); + + //产生MVP矩阵UBO数据 + { + const uint32_t count=render_node_list.GetCount(); + + { + //按当前总节点数量分配UBO + mvp_array->Alloc(count); + mvp_array->Clear(); + + ri_list.ClearData(); + ri_list.SetCount(count); + } + + { + ubo_align=mvp_array->GetUnitSize(); + + char *mp=(char *)(mvp_array->Map(0,count)); + Renderable **ri=ri_list.GetData(); + + for(RenderNode *node:render_node_list) //未来可能要在Expend处考虑做去重 + { + memcpy(mp,&(node->matrix),MVPMatrixBytes); + mp+=ubo_align; + + (*ri)=node->ri; + ++ri; + } + + mvp_array->Flush(count); + } + } + + //为所有的材质绑定 + for(Material *mtl:material_sets) + { + MaterialParameters *mp=mtl->GetMP(DescriptorSetType::PerObject); + + if(mp) + { + if(mp->BindUBO("r_scene_info",mvp_array->GetBuffer(),true)) + mp->Update(); + } + } + } + + bool RenderList::Expend(SceneNode *sn) + { + if(!sn)return(false); + + Renderable *ri=sn->GetRenderable(); + + if(ri) + { + RenderNode *rn=new RenderNode; + + rn->matrix.Set(sn->GetLocalToWorldMatrix(),camera_info.vp,camera_info.view); + + rn->WorldCenter=sn->GetWorldCenter(); + + rn->distance_to_camera_square=length_squared(rn->WorldCenter,camera_info.pos); +// rn->distance_to_camera=sqrtf(rn->distance_to_camera_square); + + rn->ri=ri; + + render_node_list.Add(rn); + + material_sets.Add(ri->GetMaterial()); + } + + for(SceneNode *sub:sn->SubNode) + Expend(sub); + + return(true); + } + + bool RenderList::Expend(const CameraInfo &ci,SceneNode *sn) + { + if(!device|!sn)return(false); + + camera_info=ci; + + Begin(); + Expend(sn); + End(); + + return(true); + } + + void RenderList::Render(Renderable *ri) + { + if(last_pipeline!=ri->GetPipeline()) + { + last_pipeline=ri->GetPipeline(); + + cmd_buf->BindPipeline(last_pipeline); + } + + { + uint32_t ds_count=0; + uint32_t first_set=0; + MaterialParameters *mp; + + ENUM_CLASS_FOR(DescriptorSetType,int,i) + { + if(i==(int)DescriptorSetType::PerObject)continue; + + mp=ri->GetMP((DescriptorSetType)i); + + if(last_mp[i]!=mp) + { + last_mp[i]=mp; + + if(mp) + { + ds_list[ds_count]=mp->GetVkDescriptorSet(); + ++ds_count; + } + } + else + { + if(mp) + ++first_set; + } + } + + { + mp=ri->GetMP(DescriptorSetType::PerObject); + + if(mp) + { + ds_list[ds_count]=mp->GetVkDescriptorSet(); + ++ds_count; + + cmd_buf->BindDescriptorSets(ri->GetPipelineLayout(),first_set,ds_list,ds_count,&ubo_offset,1); + } + else + { + cmd_buf->BindDescriptorSets(ri->GetPipelineLayout(),first_set,ds_list,ds_count,nullptr,0); + } + + ubo_offset+=ubo_align; + } + } + + if(last_vbo!=ri->GetBufferHash()) + { + last_vbo=ri->GetBufferHash(); + + cmd_buf->BindVBO(ri); + } + + const IndexBuffer *ib=ri->GetIndexBuffer(); + + if(ib) + { + cmd_buf->DrawIndexed(ib->GetCount()); + } + else + { + cmd_buf->Draw(ri->GetDrawCount()); + } + } + + bool RenderList::Render(RenderCmdBuffer *cb) + { + if(!cb) + return(false); + + if(ri_list.GetCount()<=0) + return(true); + + cmd_buf=cb; + + last_pipeline=nullptr; + hgl_zero(last_mp); + last_vbo=0; + ubo_offset=0; + + for(Renderable *ri:ri_list) + Render(ri); + + return(true); + } + }//namespace graph +}//namespace hgl diff --git a/src/SceneGraph/Vulkan/VKRenderResourceMaterial.cpp b/src/SceneGraph/Vulkan/VKRenderResourceMaterial.cpp index 9574ca58..09f5bb6c 100644 --- a/src/SceneGraph/Vulkan/VKRenderResourceMaterial.cpp +++ b/src/SceneGraph/Vulkan/VKRenderResourceMaterial.cpp @@ -69,7 +69,7 @@ void LoadShaderDescriptor(io::ConstBufferReader &cbr,ShaderDescriptor *sd_list,c cbr.Read(sd->binding); cbr.Read(sd->stage_flag); - if(sd->set_type==DescriptorSetType::PerObject) + if(sd->set_type>=DescriptorSetType::PerObject) { if(sd->desc_type==VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)sd->desc_type=VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;else if(sd->desc_type==VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)sd->desc_type=VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;