diff --git a/CMSceneGraph b/CMSceneGraph index 5009069a..74e33b49 160000 --- a/CMSceneGraph +++ b/CMSceneGraph @@ -1 +1 @@ -Subproject commit 5009069a3081d458f41f21f30236e3afebf1fd8a +Subproject commit 74e33b497274e51c35a5ee19a274b12dc86deecb diff --git a/example/Basic/auto_instance.cpp b/example/Basic/auto_instance.cpp index 87c40c9f..b5e4a841 100644 --- a/example/Basic/auto_instance.cpp +++ b/example/Basic/auto_instance.cpp @@ -5,6 +5,7 @@ #include #include #include +#include using namespace hgl; using namespace hgl::graph; @@ -79,10 +80,10 @@ private: for(uint i=0;i((360.0f/double(TRIANGLE_NUMBER))*i); //这里一定要加,否则结果用int保存会出现问题 + rad=deg2rad((360.0f/double(TRIANGLE_NUMBER))*i); //这里一定要加,否则结果用int保存会出现问题 mat=rotate(rad,Vector3f(0,0,1)); - scene_root->Add(new SceneNode(mat,render_obj)); + CreateComponent(mat,scene_root,render_obj); } return(true); diff --git a/inc/hgl/WorkObject.h b/inc/hgl/WorkObject.h index 5db86956..e11c5465 100644 --- a/inc/hgl/WorkObject.h +++ b/inc/hgl/WorkObject.h @@ -160,6 +160,30 @@ namespace hgl return c; } + + template + inline C *CreateComponent(const graph::Matrix4f &mat,graph::SceneNode *parent_node,ARGS...args) + { + if(!parent_node) + { + // LOG_ERROR(OS_TEXT("CreateComponent failed, parent node is null!")); + return(nullptr); + } + + C *c=this->CreateComponent(args...); //创建组件 + + if(!c) + { + // LOG_ERROR(OS_TEXT("CreateComponent failed, create component failed!")); + return(nullptr); + } + + parent_node->AttachComponent(c); //将组件附加到父节点 + + c->graph::SceneOrient::SetLocalMatrix(mat); + + return c; + } };//class WorkObject /** diff --git a/inc/hgl/component/Component.h b/inc/hgl/component/Component.h index 74473062..8102cbcf 100644 --- a/inc/hgl/component/Component.h +++ b/inc/hgl/component/Component.h @@ -23,14 +23,15 @@ * * Component是组件的基类,所有组件都从这里派生。 * -* -* RenderComponent是可渲染组件的基类,所有可渲染组件都从这里派生。它继承于Component。 -* -* PrimitiveComponent是图元组件的基类,所有图元组件都从这里派生。它继承于RenderComponent。 +* SceneComponent是场景组件基类,只要是放在场景中的都从它派生, +* +* PrimitiveComponent是图元组件的基类,所有图元组件都从这里派生。 * 它再度派生出的任何Component都必须是一个有3D空间的几何图元。 * 引擎中的空间、物理、等都由PrimitiveComponent提供数据进行计算。 + +* RenderComponent是可渲染组件的基类,所有可渲染组件都从这里派生。 * -* StaticMeshComponent是静态网格组件,它是一个具体的PrimitiveComponent实现。 +* StaticMeshComponent是静态网格组件,它是一个具体的RenderComponent实现。 * */ @@ -89,6 +90,7 @@ public: //事件 };//class Component using ComponentSet=SortedSet; +using ComponentList=ArrayList; class ComponentManager { diff --git a/inc/hgl/component/SceneComponent.h b/inc/hgl/component/SceneComponent.h index 86726fff..9628f82e 100644 --- a/inc/hgl/component/SceneComponent.h +++ b/inc/hgl/component/SceneComponent.h @@ -1,6 +1,7 @@ #pragma once #include +#include COMPONENT_NAMESPACE_BEGIN @@ -8,12 +9,11 @@ COMPONENT_NAMESPACE_BEGIN * 场景组件
* 场景组件中的元素必须是针对场景起作用的,并不一定需要自己绘出来,但也对场景产生影响。比如太阳光、全局风场 */ -class SceneComponent:public Component +class SceneComponent:public Component,public SceneOrient { public: using Component::Component; - virtual ~SceneComponent()=default; };//class SceneComponent diff --git a/inc/hgl/component/StaticMeshComponent.h b/inc/hgl/component/StaticMeshComponent.h index f480bb8b..ca3d43cf 100644 --- a/inc/hgl/component/StaticMeshComponent.h +++ b/inc/hgl/component/StaticMeshComponent.h @@ -63,11 +63,7 @@ class StaticMeshComponent:public RenderComponent public: - StaticMeshComponent(StaticMeshComponentData *cd,StaticMeshComponentManager *cm) - :RenderComponent(cd,cm) - { - sm_data=cd; - } + StaticMeshComponent(StaticMeshComponentData *cd,StaticMeshComponentManager *cm):RenderComponent(cd,cm){sm_data=cd;} virtual ~StaticMeshComponent()=default; diff --git a/inc/hgl/graph/SceneNode.h b/inc/hgl/graph/SceneNode.h index 551cba06..ac4d5881 100644 --- a/inc/hgl/graph/SceneNode.h +++ b/inc/hgl/graph/SceneNode.h @@ -19,33 +19,33 @@ namespace hgl::graph */ class SceneNode:public SceneOrient ///场景节点类 { - SceneNode *ParentNode=nullptr; ///<上级节点 + SceneNode *parent_node=nullptr; ///<上级节点 - SceneNodeID NodeID=-1; ///<节点ID - SceneNodeName NodeName; ///<节点名称 + SceneNodeID node_id=-1; ///<节点ID + SceneNodeName node_name; ///<节点名称 protected: - AABB BoundingBox; ///<绑定盒 - AABB LocalBoundingBox; ///<本地坐标绑定盒 + AABB bounding_box; ///<绑定盒 + AABB local_bounding_box; ///<本地坐标绑定盒 //AABB WorldBoundingBox; ///<世界坐标绑定盒 protected: - ObjectList ChildNode; ///<子节点 + ObjectList child_nodes; ///<子节点 /** * 组件合集,一个SceneNode下可能会包含多个组件,同时一个组件也可能被多个SceneNode使用。 * 所以这里只保留一个指针,不拥有组件的生命周期,组件的生命周期由其对应的ComponentManager管理。 */ - SortedSet ComponentSet; ///<组件合集 + ComponentSet component_set; ///<组件合集 public: - const SceneNodeID & GetNodeID ()const { return NodeID; } ///<取得节点ID - const SceneNodeName & GetNodeName ()const { return NodeName; } ///<取得节点名称 + const SceneNodeID & GetNodeID ()const { return node_id; } ///<取得节点ID + const SceneNodeName & GetNodeName ()const { return node_name; } ///<取得节点名称 - const ObjectList &GetChildNode()const { return ChildNode; } ///<取得子节点列表 + const ObjectList &GetChildNode()const { return child_nodes; } ///<取得子节点列表 public: @@ -63,56 +63,56 @@ namespace hgl::graph { SceneOrient::Clear(); - ParentNode=nullptr; + parent_node=nullptr; - BoundingBox.SetZero(); - LocalBoundingBox.SetZero(); + bounding_box.SetZero(); + local_bounding_box.SetZero(); - ChildNode.Clear(); - ComponentSet.Clear(); + child_nodes.Clear(); + component_set.Clear(); } const bool ChildNodeIsEmpty()const { - if(ChildNode.GetCount())return(false); + if(child_nodes.GetCount())return(false); return(true); } - void SetParent(SceneNode *sn) {ParentNode=sn;} - SceneNode * GetParent() noexcept{return ParentNode;} - const SceneNode * GetParent()const noexcept{return ParentNode;} + void SetParent(SceneNode *sn) {parent_node=sn;} + SceneNode * GetParent() noexcept{return parent_node;} + const SceneNode * GetParent()const noexcept{return parent_node;} SceneNode *Add(SceneNode *sn) { if(!sn) return(nullptr); - ChildNode.Add(sn); + child_nodes.Add(sn); sn->SetParent(this); return sn; } public: //坐标相关方法 - virtual void SetBoundingBox (const AABB &bb){BoundingBox=bb;} ///<设置绑定盒 + virtual void SetBoundingBox (const AABB &bb){bounding_box=bb;} ///<设置绑定盒 virtual void RefreshMatrix () override; ///<刷新世界变换 virtual void RefreshBoundingBox (); ///<刷新绑定盒 - virtual const AABB & GetBoundingBox ()const{return BoundingBox;} ///<取得绑定盒 - virtual const AABB & GetLocalBoundingBox ()const{return LocalBoundingBox;} ///<取得本地坐标绑定盒 + virtual const AABB & GetBoundingBox ()const{return bounding_box;} ///<取得绑定盒 + virtual const AABB & GetLocalBoundingBox ()const{return local_bounding_box;} ///<取得本地坐标绑定盒 // virtual const AABB & GetWorldBoundingBox ()const{return WorldBoundingBox;} ///<取得世界坐标绑定盒 public: //组件相关方法 - bool ComponentIsEmpty ()const{return ComponentSet.GetCount()==0;} ///<是否没有组件 - virtual int GetComponentCount ()const{return ComponentSet.GetCount();} ///<取得组件数量 + bool ComponentIsEmpty ()const{return component_set.GetCount()==0;} ///<是否没有组件 + virtual int GetComponentCount ()const{return component_set.GetCount();} ///<取得组件数量 virtual bool AttachComponent (Component *comp) ///<添加一个组件 { if(!comp)return(false); - if(ComponentSet.Add(comp)<0) + if(component_set.Add(comp)<0) return(false); comp->OnAttach(this); //调用组件的OnAttach方法 @@ -123,17 +123,17 @@ namespace hgl::graph { if (!comp)return; - ComponentSet.Delete(comp); + component_set.Delete(comp); comp->OnDetach(this); //调用组件的OnDetach方法 } - bool Contains (Component *comp){return ComponentSet.Contains(comp);} ///<是否包含指定组件 + bool Contains (Component *comp){return component_set.Contains(comp);} ///<是否包含指定组件 bool HasComponent (const ComponentManager *); ///<是否有指定组件管理器的组件 - virtual int GetComponents (ArrayList &comp_list,const ComponentManager *); ///<取得所有组件 + virtual int GetComponents (ComponentList &comp_list,const ComponentManager *); ///<取得所有组件 - const SortedSet & GetComponents ()const{return ComponentSet;} + const ComponentSet &GetComponents ()const{return component_set;} };//class SceneNode SceneNode *Duplication(SceneNode *); ///<复制一个场景节点 diff --git a/inc/hgl/graph/VKPrimitive.h b/inc/hgl/graph/VKPrimitive.h index 4ab02764..eab2d294 100644 --- a/inc/hgl/graph/VKPrimitive.h +++ b/inc/hgl/graph/VKPrimitive.h @@ -21,7 +21,7 @@ protected: protected: - AABB BoundingBox; + AABB bounding_box; public: @@ -48,6 +48,6 @@ public: VertexDataManager * GetVDM (); ///<取得顶点数据管理器 - const AABB & GetBoundingBox ()const{return BoundingBox;} + const AABB & GetBoundingBox ()const{return bounding_box;} };//class Primitive VK_NAMESPACE_END diff --git a/src/SceneGraph/CMakeLists.txt b/src/SceneGraph/CMakeLists.txt index 472c1ca8..f4fe9cbf 100644 --- a/src/SceneGraph/CMakeLists.txt +++ b/src/SceneGraph/CMakeLists.txt @@ -304,6 +304,7 @@ SET(COMPONENT_FILES ${COMPONENT_INCLUDE_PATH}/Component.h ${COMPONENT_INCLUDE_PATH}/StaticMeshComponent.h component/Component.cpp component/ComponentManager.cpp + component/SceneComponent.cpp component/StaticMeshComponentManager.cpp ) diff --git a/src/SceneGraph/component/SceneComponent.cpp b/src/SceneGraph/component/SceneComponent.cpp new file mode 100644 index 00000000..1ed9d604 --- /dev/null +++ b/src/SceneGraph/component/SceneComponent.cpp @@ -0,0 +1,5 @@ +#include + +COMPONENT_NAMESPACE_BEGIN + +COMPONENT_NAMESPACE_END diff --git a/src/SceneGraph/render/MaterialRenderList.cpp b/src/SceneGraph/render/MaterialRenderList.cpp index e97d7eb4..94821976 100644 --- a/src/SceneGraph/render/MaterialRenderList.cpp +++ b/src/SceneGraph/render/MaterialRenderList.cpp @@ -56,12 +56,10 @@ void MaterialRenderList::Add(StaticMeshComponent *smc) rn.sm_component =smc; - SceneNode *sn=smc->GetOwnerNode(); //目前先这样处理,未来改成每个Component有自己的再一次的变换矩阵 - - rn.l2w_version =sn->GetLocalToWorldMatrixVersion(); + rn.l2w_version =smc->GetLocalToWorldMatrixVersion(); rn.l2w_index =0; - rn.world_position =sn->GetWorldPosition(); + rn.world_position =smc->GetWorldPosition(); if(camera_info) rn.to_camera_distance=length(camera_info->pos,rn.world_position); @@ -104,7 +102,7 @@ void MaterialRenderList::UpdateLocalToWorld() for(int i=0;ism_component->GetOwnerNode()->GetLocalToWorldMatrixVersion(); + l2w_version=rn->sm_component->GetLocalToWorldMatrixVersion(); if(rn->l2w_version!=l2w_version) //版本不对,需要更新 { diff --git a/src/SceneGraph/render/RenderAssignBuffer.cpp b/src/SceneGraph/render/RenderAssignBuffer.cpp index e1392715..81ec5614 100644 --- a/src/SceneGraph/render/RenderAssignBuffer.cpp +++ b/src/SceneGraph/render/RenderAssignBuffer.cpp @@ -74,7 +74,7 @@ void RenderAssignBuffer::StatL2W(const RenderNodeList &rn_list) for(int i=0;ism_component->GetOwnerNode()->GetLocalToWorldMatrix(); + *l2wp=rn->sm_component->GetLocalToWorldMatrix(); ++l2wp; ++rn; } @@ -98,7 +98,7 @@ void RenderAssignBuffer::UpdateLocalToWorld(const RenderNodePointerList &rnp_lis for(uint i=0;il2w_index-first]=(*rn)->sm_component->GetOwnerNode()->GetLocalToWorldMatrix(); + l2wp[(*rn)->l2w_index-first]=(*rn)->sm_component->GetLocalToWorldMatrix(); ++rn; } diff --git a/src/SceneGraph/render/RenderNode.cpp b/src/SceneGraph/render/RenderNode.cpp new file mode 100644 index 00000000..7fac47d9 --- /dev/null +++ b/src/SceneGraph/render/RenderNode.cpp @@ -0,0 +1,79 @@ +#include +#include +#include + +VK_NAMESPACE_BEGIN +/** +* +* 理论上讲,我们需要按以下顺序排序 +* +* for(material) +* for(pipeline) +* for(material_instance) +* for(vab) +* +* +* 关于Indirect Command Buffer + +建立一个大的IndirectCommandBuffer,用于存放所有的渲染指令,包括那些不能使用Indirect渲染的。 +这样就可以保证所有的渲染操作就算要切VBO,也不需要切换INDIRECT缓冲区,定位指令也很方便。 +*/ +const int RenderNode::compare(const RenderNode &other)const +{ + hgl::int64 off; + + hgl::graph::Mesh *ri_one=other.sm_component->GetMesh(); + hgl::graph::Mesh *ri_two=sm_component->GetMesh(); + + 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; +} + +Mesh *RenderNode::GetMesh()const +{ + return sm_component?sm_component->GetMesh():nullptr; +} + +MaterialInstance *RenderNode::GetMaterialInstance()const +{ + if(!sm_component)return(nullptr); + if(!sm_component->GetMesh())return(nullptr); + + return sm_component->GetMesh()->GetMaterialInstance(); +} +VK_NAMESPACE_END + diff --git a/src/SceneGraph/scene/SceneNode.cpp b/src/SceneGraph/scene/SceneNode.cpp index 2f4c8191..1c3cbc98 100644 --- a/src/SceneGraph/scene/SceneNode.cpp +++ b/src/SceneGraph/scene/SceneNode.cpp @@ -1,4 +1,5 @@ #include +#include #include namespace hgl::graph @@ -30,10 +31,10 @@ namespace hgl::graph // } // else // { - // BoundingBox.SetZero(); + // bounding_box.SetZero(); // //WorldBoundingBox= - // LocalBoundingBox=BoundingBox; + // local_bounding_box=bounding_box; // } //} @@ -49,16 +50,21 @@ namespace hgl::graph const Matrix4f &l2w=scene_matrix.GetLocalToWorldMatrix(); - const int count=ChildNode.GetCount(); - - SceneNode **sub=ChildNode.GetData(); - - for(int i=0;iSetParentMatrix(l2w); - (*sub)->RefreshMatrix(); + sub->SetParentMatrix(l2w); + sub->RefreshMatrix(); + } - sub++; + for(Component *com:component_set) + { + SceneComponent *sc=reinterpret_cast(com); + + if(!sc) + continue; + + sc->SetParentMatrix(l2w); + sc->RefreshMatrix(); } } @@ -67,8 +73,8 @@ namespace hgl::graph */ void SceneNode::RefreshBoundingBox() { - int count=ChildNode.GetCount(); - SceneNode **sub=ChildNode.GetData(); + int count=child_nodes.GetCount(); + SceneNode **sub=child_nodes.GetData(); AABB local,world; @@ -85,17 +91,17 @@ namespace hgl::graph ++sub; } - LocalBoundingBox=local; + local_bounding_box=local; } - int SceneNode::GetComponents(ArrayList &comp_list,const ComponentManager *mgr) + int SceneNode::GetComponents(ComponentList &comp_list,const ComponentManager *mgr) { if(!mgr)return(-1); if(ComponentIsEmpty())return(0); int result=0; - for(Component *c:ComponentSet) + for(Component *c:component_set) { if(c->GetManager()==mgr) { @@ -112,7 +118,7 @@ namespace hgl::graph if(!mgr)return(false); if(ComponentIsEmpty())return(false); - for(Component *c:ComponentSet) + for(Component *c:component_set) { if(c->GetManager()==mgr) return(true);