diff --git a/inc/hgl/graph/MaterialRenderList.h b/inc/hgl/graph/MaterialRenderList.h index 0d92a5d4..6da221f3 100644 --- a/inc/hgl/graph/MaterialRenderList.h +++ b/inc/hgl/graph/MaterialRenderList.h @@ -2,7 +2,7 @@ #include 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 mi_set; + MaterialInstanceSets mi_set; List ri_list; uint ri_count; diff --git a/inc/hgl/graph/RenderNode.h b/inc/hgl/graph/RenderNode.h index 143705d9..9e42d2b7 100644 --- a/inc/hgl/graph/RenderNode.h +++ b/inc/hgl/graph/RenderNode.h @@ -2,12 +2,14 @@ #define HGL_GRAPH_RENDER_NODE_INCLUDE #include +#include 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; + + using MaterialInstanceSets=SortedSets; }//namespace graph }//namespace hgl #endif//HGL_GRAPH_RENDER_NODE_INCLUDE diff --git a/src/SceneGraph/MaterialRenderList.cpp b/src/SceneGraph/MaterialRenderList.cpp index ba49f66a..731c9d9e 100644 --- a/src/SceneGraph/MaterialRenderList.cpp +++ b/src/SceneGraph/MaterialRenderList.cpp @@ -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; + if(!extra_buffer) + extra_buffer=new RenderExtraBuffer; - if(extra_buffer->node_countNodeAlloc(device,count); - - //写入数据 - extra_buffer->WriteData(rn_list.GetData(),count); - } + if(extra_buffer->node_countNodeAlloc(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_countMIAlloc(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; } diff --git a/src/SceneGraph/RenderExtraBuffer.h b/src/SceneGraph/RenderExtraBuffer.h index 8673231c..408d138b 100644 --- a/src/SceneGraph/RenderExtraBuffer.h +++ b/src/SceneGraph/RenderExtraBuffer.h @@ -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;iri->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;iGetData(),mi_size); + + ++mi; + tp+=mi_size; + } + + mi_data_buffer->Unmap(); + } + } +};//struct RenderExtraBuffer VK_NAMESPACE_END