diff --git a/inc/hgl/graph/VertexBuffer.h b/inc/hgl/graph/VertexBuffer.h index dd4e6b71..1fc342f6 100644 --- a/inc/hgl/graph/VertexBuffer.h +++ b/inc/hgl/graph/VertexBuffer.h @@ -21,17 +21,15 @@ namespace hgl { protected: - T *mem_type; ///<符合当前类型的地址 - T *access; ///<当前访问地址 + T *mem_type; ///<符合当前类型的地址 + T *access; ///<当前访问地址 - T *start; ///<访问起始地址 + T *start; ///<访问起始地址 public: - VertexBuffer(int _size,const T *_data=nullptr,uint level=GL_STATIC_DRAW):VertexBufferBase(level,C*_size*sizeof(T)) + VertexBuffer(const uint type,const uint dt,const int _size,const T *_data=nullptr,uint level=GL_STATIC_DRAW):VertexBufferBase(type,dt,sizeof(T),C,_size,level) { - dc_num=C; - count=_size; mem_type=(T *)GetData(); @@ -39,16 +37,14 @@ namespace hgl start=0; if(_data) - memcpy(mem_type,_data,bytes); + { + memcpy(mem_type,_data,this->total_bytes); + this->Update(); + } } virtual ~VertexBuffer()=default; - int GetDataBytes()const - { - return sizeof(T); - } - void SetCount(int _count) { count=_count; @@ -102,9 +98,9 @@ namespace hgl */ void End() { - ChangeVertexBuffer( ((char *)start )-((char *)mem_type), - ((char *)access)-((char *)start), - start); + this->Change(((char *)start )-((char *)mem_type), + ((char *)access)-((char *)start), + start); access=nullptr; start=nullptr; @@ -134,15 +130,14 @@ namespace hgl /** * 一元数据缓冲区 */ - template class VertexBuffer1:public VertexBuffer + template class VertexBuffer1:public VertexBuffer { public: - using VertexBuffer::VertexBuffer; + VertexBuffer1(const uint type,const int _size,const T *_data=nullptr,uint level=GL_STATIC_DRAW):VertexBuffer(type,DT,_size,_data,level){} + VertexBuffer1(const int _size,const T *_data=nullptr,uint level=GL_STATIC_DRAW):VertexBuffer(GL_ARRAY_BUFFER,DT,_size,_data,level){} virtual ~VertexBuffer1()=default; - uint GetDataType()const; - bool Write(const T v1) { if(!this->access||this->access+1>this->mem_end) @@ -160,7 +155,7 @@ namespace hgl * @param v 值 * @param count 写入数量 */ - bool Write(const T v,const int count) + bool WriteRepeat(const T v,const int count) { if(!this->access||this->access+count>this->mem_end) { @@ -174,18 +169,26 @@ namespace hgl } };//class VertexBuffer1 + /** + * 索引数据缓冲区 + */ + template class ElementBuffer:public VertexBuffer1 + { + public: + ElementBuffer(const int _size,const T *_data=nullptr,uint level=GL_STATIC_DRAW):VertexBuffer1(GL_ELEMENT_ARRAY_BUFFER,DT,_size,_data,level){} + virtual ~ElementBuffer()=default; + };// + /** * 二元数据缓冲区 */ - template class VertexBuffer2:public VertexBuffer + template class VertexBuffer2:public VertexBuffer { public: - using VertexBuffer::VertexBuffer; + VertexBuffer2(const int _size,const T *_data=nullptr,uint level=GL_STATIC_DRAW):VertexBuffer(GL_ARRAY_BUFFER,DT,_size,_data,level){} virtual ~VertexBuffer2()=default; - uint GetDataType()const; - bool Write(const T v1,const T v2) { if(!this->access||this->access+2>this->mem_end) @@ -360,15 +363,13 @@ namespace hgl /** * 三元数据缓冲区 */ - template class VertexBuffer3:public VertexBuffer + template class VertexBuffer3:public VertexBuffer { public: - using VertexBuffer::VertexBuffer; + VertexBuffer3(const int _size,const T *_data=nullptr,uint level=GL_STATIC_DRAW):VertexBuffer(GL_ARRAY_BUFFER,DT,_size,_data,level){} virtual ~VertexBuffer3()=default; - uint GetDataType()const; - /** * 计算绑定盒 * @param min_vertex 最小值坐标 @@ -607,15 +608,13 @@ namespace hgl /** * 四元数据缓冲区 */ - template class VertexBuffer4:public VertexBuffer + template class VertexBuffer4:public VertexBuffer { public: - using VertexBuffer::VertexBuffer; + VertexBuffer4(const int _size,const T *_data=nullptr,uint level=GL_STATIC_DRAW):VertexBuffer(GL_ARRAY_BUFFER,DT,_size,_data,level){} virtual ~VertexBuffer4()=default; - uint GetDataType()const; - /** * 计算绑定盒 * @param min_vertex 最小值坐标 @@ -884,44 +883,33 @@ namespace hgl };//class VertexBuffer4 //缓冲区具体数据类型定义 - typedef VertexBuffer1 VB1i8 ,VB1b; template<> inline uint VertexBuffer1::GetDataType()const{return GL_BYTE; } - typedef VertexBuffer1 VB1i16 ,VB1s; template<> inline uint VertexBuffer1::GetDataType()const{return GL_SHORT; } - typedef VertexBuffer1 VB1i32 ,VB1i; template<> inline uint VertexBuffer1::GetDataType()const{return GL_INT; } - typedef VertexBuffer1 VB1u8 ,VB1ub; template<> inline uint VertexBuffer1::GetDataType()const{return GL_UNSIGNED_BYTE; } - typedef VertexBuffer1 VB1u16 ,VB1us; template<> inline uint VertexBuffer1::GetDataType()const{return GL_UNSIGNED_SHORT;} - typedef VertexBuffer1 VB1u32 ,VB1ui; template<> inline uint VertexBuffer1::GetDataType()const{return GL_UNSIGNED_INT; } - typedef VertexBuffer1 VB1f; template<> inline uint VertexBuffer1::GetDataType()const{return GL_FLOAT; } - typedef VertexBuffer1 VB1d; template<> inline uint VertexBuffer1::GetDataType()const{return GL_DOUBLE; } + using EB16=ElementBuffer; + using EB32=ElementBuffer; - using EB16=VB1u16; - using EB32=VB1u32; +#define USING_VB1234(type,gl_type,short_name) using VB1##short_name=VertexBuffer1; \ + using VB2##short_name=VertexBuffer2; \ + using VB3##short_name=VertexBuffer3; \ + using VB4##short_name=VertexBuffer4; - typedef VertexBuffer2 VB2i8 ,VB2b; template<> inline uint VertexBuffer2::GetDataType()const{return GL_BYTE; } - typedef VertexBuffer2 VB2i16 ,VB2s; template<> inline uint VertexBuffer2::GetDataType()const{return GL_SHORT; } - typedef VertexBuffer2 VB2i32 ,VB2i; template<> inline uint VertexBuffer2::GetDataType()const{return GL_INT; } - typedef VertexBuffer2 VB2u8 ,VB2ub; template<> inline uint VertexBuffer2::GetDataType()const{return GL_UNSIGNED_BYTE; } - typedef VertexBuffer2 VB2u16 ,VB2us; template<> inline uint VertexBuffer2::GetDataType()const{return GL_UNSIGNED_SHORT;} - typedef VertexBuffer2 VB2u32 ,VB2ui; template<> inline uint VertexBuffer2::GetDataType()const{return GL_UNSIGNED_INT; } - typedef VertexBuffer2 VB2f; template<> inline uint VertexBuffer2::GetDataType()const{return GL_FLOAT; } - typedef VertexBuffer2 VB2d; template<> inline uint VertexBuffer2::GetDataType()const{return GL_DOUBLE; } + USING_VB1234(int8, GL_BYTE, i8) + USING_VB1234(int8, GL_BYTE, b) + USING_VB1234(int16, GL_SHORT, i16) + USING_VB1234(int16, GL_SHORT, s) + USING_VB1234(int32, GL_INT, i32) + USING_VB1234(int32, GL_INT, i) - typedef VertexBuffer3 VB3i8 ,VB3b; template<> inline uint VertexBuffer3::GetDataType()const{return GL_BYTE; } - typedef VertexBuffer3 VB3i16 ,VB3s; template<> inline uint VertexBuffer3::GetDataType()const{return GL_SHORT; } - typedef VertexBuffer3 VB3i32 ,VB3i; template<> inline uint VertexBuffer3::GetDataType()const{return GL_INT; } - typedef VertexBuffer3 VB3u8 ,VB3ub; template<> inline uint VertexBuffer3::GetDataType()const{return GL_UNSIGNED_BYTE; } - typedef VertexBuffer3 VB3u16 ,VB3us; template<> inline uint VertexBuffer3::GetDataType()const{return GL_UNSIGNED_SHORT;} - typedef VertexBuffer3 VB3u32 ,VB3ui; template<> inline uint VertexBuffer3::GetDataType()const{return GL_UNSIGNED_INT; } - typedef VertexBuffer3 VB3f; template<> inline uint VertexBuffer3::GetDataType()const{return GL_FLOAT; } - typedef VertexBuffer3 VB3d; template<> inline uint VertexBuffer3::GetDataType()const{return GL_DOUBLE; } + USING_VB1234(int8, GL_UNSIGNED_BYTE, u8) + USING_VB1234(int8, GL_UNSIGNED_BYTE, ub) + USING_VB1234(int16, GL_UNSIGNED_SHORT, u16) + USING_VB1234(int16, GL_UNSIGNED_SHORT, us) + USING_VB1234(int32, GL_UNSIGNED_INT, u32) + USING_VB1234(int32, GL_UNSIGNED_INT, ui) + + USING_VB1234(float, GL_FLOAT, f) + USING_VB1234(double,GL_DOUBLE, d) + +#undef USING_VB1234 - typedef VertexBuffer4 VB4i8 ,VB4b; template<> inline uint VertexBuffer4::GetDataType()const{return GL_BYTE; } - typedef VertexBuffer4 VB4i16 ,VB4s; template<> inline uint VertexBuffer4::GetDataType()const{return GL_SHORT; } - typedef VertexBuffer4 VB4i32 ,VB4i; template<> inline uint VertexBuffer4::GetDataType()const{return GL_INT; } - typedef VertexBuffer4 VB4u8 ,VB4ub; template<> inline uint VertexBuffer4::GetDataType()const{return GL_UNSIGNED_BYTE; } - typedef VertexBuffer4 VB4u16 ,VB4us; template<> inline uint VertexBuffer4::GetDataType()const{return GL_UNSIGNED_SHORT;} - typedef VertexBuffer4 VB4u32 ,VB4ui; template<> inline uint VertexBuffer4::GetDataType()const{return GL_UNSIGNED_INT; } - typedef VertexBuffer4 VB4f; template<> inline uint VertexBuffer4::GetDataType()const{return GL_FLOAT; } - typedef VertexBuffer4 VB4d; template<> inline uint VertexBuffer4::GetDataType()const{return GL_DOUBLE; } }//namespace graph }//namespace hgl #endif//HGL_VERTEX_BUFFER_OBJECT_INCLUDE diff --git a/inc/hgl/graph/VertexBufferBase.h b/inc/hgl/graph/VertexBufferBase.h index 8513a8c7..887b7579 100644 --- a/inc/hgl/graph/VertexBufferBase.h +++ b/inc/hgl/graph/VertexBufferBase.h @@ -10,22 +10,27 @@ namespace hgl class VertexBufferBase { - void *mem_data; ///<内存中的数据 + void *mem_data; ///<内存中的数据 protected: - int dc_num; ///<每个数据成员数(比如二维坐标为2、三维坐标为3) - int count; ///<数据个数 + uint vb_type; ///<缓冲区类型(GL_ARRAY_BUFFER,GL_ELEMENT_ARRAY_BUFFER等) - int bytes; ///<字节数 + uint dc_num; ///<每个数据成员数(比如二维坐标为2、三维坐标为3) + uint data_type; ///<单个数据类型(GL_BYTE,GL_UNSIGNED_SHORT等) + uint data_bytes; - void *mem_end; ///<内存数据区访问结束地址 + uint count; ///<数据个数 + + uint total_bytes; ///<总据总字节数 + + void *mem_end; ///<内存数据区访问结束地址 protected: - uint data_level; ///<数据级别 + uint data_usage; ///<数据使用方式 - VertexBufferControl *vbc; ///<顶点缓冲区控制器 + VertexBufferControl *vbc; ///<顶点缓冲区控制器 protected: @@ -33,25 +38,33 @@ namespace hgl public: - VertexBufferBase(uint level,uint size); + /** + * @param type 缓冲区类型(GL_ARRAY_BUFFER,GL_ELEMENT_ARRAY_BUFFER等) + * @param dt 单个数据类型 (GL_BYTE,GL_UNSIGNED_SHORT,GL_FLOAT等) + * @param dbyte 单个数据字节数 (GL_BYTE为1,GL_UNSIGNED_SHORT为2,GL_FLOAT为4等) + * @param dcm 数据成员数 (1/2/3/4,如2D纹理坐标用2,3D坐标用3) + * @param size 数据数量 + * @param usage 存取使用方式(GL_STATIC_DRAW,GL_DYNAMIC_DRAW等) + */ + VertexBufferBase(uint type,uint dt,uint dbyte,uint dcm,uint size,uint usage); virtual ~VertexBufferBase(); - virtual uint GetDataType()const=0; ///<取得数据类型 - virtual int GetDataBytes()const=0; ///<取得每数据字节数 - int GetComponent()const { return dc_num; } ///<取数缓冲区元数据数量 - int GetCount()const { return count; } ///<取得数据数量 - int GetStride()const { return dc_num*GetDataBytes();} ///<取得每一组数据字节数 - void * GetData()const { return mem_data;} ///<取得数据指针 - void * GetData(const uint offset){return ((char *)mem_data)+GetDataBytes()*offset;}///<取得数据指针 - int GetBytes()const { return bytes; } ///<取得数据字节数 + uint GetBufferType ()const {return vb_type;} ///<取得缓冲区类型 + uint GetDataType ()const {return data_type;} ///<取得数据类型 + uint GetComponent ()const {return dc_num;} ///<取数每一组数据中的数据数量 + uint GetCount ()const {return count;} ///<取得数据数量 + uint GetStride ()const {return dc_num*data_bytes;} ///<取得每一组数据字节数 + uint GetTotalBytes ()const {return total_bytes;} ///<取得数据总字节数 + void * GetData ()const {return mem_data;} ///<取得数据指针 + void * GetData (const uint off){return ((char *)mem_data)+data_bytes*off;} ///<取得数据指针 - public: //以下函数在各渲染器内部实现 + public: - bool CreateVertexBuffer(uint type); - void ChangeVertexBuffer(int,int,void *); - //void BindVertexBuffer(); - int GetBufferIndex()const; ///<取得缓冲区索引 - void CloseVertexBuffer(); + void Update(); ///<完整更新内存中的数据到显示 + + void Change(int,int,void *); + //void BindVertexBuffer(); + int GetBufferIndex()const; ///<取得缓冲区索引 };//class VertexBufferBase }//namespace graph }//namespace hgl diff --git a/src/RenderDriver/VertexBuffer.cpp b/src/RenderDriver/VertexBuffer.cpp index 024cbb9c..c0d59bd2 100644 --- a/src/RenderDriver/VertexBuffer.cpp +++ b/src/RenderDriver/VertexBuffer.cpp @@ -10,45 +10,24 @@ namespace hgl VertexBufferControl *CreateVertexBufferControlDSA(uint); VertexBufferControl *CreateVertexBufferControlBind(uint); - VertexBufferControl *(*CreateVertexBufferControl)(uint)=nullptr; - - void DeleteVertexBufferControlDSA(VertexBufferControl *); - void DeleteVertexBufferControlBind(VertexBufferControl *); - - void (*DeleteVertexBufferControl)(VertexBufferControl *)=nullptr; - - void InitVertexBufferDSA() + namespace { - CreateVertexBufferControl=CreateVertexBufferControlDSA; - DeleteVertexBufferControl=DeleteVertexBufferControlDSA; - } + static VertexBufferControl *(*CreateVertexBufferControl)(uint)=nullptr; - void InitVertexBufferBind() - { - CreateVertexBufferControl=CreateVertexBufferControlBind; - DeleteVertexBufferControl=DeleteVertexBufferControlBind; - } - - bool InitVertexBufferAPI() - { - if (GLEW_ARB_direct_state_access) //4.5 + void InitVertexBufferAPI() { - InitVertexBufferDSA(); - return(true); + if(GLEW_VERSION_4_5||GLEW_ARB_direct_state_access) + CreateVertexBufferControl=CreateVertexBufferControlDSA; + else + CreateVertexBufferControl=CreateVertexBufferControlBind; } + }//namespace - InitVertexBufferBind(); - return(true); - } - }//namespace graph - - namespace graph - { void VertexBufferBase::SetDataSize(int size) { - if (bytes == size)return; + if (total_bytes == size)return; - bytes = size; + total_bytes = size; if (mem_data) mem_data = hgl_realloc(mem_data, size); @@ -58,57 +37,48 @@ namespace hgl mem_end = ((char *)mem_data) + size; } - VertexBufferBase::VertexBufferBase(uint level, uint size) + VertexBufferBase::VertexBufferBase(uint type,uint dt,uint dbyte,uint dcm,uint size,uint usage) { - dc_num = 0; + vb_type =type; + data_type =dt; + data_bytes =dbyte; - bytes = size; + dc_num =dcm; + count =size; + total_bytes =dcm*size*dbyte; - mem_data = hgl_malloc(size); //在很多情况下,hgl_malloc分配的内存是对齐的,这样有效率上的提升 - mem_end = ((char *)mem_data) + size; + mem_data =hgl_malloc(total_bytes); //在很多情况下,hgl_malloc分配的内存是对齐的,这样有效率上的提升 + mem_end =((char *)mem_data)+total_bytes; - data_level = level; + data_usage =usage; - vbc=nullptr; + if(!CreateVertexBufferControl) + InitVertexBufferAPI(); + + vbc=CreateVertexBufferControl(type); } VertexBufferBase::~VertexBufferBase() { - CloseVertexBuffer(); - hgl_free(mem_data); - if(vbc) - DeleteVertexBufferControl(vbc); + SAFE_CLEAR(vbc); } - void VertexBufferBase::CloseVertexBuffer() + void VertexBufferBase::Update() { - if(!vbc)return; + if(!vbc)return; - DeleteVertexBufferControl(vbc); - vbc = nullptr; + vbc->Set(total_bytes,mem_data,data_usage); } - void VertexBufferBase::ChangeVertexBuffer(int start, int size, void *data) + void VertexBufferBase::Change(int start, int size, void *data) { if (!vbc)return; vbc->Change(start,size,data); } - bool VertexBufferBase::CreateVertexBuffer(uint type) - { - DeleteVertexBufferControl(vbc); - - vbc=CreateVertexBufferControl(type); - - if(vbc) - vbc->Set(bytes,mem_data,data_level); - - return vbc; - } - // void VertexBufferBase::BindVertexBuffer() // { // if(!video_buffer_type)return; @@ -121,27 +91,4 @@ namespace hgl return vbc?vbc->GetIndex():-1; } }//namespace graph - - namespace graph - { - /** - * 设置顶点缓冲区数据 - * @param vbt 顶点缓冲区类型 - * @param vb 数据缓冲区 - * @return 是否设置成功 - */ - bool VertexArray::_SetVertexBuffer(VertexBufferBase *vb) - { - vb->CreateVertexBuffer(GL_ARRAY_BUFFER); - - return(true); - } - - bool VertexArray::_SetElementBuffer() - { - element_buffer->CreateVertexBuffer(GL_ELEMENT_ARRAY_BUFFER); - - return(true); - } - }//namespace graph }//namespace hgl diff --git a/src/RenderDriver/VertexBufferControl.h b/src/RenderDriver/VertexBufferControl.h index 9f5658a7..775b8c6c 100644 --- a/src/RenderDriver/VertexBufferControl.h +++ b/src/RenderDriver/VertexBufferControl.h @@ -26,8 +26,8 @@ namespace hgl Clear(); } - virtual void Set(int, void *,uint)=0; - virtual void Change(int, int, void *)=0; + virtual void Set(GLsizei, void *,GLenum)=0; + virtual void Change(GLintptr,GLsizei, void *)=0; void Clear() { if(!type||!index)return; diff --git a/src/RenderDriver/VertexBufferControlBind.cpp b/src/RenderDriver/VertexBufferControlBind.cpp index f3b94ce6..f345fdbc 100644 --- a/src/RenderDriver/VertexBufferControlBind.cpp +++ b/src/RenderDriver/VertexBufferControlBind.cpp @@ -29,14 +29,18 @@ namespace hgl public: using VertexBufferControl::VertexBufferControl; - - void Set(int size, void *data, uint data_level) + ~VertexBufferControlBind() { - glBindBuffer(this->type,this->index); - glBufferData(this->type, size, data, data_level); + glDeleteBuffers(1,&(this->index)); } - void Change(int start, int size, void *data) + void Set(GLsizei size, void *data, GLenum data_usage) + { + glBindBuffer(this->type,this->index); + glBufferData(this->type, size, data, data_usage); + } + + void Change(GLintptr start, GLsizei size, void *data) { glBindBuffer(this->type, this->index); glBufferSubData(this->type, start, size, data); @@ -50,10 +54,5 @@ namespace hgl glGenBuffers(1, &index); return(new VertexBufferControlBind(type, index)); } - - void DeleteVertexBufferControlBind(VertexBufferControl *vbc) - { - SAFE_CLEAR(vbc); - } }//namespace graph }//namespace hgl diff --git a/src/RenderDriver/VertexBufferControlDSA.cpp b/src/RenderDriver/VertexBufferControlDSA.cpp index 8d79ca5a..80e43494 100644 --- a/src/RenderDriver/VertexBufferControlDSA.cpp +++ b/src/RenderDriver/VertexBufferControlDSA.cpp @@ -11,12 +11,12 @@ namespace hgl using VertexBufferControl::VertexBufferControl; - void Set(int size, void *data,uint data_level) + void Set(GLsizei size, void *data,GLenum data_usage) { - glNamedBufferData(this->index, size, data, data_level); + glNamedBufferData(this->index, size, data, data_usage); } - void Change(int start, int size, void *data) + void Change(GLintptr start, GLsizei size, void *data) { glNamedBufferSubData(this->index, start, size, data); }