From f9675fc1e58eb388c17c68d65a239188065ce285 Mon Sep 17 00:00:00 2001 From: hyzboy Date: Sat, 14 Jun 2025 21:05:36 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=81=E7=A7=BB=E5=88=B0StaticMeshComponent?= =?UTF-8?q?=E6=B8=B2=E6=9F=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example/Basic/draw_triangle_use_UBO.cpp | 16 +++- inc/hgl/component/Component.h | 2 +- inc/hgl/component/PrimitiveComponent.h | 6 +- inc/hgl/component/RenderComponent.h | 6 +- inc/hgl/component/SceneComponent.h | 20 +++++ inc/hgl/component/StaticMeshComponent.h | 6 +- inc/hgl/graph/MaterialRenderList.h | 4 +- inc/hgl/graph/RenderList.h | 2 +- inc/hgl/graph/RenderNode.h | 9 ++- inc/hgl/graph/SceneNode.h | 33 +++++--- src/SceneGraph/CMakeLists.txt | 4 +- src/SceneGraph/render/MaterialRenderList.cpp | 84 ++++---------------- src/SceneGraph/render/RenderAssignBuffer.cpp | 11 +-- src/SceneGraph/render/RenderList.cpp | 26 +++--- src/SceneGraph/scene/SceneNode.cpp | 52 ++++++------ 15 files changed, 140 insertions(+), 141 deletions(-) create mode 100644 inc/hgl/component/SceneComponent.h diff --git a/example/Basic/draw_triangle_use_UBO.cpp b/example/Basic/draw_triangle_use_UBO.cpp index a104832b..d51113cc 100644 --- a/example/Basic/draw_triangle_use_UBO.cpp +++ b/example/Basic/draw_triangle_use_UBO.cpp @@ -89,13 +89,22 @@ private: {VAN::Color, COLOR_DATA_FORMAT, color_data} }); + return(mesh_triangle); + } + + bool InitScene() + { + if(!mesh_triangle) + return(false); + SceneNode *scene_root=GetSceneRoot(); ///<取得场景根节点 sm_component=CreateComponent(scene_root,mesh_triangle); //创建一个静态网格组件 - scene_root->Add(new SceneNode(mesh_triangle)); + if(!sm_component) + return(false); - return(mesh_triangle); + return(true); } public: @@ -115,6 +124,9 @@ public: if(!InitVBO()) return(false); + if(!InitScene()) + return(false); + return(true); } };//class TestApp:public WorkObject diff --git a/inc/hgl/component/Component.h b/inc/hgl/component/Component.h index e86ddb38..74473062 100644 --- a/inc/hgl/component/Component.h +++ b/inc/hgl/component/Component.h @@ -82,7 +82,7 @@ public: public: //事件 virtual void OnAttach(SceneNode *node){if(node)OwnerNode=node;} ///<附加到节点事件 - virtual void OnDetach(){OwnerNode=nullptr;} ///<从节点分离事件 + virtual void OnDetach(SceneNode *node){OwnerNode=nullptr;} ///<从节点分离事件 virtual void OnFocusLost(){} ///<焦点丢失事件 virtual void OnFocusGained(){} ///<焦点获得事件 diff --git a/inc/hgl/component/PrimitiveComponent.h b/inc/hgl/component/PrimitiveComponent.h index fd42f0dd..38452530 100644 --- a/inc/hgl/component/PrimitiveComponent.h +++ b/inc/hgl/component/PrimitiveComponent.h @@ -1,6 +1,6 @@ #pragma once -#include +#include COMPONENT_NAMESPACE_BEGIN @@ -8,11 +8,11 @@ COMPONENT_NAMESPACE_BEGIN * 图元组件
* 组件中的元素必须是一个可以明确描述的几何体,可以被明确标记尺寸、参与空间、物理计算等。 */ -class PrimitiveComponent:public RenderComponent +class PrimitiveComponent:public SceneComponent { public: - using RenderComponent::RenderComponent; + using SceneComponent::SceneComponent; virtual ~PrimitiveComponent()=default; };//class PrimitiveComponent diff --git a/inc/hgl/component/RenderComponent.h b/inc/hgl/component/RenderComponent.h index a94d6380..c8936e86 100644 --- a/inc/hgl/component/RenderComponent.h +++ b/inc/hgl/component/RenderComponent.h @@ -1,17 +1,17 @@ #pragma once -#include +#include COMPONENT_NAMESPACE_BEGIN /** * 可渲染组件 */ -class RenderComponent: public Component +class RenderComponent:public PrimitiveComponent { public: - using Component::Component; + using PrimitiveComponent::PrimitiveComponent; virtual ~RenderComponent()=default; };//class RenderComponent diff --git a/inc/hgl/component/SceneComponent.h b/inc/hgl/component/SceneComponent.h new file mode 100644 index 00000000..86726fff --- /dev/null +++ b/inc/hgl/component/SceneComponent.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +COMPONENT_NAMESPACE_BEGIN + +/** +* 场景组件
+* 场景组件中的元素必须是针对场景起作用的,并不一定需要自己绘出来,但也对场景产生影响。比如太阳光、全局风场 +*/ +class SceneComponent:public Component +{ +public: + + using Component::Component; + + virtual ~SceneComponent()=default; +};//class SceneComponent + +COMPONENT_NAMESPACE_END diff --git a/inc/hgl/component/StaticMeshComponent.h b/inc/hgl/component/StaticMeshComponent.h index 30c70bf0..f480bb8b 100644 --- a/inc/hgl/component/StaticMeshComponent.h +++ b/inc/hgl/component/StaticMeshComponent.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include COMPONENT_NAMESPACE_BEGIN @@ -57,14 +57,14 @@ public: virtual Component *CreateComponent(ComponentData *data) override; };//class StaticMeshComponentManager -class StaticMeshComponent:public PrimitiveComponent +class StaticMeshComponent:public RenderComponent { StaticMeshComponentData *sm_data; public: StaticMeshComponent(StaticMeshComponentData *cd,StaticMeshComponentManager *cm) - :PrimitiveComponent(cd,cm) + :RenderComponent(cd,cm) { sm_data=cd; } diff --git a/inc/hgl/graph/MaterialRenderList.h b/inc/hgl/graph/MaterialRenderList.h index 9214e27a..8abe9d3c 100644 --- a/inc/hgl/graph/MaterialRenderList.h +++ b/inc/hgl/graph/MaterialRenderList.h @@ -109,7 +109,7 @@ public: MaterialRenderList(VulkanDevice *d,bool l2w,const RenderPipelineIndex &rpi); ~MaterialRenderList(); - void Add(SceneNode *); + void Add(StaticMeshComponent *); void SetCameraInfo(CameraInfo *ci){camera_info=ci;} @@ -120,6 +120,6 @@ public: void Render(RenderCmdBuffer *); void UpdateLocalToWorld(); //刷新所有对象的LocalToWorld矩阵 - void UpdateMaterialInstance(SceneNode *); + void UpdateMaterialInstance(StaticMeshComponent *); };//class MaterialRenderList VK_NAMESPACE_END diff --git a/inc/hgl/graph/RenderList.h b/inc/hgl/graph/RenderList.h index fc4157ff..8a31121c 100644 --- a/inc/hgl/graph/RenderList.h +++ b/inc/hgl/graph/RenderList.h @@ -46,7 +46,7 @@ namespace hgl virtual bool Render(RenderCmdBuffer *); ///<渲染所有对象 virtual void UpdateLocalToWorld(); ///<更新所有对象的变换数据 - virtual void UpdateMaterialInstance(SceneNode *); ///<有对象互换了材质实例 + virtual void UpdateMaterialInstance(StaticMeshComponent *); ///<有对象互换了材质实例 virtual void Clear(); ///<彻底清理 };//class RenderList diff --git a/inc/hgl/graph/RenderNode.h b/inc/hgl/graph/RenderNode.h index 697aa50c..e6a887b3 100644 --- a/inc/hgl/graph/RenderNode.h +++ b/inc/hgl/graph/RenderNode.h @@ -9,13 +9,13 @@ namespace hgl { class Mesh; class MaterialInstance; - class SceneNode; + class StaticMeshComponent; struct RenderNode:public Comparator { uint index; ///<在MaterialRenderList中的索引 - SceneNode * scene_node; + StaticMeshComponent *sm_component; ///<静态网格组件 uint32 l2w_version; uint32 l2w_index; @@ -27,6 +27,11 @@ namespace hgl //该函数位于MaterialRenderList.cpp const int compare(const RenderNode &)const override; + + public: + + Mesh *GetMesh()const; + MaterialInstance *GetMaterialInstance()const; }; using RenderNodeList=ArrayList; diff --git a/inc/hgl/graph/SceneNode.h b/inc/hgl/graph/SceneNode.h index 9fc6fd6d..551cba06 100644 --- a/inc/hgl/graph/SceneNode.h +++ b/inc/hgl/graph/SceneNode.h @@ -30,8 +30,6 @@ namespace hgl::graph AABB LocalBoundingBox; ///<本地坐标绑定盒 //AABB WorldBoundingBox; ///<世界坐标绑定盒 - Mesh *render_obj=nullptr; ///<可渲染实例 - protected: ObjectList ChildNode; ///<子节点 @@ -55,9 +53,7 @@ namespace hgl::graph SceneNode(const SceneNode &)=delete; SceneNode(const SceneNode *)=delete; SceneNode(const SceneOrient &so ):SceneOrient(so) {} - SceneNode( Mesh *ri ) {render_obj=ri;} SceneNode(const Matrix4f &mat ):SceneOrient(mat) {} - SceneNode(const Matrix4f &mat, Mesh *ri ):SceneOrient(mat) {render_obj=ri;} public: @@ -74,12 +70,10 @@ namespace hgl::graph ChildNode.Clear(); ComponentSet.Clear(); - render_obj=nullptr; } const bool ChildNodeIsEmpty()const { - if(render_obj)return(false); if(ChildNode.GetCount())return(false); return(true); @@ -89,10 +83,6 @@ namespace hgl::graph SceneNode * GetParent() noexcept{return ParentNode;} const SceneNode * GetParent()const noexcept{return ParentNode;} - void SetRenderable(Mesh *); - Mesh * GetRenderable() noexcept{return render_obj;} - const Mesh * GetRenderable()const noexcept{return render_obj;} - SceneNode *Add(SceneNode *sn) { if(!sn) @@ -118,13 +108,32 @@ namespace hgl::graph bool ComponentIsEmpty ()const{return ComponentSet.GetCount()==0;} ///<是否没有组件 virtual int GetComponentCount ()const{return ComponentSet.GetCount();} ///<取得组件数量 - virtual void AttachComponent (Component *comp){ComponentSet.Add(comp);} ///<添加一个组件 - virtual void DetachComponent (Component *comp){ComponentSet.Delete(comp);} ///<删除一个组件 + virtual bool AttachComponent (Component *comp) ///<添加一个组件 + { + if(!comp)return(false); + + if(ComponentSet.Add(comp)<0) + return(false); + + comp->OnAttach(this); //调用组件的OnAttach方法 + return(true); + } + + virtual void DetachComponent (Component *comp) ///<删除一个组件 + { + if (!comp)return; + + ComponentSet.Delete(comp); + + comp->OnDetach(this); //调用组件的OnDetach方法 + } + bool Contains (Component *comp){return ComponentSet.Contains(comp);} ///<是否包含指定组件 bool HasComponent (const ComponentManager *); ///<是否有指定组件管理器的组件 virtual int GetComponents (ArrayList &comp_list,const ComponentManager *); ///<取得所有组件 + const SortedSet & GetComponents ()const{return ComponentSet;} };//class SceneNode SceneNode *Duplication(SceneNode *); ///<复制一个场景节点 diff --git a/src/SceneGraph/CMakeLists.txt b/src/SceneGraph/CMakeLists.txt index 196a780a..472c1ca8 100644 --- a/src/SceneGraph/CMakeLists.txt +++ b/src/SceneGraph/CMakeLists.txt @@ -91,6 +91,7 @@ SET(SG_RENDER_SOURCE ${SG_INCLUDE_PATH}/RenderNode.h ${SG_INCLUDE_PATH}/RenderTask.h ${SG_INCLUDE_PATH}/Renderer.h render/Renderer.cpp + render/RenderNode.cpp render/RenderTask.cpp render/RenderList.cpp render/MaterialRenderList.cpp @@ -297,8 +298,9 @@ SOURCE_GROUP("Vulkan\\Mesh" FILES ${VK_MESH_SOURCE}) set(COMPONENT_INCLUDE_PATH ${ROOT_INCLUDE_PATH}/hgl/component) SET(COMPONENT_FILES ${COMPONENT_INCLUDE_PATH}/Component.h - ${COMPONENT_INCLUDE_PATH}/RenderComponent.h + ${COMPONENT_INCLUDE_PATH}/SceneComponent.h ${COMPONENT_INCLUDE_PATH}/PrimitiveComponent.h + ${COMPONENT_INCLUDE_PATH}/RenderComponent.h ${COMPONENT_INCLUDE_PATH}/StaticMeshComponent.h component/Component.cpp component/ComponentManager.cpp diff --git a/src/SceneGraph/render/MaterialRenderList.cpp b/src/SceneGraph/render/MaterialRenderList.cpp index 7efa081e..e97d7eb4 100644 --- a/src/SceneGraph/render/MaterialRenderList.cpp +++ b/src/SceneGraph/render/MaterialRenderList.cpp @@ -6,72 +6,11 @@ #include #include #include"RenderAssignBuffer.h" -#include #include #include - -/** -* -* 理论上讲,我们需要按以下顺序排序 -* -* for(material) -* for(pipeline) -* for(material_instance) -* for(vab) -* -* -* 关于Indirect Command Buffer - - 建立一个大的IndirectCommandBuffer,用于存放所有的渲染指令,包括那些不能使用Indirect渲染的。 - 这样就可以保证所有的渲染操作就算要切VBO,也不需要切换INDIRECT缓冲区,定位指令也很方便。 -*/ +#include VK_NAMESPACE_BEGIN -const int RenderNode::compare(const RenderNode &other)const -{ - hgl::int64 off; - - hgl::graph::Mesh *ri_one=other.scene_node->GetRenderable(); - hgl::graph::Mesh *ri_two=scene_node->GetRenderable(); - - auto *prim_one=ri_one->GetPrimitive(); - auto *prim_two=ri_two->GetPrimitive(); - - //比较VDM - - if(prim_one->GetVDM()) //有VDM - { - off=prim_one->GetVDM() - -prim_two->GetVDM(); - - if(off) - return off; - - //比较模型 - { - off=prim_one - -prim_two; - - if(off) - { - off=prim_one->GetVertexOffset()-prim_two->GetVertexOffset(); //保证vertex offset小的在前面 - - return off; - } - } - } - - //比较距离。。。。。。。。。。。。。。。。。。。。。还不知道这个是正了还是反了,等测出来确认后修改下面的返回值和这里的注释 - - float foff=other.to_camera_distance - -to_camera_distance; - - if(foff>0) - return 1; - else - return -1; -} - MaterialRenderList::MaterialRenderList(VulkanDevice *d,bool l2w,const RenderPipelineIndex &rpi) { device=d; @@ -106,13 +45,18 @@ MaterialRenderList::~MaterialRenderList() SAFE_CLEAR(assign_buffer); } -void MaterialRenderList::Add(SceneNode *sn) +void MaterialRenderList::Add(StaticMeshComponent *smc) { + if(!smc) + return; + RenderNode rn; rn.index =rn_list.GetCount(); - rn.scene_node =sn; + rn.sm_component =smc; + + SceneNode *sn=smc->GetOwnerNode(); //目前先这样处理,未来改成每个Component有自己的再一次的变换矩阵 rn.l2w_version =sn->GetLocalToWorldMatrixVersion(); rn.l2w_index =0; @@ -160,7 +104,7 @@ void MaterialRenderList::UpdateLocalToWorld() for(int i=0;iscene_node->GetLocalToWorldMatrixVersion(); + l2w_version=rn->sm_component->GetOwnerNode()->GetLocalToWorldMatrixVersion(); if(rn->l2w_version!=l2w_version) //版本不对,需要更新 { @@ -188,9 +132,9 @@ void MaterialRenderList::UpdateLocalToWorld() } } -void MaterialRenderList::UpdateMaterialInstance(SceneNode *sn) +void MaterialRenderList::UpdateMaterialInstance(StaticMeshComponent *smc) { - if(!sn)return; + if(!smc)return; if(!assign_buffer) return; @@ -202,7 +146,7 @@ void MaterialRenderList::UpdateMaterialInstance(SceneNode *sn) for(int i=0;iscene_node==sn) + if(rn->sm_component==smc) { assign_buffer->UpdateMaterialInstance(rn); return; @@ -270,7 +214,7 @@ void MaterialRenderList::Stat() ri_array.Alloc(count); RenderItem *ri=ri_array.GetData(); - Mesh *ro=rn->scene_node->GetRenderable(); + Mesh *ro=rn->sm_component->GetMesh(); ri_count=1; @@ -286,7 +230,7 @@ void MaterialRenderList::Stat() for(uint i=1;iscene_node->GetRenderable(); + ro=rn->sm_component->GetMesh(); if(*last_data_buffer==*ro->GetDataBuffer()) if(*last_render_data==*ro->GetRenderData()) diff --git a/src/SceneGraph/render/RenderAssignBuffer.cpp b/src/SceneGraph/render/RenderAssignBuffer.cpp index db0ab370..e1392715 100644 --- a/src/SceneGraph/render/RenderAssignBuffer.cpp +++ b/src/SceneGraph/render/RenderAssignBuffer.cpp @@ -7,6 +7,7 @@ #include #include #include +#include VK_NAMESPACE_BEGIN RenderAssignBuffer::RenderAssignBuffer(VulkanDevice *dev,Material *mtl) @@ -73,7 +74,7 @@ void RenderAssignBuffer::StatL2W(const RenderNodeList &rn_list) for(int i=0;iscene_node->GetLocalToWorldMatrix(); + *l2wp=rn->sm_component->GetOwnerNode()->GetLocalToWorldMatrix(); ++l2wp; ++rn; } @@ -97,7 +98,7 @@ void RenderAssignBuffer::UpdateLocalToWorld(const RenderNodePointerList &rnp_lis for(uint i=0;il2w_index-first]=(*rn)->scene_node->GetLocalToWorldMatrix(); + l2wp[(*rn)->l2w_index-first]=(*rn)->sm_component->GetOwnerNode()->GetLocalToWorldMatrix(); ++rn; } @@ -112,7 +113,7 @@ void RenderAssignBuffer::UpdateMaterialInstance(const RenderNode *rn) AssignData *adp=(AssignData *)(assign_vab->DeviceBuffer::Map(sizeof(AssignData)*rn->index,sizeof(AssignData))); - adp->mi=mi_set.Find(rn->scene_node->GetRenderable()->GetMaterialInstance()); + adp->mi=mi_set.Find(rn->sm_component->GetMesh()->GetMaterialInstance()); assign_vab->Unmap(); } @@ -152,7 +153,7 @@ void RenderAssignBuffer::StatMI(const RenderNodeList &rn_list) mi_set.PreAlloc(rn_list.GetCount()); for(RenderNode &rn:rn_list) - mi_set.Add(rn.scene_node->GetRenderable()->GetMaterialInstance()); + mi_set.Add(rn.sm_component->GetMesh()->GetMaterialInstance()); if(mi_set.GetCount()>material->GetMIMaxCount()) { @@ -220,7 +221,7 @@ void RenderAssignBuffer::WriteNode(const RenderNodeList &rn_list) rn->l2w_index=i; adp->l2w=i; - adp->mi=mi_set.Find(rn->scene_node->GetRenderable()->GetMaterialInstance()); + adp->mi=mi_set.Find(rn->sm_component->GetMesh()->GetMaterialInstance()); ++adp; ++rn; diff --git a/src/SceneGraph/render/RenderList.cpp b/src/SceneGraph/render/RenderList.cpp index 39cdc370..a9b7a92e 100644 --- a/src/SceneGraph/render/RenderList.cpp +++ b/src/SceneGraph/render/RenderList.cpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace hgl { @@ -22,11 +23,16 @@ namespace hgl { if(!sn)return(false); - Mesh *ri=sn->GetRenderable(); - - if(ri) + for(auto component:sn->GetComponents()) { - RenderPipelineIndex rpi(ri->GetMaterial(),ri->GetPipeline()); + if(component->GetHashCode()!=StaticMeshComponent::StaticHashCode()) //暂时只支持StaticMeshComponent + continue; + + StaticMeshComponent *smc=reinterpret_cast(component); + + Mesh *mesh=smc->GetMesh(); + + RenderPipelineIndex rpi(mesh->GetMaterial(),mesh->GetPipeline()); MaterialRenderList *mrl; @@ -36,8 +42,8 @@ namespace hgl mrl_map.Add(rpi,mrl); } - - mrl->Add(sn); + + mrl->Add(smc); ++renderable_count; } @@ -85,11 +91,11 @@ namespace hgl mrl_map.UpdateLocalToWorld(); } - void RenderList::UpdateMaterialInstance(SceneNode *sn) + void RenderList::UpdateMaterialInstance(StaticMeshComponent *smc) { - if(!sn)return; + if(!smc)return; - Mesh *ri=sn->GetRenderable(); + Mesh *ri=smc->GetMesh(); if(!ri)return; @@ -99,7 +105,7 @@ namespace hgl if(!mrl_map.Get(rli,mrl)) //找到对应的 return; - mrl->UpdateMaterialInstance(sn); + mrl->UpdateMaterialInstance(smc); } }//namespace graph }//namespace hgl diff --git a/src/SceneGraph/scene/SceneNode.cpp b/src/SceneGraph/scene/SceneNode.cpp index 613252d6..2f4c8191 100644 --- a/src/SceneGraph/scene/SceneNode.cpp +++ b/src/SceneGraph/scene/SceneNode.cpp @@ -3,39 +3,39 @@ namespace hgl::graph { - SceneNode *Duplication(SceneNode *src_node) - { - if(!src_node) - return nullptr; + //SceneNode *Duplication(SceneNode *src_node) + //{ + // if(!src_node) + // return nullptr; - SceneNode *node=new SceneNode(*(SceneOrient *)src_node); + // SceneNode *node=new SceneNode(*(SceneOrient *)src_node); - node->SetRenderable(src_node->GetRenderable()); + // node->SetRenderable(src_node->GetRenderable()); - for(SceneNode *sn:src_node->GetChildNode()) - { - node->Add(Duplication(sn)); - } + // for(SceneNode *sn:src_node->GetChildNode()) + // { + // node->Add(Duplication(sn)); + // } - return node; - } + // return node; + //} - void SceneNode::SetRenderable(Mesh *ri) - { - render_obj=ri; + //void SceneNode::SetRenderable(Mesh *ri) + //{ + // render_obj=ri; - if(render_obj) - { - SetBoundingBox(render_obj->GetBoundingBox()); - } - else - { - BoundingBox.SetZero(); + // if(render_obj) + // { + // SetBoundingBox(render_obj->GetBoundingBox()); + // } + // else + // { + // BoundingBox.SetZero(); - //WorldBoundingBox= - LocalBoundingBox=BoundingBox; - } - } + // //WorldBoundingBox= + // LocalBoundingBox=BoundingBox; + // } + //} /** * 刷新矩阵变换