diff --git a/inc/hgl/graph/MaterialRenderList.h b/inc/hgl/graph/MaterialRenderList.h new file mode 100644 index 00000000..0d92a5d4 --- /dev/null +++ b/inc/hgl/graph/MaterialRenderList.h @@ -0,0 +1,75 @@ +#pragma once +#include + +VK_NAMESPACE_BEGIN +struct RenderNodeExtraBuffer; + +/** +* 同一材质的对象渲染列表 +*/ +class MaterialRenderList +{ + GPUDevice *device; + RenderCmdBuffer *cmd_buf; + + Material *mtl; + + RenderNodeList rn_list; + +private: + + RenderNodeExtraBuffer *extra_buffer; + + struct RenderItem + { + uint32_t first; + uint32_t count; + + Pipeline * pipeline; + MaterialInstance * mi; + const VertexInputData * vid; + + public: + + void Set(Renderable *); + }; + + SortedSets mi_set; + List ri_list; + uint ri_count; + + void Stat(); + +protected: + + uint32_t binding_count; + VkBuffer *buffer_list; + VkDeviceSize *buffer_offset; + + MaterialInstance * last_mi; + Pipeline * last_pipeline; + const VertexInputData * last_vid; + uint last_index; + + void Bind(MaterialInstance *); + bool Bind(const VertexInputData *,const uint); + + void Render(RenderItem *); + +public: + + MaterialRenderList(GPUDevice *d,Material *m); + ~MaterialRenderList(); + + void Add(Renderable *ri,const Matrix4f &mat); + + void ClearData() + { + rn_list.ClearData(); + } + + void End(); + + void Render(RenderCmdBuffer *); +};//class MaterialRenderList +VK_NAMESPACE_END diff --git a/inc/hgl/graph/MaterialRenderMap.h b/inc/hgl/graph/MaterialRenderMap.h new file mode 100644 index 00000000..c274cc03 --- /dev/null +++ b/inc/hgl/graph/MaterialRenderMap.h @@ -0,0 +1,32 @@ +#pragma once +#include + +VK_NAMESPACE_BEGIN +class MaterialRenderMap:public ObjectMap +{ +public: + + MaterialRenderMap()=default; + virtual ~MaterialRenderMap()=default; + + void Begin() + { + for(auto *it:data_list) + it->value->ClearData(); + } + + void End() + { + for(auto *it:data_list) + it->value->End(); + } + + void Render(RenderCmdBuffer *rcb) + { + if(!rcb)return; + + for(auto *it:data_list) + it->value->Render(rcb); + } +};//class MaterialRenderMap +VK_NAMESPACE_END diff --git a/inc/hgl/graph/RenderList.h b/inc/hgl/graph/RenderList.h index 3e2f8cf7..9d9dcaf2 100644 --- a/inc/hgl/graph/RenderList.h +++ b/inc/hgl/graph/RenderList.h @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include namespace hgl diff --git a/inc/hgl/graph/RenderNode.h b/inc/hgl/graph/RenderNode.h index 11406128..143705d9 100644 --- a/inc/hgl/graph/RenderNode.h +++ b/inc/hgl/graph/RenderNode.h @@ -1,9 +1,6 @@ 锘#ifndef HGL_GRAPH_RENDER_NODE_INCLUDE #define HGL_GRAPH_RENDER_NODE_INCLUDE -#include -#include -#include #include namespace hgl { @@ -23,105 +20,6 @@ namespace hgl }; using RenderNodeList=List; - - struct RenderNodeExtraBuffer; - - /** - * 鍚屼竴鏉愯川鐨勫璞℃覆鏌撳垪琛 - */ - class MaterialRenderList - { - GPUDevice *device; - RenderCmdBuffer *cmd_buf; - - Material *mtl; - - RenderNodeList rn_list; - - private: - - RenderNodeExtraBuffer *extra_buffer; - - struct RenderItem - { - uint32_t first; - uint32_t count; - - Pipeline * pipeline; - MaterialInstance * mi; - const VertexInputData * vid; - - public: - - void Set(Renderable *); - }; - - SortedSets mi_set; - List ri_list; - uint ri_count; - - void Stat(); - - protected: - - uint32_t binding_count; - VkBuffer *buffer_list; - VkDeviceSize *buffer_offset; - - MaterialInstance * last_mi; - Pipeline * last_pipeline; - const VertexInputData * last_vid; - uint last_index; - - void Bind(MaterialInstance *); - bool Bind(const VertexInputData *,const uint); - - void Render(RenderItem *); - - public: - - MaterialRenderList(GPUDevice *d,Material *m); - ~MaterialRenderList(); - - void Add(Renderable *ri,const Matrix4f &mat); - - void ClearData() - { - rn_list.ClearData(); - } - - void End(); - - void Render(RenderCmdBuffer *); - }; - - class MaterialRenderMap:public ObjectMap - { - public: - - MaterialRenderMap()=default; - virtual ~MaterialRenderMap()=default; - - void Begin() - { - for(auto *it:data_list) - it->value->ClearData(); - } - - void End() - { - for(auto *it:data_list) - it->value->End(); - } - - void Render(RenderCmdBuffer *rcb) - { - if(!rcb)return; - - for(auto *it:data_list) - it->value->Render(rcb); - } - }; }//namespace graph }//namespace hgl #endif//HGL_GRAPH_RENDER_NODE_INCLUDE diff --git a/src/SceneGraph/CMakeLists.txt b/src/SceneGraph/CMakeLists.txt index 0d78cd61..7e30838f 100644 --- a/src/SceneGraph/CMakeLists.txt +++ b/src/SceneGraph/CMakeLists.txt @@ -38,11 +38,13 @@ SET(SCENE_GRAPH_HEADER ${SG_INCLUDE_PATH}/SceneInfo.h ${SG_INCLUDE_PATH}/RenderNode.h ${SG_INCLUDE_PATH}/SceneOrient.h ${SG_INCLUDE_PATH}/RenderList.h + ${SG_INCLUDE_PATH}/MaterialRenderList.h + ${SG_INCLUDE_PATH}/MaterialRenderMap.h ) -SET(SCENE_GRAPH_SOURCE - RenderList.cpp - RenderNode.cpp +SET(SCENE_GRAPH_SOURCE RenderList.cpp + MaterialRenderList.cpp + RenderExtraBuffer.h SceneNode.cpp SceneOrient.cpp) diff --git a/src/SceneGraph/MaterialRenderList.cpp b/src/SceneGraph/MaterialRenderList.cpp new file mode 100644 index 00000000..ba49f66a --- /dev/null +++ b/src/SceneGraph/MaterialRenderList.cpp @@ -0,0 +1,338 @@ +锘#include +#include +#include +#include +#include +#include +#include"RenderExtraBuffer.h" + +/** +* +* 鐞嗚涓婅锛屾垜浠渶瑕佹寜浠ヤ笅椤哄簭鎺掑簭 +* +* for(material) +* for(pipeline) +* for(material_instance) +* for(vbo) +*/ + +template<> +int Comparator::compare(const hgl::graph::RenderNode &obj_one,const hgl::graph::RenderNode &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; + } + + //姣旇緝鏉愯川瀹炰緥 + { + off=ri_one->GetMaterialInstance() + -ri_two->GetMaterialInstance(); + + if(off) + return off; + } + + //姣旇緝妯″瀷 + { + off=ri_one->GetPrimitive() + -ri_two->GetPrimitive(); + + if(off) + return off; + } + + return 0; +} + +VK_NAMESPACE_BEGIN +MaterialRenderList::MaterialRenderList(GPUDevice *d,Material *m) +{ + device=d; + cmd_buf=nullptr; + mtl=m; + extra_buffer=nullptr; + + const VertexInput *vi=mtl->GetVertexInput(); + + binding_count=vi->GetCount(); + buffer_list=new VkBuffer[binding_count]; + buffer_offset=new VkDeviceSize[binding_count]; +} + +MaterialRenderList::~MaterialRenderList() +{ + delete[] buffer_offset; + delete[] buffer_list; + + SAFE_CLEAR(extra_buffer) +} + +void MaterialRenderList::Add(Renderable *ri,const Matrix4f &mat) +{ + RenderNode rn; + + rn.local_to_world=mat; + rn.ri=ri; + + rn_list.Add(rn); +} + +void MaterialRenderList::End() +{ + //鎺掑簭 + { + Comparator rnc; + + Sort(rn_list,&rnc); + } + + //鍐欏叆LocalToWorld鏁版嵁 + { + uint count=rn_list.GetCount(); + + if(count<=0)return; + + if(!extra_buffer) + extra_buffer=new RenderNodeExtraBuffer; + + if(extra_buffer->node_countNodeAlloc(device,count); + + //鍐欏叆鏁版嵁 + extra_buffer->WriteData(rn_list.GetData(),count); + } + + Stat(); +} + +void MaterialRenderList::RenderItem::Set(Renderable *ri) +{ + pipeline =ri->GetPipeline(); + mi =ri->GetMaterialInstance(); + vid =ri->GetVertexInputData(); +} + +void MaterialRenderList::Stat() +{ + const uint count=rn_list.GetCount(); + RenderNode *rn=rn_list.GetData(); + + ri_list.ClearData(); + ri_list.PreMalloc(count); + + mi_set.ClearData(); + + RenderItem *ri=ri_list.GetData(); + + ri_count=1; + + ri->first=0; + ri->count=1; + ri->Set(rn->ri); + + last_pipeline =ri->pipeline; + last_mi =ri->mi; + last_vid =ri->vid; + + mi_set.Add(last_mi); + + ++rn; + + for(uint i=1;iri->GetPipeline()) + if(last_mi==rn->ri->GetMaterialInstance()) + if(last_vid==rn->ri->GetVertexInputData()) + { + ++ri->count; + ++rn; + continue; + } + + ++ri_count; + ++ri; + + ri->first=i; + ri->count=1; + ri->Set(rn->ri); + + if(last_mi!=ri->mi) + mi_set.Add(ri->mi); + + last_pipeline =ri->pipeline; + last_mi =ri->mi; + last_vid =ri->vid; + + ++rn; + } +} + +void MaterialRenderList::Bind(MaterialInstance *mi) +{ +} + +bool MaterialRenderList::Bind(const VertexInputData *vid,const uint first) +{ + //binding鍙烽兘鏄湪VertexInput::CreateVIL鏃惰繛缁揣瀵嗘帓鍒楃敓鎴愮殑锛屾墍浠ind鏃秄irst_binding鍐0灏辫浜嗐 + + const VIL *vil=last_mi->GetVIL(); + + if(vil->GetCount(VertexInputGroup::Basic)!=vid->binding_count) + return(false); //杩欓噷鍩烘湰涓嶅お鍙兘锛屽洜涓篊reateRenderable鏃跺氨浼氭鏌ュ兼槸鍚︿竴鏍 + + uint count=0; + + //Basic缁勶紝瀹冩墍鏈夌殑VBO淇℃伅鍧囨潵鑷簬Primitive锛岀敱vid鍙傛暟浼犻掕繘鏉 + { + hgl_cpy(buffer_list,vid->buffer_list,vid->binding_count); + hgl_cpy(buffer_offset,vid->buffer_offset,vid->binding_count); + + count=vid->binding_count; + } + + if(countGetCount(VertexInputGroup::MaterialInstanceID); + + if(mtl_binding_count>0) + { + if(mtl_binding_count!=1) //鍙湁MaterialInstanceID + return(false); + + count+=mtl_binding_count; + } + } + + if(countGetCount(VertexInputGroup::JointID); + + if(joint_id_binding_count>0) //鏈夌煩闃典俊鎭 + { + count+=joint_id_binding_count; + + if(countGetCount(VertexInputGroup::JointWeight); + + if(joing_weight_binding_count!=1) + { + ++count; + } + else //JointWieght涓嶄负1鏄釜bug锛岄櫎闈炴湭鏉ユ敮鎸8鏉冮噸 + { + return(false); + } + } + else //鏈塉ointID娌℃湁JointWeight? 杩欐槸涓狟UG + { + return(false); + } + } + } + + if(countGetCount(VertexInputGroup::LocalToWorld); + + if(l2w_binding_count>0) //鏈夊彉鎹㈢煩闃典俊鎭 + { + if(l2w_binding_count!=4) + return(false); + + 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瀛楄妭 + + count+=l2w_binding_count; + } + } + + if(count!=binding_count) + { + //杩樻湁娌℃敮鎸佺殑缁戝畾缁勶紵锛燂紵锛 + + return(false); + } + + cmd_buf->BindVBO(0,count,buffer_list,buffer_offset); + + return(true); +} + +void MaterialRenderList::Render(RenderItem *ri) +{ + if(last_pipeline!=ri->pipeline) + { + cmd_buf->BindPipeline(ri->pipeline); + last_pipeline=ri->pipeline; + + last_mi=nullptr; + last_vid=nullptr; + + //杩欓噷鏈潵灏濊瘯鎹ipeline鍚屾椂涓嶆崲mi/primitive鏄惁闇瑕侀噸鏂扮粦瀹歮i/primitive + } + + if(last_mi!=ri->mi) + { + Bind(ri->mi); + last_mi=ri->mi; + + last_vid=nullptr; + } + + if(!ri->vid->Comp(last_vid)) + { + Bind(ri->vid,ri->first); + last_vid=ri->vid; + } + + const IndexBufferData *ibd=last_vid->index_buffer; + + if(ibd->buffer) + { + cmd_buf->BindIBO(ibd); + + cmd_buf->DrawIndexed(ibd->buffer->GetCount(),ri->count); + } + else + { + cmd_buf->Draw(last_vid->vertex_count,ri->count); + } +} + +void MaterialRenderList::Render(RenderCmdBuffer *rcb) +{ + if(!rcb)return; + const uint count=rn_list.GetCount(); + + if(count<=0)return; + + if(ri_count<=0)return; + + cmd_buf=rcb; + + RenderItem *ri=ri_list.GetData(); + + last_pipeline =nullptr; + last_mi =nullptr; + last_vid =nullptr; + + for(uint i=0;i + +VK_NAMESPACE_BEGIN +// ubo_range澶ц嚧鍒嗕负涓夋。: +// +// 16k: Mali-T绯诲垪鎴栨洿鏃┿丮ali-G71銆乶Vidia GeForce RTX 3070 Laptop涓16k +// +// 64k: 澶ч儴鍒嗘墜鏈轰笌PC鍧囦负64k +// +// >64k: Intel 鏍告樉涓 PowerVR 涓128MB锛孉MD鏄惧崱涓4GB锛屽彲瑙嗕负闅忔樉瀛樻棤涓婇檺銆 +// +// 鎴戜滑浣跨敤uint8绫诲瀷鍦╲ertex input涓繚瀛楳aterialInstance ID锛岃〃绀鸿寖鍥0-255銆 +// 鎵浠aterialInstance缁撴瀯瀹归噺鎸16k/64k鍒嗕负涓や釜妗f锛64瀛楄妭鍜256瀛楄妭 + +// 濡傛灉涓瀹氳浣跨敤瓒呰繃16K/64K纭欢闄愬埗鐨勫閲忥紝鏈変袱绉嶅姙娉 +// 涓銆佸垎澶氭娓叉煋锛屼娇鐢║BO Offset鍋忕ЩUBO鏁版嵁鍖恒 +// 浜屻佷娇鐢⊿SBO锛屼絾杩欐牱浼氬鑷存ц兘涓嬮檷锛屾墍浠ヤ笉鎺ㄨ崘浣跨敤銆 + +// 浣嗘垜浠笉瑙e喅杩欎釜闂 +// 鎴戜滑澶╃劧瑕佹眰灏嗘潗璐ㄥ疄渚嬫暟鎹垎涓轰袱涓瓑绾э紝鍚屾椂瑕佹眰涓娆℃覆鏌撲笉鑳借秴杩256绉嶆潗璐ㄥ疄渚嬨 +// 鎵浠 UBO Range涓16k鏃讹紝瀹炰緥鏁版嵁涓嶈兘瓒呰繃64瀛楄妭銆俇BO Range涓64k鏃讹紝瀹炰緥鏁版嵁涓嶈兘瓒呰繃256瀛楄妭銆 + +/* +* 娓叉煋鑺傜偣棰濆鎻愪緵鐨勬暟鎹 +*/ +struct RenderNodeExtraBuffer +{ + uint node_count; ///<娓叉煋鑺傜偣鏁伴噺 + uint mi_count; ///<鏉愯川瀹炰緥鏁伴噺 + + uint mi_size; ///<鍗曚釜鏉愯川瀹炰緥鏁伴噺闀垮害 + DeviceBuffer *mi_data_buffer; ///<鏉愯川瀹炰緥鏁版嵁UBO/SSBO + + VBO *mi_id; + VkBuffer mi_id_buffer; + + VBO *bone_id,*bone_weight; + VkBuffer bone_id_buffer,bone_weight_buffer; + + VBO *l2w_vbo[4]; + VkBuffer l2w_buffer[4]; + +public: + + RenderNodeExtraBuffer() + { + hgl_zero(*this); + } + + ~RenderNodeExtraBuffer() + { + Clear(); + } + + void Clear() + { + 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]) + SAFE_CLEAR(l2w_vbo[3]) + node_count=0; + } + + void NodeAlloc(GPUDevice *dev,const uint c) + { + Clear(); + node_count=power_to_2(c); + + for(uint i=0;i<4;i++) + { + l2w_vbo[i]=dev->CreateVBO(VF_V4F,node_count); + l2w_buffer[i]=l2w_vbo[i]->GetBuffer(); + } + } + + void MIAlloc(GPUDevice *dev,const uint c) + { + if(c<=0||mi_size<=0)return; + + mi_count=power_to_2(c); + + mi_id=dev->CreateVBO(VF_V1U8,mi_count); + mi_id_buffer=mi_id->GetBuffer(); + + mi_data_buffer=dev->CreateUBO(mi_count*mi_size); + } + + void WriteData(RenderNode *render_node,const uint count) + { + RenderNode *rn; + glm::vec4 *tp; + + for(uint col=0;col<4;col++) + { + tp=(glm::vec4 *)(l2w_vbo[col]->Map()); + + rn=render_node; + + for(uint i=0;ilocal_to_world[col]; + ++tp; + ++rn; + } + + l2w_vbo[col]->Unmap(); + } + } +};//struct RenderNodeExtraBuffer +VK_NAMESPACE_END diff --git a/src/SceneGraph/RenderNode.cpp b/src/SceneGraph/RenderNode.cpp deleted file mode 100644 index 07ccbe1c..00000000 --- a/src/SceneGraph/RenderNode.cpp +++ /dev/null @@ -1,455 +0,0 @@ -锘#include -#include -#include -#include -#include -#include -#include - -/** -* -* 鐞嗚涓婅锛屾垜浠渶瑕佹寜浠ヤ笅椤哄簭鎺掑簭 -* -* for(material) -* for(pipeline) -* for(material_instance) -* for(vbo) -*/ - -template<> -int Comparator::compare(const hgl::graph::RenderNode &obj_one,const hgl::graph::RenderNode &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; - } - - //姣旇緝鏉愯川瀹炰緥 - { - off=ri_one->GetMaterialInstance() - -ri_two->GetMaterialInstance(); - - if(off) - return off; - } - - //姣旇緝妯″瀷 - { - off=ri_one->GetPrimitive() - -ri_two->GetPrimitive(); - - if(off) - return off; - } - - return 0; -} - -namespace hgl -{ - namespace graph - { - // ubo_range澶ц嚧鍒嗕负涓夋。: - // - // 16k: Mali-T绯诲垪鎴栨洿鏃┿丮ali-G71銆乶Vidia GeForce RTX 3070 Laptop涓16k - // - // 64k: 澶ч儴鍒嗘墜鏈轰笌PC鍧囦负64k - // - // >64k: Intel 鏍告樉涓 PowerVR 涓128MB锛孉MD鏄惧崱涓4GB锛屽彲瑙嗕负闅忔樉瀛樻棤涓婇檺銆 - // - // 鎴戜滑浣跨敤uint8绫诲瀷鍦╲ertex input涓繚瀛楳aterialInstance ID锛岃〃绀鸿寖鍥0-255銆 - // 鎵浠aterialInstance缁撴瀯瀹归噺鎸16k/64k鍒嗕负涓や釜妗f锛64瀛楄妭鍜256瀛楄妭 - - // 濡傛灉涓瀹氳浣跨敤瓒呰繃16K/64K纭欢闄愬埗鐨勫閲忥紝鏈変袱绉嶅姙娉 - // 涓銆佸垎澶氭娓叉煋锛屼娇鐢║BO Offset鍋忕ЩUBO鏁版嵁鍖恒 - // 浜屻佷娇鐢⊿SBO锛屼絾杩欐牱浼氬鑷存ц兘涓嬮檷锛屾墍浠ヤ笉鎺ㄨ崘浣跨敤銆 - - // 浣嗘垜浠笉瑙e喅杩欎釜闂 - // 鎴戜滑澶╃劧瑕佹眰灏嗘潗璐ㄥ疄渚嬫暟鎹垎涓轰袱涓瓑绾э紝鍚屾椂瑕佹眰涓娆℃覆鏌撲笉鑳借秴杩256绉嶆潗璐ㄥ疄渚嬨 - // 鎵浠 UBO Range涓16k鏃讹紝瀹炰緥鏁版嵁涓嶈兘瓒呰繃64瀛楄妭銆俇BO Range涓64k鏃讹紝瀹炰緥鏁版嵁涓嶈兘瓒呰繃256瀛楄妭銆 - - /* - * 娓叉煋鑺傜偣棰濆鎻愪緵鐨勬暟鎹 - */ - struct RenderNodeExtraBuffer - { - uint node_count; ///<娓叉煋鑺傜偣鏁伴噺 - uint mi_count; ///<鏉愯川瀹炰緥鏁伴噺 - - uint mi_size; ///<鍗曚釜鏉愯川瀹炰緥鏁伴噺闀垮害 - DeviceBuffer *mi_data_buffer; ///<鏉愯川瀹炰緥鏁版嵁UBO/SSBO - - VBO *mi_id; - VkBuffer mi_id_buffer; - - VBO *bone_id,*bone_weight; - VkBuffer bone_id_buffer,bone_weight_buffer; - - VBO *l2w_vbo[4]; - VkBuffer l2w_buffer[4]; - - public: - - RenderNodeExtraBuffer() - { - hgl_zero(*this); - } - - ~RenderNodeExtraBuffer() - { - Clear(); - } - - void Clear() - { - 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]) - SAFE_CLEAR(l2w_vbo[3]) - node_count=0; - } - - void NodeAlloc(GPUDevice *dev,const uint c) - { - Clear(); - node_count=power_to_2(c); - - for(uint i=0;i<4;i++) - { - l2w_vbo[i]=dev->CreateVBO(VF_V4F,node_count); - l2w_buffer[i]=l2w_vbo[i]->GetBuffer(); - } - } - - void MIAlloc(GPUDevice *dev,const uint c) - { - if(c<=0||mi_size<=0)return; - - mi_count=power_to_2(c); - - mi_id=dev->CreateVBO(VF_V1U8,mi_count); - mi_id_buffer=mi_id->GetBuffer(); - - mi_data_buffer=dev->CreateUBO(mi_count*mi_size); - } - - void WriteData(RenderNode *render_node,const uint count) - { - RenderNode *rn; - glm::vec4 *tp; - - for(uint col=0;col<4;col++) - { - tp=(glm::vec4 *)(l2w_vbo[col]->Map()); - - rn=render_node; - - for(uint i=0;ilocal_to_world[col]; - ++tp; - ++rn; - } - - l2w_vbo[col]->Unmap(); - } - } - };//struct RenderNodeExtraBuffer - - MaterialRenderList::MaterialRenderList(GPUDevice *d,Material *m) - { - device=d; - cmd_buf=nullptr; - mtl=m; - extra_buffer=nullptr; - - const VertexInput *vi=mtl->GetVertexInput(); - - binding_count=vi->GetCount(); - buffer_list=new VkBuffer[binding_count]; - buffer_offset=new VkDeviceSize[binding_count]; - } - - MaterialRenderList::~MaterialRenderList() - { - delete[] buffer_offset; - delete[] buffer_list; - - SAFE_CLEAR(extra_buffer) - } - - void MaterialRenderList::Add(Renderable *ri,const Matrix4f &mat) - { - RenderNode rn; - - rn.local_to_world=mat; - rn.ri=ri; - - rn_list.Add(rn); - } - - void MaterialRenderList::End() - { - //鎺掑簭 - { - Comparator rnc; - - Sort(rn_list,&rnc); - } - - //鍐欏叆LocalToWorld鏁版嵁 - { - uint count=rn_list.GetCount(); - - if(count<=0)return; - - if(!extra_buffer) - extra_buffer=new RenderNodeExtraBuffer; - - if(extra_buffer->node_countNodeAlloc(device,count); - - //鍐欏叆鏁版嵁 - extra_buffer->WriteData(rn_list.GetData(),count); - } - - Stat(); - } - - void MaterialRenderList::RenderItem::Set(Renderable *ri) - { - pipeline =ri->GetPipeline(); - mi =ri->GetMaterialInstance(); - vid =ri->GetVertexInputData(); - } - - void MaterialRenderList::Stat() - { - const uint count=rn_list.GetCount(); - RenderNode *rn=rn_list.GetData(); - - ri_list.ClearData(); - ri_list.PreMalloc(count); - - mi_set.ClearData(); - - RenderItem *ri=ri_list.GetData(); - - ri_count=1; - - ri->first=0; - ri->count=1; - ri->Set(rn->ri); - - last_pipeline =ri->pipeline; - last_mi =ri->mi; - last_vid =ri->vid; - - mi_set.Add(last_mi); - - ++rn; - - for(uint i=1;iri->GetPipeline()) - if(last_mi==rn->ri->GetMaterialInstance()) - if(last_vid==rn->ri->GetVertexInputData()) - { - ++ri->count; - ++rn; - continue; - } - - ++ri_count; - ++ri; - - ri->first=i; - ri->count=1; - ri->Set(rn->ri); - - if(last_mi!=ri->mi) - mi_set.Add(ri->mi); - - last_pipeline =ri->pipeline; - last_mi =ri->mi; - last_vid =ri->vid; - - ++rn; - } - } - - void MaterialRenderList::Bind(MaterialInstance *mi) - { - } - - bool MaterialRenderList::Bind(const VertexInputData *vid,const uint first) - { - //binding鍙烽兘鏄湪VertexInput::CreateVIL鏃惰繛缁揣瀵嗘帓鍒楃敓鎴愮殑锛屾墍浠ind鏃秄irst_binding鍐0灏辫浜嗐 - - const VIL *vil=last_mi->GetVIL(); - - if(vil->GetCount(VertexInputGroup::Basic)!=vid->binding_count) - return(false); //杩欓噷鍩烘湰涓嶅お鍙兘锛屽洜涓篊reateRenderable鏃跺氨浼氭鏌ュ兼槸鍚︿竴鏍 - - uint count=0; - - //Basic缁勶紝瀹冩墍鏈夌殑VBO淇℃伅鍧囨潵鑷簬Primitive锛岀敱vid鍙傛暟浼犻掕繘鏉 - { - hgl_cpy(buffer_list,vid->buffer_list,vid->binding_count); - hgl_cpy(buffer_offset,vid->buffer_offset,vid->binding_count); - - count=vid->binding_count; - } - - if(countGetCount(VertexInputGroup::MaterialInstanceID); - - if(mtl_binding_count>0) - { - if(mtl_binding_count!=1) //鍙湁MaterialInstanceID - return(false); - - count+=mtl_binding_count; - } - } - - if(countGetCount(VertexInputGroup::JointID); - - if(joint_id_binding_count>0) //鏈夌煩闃典俊鎭 - { - count+=joint_id_binding_count; - - if(countGetCount(VertexInputGroup::JointWeight); - - if(joing_weight_binding_count!=1) - { - ++count; - } - else //JointWieght涓嶄负1鏄釜bug锛岄櫎闈炴湭鏉ユ敮鎸8鏉冮噸 - { - return(false); - } - } - else //鏈塉ointID娌℃湁JointWeight? 杩欐槸涓狟UG - { - return(false); - } - } - } - - if(countGetCount(VertexInputGroup::LocalToWorld); - - if(l2w_binding_count>0) //鏈夊彉鎹㈢煩闃典俊鎭 - { - if(l2w_binding_count!=4) - return(false); - - 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瀛楄妭 - - count+=l2w_binding_count; - } - } - - if(count!=binding_count) - { - //杩樻湁娌℃敮鎸佺殑缁戝畾缁勶紵锛燂紵锛 - - return(false); - } - - cmd_buf->BindVBO(0,count,buffer_list,buffer_offset); - - return(true); - } - - void MaterialRenderList::Render(RenderItem *ri) - { - if(last_pipeline!=ri->pipeline) - { - cmd_buf->BindPipeline(ri->pipeline); - last_pipeline=ri->pipeline; - - last_mi=nullptr; - last_vid=nullptr; - - //杩欓噷鏈潵灏濊瘯鎹ipeline鍚屾椂涓嶆崲mi/primitive鏄惁闇瑕侀噸鏂扮粦瀹歮i/primitive - } - - if(last_mi!=ri->mi) - { - Bind(ri->mi); - last_mi=ri->mi; - - last_vid=nullptr; - } - - if(!ri->vid->Comp(last_vid)) - { - Bind(ri->vid,ri->first); - last_vid=ri->vid; - } - - const IndexBufferData *ibd=last_vid->index_buffer; - - if(ibd->buffer) - { - cmd_buf->BindIBO(ibd); - - cmd_buf->DrawIndexed(ibd->buffer->GetCount(),ri->count); - } - else - { - cmd_buf->Draw(last_vid->vertex_count,ri->count); - } - } - - void MaterialRenderList::Render(RenderCmdBuffer *rcb) - { - if(!rcb)return; - const uint count=rn_list.GetCount(); - - if(count<=0)return; - - if(ri_count<=0)return; - - cmd_buf=rcb; - - RenderItem *ri=ri_list.GetData(); - - last_pipeline =nullptr; - last_mi =nullptr; - last_vid =nullptr; - - for(uint i=0;i