ULRE/src/SceneGraph/RenderList.cpp

213 lines
5.5 KiB
C++
Raw Normal View History

2019-05-25 00:50:04 +08:00
#include<hgl/graph/RenderList.h>
#include<hgl/graph/Camera.h>
2019-05-21 21:28:33 +08:00
#include<hgl/graph/SceneNode.h>
2020-12-18 16:52:45 +08:00
#include<hgl/graph/VKDevice.h>
#include<hgl/graph/VKRenderable.h>
#include<hgl/graph/VKCommandBuffer.h>
#include<hgl/graph/VertexAttribDataAccess.h>
#include<hgl/graph/VKMaterialInstance.h>
#include<hgl/graph/VKRenderableInstance.h>
2019-05-25 00:50:04 +08:00
2019-05-21 21:28:33 +08:00
namespace hgl
{
namespace graph
{
/**
* MVP矩阵
*/
struct MVPMatrix
2020-12-18 16:52:45 +08:00
{
Matrix4f l2w; ///< Local to World
Matrix4f inverse_l2w;
2020-12-18 16:52:45 +08:00
Matrix4f mvp; ///< projection * view * local_to_world
Matrix4f inverse_mvp;
2020-12-18 16:52:45 +08:00
public:
void Set(const Matrix4f &w,const Matrix4f &vp)
2020-12-18 16:52:45 +08:00
{
l2w=w;
inverse_l2w=l2w.Inverted();
2020-12-18 16:52:45 +08:00
mvp=vp*l2w;
inverse_mvp=mvp.Inverted();
2020-12-18 16:52:45 +08:00
}
};//struct MVPMatrix
constexpr size_t MVPMatrixBytes=sizeof(MVPMatrix);
2020-12-18 16:52:45 +08:00
2019-05-24 21:43:59 +08:00
float CameraLengthComp(Camera *cam,SceneNode *obj_one,SceneNode *obj_two)
2019-05-21 21:28:33 +08:00
{
if(!cam||!obj_one||!obj_two)
return(0);
2020-11-17 17:20:59 +08:00
return( length_squared(obj_one->GetCenter(),cam->pos)-
length_squared(obj_two->GetCenter(),cam->pos));
2019-05-21 21:28:33 +08:00
}
2019-05-24 21:43:59 +08:00
//bool FrustumClipFilter(const SceneNode *node,void *fc)
//{
// if(!node||!fc)return(false);
2019-05-21 21:28:33 +08:00
2019-05-24 21:43:59 +08:00
// return (((Frustum *)fc)->BoxIn(node->GetWorldBoundingBox())!=Frustum::OUTSIDE);
//}
2019-05-21 21:28:33 +08:00
2020-12-18 16:52:45 +08:00
RenderList::RenderList(GPUDevice *gd)
{
2020-12-18 16:52:45 +08:00
device =gd;
cmd_buf =nullptr;
last_pipeline =nullptr;
last_ri =nullptr;
2020-12-18 16:52:45 +08:00
mvp_array=new MVPArray;
2020-12-18 16:52:45 +08:00
}
RenderList::~RenderList()
{
delete mvp_array;
}
void RenderList::Begin()
{
scene_node_list.ClearData();
last_pipeline =nullptr;
last_ri =nullptr;
}
void RenderList::Add(SceneNode *node)
{
if(!node)return;
scene_node_list.Add(node);
}
void RenderList::End(CameraMatrix *camera_matrix)
{
2020-12-18 16:52:45 +08:00
//清0计数器
uint32_t mvp_count=0; //local to world矩阵总数量
2020-12-18 16:52:45 +08:00
//统计Render
const uint32_t count=scene_node_list.GetCount();
mvp_array->Init(count);
2020-12-18 16:52:45 +08:00
MVPMatrix *mp=mvp_array->items.GetData();
uint32_t *op=mvp_array->offset.GetData();
2020-12-18 16:52:45 +08:00
for(SceneNode *node:scene_node_list)
{
const Matrix4f &l2w=node->GetLocalToWorldMatrix();
2020-12-18 16:52:45 +08:00
if(!l2w.IsIdentity())
2020-12-18 16:52:45 +08:00
{
mp->Set(l2w,camera_matrix->vp);
2020-12-18 16:52:45 +08:00
++mp;
*op=(mvp_count)*MVPMatrixBytes;
++mvp_count;
2020-12-18 16:52:45 +08:00
}
else
{
*op=mvp_count;
2020-12-18 16:52:45 +08:00
}
++op;
}
2020-12-18 16:52:45 +08:00
if(mvp_array->buffer)
2020-12-18 16:52:45 +08:00
{
if(mvp_array->alloc_count<mvp_count)
2020-12-18 16:52:45 +08:00
{
mvp_array->buffer->Unmap();
delete mvp_array->buffer;
mvp_array->buffer=nullptr;
// mvp_array->buffer_address=nullptr; //下面一定会重写,所以这一行没必要操作
2020-12-18 16:52:45 +08:00
}
}
if(!mvp_array->buffer)
2020-12-18 16:52:45 +08:00
{
mvp_array->alloc_count=power_to_2(mvp_count);
mvp_array->buffer=device->CreateUBO(mvp_array->alloc_count*MVPMatrixBytes);
mvp_array->buffer_address=(MVPMatrix *)(mvp_array->buffer->Map());
2020-12-18 16:52:45 +08:00
}
hgl_cpy(mvp_array->buffer_address,mvp_array->items.GetData(),mvp_count);
}
2020-10-21 12:47:06 +08:00
void RenderList::Render(SceneNode *node,RenderableInstance *ri)
2019-05-21 21:28:33 +08:00
{
2019-05-25 00:50:04 +08:00
if(last_pipeline!=ri->GetPipeline())
{
last_pipeline=ri->GetPipeline();
cmd_buf->BindPipeline(last_pipeline);
2019-05-25 00:50:04 +08:00
}
2019-05-25 00:50:04 +08:00
{
2020-12-18 16:52:45 +08:00
MaterialInstance *mi=ri->GetMaterialInstance();
2020-12-18 16:52:45 +08:00
cmd_buf->BindDescriptorSets(mi->GetDescriptorSets());
}
2019-05-25 00:50:04 +08:00
//更新fin_mvp
if(ri!=last_ri)
2019-05-25 00:50:04 +08:00
{
cmd_buf->BindVAB(ri);
2019-05-25 00:50:04 +08:00
last_ri=ri;
2019-05-25 00:50:04 +08:00
}
2020-10-21 12:47:06 +08:00
const IndexBuffer *ib=ri->GetIndexBuffer();
2019-05-25 00:50:04 +08:00
if(ib)
{
cmd_buf->DrawIndexed(ib->GetCount());
}
else
{
cmd_buf->Draw(ri->GetDrawCount());
2019-05-25 00:50:04 +08:00
}
}
2020-10-21 12:47:06 +08:00
void RenderList::Render(SceneNode *node,List<RenderableInstance *> &ri_list)
2019-05-25 00:50:04 +08:00
{
const int count=ri_list.GetCount();
2020-10-21 12:47:06 +08:00
RenderableInstance **ri=ri_list.GetData();
for(int i=0;i<count;i++)
{
Render(node,*ri);
++ri;
}
}
bool RenderList::Render(RenderCmdBuffer *cb)
{
if(!cb)
2019-05-21 21:28:33 +08:00
return(false);
cmd_buf=cb;
2019-05-25 00:50:04 +08:00
last_pipeline=nullptr;
last_ri=nullptr;
2019-05-25 00:50:04 +08:00
const int count=scene_node_list.GetCount();
SceneNode **node=scene_node_list.GetData();
2019-05-21 21:28:33 +08:00
for(int i=0;i<count;i++)
{
Render(*node,(*node)->renderable_instances);
++node;
2019-05-21 21:28:33 +08:00
}
return(true);
}
}//namespace graph
}//namespace hgl