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
{
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<const SceneNode *> SceneNodeList;
List<RenderableNode *> 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;

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
{
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<RenderableInstance *> RenderableList; ///<可渲染实例列表
ObjectList<SceneNode> 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;} ///<取得本地坐标中心点

View File

@ -120,6 +120,46 @@ namespace hgl
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)
{
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<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)
{
if(!this->access||this->access+2>this->mem_end)
@ -416,7 +498,7 @@ namespace hgl
* @param max_vertex
*/
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;
@ -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<typename V>
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(*p<min_vertex.z)min_vertex.z=*p;
if(*p>max_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)

View File

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

View File

@ -4,6 +4,7 @@
#include<hgl/graph/vulkan/VK.h>
#include<hgl/graph/vulkan/VKBuffer.h>
#include<hgl/type/BaseString.h>
#include<hgl/math/Math.h>
VK_NAMESPACE_BEGIN
/**
* <br>
@ -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);

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/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})

View File

@ -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;

View File

@ -4,9 +4,7 @@
#include<hgl/graph/vulkan/VKRenderable.h>
#include<hgl/graph/vulkan/VKCommandBuffer.h>
#include<hgl/graph/VertexBuffer.h>
#include<hgl/math/Math.h>
#include<hgl/graph/vulkan/VKRenderableInstance.h>
#include<hgl/graph/RenderableNode.h>
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;i<count;i++)
{
const Matrix4f fin_mv=ubo_matrix.modelview*(*node)->GetLocalToWorldMatrix();
int sn=(*node)->RenderableList.GetCount();
RenderableInstance **p=(*node)->RenderableList.GetData();
for(int j=0;j<sn;j++)
{
Render(*p,ubo_matrix.projection*fin_mv);
p++;
}
Render(*node,ubo_matrix.projection*fin_mv);
node++;
}

View File

@ -7,14 +7,14 @@ namespace hgl
{
/**
*
* @param root
* @param root_matrix
*/
void SceneNode::RefreshMatrix(const Matrix4f *root_matrix)
{
if(root_matrix)
RefreshLocalToWorldMatrix(root_matrix);
else
LocalToWorldMatrix=LocalMatrix;
SetLocalToWorldMatrix(LocalMatrix);
const int count=SubNode.GetCount();
@ -36,19 +36,22 @@ namespace hgl
int count=SubNode.GetCount();
SceneNode **sub=SubNode.GetData();
Vector3f min_v,max_v;
AABB local,world;
for(int i=0;i<count;i++)
{
(*sub)->RefreshBoundingBox();
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();