diff --git a/inc/hgl/graph/BufferData.h b/inc/hgl/graph/BufferData.h new file mode 100644 index 00000000..016344db --- /dev/null +++ b/inc/hgl/graph/BufferData.h @@ -0,0 +1,84 @@ +#ifndef HGL_GRAPH_BUFFER_DATA_INCLUDE +#define HGL_GRAPH_BUFFER_DATA_INCLUDE + +#include +#include +namespace hgl +{ + namespace graph + { + /** + * 缓冲区数据管理类 + */ + class BufferData + { + protected: + + GLenum data_type; ///<单个数据类型 (GL_BYTE,GL_UNSIGNED_SHORT,GL_FLOAT等) + uint data_bytes; ///<单个数据字节数 (GL_BYTE为1,GL_UNSIGNED_SHORT为2,GL_FLOAT为4等) + uint data_comp; ///<数据成员数 (1/2/3/4,如2D纹理坐标用2,3D坐标/法线用3) + + uint data_stride; ///<每组数据字节数 + + GLsizeiptr data_count; ///<数据数量 + GLsizeiptr total_bytes; ///<数据总字节数 + + char * buffer_data; + + protected: + + friend BufferData *CreateBufferData(const GLenum &dt,const uint &dbytes,const uint &dcm,const GLsizeiptr &count); + friend BufferData *CreateBufferData(void *data,const GLenum &dt,const uint &dbytes,const uint &dcm,const GLsizeiptr &count); + + BufferData(const GLenum &dt,const uint &dbytes,const uint &dcm,const GLsizeiptr &count,char *data) + { + data_type =dt; + data_bytes =dbytes; + data_comp =dcm; + + data_stride =data_comp*data_bytes; + + data_count =count; + total_bytes =data_stride*data_count; + + buffer_data =data; + } + + public: + + virtual ~BufferData()=default; + + GLenum GetDataType ()const {return data_type;} ///<取得数据类型 + uint GetComponent ()const {return data_comp;} ///<取数每一组数据中的数据数量 + uint GetStride ()const {return data_stride;} ///<取得每一组数据字节数 + + GLsizeiptr GetCount ()const {return data_count;} ///<取得数据数量 + GLsizeiptr GetTotalBytes ()const {return total_bytes;} ///<取得数据总字节数 + + public: + + void * GetData ()const {return buffer_data;} ///<取得数据指针 + };//class BufferData + + /** + * 创建一个数据缓冲区
+ * 这种方式创建的缓冲区,它会自行分配内存,最终释放 + * @param dt 单个数据类型 (GL_BYTE,GL_UNSIGNED_SHORT,GL_FLOAT等) + * @param dbytes 单个数据字节数 (GL_BYTE为1,GL_UNSIGNED_SHORT为2,GL_FLOAT为4等) + * @param dcm 数据成员数 (1/2/3/4,如2D纹理坐标用2,3D坐标/法线用3) + * @param count 数据数量 + */ + BufferData *CreateBufferData(const GLenum &dt,const uint &dbytes,const uint &dcm,const GLsizeiptr &count); + + /** + * 创建一个数据缓冲区 + * @param data 数据指针 + * @param dt 单个数据类型 (GL_BYTE,GL_UNSIGNED_SHORT,GL_FLOAT等) + * @param dbytes 单个数据字节数 (GL_BYTE为1,GL_UNSIGNED_SHORT为2,GL_FLOAT为4等) + * @param dcm 数据成员数 (1/2/3/4,如2D纹理坐标用2,3D坐标/法线用3) + * @param count 数据数量 + */ + BufferData *CreateBufferData(void *data,const GLenum &dt,const uint &dbytes,const uint &dcm,const GLsizeiptr &count); + }//namespace graph +}//namespace hgl +#endif//HGL_GRAPH_BUFFER_DATA_INCLUDE diff --git a/src/RenderDriver/BufferData.cpp b/src/RenderDriver/BufferData.cpp new file mode 100644 index 00000000..b78e1352 --- /dev/null +++ b/src/RenderDriver/BufferData.cpp @@ -0,0 +1,44 @@ +#include + +namespace hgl +{ + namespace graph + { + class BufferDataSelfAlloc:public BufferData + { + public: + + using BufferData::BufferData; + ~BufferDataSelfAlloc() + { + delete[] buffer_data; + } + };//class BufferDataSelfAlloc:public BufferData + + BufferData *CreateBufferData(const GLenum &dt,const uint &dbytes,const uint &dcm,const GLsizeiptr &count) + { + if(dbytes<=0||dcm<=0||dcm>=5||count<=0) + return(nullptr); + + const uint total_bytes=dbytes*dcm*count; + + char *data=new char[total_bytes]; + + if(!data) + return(nullptr); + + return(new BufferDataSelfAlloc(dt,dbytes,dcm,count,data)); + } + + BufferData *CreateBufferData(void *data,const GLenum &dt,const uint &dbytes,const uint &dcm,const GLsizeiptr &count) + { + if(!data) + return(nullptr); + + if(dbytes<=0||dcm<=0||dcm>=5||count<=0) + return(nullptr); + + return(new BufferData(dt,dbytes,dcm,count,(char *)data)); + } + }//namespace graph +}//namespace hgl diff --git a/src/RenderDriver/BufferObject.cpp b/src/RenderDriver/BufferObject.cpp new file mode 100644 index 00000000..4570ba75 --- /dev/null +++ b/src/RenderDriver/BufferObject.cpp @@ -0,0 +1,92 @@ +#include +namespace hgl +{ + namespace graph + { + BufferObject::~BufferObject() + { + SAFE_CLEAR(buffer_data); + + glDeleteBuffers(1,&buffer_index); + } + + class BufferObjectBind:public BufferObject + { + public: + + using BufferObject::BufferObject; + ~BufferObjectBind()=default; + + bool Submit(const void *data,GLsizeiptr size,GLenum up) override + { + if(!data||size<=0)return(false); + + user_pattern=up; + glBindBuffer(buffer_bytes,buffer_index); + glBufferData(buffer_type,size,data,user_pattern); + + return(true); + } + + bool Change(const void *data,GLsizeiptr start,GLsizeiptr size) override + { + if(!data||start<0||size<=0)return(false); + + glBindBuffer(buffer_bytes,buffer_index); + glBufferSubData(buffer_type,start,size,data); + + return(true); + } + };//class BufferObjectBind:public BufferObject + + class BufferObjectDSA:public BufferObject + { + public: + + using BufferObject::BufferObject; + ~BufferObjectDSA()=default; + + bool Submit(const void *data,GLsizeiptr size,GLenum up) override + { + if(!data||size<=0)return(false); + + user_pattern=up; + buffer_bytes=size; + glNamedBufferData(buffer_index,size,data,user_pattern); + + return(true); + } + + bool Change(const void *data,GLsizeiptr start,GLsizeiptr size) override + { + if(!data||start<0||size<=0)return(false); + + glNamedBufferSubData(buffer_index,start,size,data); + + return(true); + } + };//class BufferObjectDSA:public BufferObject + + BufferObject *CreateBuffer(GLenum type,GLenum user_pattern,BufferData *buf) + { + GLuint index; + BufferObject *obj; + + if(GLEW_VERSION_4_5||GLEW_ARB_direct_state_access) + { + glCreateBuffers(1,&index); + obj=new BufferObjectDSA(index,type); + } + else + { + glGenBuffers(1,&index); + obj=new BufferObjectBind(index,type); + } + + if(buf) + obj->Submit(buf->GetData(),buf->GetTotalBytes(),user_pattern); + + return(obj); + } + }//namespace graph +}//namespace hgl