From 8a8339a431ca8eee53cf56a9c4cbff4ed84e2031 Mon Sep 17 00:00:00 2001 From: HuYingzhuo Date: Wed, 27 Mar 2019 14:09:01 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E7=9A=84BufferData/VertexBufferData?= =?UTF-8?q?=E5=92=8CBufferObject/VertexBufferObject?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- inc/hgl/graph/BufferData.h | 79 ++++++++++------- inc/hgl/graph/BufferObject.h | 46 +++++++--- src/RenderDriver/BufferData.cpp | 50 +++++++++-- src/RenderDriver/BufferObject.cpp | 140 ++++++++++++++++-------------- 4 files changed, 203 insertions(+), 112 deletions(-) diff --git a/inc/hgl/graph/BufferData.h b/inc/hgl/graph/BufferData.h index 1175a8e8..f848c64c 100644 --- a/inc/hgl/graph/BufferData.h +++ b/inc/hgl/graph/BufferData.h @@ -14,32 +14,17 @@ namespace hgl { 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(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; + friend BufferData *CreateBufferData(void *data,const GLsizeiptr &length); + BufferData(char *data,const GLsizeiptr &length) + { + total_bytes =length; buffer_data =data; } @@ -47,37 +32,69 @@ namespace hgl 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 + BufferData *CreateBufferData(const GLsizeiptr &length); + BufferData *CreateBufferData(void *data,const GLsizeiptr &length); + + class VertexBufferData:public BufferData + { + 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; ///<数据数量 + + protected: + + friend VertexBufferData *CreateVertexBufferData(void *data,const GLenum &dt,const uint &dbytes,const uint &dcm,const GLsizeiptr &count); + + VertexBufferData(const GLenum &dt,const uint &dbytes,const uint &dcm,const GLsizeiptr &count,char *data):BufferData(data,dbytes*dcm*count) + { + data_type=dt; + data_bytes=dbytes; + data_comp=dcm; + + data_stride=data_comp*data_bytes; + + data_count=count; + } + + public: + + virtual ~VertexBufferData()=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; } ///<取得数据总字节数 + }; + /** - * 创建一个数据缓冲区
+ * 创建一个顶点数据缓冲区
* 这种方式创建的缓冲区,它会自行分配内存,最终释放 * @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); + VertexBufferData *CreateVertexBufferData(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); + VertexBufferData *CreateVertexBufferData(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/inc/hgl/graph/BufferObject.h b/inc/hgl/graph/BufferObject.h index c4610f1b..885ccb2c 100644 --- a/inc/hgl/graph/BufferObject.h +++ b/inc/hgl/graph/BufferObject.h @@ -21,16 +21,9 @@ namespace hgl GLsizeiptr buffer_bytes; const BufferData *buffer_data; - protected: - - friend BufferObject *CreateBufferObject(GLenum,GLenum,BufferData *buf); - friend BufferObject *CreateBufferObject(const GLenum &,const GLenum &,const GLsizeiptr &); - friend BufferObject *CreateBufferObject(const GLenum &,const GLenum &,const GLsizeiptr &,void *); - - BufferObject(GLuint index,GLenum type); - public: + BufferObject(GLenum type); virtual ~BufferObject(); public: @@ -40,18 +33,47 @@ namespace hgl GLenum GetUserPattern ()const {return user_pattern;} ///<取得缓冲区使用方法 const BufferData *GetBufferData ()const {return buffer_data;} ///<取得缓冲数区(这里返回const是为了不想让只有BufferObject的模块可以修改数据) + const GLsizeiptr GetBufferSize ()const {return buffer_bytes;} ///<取得缓冲区总计字数 public: - bool Create (GLsizeiptr,GLenum user_pattern); ///<创建数据区 - bool Submit (void *,GLsizeiptr,GLenum user_pattern); ///<提交数据 - bool Submit (const BufferData *buf_data,GLenum user_pattern); ///<提交数据 +// bool Create (GLsizeiptr,GLenum up); ///<创建数据区 + bool Submit (void *,GLsizeiptr,GLenum up); ///<提交数据 + bool Submit (const BufferData *buf_data,GLenum up); ///<提交数据 bool Change (void *,GLsizeiptr,GLsizeiptr); ///<修改数据 };//class BufferObject - BufferObject *CreateBufferObject(GLenum type,GLenum user_pattern=0,BufferData *buf=nullptr); ///<创建一个缓冲区对象 + BufferObject *CreateBufferObject(const GLenum &type,const GLenum &user_pattern=0,BufferData *buf=nullptr); ///<创建一个缓冲区对象 BufferObject *CreateBufferObject(const GLenum &buf_type,const GLenum &user_pattern,const GLsizeiptr &total_bytes); ///<创建一个缓冲区对象 BufferObject *CreateBufferObject(const GLenum &buf_type,const GLenum &user_pattern,const GLsizeiptr &total_bytes,void *data); ///<创建一个缓冲区对象 + + /** + * 显存顶点属性数据缓冲区对象 + */ + class VertexBufferObject:public BufferObject + { + const VertexBufferData *vertex_buffer_data; + + public: + + using BufferObject::BufferObject; + ~VertexBufferObject()=default; + + const VertexBufferData *GetVertexBufferData()const { return vertex_buffer_data; } + + #define VBD_FUNC_COPY(type,name) type Get##name()const{vertex_buffer_data?vertex_buffer_data->Get##name():0;} + + VBD_FUNC_COPY(GLenum,DataType) + VBD_FUNC_COPY(uint,Component) + VBD_FUNC_COPY(uint,Stride) + VBD_FUNC_COPY(GLsizeiptr,Count) + + #undef VBD_FUNC_COPY + };//class VertexBufferObject:public BufferObject + + VertexBufferObject *CreateVertexBufferObject(const GLenum &type,const GLenum &user_pattern=0,VertexBufferData *buf=nullptr); ///<创建一个顶点缓冲区对象 + VertexBufferObject *CreateVertexBufferObject(const GLenum &buf_type,const GLenum &user_pattern,const GLsizeiptr &total_bytes); ///<创建一个顶点缓冲区对象 + VertexBufferObject *CreateVertexBufferObject(const GLenum &buf_type,const GLenum &user_pattern,const GLsizeiptr &total_bytes,void *data); ///<创建一个顶点缓冲区对象 }//namespace graph }//namespace hgl #endif//HGL_GRAPH_BUFFER_OBJECT_INCLUDE diff --git a/src/RenderDriver/BufferData.cpp b/src/RenderDriver/BufferData.cpp index f9eb5b04..01f802d4 100644 --- a/src/RenderDriver/BufferData.cpp +++ b/src/RenderDriver/BufferData.cpp @@ -6,7 +6,8 @@ namespace hgl { class BufferDataSelfAlloc:public BufferData { - friend BufferData *CreateBufferData(const GLenum &dt,const uint &dbytes,const uint &dcm,const GLsizeiptr &count); + friend BufferData *CreateBufferData(const GLsizeiptr &count); + public: using BufferData::BufferData; @@ -16,7 +17,46 @@ namespace hgl } };//class BufferDataSelfAlloc:public BufferData - BufferData *CreateBufferData(const GLenum &dt,const uint &dbytes,const uint &dcm,const GLsizeiptr &count) + BufferData *CreateBufferData(const GLsizeiptr &total_bytes) + { + if(total_bytes<=0) + return(nullptr); + + char *data=new char[total_bytes]; + + if(!data) + return(nullptr); + + return(new BufferDataSelfAlloc(data,total_bytes)); + } + + BufferData *CreateBufferData(void *data,const GLsizeiptr &count) + { + if(!data) + return(nullptr); + + if(count<=0) + return(nullptr); + + return(new BufferData((char *)data,count)); + } + } + namespace graph + { + class VertexBufferDataSelfAlloc:public VertexBufferData + { + friend VertexBufferData *CreateVertexBufferData(const GLenum &dt,const uint &dbytes,const uint &dcm,const GLsizeiptr &count); + + public: + + using VertexBufferData::VertexBufferData; + ~VertexBufferDataSelfAlloc() + { + delete[] buffer_data; + } + };//class BufferDataSelfAlloc:public VertexBufferData + + VertexBufferData *CreateVertexBufferData(const GLenum &dt,const uint &dbytes,const uint &dcm,const GLsizeiptr &count) { if(dbytes<=0||dcm<=0||dcm>=5||count<=0) return(nullptr); @@ -28,10 +68,10 @@ namespace hgl if(!data) return(nullptr); - return(new BufferDataSelfAlloc(dt,dbytes,dcm,count,data)); + return(new VertexBufferDataSelfAlloc(dt,dbytes,dcm,count,data)); } - BufferData *CreateBufferData(void *data,const GLenum &dt,const uint &dbytes,const uint &dcm,const GLsizeiptr &count) + VertexBufferData *CreateVertexBufferData(void *data,const GLenum &dt,const uint &dbytes,const uint &dcm,const GLsizeiptr &count) { if(!data) return(nullptr); @@ -39,7 +79,7 @@ namespace hgl if(dbytes<=0||dcm<=0||dcm>=5||count<=0) return(nullptr); - return(new BufferData(dt,dbytes,dcm,count,(char *)data)); + return(new VertexBufferData(dt,dbytes,dcm,count,(char *)data)); } }//namespace graph }//namespace hgl diff --git a/src/RenderDriver/BufferObject.cpp b/src/RenderDriver/BufferObject.cpp index a440e9e5..4ebfc82d 100644 --- a/src/RenderDriver/BufferObject.cpp +++ b/src/RenderDriver/BufferObject.cpp @@ -7,9 +7,13 @@ namespace hgl { namespace dsa { - void CreateBuffer(GLenum type,GLuint *index) + GLuint CreateBuffer() { - glCreateBuffers(1,index); + GLuint index; + + glCreateBuffers(1,&index); + + return index; } void BufferAlloc(GLenum type,GLuint index,GLsizeiptr size) @@ -53,9 +57,13 @@ namespace hgl namespace bind { - void CreateBuffer(GLenum type,GLuint *index) + GLuint CreateBuffer() { - glGenBuffers(1,index); + GLuint index; + + glGenBuffers(1,&index); + + return index; } void BufferData(GLenum type,GLuint index,void *data,GLsizeiptr size,GLenum user_pattern) @@ -71,41 +79,41 @@ namespace hgl } } - static void (*CreateBuffer)(GLenum type,GLuint *); - static void (*BufferData)(GLenum type,GLuint index,void *data,GLsizeiptr size,GLenum user_pattern); - static void (*BufferSubData)(GLenum type,GLuint index,void *data,GLsizeiptr start,GLsizeiptr size); + static GLuint(*CreateBuffer)(); + static void(*BufferData)(GLenum type,GLuint index,void *data,GLsizeiptr size,GLenum user_pattern); + static void(*BufferSubData)(GLenum type,GLuint index,void *data,GLsizeiptr start,GLsizeiptr size); void InitBufferObjectAPI() { if(glCreateBuffers - ||glNamedBufferData - ||glNamedBufferSubData) //dsa + ||glNamedBufferData + ||glNamedBufferSubData) //dsa { - hgl::graph::gl::CreateBuffer =dsa::CreateBuffer; - hgl::graph::gl::BufferData =dsa::BufferData; - hgl::graph::gl::BufferSubData =dsa::BufferSubData; + hgl::graph::gl::CreateBuffer=dsa::CreateBuffer; + hgl::graph::gl::BufferData=dsa::BufferData; + hgl::graph::gl::BufferSubData=dsa::BufferSubData; } else - if(glNamedBufferDataEXT - ||glNamedBufferSubDataEXT) - { - hgl::graph::gl::CreateBuffer =bind::CreateBuffer; - hgl::graph::gl::BufferData =dsa_ext::BufferData; - hgl::graph::gl::BufferSubData =dsa_ext::BufferSubData; - } - else - { - hgl::graph::gl::CreateBuffer =bind::CreateBuffer; - hgl::graph::gl::BufferData =bind::BufferData; - hgl::graph::gl::BufferSubData =bind::BufferSubData; - } + if(glNamedBufferDataEXT + ||glNamedBufferSubDataEXT) + { + hgl::graph::gl::CreateBuffer=bind::CreateBuffer; + hgl::graph::gl::BufferData=dsa_ext::BufferData; + hgl::graph::gl::BufferSubData=dsa_ext::BufferSubData; + } + else + { + hgl::graph::gl::CreateBuffer=bind::CreateBuffer; + hgl::graph::gl::BufferData=bind::BufferData; + hgl::graph::gl::BufferSubData=bind::BufferSubData; + } } }//namespace gl - BufferObject::BufferObject(GLuint index,GLenum type) + BufferObject::BufferObject(GLenum type) { - buffer_index=index; - buffer_type =type; + buffer_index=gl::CreateBuffer(); + buffer_type=type; user_pattern=0; buffer_bytes=0; @@ -119,22 +127,25 @@ namespace hgl glDeleteBuffers(1,&buffer_index); } - bool BufferObject::Create(GLsizeiptr size,GLenum up) - { - return true; - } + //bool BufferObject::Create(GLsizeiptr size,GLenum up) + //{ + // if(size<=0)return(false); + + // return true; + //} bool BufferObject::Submit(void *data,GLsizeiptr size,GLenum up) { if(!data||size<=0)return(false); user_pattern=up; + buffer_bytes=size; gl::BufferData(buffer_type,buffer_index,data,size,user_pattern); return(true); } - bool BufferObject::Submit(const BufferData *buf_data,GLenum user_pattern) + bool BufferObject::Submit(const BufferData *buf_data,GLenum up) { if(!buf_data)return(false); buffer_data=buf_data; @@ -144,7 +155,7 @@ namespace hgl if(!data||size<=0)return(false); - return Submit(data,size,user_pattern); + return Submit(data,size,up); } bool BufferObject::Change(void *data,GLsizeiptr start,GLsizeiptr size) @@ -155,24 +166,24 @@ namespace hgl return(true); } + }//namespace graph + + namespace graph + { /** * 创建一个缓冲区对象 - * @param type 缓冲区类型(GL_ARRAY_BUFFER,GL_ELEMENT_ARRAY_BUFFER等) - * @param user_pattern 缓冲区数据用法(GL_STATIC_DRAW,GL_DYNAMIC_DRAW等) + * @param buf_type 缓冲区类型(GL_ARRAY_BUFFER,GL_ELEMENT_ARRAY_BUFFER等) + * @param user_pattern 数据存储区使用模式(GL_STATIC_DRAW,GL_DYNAMIC_DRAW等) * @param buf 数据缓冲区 */ - BufferObject *CreateBufferObject(GLenum type,GLenum user_pattern,BufferData *buf) + template + BO *_CreateBufferObject(const GLenum &buf_type,const GLenum &user_pattern,BD *buf) { - GLuint index; - BufferObject *obj; - - gl::CreateBuffer(1,&index); - - obj=new BufferObject(index,type); + BO *obj=new BO(buf_type); if(buf) - obj->Submit(buf->GetData(),buf->GetTotalBytes(),user_pattern); + obj->Submit(buf,user_pattern); return(obj); } @@ -183,20 +194,17 @@ namespace hgl * @param user_pattern 数据存储区使用模式(GL_STATIC_DRAW,GL_DYNAMIC_DRAW等) * @param total_bytes 数据总字节数 */ - BufferObject *CreateBufferObject( const GLenum &buf_type, - const GLenum &user_pattern, - const GLsizeiptr &total_bytes) + template + BO *_CreateBufferObject(const GLenum &buf_type, + const GLenum &user_pattern, + const GLsizeiptr &total_bytes) { if(total_bytes<=0)return(nullptr); - GLuint index; + BO *buf=new BO(buf_type); - gl::CreateBuffer(1,&index); - - BufferObject *buf=new BufferObject(index,buf_type); - - if(buf->Create(total_bytes,user_pattern)) - return buf; + //if(buf->Create(total_bytes,user_pattern)) + // return buf; delete buf; return(nullptr); @@ -209,21 +217,18 @@ namespace hgl * @param total_bytes 数据总字节数 * @param data 数据指针 */ - inline BufferObject *CreateBufferObject( const GLenum &buf_type, - const GLenum &user_pattern, - const GLsizeiptr &total_bytes,void *data) + template + inline BO *_CreateBufferObject( const GLenum &buf_type, + const GLenum &user_pattern, + const GLsizeiptr &total_bytes,void *data) { if(total_bytes<=0)return(nullptr); if(!data)return(nullptr); - GLuint index; + BO *buf=new BO(buf_type); - gl::CreateBuffer(1,&index); - - BufferObject *buf=new BufferObject(index,buf_type); - - if(buf->Create(total_bytes,user_pattern)) - return buf; + //if(buf->Create(total_bytes,user_pattern)) + // return buf; if(buf->Submit(data,total_bytes,user_pattern)) return buf; @@ -231,5 +236,12 @@ namespace hgl delete buf; return(nullptr); } + + BufferObject *CreateBufferObject(const GLenum &type,const GLenum &up,BufferData *buf) { return _CreateBufferObject(type,up,buf); } + BufferObject *CreateBufferObject(const GLenum &type,const GLenum &up,const GLsizeiptr &size) { return _CreateBufferObject(type,up,size); } + BufferObject *CreateBufferObject(const GLenum &type,const GLenum &up,const GLsizeiptr &size,void *data) { return _CreateBufferObject(type,up,size,data); } + VertexBufferObject *CreateVertexBufferObject(const GLenum &type,const GLenum &up,VertexBufferData *buf) { return _CreateBufferObject(type,up,buf); } + VertexBufferObject *CreateVertexBufferObject(const GLenum &type,const GLenum &up,const GLsizeiptr &size) { return _CreateBufferObject(type,up,size); } + VertexBufferObject *CreateVertexBufferObject(const GLenum &type,const GLenum &up,const GLsizeiptr &size,void *data) { return _CreateBufferObject(type,up,size,data); } }//namespace graph }//namespace hgl