From 72ceffeda2f52e0e3ce44147bc3d5974ceb0f09c Mon Sep 17 00:00:00 2001 From: hyzboy Date: Fri, 30 Aug 2024 03:36:01 +0800 Subject: [PATCH] Added UpdateMaterialInstance method. but no any test. --- inc/hgl/graph/MaterialRenderList.h | 1 + inc/hgl/graph/RenderList.h | 1 + inc/hgl/graph/RenderNode.h | 12 ++++++----- inc/hgl/graph/VKRenderable.h | 14 +++++++++++++ src/SceneGraph/MaterialRenderList.cpp | 30 +++++++++++++++++++++++++-- src/SceneGraph/RenderAssignBuffer.cpp | 12 +++++++++++ src/SceneGraph/RenderAssignBuffer.h | 1 + src/SceneGraph/RenderList.cpp | 17 +++++++++++++++ 8 files changed, 81 insertions(+), 7 deletions(-) diff --git a/inc/hgl/graph/MaterialRenderList.h b/inc/hgl/graph/MaterialRenderList.h index 18d2b052..f9134773 100644 --- a/inc/hgl/graph/MaterialRenderList.h +++ b/inc/hgl/graph/MaterialRenderList.h @@ -96,5 +96,6 @@ public: void Render(RenderCmdBuffer *); void UpdateLocalToWorld(); //刷新所有对象的LocalToWorld矩阵 + void UpdateMaterialInstance(SceneNode *); };//class MaterialRenderList VK_NAMESPACE_END diff --git a/inc/hgl/graph/RenderList.h b/inc/hgl/graph/RenderList.h index 1bef8afd..94ec4111 100644 --- a/inc/hgl/graph/RenderList.h +++ b/inc/hgl/graph/RenderList.h @@ -40,6 +40,7 @@ namespace hgl virtual bool Render(RenderCmdBuffer *); ///<渲染所有对象 virtual void UpdateLocalToWorld(); ///<更新所有对象的变换数据 + virtual void UpdateMaterialInstance(SceneNode *); ///<有对象互换了材质实例 virtual void Clear(); ///<彻底清理 };//class RenderList diff --git a/inc/hgl/graph/RenderNode.h b/inc/hgl/graph/RenderNode.h index 9e3c88d2..41a42dcc 100644 --- a/inc/hgl/graph/RenderNode.h +++ b/inc/hgl/graph/RenderNode.h @@ -13,13 +13,15 @@ namespace hgl struct RenderNode { - SceneNode *scene_node; + uint index; ///<在MaterialRenderList中的索引 - uint32 l2w_version; - uint32 l2w_index; + SceneNode * scene_node; - Vector3f world_position; - float to_camera_distance; + uint32 l2w_version; + uint32 l2w_index; + + Vector3f world_position; + float to_camera_distance; }; using RenderNodeList=List; diff --git a/inc/hgl/graph/VKRenderable.h b/inc/hgl/graph/VKRenderable.h index ca2e7b26..5a40e799 100644 --- a/inc/hgl/graph/VKRenderable.h +++ b/inc/hgl/graph/VKRenderable.h @@ -103,6 +103,20 @@ public: const PrimitiveDataBuffer *GetDataBuffer ()const{return primitive_data_buffer;} const PrimitiveRenderData *GetRenderData ()const{return primitive_render_data;} + +public: + + bool ChangeMaterialInstance(MaterialInstance *mi) + { + if(!mi) + return(false); + + if(mi->GetMaterial()!=mat_inst->GetMaterial()) //不能换母材质 + return(false); + + mat_inst=mi; + return(true); + } };//class Renderable Renderable *CreateRenderable(Primitive *,MaterialInstance *,Pipeline *); diff --git a/src/SceneGraph/MaterialRenderList.cpp b/src/SceneGraph/MaterialRenderList.cpp index 922e19f2..757578e5 100644 --- a/src/SceneGraph/MaterialRenderList.cpp +++ b/src/SceneGraph/MaterialRenderList.cpp @@ -111,10 +111,12 @@ void MaterialRenderList::Add(SceneNode *sn) { RenderNode rn; + rn.index =rn_list.GetCount(); + rn.scene_node =sn; - rn.l2w_version=sn->GetLocalToWorldMatrixVersion(); - rn.l2w_index=0; + rn.l2w_version =sn->GetLocalToWorldMatrixVersion(); + rn.l2w_index =0; rn.world_position =sn->GetWorldPosition(); @@ -187,6 +189,30 @@ void MaterialRenderList::UpdateLocalToWorld() } } +void MaterialRenderList::UpdateMaterialInstance(SceneNode *sn) +{ + if(!sn)return; + + if(!assign_buffer) + return; + + const int node_count=rn_list.GetCount(); + + if(node_count<=0)return; + RenderNode *rn=rn_list.GetData(); + + for(int i=0;iscene_node==sn) + { + assign_buffer->UpdateMaterialInstance(rn); + return; + } + + ++rn; + } +} + void MaterialRenderList::RenderItem::Set(Renderable *ri) { pipeline=ri->GetPipeline(); diff --git a/src/SceneGraph/RenderAssignBuffer.cpp b/src/SceneGraph/RenderAssignBuffer.cpp index b5703ef7..46660ddb 100644 --- a/src/SceneGraph/RenderAssignBuffer.cpp +++ b/src/SceneGraph/RenderAssignBuffer.cpp @@ -105,6 +105,18 @@ void RenderAssignBuffer::UpdateLocalToWorld(const RenderNodePointerList &rnp_lis l2w_buffer->Unmap(); } +void RenderAssignBuffer::UpdateMaterialInstance(const RenderNode *rn) +{ + if(!rn) + return; + + AssignData *adp=(AssignData *)(assign_vab->DeviceBuffer::Map(sizeof(AssignData)*rn->index,sizeof(AssignData))); + + adp->mi=mi_set.Find(rn->scene_node->GetRenderable()->GetMaterialInstance()); + + assign_vab->Unmap(); +} + void RenderAssignBuffer::StatMI(const RenderNodeList &rn_list) { mi_set.Clear(); diff --git a/src/SceneGraph/RenderAssignBuffer.h b/src/SceneGraph/RenderAssignBuffer.h index c7820891..d387e5d9 100644 --- a/src/SceneGraph/RenderAssignBuffer.h +++ b/src/SceneGraph/RenderAssignBuffer.h @@ -93,5 +93,6 @@ public: void WriteNode(const RenderNodeList &); void UpdateLocalToWorld(const RenderNodePointerList &,const int first,const int last); + void UpdateMaterialInstance(const RenderNode *); };//struct RenderAssignBuffer VK_NAMESPACE_END diff --git a/src/SceneGraph/RenderList.cpp b/src/SceneGraph/RenderList.cpp index edbd96be..536882de 100644 --- a/src/SceneGraph/RenderList.cpp +++ b/src/SceneGraph/RenderList.cpp @@ -85,5 +85,22 @@ namespace hgl mrl_map.UpdateLocalToWorld(); } + + void RenderList::UpdateMaterialInstance(SceneNode *sn) + { + if(!sn)return; + + Renderable *ri=sn->GetRenderable(); + + if(!ri)return; + + Material *mtl=ri->GetMaterial(); + MaterialRenderList *mrl; + + if(!mrl_map.Get(mtl,mrl)) //找到对应的 + return; + + mrl->UpdateMaterialInstance(sn); + } }//namespace graph }//namespace hgl