diff --git a/inc/hgl/graph/RenderNode2D.h b/inc/hgl/graph/RenderNode2D.h index fad5b5e7..f360bf3d 100644 --- a/inc/hgl/graph/RenderNode2D.h +++ b/inc/hgl/graph/RenderNode2D.h @@ -11,6 +11,8 @@ namespace hgl class Renderable; class Material; class GPUDevice; + struct VertexInputData; + struct IndexBufferData; struct RenderNode2D { @@ -35,20 +37,44 @@ namespace hgl RenderNode2DList rn_list; + private: + RenderNode2DExtraBuffer *extra_buffer; + struct RenderItem + { + uint32_t first; + uint32_t count; + + Pipeline * pipeline; + MaterialInstance * mi; + const VertexInputData * vid; + + public: + + void Set(Renderable *); + }; + + 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; - Primitive *last_primitive; - uint first_index; + MaterialInstance * last_mi; + Pipeline * last_pipeline; + const VertexInputData * last_vid; + uint last_index; - void Render(const uint index,Renderable *); + void Bind(MaterialInstance *); + bool Bind(const VertexInputData *,const uint); + + void Render(RenderItem *); public: diff --git a/inc/hgl/graph/VKPrimitive.h b/inc/hgl/graph/VKPrimitive.h index 21b1f2e2..2b09d6e2 100644 --- a/inc/hgl/graph/VKPrimitive.h +++ b/inc/hgl/graph/VKPrimitive.h @@ -7,6 +7,12 @@ #include #include VK_NAMESPACE_BEGIN +struct IndexBufferData +{ + IndexBuffer *buffer; + VkDeviceSize offset; +}; + /** * 单一图元数据 */ @@ -26,10 +32,9 @@ class Primitive protected: - uint32_t draw_count; + uint32_t vertex_count; - IndexBuffer *indices_buffer=nullptr; - VkDeviceSize indices_offset=0; + IndexBufferData index_buffer_data; protected: @@ -46,42 +51,34 @@ protected: public: - Primitive(const uint32_t dc=0):draw_count(dc){} + Primitive(const uint32_t vc=0):vertex_count(vc){} virtual ~Primitive()=default; const uint GetRefCount()const{return ref_count;} - void SetBoundingBox(const AABB &aabb){BoundingBox=aabb;} + void SetBoundingBox(const AABB &aabb){BoundingBox=aabb;} const AABB & GetBoundingBox()const {return BoundingBox;} - bool Set(const AnsiString &name,VBO *vb,VkDeviceSize offset=0); + bool Set(const AnsiString &name,VBO *vb,VkDeviceSize offset=0); - bool Set(IndexBuffer *ib,VkDeviceSize offset=0) + bool Set(IndexBuffer *ib,VkDeviceSize offset=0) { if(!ib)return(false); - indices_buffer=ib; - indices_offset=offset; + index_buffer_data.buffer=ib; + index_buffer_data.offset=offset; return(true); } public: - void SetDrawCount(const uint32_t dc){draw_count=dc;} ///<设置当前对象绘制需要多少个顶点 - virtual const uint32_t GetDrawCount()const ///<取得当前对象绘制需要多少个顶点 - { - if(indices_buffer) - return indices_buffer->GetCount(); + const uint32_t GetVertexCount ()const {return vertex_count;} - return draw_count; - } + VBO * GetVBO (const AnsiString &,VkDeviceSize *); + VkBuffer GetBuffer (const AnsiString &,VkDeviceSize *); + const int GetBufferCount ()const {return buffer_list.GetCount();} - VBO * GetVBO (const AnsiString &,VkDeviceSize *); - VkBuffer GetBuffer (const AnsiString &,VkDeviceSize *); - const int GetBufferCount ()const {return buffer_list.GetCount();} - - IndexBuffer * GetIndexBuffer () {return indices_buffer;} - const VkDeviceSize GetIndexBufferOffset()const {return indices_offset;} + const IndexBufferData * GetIndexBuffer ()const {return &index_buffer_data;} };//class Primitive VK_NAMESPACE_END #endif//HGL_GRAPH_VULKAN_PRIMITIVE_INCLUDE diff --git a/src/SceneGraph/RenderNode2D.cpp b/src/SceneGraph/RenderNode2D.cpp index eba1a5d5..cd6e7d3b 100644 --- a/src/SceneGraph/RenderNode2D.cpp +++ b/src/SceneGraph/RenderNode2D.cpp @@ -67,6 +67,8 @@ namespace hgl VBO *local_to_world[3]; + VkBuffer buffer[3]; + public: RenderNode2DExtraBuffer() @@ -92,9 +94,11 @@ namespace hgl Clear(); count=power_to_2(c); - local_to_world[0]=dev->CreateVBO(VF_V4F,count); - local_to_world[1]=dev->CreateVBO(VF_V4F,count); - local_to_world[2]=dev->CreateVBO(VF_V4F,count); + for(uint i=0;i<3;i++) + { + local_to_world[i]=dev->CreateVBO(VF_V4F,count); + buffer[i]=local_to_world[i]->GetBuffer(); + } } void WriteData(RenderNode2D *render_node,const uint count) @@ -178,52 +182,175 @@ namespace hgl } } - void MaterialRenderList2D::Render(const uint index,Renderable *ri) + void MaterialRenderList2D::RenderItem::Set(Renderable *ri) { - if(last_mi!=ri->GetMaterialInstance()) - { - + pipeline =ri->GetPipeline(); + mi =ri->GetMaterialInstance(); + vid =ri->GetVertexInputData(); + } - last_pipeline=nullptr; - last_primitive=nullptr; + void MaterialRenderList2D::Stat() + { + const uint count=rn_list.GetCount(); + RenderNode2D *rn=rn_list.GetData(); + + ri_list.ClearData(); + ri_list.PreMalloc(count); + + 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; + + ++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); + + last_pipeline =ri->pipeline; + last_mi =ri->mi; + last_vid =ri->vid; + + ++rn; + } + } + + void MaterialRenderList2D::Bind(MaterialInstance *mi) + { + } + + bool MaterialRenderList2D::Bind(const VertexInputData *vid,const uint first) + { + //binding号都是在VertexInput::CreateVIL时连续紧密排列生成的,所以bind时first_binding写0就行了。 + + const VIL *vil=last_mi->GetVIL(); + + if(vil->GetCount(VertexInputGroup::Basic)!=vid->binding_count) + return(false); //这里基本不太可能,因为CreateRenderable时就会检查值是否一样 + + uint count=0; + + //vid信息来自于Primitive,它只提供模型本身的vbo数据 + hgl_cpy(buffer_list,vid->buffer_list,vid->binding_count); + hgl_cpy(buffer_offset,vid->buffer_offset,vid->binding_count); + + if(binding_count==vid->binding_count) + return(true); + + count=vid->binding_count; + + const uint bone_binding_count=vil->GetCount(VertexInputGroup::Bone); + + if(bone_binding_count>0) //有骨骼矩阵信息 + { + if(bone_binding_count!=2) //只有BoneID/BondWeight,,,不是2的话根本就不对 + return(false); + + count+=bone_binding_count; } - if(last_pipeline!=ri->GetPipeline()) + const uint l2w_binding_count=vil->GetCount(VertexInputGroup::LocalToWorld); + + if(l2w_binding_count>0) //有变换矩阵信息 { - last_pipeline=ri->GetPipeline(); + if(vil->GetCount(VertexInputGroup::LocalToWorld)!=3) //2D的l2w使用mat3x4,应该只有3个 + return(false); - cmd_buf->BindPipeline(last_pipeline); + hgl_cpy(buffer_list+count,extra_buffer->buffer,3); - last_primitive=nullptr; + for(uint i=0;i<3;i++) + buffer_offset[count+i]=first*16; //16 + + count+=l2w_binding_count; } - if(last_primitive!=ri->GetPrimitive()) + if(count!=binding_count) { - //把之前的一次性画了 + //还有没支持的绑定组???? - last_primitive=ri->GetPrimitive(); - - first_index=index; + return(false); } + + return(true); + } + + void MaterialRenderList2D::Render(RenderItem *ri) + { + if(last_pipeline!=ri->pipeline) + { + cmd_buf->BindPipeline(ri->pipeline); + last_pipeline=ri->pipeline; + + last_mi=nullptr; + last_vid=nullptr; + + //这里未来尝试换pipeline,但是不换mi/primitive是否需要重新绑定 + } + + if(last_mi!=ri->mi) + { + Bind(ri->mi); + last_mi=ri->mi; + + last_vid=nullptr; + } + + if(!last_vid->Comp(ri->vid)) + { + Bind(ri->vid,ri->first); + last_vid=ri->vid; + } + + const IndexBufferData *ibd=last_primitive->GetIndexBuffer(); + + if(ib) + cmd_buf->DrawIndexed(ib->GetCount(),ri->count); + else + cmd_buf->Draw(last_primitive->GetDrawCount(),ri->count); } void MaterialRenderList2D::Render() { - last_mi=nullptr; - last_pipeline=nullptr; - last_primitive=nullptr; - first_index=0; - const uint count=rn_list.GetCount(); if(count<=0)return; - RenderNode2D *rn=rn_list.GetData(); + Stat(); - for(uint i=0;iri); - ++rn; + Render(ri); + ++ri; } } }//namespace graph diff --git a/src/SceneGraph/font/TextPrimitive.cpp b/src/SceneGraph/font/TextPrimitive.cpp index 4e53c811..2b509081 100644 --- a/src/SceneGraph/font/TextPrimitive.cpp +++ b/src/SceneGraph/font/TextPrimitive.cpp @@ -26,7 +26,7 @@ namespace hgl void TextPrimitive::SetCharCount(const uint cc) { - this->draw_count=cc; + this->vertex_count=cc; if(cc<=max_count)return; max_count=power_to_2(cc); @@ -48,7 +48,7 @@ namespace hgl } } - bool TextPrimitive::WriteVertex (const int16 *fp){if(!fp)return(false);if(!vbo_position )return(false);return vbo_position ->Write(fp,draw_count*4*sizeof(int16));} - bool TextPrimitive::WriteTexCoord (const float *fp){if(!fp)return(false);if(!vbo_tex_coord)return(false);return vbo_tex_coord ->Write(fp,draw_count*4*sizeof(float));} + bool TextPrimitive::WriteVertex (const int16 *fp){if(!fp)return(false);if(!vbo_position )return(false);return vbo_position ->Write(fp,vertex_count*4*sizeof(int16));} + bool TextPrimitive::WriteTexCoord (const float *fp){if(!fp)return(false);if(!vbo_tex_coord)return(false);return vbo_tex_coord ->Write(fp,vertex_count*4*sizeof(float));} }//namespace graph }//namespace hgl