1.VertexBuffer类增加GetBoundingBox/GetAABB成员函数

2.VKRenderableInstance改为RenderableNode,并从SceneNode派生
3.改造SceneNode结构
4.改造RenderList
This commit is contained in:
hyzboy 2019-05-25 14:52:24 +08:00
parent 962ed65fee
commit c6700d60a7
11 changed files with 241 additions and 131 deletions

View File

@ -8,7 +8,7 @@ namespace hgl
{ {
namespace graph namespace graph
{ {
class SceneNode; class RenderableNode;
struct UBOMatrixData struct UBOMatrixData
{ {
@ -21,7 +21,7 @@ namespace hgl
struct UBOSkyLight struct UBOSkyLight
{ {
Color4f sun_color; Color4f sun_color;
Vector3f alignas(16) sun_direction; Vector4f sun_direction;
};// };//
class RenderList class RenderList
@ -41,13 +41,13 @@ namespace hgl
private: private:
List<const SceneNode *> SceneNodeList; List<RenderableNode *> renderable_node_list;
vulkan::Pipeline * last_pipeline; vulkan::Pipeline * last_pipeline;
vulkan::DescriptorSets *last_desc_sets; vulkan::DescriptorSets *last_desc_sets;
vulkan::Renderable * last_renderable; vulkan::Renderable * last_renderable;
void Render(vulkan::RenderableInstance *,const Matrix4f &); void Render(RenderableNode *,const Matrix4f &);
public: public:
@ -61,11 +61,11 @@ namespace hgl
~RenderList()=default; ~RenderList()=default;
void Add (const SceneNode *node) {if(node)SceneNodeList.Add(node);} void Add (RenderableNode *node) {if(node)renderable_node_list.Add(node);}
void Clear () {SceneNodeList.ClearData();} void Clear () {renderable_node_list.ClearData();}
void SetCamera(const Camera &); 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_color=c;
ubo_skylight.sun_direction=d; ubo_skylight.sun_direction=d;

View File

@ -0,0 +1,79 @@
#ifndef HGL_GRAPH_RENDERABLE_NODE_INCLUDE
#define HGL_GRAPH_RENDERABLE_NODE_INCLUDE
#include<hgl/graph/vulkan/VKRenderable.h>
#include<hgl/graph/vulkan/VKPipeline.h>
#include<hgl/graph/vulkan/VKDescriptorSets.h>
#include<hgl/graph/SceneNode.h>
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

View File

@ -8,11 +8,8 @@ namespace hgl
{ {
namespace graph namespace graph
{ {
using namespace vulkan;
class SceneNode; class SceneNode;
struct Camera; struct Camera;
class Frustum;
class RenderList; class RenderList;
using RenderListCompFunc=float (*)(Camera *,SceneNode *,SceneNode *); ///<渲染列表排序比较函数 using RenderListCompFunc=float (*)(Camera *,SceneNode *,SceneNode *); ///<渲染列表排序比较函数
@ -32,8 +29,8 @@ namespace hgl
protected: protected:
AABB BoundingBox; ///<绑定盒 AABB BoundingBox; ///<绑定盒
// AABB LocalBoundingBox; ///<本地坐标绑定盒 AABB LocalBoundingBox; ///<本地坐标绑定盒
// AABB WorldBoundingBox; ///<世界坐标绑定盒 AABB WorldBoundingBox; ///<世界坐标绑定盒
Vector3f Center; ///<中心点 Vector3f Center; ///<中心点
Vector3f LocalCenter; ///<本地坐标中心点 Vector3f LocalCenter; ///<本地坐标中心点
@ -41,7 +38,6 @@ namespace hgl
public: public:
List<RenderableInstance *> RenderableList; ///<可渲染实例列表
ObjectList<SceneNode> SubNode; ///<子节点 ObjectList<SceneNode> SubNode; ///<子节点
public: public:
@ -50,12 +46,8 @@ namespace hgl
virtual ~SceneNode() virtual ~SceneNode()
{ {
ClearSubNode(); ClearSubNode();
ClearRenderable();
} }
void Add(RenderableInstance *r){if(r)RenderableList.Add(r);} ///<增加一个可渲染实例
void ClearRenderable(){RenderableList.Clear();} ///<清除所有可渲染实例
void AddSubNode(SceneNode *n){if(n)SubNode.Add(n);} ///<增加一个子节点 void AddSubNode(SceneNode *n){if(n)SubNode.Add(n);} ///<增加一个子节点
SceneNode * CreateSubNode() ///<创建一个子节点 SceneNode * CreateSubNode() ///<创建一个子节点
{ {
@ -64,18 +56,14 @@ namespace hgl
return sn; 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();} ///<清除子节点 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: //坐标相关方法 public: //坐标相关方法
virtual void SetBoundingBox (const AABB &bb){BoundingBox=bb;} ///<设置绑定盒 virtual void SetBoundingBox (const AABB &bb){BoundingBox=bb;} ///<设置绑定盒
@ -84,8 +72,8 @@ namespace hgl
virtual void RefreshBoundingBox (); ///<刷新绑定盒 virtual void RefreshBoundingBox (); ///<刷新绑定盒
virtual const AABB & GetBoundingBox ()const{return BoundingBox;} ///<取得绑定盒 virtual const AABB & GetBoundingBox ()const{return BoundingBox;} ///<取得绑定盒
// virtual const AABB & GetLocalBoundingBox ()const{return LocalBoundingBox;} ///<取得本地坐标绑定盒 virtual const AABB & GetLocalBoundingBox ()const{return LocalBoundingBox;} ///<取得本地坐标绑定盒
// virtual const AABB & GetWorldBoundingBox ()const{return WorldBoundingBox;} ///<取得世界坐标绑定盒 virtual const AABB & GetWorldBoundingBox ()const{return WorldBoundingBox;} ///<取得世界坐标绑定盒
virtual const Vector3f & GetCenter ()const{return Center;} ///<取得中心点 virtual const Vector3f & GetCenter ()const{return Center;} ///<取得中心点
virtual const Vector3f & GetLocalCenter ()const{return LocalCenter;} ///<取得本地坐标中心点 virtual const Vector3f & GetLocalCenter ()const{return LocalCenter;} ///<取得本地坐标中心点

View File

@ -120,6 +120,46 @@ namespace hgl
VkFormat GetDataType()const override; VkFormat GetDataType()const override;
/**
*
* @param min_vertex
* @param max_vertex
*/
template<typename V>
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;i<this->count;i++)
{
if(*p<min_vertex.x)min_vertex.x=*p;
if(*p>max_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) bool Write(const T v1)
{ {
if(!this->access||this->access+1>this->mem_end) if(!this->access||this->access+1>this->mem_end)
@ -163,6 +203,48 @@ namespace hgl
VkFormat GetDataType()const override; VkFormat GetDataType()const override;
/**
*
* @param min_vertex
* @param max_vertex
*/
template<typename V>
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;i<this->count;i++)
{
if(*p<min_vertex.x)min_vertex.x=*p;
if(*p>max_vertex.x)max_vertex.x=*p;
++p;
if(*p<min_vertex.y)min_vertex.y=*p;
if(*p>max_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) bool Write(const T v1,const T v2)
{ {
if(!this->access||this->access+2>this->mem_end) if(!this->access||this->access+2>this->mem_end)
@ -416,7 +498,7 @@ namespace hgl
* @param max_vertex * @param max_vertex
*/ */
template<typename V> template<typename V>
void GetBoundingBox(V &min_vertex,V &max_vertex) void GetBoundingBox(V &min_vertex,V &max_vertex) const
{ {
T *p=this->mem_type; 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) bool Write(const T v1,const T v2,const T v3)
{ {
if(!this->access||this->access+3>this->mem_end) if(!this->access||this->access+3>this->mem_end)
@ -656,7 +750,7 @@ namespace hgl
* @param max_vertex * @param max_vertex
*/ */
template<typename V> template<typename V>
void GetBoundingBox(V &min_vertex,V &max_vertex) void GetBoundingBox(V &min_vertex,V &max_vertex) const
{ {
T *p=this->mem_type; T *p=this->mem_type;
@ -664,6 +758,7 @@ namespace hgl
min_vertex.x=*p++; min_vertex.x=*p++;
min_vertex.y=*p++; min_vertex.y=*p++;
min_vertex.z=*p++; min_vertex.z=*p++;
++p;
max_vertex=min_vertex; max_vertex=min_vertex;
@ -680,9 +775,23 @@ namespace hgl
if(*p<min_vertex.z)min_vertex.z=*p; if(*p<min_vertex.z)min_vertex.z=*p;
if(*p>max_vertex.z)max_vertex.z=*p; if(*p>max_vertex.z)max_vertex.z=*p;
++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) bool Write(const T v1,const T v2,const T v3,const T v4)
{ {
if(!this->access||this->access+4>this->mem_end) if(!this->access||this->access+4>this->mem_end)

View File

@ -49,7 +49,6 @@ class DescriptorSets;
class VertexAttributeBinding; class VertexAttributeBinding;
class Renderable; class Renderable;
class RenderableInstance;
using CharPointerList=hgl::List<const char *>; using CharPointerList=hgl::List<const char *>;

View File

@ -4,6 +4,7 @@
#include<hgl/graph/vulkan/VK.h> #include<hgl/graph/vulkan/VK.h>
#include<hgl/graph/vulkan/VKBuffer.h> #include<hgl/graph/vulkan/VKBuffer.h>
#include<hgl/type/BaseString.h> #include<hgl/type/BaseString.h>
#include<hgl/math/Math.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
/** /**
* <br> * <br>
@ -23,9 +24,13 @@ class Renderable
IndexBuffer *indices_buffer=nullptr; IndexBuffer *indices_buffer=nullptr;
VkDeviceSize indices_offset=0; VkDeviceSize indices_offset=0;
private:
AABB BoundingBox;
protected: protected:
friend class RenderableInstance; friend class RenderableNode;
uint ref_count=0; uint ref_count=0;
@ -39,6 +44,9 @@ public:
const uint GetRefCount()const{return ref_count;} 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 int stage_input_binding, VertexBuffer *vb,VkDeviceSize offset=0);
bool Set(const UTF8String &name, VertexBuffer *vb,VkDeviceSize offset=0); bool Set(const UTF8String &name, VertexBuffer *vb,VkDeviceSize offset=0);

View File

@ -1,70 +0,0 @@
#ifndef HGL_GRAPH_VULKAN_RENDERABLE_INSTANCE_INCLUDE
#define HGL_GRAPH_VULKAN_RENDERABLE_INSTANCE_INCLUDE
#include<hgl/graph/vulkan/VKRenderable.h>
#include<hgl/graph/vulkan/VKPipeline.h>
#include<hgl/graph/vulkan/VKDescriptorSets.h>
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

View File

@ -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/Camera.h
${ROOT_INCLUDE_PATH}/hgl/graph/Light.h ${ROOT_INCLUDE_PATH}/hgl/graph/Light.h
${ROOT_INCLUDE_PATH}/hgl/graph/SceneNode.h ${ROOT_INCLUDE_PATH}/hgl/graph/SceneNode.h
${ROOT_INCLUDE_PATH}/hgl/graph/SceneOrient.h ${ROOT_INCLUDE_PATH}/hgl/graph/SceneOrient.h
${ROOT_INCLUDE_PATH}/hgl/graph/VertexBufferCreater.h ${ROOT_INCLUDE_PATH}/hgl/graph/RenderableNode.h
${ROOT_INCLUDE_PATH}/hgl/graph/VertexBuffer.h ${ROOT_INCLUDE_PATH}/hgl/graph/VertexBufferCreater.h
${ROOT_INCLUDE_PATH}/hgl/graph/InlineGeometry.h) ${ROOT_INCLUDE_PATH}/hgl/graph/VertexBuffer.h
${ROOT_INCLUDE_PATH}/hgl/graph/InlineGeometry.h)
SET(SCENE_GRAPH_SOURCE AABox.cpp SET(SCENE_GRAPH_SOURCE AABox.cpp
Camera.cpp Camera.cpp
RenderList.cpp RenderList.cpp
SceneNode.cpp SceneNode.cpp
SceneOrient.cpp SceneOrient.cpp
InlineGeometry.cpp) InlineGeometry.cpp)
SOURCE_GROUP("Header Files" FILES ${SCENE_GRAPH_HEADER}) SOURCE_GROUP("Header Files" FILES ${SCENE_GRAPH_HEADER})
SOURCE_GROUP("Source Files" FILES ${SCENE_GRAPH_SOURCE}) SOURCE_GROUP("Source Files" FILES ${SCENE_GRAPH_SOURCE})

View File

@ -25,6 +25,7 @@ namespace hgl
vulkan::Renderable *render_obj=mtl->CreateRenderable(vertex->GetCount()); vulkan::Renderable *render_obj=mtl->CreateRenderable(vertex->GetCount());
render_obj->Set(vertex_binding,device->CreateVBO(vertex)); render_obj->Set(vertex_binding,device->CreateVBO(vertex));
render_obj->SetBoundingBox(vertex->GetAABB());
delete vertex; delete vertex;
return render_obj; return render_obj;
@ -106,6 +107,7 @@ namespace hgl
render_obj=mtl->CreateRenderable(vertex->GetCount()); render_obj=mtl->CreateRenderable(vertex->GetCount());
render_obj->Set(vertex_binding,device->CreateVBO(vertex)); render_obj->Set(vertex_binding,device->CreateVBO(vertex));
render_obj->SetBoundingBox(vertex->GetAABB());
delete vertex; delete vertex;
return render_obj; return render_obj;
@ -140,6 +142,7 @@ namespace hgl
vulkan::Renderable *render_obj=mtl->CreateRenderable(vertex->GetCount()); vulkan::Renderable *render_obj=mtl->CreateRenderable(vertex->GetCount());
render_obj->Set(vertex_binding,device->CreateVBO(vertex)); render_obj->Set(vertex_binding,device->CreateVBO(vertex));
render_obj->SetBoundingBox(vertex->GetAABB());
delete vertex; delete vertex;
return render_obj; return render_obj;

View File

@ -4,9 +4,7 @@
#include<hgl/graph/vulkan/VKRenderable.h> #include<hgl/graph/vulkan/VKRenderable.h>
#include<hgl/graph/vulkan/VKCommandBuffer.h> #include<hgl/graph/vulkan/VKCommandBuffer.h>
#include<hgl/graph/VertexBuffer.h> #include<hgl/graph/VertexBuffer.h>
#include<hgl/math/Math.h> #include<hgl/graph/RenderableNode.h>
#include<hgl/graph/vulkan/VKRenderableInstance.h>
namespace hgl namespace hgl
{ {
@ -43,7 +41,7 @@ namespace hgl
&camera); &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()) if(last_pipeline!=ri->GetPipeline())
{ {
@ -95,22 +93,14 @@ namespace hgl
last_desc_sets=nullptr; last_desc_sets=nullptr;
last_renderable=nullptr; last_renderable=nullptr;
int count=SceneNodeList.GetCount(); const int count=renderable_node_list.GetCount();
const SceneNode **node=SceneNodeList.GetData(); RenderableNode **node=renderable_node_list.GetData();
for(int i=0;i<count;i++) for(int i=0;i<count;i++)
{ {
const Matrix4f fin_mv=ubo_matrix.modelview*(*node)->GetLocalToWorldMatrix(); const Matrix4f fin_mv=ubo_matrix.modelview*(*node)->GetLocalToWorldMatrix();
int sn=(*node)->RenderableList.GetCount(); Render(*node,ubo_matrix.projection*fin_mv);
RenderableInstance **p=(*node)->RenderableList.GetData();
for(int j=0;j<sn;j++)
{
Render(*p,ubo_matrix.projection*fin_mv);
p++;
}
node++; node++;
} }

View File

@ -7,14 +7,14 @@ namespace hgl
{ {
/** /**
* *
* @param root * @param root_matrix
*/ */
void SceneNode::RefreshMatrix(const Matrix4f *root_matrix) void SceneNode::RefreshMatrix(const Matrix4f *root_matrix)
{ {
if(root_matrix) if(root_matrix)
RefreshLocalToWorldMatrix(root_matrix); RefreshLocalToWorldMatrix(root_matrix);
else else
LocalToWorldMatrix=LocalMatrix; SetLocalToWorldMatrix(LocalMatrix);
const int count=SubNode.GetCount(); const int count=SubNode.GetCount();
@ -36,19 +36,22 @@ namespace hgl
int count=SubNode.GetCount(); int count=SubNode.GetCount();
SceneNode **sub=SubNode.GetData(); SceneNode **sub=SubNode.GetData();
Vector3f min_v,max_v; AABB local,world;
for(int i=0;i<count;i++) for(int i=0;i<count;i++)
{ {
(*sub)->RefreshBoundingBox(); (*sub)->RefreshBoundingBox();
if(i==0) if(i==0)
{ local=(*sub)->GetLocalBoundingBox();
// min_v=(*sub)->GetBounding(); else
} local.Enclose((*sub)->GetLocalBoundingBox());
sub++; sub++;
} }
} }
/** /**
@ -66,8 +69,8 @@ namespace hgl
if(!func(this,func_data)) if(!func(this,func_data))
return(false); return(false);
if(RenderableList.GetCount()) if(CanRenderable())
rl->Add(this); //增加当前节点 rl->Add((RenderableNode *)this); //增加当前节点
int count=SubNode.GetCount(); int count=SubNode.GetCount();
SceneNode **sub=SubNode.GetData(); SceneNode **sub=SubNode.GetData();