use VAB instead of VBO

This commit is contained in:
hyzboy 2024-04-24 01:38:55 +08:00
parent acb69d3bf5
commit d8140ae64e
26 changed files with 167 additions and 152 deletions

@ -1 +1 @@
Subproject commit 6236361903f2a94f7ae8400294ff048263ff3725 Subproject commit 509273e44937426ecc51116f5094564b96ea8b87

View File

@ -116,7 +116,7 @@ private:
Primitive *primitive=db->CreatePrimitive(VERTEX_COUNT); Primitive *primitive=db->CreatePrimitive(VERTEX_COUNT);
if(!primitive)return(false); if(!primitive)return(false);
if(!primitive->Set(VAN::Position, db->CreateVBO(VF_V2F,VERTEX_COUNT,position_data)))return(false); if(!primitive->Set(VAN::Position, db->CreateVAB(VF_V2F,VERTEX_COUNT,position_data)))return(false);
render_obj=db->CreateRenderable(primitive,material_instance,pipeline); render_obj=db->CreateRenderable(primitive,material_instance,pipeline);
return(true); return(true);

View File

@ -138,7 +138,7 @@ private:
Primitive *primitive=db->CreatePrimitive(VERTEX_COUNT); Primitive *primitive=db->CreatePrimitive(VERTEX_COUNT);
if(!primitive)return(false); if(!primitive)return(false);
if(!primitive->Set(VAN::Position, db->CreateVBO(VF_V4I16,VERTEX_COUNT,position_data)))return(false); if(!primitive->Set(VAN::Position, db->CreateVAB(VF_V4I16,VERTEX_COUNT,position_data)))return(false);
render_obj=db->CreateRenderable(primitive,material_instance,pipeline); render_obj=db->CreateRenderable(primitive,material_instance,pipeline);
return(true); return(true);

View File

@ -180,8 +180,8 @@ private:
for(Color4f &c:color_data[1])c=Color4f(0,1,0,1); for(Color4f &c:color_data[1])c=Color4f(0,1,0,1);
for(Color4f &c:color_data[2])c=Color4f(0,0,1,1); for(Color4f &c:color_data[2])c=Color4f(0,0,1,1);
if(!ro_line->Set(VAN::Position, db->CreateVBO(VF_V3F,AXIS_MAX_VERTICES,position_data)))return(false); if(!ro_line->Set(VAN::Position, db->CreateVAB(VF_V3F,AXIS_MAX_VERTICES,position_data)))return(false);
if(!ro_line->Set(VAN::Color, db->CreateVBO(VF_V4F,AXIS_MAX_VERTICES,color_data )))return(false); if(!ro_line->Set(VAN::Color, db->CreateVAB(VF_V4F,AXIS_MAX_VERTICES,color_data )))return(false);
} }
return(true); return(true);

View File

@ -106,8 +106,8 @@ private:
ro_line=db->CreatePrimitive("Line",2); ro_line=db->CreatePrimitive("Line",2);
if(!ro_line)return(false); if(!ro_line)return(false);
if(!ro_line->Set(VAN::Position, vbo_pos= db->CreateVBO(VF_V3F,2,position_data )))return(false); if(!ro_line->Set(VAN::Position, vbo_pos= db->CreateVAB(VF_V3F,2,position_data )))return(false);
if(!ro_line->Set(VAN::Luminance, db->CreateVBO(VF_V1F,2,lumiance_data )))return(false); if(!ro_line->Set(VAN::Luminance, db->CreateVAB(VF_V1F,2,lumiance_data )))return(false);
} }
return(true); return(true);

View File

