From 5c3caf4111bf00345391d08e74acde810573b5f5 Mon Sep 17 00:00:00 2001 From: hyzboy Date: Wed, 28 Nov 2018 20:56:55 +0800 Subject: [PATCH] =?UTF-8?q?List=E5=88=A0=E9=99=A4=E4=B8=8D=E5=90=88?= =?UTF-8?q?=E7=90=86=E8=AE=BE=E8=AE=A1=E7=9A=84[]=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E7=AC=A6=E9=87=8D=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- inc/hgl/Macro.h | 6 +- inc/hgl/endian/Endian.h | 4 +- inc/hgl/render/Shader.h | 195 +++++++++++ inc/hgl/thread/ThreadMutex.h | 6 +- inc/hgl/type/List.cpp | 100 ++++-- inc/hgl/type/List.h | 6 +- inc/hgl/type/Map.cpp | 582 ++++++++++++++++++++++++++++++++ inc/hgl/type/Map.h | 325 ++++++++++++++++++ inc/hgl/type/Pair.h | 82 +++++ inc/hgl/type/Pool.cpp | 139 ++++++++ inc/hgl/type/Pool.h | 262 ++++++++++++++ inc/hgl/type/Queue.cpp | 239 +++++++++++++ inc/hgl/type/Queue.h | 75 ++++ inc/hgl/type/ResManage.cpp | 134 ++++++++ inc/hgl/type/ResManage.h | 55 +++ inc/hgl/type/ResPoolManage.h | 34 ++ inc/hgl/type/Set.cpp | 365 ++++++++++++++++++++ inc/hgl/type/Set.h | 77 +++++ inc/hgl/type/Smart.h | 1 - inc/hgl/type/Stack.cpp | 261 ++++++++++++++ inc/hgl/type/Stack.h | 59 ++++ src/CMakeLists.txt | 2 +- src/RenderDriver/CMakeLists.txt | 3 +- src/RenderDriver/GLSL.cpp | 392 +++++++++++++++++++++ src/RenderDriver/Shader.cpp | 250 ++++++++++++++ 25 files changed, 3606 insertions(+), 48 deletions(-) create mode 100644 inc/hgl/render/Shader.h create mode 100644 inc/hgl/type/Map.cpp create mode 100644 inc/hgl/type/Map.h create mode 100644 inc/hgl/type/Pair.h create mode 100644 inc/hgl/type/Pool.cpp create mode 100644 inc/hgl/type/Pool.h create mode 100644 inc/hgl/type/Queue.cpp create mode 100644 inc/hgl/type/Queue.h create mode 100644 inc/hgl/type/ResManage.cpp create mode 100644 inc/hgl/type/ResManage.h create mode 100644 inc/hgl/type/ResPoolManage.h create mode 100644 inc/hgl/type/Set.cpp create mode 100644 inc/hgl/type/Set.h create mode 100644 inc/hgl/type/Stack.cpp create mode 100644 inc/hgl/type/Stack.h create mode 100644 src/RenderDriver/GLSL.cpp create mode 100644 src/RenderDriver/Shader.cpp diff --git a/inc/hgl/Macro.h b/inc/hgl/Macro.h index fd051a60..5c8eb327 100644 --- a/inc/hgl/Macro.h +++ b/inc/hgl/Macro.h @@ -1,4 +1,4 @@ -#ifndef HGL_MACRO_INCLUDE +#ifndef HGL_MACRO_INCLUDE #define HGL_MACRO_INCLUDE namespace hgl @@ -50,7 +50,7 @@ namespace hgl if(name[free_object_array_number]) \ delete name[free_object_array_number]; \ \ - cm_free(name); \ + hgl_free(name); \ name=nullptr; \ } \ } @@ -62,7 +62,7 @@ namespace hgl #define SAFE_FREE(name) { \ if(name) \ - cm_free(name); \ + hgl_free(name); \ } #define SAFE_RECREATE(name,code) { \ diff --git a/inc/hgl/endian/Endian.h b/inc/hgl/endian/Endian.h index f54bbc1b..03b178c2 100644 --- a/inc/hgl/endian/Endian.h +++ b/inc/hgl/endian/Endian.h @@ -198,7 +198,7 @@ namespace hgl template T ToBigEndian(T value){return value;} template inline void ToBigEndian(T *value,const int64 count){} - template inline void ToBigEndian(D *dst,const S *src,const int64 count){cm_cpy(dst,src,count);} + template inline void ToBigEndian(D *dst,const S *src,const int64 count){hgl_cpy(dst,src,count);} template T ToLittleEndian(T value){return EndianSwap(value);} @@ -223,7 +223,7 @@ namespace hgl template T ToLittleEndian(T value){return value;} template inline void ToLittleEndian(T *,const int64){} - template inline void ToLittleEndian(D *dst,const S *src,const int64 count){cm_cpy(dst,src,count);} + template inline void ToLittleEndian(D *dst,const S *src,const int64 count){hgl_cpy(dst,src,count);} #endif//HGL_BIG_ENDIAN diff --git a/inc/hgl/render/Shader.h b/inc/hgl/render/Shader.h new file mode 100644 index 00000000..65ea082a --- /dev/null +++ b/inc/hgl/render/Shader.h @@ -0,0 +1,195 @@ +#ifndef HGL_SHADER_INCLUDE +#define HGL_SHADER_INCLUDE + +#include +#include +#include +// #include +// #include +namespace hgl +{ + constexpr uint HGL_MAX_SHADER_NAME_LENGTH=128; ///<最大Shader名称长度 + + /** + * 着色程序类型枚举 + */ + enum ShaderType ///着色程序类型 + { + stVertex=0, ///<顶点着色程序 + stTessControl, ///<镶嵌控制着色程序(需OpenGL 4.0或ARB_tessellation_shader) + stTessEval, ///<镶嵌评估着色程序(需OpenGL 4.0或ARB_tessellation_shader) + stGeometry, ///<几何着色程序 + stFragment, ///<片断着色程序 + stCompute, ///<计算着色程序(需OpenGL 4.3或ARB_compute_shader) + + stEnd + };//enum ShaderType + + extern const char ShaderTypeName[ShaderType::stEnd][32]; ///<着色程序名称 + + /** + * 着色器程序 + */ + class Shader + { + uint program; + + uint shader_index[ShaderType::stEnd]; + + private: + + bool Link(); ///<连接使用当前着色程序 + + protected: + + Map attrib_location; + Map uniform_location; + +// Map uniform_block_index; +// MapObject uniform_block_object; +// +// Map ssbo_index; +// MapObject ssbo_object; + + int _GetAttribLocation(const char *); ///<取得指定属性地址 + int _GetUniformLocation(const char *); ///<取得一个变量的地址 +// int _GetUniformBlockIndex(const char *); ///<取得一个只读数据块的地址索引 +// int _GetShaderStorageIndex(const char *); ///<取得一个数据存储区的地址索引 + + public: + + Shader(){program=0;hgl_zero(shader_index,ShaderType::stEnd);} + ~Shader(){Clear();} + + void Clear(); ///<清除着色程序 + + bool AddShader (const int shader_type,const char *); ///<增加一个着色程序 + + bool AddVertexShader (const char *code){return AddShader(ShaderType::stVertex,code);} ///<增加一个顶点着色程序 + bool AddGeometryShader (const char *code){return AddShader(ShaderType::stGeometry,code);} ///<增加一个几何着色程序 + bool AddFragmentShader (const char *code){return AddShader(ShaderType::stFragment,code);} ///<增加一个片断着色程序 + bool AddComputeShader (const char *code){return AddShader(ShaderType::stFragment,code);} ///<增加一个计算着色程序 + + bool AddTessShader (const char *tess_control_shader,const char *tess_evaluation_shader) ///<增加一个镶嵌着色程序 + { + if(!AddShader(ShaderType::stTessControl,tess_control_shader ))return(false); + if(!AddShader(ShaderType::stTessEval, tess_evaluation_shader ))return(false); + return(true); + } + + bool Build(); ///<构建当前添加的着色程序 + + bool Use(); ///<使用当前着色程序 + + int GetAttribLocation(const char *); ///<取得指定属性地址 + int GetUniformLocation(const char *); ///<取得一个变量的地址 +// int GetUniformBlockIndex(const char *); ///<取得一个只读数据块索引 +// int GetShaderStorageIndex(const char *); ///<取得一个数据存储区索引 + + //bool SetAttrib1f(int,float); + //bool GetAttrib1f(int,float &); + + public: //设置一致变量用函数 + + bool SetUniform1f(int,float); + bool SetUniform2f(int,float,float); + bool SetUniform3f(int,float,float,float); + bool SetUniform4f(int,float,float,float,float); + + bool SetUniform1i(int,int); + bool SetUniform2i(int,int,int); + bool SetUniform3i(int,int,int,int); + bool SetUniform4i(int,int,int,int,int); + + bool SetUniform1ui(int,unsigned int); + bool SetUniform2ui(int,unsigned int,unsigned int); + bool SetUniform3ui(int,unsigned int,unsigned int,unsigned int); + bool SetUniform4ui(int,unsigned int,unsigned int,unsigned int,unsigned int); + + bool SetUniform1fv(int,const float *); + bool SetUniform2fv(int,const float *); + bool SetUniform3fv(int,const float *); + bool SetUniform4fv(int,const float *); + + bool SetUniform2fv(int index,const Vector2f &v){return SetUniform2fv(index,(const float *)&v);} + bool SetUniform3fv(int index,const Vector3f &v){return SetUniform3fv(index,(const float *)&v);} + bool SetUniform4fv(int index,const Vector4f &v){return SetUniform4fv(index,(const float *)&v);} + + bool SetUniform1iv(int,const int *); + bool SetUniform2iv(int,const int *); + bool SetUniform3iv(int,const int *); + bool SetUniform4iv(int,const int *); + + bool SetUniform1uiv(int,const unsigned int *); + bool SetUniform2uiv(int,const unsigned int *); + bool SetUniform3uiv(int,const unsigned int *); + bool SetUniform4uiv(int,const unsigned int *); + + bool SetUniformMatrix2fv(int,const float *); + bool SetUniformMatrix3fv(int,const float *); + bool SetUniformMatrix4fv(int,const float *); + + bool SetUniformMatrix2x3fv(int,const float *); + bool SetUniformMatrix3x2fv(int,const float *); + bool SetUniformMatrix2x4fv(int,const float *); + bool SetUniformMatrix4x2fv(int,const float *); + bool SetUniformMatrix3x4fv(int,const float *); + bool SetUniformMatrix4x3fv(int,const float *); + + public: + + bool SetUniform1f(const char *,float); + bool SetUniform2f(const char *,float,float); + bool SetUniform3f(const char *,float,float,float); + bool SetUniform4f(const char *,float,float,float,float); + + bool SetUniform1i(const char *,int); + bool SetUniform2i(const char *,int,int); + bool SetUniform3i(const char *,int,int,int); + bool SetUniform4i(const char *,int,int,int,int); + + bool SetUniform1ui(const char *,unsigned int); + bool SetUniform2ui(const char *,unsigned int,unsigned int); + bool SetUniform3ui(const char *,unsigned int,unsigned int,unsigned int); + bool SetUniform4ui(const char *,unsigned int,unsigned int,unsigned int,unsigned int); + + bool SetUniform1fv(const char *,const float *); + bool SetUniform2fv(const char *,const float *); + bool SetUniform3fv(const char *,const float *); + bool SetUniform4fv(const char *,const float *); + + bool SetUniform2fv(const char *name,const Vector2f &v){return SetUniform2fv(name,(const float *)&v);} + bool SetUniform3fv(const char *name,const Vector3f &v){return SetUniform3fv(name,(const float *)&v);} + bool SetUniform4fv(const char *name,const Vector4f &v){return SetUniform4fv(name,(const float *)&v);} + + bool SetUniform1iv(const char *,const int *); + bool SetUniform2iv(const char *,const int *); + bool SetUniform3iv(const char *,const int *); + bool SetUniform4iv(const char *,const int *); + + bool SetUniform1uiv(const char *,const unsigned int *); + bool SetUniform2uiv(const char *,const unsigned int *); + bool SetUniform3uiv(const char *,const unsigned int *); + bool SetUniform4uiv(const char *,const unsigned int *); + + bool SetUniformMatrix2fv(const char *,const float *); + bool SetUniformMatrix3fv(const char *,const float *); + bool SetUniformMatrix4fv(const char *,const float *); + + bool SetUniformMatrix3fv(const char *name,const Matrix3f &m){return SetUniformMatrix3fv(name,(const float *)&m);} + bool SetUniformMatrix4fv(const char *name,const Matrix4f &m){return SetUniformMatrix4fv(name,(const float *)&m);} + + bool SetUniformMatrix2x3fv(const char *,const float *); + bool SetUniformMatrix3x2fv(const char *,const float *); + bool SetUniformMatrix2x4fv(const char *,const float *); + bool SetUniformMatrix4x2fv(const char *,const float *); + bool SetUniformMatrix3x4fv(const char *,const float *); + bool SetUniformMatrix4x3fv(const char *,const float *); + + // public: //Uniform Block + // + // UBO *GetUniformBlock(const char *,uint=HGL_DYNAMIC_DRAW); + // SSBO *GetShaderStorage(const char *,uint=HGL_DYNAMIC_DRAW); + };//class Shader +}//namespace hgl +#endif//HGL_SHADER_INCLUDE diff --git a/inc/hgl/thread/ThreadMutex.h b/inc/hgl/thread/ThreadMutex.h index 47d6dd35..920a41aa 100644 --- a/inc/hgl/thread/ThreadMutex.h +++ b/inc/hgl/thread/ThreadMutex.h @@ -1,4 +1,4 @@ -#ifndef HGL_THREAD_MUTEX_INCLUDE +#ifndef HGL_THREAD_MUTEX_INCLUDE #define HGL_THREAD_MUTEX_INCLUDE #include @@ -11,14 +11,14 @@ namespace hgl */ class ThreadMutex ///排斥访问类(仅当前进程) { - cm_thread_mutex ptr; + hgl_thread_mutex ptr; public: ThreadMutex(); ///<本类构造函数 virtual ~ThreadMutex(); ///<本类析构函数 - cm_thread_mutex *GetThreadMutex(){return &ptr;} + hgl_thread_mutex *GetThreadMutex(){return &ptr;} virtual void Lock(); ///<取得的控制权(如果对象处于排斥状态,则等待) virtual bool TryLock(); ///<尝试取得控制权 diff --git a/inc/hgl/type/List.cpp b/inc/hgl/type/List.cpp index 797b103c..0ea5843e 100644 --- a/inc/hgl/type/List.cpp +++ b/inc/hgl/type/List.cpp @@ -2,6 +2,7 @@ #define HGL_LIST_CPP #include +#include //-------------------------------------------------------------------------------------------------- // 代码中的部分memcpy可替换为memmove,但这样会引起CodeGuard/Valgrind之类的内存调试器报错 //-------------------------------------------------------------------------------------------------- @@ -11,7 +12,10 @@ namespace hgl bool List::Get(int index,T &ti)const { if(!items||index<0||index>=count) + { + LOG_ERROR(OS_TEXT("List<>::Get(index=")+OSString(index)+OS_TEXT(") error,DataCount=")+OSString(count)); return(false); + } memcpy(&ti,items+index,sizeof(T)); return(true); @@ -48,14 +52,34 @@ namespace hgl } template - bool List::Set(int index,const T &val) + T &List::operator[](int index)const ///<操作符重载取得指定索引处的数据 { - if(!items||index<0||index>=count) - return(false); + if(!items||index<0||index>=count) + { + static T *null_ptr=nullptr; - memcpy(items+index,&val,sizeof(T));//items[index]=val; + LOG_ERROR(OS_TEXT("List<>::operator(index=")+OSString(index)+OS_TEXT(") error,DataCount=")+OSString(count)); - return(true); + return(*null_ptr); + } + + return items[index]; + } + + template + void List::Set(int index,const T &val) + { + #ifdef _DEBUG + if(!items||index<0||index>=count) + { + LOG_ERROR(OS_TEXT("List<>::Set(index=")+OSString(index)+OS_TEXT(",T &) error,DataCount=")+OSString(count)); + } + else + memcpy(items+index,&val,sizeof(T));//items[index]=val; + #else + if(index>=0&&index void List::DeleteClear() { - if(count<=0) - return; + if(count) + { + T *p=items; - T *p=items; + while(count--) + { + delete *p; + ++p; + } - while(count--) - { - delete *p; - ++p; - } - - count=0; + count=0; + } } /** @@ -246,15 +270,17 @@ namespace hgl template bool List::Delete(int index) { - if(!items||count<=0||index<0||index>=count) - return(false); + if(count>0&&index>=0&&index bool List::DeleteMove(int index) { - if(!items||count<=0||index<0||index>=count) - return(false); + if(count>0&&index>=0&&index bool List::DeleteByValue(const T &dat) { - const int index=Find(dat); + int index=Find(dat); - if(index==-1) - return(false); - - Delete(index); - return(true); + if(index!=-1) + { + Delete(index); + return(true); + } + else + return(false); } /** diff --git a/inc/hgl/type/List.h b/inc/hgl/type/List.h index 439b9570..394e9329 100644 --- a/inc/hgl/type/List.h +++ b/inc/hgl/type/List.h @@ -1,6 +1,7 @@ #ifndef HGL_LIST_INCLUDE #define HGL_LIST_INCLUDE +#include #include #include @@ -63,12 +64,13 @@ namespace hgl virtual void operator += (const T &obj){Add(obj);} ///<操作符重载添加一个数据 virtual void operator << (const T &obj){Add(obj);} ///<操作符重载添加一个数据 - virtual void operator -= (const T &obj){DeleteByValue(obj);} ///<操作符重载删除一个数据 + virtual void operator -= (const T &obj){DeleteByValue(obj);} ///<操作符重载删除一个数据 bool Get(int,T &)const; ///<取得指定索引处的数据 - bool Set(int,const T &); ///<设置指定索引处的数据 + void Set(int,const T &); ///<设置指定索引处的数据 bool Rand(T &)const; ///<随机取得一个数据 + virtual T &operator[](int n)const; ///<操作符重载取得指定索引处的数据 virtual bool Begin(T &)const; ///<取第一个数据 virtual bool End(T &)const; ///<取最后一个数据 diff --git a/inc/hgl/type/Map.cpp b/inc/hgl/type/Map.cpp new file mode 100644 index 00000000..2effe73c --- /dev/null +++ b/inc/hgl/type/Map.cpp @@ -0,0 +1,582 @@ +#ifndef HGL_MAP_CPP +#define HGL_MAP_CPP + +namespace hgl +{ + /** + * 查找数据是否存在 + * @param flag 数据标识 + * @return 数据所在索引,-1表示不存在 + */ + template + int _Map::Find(const F &flag)const + { + int left=0,right=data_list.GetCount()-1; //使用left,right而不使用min,max是为了让代码能够更好的阅读。 + int mid; + + DataPair **data_array=data_list.GetData(); + + while(left<=right) + { + if(data_array[left ]->left==flag)return(left); + if(data_array[right]->left==flag)return(right); + + mid=(right+left)>>1; + + if(data_array[mid]->left==flag)return(mid); + + if(data_array[mid]->left>flag) + { + ++left; + right=mid-1; + } + else + { + --right; + left=mid+1; + } + } + +// LOG_PROBLEM(OS_TEXT("Map::Find,no result.")); + return(-1); + } + + template + bool _Map::FindPos(const F &flag,int &pos)const + { + int left=0,right=data_list.GetCount()-1; + int mid; + + DataPair **data_array=data_list.GetData(); + + while(left<=right) + { + if(data_array[left ]->left>flag) + { + pos=left; + return(false); + } + else + if(data_array[left ]->left==flag) + { + pos=left; + return(true); + } + + if(data_array[right]->leftleft==flag) + { + pos=right; + return(true); + } + + mid=(right+left)>>1; + + if(data_array[mid]->left==flag) + { + pos=mid; + return(true); + } + + if(data_array[mid]->left>flag) + { + if(data_array[mid-1]->leftleft==flag) + { + pos=mid-1; + return(true); + } + + ++left; + right=mid-1; + } + else + { + if(data_array[mid+1]->left>flag) + { + pos=mid+1; + return(false); + } + else + if(data_array[mid+1]->left==flag) + { + pos=mid+1; + return(true); + } + + --right; + left=mid+1; + } + } + +// LOG_PROBLEM(OS_TEXT("Map::FindPos,no result.")); + pos=-1; + return(false); + } + + template + int _Map::FindByValue(const T &data)const + { + const int count=data_list.GetCount(); + + DataPair **data_array=data_list.GetData(); + + for(int i=0;iright==data) + return(i); + + ++data_array; + } + + return -1; + } + + /** + * 添加一个数据 + * @param flag 数据标识 + * @param data 数据 + * @return 新创建好的数据结构 + */ + template + DataPair *_Map::Add(const F &flag,const T &data) + { + DataPair *ds=data_pool.Acquire(); + + ds->left=flag; + ds->right=data; + + int pos; + + if(FindPos(flag,pos)) + return(nullptr); + + data_list.Insert(pos,ds); + + return(ds); + } + + /** + * 添加一个数据 + * @param flag 数据标识 + * @return 创建好的数据 + */ + template + T &_Map::Add(const F &flag) + { + DataPair *ds=data_pool.Acquire(); + + ds->left=flag; + + int pos; + + FindPos(flag,pos); + + data_list.Insert(pos,ds); + + return ds->right; + } + + /** + * 添加一个数据 + * @param obj 数据 + */ + template + void _Map::Add(DataPair *obj) + { + data_list.Insert(FindPos(obj->left),obj); + } + + /** + * 根据索引取得数据 + * @param flag 数据索引 + * @param data 数据存放处 + * @return 是否取得成功 + */ + template + bool _Map::Get(const F &flag,T &data) const + { + int index=Find(flag); + + if(index==-1)return(false); + + data=data_list[index]->right; + + return(true); + } + + /** + * 根据序号取得数据 + * @param index 序号 + * @param f 数据索引存放处 + * @param t 数据存放处 + * @return 是否取得成功 + */ + template + bool _Map::Get(int index,F &f,T &t) const + { + if(index<0||index>=data_list.GetCount())return(false); + + DataPair *ds=data_list[index]; + + f=ds->left; + t=ds->right; + + return(true); + } + + /** + * 根据序号取得索引 + * @param index 序号 + * @param f 数据索引存放处 + * @return 是否取得成功 + */ + template + bool _Map::GetKey(int index,F &f) const + { + if(index<0||index>=data_list.GetCount())return(false); + + DataPair *ds=data_list[index]; + + f=ds->left; + + return(true); + } + + /** + * 根据序号取得数据 + * @param index 序号 + * @param t 数据存放处 + * @return 是否取得成功 + */ + template + bool _Map::GetValue(int index,T &t) const + { + if(index<0||index>=data_list.GetCount())return(false); + + DataPair *ds=data_list[index]; + + if(!ds)return(false); + + t=ds->right; + + return(true); + } + + /** + * 根据序号设置数据 + * @param index 数据序号 + * @param t 数据 + */ + template + bool _Map::SetValueBySerial(int index,T &t) + { + if(index<0||index>=data_list.GetCount())return(false); + + data_list[index]->right=t; + + return(true); + } + + /** + * 将指定数据从列表中移除同时取得这个数据 + * @param flag 数据标识 + * @param data 数据存放位处 + * @return 是否成功 + */ + template + bool _Map::Delete(const F &flag,T &data) + { + int index=Find(flag); + + if(index==-1)return(false); + + DataPair *dp=data_list[index]; + + data=dp->right; + + data_pool.Release(dp); + data_list.DeleteMove(index); + + return(true); + } + + /** + * 根据索引将指定数据从列表中移除 + * @param flag 索引 + * @return 是否成功 + */ + template + bool _Map::DeleteByKey(const F &flag) + { + int index=Find(flag); + + if(index==-1)return(false); + + data_pool.Release(data_list[index]); + data_list.DeleteMove(index); + + return(true); + } + + /** + * 根据索引将指定数据从列表中批量移除 + * @param fp 索引列表 + * @param count 索引数量 + * @return 是否成功 + */ + template + int _Map::DeleteByKey(const F *fp,const int count) + { + if(!fp||count<=0)return(0); + + int total=0; + + for(int i=0;i + bool _Map::DeleteByValue(const T &data) + { + int index=FindByValue(data); + + if(index==-1)return(false); + + data_pool.Release(data_list[index]); + data_list.DeleteMove(index); + + return(true); + } + + /** + * 根据序号将指定数据从列表中移除 + * @param index 序号 + * @return 是否成功 + */ + template + bool _Map::DeleteBySerial(int index) + { + if(index<0 + ||index>=data_list.GetCount())return(false); + + data_pool.Release(data_list[index]); + data_list.DeleteMove(index); + + return(true); + } + + /** + * 根据序号将指定数据从列表中移除 + * @param start 起始序号 + * @param number 数量 + * @return 是否成功 + */ + template + bool _Map::DeleteBySerial(int start,int number) + { + DataPair **dp=data_list.GetData()+start; + + for(int i=0;i + void _Map::Update(const F &flag,const T &data) + { + int result; + + if(FindPos(flag,result)) + data_list[result]->right=data; + else + { + DataPair *ds=data_pool.Acquire(); + + ds->left=flag; + ds->right=data; + + data_list.Insert(result,ds); + } + } + + /** + * 更改数据,这个更改和Set不同,它要求指定标识的数据必须存在,则否就会更改失败 + * @param flag 数据标识 + * @param data 新的数据内容 + * @param return 是否更改成功 + */ + template + bool _Map::Change(const F &flag,const T &data) + { + int result=Find(flag); + + if(result==-1) + return(false); + + data_list[result]->right=data; + + return(true); + } + + /** + * 清除所有数据 + */ + template + void _Map::Clear() + { + data_pool.ClearAll(); + data_list.Clear(); + } + + /** + * 清除所有数据,但不释放内存 + */ + template + void _Map::ClearData() + { + data_pool.ReleaseAll(); + data_list.ClearData(); + } + + template + void _Map::operator=(const _Map &ftd) + { + Clear(); + + data_pool.ClearAll(); + data_list.ClearData(); + + const int count=ftd.data_list.GetCount(); + + if(count<=0) + return; + + IDItem **obj=ftd.data_list.GetData(); + + for(int i=0;ileft=(*obj)->left; + new_obj->right=(*obj)->right; + + data_list.Add(new_obj); + + ++obj; + } + } + + template + void _Map::Enum(void (*enum_func)(const F &,T)) + { + const int count=data_list.GetCount(); + + if(count<=0) + return; + + IDItem **idp=data_list.GetData(); + + for(int i=0;ileft,(*idp)->right); + + ++idp; + } + } + + template + void _Map::EnumKey(void (*enum_func)(const F &))const + { + const int count=data_list.GetCount(); + + if(count<=0) + return; + + IDItem **idp=data_list.GetData(); + + for(int i=0;ileft); + + ++idp; + } + } + + template + void _Map::EnumValue(void (*enum_func)(T)) + { + const int count=data_list.GetCount(); + + if(count<=0) + return; + + IDItem **idp=data_list.GetData(); + + for(int i=0;iright); + + ++idp; + } + } + + template + void _Map::EnumValue(bool (*enum_func)(T)) + { + const int count=data_list.GetCount(); + + if(count<=0) + return; + + IDItem **idp=data_list.GetData(); + + for(int i=0;iright)) + return; + + ++idp; + } + } +}//namespace hgl +#endif//HGL_MAP_CPP diff --git a/inc/hgl/type/Map.h b/inc/hgl/type/Map.h new file mode 100644 index 00000000..8bb26c84 --- /dev/null +++ b/inc/hgl/type/Map.h @@ -0,0 +1,325 @@ +#ifndef HGL_MAP_INCLUDE +#define HGL_MAP_INCLUDE + +#include +#include +#include +#include +#include +namespace hgl +{ + /** + * 索引数据模板 + */ + template class _Map + { + public: + + using IDItem=DataPair; + + protected: + + ObjectPool data_pool; + List data_list; + + using this_calss=_Map; + + public: //方法 + + _Map()=default; + virtual ~_Map()=default; + + const int GetCount()const{return data_list.GetCount();} ///<取得数据总量 + + IDItem * Add(const F &,const T &); ///<添加一个数据,数果索引已存在,返回nullptr + T & Add(const F &); ///<添加一个数据 + void Add(IDItem *); ///<添加一个数据 + bool FindPos(const F &,int &)const; ///<查找数据如果插入后,会所在的位置,返回是否存在这个数据 + int FindPos(const F &flag)const{int pos;FindPos(flag,pos);return(pos);} ///<查找数据如果插入后,会所在的位置 + int Find(const F &)const; ///<查找数据是否存在,返回-1表示数据不存在 + int FindByValue(const T &)const; ///<查找数据是否存在,返回-1表示数据不存在 + bool KeyExist(const F &key)const{return(Find(key)!=-1);} ///<确认这个数据是否存在 + bool ValueExist(const T &value)const{return(FindByValue(value)!=-1);} ///<确认这个数据是否存在 + virtual bool Get(const F &,T &)const; ///<取得数据 + virtual bool Delete(const F &,T &); ///<将指定数据从列表中移除,并获得这个数据 + virtual bool DeleteByKey(const F &); ///<根据索引将指定数据从列表中移除 + virtual int DeleteByKey(const F *,const int); ///<根据索引将指定数据从列表中批量移除 + virtual bool DeleteByValue(const T &); ///<根据数据将指定数据从列表中移除 + virtual bool DeleteBySerial(int); ///<根据序号将指定数据从列表中移除 + virtual bool DeleteBySerial(int,int); ///<根据序号将指定数据从列表中移除 + virtual void Update(const F &,const T &); ///<更新一个数据的内容(如不存在则添加) + virtual bool Change(const F &,const T &); ///<更改一个数据的内容(如不存在则更改失效) + virtual void Clear(); ///<清除所有数据 + virtual void ClearData(); ///<清除所有数据,但不释放内存 + + List &GetList(){return data_list;} ///<取得线性列表 + IDItem ** GetDataList()const{return data_list.GetData();} ///<取得纯数据线性列表 + + template + int GetKey(IT &il_list) ///<取得所有索引合集 + { + const int count=data_list.GetCount(); + + if(count<=0) + return count; + + IDItem **idp=data_list.GetData(); + + for(int i=0;ileft); + ++idp; + } + + return count; + } + + template + int GetValue(IT &il_list) ///<取得所有数值合集 + { + const int count=data_list.GetCount(); + + if(count<=0) + return count; + + IDItem **idp=data_list.GetData(); + + for(int i=0;iright); + ++idp; + } + + return count; + } + + IDItem *GetItem(int n)const{return data_list[n];} ///<取指定序号的数据 + bool Get(int,F &,T &)const; ///<取指定序号的数据 + bool GetKey(int,F &)const; ///<取指定序号的索引 + bool GetValue(int,T &)const; ///<取指定序号的数据 + + bool SetValueBySerial(int,T &); ///<根据序号设置数据 + + void operator=(const _Map &); ///<操作符重载,复制一个列表 + + void Enum(void (*enum_func)(const F &,T)); ///<枚举所有数据项 + void EnumKey(void (*enum_func)(const F &))const; ///<枚举所有索引 + void EnumValue(void (*enum_func)(T)); ///<枚举所有数值 + + void EnumValue(bool (*enum_func)(T)); ///<枚举所有数值 + };//class _Map + + template class Map:public _Map > + { + public: + + Map()=default; + virtual ~Map()=default; + };//class Map + + template T_U *GetObject(Map &list,const T_ID &id) + { + T_U *result; + + if(!list.Get(id,result)) + return(nullptr); + + return result; + } + + template class _MapObject:public _Map + { + protected: + + typedef _Map SuperClass; + + virtual void DeleteObject(const F &,T *)=0; ///<删除一个数据 + void DeleteObject(DataPair *ds){DeleteObject(ds->left,ds->right);} + void DeleteObject(int index){DeleteObject(this->data_list[index]);} + + public: + + _MapObject()=default; + virtual ~_MapObject() + { + if(SuperClass::GetCount()>0) + { + //LOG_ERROR(u"这是一个严重的程序设计错误,会产生纯虚函数调用,请在派生类的析构函数中调用Clear函数以清除数据。"); + LOG_ERROR(OS_TEXT("This is a serious design errors, will produce the pure virtual function call, please call in the destructor of the derived class the function to clear the data.")); + } + } + + /** + * 断开一个数据 + * @param flag 要断开的数据标识 + * @return 是否断开成功 + */ + bool UnlinkByKey(const F &flag) + { + return UnlinkBySerial(SuperClass::Find(flag)); + } + + /** + * 断开一个数据 + * @param tp 要断开的数据 + * @return 是否断开成功 + */ + bool UnlinkByValue(T *tp) + { + return UnlinkBySerial(this->FindByValue(tp)); + } + + /** + * 断开一个数据关联 + * @param index 要断开的数据的序列号 + * @return 是否断开成功 + */ + bool UnlinkBySerial(int index) + { + if(index<0||index>=this->data_list.GetCount())return(false); + + SuperClass::DeleteBySerial(index); + + return(true); + } + + /** + * 断开所有数据关联 + */ + void UnlinkAll() + { + SuperClass::Clear(); + } + + /** + * 删除一个数据 + * @param flag 要删除的数据标识 + * @return 是否删除成功 + */ + bool DeleteByKey(const F &flag) + { + return DeleteBySerial(SuperClass::Find(flag)); + } + + /** + * 删除一个数据 + * @param tp 要删除的数据 + * @return 是否删除成功 + */ + bool DeleteByValue(T *tp) + { + return DeleteBySerial(this->FindByValue(tp)); + } + + /** + * 删除一个数据 + * @param index 要删除的数据的序列号 + * @return 是否删除成功 + */ + bool DeleteBySerial(int index) + { + if(index<0||index>=this->data_list.GetCount())return(false); + + DeleteObject(index); + SuperClass::DeleteBySerial(index); + + return(true); + } + + /** + * 清除所有数据 + */ + void DeleteAll() + { + int n=this->data_list.GetCount(); + + while(n--) + DeleteObject(n); + + _Map::Clear(); + } + + /** + * 更新数据,如果数据不存在就添加一个新的 + * @param flag 数据标识 + * @param data 新的数据内容 + */ + void Update(const F &flag,T *data) + { + int index=this->Find(flag); + + if(index!=-1) + { + DeleteObject(index); + + this->data_list[index]->second=data; + } + else + { + this->Add(flag,data); + } + } + + /** + * 更改数据,这个更改和Set不同,它要求指定标识的数据必须存在,则否就会更改失败 + * @param flag 数据标识 + * @param data 新的数据内容 + * @param return 是否更改成功 + */ + bool Change(const F &flag,T *data) + { + int index=this->Find(flag); + + if(index!=-1) + { + DeleteObject(index); + + this->data_list[index]->second=data; + + return(true); + } + else + return(false); + } + + void Clear(){DeleteAll();} + };//class _MapObject + + template class CusMapObject:public _MapObject + { + protected: + + //virtual T * CreateObject(const F &){return(new T);} ///<创建一个数据 + virtual void DeleteObject(const F &,T *obj){delete obj;} ///<删除一个数据 + + public: + + CusMapObject()=default; + virtual ~CusMapObject() + { + _MapObject::Clear(); + } + };//class CusMapObject + + template class MapObject:public CusMapObject > + { + public: + + MapObject()=default; + virtual ~MapObject() + { + CusMapObject >::Clear(); + } + + T *operator[](const F &index)const + { + const int pos=this->Find(index); + + if(pos==-1)return(nullptr); + + return this->data_list[pos]->right; + }; + };//class MapObject +}//namespace hgl +#include +#endif//HGL_MAP_INCLUDE diff --git a/inc/hgl/type/Pair.h b/inc/hgl/type/Pair.h new file mode 100644 index 00000000..4f1e7895 --- /dev/null +++ b/inc/hgl/type/Pair.h @@ -0,0 +1,82 @@ +#ifndef HGL_TYPE_PAIR_INCLUDE +#define HGL_TYPE_PAIR_INCLUDE + +#include +#include + +namespace hgl +{ + /** + * 成对数据模板 + */ + template struct Pair ///成对数据模板 + { + L left; + R right; + + using SelfClass=Pair; + + public: + + Pair()=default; + + Pair(const L &l,const R &r) + { + left=l; + right=r; + } + + Pair(const SelfClass &p) + { + operator=(p); + } + + Pair(const SelfClass *p) + { + operator=(p); + } + + virtual ~Pair()=default; + + SelfClass &operator=(const SelfClass &p) + { + left=p.left; + right=p.right; + + return(*this); + } + + SelfClass &operator=(const SelfClass *p) + { + if(!p)return(*this); + + left=p->left; + right=p->right; + + return(*this); + } + + void Swap(Pair &p) + { + p.left=right; + p.right=left; + } + + //不使用CompOperator是因为某些类型无法做+-处理 + + const bool operator == (const SelfClass &p)const + { + if(this->left!=p.left)return(false); + + return this->right==p.right; + } + + const bool operator != (const SelfClass &p)const + { + if(this->left==p.left)return(false); + + return this->right!=p.right; + } + };//template struct Pair +}//namespace hgl +#endif//HGL_TYPE_PAIR_INCLUDE diff --git a/inc/hgl/type/Pool.cpp b/inc/hgl/type/Pool.cpp new file mode 100644 index 00000000..2bec56d1 --- /dev/null +++ b/inc/hgl/type/Pool.cpp @@ -0,0 +1,139 @@ +#ifndef HGL_POOL_CPP +#define HGL_POOL_CPP + +#include +#include +namespace hgl +{ + template + void Pool::PreMalloc(int num) + { + if(num<=0)return; + + for(int i=0;ihistory_max) + history_max=count; + } + + template + T Pool::Acquire() + { + T result; + + if(!Inactive.Pop(result)) + { + result=Create(); + + count++; + + if(count>history_max) + history_max=count; + } + + Active.Add(result); + + return(result); + } + + template + void Pool::Append(T value) + { + T result; + + if(!Inactive.Pop(result)) + { + count++; + + if(count>history_max) + history_max=count; + } + + Active.Add(result); + + result=value; + } + + template + bool Pool::Release(T value) + { + int index=Active.Find(value); + + if(index!=-1) + { + Active.Delete(index); + + Inactive.Push(value); + + return(true); + } + + return(false); + } + + template + int Pool::Release(T *vl,int count) + { + int total=0; + + for(int i=0;i + int Pool::ReleaseAll() + { + int count=Active.GetCount(); + T *p=Active.GetData(); + + for(int i=0;i + void Pool::ClearInactive() + { + T result; + + count-=Inactive.GetCount(); + + while(Inactive.Pop(result)) + Clear(result); + } + + template + void Pool::ClearAll() + { + { //不能直接调ClearInactive + T result; + + count-=Inactive.GetCount(); + + while(Inactive.Pop(result)) + Clear(result); + } + + { + int n=Active.GetCount(); + while(n--) + Clear(Active[n]); + + Active.Clear(); + } + + count=0; + } +}//namespace hgl +#endif//HGL_POOL_CPP diff --git a/inc/hgl/type/Pool.h b/inc/hgl/type/Pool.h new file mode 100644 index 00000000..ef09df44 --- /dev/null +++ b/inc/hgl/type/Pool.h @@ -0,0 +1,262 @@ +#ifndef HGL_POOL_INCLUDE +#define HGL_POOL_INCLUDE + +#include +#include +#include +#include +#include +namespace hgl +{ + /** + * 数据池模板用于管于两个队列,一个在用的,一个空闲的 + */ + template class Pool ///数据池 + { + protected: + + List Active; + Queue Inactive; + + int count; + int history_max; + + protected: + + virtual T Create()=0; ///<创建数据 + virtual void Clear(T)=0; ///<清除数据 + + public: //属性 + + virtual int GetActiveCount() const{return Active.GetCount();} ///<取得活动数据数量 + virtual int GetInactiveCount() const{return Inactive.GetCount();} ///<取得非活动数据数量 + virtual int GetHistoryMaxCount()const{return history_max;} ///<取得历史性最大数据数量 + + public: + + Pool(){count=0;history_max=0;} + virtual ~Pool()=default; + + virtual void PreMalloc(int); ///<预分配空间 + + virtual T Acquire(); ///<申请一个数据 + virtual void Append(T); ///<添加一个数据 + virtual bool Release(T); ///<释放一个数据 + virtual int Release(T *,int); ///<释放一批数据 + virtual int ReleaseAll(); ///<释放所有数据 + + virtual void ClearInactive(); ///<清除所有空闲的 + virtual void ClearAll(); ///<清除所有的 + + virtual T operator[](int n){return Active[n];} + };//template class Pool + + template class MTPool:public Pool ///多线程数据池 + { + RWLock lock; + + protected: + + virtual T Create()=0; ///<创建数据 + virtual void Clear(T)=0; ///<清除数据 + + public: + + virtual int GetActiveCount() {OnlyReadLock rl(lock);return Pool::Active.GetCount(); } + virtual int GetInactiveCount() {OnlyReadLock rl(lock);return Pool::Inactive.GetCount(); } + virtual int GetHistoryMaxCount(){OnlyReadLock rl(lock);return Pool::history_max; } + + public: + + virtual ~MTPool()=default; + + virtual T *ReadLock(int &c) ///<读列表锁定(用于访问整个列表) + { + lock.ReadLock(); + + c=Pool::GetActiveCount(); + return(Pool::Active.GetData()); + } + + virtual T *WriteLock(int &c) ///<写列表锁定(用于访问整个列表) + { + lock.WriteLock(); + + c=Pool::GetActiveCount(); + return(Pool::Active.GetData()); + } + + virtual T *TryReadLock(int &c) ///<尝试读列表锁定(用于访问整个列表) + { + if(!lock.TryReadLock()) + return(nullptr); + + c=Pool::GetActiveCount(); + return(Pool::Active.GetData()); + } + + virtual T *TryWriteLock(int &c) ///<尝试写列表锁定(用于访问整个列表) + { + if(!lock.TryWriteLock()) + return(nullptr); + + c=Pool::GetActiveCount(); + return(Pool::Active.GetData()); + } + + virtual void ReadLock(){lock.ReadLock();} + virtual void WriteLock(){lock.WriteLock();} + virtual bool TryReadLock(){return lock.TryReadLock();} + virtual bool TryWriteLock(){return lock.TryWriteLock();} + + virtual void ReadUnlock(){lock.ReadUnlock();} ///<读访问解锁(用于访问整个列表) + virtual void WriteUnlock(){lock.WriteUnlock();} ///<写访问解锁(用于访问整个列表) + + virtual T SafeAcquire() ///<安全申请一个数据 + { + T tmp; + + lock.WriteLock(); + tmp=Pool::Acquire(); + lock.WriteUnlock(); + + return tmp; + } + + virtual void SafeAppend(T tmp) ///<安全添加一个数据 + { + lock.WriteLock(); + Pool::Append(tmp); + lock.WriteUnlock(); + } + + virtual bool SafeRelease(T tmp) ///<安全释放一个数据 + { + bool result; + + lock.WriteLock(); + result=Pool::Release(tmp); + lock.WriteUnlock(); + + return result; + } + + virtual int SafeRelease(T *tmp,int num) ///<安全释放一批数据 + { + int result; + + lock.WriteLock(); + result=Pool::Release(tmp,num); + lock.WriteUnlock(); + + return result; + } + + virtual int SafeReleaseAll() ///<安全释放所有数据 + { + int result; + + lock.WriteLock(); + result=Pool::ReleaseAll(); + lock.WriteUnlock(); + + return(result); + } + + virtual void SafeClearInactive() ///<安全清除所有空闲数据 + { + lock.WriteLock(); + Pool::ClearInactive(); + lock.WriteUnlock(); + } + + virtual void SafeClearAll() ///<安全清除所有的 + { + lock.WriteLock(); + Pool::ClearAll(); + lock.WriteUnlock(); + } + };//template class MTPool + + template class _ObjectPool:public Pool ///对象池 + { + virtual T *Create()=0; + + virtual void Clear(T *obj) { if(obj)delete obj; } + + public: + + using Pool::Pool; + virtual ~_ObjectPool(){Pool::ClearAll();} + };//template class _ObjectPool + + template class ObjectPool:public _ObjectPool ///对象池 + { + virtual T *Create()override{return(new T());} + + public: + + using _ObjectPool::_ObjectPool; + virtual ~ObjectPool(){_ObjectPool::ClearAll();} + };//template class ObjectPool + + template class _MTObjectPool:public MTPool ///多线程对象池 + { + virtual T *Create() override=0; + + virtual void Clear(T *obj) override { if(obj)delete obj; } + + public: + + using MTPool::MTPool; + virtual ~_MTObjectPool(){MTPool::ClearAll();} + };//template class MTObjectPool + + template class MTObjectPool:public _MTObjectPool ///多线程对象池 + { + virtual T *Create() override {return(new T());} + + virtual void Clear(T *obj) override { if(obj)delete obj; } + + public: + + using _MTObjectPool::_MTObjectPool; + virtual ~MTObjectPool(){_MTObjectPool::ClearAll();} + };//template class MTObjectPool + + template class MemBlockPool:public Pool ///内存块池 + { + int memblock_size; + + T *Create() { return(new T[memblock_size]); } + + void Clear(T *obj) { if(obj)delete[] obj; } + + public: + + MemBlockPool(int size){SetSize(size);} + virtual ~MemBlockPool(){Pool::ClearAll();} + + void SetSize(int size){memblock_size=size;} + int GetSize(){return memblock_size;} + };//template class MemBlockPool + + template class MTMemBlockPool:public MTPool ///多线程内存块池 + { + int memblock_size; + + T *Create() { return(new T[memblock_size]); } + + void Clear(T *obj) { if(obj)delete[] obj; } + + public: + + MTMemBlockPool(int size){SetSize(size);} + virtual ~MTMemBlockPool(){MTPool::ClearAll();} + + void SetSize(int size){memblock_size=size;} + int GetSize(){return memblock_size;} + };//template class MTMemBlockPool +}//namespace hgl +#include +#endif//HGL_POOL_INCLUDE diff --git a/inc/hgl/type/Queue.cpp b/inc/hgl/type/Queue.cpp new file mode 100644 index 00000000..fe23ac1a --- /dev/null +++ b/inc/hgl/type/Queue.cpp @@ -0,0 +1,239 @@ +#ifndef HGL_QUEUE_CPP +#define HGL_QUEUE_CPP + +namespace hgl +{ + /** + * 本类构造函数 + * @param m 如果m的值不为0,则表示使用固定的队列大小。固定大小的队列会在一开始即分配好内存。 + */ + template + Queue::Queue(int m) + { + count=0; + + if(m) + { + max_count=m; + + items=hgl_aligned_malloc(max_count); + } + else max_count=0; + + mem_count=max_count; + } + + template + Queue::~Queue() + { + if(count||max_count)hgl_free(items); + } + + /** + * 修改队列的最大值 + */ + template + void Queue::SetMax(int m) + { + if(max_count||(!max_count&&count)) + items=(T *)hgl_realloc(items,m*sizeof(T)); + else + items=hgl_aligned_malloc(m); + + max_count=m; + mem_count=m; + + if(count>=max_count)count=max_count-1; + } + + /** + * 清除队列中的所有数据 + */ + template + void Queue::Clear() + { + if(max_count==0) + if(count) + { + hgl_free(items); + mem_count=0; + } + + count=0; + } + + /** + * 清除队列中的所有数据,但不释放内存 + */ + template + void Queue::ClearData() + { + count=0; + } + + /** + * 访问队列中的一个数据,但不清除它 + * @param t 取出的数据保存地 + * @return 是否成功取出数据 + */ + template + bool Queue::Peek(T &t) + { + if(count) + { +// t=items[0]; + memcpy(&t,items,sizeof(T)); + return(true); + } + else + return(false); + } + + /** + * 删除队列中的指定数据 + * @param index 索引 + */ + template + bool Queue::Delete(int index) + { + if(index<0||index>=count) + return(false); + + count--; + + if(count) + { + if(index + bool Queue::Pop(T &t) + { + if(count) + { +// t=items[0]; + memcpy(&t,items,sizeof(T)); + + count--; + + if(max_count==0) + { + if(count) + { + //memcpy(items,items+1,count*sizeof(T)); + memmove(items,items+1,count*sizeof(T)); +// items=(T *)hgl_realloc(items,count*sizeof(T)); + } + } + else + { + memcpy(items,items+1,count*sizeof(T)); + } + + return(true); + } + else + return(false); + } + + /** + * 向队列中放入一个数据 + * @param data 要放入的数据指针 + * @return true 放入数据成功 + * @return false 放入数据失败 + */ + template + bool Queue::Push(const T &data) + { + if(max_count) + { + if(count>=max_count)return(false); + } + else + { + if(count) + { + if(count+1>mem_count) + { + mem_count=power_to_2(count+1); + + items=(T *)hgl_realloc(items,mem_count*sizeof(T)); + } + } + else + { + items=hgl_aligned_malloc(1); + + mem_count=1; + } + } + +// items[count++]=data; + memcpy(items+count,&data,sizeof(T)); + count++; + + return(true); + } + + template + int Queue::Find(const T &data) + { + if(count<=0) + return(-1); + + T *p=items; + for(int i=0;i + void Queue::operator =(const Queue &ori) + { + if(ori.count==0)return; + + Clear(); + + max_count=ori.count; + count=ori.count; + + if(max_count==0) + mem_count=count; + else + mem_count=max_count; + + items=hgl_aligned_malloc(mem_count); + + memcpy(items,ori.items,mem_count*sizeof(T)); + } +} + +namespace hgl +{ + template + void QueueObject::Clear() + { + int n=Queue::count; + + while(n--) + delete Queue::items[n]; + + Queue::Clear(); + } +} +#endif//HGL_QUEUE_CPP diff --git a/inc/hgl/type/Queue.h b/inc/hgl/type/Queue.h new file mode 100644 index 00000000..88a5d020 --- /dev/null +++ b/inc/hgl/type/Queue.h @@ -0,0 +1,75 @@ +#ifndef HGL_QUEUE_INCLUDE +#define HGL_QUEUE_INCLUDE + +#include +namespace hgl +{ + /** + * Queue模板类用于保存一个先进先出、后进后出的数据队列 + * + * 注:这个类还在测试中,请不要修改这个类的源代码,如有修改意见,请致电作者。 + */ + template class Queue ///队列顺序数据访问类 + { + protected: + + int max_count; + int mem_count; + int count; + T *items; + + public: //属性 + + T *GetData()const{return items;} ///<取得原始数据 + int GetCount()const{return count;} ///<取得数据数量 + + int GetMax()const{return max_count;} ///<取得最大数量 + void SetMax(int); ///<设置最大数量 + + T *GetData(){return items;} ///<取得原始数据 + + public: //方法 + + Queue(int=0); + virtual ~Queue(); + + bool Peek(T &); ///<尝试访问一个数据 + bool Pop(T &); ///<弹出一个数据 + bool Push(const T &); ///<压入一个数据 + + int Find(const T &); ///<查找队列中这个数据的编号 + bool Delete(int); ///<删除队列中指定编号的数据 + + void Clear(); ///<清除所有数据 + void ClearData(); ///<清除所有数据,但不释放内存 + + bool GetItem(int n,T &ti) ///<取得指定项数据 + { + if(n<0||n>=count)return(false); + + ti=items[n]; + return(true); + } + + virtual void operator =(const Queue &); + };//template class Queue + + template class QueueObject:public Queue ///堆栈对象 + { + public: + + using Queue::Queue; + virtual ~QueueObject(){Clear();} + + void Clear(); + + T *operator[](int n)const + { + if(n<0||n>=Queue::count)return(nullptr); + + return Queue::items[n]; + } + };//template class QueueObject +}//namespace hgl +#include +#endif//HGL_QUEUE_INCLUDE diff --git a/inc/hgl/type/ResManage.cpp b/inc/hgl/type/ResManage.cpp new file mode 100644 index 00000000..74210a5a --- /dev/null +++ b/inc/hgl/type/ResManage.cpp @@ -0,0 +1,134 @@ +#ifndef HGL_RES_MANAGE_CPP +#define HGL_RES_MANAGE_CPP + +#include +namespace hgl +{ + template + ResManage::~ResManage() + { + Clear(); + } + + template + void ResManage::Clear() + { + int n=items.GetCount(); + + while(n--) + { + ResItem *obj=items.GetItem(n); + + Clear(obj->right); + } + + items.Clear(); + } + + template + void ResManage::ClearZero() + { + int n=items.GetCount(); + + while(n--) + { + ResItem *obj=items.GetItem(n); + + if(obj->count<=0) + { + Clear(obj->right); + items.DeleteBySerial(n); + } + } + } + + template + bool ResManage::Add(const F &flag,T *obj) + { + if(!obj)return(false); + + if(items.KeyExist(flag)) + return(false); + + items.Add(flag,obj); + return(true); + } + + template + T *ResManage::Find(const F &flag) + { + int index=items.Find(flag); + + if(index==-1) + return(nullptr); + + T *result; + + if(items.Get(flag,result)) + return(result); + + return(nullptr); + } + + template + T *ResManage::Get(const F &flag) + { + int index=items.Find(flag); + + if(index!=-1) + { + ResItem *obj=items.GetItem(index); + + //items[index]->count++; + obj->count++; + +// return(items[index]->data); + return obj->right; + } + + T *data=Create(flag); + + if(data) + { + items.Add(flag,data); + + return(data); + } + + return(nullptr); + } + + template + void ResManage::ReleaseBySerial(int index,bool zero_clear) + { + if(index==-1) + { +// ErrorHint(u"所释放的资源不存在"); + return; + } + + ResItem *obj=items.GetItem(index); + + --obj->count; + + if(zero_clear&&obj->count==0) + { + Clear(obj->right); + + items.DeleteBySerial(index); + } + } + + template + void ResManage::Release(const F &flag,bool zero_clear) + { + ReleaseBySerial(items.Find(flag),zero_clear); + } + + template + void ResManage::Release(T *td,bool zero_clear) + { + ReleaseBySerial(items.FindByValue(td),zero_clear); + } +}//namespace hgl +#endif//HGL_RES_MANAGE_CPP diff --git a/inc/hgl/type/ResManage.h b/inc/hgl/type/ResManage.h new file mode 100644 index 00000000..8b94083f --- /dev/null +++ b/inc/hgl/type/ResManage.h @@ -0,0 +1,55 @@ +#ifndef HGL_RES_MANAGE_INCLUDE +#define HGL_RES_MANAGE_INCLUDE + +#include +namespace hgl +{ + template struct RefFlagData:public Pair + { + uint count; + + public: + + RefFlagData():Pair() + { + count=1; + } + }; + + /** + * 资源管理器,它没有缓冲管理,仅仅是管理数据,并保证不会被重复加载 + */ + template class ResManage + { + protected: + + typedef RefFlagData ResItem; + + _Map items; + + void ReleaseBySerial(int,bool); + + protected: + + virtual T *Create(const F &)=0; ///<资源创建虚拟函数无实现,请特例化实现 + virtual void Clear(T *obj){delete obj;} ///<资源释放虚拟函数(缺省为直接delete对象) + + public: + + virtual ~ResManage(); + + virtual void Clear(); ///<清除所有数据 + virtual void ClearZero(); ///<清除所有没有用到的数据 + + const int GetCount()const{return items.GetCount();} ///<取得数据数量 + + virtual bool Add(const F &,T *); ///<添加一个数据 + virtual T * Find(const F &); ///<查找一个数据 + virtual T * Get(const F &); ///<取得一个数据,如不存在则创建 + + virtual void Release(const F &,bool zero_clear=false); ///<释放一个数据 + virtual void Release(T *,bool zero_clear=false); ///<释放一个数据 + };//template class ResManage +}//namespace hgl +#include +#endif//HGL_RES_MANAGE_INCLUDE diff --git a/inc/hgl/type/ResPoolManage.h b/inc/hgl/type/ResPoolManage.h new file mode 100644 index 00000000..9a282de9 --- /dev/null +++ b/inc/hgl/type/ResPoolManage.h @@ -0,0 +1,34 @@ +#ifndef HGL_RES_POOL_MANAGE_INCLUDE +#define HGL_RES_POOL_MANAGE_INCLUDE + +#include +#include + +namespace hgl +{ + /** + * 资源池是Pool/ResManage两个模板的组合应用 + */ + template class ResPoolManage:public ResManage + { + protected: + + ObjectPool data_pool; + + public: + + virtual T *Create(const I &flag){return data_pool.Acquire();} + virtual void Clear(T *obj){data_pool.Release(obj);} + + public: + + virtual ~ResPoolManage()=default; + + virtual void Clear() + { + this->items.Clear(); + data_pool.ClearAll(); + } + };//template class ResPoolManage:public ResManage +}//namespace hgl +#endif//HGL_RES_POOL_MANAGE_INCLUDE diff --git a/inc/hgl/type/Set.cpp b/inc/hgl/type/Set.cpp new file mode 100644 index 00000000..8de586ff --- /dev/null +++ b/inc/hgl/type/Set.cpp @@ -0,0 +1,365 @@ +#ifndef HGL_TYPE_SET_CPP +#define HGL_TYPE_SET_CPP + +#include +namespace hgl +{ + /** + * 查找数据是否存在 + * @param flag 数据 + * @return 数据所在索引,-1表示不存在 + */ + template + const int Set::Find(const T &flag)const + { + int left=0,right=data_list.GetCount()-1; //使用left,right而不使用min,max是为了让代码能够更好的阅读。 + int mid; + + T *data_array=data_list.GetData(); + + while(left<=right) + { + if(data_array[left ]==flag)return(left); + if(data_array[right]==flag)return(right); + + mid=(right+left)>>1; + + if(data_array[mid]==flag)return(mid); + + if(data_array[mid]>flag) + { + left++; + right=mid-1; + } + else + { + right--; + left=mid+1; + } + } + + return(-1); + } + + template + bool Set::FindPos(const T &flag,int &pos)const + { + int left=0,right=data_list.GetCount()-1; + int mid; + + T *data_array=data_list.GetData(); + + while(left<=right) + { + if(data_array[left]>flag) + { + pos=left; + return(false); + } + else + if(data_array[left]==flag) + { + pos=left; + return(true); + } + + if(data_array[right]>1; + + if(data_array[mid]==flag) + { + pos=mid; + return(true); + } + + if(data_array[mid]>flag) + { + if(data_array[mid-1]flag) + { + pos=mid+1; + return(false); + } + else + if(data_array[mid+1]==flag) + { + pos=mid+1; + return(true); + } + + --right; + left=mid+1; + } + } + + return(false); + } + + /** + * 添加一个数据 + * @param data 数据 + * @return 位置 + */ + template + int Set::Add(const T &data) + { + if(data_list.GetCount()<=0) + { + data_list.Add(data); + + return 0; + } + else + { + int pos; + + if(FindPos(data,pos)) + return(-1); //数据已存在 + + data_list.Insert(pos,data); + + return(pos); + } + } + + /** + * 添加一批数据 + * @param dp 数据指针 + * @param count 数据个数 + * @return 成功加入的数据个数 + */ + template + int Set::Add(const T *dp,const int count) + { + int total=0; + + for(int i=0;i + bool Set::Update(const T &data) + { + if(data_list.GetCount()<=0) + return(false); + + int pos; + + if(!FindPos(data,pos)) + return(false); + + data_list.Set(pos,data); + return(true); + } + + /** + * 删除一个数据 + * @param pos 索引编号 + */ + template + bool Set::DeleteBySerial(int pos) + { + if(pos<0||pos>=data_list.GetCount())return(false); + + return data_list.DeleteMove(pos); + } + + /** + * 删除一个数据 + * @param data 数据 + */ + template + bool Set::Delete(const T &data) + { + int pos=Find(data); + + if(pos==-1)return(false); + + return DeleteBySerial(pos); + } + + /** + * 删除一批数据 + * @param dp 数据指针 + * @param count 数据个数 + * @return 成功删除的数据个数 + */ + template + int Set::Delete(T *dp,const int count) + { + int total=0; + int pos; + + for(int i=0;i + void Set::Clear() + { + data_list.Clear(); + } + + /** + * 清除所有数据,但不释放内存 + */ + template + void Set::ClearData() + { + data_list.ClearData(); + } + + /** + * 随机取得一个数据 + */ + template + bool Set::Rand(T &result)const + { + return data_list.Rand(result); + } + + /** + * 求当前合集与另一个数据集的交集 + * @param result 结果存放合集 + * @param list 要计算交集的数据集 + * @return 交集数量 + */ + template + int Set::Intersection(Set &result,const Set &list) + { + if(data_list.GetCount()<=0) + return(0); + + if(list.GetCount()<=0) + return(0); + + data_list.Enum([&](T &obj) + { + if(list->IsMember(obj)) + result.Add(obj); + }); + + return result.GetCount(); + } + + template + int Set::Intersection(const Set &list) + { + if(data_list.GetCount()<=0) + return(0); + + if(list.GetCount()<=0) + return(0); + + int count=0; + + T *obj=data_list.GetData(); + for(int i=0;i + int Set::Intersection(Set &result,const Set &il,const Set &cl) + { + if(data_list.GetCount()<=0) + return(0); + + if(il.GetCount()<=0) + return(0); + + T *obj=data_list.GetData(); + for(int i=0;i + int Set::Difference(const Set &is) + { + if(data_list.GetCount()<=0) + return(is.GetCount()); + + if(is.GetCount()<=0) + return(data_list.GetCount()); + + int count=0; + + T *obj=data_list.GetData(); + for(int i=0;i +namespace hgl +{ + /** + * 集合数据列表中不允许数据出现重复性,同时它会将数据排序,所以也可以当做有序列表使用 + */ + template class Set + { + protected: + + List data_list; + + bool FindPos(const T &,int &)const; ///<查找数据如果插入后,会所在的位置,返回是否存在这个数据 + int FindPos(const T &flag)const{int pos;FindPos(flag,pos);return(pos);} ///<查找数据如果插入后,会所在的位置 + + public: //属性 + + List & GetList ()const{return data_list;} ///<取得数据原始列表 + T * GetData ()const{return data_list.GetData();} ///<取得数据指针 + int GetCount ()const{return data_list.GetCount();} ///<取得数据总量 + + public: + + Set()=default; + virtual ~Set()=default; + + void SetCount (int count){data_list.SetCount(count);} ///<指定数据数量,一般用于批量加载前的处理 + void PreMalloc (int count){data_list.PreMalloc(count);} ///<预分配指定数量的数据空间 + + const int Find (const T &)const; ///<查找数据位置,不存在返回-1 + const bool IsMember (const T &v)const{return(Find(v)!=-1);} ///<确认是否成员 + int Add (const T &); ///<添加一个数据,返回索引号,返回-1表示数据已存在 + int Add (const T *,const int); ///<添加一批数据 + int Add (const Set &s){return Add(s.GetData(),s.GetCount());} ///<添加一批数据 + bool Update (const T &); ///<更新一个数据 + bool Delete (const T &); ///<删除一个数据 + int Delete (T *,const int); ///<删除一批数据 + bool DeleteBySerial (int); ///<删除一个数据,使用序号 + void Clear (); ///<清除数据 + void ClearData (); ///<清除数据,但不释放内存 + void DeleteClear (){data_list.DeleteClear();} ///<清除所有数据并全部调用delete + + bool Get (const int index,T &data) + { + if(index<0||index>=data_list.GetCount()) + return(false); + + data=*(data_list.GetData()+index); + return(true); + } + + int Intersection (Set &result,const Set &set); ///<取得与指定合集的交集 + int Intersection (const Set &set); ///<取得与指定合集的交集数量 + + /** + * 取得与指定交集is的合集,但排斥cs合集中的数据 + * @param result 结果合集 + * @param is 求交集的合集 + * @param cs 求排斥的合集 + * @return 结果数量 + */ + int Intersection (Set &result,const Set &is,const Set &cs); + + int Difference (const Set &is); ///<求差集数量 + + void operator =(const Set &set){data_list=set.data_list;} ///<等号操作符重载 + + bool Rand (T &)const; ///<随机取得一个 + + virtual void Enum (void (*enum_func)(T &)){data_list.Enum(enum_func);} ///<枚举所有数据成员 + };//template class Set +}//namespace hgl +#include +#endif//HGL_TYPE_SET_INCLUDE diff --git a/inc/hgl/type/Smart.h b/inc/hgl/type/Smart.h index a7605cc8..03287ade 100644 --- a/inc/hgl/type/Smart.h +++ b/inc/hgl/type/Smart.h @@ -2,7 +2,6 @@ #define HGL_SMART_INCLUDE #include -#include #include namespace hgl { diff --git a/inc/hgl/type/Stack.cpp b/inc/hgl/type/Stack.cpp new file mode 100644 index 00000000..67923dd3 --- /dev/null +++ b/inc/hgl/type/Stack.cpp @@ -0,0 +1,261 @@ +#ifndef HGL_STACK_CPP +#define HGL_STACK_CPP + +#include +namespace hgl +{ + /** + * 本类构造函数 + * @param m 如果m的值不为0,则表示使用固定的堆栈大小。固定大小的堆栈会在一开始即分配好内存。 + */ + template + Stack::Stack(int m) + { + count=0; + + if(m) + { + max_count=m; + + items=hgl_aligned_malloc(max_count); + } + else + max_count=0; + + mem_count=max_count; + } + + template + Stack::~Stack() + { + if(count||max_count)hgl_free(items); + } + + /** + * 修改堆栈的最大值 + */ + template + void Stack::SetMax(int m) + { + if(m<=0)return; + + if(mem_count==0) + { + mem_count=power_to_2(m); + items=hgl_aligned_malloc(mem_count); + } + else + if(mem_count=max_count)count=max_count-1; + } + + template + bool Stack::SetCount(int c) + { + if(c<0)return(false); + + if(c>max_count) + return(false); + + count=c; + return(true); + } + + /** + * 清除堆栈中的所有数据 + */ + template + void Stack::Clear() + { + if(max_count==0) + if(count) + { + hgl_free(items); + mem_count=0; + } + + count=0; + } + + template + bool Stack::GetItem(int n,T &data) + { + if(n<0||n>=count) + { + LOG_ERROR(OS_TEXT("从堆栈中按索引<") + OSString(n) + OS_TEXT(">取数据,超出正常范围<")+OSString(count) + OS_TEXT(">")); + + return(false); + } + + data=items[n]; + return(true); + } + + /** + * 访问堆栈中的一个数据,但不清除它 + * @param t 取出的数据保存地 + * @return 是否成功取出数据 + */ + template + bool Stack::Peek(T &t) + { + if(count) + { + memcpy(&t,items+(count-1),sizeof(T)); +// t=items[count-1]; + return(true); + } + else + return(false); + } + + /** + * 从堆栈中取出一个数据 + * @param t 取出的数据保存地 + * @return 是否成功取出数据 + */ + template + bool Stack::Pop(T &t) + { + if(count) + { +// t=items[--count]; + count--; + memcpy(&t,items+count,sizeof(T)); + + if(max_count==0) + { + if(count==0) + { + hgl_free(items); + + mem_count=0; + } + //else + //items=(T *)hgl_realloc(items,count*sizeof(T)); + } + + return(true); + } + else + return(false); + } + + /** + * 向堆栈中放入一个数据 + * @param data 要放入的数据指针 + * @return true 放入数据成功 + * @return false 放入数据失败 + */ + template + bool Stack::Push(T &data) + { + if(max_count) + { + if(count>=max_count)return(false); + } + else + { + if(count) + { + if(count+1>mem_count) + { + mem_count=power_to_2(count+1); + + items=(T *)hgl_realloc(items,mem_count*sizeof(T)); + } + } + else + { + items=hgl_aligned_malloc(1); + + mem_count=1; + } + } + +// items[count++]=data; + memcpy(items+count,&data,sizeof(T)); + count++; + + return(true); + } + + /** + * 向堆栈中放入多个数据 + * @param data 要放入的数据 + * @param data_count 要放入的数据个数 + * @return true 放入数据成功 + * @return false 放入数据失败 + */ + template + bool Stack::MultiPush(T *data,int data_count) + { + if(max_count) + { + if(count>=max_count)return(false); + } + else + { + if(count) + { + if(count+data_count>mem_count) + { + mem_count=power_to_2(count+data_count); + + items=(T *)hgl_realloc(items,mem_count*sizeof(T)); + } + } + else + { + items=hgl_aligned_malloc(data_count); + + mem_count=data_count; + } + } + + memcpy(items+count,data,data_count*sizeof(T)); + count+=data_count; + + return(true); + } + + template + void Stack::operator =(const Stack &ori) + { + if(ori.count==0)return; + + Clear(); + + max_count=ori.count; + count=ori.count; + + if(max_count==0) + mem_count=count; + else + mem_count=max_count; + + items=hgl_aligned_malloc(mem_count); + + memcpy(items,ori.items,mem_count*sizeof(T)); + } +}//namespace hgl + +namespace hgl +{ + template + void StackObject::Clear() + { + for(int i=0;icount;i++) + delete this->items[i]; + + Stack::Clear(); + } +}//namespace hgl +#endif//HGL_STACK_CPP diff --git a/inc/hgl/type/Stack.h b/inc/hgl/type/Stack.h new file mode 100644 index 00000000..f9d85e53 --- /dev/null +++ b/inc/hgl/type/Stack.h @@ -0,0 +1,59 @@ +#ifndef HGL_STACK_INCLUDE +#define HGL_STACK_INCLUDE + +#include +namespace hgl +{ + /** + * Stack模板类用于保存一个先进后出、后进先出的数据堆栈 + * + * 注:这个类还在测试中,请不要修改这个类的源代码,如有修改意见,请致电作者。 + */ + template class Stack ///堆栈顺序数据访问类 + { + protected: + + int max_count; + int mem_count; + int count; + T *items; + + public: //属性 + + int GetCount() const{return count;} ///<取得堆栈中数据的个数 + bool SetCount(int c); ///<直接设置堆栈中数据的个数 + + int GetMax () const{return max_count;} ///<取得堆栈中的最大数据个数 + void SetMax (int); ///<设置堆栈中的最大数据个数 + + T * GetData () {return items;} ///<取得原始数据 + + public: //方法 + + Stack(int=0); + virtual ~Stack(); + + bool Peek(T &); ///<尝试访问一个数据 + virtual bool Pop(T &); ///<弹出一个数据 + bool Push(T &); ///<压入一个数据 + bool MultiPush(T *,int); ///<放入多个数据 + + virtual void Clear(); ///<清除所有数据 + + bool GetItem(int,T &); + + virtual void operator =(const Stack &); + };//template class Stack + + template class StackObject:public Stack ///堆栈对象 + { + public: + + using Stack::Stack; + virtual ~StackObject(){Clear();}; + + void Clear(); + };//template class StackObject +}//namespace hgl +#include +#endif//HGL_STACK_INCLUDE diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 24414f70..34f54d4c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,2 +1,2 @@ add_subdirectory(RenderDevice) -# add_subdirectory(RenderDriver) +add_subdirectory(RenderDriver) diff --git a/src/RenderDriver/CMakeLists.txt b/src/RenderDriver/CMakeLists.txt index 1d8d451a..066a9486 100644 --- a/src/RenderDriver/CMakeLists.txt +++ b/src/RenderDriver/CMakeLists.txt @@ -1,2 +1,3 @@ -add_library(ULRE.RenderDriver STATIC GLCore/) +add_library(ULRE.RenderDriver STATIC GLSL.cpp + Shader.cpp) diff --git a/src/RenderDriver/GLSL.cpp b/src/RenderDriver/GLSL.cpp new file mode 100644 index 00000000..8b71f30f --- /dev/null +++ b/src/RenderDriver/GLSL.cpp @@ -0,0 +1,392 @@ +#include +#include +#include +#include + +namespace hgl +{ + namespace + { + constexpr uint OpenGLShaderType[ShaderType::stEnd]= + { + GL_VERTEX_SHADER, ///<顶点着色程序 + GL_TESS_CONTROL_SHADER, ///<镶嵌控制着色程序(需OpenGL 4.0或ARB_tessellation_shader) + GL_TESS_EVALUATION_SHADER, ///<镶嵌评估着色程序(需OpenGL 4.0或ARB_tessellation_shader) + GL_GEOMETRY_SHADER, ///<几何着色程序 + GL_FRAGMENT_SHADER, ///<片断着色程序 + GL_COMPUTE_SHADER ///<计算着色程序(需OpenGL 4.3或ARB_compute_shader) + }; + } + + const char ShaderTypeName[ShaderType::stEnd][32]= + { + "Vertex", + "TessControl", + "TessEvaluation", + "Geometry", + "Fragment", + "Compute" + }; + + namespace + { + /** + * 编译一段shader + * @param type 类型 + * @param name 名称 + * @param shader_source 代码 + * @return 编译成功的shader句柄 + * @return 0 编译失败 + */ + GLuint CompileShader(GLenum type,const char *name,const char *shader_source) + { + if(!shader_source)return(0); + + GLuint shader=glCreateShader(type); + + glShaderSource(shader,1,&shader_source,0); + + glCompileShader(shader); + + GLint compiled,log_length; + + glGetShaderiv(shader,GL_COMPILE_STATUS,&compiled); + + if(compiled) + return(shader); + + glGetShaderiv(shader,GL_INFO_LOG_LENGTH,&log_length); + + GLint char_writen; + char *log=new char[log_length]; + + glGetShaderInfoLog(shader,log_length,&char_writen,log); + + LOG_HINT(UTF8String(name)+U8_TEXT(" shader compile error\n\n")+ UTF8String(log)); + + delete[] log; + + LOG_ERROR(shader_source); + + glDeleteShader(shader); + + return(0); + } + }//namespace + + void Shader::Clear() + { + for(int i=0;i=ShaderType::stEnd)return(false); + if(shader_index[shader_type])return(false); + + if(!shader_codes + ||!(*shader_codes))return(false); + + shader_index[shader_type]=CompileShader(OpenGLShaderType[shader_type],ShaderName[shader_type],shader_codes); + + if(!shader_index[shader_type]) + return(false); + + return(true); + } + + bool Shader::Build() + { + program=glCreateProgram(); + + for(int i=0;i +//#include + +namespace hgl +{ + /** + * 取得属性索引地址 + * @param name 属性名称 + * @return 索引地址 + * @return -1 出错 + */ + int Shader::GetAttribLocation(const char *name) + { + if(!name||!(*name))return(-1); + + int result; + + if(!attrib_location.Get(name,result)) + { + result=_GetAttribLocation(name); + + attrib_location.Add(name,result); + } + + return result; + } + + /** + * 取得一个变量的地址 + * @param name 变量名称 + * @return 地址 + * @return -1 出错 + */ + int Shader::GetUniformLocation(const char *name) ///<取得一个变量的地址 + { + if(!name||!(*name))return(-1); + + int result; + + if(!uniform_location.Get(name,result)) + { + result=_GetUniformLocation(name); + + uniform_location.Add(name,result); + } + + return result; + } + + /** + * 取得一个Shader只读数据区索引 + * @param name 数据区名称 + * @return 数据区索引 + * @return -1 出错 + */ + int Shader::GetUniformBlockIndex(const char *name) + { + if(!name||!(*name))return(-1); + + int result; + + if(!uniform_block_index.Get(name,result)) + { + result=_GetUniformBlockIndex(name); + + uniform_block_index.Add(name,result); + } + + return result; + } + + /** + * 取得一个Shader数据存储区索引 + * @param name 数据存储区名称 + * @return 数据存储区索引 + * @return -1 出错 + */ + int Shader::GetShaderStorageIndex(const char *name) + { + if(!name||!(*name))return(-1); + + int result; + + if(!ssbo_index.Get(name,result)) + { + result=_GetShaderStorageIndex(name); + + ssbo_index.Add(name,result); + } + + return result; + } + + #define HGL_GLSL_SetUniform1234(func,type) bool Shader::SetUniform1##func(const char *uniform_name,type v0) \ + { \ + const int location=GetUniformLocation(uniform_name); \ + \ + if(location==-1)return(false); \ + \ + return SetUniform1##func(location,v0); \ + } \ + \ + bool Shader::SetUniform2##func(const char *uniform_name,type v0,type v1) \ + { \ + const int location=GetUniformLocation(uniform_name); \ + \ + if(location==-1)return(false); \ + \ + return SetUniform2##func(location,v0,v1); \ + } \ + \ + bool Shader::SetUniform3##func(const char *uniform_name,type v0,type v1,type v2) \ + { \ + const int location=GetUniformLocation(uniform_name); \ + \ + if(location==-1)return(false); \ + \ + return SetUniform3##func(location,v0,v1,v2); \ + } \ + \ + bool Shader::SetUniform4##func(const char *uniform_name,type v0,type v1,type v2,type v3) \ + { \ + const int location=GetUniformLocation(uniform_name); \ + \ + if(location==-1)return(false); \ + \ + return SetUniform4##func(location,v0,v1,v2,v3); \ + } + HGL_GLSL_SetUniform1234(f,float); + HGL_GLSL_SetUniform1234(i,int); + HGL_GLSL_SetUniform1234(ui,unsigned int); + + #undef HGL_GLSL_SetUniform1234 + + #define HGL_GLSL_SetUniformPointer(func,type) bool Shader::SetUniform##func(const char *uniform_name,const type *value) \ + { \ + const int location=GetUniformLocation(uniform_name); \ + \ + if(location==-1)return(false); \ + \ + return SetUniform##func(location,value); \ + } + + HGL_GLSL_SetUniformPointer(1fv,float); + HGL_GLSL_SetUniformPointer(2fv,float); + HGL_GLSL_SetUniformPointer(3fv,float); + HGL_GLSL_SetUniformPointer(4fv,float); + + HGL_GLSL_SetUniformPointer(1iv,int); + HGL_GLSL_SetUniformPointer(2iv,int); + HGL_GLSL_SetUniformPointer(3iv,int); + HGL_GLSL_SetUniformPointer(4iv,int); + + HGL_GLSL_SetUniformPointer(1uiv,unsigned int); + HGL_GLSL_SetUniformPointer(2uiv,unsigned int); + HGL_GLSL_SetUniformPointer(3uiv,unsigned int); + HGL_GLSL_SetUniformPointer(4uiv,unsigned int); + + #undef HGL_GLSL_SetUniformPointer + + #define HGL_GLSL_SetUniformMatrixPointer(func) bool Shader::SetUniformMatrix##func(const char *uniform_name,const float *mat) \ + { \ + const int location=GetUniformLocation(uniform_name); \ + \ + if(location==-1)return(false); \ + \ + return SetUniformMatrix##func(location,mat); \ + } + + HGL_GLSL_SetUniformMatrixPointer(2fv); + HGL_GLSL_SetUniformMatrixPointer(3fv); + HGL_GLSL_SetUniformMatrixPointer(4fv); + + HGL_GLSL_SetUniformMatrixPointer(2x3fv); + HGL_GLSL_SetUniformMatrixPointer(3x2fv); + HGL_GLSL_SetUniformMatrixPointer(2x4fv); + HGL_GLSL_SetUniformMatrixPointer(4x2fv); + HGL_GLSL_SetUniformMatrixPointer(3x4fv); + HGL_GLSL_SetUniformMatrixPointer(4x3fv); + + #undef HGL_GLSL_SetUniformMatrixPointer + +// /** +// * 取得一个Shader只读数据区的访问对象 +// * @param name 对象名称 +// * @param level 访问级别 +// * @return 对象指针 +// */ +// UBO *Shader::GetUniformBlock(const char *name,uint level) +// { +// if(!name||!(*name)) +// { +// LOG_ERROR(U8_TEXT("UBO name error:")); +// return(nullptr); +// } +// +// UBO *ubo=uniform_block_object[name]; +// +// if(ubo) +// return ubo; +// +// const int index=GetUniformBlockIndex(name); +// +// if(index<0) +// { +// LOG_ERROR(U8_TEXT("UBO name error:")+UTF8String(name)); +// return(nullptr); +// } +// +// ubo=new UBO(name,program,index,level); +// +// uniform_block_object.Add(name,ubo); +// +// return ubo; +// } +// +// /** +// * 取得一个Shader数据存储区的访问对象 +// * @param name 对象名称 +// * @param level 访问级别 +// * @return 对象指针 +// */ +// SSBO *Shader::GetShaderStorage(const char *name,uint level) +// { +// if(!name||!(*name)) +// { +// LOG_ERROR(U8_TEXT("SSBO name error:")); +// return(nullptr); +// } +// +// SSBO *ssbo=ssbo_object[name]; +// +// if(ssbo) +// return ssbo; +// +// const int index=GetShaderStorageIndex(name); +// +// if(index<0) +// { +// LOG_ERROR(U8_TEXT("SSBO name error:")+UTF8String(name)); +// return(nullptr); +// } +// +// ssbo=new SSBO(name,program,index,level); +// +// ssbo_object.Add(name,ssbo); +// +// return ssbo; +// } +}//namespace hgl