added WriteMaterialInstance in RenderExtraBuffer

This commit is contained in:
HuYingzhuo(hugo/hyzboy) 2023-06-01 21:25:50 +08:00
parent e076b72f1a
commit f8fe0e46d6
4 changed files with 90 additions and 34 deletions

View File

@ -2,7 +2,7 @@
#include<hgl/graph/RenderNode.h>
VK_NAMESPACE_BEGIN
struct RenderNodeExtraBuffer;
struct RenderExtraBuffer;
/**
*
@ -18,7 +18,7 @@ class MaterialRenderList
private:
RenderNodeExtraBuffer *extra_buffer;
RenderExtraBuffer *extra_buffer;
struct RenderItem
{
@ -34,7 +34,7 @@ private:
void Set(Renderable *);
};
SortedSets<MaterialInstance *> mi_set;
MaterialInstanceSets mi_set;
List<RenderItem> ri_list;
uint ri_count;

View File

@ -2,12 +2,14 @@
#define HGL_GRAPH_RENDER_NODE_INCLUDE
#include<hgl/graph/VK.h>
#include<hgl/type/SortedSets.h>
namespace hgl
{
namespace graph
{
class Renderable;
class Material;
class MaterialInstance;
class GPUDevice;
struct VertexInputData;
struct IndexBufferData;
@ -20,6 +22,8 @@ namespace hgl
};
using RenderNodeList=List<RenderNode>;
using MaterialInstanceSets=SortedSets<MaterialInstance *>;
}//namespace graph
}//namespace hgl
#endif//HGL_GRAPH_RENDER_NODE_INCLUDE

View File

@ -96,23 +96,28 @@ void MaterialRenderList::End()
Sort(rn_list,&rnc);
}
//写入LocalToWorld数据
{
uint count=rn_list.GetCount();
const uint node_count=rn_list.GetCount();
if(count<=0)return;
if(node_count<=0)return;
if(!extra_buffer)
extra_buffer=new RenderNodeExtraBuffer;
extra_buffer=new RenderExtraBuffer;
if(extra_buffer->node_count<count)
extra_buffer->NodeAlloc(device,count);
//写入数据
extra_buffer->WriteData(rn_list.GetData(),count);
}
if(extra_buffer->node_count<node_count)
extra_buffer->NodeAlloc(device,node_count);
Stat();
//写入LocalToWorld数据
extra_buffer->WriteLocalToWorld(rn_list.GetData(),node_count);
const uint mi_count=mi_set.GetCount();
if(mi_count<=0)return;
if(extra_buffer->mi_count<mi_count)
extra_buffer->MIAlloc(device,mi_count,);
extra_buffer->WriteMaterialInstance(rn_list.GetData(),node_count,mi_set);
}
void MaterialRenderList::RenderItem::Set(Renderable *ri)
@ -181,7 +186,7 @@ void MaterialRenderList::Bind(MaterialInstance *mi)
{
}
bool MaterialRenderList::Bind(const VertexInputData *vid,const uint first)
bool MaterialRenderList::Bind(const VertexInputData *vid,const uint ri_index)
{
//binding号都是在VertexInput::CreateVIL时连续紧密排列生成的所以bind时first_binding写0就行了。
@ -253,7 +258,7 @@ bool MaterialRenderList::Bind(const VertexInputData *vid,const uint first)
hgl_cpy(buffer_list+count,extra_buffer->l2w_buffer,4);
for(uint i=0;i<4;i++)
buffer_offset[count+i]=first*16; //mat4每列都是rgba32f自然是16字节
buffer_offset[count+i]=ri_index*16; //mat4每列都是rgba32f自然是16字节
count+=l2w_binding_count;
}

View File

@ -4,7 +4,7 @@
VK_NAMESPACE_BEGIN
// ubo_range大致分为三档:
//
// 16k: Mali-T系列或更早、Mali-G71、nVidia GeForce RTX 3070 Laptop为16k
// 16k: Mali-T系列或更早、Mali-G71为16k
//
// 64k: 大部分手机与PC均为64k
//
@ -24,7 +24,7 @@ VK_NAMESPACE_BEGIN
/*
*
*/
struct RenderNodeExtraBuffer
struct RenderExtraBuffer
{
uint node_count; ///<渲染节点数量
uint mi_count; ///<材质实例数量
@ -35,32 +35,26 @@ struct RenderNodeExtraBuffer
VBO *mi_id;
VkBuffer mi_id_buffer;
VBO *bone_id,*bone_weight;
VkBuffer bone_id_buffer,bone_weight_buffer;
// VBO *bone_id,*bone_weight;
// VkBuffer bone_id_buffer,bone_weight_buffer;
VBO *l2w_vbo[4];
VkBuffer l2w_buffer[4];
public:
RenderNodeExtraBuffer()
RenderExtraBuffer()
{
hgl_zero(*this);
}
~RenderNodeExtraBuffer()
~RenderExtraBuffer()
{
Clear();
}
void Clear()
void ClearNode()
{
SAFE_CLEAR(mi_id)
SAFE_CLEAR(mi_data_buffer);
SAFE_CLEAR(bone_id)
SAFE_CLEAR(bone_weight)
SAFE_CLEAR(l2w_vbo[0])
SAFE_CLEAR(l2w_vbo[1])
SAFE_CLEAR(l2w_vbo[2])
@ -68,9 +62,26 @@ public:
node_count=0;
}
void ClearMI()
{
SAFE_CLEAR(mi_id)
SAFE_CLEAR(mi_data_buffer);
mi_count=0;
mi_size=0;
}
void Clear()
{
ClearNode();
ClearMI();
// SAFE_CLEAR(bone_id)
// SAFE_CLEAR(bone_weight)
}
void NodeAlloc(GPUDevice *dev,const uint c)
{
Clear();
ClearNode();
node_count=power_to_2(c);
for(uint i=0;i<4;i++)
@ -80,11 +91,13 @@ public:
}
}
void MIAlloc(GPUDevice *dev,const uint c)
void MIAlloc(GPUDevice *dev,const uint c,const uint mis)
{
ClearMI();
if(c<=0||mi_size<=0)return;
mi_count=power_to_2(c);
mi_size=mis;
mi_id=dev->CreateVBO(VF_V1U8,mi_count);
mi_id_buffer=mi_id->GetBuffer();
@ -92,7 +105,7 @@ public:
mi_data_buffer=dev->CreateUBO(mi_count*mi_size);
}
void WriteData(RenderNode *render_node,const uint count)
void WriteLocalToWorld(RenderNode *render_node,const uint count)
{
RenderNode *rn;
glm::vec4 *tp;
@ -113,5 +126,39 @@ public:
l2w_vbo[col]->Unmap();
}
}
};//struct RenderNodeExtraBuffer
void WriteMaterialInstance(RenderNode *render_node,const uint count,const MaterialInstanceSets &mi_set)
{
//MaterialInstance ID
{
uint8 *tp=(uint8 *)(mi_id->Map());
for(uint i=0;i<count;i++)
{
*tp=mi_set.Find(render_node->ri->GetMaterialInstance());
++tp;
++render_node;
}
mi_id->Unmap();
}
//MaterialInstance Data
{
const uint count=mi_set.GetCount();
uint8 *tp=(uint8 *)(mi_data_buffer->Map());
const MaterialInstance **mi=mi_set.GetData();
for(uint i=0;i<count;i++)
{
memcpy(tp,(*mi)->GetData(),mi_size);
++mi;
tp+=mi_size;
}
mi_data_buffer->Unmap();
}
}
};//struct RenderExtraBuffer
VK_NAMESPACE_END