@ -32,11 +32,11 @@ namespace hgl
IndexBuffer * ibo; IndexBuffer * ibo;
void * ibo_map; void * ibo_map;
VBOAccessMap vbo_map; VABAccessMap vbo_map;
protected: protected:
bool AcquirePVB(VBOAccessData *,const AnsiString &,const void *data); ///<请求一个顶点属性数据区 bool AcquirePVB(VABAccess *,const AnsiString &,const void *data); ///<请求一个顶点属性数据区
void ClearAllData(); void ClearAllData();
@ -49,14 +49,14 @@ namespace hgl
virtual bool Init(const uint32 vertices_count,const uint32 index_count,IndexType it=IndexType::AUTO); ///<初始化,参数为顶点数量 virtual bool Init(const uint32 vertices_count,const uint32 index_count,IndexType it=IndexType::AUTO); ///<初始化,参数为顶点数量
template<typename T> template<typename T>
T * AccessVBO(const AnsiString &name) ///<创建一个顶点属性数据缓冲区以及访问器 T * AccessVAB(const AnsiString &name) ///<创建一个顶点属性数据缓冲区以及访问器
{ {
const VkFormat format=vil->GetVulkanFormat(name); const VkFormat format=vil->GetVulkanFormat(name);
if(format!=T::GetVulkanFormat()) if(format!=T::GetVulkanFormat())
return(nullptr); return(nullptr);
VBOAccessData vad; VABAccess vad;
if(!this->AcquirePVB(&vad,name,nullptr)) if(!this->AcquirePVB(&vad,name,nullptr))
return(nullptr); return(nullptr);
@ -67,9 +67,10 @@ namespace hgl
return access; return access;
} }
bool WriteVBO(const AnsiString &name,const void *data,const uint32_t bytes); ///<直接写入顶点属性数据 bool WriteVAB(const AnsiString &name,const void *data,const uint32_t bytes); ///<直接写入顶点属性数据
const IndexType GetIndexType()const{return ibo?ibo->GetType():IndexType::ERR;} ///<取得索引数据类型 const IndexType GetIndexType()const{return ibo?ibo->GetType():IndexType::ERR;} ///<取得索引数据类型
template<typename T> T *AccessIBO() template<typename T> T *AccessIBO()
{ {
if(!ibo)return(nullptr); if(!ibo)return(nullptr);

View File

@ -55,7 +55,7 @@ class DeviceBuffer;
struct DeviceBufferData; struct DeviceBufferData;
class VertexAttribBuffer; class VertexAttribBuffer;
using VBO=VertexAttribBuffer; using VAB=VertexAttribBuffer;
class IndexBuffer; class IndexBuffer;

View File

@ -154,9 +154,9 @@ public:
void PushConstants(const void *data,const uint32_t size) {vkCmdPushConstants(cmd_buf,pipeline_layout,VK_SHADER_STAGE_VERTEX_BIT,0, size,data);} void PushConstants(const void *data,const uint32_t size) {vkCmdPushConstants(cmd_buf,pipeline_layout,VK_SHADER_STAGE_VERTEX_BIT,0, size,data);}
void PushConstants(const void *data,const uint32_t offset,const uint32_t size) {vkCmdPushConstants(cmd_buf,pipeline_layout,VK_SHADER_STAGE_VERTEX_BIT,offset, size,data);} void PushConstants(const void *data,const uint32_t offset,const uint32_t size) {vkCmdPushConstants(cmd_buf,pipeline_layout,VK_SHADER_STAGE_VERTEX_BIT,offset, size,data);}
void BindVBO(const uint32_t first,const uint32_t count,const VkBuffer *vbo,const VkDeviceSize *offsets) void BindVBO(const uint32_t first,const uint32_t count,const VkBuffer *vab,const VkDeviceSize *offsets)
{ {
vkCmdBindVertexBuffers(cmd_buf,first,count,vbo,offsets); vkCmdBindVertexBuffers(cmd_buf,first,count,vab,offsets);
} }
bool BindVBO(VBOList *vbo_list) bool BindVBO(VBOList *vbo_list)

View File

@ -114,8 +114,8 @@ public: //Buffer相关
DeviceBuffer * CreateBuffer(VkBufferUsageFlags buf_usage, VkDeviceSize size,const void *data, SharingMode sm=SharingMode::Exclusive){return CreateBuffer(buf_usage,size,size,data,sm);} DeviceBuffer * CreateBuffer(VkBufferUsageFlags buf_usage, VkDeviceSize size,const void *data, SharingMode sm=SharingMode::Exclusive){return CreateBuffer(buf_usage,size,size,data,sm);}
DeviceBuffer * CreateBuffer(VkBufferUsageFlags buf_usage, VkDeviceSize size, SharingMode sm=SharingMode::Exclusive){return CreateBuffer(buf_usage,size,size,nullptr,sm);} DeviceBuffer * CreateBuffer(VkBufferUsageFlags buf_usage, VkDeviceSize size, SharingMode sm=SharingMode::Exclusive){return CreateBuffer(buf_usage,size,size,nullptr,sm);}
VBO * CreateVBO (VkFormat format, uint32_t count,const void *data, SharingMode sm=SharingMode::Exclusive); VAB * CreateVAB (VkFormat format, uint32_t count,const void *data, SharingMode sm=SharingMode::Exclusive);
VBO * CreateVBO (VkFormat format, uint32_t count, SharingMode sm=SharingMode::Exclusive){return CreateVBO(format,count,nullptr,sm);} VAB * CreateVAB (VkFormat format, uint32_t count, SharingMode sm=SharingMode::Exclusive){return CreateVAB(format,count,nullptr,sm);}
const IndexType ChooseIndexType (const VkDeviceSize &vertex_count)const; ///<求一个合适的索引类型 const IndexType ChooseIndexType (const VkDeviceSize &vertex_count)const; ///<求一个合适的索引类型
const bool CheckIndexType (const IndexType,const VkDeviceSize &vertex_count)const; ///<检测一个索引类型是否合适 const bool CheckIndexType (const IndexType,const VkDeviceSize &vertex_count)const; ///<检测一个索引类型是否合适

View File

@ -58,7 +58,7 @@ struct VulkanHardwareRequirement
// primitive topology // primitive topology
// viewport // viewport
// scissor // scissor
// bind vbo // bind vab
// depth test // depth test
// depth write // depth write
// depth compare op // depth compare op

View File

@ -8,6 +8,22 @@
#include<hgl/graph/AABB.h> #include<hgl/graph/AABB.h>
#include<hgl/graph/VKVertexAttribBuffer.h> #include<hgl/graph/VKVertexAttribBuffer.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
struct PrimitiveData
{
uint32_t vertex_count;
uint32_t va_count;
VABAccess *vab_list;
IndexBufferData index_buffer_data;
AABB BoundingBox;
};
/** /**
* *
*/ */
@ -16,15 +32,13 @@ class Primitive
GPUDevice *device; GPUDevice *device;
AnsiString prim_name; AnsiString prim_name;
VBOAccessMap buffer_list;
protected: protected:
uint32_t vertex_count; uint32_t vertex_count;
IndexBufferData index_buffer_data; VABAccessMap buffer_list;
protected: IndexBufferData index_buffer_data;
AABB BoundingBox; AABB BoundingBox;
@ -53,7 +67,7 @@ public:
void SetBoundingBox(const AABB &aabb){BoundingBox=aabb;} void SetBoundingBox(const AABB &aabb){BoundingBox=aabb;}
const AABB & GetBoundingBox()const {return BoundingBox;} const AABB & GetBoundingBox()const {return BoundingBox;}
bool Set(const AnsiString &name,VBO *vb,VkDeviceSize offset=0); bool Set(const AnsiString &name,VAB *vb,VkDeviceSize offset=0);
bool Set(IndexBuffer *ib,VkDeviceSize offset=0); bool Set(IndexBuffer *ib,VkDeviceSize offset=0);
@ -61,7 +75,7 @@ public:
const uint32_t GetVertexCount ()const {return vertex_count;} const uint32_t GetVertexCount ()const {return vertex_count;}
bool GetVBOAccessData (const AnsiString &,VBOAccessData *); bool GetVBOAccessData (const AnsiString &,VABAccess *);
const int GetBufferCount ()const {return buffer_list.GetCount();} const int GetBufferCount ()const {return buffer_list.GetCount();}
const IndexBufferData * GetIndexBufferData ()const {return &index_buffer_data;} const IndexBufferData * GetIndexBufferData ()const {return &index_buffer_data;}

View File

@ -105,8 +105,8 @@ public: //Add
public: // VBO/VAO public: // VBO/VAO
VBO *CreateVBO(VkFormat format,uint32_t count,const void *data, SharingMode sm=SharingMode::Exclusive); VAB *CreateVAB(VkFormat format,uint32_t count,const void *data, SharingMode sm=SharingMode::Exclusive);
VBO *CreateVBO(VkFormat format,uint32_t count, SharingMode sm=SharingMode::Exclusive){return CreateVBO(format, count, nullptr, sm);} VAB *CreateVAB(VkFormat format,uint32_t count, SharingMode sm=SharingMode::Exclusive){return CreateVAB(format, count, nullptr, sm);}
#define SCENE_DB_CREATE_FUNC(name) DeviceBuffer *Create##name(const AnsiString &buf_name,VkDeviceSize size,void *data,SharingMode sm=SharingMode::Exclusive); \ #define SCENE_DB_CREATE_FUNC(name) DeviceBuffer *Create##name(const AnsiString &buf_name,VkDeviceSize size,void *data,SharingMode sm=SharingMode::Exclusive); \
DeviceBuffer *Create##name(const AnsiString &buf_name,VkDeviceSize size,SharingMode sm=SharingMode::Exclusive){return Create##name(buf_name,size,nullptr,sm);} DeviceBuffer *Create##name(const AnsiString &buf_name,VkDeviceSize size,SharingMode sm=SharingMode::Exclusive){return Create##name(buf_name,size,nullptr,sm);}

View File

@ -24,13 +24,13 @@ public:
VBO *SetVBO(const AnsiString &name,const VkFormat &fmt,const void *buf) VBO *SetVBO(const AnsiString &name,const VkFormat &fmt,const void *buf)
{ {
VBO *vbo=rr->CreateVBO(fmt,vertex_count,buf); VBO *vab=rr->CreateVAB(fmt,vertex_count,buf);
if(!vbo) if(!vab)
return(nullptr); return(nullptr);
prim->Set(name,vbo); prim->Set(name,vab);
return(vbo); return(vab);
} }
IndexBuffer *SetIBO(const IndexType &it,const void *buf,const uint32_t index_count) IndexBuffer *SetIBO(const IndexType &it,const void *buf,const uint32_t index_count)

View File

@ -35,11 +35,11 @@ namespace hgl
const VkDeviceSize GetBytes()const { return stride*count; } const VkDeviceSize GetBytes()const { return stride*count; }
};//class VertexAttribBuffer:public DeviceBuffer };//class VertexAttribBuffer:public DeviceBuffer
using VBO=VertexAttribBuffer; using VAB=VertexAttribBuffer;
struct VBOAccessData struct VABAccess
{ {
VBO *vbo; VAB *vab;
VkDeviceSize offset; VkDeviceSize offset;
VkDeviceSize size; VkDeviceSize size;
@ -47,10 +47,10 @@ namespace hgl
public: public:
CompOperatorMemcmp(const VBOAccessData &); CompOperatorMemcmp(const VABAccess &);
};//class VBOAccessData };//class VABAccess
using VBOAccessMap=Map<AnsiString,VBOAccessData>; using VABAccessMap=Map<AnsiString,VABAccess>;
}//namespace graph }//namespace graph
}//namespace hgl }//namespace hgl
#endif//HGL_GRAPH_VULKAN_VERTEX_ATTRIB_BUFFER_INCLUDE #endif//HGL_GRAPH_VULKAN_VERTEX_ATTRIB_BUFFER_INCLUDE

