#include"VKPrimitiveData.h" #include #include #include #include #include VK_NAMESPACE_BEGIN PrimitiveData::PrimitiveData(const VIL *_vil,const uint32_t vc) { vil=_vil; vertex_count=vc; vab_list=hgl_zero_new(_vil->GetVertexAttribCount()); ibo=nullptr; } PrimitiveData::~PrimitiveData() { delete[] vab_list; //注意:这里并不释放VAB,在派生类中释放 } const int PrimitiveData::GetVABCount()const { return vil->GetVertexAttribCount(); } const int PrimitiveData::GetVABIndex(const AnsiString &name) const { if(name.IsEmpty())return(-1); return vil->GetIndex(name); } VAB *PrimitiveData::GetVAB(const int index) { if(index<0||index>=vil->GetVertexAttribCount())return(nullptr); return vab_list[index]; } namespace { /** * 直接使用GPUDevice创建VAB/IBO,并在释构时释放 */ class PrimitiveDataPrivateBuffer:public PrimitiveData { GPUDevice *device; public: int32_t GetVertexOffset ()const override{return 0;} uint32_t GetFirstIndex ()const override{return 0;} VertexDataManager * GetVDM()const override{return nullptr;} ///<取得顶点数据管理器 public: PrimitiveDataPrivateBuffer(GPUDevice *dev,const VIL *_vil,const uint32_t vc):PrimitiveData(_vil,vc) { device=dev; } ~PrimitiveDataPrivateBuffer() override { VAB **vab=vab_list; for(uint i=0;iGetVertexAttribCount();i++) { if(*vab) delete *vab; ++vab; } if(ibo) delete ibo; } IndexBuffer *InitIBO(const uint32_t ic,IndexType it) override { if(!device)return(nullptr); if(ibo)delete ibo; ibo=device->CreateIBO(it,ic); if(!ibo) return(nullptr); index_count=ic; return(ibo); } VAB *InitVAB(const int vab_index,const VkFormat &format,const void *data) { if(!device)return(nullptr); if(!vil)return(nullptr); if(vab_index<0||vab_index>=vil->GetVertexAttribCount()) return(nullptr); const VertexInputFormat *vif=vil->GetConfig(vab_index); if(!vif)return(nullptr); if(vif->format!=format) return(nullptr); if(!vab_list[vab_index]) { vab_list[vab_index]=device->CreateVAB(format,vertex_count,data); if(!vab_list[vab_index]) return(nullptr); } if(vab_list[vab_index]&&data) { vab_list[vab_index]->Write(data,vertex_count); } return vab_list[vab_index]; } };//class PrimitiveDataPrivateBuffer:public PrimitiveData /** * 使用VertexDataBuffer分配VAB/IBO,在本类析构时归还数据 */ class PrimitiveDataVDM:public PrimitiveData { VertexDataManager *vdm; DataChain::UserNode *ib_node; DataChain::UserNode *vab_node; public: int32_t GetVertexOffset()const override { return vab_node->GetStart(); } uint32_t GetFirstIndex ()const override { return ib_node->GetStart(); } VertexDataManager * GetVDM()const override{return vdm;} ///<取得顶点数据管理器 public: PrimitiveDataVDM(VertexDataManager *_vdm,const uint32_t vc):PrimitiveData(_vdm->GetVIL(),vc) { vdm=_vdm; ib_node=nullptr; vab_node=vdm->AcquireVAB(vc); } ~PrimitiveDataVDM() override { if(ib_node) vdm->ReleaseIB(ib_node); if(vab_node) vdm->ReleaseVAB(vab_node); } IndexBuffer *InitIBO(const uint32_t ic,IndexType it) override { if(ic<=0)return(nullptr); if(!vdm)return(nullptr); if(!ib_node) { ib_node=vdm->AcquireIB(ic); if(!ib_node) return(nullptr); ibo=vdm->GetIBO(); } index_count=ic; return ibo; } VAB *InitVAB(const int vab_index,const VkFormat &format,const void *data) { if(!vdm)return(nullptr); if(!vil)return(nullptr); if (vab_index<0||vab_index>=vil->GetVertexAttribCount()) return(nullptr); const VertexInputFormat *vif=vil->GetConfig(vab_index); if(!vif)return(nullptr); if(vif->format!=format) return(nullptr); if (!vab_list[vab_index]) { vab_list[vab_index]=vdm->GetVAB(vab_index); if(!vab_list[vab_index]) return(nullptr); } if(vab_list[vab_index]&&data) vab_list[vab_index]->Write(data,vab_node->GetStart(),vertex_count); return vab_list[vab_index]; } };//class PrimitiveDataVDM:public PrimitiveData }//namespace PrimitiveData *CreatePrimitiveData(GPUDevice *dev,const VIL *_vil,const uint32_t vc) { if(!dev)return(nullptr); if(!_vil)return(nullptr); if(vc<=0)return(nullptr); return(new PrimitiveDataPrivateBuffer(dev,_vil,vc)); } PrimitiveData *CreatePrimitiveData(VertexDataManager *vdm,const uint32_t vc) { if(!vdm)return(nullptr); if(vc<=0)return(nullptr); return(new PrimitiveDataVDM(vdm,vc)); } VK_NAMESPACE_END