From c6700d60a7c025065843b743cdf00c2ee9b4d863 Mon Sep 17 00:00:00 2001 From: hyzboy Date: Sat, 25 May 2019 14:52:24 +0800 Subject: [PATCH] =?UTF-8?q?1.VertexBuffer=E7=B1=BB=E5=A2=9E=E5=8A=A0GetBou?= =?UTF-8?q?ndingBox/GetAABB=E6=88=90=E5=91=98=E5=87=BD=E6=95=B0=202.VKRend?= =?UTF-8?q?erableInstance=E6=94=B9=E4=B8=BARenderableNode=EF=BC=8C?= =?UTF-8?q?=E5=B9=B6=E4=BB=8ESceneNode=E6=B4=BE=E7=94=9F=203.=E6=94=B9?= =?UTF-8?q?=E9=80=A0SceneNode=E7=BB=93=E6=9E=84=204.=E6=94=B9=E9=80=A0Rend?= =?UTF-8?q?erList?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- inc/hgl/graph/RenderList.h | 14 +-- inc/hgl/graph/RenderableNode.h | 79 ++++++++++++++ inc/hgl/graph/SceneNode.h | 32 ++---- inc/hgl/graph/VertexBuffer.h | 113 +++++++++++++++++++- inc/hgl/graph/vulkan/VK.h | 1 - inc/hgl/graph/vulkan/VKRenderable.h | 10 +- inc/hgl/graph/vulkan/VKRenderableInstance.h | 70 ------------ src/SceneGraph/CMakeLists.txt | 11 +- src/SceneGraph/InlineGeometry.cpp | 3 + src/SceneGraph/RenderList.cpp | 20 +--- src/SceneGraph/SceneNode.cpp | 19 ++-- 11 files changed, 241 insertions(+), 131 deletions(-) create mode 100644 inc/hgl/graph/RenderableNode.h delete mode 100644 inc/hgl/graph/vulkan/VKRenderableInstance.h diff --git a/inc/hgl/graph/RenderList.h b/inc/hgl/graph/RenderList.h index 93d02489..241e184c 100644 --- a/inc/hgl/graph/RenderList.h +++ b/inc/hgl/graph/RenderList.h @@ -8,7 +8,7 @@ namespace hgl { namespace graph { - class SceneNode; + class RenderableNode; struct UBOMatrixData { @@ -21,7 +21,7 @@ namespace hgl struct UBOSkyLight { Color4f sun_color; - Vector3f alignas(16) sun_direction; + Vector4f sun_direction; };// class RenderList @@ -41,13 +41,13 @@ namespace hgl private: - List SceneNodeList; + List renderable_node_list; vulkan::Pipeline * last_pipeline; vulkan::DescriptorSets *last_desc_sets; vulkan::Renderable * last_renderable; - void Render(vulkan::RenderableInstance *,const Matrix4f &); + void Render(RenderableNode *,const Matrix4f &); public: @@ -61,11 +61,11 @@ namespace hgl ~RenderList()=default; - void Add (const SceneNode *node) {if(node)SceneNodeList.Add(node);} - void Clear () {SceneNodeList.ClearData();} + void Add (RenderableNode *node) {if(node)renderable_node_list.Add(node);} + void Clear () {renderable_node_list.ClearData();} void SetCamera(const Camera &); - void SetSkyLightColor(const Color4f &c,const Vector3f &d) + void SetSkyLightColor(const Color4f &c,const Vector4f &d) { ubo_skylight.sun_color=c; ubo_skylight.sun_direction=d; diff --git a/inc/hgl/graph/RenderableNode.h b/inc/hgl/graph/RenderableNode.h new file mode 100644 index 00000000..127dbf70 --- /dev/null +++ b/inc/hgl/graph/RenderableNode.h @@ -0,0 +1,79 @@ +#ifndef HGL_GRAPH_RENDERABLE_NODE_INCLUDE +#define HGL_GRAPH_RENDERABLE_NODE_INCLUDE + +#include +#include +#include +#include +namespace hgl +{ + namespace graph + { + /** + * 可渲染对象节点 + */ + class RenderableNode:public SceneNode + { + vulkan::Pipeline * pipeline; + vulkan::DescriptorSets * desc_sets; + vulkan::Renderable * render_obj; + + public: + + RenderableNode(vulkan::Pipeline *p,vulkan::DescriptorSets *ds,vulkan::Renderable *r):pipeline(p),desc_sets(ds),render_obj(r){} + virtual ~RenderableNode() + { + //需要在这里添加删除pipeline/desc_sets/render_obj引用计数的代码 + } + + vulkan::Pipeline * GetPipeline (){return pipeline;} + vulkan::DescriptorSets *GetDescriptorSets (){return desc_sets;} + 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 + { + //绘制顺序: + + // ARM Mali GPU : 不透明、AlphaTest、半透明 + // Adreno/NV/AMD: AlphaTest、不透明、半透明 + // PowerVR: 同Adreno/NV/AMD,但不透明部分可以不排序 + + if(pipeline->IsAlphaBlend()) + { + if(!ri->pipeline->IsAlphaBlend()) + return 1; + } + else + { + if(ri->pipeline->IsAlphaBlend()) + return -1; + } + + if(pipeline->IsAlphaTest()) + { + if(!ri->pipeline->IsAlphaTest()) + return 1; + } + else + { + if(ri->pipeline->IsAlphaTest()) + return -1; + } + + if(pipeline!=ri->pipeline) + return pipeline-ri->pipeline; + + if(desc_sets!=ri->desc_sets) + return desc_sets-ri->desc_sets; + + return render_obj-ri->render_obj; + } + + CompOperator(const RenderableNode *,Comp) + };//class RenderableNode + }//namespace graph +}//namespace hgl +#endif//HGL_GRAPH_RENDERABLE_NODE_INCLUDE diff --git a/inc/hgl/graph/SceneNode.h b/inc/hgl/graph/SceneNode.h index 775c1c2a..be8658f1 100644 --- a/inc/hgl/graph/SceneNode.h +++ b/inc/hgl/graph/SceneNode.h @@ -8,11 +8,8 @@ namespace hgl { namespace graph { - using namespace vulkan; - class SceneNode; struct Camera; - class Frustum; class RenderList; using RenderListCompFunc=float (*)(Camera *,SceneNode *,SceneNode *); ///<渲染列表排序比较函数 @@ -32,8 +29,8 @@ namespace hgl protected: AABB BoundingBox; ///<绑定盒 -// AABB LocalBoundingBox; ///<本地坐标绑定盒 -// AABB WorldBoundingBox; ///<世界坐标绑定盒 + AABB LocalBoundingBox; ///<本地坐标绑定盒 + AABB WorldBoundingBox; ///<世界坐标绑定盒 Vector3f Center; ///<中心点 Vector3f LocalCenter; ///<本地坐标中心点 @@ -41,7 +38,6 @@ namespace hgl public: - List RenderableList; ///<可渲染实例列表 ObjectList SubNode; ///<子节点 public: @@ -50,12 +46,8 @@ namespace hgl virtual ~SceneNode() { ClearSubNode(); - ClearRenderable(); } - void Add(RenderableInstance *r){if(r)RenderableList.Add(r);} ///<增加一个可渲染实例 - void ClearRenderable(){RenderableList.Clear();} ///<清除所有可渲染实例 - void AddSubNode(SceneNode *n){if(n)SubNode.Add(n);} ///<增加一个子节点 SceneNode * CreateSubNode() ///<创建一个子节点 { @@ -64,18 +56,14 @@ namespace hgl return sn; } - SceneNode * AddSubNode(RenderableInstance *r,const Matrix4f &m) - { - if(!r)return(nullptr); - - SceneNode *sn=CreateSubNode(); - sn->Add(r); - sn->SetLocalMatrix(m); - return sn; - } - 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;} ///<是否可以渲染 + public: //坐标相关方法 virtual void SetBoundingBox (const AABB &bb){BoundingBox=bb;} ///<设置绑定盒 @@ -84,8 +72,8 @@ namespace hgl virtual void RefreshBoundingBox (); ///<刷新绑定盒 virtual const AABB & GetBoundingBox ()const{return BoundingBox;} ///<取得绑定盒 -// virtual const AABB & GetLocalBoundingBox ()const{return LocalBoundingBox;} ///<取得本地坐标绑定盒 -// virtual const AABB & GetWorldBoundingBox ()const{return WorldBoundingBox;} ///<取得世界坐标绑定盒 + virtual const AABB & GetLocalBoundingBox ()const{return LocalBoundingBox;} ///<取得本地坐标绑定盒 + virtual const AABB & GetWorldBoundingBox ()const{return WorldBoundingBox;} ///<取得世界坐标绑定盒 virtual const Vector3f & GetCenter ()const{return Center;} ///<取得中心点 virtual const Vector3f & GetLocalCenter ()const{return LocalCenter;} ///<取得本地坐标中心点 diff --git a/inc/hgl/graph/VertexBuffer.h b/inc/hgl/graph/VertexBuffer.h index 47c97a0d..5fb1b1d0 100644 --- a/inc/hgl/graph/VertexBuffer.h +++ b/inc/hgl/graph/VertexBuffer.h @@ -120,6 +120,46 @@ namespace hgl VkFormat GetDataType()const override; + /** + * 计算绑定盒 + * @param min_vertex 最小值坐标 + * @param max_vertex 最大值坐标 + */ + template + void GetBoundingBox(V &min_vertex,V &max_vertex) const + { + T *p=this->mem_type; + + //先以corner为最小值,length为最大值,求取最小最大值 + min_vertex.x=*p++; + + max_vertex=min_vertex; + + for(uint32_t i=1;icount;i++) + { + if(*pmax_vertex.x)max_vertex.x=*p; + ++p; + } + } + + AABB GetAABB()const + { + vec min_point,max_point; + + GetBoundingBox(min_point,max_point); + + min_point.y=0; + min_point.z=0; + min_point.w=0; + + max_point.y=0; + max_point.z=0; + max_point.w=0; + + return AABB(min_point,max_point); + } + bool Write(const T v1) { if(!this->access||this->access+1>this->mem_end) @@ -163,6 +203,48 @@ namespace hgl VkFormat GetDataType()const override; + /** + * 计算绑定盒 + * @param min_vertex 最小值坐标 + * @param max_vertex 最大值坐标 + */ + template + void GetBoundingBox(V &min_vertex,V &max_vertex) const + { + T *p=this->mem_type; + + //先以corner为最小值,length为最大值,求取最小最大值 + min_vertex.x=*p++; + min_vertex.y=*p++; + + max_vertex=min_vertex; + + for(uint32_t i=1;icount;i++) + { + if(*pmax_vertex.x)max_vertex.x=*p; + ++p; + + if(*pmax_vertex.y)max_vertex.y=*p; + ++p; + } + } + + AABB GetAABB()const + { + vec min_point,max_point; + + GetBoundingBox(min_point,max_point); + + min_point.z=0; + min_point.w=0; + max_point.z=0; + max_point.w=0; + + return AABB(min_point,max_point); + } + bool Write(const T v1,const T v2) { if(!this->access||this->access+2>this->mem_end) @@ -416,7 +498,7 @@ namespace hgl * @param max_vertex 最大值坐标 */ template - void GetBoundingBox(V &min_vertex,V &max_vertex) + void GetBoundingBox(V &min_vertex,V &max_vertex) const { T *p=this->mem_type; @@ -443,6 +525,18 @@ namespace hgl } } + AABB GetAABB()const + { + vec min_point,max_point; + + GetBoundingBox(min_point,max_point); + + min_point.w=0; + max_point.w=0; + + return AABB(min_point,max_point); + } + bool Write(const T v1,const T v2,const T v3) { if(!this->access||this->access+3>this->mem_end) @@ -656,7 +750,7 @@ namespace hgl * @param max_vertex 最大值坐标 */ template - void GetBoundingBox(V &min_vertex,V &max_vertex) + void GetBoundingBox(V &min_vertex,V &max_vertex) const { T *p=this->mem_type; @@ -664,6 +758,7 @@ namespace hgl min_vertex.x=*p++; min_vertex.y=*p++; min_vertex.z=*p++; + ++p; max_vertex=min_vertex; @@ -680,9 +775,23 @@ namespace hgl if(*pmax_vertex.z)max_vertex.z=*p; ++p; + + ++p; } } + AABB GetAABB()const + { + vec min_point,max_point; + + GetBoundingBox(min_point,max_point); + + min_point.w=0; + max_point.w=0; + + return AABB(min_point,max_point); + } + bool Write(const T v1,const T v2,const T v3,const T v4) { if(!this->access||this->access+4>this->mem_end) diff --git a/inc/hgl/graph/vulkan/VK.h b/inc/hgl/graph/vulkan/VK.h index 4a45f59e..646567b1 100644 --- a/inc/hgl/graph/vulkan/VK.h +++ b/inc/hgl/graph/vulkan/VK.h @@ -49,7 +49,6 @@ class DescriptorSets; class VertexAttributeBinding; class Renderable; -class RenderableInstance; using CharPointerList=hgl::List; diff --git a/inc/hgl/graph/vulkan/VKRenderable.h b/inc/hgl/graph/vulkan/VKRenderable.h index d52233ff..09465b35 100644 --- a/inc/hgl/graph/vulkan/VKRenderable.h +++ b/inc/hgl/graph/vulkan/VKRenderable.h @@ -4,6 +4,7 @@ #include #include #include +#include VK_NAMESPACE_BEGIN /** * 可渲染数据对象
@@ -23,9 +24,13 @@ class Renderable IndexBuffer *indices_buffer=nullptr; VkDeviceSize indices_offset=0; +private: + + AABB BoundingBox; + protected: - friend class RenderableInstance; + friend class RenderableNode; uint ref_count=0; @@ -39,6 +44,9 @@ public: const uint GetRefCount()const{return ref_count;} + void SetBoundingBox(const AABB &aabb){BoundingBox=aabb;} + const AABB &GetBoundingBox()const {return BoundingBox;} + bool Set(const int stage_input_binding, VertexBuffer *vb,VkDeviceSize offset=0); bool Set(const UTF8String &name, VertexBuffer *vb,VkDeviceSize offset=0); diff --git a/inc/hgl/graph/vulkan/VKRenderableInstance.h b/inc/hgl/graph/vulkan/VKRenderableInstance.h deleted file mode 100644 index cedc25ee..00000000 --- a/inc/hgl/graph/vulkan/VKRenderableInstance.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef HGL_GRAPH_VULKAN_RENDERABLE_INSTANCE_INCLUDE -#define HGL_GRAPH_VULKAN_RENDERABLE_INSTANCE_INCLUDE - -#include -#include -#include -VK_NAMESPACE_BEGIN -/** -* 可渲染对象实例 -*/ -class RenderableInstance -{ - Pipeline * pipeline; - DescriptorSets * desc_sets; - Renderable * render_obj; - -public: - - RenderableInstance(Pipeline *p,DescriptorSets *ds,Renderable *r):pipeline(p),desc_sets(ds),render_obj(r){} - virtual ~RenderableInstance() - { - } - - Pipeline * GetPipeline (){return pipeline;} - DescriptorSets *GetDescriptorSets (){return desc_sets;} - Renderable * GetRenderable (){return render_obj;} - - const int Comp(const RenderableInstance *ri)const - { - //绘制顺序: - - // ARM Mali GPU : 不透明、AlphaTest、半透明 - // Adreno/NV/AMD: AlphaTest、不透明、半透明 - // PowerVR: 同Adreno/NV/AMD,但不透明部分可以不排序 - - if(pipeline->IsAlphaBlend()) - { - if(!ri->pipeline->IsAlphaBlend()) - return 1; - } - else - { - if(ri->pipeline->IsAlphaBlend()) - return -1; - } - - if(pipeline->IsAlphaTest()) - { - if(!ri->pipeline->IsAlphaTest()) - return 1; - } - else - { - if(ri->pipeline->IsAlphaTest()) - return -1; - } - - if(pipeline!=ri->pipeline) - return pipeline-ri->pipeline; - - if(desc_sets!=ri->desc_sets) - return desc_sets-ri->desc_sets; - - return render_obj-ri->render_obj; - } - - CompOperator(const RenderableInstance *,Comp) -};//class RenderableInstance -VK_NAMESPACE_END -#endif//HGL_GRAPH_VULKAN_RENDERABLE_INSTANCE_INCLUDE diff --git a/src/SceneGraph/CMakeLists.txt b/src/SceneGraph/CMakeLists.txt index 1ad55edd..49461734 100644 --- a/src/SceneGraph/CMakeLists.txt +++ b/src/SceneGraph/CMakeLists.txt @@ -1,18 +1,19 @@ -SET(SCENE_GRAPH_HEADER ${ROOT_INCLUDE_PATH}/hgl/graph/AABox.h +SET(SCENE_GRAPH_HEADER ${ROOT_INCLUDE_PATH}/hgl/graph/AABox.h ${ROOT_INCLUDE_PATH}/hgl/graph/Camera.h ${ROOT_INCLUDE_PATH}/hgl/graph/Light.h ${ROOT_INCLUDE_PATH}/hgl/graph/SceneNode.h ${ROOT_INCLUDE_PATH}/hgl/graph/SceneOrient.h - ${ROOT_INCLUDE_PATH}/hgl/graph/VertexBufferCreater.h - ${ROOT_INCLUDE_PATH}/hgl/graph/VertexBuffer.h - ${ROOT_INCLUDE_PATH}/hgl/graph/InlineGeometry.h) + ${ROOT_INCLUDE_PATH}/hgl/graph/RenderableNode.h + ${ROOT_INCLUDE_PATH}/hgl/graph/VertexBufferCreater.h + ${ROOT_INCLUDE_PATH}/hgl/graph/VertexBuffer.h + ${ROOT_INCLUDE_PATH}/hgl/graph/InlineGeometry.h) SET(SCENE_GRAPH_SOURCE AABox.cpp Camera.cpp RenderList.cpp SceneNode.cpp SceneOrient.cpp - InlineGeometry.cpp) + InlineGeometry.cpp) SOURCE_GROUP("Header Files" FILES ${SCENE_GRAPH_HEADER}) SOURCE_GROUP("Source Files" FILES ${SCENE_GRAPH_SOURCE}) diff --git a/src/SceneGraph/InlineGeometry.cpp b/src/SceneGraph/InlineGeometry.cpp index faff68ce..3c9c7a3d 100644 --- a/src/SceneGraph/InlineGeometry.cpp +++ b/src/SceneGraph/InlineGeometry.cpp @@ -25,6 +25,7 @@ namespace hgl vulkan::Renderable *render_obj=mtl->CreateRenderable(vertex->GetCount()); render_obj->Set(vertex_binding,device->CreateVBO(vertex)); + render_obj->SetBoundingBox(vertex->GetAABB()); delete vertex; return render_obj; @@ -106,6 +107,7 @@ namespace hgl render_obj=mtl->CreateRenderable(vertex->GetCount()); render_obj->Set(vertex_binding,device->CreateVBO(vertex)); + render_obj->SetBoundingBox(vertex->GetAABB()); delete vertex; return render_obj; @@ -140,6 +142,7 @@ namespace hgl vulkan::Renderable *render_obj=mtl->CreateRenderable(vertex->GetCount()); render_obj->Set(vertex_binding,device->CreateVBO(vertex)); + render_obj->SetBoundingBox(vertex->GetAABB()); delete vertex; return render_obj; diff --git a/src/SceneGraph/RenderList.cpp b/src/SceneGraph/RenderList.cpp index 831e807e..123a2996 100644 --- a/src/SceneGraph/RenderList.cpp +++ b/src/SceneGraph/RenderList.cpp @@ -4,9 +4,7 @@ #include #include #include -#include - -#include +#include namespace hgl { @@ -43,7 +41,7 @@ namespace hgl &camera); } - void RenderList::Render(vulkan::RenderableInstance *ri,const Matrix4f &fin_mvp) + void RenderList::Render(RenderableNode *ri,const Matrix4f &fin_mvp) { if(last_pipeline!=ri->GetPipeline()) { @@ -95,22 +93,14 @@ namespace hgl last_desc_sets=nullptr; last_renderable=nullptr; - int count=SceneNodeList.GetCount(); - const SceneNode **node=SceneNodeList.GetData(); + const int count=renderable_node_list.GetCount(); + RenderableNode **node=renderable_node_list.GetData(); for(int i=0;iGetLocalToWorldMatrix(); - int sn=(*node)->RenderableList.GetCount(); - RenderableInstance **p=(*node)->RenderableList.GetData(); - - for(int j=0;jRefreshBoundingBox(); if(i==0) - { -// min_v=(*sub)->GetBounding(); - } + local=(*sub)->GetLocalBoundingBox(); + else + local.Enclose((*sub)->GetLocalBoundingBox()); sub++; } + + + } /** @@ -66,8 +69,8 @@ namespace hgl if(!func(this,func_data)) return(false); - if(RenderableList.GetCount()) - rl->Add(this); //增加当前节点 + if(CanRenderable()) + rl->Add((RenderableNode *)this); //增加当前节点 int count=SubNode.GetCount(); SceneNode **sub=SubNode.GetData();