View File

@ -18,9 +18,9 @@ namespace hgl
uint vi_count; ///<顶点输入流数量 uint vi_count; ///<顶点输入流数量
const VIF * vif_list; ///<顶点输入格式列表 const VIF * vif_list; ///<顶点输入格式列表
VkDeviceSize vbo_max_size; ///<顶点缓冲区分配空间大小 VkDeviceSize vab_max_size; ///<顶点缓冲区分配空间大小
VkDeviceSize vbo_cur_size; ///<顶点缓冲区当前使用大小 VkDeviceSize vab_cur_size; ///<顶点缓冲区当前使用大小
VBO ** vbo; ///<顶点缓冲区列表 VAB ** vab; ///<顶点缓冲区列表
VkDeviceSize ibo_cur_size; ///<索引缓冲区当前使用大小 VkDeviceSize ibo_cur_size; ///<索引缓冲区当前使用大小
IndexBuffer * ibo; ///<索引缓冲区 IndexBuffer * ibo; ///<索引缓冲区
@ -39,8 +39,8 @@ namespace hgl
const VIL * GetVIL ()const{return vil;} ///<取得顶点输入格式列表 const VIL * GetVIL ()const{return vil;} ///<取得顶点输入格式列表
const VkDeviceSize GetVBOMaxCount ()const{return vbo_max_size;} ///<取得顶点缓冲区分配的空间最大数量 const VkDeviceSize GetVABMaxCount ()const{return vab_max_size;} ///<取得顶点属性缓冲区分配的空间最大数量
const VkDeviceSize GetVBOCurCount ()const{return vbo_cur_size;} ///<取得顶点缓冲区当前数量 const VkDeviceSize GetVABCurCount ()const{return vab_cur_size;} ///<取得顶点属性缓冲区当前数量
const IndexType GetIBOType ()const{return ibo?ibo->GetType():IndexType::ERR;} ///<取得索引缓冲区类型 const IndexType GetIBOType ()const{return ibo?ibo->GetType():IndexType::ERR;} ///<取得索引缓冲区类型
const VkDeviceSize GetIBOMaxCount ()const{return ibo?ibo->GetCount():-1;} ///<取得索引缓冲区分配的空间最大数量 const VkDeviceSize GetIBOMaxCount ()const{return ibo?ibo->GetCount():-1;} ///<取得索引缓冲区分配的空间最大数量

View File

@ -16,8 +16,8 @@ namespace hgl
uint max_count; ///<缓冲区最大容量 uint max_count; ///<缓冲区最大容量
VBO * vbo_position; VAB * vab_position;
VBO * vbo_tex_coord; VAB * vab_tex_coord;
protected: protected:

View File

