ULRE/src/SceneGraph/RenderList.cpp

298 lines
7.4 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>
#include<hgl/graph/VKBuffer.h>
2022-06-24 17:51:05 +08:00
#include<hgl/graph/VKPrimitive.h>
#include<hgl/graph/VKCommandBuffer.h>
#include<hgl/graph/VertexAttribDataAccess.h>
#include<hgl/graph/VKMaterialParameters.h>
#include<hgl/graph/VKRenderable.h>
#include<hgl/util/sort/Sort.h>
/**
*
*
* for(pipeline)
* for(material_instance)
* for(vbo)
* for(distance)
*/
template<>
2023-03-23 21:43:10 +08:00
int Comparator<RenderNode3DPointer>::compare(const RenderNode3DPointer &obj_one,const RenderNode3DPointer &obj_two) const
{
int off;
hgl::graph::Renderable *ri_one=obj_one->ri;
hgl::graph::Renderable *ri_two=obj_two->ri;
//比较管线
{
off=ri_one->GetPipeline()
-ri_two->GetPipeline();
if(off)
return off;
}
//比较材质实例
{
for(int i =(int)hgl::graph::DescriptorSetType::BEGIN_RANGE;
i<=(int)hgl::graph::DescriptorSetType::END_RANGE;
i++)
{
off=ri_one->GetMP((hgl::graph::DescriptorSetType)i)
-ri_two->GetMP((hgl::graph::DescriptorSetType)i);
if(off)
return off;
}
}
//比较vbo+ebo
{
off=ri_one->GetBufferHash()
-ri_two->GetBufferHash();
if(off)
return off;
}
//比较距离
{
const double dist=obj_one->distance_to_camera_square-
obj_two->distance_to_camera_square;
//由于距离差距可能会小于1但又返回int所以需要做如此处理
if(dist>0)return 1;else
if(dist<0)return -1;
}
return 0;
}
2019-05-25 00:50:04 +08:00
2019-05-21 21:28:33 +08:00
namespace hgl
{
namespace graph
{
RenderList::RenderList(GPUDevice *dev)
{
device =dev;
cmd_buf =nullptr;
ubo_offset =0;
ubo_align =0;
last_pipeline =nullptr;
2021-06-16 20:29:25 +08:00
hgl_zero(last_mp);
last_vbo =0;
}
RenderList::~RenderList()
{
2023-03-23 21:43:10 +08:00
}
bool RenderList::Begin()
{
render_node_list.ClearData();
ri_list.ClearData();
material_sets.ClearData();
return(true);
}
void RenderList::End()
{
if(render_node_list.GetCount()<=0)return;
//排序
Sort(render_node_list,&render_node_comparator);
//产生MVP矩阵UBO数据
{
const uint32_t count=render_node_list.GetCount();
{
//按当前总节点数量分配UBO
mvp_array->Alloc(count);
mvp_array->Clear();
ri_list.ClearData();
ri_list.SetCount(count);
}
{
ubo_align=mvp_array->GetAlignSize();
char *mp=(char *)(mvp_array->Map(0,count));
Renderable **ri=ri_list.GetData();
for(RenderNode *node:render_node_list) //未来可能要在Expend处考虑做去重
{
memcpy(mp,&(node->matrix),MVPMatrixBytes);
mp+=ubo_align;
(*ri)=node->ri;
++ri;
}
mvp_array->Flush(count);
}
}
//为所有的材质绑定
for(Material *mtl:material_sets)
{
MaterialParameters *mp=mtl->GetMP(DescriptorSetType::PerObject);
if(mp)
{
if(mp->BindUBO("r_scene_info",mvp_array->GetBuffer(),true))
mp->Update();
}
}
}
bool RenderList::Expend(SceneNode *sn)
{
if(!sn)return(false);
Renderable *ri=sn->GetRenderable();
if(ri)
{
RenderNode *rn=new RenderNode;
2022-01-11 10:41:18 +08:00
rn->matrix.Set(sn->GetLocalToWorldMatrix(),camera_info.vp,camera_info.view);
rn->WorldCenter=sn->GetWorldCenter();
rn->distance_to_camera_square=length_squared(rn->WorldCenter,camera_info.pos);
// rn->distance_to_camera=sqrtf(rn->distance_to_camera_square);
rn->ri=ri;
render_node_list.Add(rn);
material_sets.Add(ri->GetMaterial());
}
for(SceneNode *sub:sn->SubNode)
Expend(sub);
return(true);
}
bool RenderList::Expend(const CameraInfo &ci,SceneNode *sn)
{
if(!device|!sn)return(false);
camera_info=ci;
Begin();
Expend(sn);
End();
return(true);
}
void RenderList::Render(Renderable *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
{
uint32_t ds_count=0;
uint32_t first_set=0;
2021-06-16 20:29:25 +08:00
MaterialParameters *mp;
2023-02-22 21:59:35 +08:00
ENUM_CLASS_FOR(DescriptorSetType,int,i)
{
2023-02-22 21:59:35 +08:00
if(i==(int)DescriptorSetType::PerObject)continue;
mp=ri->GetMP((DescriptorSetType)i);
2021-06-16 20:29:25 +08:00
if(last_mp[i]!=mp)
2021-06-16 20:29:25 +08:00
{
last_mp[i]=mp;
2021-06-16 20:29:25 +08:00
if(mp)
{
ds_list[ds_count]=mp->GetVkDescriptorSet();
++ds_count;
}
}
else
{
if(mp)
++first_set;
}
}
2021-06-16 20:29:25 +08:00
{
mp=ri->GetMP(DescriptorSetType::PerObject);
2021-06-16 20:29:25 +08:00
if(mp)
{
ds_list[ds_count]=mp->GetVkDescriptorSet();
++ds_count;
2023-02-22 21:50:18 +08:00
cmd_buf->BindDescriptorSets(ri->GetPipelineLayout(),first_set,ds_list,ds_count,&ubo_offset,1);
}
else
2023-03-22 21:19:23 +08:00
{
cmd_buf->BindDescriptorSets(ri->GetPipelineLayout(),first_set,ds_list,ds_count,nullptr,0);
2021-06-16 20:29:25 +08:00
}
ubo_offset+=ubo_align;
}
}
2019-05-25 00:50:04 +08:00
if(last_vbo!=ri->GetBufferHash())
2019-05-25 00:50:04 +08:00
{
last_vbo=ri->GetBufferHash();
2021-12-15 14:24:35 +08:00
cmd_buf->BindVBO(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
}
}
bool RenderList::Render(RenderCmdBuffer *cb)
{
if(!cb)
2019-05-21 21:28:33 +08:00
return(false);
if(ri_list.GetCount()<=0)
return(true);
cmd_buf=cb;
2021-06-16 20:29:25 +08:00
last_pipeline=nullptr;
hgl_zero(last_mp);
last_vbo=0;
ubo_offset=0;
2019-05-25 00:50:04 +08:00
for(Renderable *ri:ri_list)
Render(ri);
2019-05-21 21:28:33 +08:00
return(true);
}
}//namespace graph
}//namespace hgl