finished to stat render list,maked buffer list....next step to bind buffer.

This commit is contained in:
HuYingzhuo(hugo/hyzboy) 2023-05-05 21:12:53 +08:00
parent 2eac17ac61
commit 21201b1695
4 changed files with 207 additions and 57 deletions

View File

@ -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<RenderItem> 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:

View File

@ -7,6 +7,12 @@
#include<hgl/math/Math.h>
#include<hgl/graph/AABB.h>
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,7 +51,7 @@ 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;}
@ -60,28 +65,20 @@ public:
{
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();
return draw_count;
}
const uint32_t GetVertexCount ()const {return vertex_count;}
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

View File

@ -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())
{
last_pipeline=nullptr;
last_primitive=nullptr;
pipeline =ri->GetPipeline();
mi =ri->GetMaterialInstance();
vid =ri->GetVertexInputData();
}
if(last_pipeline!=ri->GetPipeline())
void MaterialRenderList2D::Stat()
{
last_pipeline=ri->GetPipeline();
const uint count=rn_list.GetCount();
RenderNode2D *rn=rn_list.GetData();
cmd_buf->BindPipeline(last_pipeline);
ri_list.ClearData();
ri_list.PreMalloc(count);
last_primitive=nullptr;
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;i<count;i++)
{
if(last_pipeline==rn->ri->GetPipeline())
if(last_mi==rn->ri->GetMaterialInstance())
if(last_vid==rn->ri->GetVertexInputData())
{
++ri->count;
++rn;
continue;
}
if(last_primitive!=ri->GetPrimitive())
{
//把之前的一次性画了
++ri_count;
last_primitive=ri->GetPrimitive();
++ri;
ri->first=i;
ri->count=1;
ri->Set(rn->ri);
first_index=index;
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;
}
const uint l2w_binding_count=vil->GetCount(VertexInputGroup::LocalToWorld);
if(l2w_binding_count>0) //有变换矩阵信息
{
if(vil->GetCount(VertexInputGroup::LocalToWorld)!=3) //2D的l2w使用mat3x4应该只有3个
return(false);
hgl_cpy(buffer_list+count,extra_buffer->buffer,3);
for(uint i=0;i<3;i++)
buffer_offset[count+i]=first*16; //16
count+=l2w_binding_count;
}
if(count!=binding_count)
{
//还有没支持的绑定组????
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;i<count;i++)
if(ri_count<=0)return;
RenderItem *ri=ri_list.GetData();
last_pipeline =nullptr;
last_mi =nullptr;
last_vid =nullptr;
for(uint i=0;i<ri_count;i++)
{
Render(i,rn->ri);
++rn;
Render(ri);
++ri;
}
}
}//namespace graph

View File

@ -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