更新VertexBuffer组织方式

This commit is contained in:
hyzboy 2018-12-07 15:32:01 +08:00
parent 04886888e3
commit 1fd65faade
6 changed files with 132 additions and 185 deletions

View File

@ -21,17 +21,15 @@ namespace hgl
{ {
protected: protected:
T *mem_type; ///<符合当前类型的地址 T *mem_type; ///<符合当前类型的地址
T *access; ///<当前访问地址 T *access; ///<当前访问地址
T *start; ///<访问起始地址 T *start; ///<访问起始地址
public: 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; count=_size;
mem_type=(T *)GetData(); mem_type=(T *)GetData();
@ -39,16 +37,14 @@ namespace hgl
start=0; start=0;
if(_data) if(_data)
memcpy(mem_type,_data,bytes); {
memcpy(mem_type,_data,this->total_bytes);
this->Update();
}
} }
virtual ~VertexBuffer()=default; virtual ~VertexBuffer()=default;
int GetDataBytes()const
{
return sizeof(T);
}
void SetCount(int _count) void SetCount(int _count)
{ {
count=_count; count=_count;
@ -102,9 +98,9 @@ namespace hgl
*/ */
void End() void End()
{ {
ChangeVertexBuffer( ((char *)start )-((char *)mem_type), this->Change(((char *)start )-((char *)mem_type),
((char *)access)-((char *)start), ((char *)access)-((char *)start),
start); start);
access=nullptr; access=nullptr;
start=nullptr; start=nullptr;
@ -134,15 +130,14 @@ namespace hgl
/** /**
* *
*/ */
template<typename T> class VertexBuffer1:public VertexBuffer<T,1> template<typename T,uint DT> class VertexBuffer1:public VertexBuffer<T,1>
{ {
public: public:
using VertexBuffer<T,1>::VertexBuffer; VertexBuffer1(const uint type,const int _size,const T *_data=nullptr,uint level=GL_STATIC_DRAW):VertexBuffer<T,1>(type,DT,_size,_data,level){}
VertexBuffer1(const int _size,const T *_data=nullptr,uint level=GL_STATIC_DRAW):VertexBuffer<T,1>(GL_ARRAY_BUFFER,DT,_size,_data,level){}
virtual ~VertexBuffer1()=default; virtual ~VertexBuffer1()=default;
uint GetDataType()const;
bool Write(const T v1) bool Write(const T v1)
{ {
if(!this->access||this->access+1>this->mem_end) if(!this->access||this->access+1>this->mem_end)
@ -160,7 +155,7 @@ namespace hgl
* @param v * @param v
* @param count * @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) if(!this->access||this->access+count>this->mem_end)
{ {
@ -174,18 +169,26 @@ namespace hgl
} }
};//class VertexBuffer1 };//class VertexBuffer1
/**
*
*/
template<typename T,uint DT> class ElementBuffer:public VertexBuffer1<T,DT>
{
public:
ElementBuffer(const int _size,const T *_data=nullptr,uint level=GL_STATIC_DRAW):VertexBuffer1<T,DT>(GL_ELEMENT_ARRAY_BUFFER,DT,_size,_data,level){}
virtual ~ElementBuffer()=default;
};//
/** /**
* *
*/ */
template<typename T> class VertexBuffer2:public VertexBuffer<T,2> template<typename T,uint DT> class VertexBuffer2:public VertexBuffer<T,2>
{ {
public: public:
using VertexBuffer<T,2>::VertexBuffer; VertexBuffer2(const int _size,const T *_data=nullptr,uint level=GL_STATIC_DRAW):VertexBuffer<T,2>(GL_ARRAY_BUFFER,DT,_size,_data,level){}
virtual ~VertexBuffer2()=default; virtual ~VertexBuffer2()=default;
uint GetDataType()const;
bool Write(const T v1,const T v2) bool Write(const T v1,const T v2)
{ {
if(!this->access||this->access+2>this->mem_end) if(!this->access||this->access+2>this->mem_end)
@ -360,15 +363,13 @@ namespace hgl
/** /**
* *
*/ */
template<typename T> class VertexBuffer3:public VertexBuffer<T,3> template<typename T,uint DT> class VertexBuffer3:public VertexBuffer<T,3>
{ {
public: public:
using VertexBuffer<T,3>::VertexBuffer; VertexBuffer3(const int _size,const T *_data=nullptr,uint level=GL_STATIC_DRAW):VertexBuffer<T,3>(GL_ARRAY_BUFFER,DT,_size,_data,level){}
virtual ~VertexBuffer3()=default; virtual ~VertexBuffer3()=default;
uint GetDataType()const;
/** /**
* *
* @param min_vertex * @param min_vertex
@ -607,15 +608,13 @@ namespace hgl
/** /**
* *
*/ */
template<typename T> class VertexBuffer4:public VertexBuffer<T,4> template<typename T,uint DT> class VertexBuffer4:public VertexBuffer<T,4>
{ {
public: public:
using VertexBuffer<T,4>::VertexBuffer; VertexBuffer4(const int _size,const T *_data=nullptr,uint level=GL_STATIC_DRAW):VertexBuffer<T,4>(GL_ARRAY_BUFFER,DT,_size,_data,level){}
virtual ~VertexBuffer4()=default; virtual ~VertexBuffer4()=default;
uint GetDataType()const;
/** /**
* *
* @param min_vertex * @param min_vertex
@ -884,44 +883,33 @@ namespace hgl
};//class VertexBuffer4 };//class VertexBuffer4
//缓冲区具体数据类型定义 //缓冲区具体数据类型定义
typedef VertexBuffer1<int8 > VB1i8 ,VB1b; template<> inline uint VertexBuffer1<int8 >::GetDataType()const{return GL_BYTE; } using EB16=ElementBuffer<uint16,GL_UNSIGNED_SHORT >;
typedef VertexBuffer1<int16 > VB1i16 ,VB1s; template<> inline uint VertexBuffer1<int16 >::GetDataType()const{return GL_SHORT; } using EB32=ElementBuffer<uint32,GL_UNSIGNED_INT >;
typedef VertexBuffer1<int32 > VB1i32 ,VB1i; template<> inline uint VertexBuffer1<int32 >::GetDataType()const{return GL_INT; }
typedef VertexBuffer1<uint8 > VB1u8 ,VB1ub; template<> inline uint VertexBuffer1<uint8 >::GetDataType()const{return GL_UNSIGNED_BYTE; }
typedef VertexBuffer1<uint16> VB1u16 ,VB1us; template<> inline uint VertexBuffer1<uint16 >::GetDataType()const{return GL_UNSIGNED_SHORT;}
typedef VertexBuffer1<uint32> VB1u32 ,VB1ui; template<> inline uint VertexBuffer1<uint32 >::GetDataType()const{return GL_UNSIGNED_INT; }
typedef VertexBuffer1<float > VB1f; template<> inline uint VertexBuffer1<float >::GetDataType()const{return GL_FLOAT; }
typedef VertexBuffer1<double> VB1d; template<> inline uint VertexBuffer1<double >::GetDataType()const{return GL_DOUBLE; }
using EB16=VB1u16; #define USING_VB1234(type,gl_type,short_name) using VB1##short_name=VertexBuffer1<type,gl_type>; \
using EB32=VB1u32; using VB2##short_name=VertexBuffer2<type,gl_type>; \
using VB3##short_name=VertexBuffer3<type,gl_type>; \
using VB4##short_name=VertexBuffer4<type,gl_type>;
typedef VertexBuffer2<int8 > VB2i8 ,VB2b; template<> inline uint VertexBuffer2<int8 >::GetDataType()const{return GL_BYTE; } USING_VB1234(int8, GL_BYTE, i8)
typedef VertexBuffer2<int16 > VB2i16 ,VB2s; template<> inline uint VertexBuffer2<int16 >::GetDataType()const{return GL_SHORT; } USING_VB1234(int8, GL_BYTE, b)
typedef VertexBuffer2<int32 > VB2i32 ,VB2i; template<> inline uint VertexBuffer2<int32 >::GetDataType()const{return GL_INT; } USING_VB1234(int16, GL_SHORT, i16)
typedef VertexBuffer2<uint8 > VB2u8 ,VB2ub; template<> inline uint VertexBuffer2<uint8 >::GetDataType()const{return GL_UNSIGNED_BYTE; } USING_VB1234(int16, GL_SHORT, s)
typedef VertexBuffer2<uint16> VB2u16 ,VB2us; template<> inline uint VertexBuffer2<uint16 >::GetDataType()const{return GL_UNSIGNED_SHORT;} USING_VB1234(int32, GL_INT, i32)
typedef VertexBuffer2<uint32> VB2u32 ,VB2ui; template<> inline uint VertexBuffer2<uint32 >::GetDataType()const{return GL_UNSIGNED_INT; } USING_VB1234(int32, GL_INT, i)
typedef VertexBuffer2<float > VB2f; template<> inline uint VertexBuffer2<float >::GetDataType()const{return GL_FLOAT; }
typedef VertexBuffer2<double> VB2d; template<> inline uint VertexBuffer2<double >::GetDataType()const{return GL_DOUBLE; }
typedef VertexBuffer3<int8 > VB3i8 ,VB3b; template<> inline uint VertexBuffer3<int8 >::GetDataType()const{return GL_BYTE; } USING_VB1234(int8, GL_UNSIGNED_BYTE, u8)
typedef VertexBuffer3<int16 > VB3i16 ,VB3s; template<> inline uint VertexBuffer3<int16 >::GetDataType()const{return GL_SHORT; } USING_VB1234(int8, GL_UNSIGNED_BYTE, ub)
typedef VertexBuffer3<int32 > VB3i32 ,VB3i; template<> inline uint VertexBuffer3<int32 >::GetDataType()const{return GL_INT; } USING_VB1234(int16, GL_UNSIGNED_SHORT, u16)
typedef VertexBuffer3<uint8 > VB3u8 ,VB3ub; template<> inline uint VertexBuffer3<uint8 >::GetDataType()const{return GL_UNSIGNED_BYTE; } USING_VB1234(int16, GL_UNSIGNED_SHORT, us)
typedef VertexBuffer3<uint16> VB3u16 ,VB3us; template<> inline uint VertexBuffer3<uint16 >::GetDataType()const{return GL_UNSIGNED_SHORT;} USING_VB1234(int32, GL_UNSIGNED_INT, u32)
typedef VertexBuffer3<uint32> VB3u32 ,VB3ui; template<> inline uint VertexBuffer3<uint32 >::GetDataType()const{return GL_UNSIGNED_INT; } USING_VB1234(int32, GL_UNSIGNED_INT, ui)
typedef VertexBuffer3<float > VB3f; template<> inline uint VertexBuffer3<float >::GetDataType()const{return GL_FLOAT; }
typedef VertexBuffer3<double> VB3d; template<> inline uint VertexBuffer3<double >::GetDataType()const{return GL_DOUBLE; } USING_VB1234(float, GL_FLOAT, f)
USING_VB1234(double,GL_DOUBLE, d)
#undef USING_VB1234
typedef VertexBuffer4<int8 > VB4i8 ,VB4b; template<> inline uint VertexBuffer4<int8 >::GetDataType()const{return GL_BYTE; }
typedef VertexBuffer4<int16 > VB4i16 ,VB4s; template<> inline uint VertexBuffer4<int16 >::GetDataType()const{return GL_SHORT; }
typedef VertexBuffer4<int32 > VB4i32 ,VB4i; template<> inline uint VertexBuffer4<int32 >::GetDataType()const{return GL_INT; }
typedef VertexBuffer4<uint8 > VB4u8 ,VB4ub; template<> inline uint VertexBuffer4<uint8 >::GetDataType()const{return GL_UNSIGNED_BYTE; }
typedef VertexBuffer4<uint16> VB4u16 ,VB4us; template<> inline uint VertexBuffer4<uint16 >::GetDataType()const{return GL_UNSIGNED_SHORT;}
typedef VertexBuffer4<uint32> VB4u32 ,VB4ui; template<> inline uint VertexBuffer4<uint32 >::GetDataType()const{return GL_UNSIGNED_INT; }
typedef VertexBuffer4<float > VB4f; template<> inline uint VertexBuffer4<float >::GetDataType()const{return GL_FLOAT; }
typedef VertexBuffer4<double> VB4d; template<> inline uint VertexBuffer4<double >::GetDataType()const{return GL_DOUBLE; }
}//namespace graph }//namespace graph
}//namespace hgl }//namespace hgl
#endif//HGL_VERTEX_BUFFER_OBJECT_INCLUDE #endif//HGL_VERTEX_BUFFER_OBJECT_INCLUDE

View File

@ -10,22 +10,27 @@ namespace hgl
class VertexBufferBase class VertexBufferBase
{ {
void *mem_data; ///<内存中的数据 void *mem_data; ///<内存中的数据
protected: protected:
int dc_num; ///<每个数据成员数(比如二维坐标为2、三维坐标为3) uint vb_type; ///<缓冲区类型(GL_ARRAY_BUFFER,GL_ELEMENT_ARRAY_BUFFER等)
int count; ///<数据个数
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: protected:
uint data_level; ///<数据级别 uint data_usage; ///<数据使用方式
VertexBufferControl *vbc; ///<顶点缓冲区控制器 VertexBufferControl *vbc; ///<顶点缓冲区控制器
protected: protected:
@ -33,25 +38,33 @@ namespace hgl
public: 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为2GL_FLOAT为4等)
* @param dcm (1/2/3/42D纹理坐标用23D坐标用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 ~VertexBufferBase();
virtual uint GetDataType()const=0; ///<取得数据类型 uint GetBufferType ()const {return vb_type;} ///<取得缓冲区类型
virtual int GetDataBytes()const=0; ///<取得每数据字节数 uint GetDataType ()const {return data_type;} ///<取得数据类型
int GetComponent()const { return dc_num; } ///<取数缓冲区元数据数量 uint GetComponent ()const {return dc_num;} ///<取数每一组数据中的数据数量
int GetCount()const { return count; } ///<取得数据数量 uint GetCount ()const {return count;} ///<取得数据数量
int GetStride()const { return dc_num*GetDataBytes();} ///<取得每一组数据字节数 uint GetStride ()const {return dc_num*data_bytes;} ///<取得每一组数据字节数
void * GetData()const { return mem_data;} ///<取得数据指针 uint GetTotalBytes ()const {return total_bytes;} ///<取得数据总字节数
void * GetData(const uint offset){return ((char *)mem_data)+GetDataBytes()*offset;}///<取得数据指针 void * GetData ()const {return mem_data;} ///<取得数据指针
int GetBytes()const { return bytes; } ///<取得数据字节数 void * GetData (const uint off){return ((char *)mem_data)+data_bytes*off;} ///<取得数据指针
public: //以下函数在各渲染器内部实现 public:
bool CreateVertexBuffer(uint type); void Update(); ///<完整更新内存中的数据到显示
void ChangeVertexBuffer(int,int,void *);
//void BindVertexBuffer(); void Change(int,int,void *);
int GetBufferIndex()const; ///<取得缓冲区索引 //void BindVertexBuffer();
void CloseVertexBuffer(); int GetBufferIndex()const; ///<取得缓冲区索引
};//class VertexBufferBase };//class VertexBufferBase
}//namespace graph }//namespace graph
}//namespace hgl }//namespace hgl

View File

@ -10,45 +10,24 @@ namespace hgl
VertexBufferControl *CreateVertexBufferControlDSA(uint); VertexBufferControl *CreateVertexBufferControlDSA(uint);
VertexBufferControl *CreateVertexBufferControlBind(uint); VertexBufferControl *CreateVertexBufferControlBind(uint);
VertexBufferControl *(*CreateVertexBufferControl)(uint)=nullptr; namespace
void DeleteVertexBufferControlDSA(VertexBufferControl *);
void DeleteVertexBufferControlBind(VertexBufferControl *);
void (*DeleteVertexBufferControl)(VertexBufferControl *)=nullptr;
void InitVertexBufferDSA()
{ {
CreateVertexBufferControl=CreateVertexBufferControlDSA; static VertexBufferControl *(*CreateVertexBufferControl)(uint)=nullptr;
DeleteVertexBufferControl=DeleteVertexBufferControlDSA;
}
void InitVertexBufferBind() void InitVertexBufferAPI()
{
CreateVertexBufferControl=CreateVertexBufferControlBind;
DeleteVertexBufferControl=DeleteVertexBufferControlBind;
}
bool InitVertexBufferAPI()
{
if (GLEW_ARB_direct_state_access) //4.5
{ {
InitVertexBufferDSA(); if(GLEW_VERSION_4_5||GLEW_ARB_direct_state_access)
return(true); CreateVertexBufferControl=CreateVertexBufferControlDSA;
else
CreateVertexBufferControl=CreateVertexBufferControlBind;
} }
}//namespace
InitVertexBufferBind();
return(true);
}
}//namespace graph
namespace graph
{
void VertexBufferBase::SetDataSize(int size) void VertexBufferBase::SetDataSize(int size)
{ {
if (bytes == size)return; if (total_bytes == size)return;
bytes = size; total_bytes = size;
if (mem_data) if (mem_data)
mem_data = hgl_realloc(mem_data, size); mem_data = hgl_realloc(mem_data, size);
@ -58,57 +37,48 @@ namespace hgl
mem_end = ((char *)mem_data) + size; 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_data =hgl_malloc(total_bytes); //在很多情况下hgl_malloc分配的内存是对齐的这样有效率上的提升
mem_end = ((char *)mem_data) + size; mem_end =((char *)mem_data)+total_bytes;
data_level = level; data_usage =usage;
vbc=nullptr; if(!CreateVertexBufferControl)
InitVertexBufferAPI();
vbc=CreateVertexBufferControl(type);
} }
VertexBufferBase::~VertexBufferBase() VertexBufferBase::~VertexBufferBase()
{ {
CloseVertexBuffer();
hgl_free(mem_data); hgl_free(mem_data);
if(vbc) SAFE_CLEAR(vbc);
DeleteVertexBufferControl(vbc);
} }
void VertexBufferBase::CloseVertexBuffer() void VertexBufferBase::Update()
{ {
if(!vbc)return; if(!vbc)return;
DeleteVertexBufferControl(vbc); vbc->Set(total_bytes,mem_data,data_usage);
vbc = nullptr;
} }
void VertexBufferBase::ChangeVertexBuffer(int start, int size, void *data) void VertexBufferBase::Change(int start, int size, void *data)
{ {
if (!vbc)return; if (!vbc)return;
vbc->Change(start,size,data); 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() // void VertexBufferBase::BindVertexBuffer()
// { // {
// if(!video_buffer_type)return; // if(!video_buffer_type)return;
@ -121,27 +91,4 @@ namespace hgl
return vbc?vbc->GetIndex():-1; return vbc?vbc->GetIndex():-1;
} }
}//namespace graph }//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 }//namespace hgl

View File

@ -26,8 +26,8 @@ namespace hgl
Clear(); Clear();
} }
virtual void Set(int, void *,uint)=0; virtual void Set(GLsizei, void *,GLenum)=0;
virtual void Change(int, int, void *)=0; virtual void Change(GLintptr,GLsizei, void *)=0;
void Clear() void Clear()
{ {
if(!type||!index)return; if(!type||!index)return;

View File

@ -29,14 +29,18 @@ namespace hgl
public: public:
using VertexBufferControl::VertexBufferControl; using VertexBufferControl::VertexBufferControl;
~VertexBufferControlBind()
void Set(int size, void *data, uint data_level)
{ {
glBindBuffer(this->type,this->index); glDeleteBuffers(1,&(this->index));
glBufferData(this->type, size, data, data_level);
} }
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); glBindBuffer(this->type, this->index);
glBufferSubData(this->type, start, size, data); glBufferSubData(this->type, start, size, data);
@ -50,10 +54,5 @@ namespace hgl
glGenBuffers(1, &index); glGenBuffers(1, &index);
return(new VertexBufferControlBind(type, index)); return(new VertexBufferControlBind(type, index));
} }
void DeleteVertexBufferControlBind(VertexBufferControl *vbc)
{
SAFE_CLEAR(vbc);
}
}//namespace graph }//namespace graph
}//namespace hgl }//namespace hgl

View File

@ -11,12 +11,12 @@ namespace hgl
using VertexBufferControl::VertexBufferControl; 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); glNamedBufferSubData(this->index, start, size, data);
} }