@ -21,7 +21,7 @@ namespace hgl
if(!rc.Init(4,0)) if(!rc.Init(4,0))
return(nullptr); return(nullptr);
AutoDelete<VB2f> vertex=rc.AccessVBO<VB2f>(VAN::Position); AutoDelete<VB2f> vertex=rc.AccessVAB<VB2f>(VAN::Position);
if(!vertex) if(!vertex)
return(nullptr); return(nullptr);
@ -49,7 +49,7 @@ namespace hgl
if(!rc.Init(4,0)) if(!rc.Init(4,0))
return(nullptr); return(nullptr);
AutoDelete<VB2f> vertex=rc.AccessVBO<VB2f>(VAN::Position); AutoDelete<VB2f> vertex=rc.AccessVAB<VB2f>(VAN::Position);
vertex->WriteRectFan(rci->scope); vertex->WriteRectFan(rci->scope);
} }
@ -63,7 +63,7 @@ namespace hgl
if(!rc.Init(rci->round_per*4,8)) if(!rc.Init(rci->round_per*4,8))
return(nullptr); return(nullptr);
AutoDelete<VB2f> vertex=rc.AccessVBO<VB2f>(VAN::Position); AutoDelete<VB2f> vertex=rc.AccessVAB<VB2f>(VAN::Position);
Vector2f *coord=new Vector2f[rci->round_per]; Vector2f *coord=new Vector2f[rci->round_per];
@ -131,8 +131,8 @@ namespace hgl
if(!rc.Init(cci->field_count,0))return(nullptr); if(!rc.Init(cci->field_count,0))return(nullptr);
} }
AutoDelete<VB2f> vertex=rc.AccessVBO<VB2f>(VAN::Position); AutoDelete<VB2f> vertex=rc.AccessVAB<VB2f>(VAN::Position);
AutoDelete<VB4f> color=rc.AccessVBO<VB4f>(VAN::Color); AutoDelete<VB4f> color=rc.AccessVAB<VB4f>(VAN::Color);
if(!vertex) if(!vertex)
return(nullptr); return(nullptr);
@ -169,7 +169,7 @@ namespace hgl
if(!rc.Init(((pgci->grid_size.Width()+1)+(pgci->grid_size.Height()+1))*2,0)) if(!rc.Init(((pgci->grid_size.Width()+1)+(pgci->grid_size.Height()+1))*2,0))
return(nullptr); return(nullptr);
AutoDelete<VB3f> vertex=rc.AccessVBO<VB3f>(VAN::Position); AutoDelete<VB3f> vertex=rc.AccessVAB<VB3f>(VAN::Position);
const float right=float(pgci->grid_size.Width())/2.0f; const float right=float(pgci->grid_size.Width())/2.0f;
const float left =-right; const float left =-right;
@ -189,7 +189,7 @@ namespace hgl
Vector3f(left+col,bottom,0)); Vector3f(left+col,bottom,0));
} }
AutoDelete<VB1f> lum=rc.AccessVBO<VB1f>(VAN::Luminance); AutoDelete<VB1f> lum=rc.AccessVAB<VB1f>(VAN::Luminance);
if(lum) if(lum)
{ {
for(uint row=0;row<=pgci->grid_size.Height();row++) for(uint row=0;row<=pgci->grid_size.Height();row++)
@ -224,22 +224,22 @@ namespace hgl
if(!rc.Init(4,8)) if(!rc.Init(4,8))
return(nullptr); return(nullptr);
rc.WriteVBO(VAN::Position,xy_vertices,sizeof(xy_vertices)); rc.WriteVAB(VAN::Position,xy_vertices,sizeof(xy_vertices));
{ {
AutoDelete<VB3f> normal=rc.AccessVBO<VB3f>(VAN::Normal); AutoDelete<VB3f> normal=rc.AccessVAB<VB3f>(VAN::Normal);
if(normal)normal->RepeatWrite(xy_normal,4); if(normal)normal->RepeatWrite(xy_normal,4);
} }
{ {
AutoDelete<VB3f> tangent=rc.AccessVBO<VB3f>(VAN::Tangent); AutoDelete<VB3f> tangent=rc.AccessVAB<VB3f>(VAN::Tangent);
if(tangent)tangent->RepeatWrite(xy_tangent,4); if(tangent)tangent->RepeatWrite(xy_tangent,4);
} }
{ {
AutoDelete<VB2f> tex_coord=rc.AccessVBO<VB2f>(VAN::TexCoord); AutoDelete<VB2f> tex_coord=rc.AccessVAB<VB2f>(VAN::TexCoord);
if(tex_coord) if(tex_coord)
tex_coord->Write(xy_tex_coord,4); tex_coord->Write(xy_tex_coord,4);
@ -306,22 +306,22 @@ namespace hgl
if(!rc.Init(24,6*2*3,IndexType::U16)) if(!rc.Init(24,6*2*3,IndexType::U16))
return(nullptr); return(nullptr);
rc.WriteVBO(VAN::Position,positions,sizeof(positions)); rc.WriteVAB(VAN::Position,positions,sizeof(positions));
if(cci->normal) if(cci->normal)
rc.WriteVBO(VAN::Normal,normals,sizeof(normals)); rc.WriteVAB(VAN::Normal,normals,sizeof(normals));
if(cci->tangent) if(cci->tangent)
rc.WriteVBO(VAN::Tangent,tangents,sizeof(tangents)); rc.WriteVAB(VAN::Tangent,tangents,sizeof(tangents));
if(cci->tex_coord) if(cci->tex_coord)
rc.WriteVBO(VAN::TexCoord,tex_coords,sizeof(tex_coords)); rc.WriteVAB(VAN::TexCoord,tex_coords,sizeof(tex_coords));
if(cci->color_type!=CubeCreateInfo::ColorType::NoColor) if(cci->color_type!=CubeCreateInfo::ColorType::NoColor)
{ {
RANGE_CHECK_RETURN_NULLPTR(cci->color_type); RANGE_CHECK_RETURN_NULLPTR(cci->color_type);
AutoDelete<VB4f> color=rc.AccessVBO<VB4f>(VAN::Color); AutoDelete<VB4f> color=rc.AccessVAB<VB4f>(VAN::Color);
if(color) if(color)
{ {
@ -460,10 +460,10 @@ namespace hgl
if(!rc.Init(numberVertices,numberIndices)) if(!rc.Init(numberVertices,numberIndices))
return(nullptr); return(nullptr);
AutoDelete<VB3f> vertex=rc.AccessVBO<VB3f>(VAN::Position); AutoDelete<VB3f> vertex=rc.AccessVAB<VB3f>(VAN::Position);
AutoDelete<VB3f> normal=rc.AccessVBO<VB3f>(VAN::Normal); AutoDelete<VB3f> normal=rc.AccessVAB<VB3f>(VAN::Normal);
AutoDelete<VB3f> tangent=rc.AccessVBO<VB3f>(VAN::Tangent); AutoDelete<VB3f> tangent=rc.AccessVAB<VB3f>(VAN::Tangent);
AutoDelete<VB2f> tex_coord=rc.AccessVBO<VB2f>(VAN::TexCoord); AutoDelete<VB2f> tex_coord=rc.AccessVAB<VB2f>(VAN::TexCoord);
float *vp=vertex->Get(); float *vp=vertex->Get();
float *np=normal?normal->Get():nullptr; float *np=normal?normal->Get():nullptr;
@ -546,10 +546,10 @@ namespace hgl
if(!rc.Init(numberVertices,numberIndices)) if(!rc.Init(numberVertices,numberIndices))
return(nullptr); return(nullptr);
AutoDelete<VB3f> vertex=rc.AccessVBO<VB3f>(VAN::Position); AutoDelete<VB3f> vertex=rc.AccessVAB<VB3f>(VAN::Position);
AutoDelete<VB3f> normal=rc.AccessVBO<VB3f>(VAN::Normal); AutoDelete<VB3f> normal=rc.AccessVAB<VB3f>(VAN::Normal);
AutoDelete<VB3f> tangent=rc.AccessVBO<VB3f>(VAN::Tangent); AutoDelete<VB3f> tangent=rc.AccessVAB<VB3f>(VAN::Tangent);
AutoDelete<VB2f> tex_coord=rc.AccessVBO<VB2f>(VAN::TexCoord); AutoDelete<VB2f> tex_coord=rc.AccessVAB<VB2f>(VAN::TexCoord);
float *vp=vertex->Get(); float *vp=vertex->Get();
float *np=normal?normal->Get():nullptr; float *np=normal?normal->Get():nullptr;
@ -688,10 +688,10 @@ namespace hgl
if(!rc.Init(numberVertices,numberIndices)) if(!rc.Init(numberVertices,numberIndices))
return(nullptr); return(nullptr);
AutoDelete<VB3f> vertex=rc.AccessVBO<VB3f>(VAN::Position); AutoDelete<VB3f> vertex=rc.AccessVAB<VB3f>(VAN::Position);
AutoDelete<VB3f> normal=rc.AccessVBO<VB3f>(VAN::Normal); AutoDelete<VB3f> normal=rc.AccessVAB<VB3f>(VAN::Normal);
AutoDelete<VB3f> tangent=rc.AccessVBO<VB3f>(VAN::Tangent); AutoDelete<VB3f> tangent=rc.AccessVAB<VB3f>(VAN::Tangent);
AutoDelete<VB2f> tex_coord=rc.AccessVBO<VB2f>(VAN::TexCoord); AutoDelete<VB2f> tex_coord=rc.AccessVAB<VB2f>(VAN::TexCoord);
float *vp=vertex->Get(); float *vp=vertex->Get();
float *np=normal?normal->Get():nullptr; float *np=normal?normal->Get():nullptr;
@ -827,10 +827,10 @@ namespace hgl
if (cci->numberSlices < 3 || numberVertices > GLUS_MAX_VERTICES || numberIndices > GLUS_MAX_INDICES) if (cci->numberSlices < 3 || numberVertices > GLUS_MAX_VERTICES || numberIndices > GLUS_MAX_INDICES)
return nullptr; return nullptr;
AutoDelete<VB3f> vertex=rc.AccessVBO<VB3f>(VAN::Position); AutoDelete<VB3f> vertex=rc.AccessVAB<VB3f>(VAN::Position);
AutoDelete<VB3f> normal=rc.AccessVBO<VB3f>(VAN::Normal); AutoDelete<VB3f> normal=rc.AccessVAB<VB3f>(VAN::Normal);
AutoDelete<VB3f> tangent=rc.AccessVBO<VB3f>(VAN::Tangent); AutoDelete<VB3f> tangent=rc.AccessVAB<VB3f>(VAN::Tangent);
AutoDelete<VB2f> tex_coord=rc.AccessVBO<VB2f>(VAN::TexCoord); AutoDelete<VB2f> tex_coord=rc.AccessVAB<VB2f>(VAN::TexCoord);
float *vp=vertex->Get(); float *vp=vertex->Get();
float *np=normal?normal->Get():nullptr; float *np=normal?normal->Get():nullptr;
@ -1053,10 +1053,10 @@ namespace hgl
if (cci->numberSlices < 3 || cci->numberStacks < 1 || numberVertices > GLUS_MAX_VERTICES || numberIndices > GLUS_MAX_INDICES) if (cci->numberSlices < 3 || cci->numberStacks < 1 || numberVertices > GLUS_MAX_VERTICES || numberIndices > GLUS_MAX_INDICES)
return nullptr; return nullptr;
AutoDelete<VB3f> vertex=rc.AccessVBO<VB3f>(VAN::Position); AutoDelete<VB3f> vertex=rc.AccessVAB<VB3f>(VAN::Position);
AutoDelete<VB3f> normal=rc.AccessVBO<VB3f>(VAN::Normal); AutoDelete<VB3f> normal=rc.AccessVAB<VB3f>(VAN::Normal);
AutoDelete<VB3f> tangent=rc.AccessVBO<VB3f>(VAN::Tangent); AutoDelete<VB3f> tangent=rc.AccessVAB<VB3f>(VAN::Tangent);
AutoDelete<VB2f> tex_coord=rc.AccessVBO<VB2f>(VAN::TexCoord); AutoDelete<VB2f> tex_coord=rc.AccessVAB<VB2f>(VAN::TexCoord);
float *vp=vertex->Get(); float *vp=vertex->Get();
float *np=normal?normal->Get():nullptr; float *np=normal?normal->Get():nullptr;
@ -1172,8 +1172,8 @@ namespace hgl
if(!rc.Init(6,0)) if(!rc.Init(6,0))
return(nullptr); return(nullptr);
AutoDelete<VB3f> vertex=rc.AccessVBO<VB3f>(VAN::Position); AutoDelete<VB3f> vertex=rc.AccessVAB<VB3f>(VAN::Position);
AutoDelete<VB4f> color=rc.AccessVBO<VB4f>(VAN::Color); AutoDelete<VB4f> color=rc.AccessVAB<VB4f>(VAN::Color);
if(!vertex||!color) if(!vertex||!color)
return(nullptr); return(nullptr);
@ -1217,17 +1217,17 @@ namespace hgl
if(!rc.Init(8,24,IndexType::U16)) if(!rc.Init(8,24,IndexType::U16))
return(nullptr); return(nullptr);
AutoDelete<VB3f> vertex=rc.AccessVBO<VB3f>(VAN::Position); AutoDelete<VB3f> vertex=rc.AccessVAB<VB3f>(VAN::Position);
if(!vertex)return(nullptr); if(!vertex)return(nullptr);
rc.WriteVBO(VAN::Position,points,sizeof(points)); rc.WriteVAB(VAN::Position,points,sizeof(points));
if(cci->color_type!=BoundingBoxCreateInfo::ColorType::NoColor) if(cci->color_type!=BoundingBoxCreateInfo::ColorType::NoColor)
{ {
RANGE_CHECK_RETURN_NULLPTR(cci->color_type); RANGE_CHECK_RETURN_NULLPTR(cci->color_type);
AutoDelete<VB4f> color=rc.AccessVBO<VB4f>(VAN::Color); AutoDelete<VB4f> color=rc.AccessVAB<VB4f>(VAN::Color);
if(color) if(color)
{ {

View File

@ -14,7 +14,7 @@
* for(material) * for(material)
* for(pipeline) * for(pipeline)
* for(material_instance) * for(material_instance)
* for(vbo) * for(vab)
*/ */
template<> template<>
@ -196,7 +196,7 @@ bool MaterialRenderList::Bind(const VertexInputData *vid,const uint ri_index)
} }
if(mi_buffer) //材质实例组 if(mi_buffer) //材质实例组
vbo_list->Add(mi_buffer->GetVBO(),MI_VBO_STRIDE_BYTES*ri_index); vbo_list->Add(mi_buffer->GetVBO(),MI_VAB_STRIDE_BYTES*ri_index);
//if(!vbo_list.IsFull()) //Joint组暂未支持 //if(!vbo_list.IsFull()) //Joint组暂未支持
//{ //{

View File

@ -85,7 +85,7 @@ namespace hgl
return(true); return(true);
} }
bool PrimitiveCreater::AcquirePVB(VBOAccessData *vad,const AnsiString &name,const void *data) bool PrimitiveCreater::AcquirePVB(VABAccess *vad,const AnsiString &name,const void *data)
{ {
if(!vad)return(false); if(!vad)return(false);
if(!vil)return(false); if(!vil)return(false);
@ -99,10 +99,10 @@ namespace hgl
if(vbo_map.Get(name,*vad)) if(vbo_map.Get(name,*vad))
return true; return true;
vad->vbo =db->CreateVBO(vif->format,vertices_number,data); vad->vab =db->CreateVAB(vif->format,vertices_number,data);
if(!data) if(!data)
vad->map_ptr=vad->vbo->Map(); vad->map_ptr=vad->vab->Map();
else else
vad->map_ptr=nullptr; vad->map_ptr=nullptr;
@ -111,7 +111,7 @@ namespace hgl
return true; return true;
} }
bool PrimitiveCreater::WriteVBO(const AnsiString &name,const void *data,const uint32_t bytes) bool PrimitiveCreater::WriteVAB(const AnsiString &name,const void *data,const uint32_t bytes)
{ {
if(!vil)return(false); if(!vil)return(false);
if(name.IsEmpty())return(false); if(name.IsEmpty())return(false);
@ -126,7 +126,7 @@ namespace hgl
if(vif->stride*vertices_number!=bytes) if(vif->stride*vertices_number!=bytes)
return(false); return(false);
VBOAccessData vad; VABAccess vad;
return AcquirePVB(&vad,name,data); return AcquirePVB(&vad,name,data);
} }
@ -138,10 +138,10 @@ namespace hgl
const auto *sp=vbo_map.GetDataList(); const auto *sp=vbo_map.GetDataList();
for(uint i=0;i<vbo_map.GetCount();i++) for(uint i=0;i<vbo_map.GetCount();i++)
{ {
if((*sp)->value.vbo) if((*sp)->value.vab)
{ {
(*sp)->value.vbo->Unmap(); (*sp)->value.vab->Unmap();
delete (*sp)->value.vbo; delete (*sp)->value.vab;
} }
++sp; ++sp;
@ -168,12 +168,12 @@ namespace hgl
const auto *sp=vbo_map.GetDataList(); const auto *sp=vbo_map.GetDataList();
for(uint i=0;i<si_count;i++) for(uint i=0;i<si_count;i++)
{ {
if((*sp)->value.vbo) if((*sp)->value.vab)
{ {
if((*sp)->value.map_ptr) if((*sp)->value.map_ptr)
(*sp)->value.vbo->Unmap(); (*sp)->value.vab->Unmap();
primitive->Set((*sp)->key,(*sp)->value.vbo); primitive->Set((*sp)->key,(*sp)->value.vab);
} }
else else
{ {

View File

@ -30,18 +30,18 @@ namespace
{ {
constexpr const char *l2w_buffer_name[]= constexpr const char *l2w_buffer_name[]=
{ {
"VBO:Buffer:LocalToWorld:0", "VAB:Buffer:LocalToWorld:0",
"VBO:Buffer:LocalToWorld:1", "VAB:Buffer:LocalToWorld:1",
"VBO:Buffer:LocalToWorld:2", "VAB:Buffer:LocalToWorld:2",
"VBO:Buffer:LocalToWorld:3" "VAB:Buffer:LocalToWorld:3"
}; };
constexpr const char *l2w_memory_name[]= constexpr const char *l2w_memory_name[]=
{ {
"VBO:Memory:LocalToWorld:0", "VAB:Memory:LocalToWorld:0",
"VBO:Memory:LocalToWorld:1", "VAB:Memory:LocalToWorld:1",
"VBO:Memory:LocalToWorld:2", "VAB:Memory:LocalToWorld:2",
"VBO:Memory:LocalToWorld:3" "VAB:Memory:LocalToWorld:3"
}; };
} }
#endif//_DEBUG #endif//_DEBUG
@ -55,7 +55,7 @@ void RenderL2WBuffer::Alloc(const uint nc)
for(uint i=0;i<4;i++) for(uint i=0;i<4;i++)
{ {
l2w_vbo[i]=device->CreateVBO(VF_V4F,node_count); l2w_vbo[i]=device->CreateVAB(VF_V4F,node_count);
l2w_buffer[i]=l2w_vbo[i]->GetBuffer(); l2w_buffer[i]=l2w_vbo[i]->GetBuffer();
} }
} }
@ -114,13 +114,13 @@ void RenderMIBuffer::Bind(Material *mtl)const
{ {
if(!mtl)return; if(!mtl)return;
mtl->BindUBO(DescriptorSetType::PerMaterial,mtl::SBS_MaterialInstance.name,ubo_mi); mtl->BindUBO(DescriptorSetType::PerMaterial,mtl::SBS_MaterialInstance.name,mi_data_buffer);
} }
void RenderMIBuffer::Clear() void RenderMIBuffer::Clear()
{ {
SAFE_CLEAR(ubo_mi); SAFE_CLEAR(mi_data_buffer);
SAFE_CLEAR(vbo_mi); SAFE_CLEAR(mi_vab);
mi_count=0; mi_count=0;
node_count=0; node_count=0;
@ -136,22 +136,22 @@ void RenderMIBuffer::Alloc(const uint nc,const uint mc)
{ {
mi_count=mc; mi_count=mc;
ubo_mi=device->CreateUBO(mi_data_bytes*mi_count); mi_data_buffer=device->CreateUBO(mi_data_bytes*mi_count);
} }
vbo_mi=device->CreateVBO(MI_VBO_FMT,node_count); mi_vab=device->CreateVAB(MI_VAB_FMT,node_count);
mi_buffer=vbo_mi->GetBuffer(); mi_buffer=mi_vab->GetBuffer();
#ifdef _DEBUG #ifdef _DEBUG
DebugUtils *du=device->GetDebugUtils(); DebugUtils *du=device->GetDebugUtils();
if(du) if(du)
{ {
du->SetBuffer(ubo_mi->GetBuffer(),"UBO:Buffer:MaterialInstance"); du->SetBuffer(mi_data_buffer->GetBuffer(),"UBO:Buffer:MaterialInstance");
du->SetDeviceMemory(ubo_mi->GetVkMemory(),"UBO:Memory:MaterialInstance"); du->SetDeviceMemory(mi_data_buffer->GetVkMemory(),"UBO:Memory:MaterialInstance");
du->SetBuffer(vbo_mi->GetBuffer(),"VBO:Buffer:MaterialInstanceID"); du->SetBuffer(mi_vab->GetBuffer(),"VAB:Buffer:MaterialInstanceID");
du->SetDeviceMemory(vbo_mi->GetVkMemory(),"VBO:Memory:MaterialInstanceID"); du->SetDeviceMemory(mi_vab->GetVkMemory(),"VAB:Memory:MaterialInstanceID");
} }
#endif//_DEBUG #endif//_DEBUG
} }
@ -162,7 +162,7 @@ void RenderMIBuffer::WriteNode(RenderNode *render_node,const uint count,const Ma
Alloc(count,mi_set.GetCount()); Alloc(count,mi_set.GetCount());
uint8 *mip=(uint8 *)(ubo_mi->Map()); uint8 *mip=(uint8 *)(mi_data_buffer->Map());
for(MaterialInstance *mi:mi_set) for(MaterialInstance *mi:mi_set)
{ {
@ -170,9 +170,9 @@ void RenderMIBuffer::WriteNode(RenderNode *render_node,const uint count,const Ma
mip+=mi_data_bytes; mip+=mi_data_bytes;
} }
ubo_mi->Unmap(); mi_data_buffer->Unmap();
uint16 *idp=(uint16 *)(vbo_mi->Map()); uint16 *idp=(uint16 *)(mi_vab->Map());
{ {
rn=render_node; rn=render_node;
@ -186,6 +186,6 @@ void RenderMIBuffer::WriteNode(RenderNode *render_node,const uint count,const Ma
} }
} }
vbo_mi->Unmap(); mi_vab->Unmap();
} }
VK_NAMESPACE_END VK_NAMESPACE_END

View File

@ -31,7 +31,7 @@ class RenderL2WBuffer
uint node_count; ///<渲染节点数量 uint node_count; ///<渲染节点数量
VBO *l2w_vbo[4]; VAB *l2w_vbo[4];
VkBuffer l2w_buffer[4]; VkBuffer l2w_buffer[4];
private: private:
@ -65,9 +65,9 @@ private:
uint32_t mi_data_bytes; ///<材质实例数据字节数 uint32_t mi_data_bytes; ///<材质实例数据字节数
uint32_t mi_count; ///<材质实例数量 uint32_t mi_count; ///<材质实例数量
DeviceBuffer *ubo_mi; ///<材质实例数据 DeviceBuffer *mi_data_buffer; ///<材质实例数据(UBO/SSBO)
VBO *vbo_mi; ///<材质实例ID(R16UI格式) VAB *mi_vab; ///<材质实例ID(R16UI格式)
VkBuffer mi_buffer; VkBuffer mi_buffer;
private: private:

View File

@ -16,9 +16,9 @@ namespace hgl
vi_count=_vil->GetCount(); vi_count=_vil->GetCount();
vif_list=_vil->GetVIFList(); //来自于Material不会被释放所以指针有效 vif_list=_vil->GetVIFList(); //来自于Material不会被释放所以指针有效
vbo_max_size=0; vab_max_size=0;
vbo_cur_size=0; vab_cur_size=0;
vbo=hgl_zero_new<VBO *>(vi_count); vab=hgl_zero_new<VAB *>(vi_count);
ibo_cur_size=0; ibo_cur_size=0;
ibo=nullptr; ibo=nullptr;
@ -26,7 +26,7 @@ namespace hgl
VertexDataManager::~VertexDataManager() VertexDataManager::~VertexDataManager()
{ {
SAFE_CLEAR_OBJECT_ARRAY(vbo,vi_count); SAFE_CLEAR_OBJECT_ARRAY(vab,vi_count);
SAFE_CLEAR(ibo); SAFE_CLEAR(ibo);
} }
@ -38,26 +38,26 @@ namespace hgl
*/ */
bool VertexDataManager::Init(const VkDeviceSize vbo_size,const VkDeviceSize ibo_size,const IndexType index_type) bool VertexDataManager::Init(const VkDeviceSize vbo_size,const VkDeviceSize ibo_size,const IndexType index_type)
{ {
if(vbo[0]||ibo) //已经初始化过了 if(vab[0]||ibo) //已经初始化过了
return(false); return(false);
if(vbo_size<=0) if(vbo_size<=0)
return(false); return(false);
vbo_max_size=vbo_size; vab_max_size=vbo_size;
ibo_cur_size=ibo_size; ibo_cur_size=ibo_size;
vbo_cur_size=0; vab_cur_size=0;
ibo_cur_size=0; ibo_cur_size=0;
for(uint i=0;i<vi_count;i++) for(uint i=0;i<vi_count;i++)
{ {
vbo[i]=device->CreateVBO(vif_list[i].format,vbo_max_size); vab[i]=device->CreateVAB(vif_list[i].format,vab_max_size);
if(!vbo[i]) if(!vab[i])
return(false); return(false);
} }
vbo_data_chain.Init(vbo_max_size); vbo_data_chain.Init(vab_max_size);
if(ibo_size>0) if(ibo_size>0)
{ {

View File

@ -55,7 +55,7 @@ bool GPUDevice::CreateBuffer(DeviceBufferData *buf,VkBufferUsageFlags buf_usage,
return(false); return(false);
} }
VBO *GPUDevice::CreateVBO(VkFormat format,uint32_t count,const void *data,SharingMode sharing_mode) VAB *GPUDevice::CreateVAB(VkFormat format,uint32_t count,const void *data,SharingMode sharing_mode)
{ {
if(count==0)return(nullptr); if(count==0)return(nullptr);

View File

@ -27,16 +27,16 @@ VK_NAMESPACE_BEGIN
// return(true); // return(true);
//} //}
bool Primitive::Set(const AnsiString &name,VBO *vbo,VkDeviceSize offset) bool Primitive::Set(const AnsiString &name,VAB *vab,VkDeviceSize offset)
{ {
if(!vbo)return(false); if(!vab)return(false);
if(buffer_list.KeyExist(name))return(false); if(buffer_list.KeyExist(name))return(false);
VBOAccessData vad; VABAccess vad;
vad.vbo=vbo; vad.vab=vab;
vad.offset=offset; vad.offset=offset;
vad.size=vbo->GetBytes(); vad.size=vab->GetBytes();
buffer_list.Add(name,vad); buffer_list.Add(name,vad);
@ -45,15 +45,15 @@ bool Primitive::Set(const AnsiString &name,VBO *vbo,VkDeviceSize offset)
if(du) if(du)
{ {
du->SetBuffer(vbo->GetBuffer(),prim_name+":VBO:Buffer:"+name); du->SetBuffer(vab->GetBuffer(),prim_name+":VBO:Buffer:"+name);
du->SetDeviceMemory(vbo->GetVkMemory(),prim_name+":VBO:Memory:"+name); du->SetDeviceMemory(vab->GetVkMemory(),prim_name+":VBO:Memory:"+name);
} }
#endif//_DEBUG #endif//_DEBUG
return(true); return(true);
} }
bool Primitive::GetVBOAccessData(const AnsiString &name,VBOAccessData *vad) bool Primitive::GetVBOAccessData(const AnsiString &name,VABAccess *vad)
{ {
if(name.IsEmpty())return(false); if(name.IsEmpty())return(false);
if(!vad)return(false); if(!vad)return(false);

View File

@ -5,9 +5,9 @@
#include<hgl/graph/VKVertexAttribBuffer.h> #include<hgl/graph/VKVertexAttribBuffer.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
VBO *RenderResource::CreateVBO(VkFormat format,uint32_t count,const void *data,SharingMode sharing_mode) VAB *RenderResource::CreateVAB(VkFormat format,uint32_t count,const void *data,SharingMode sharing_mode)
{ {
VBO *vb=device->CreateVBO(format,count,data,sharing_mode); VAB *vb=device->CreateVAB(format,count,data,sharing_mode);
if(!vb) if(!vb)
return(nullptr); return(nullptr);

View File

@ -55,12 +55,12 @@ Renderable *CreateRenderable(Primitive *prim,MaterialInstance *mi,Pipeline *p)
return(nullptr); return(nullptr);
} }
VBO *vbo; VAB *vab;
VertexInputData *vid=new VertexInputData(input_count,prim->GetVertexCount(),prim->GetIndexBufferData()); VertexInputData *vid=new VertexInputData(input_count,prim->GetVertexCount(),prim->GetIndexBufferData());
const VertexInputFormat *vif=vil->GetVIFList(VertexInputGroup::Basic); const VertexInputFormat *vif=vil->GetVIFList(VertexInputGroup::Basic);
VBOAccessData vad; VABAccess vad;
for(uint i=0;i<input_count;i++) for(uint i=0;i<input_count;i++)
{ {
@ -73,30 +73,30 @@ Renderable *CreateRenderable(Primitive *prim,MaterialInstance *mi,Pipeline *p)
return(nullptr); return(nullptr);
} }
vbo=vad.vbo; vab=vad.vab;
if(vbo->GetFormat()!=vif->format) if(vab->GetFormat()!=vif->format)
{ {
LOG_ERROR( "[FATAL ERROR] VBO \""+UTF8String(vif->name)+ LOG_ERROR( "[FATAL ERROR] VBO \""+UTF8String(vif->name)+
UTF8String("\" format can't match Renderable, Material(")+mtl_name+ UTF8String("\" format can't match Renderable, Material(")+mtl_name+
UTF8String(") Format(")+GetVulkanFormatName(vif->format)+ UTF8String(") Format(")+GetVulkanFormatName(vif->format)+
UTF8String("), VBO Format(")+GetVulkanFormatName(vbo->GetFormat())+ UTF8String("), VBO Format(")+GetVulkanFormatName(vab->GetFormat())+
")"); ")");
return(nullptr); return(nullptr);
} }
if(vbo->GetStride()!=vif->stride) if(vab->GetStride()!=vif->stride)
{ {
LOG_ERROR( "[FATAL ERROR] VBO \""+UTF8String(vif->name)+ LOG_ERROR( "[FATAL ERROR] VBO \""+UTF8String(vif->name)+
UTF8String("\" stride can't match Renderable, Material(")+mtl_name+ UTF8String("\" stride can't match Renderable, Material(")+mtl_name+
UTF8String(") stride(")+UTF8String::numberOf(vif->stride)+ UTF8String(") stride(")+UTF8String::numberOf(vif->stride)+
UTF8String("), VBO stride(")+UTF8String::numberOf(vbo->GetStride())+ UTF8String("), VBO stride(")+UTF8String::numberOf(vab->GetStride())+
")"); ")");
return(nullptr); return(nullptr);
} }
vid->buffer_offset[i]=vad.offset; vid->buffer_offset[i]=vad.offset;
vid->buffer_list[i]=vbo->GetBuffer(); vid->buffer_list[i]=vab->GetBuffer();
++vif; ++vif;
} }