00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef Uniform_INCLUDE_ONCE
00033 #define Uniform_INCLUDE_ONCE
00034
00035 #include <vlCore/vlnamespace.hpp>
00036 #include <vlCore/Object.hpp>
00037 #include <vlCore/Vector4.hpp>
00038 #include <vlCore/Matrix4.hpp>
00039 #include <vlGraphics/OpenGL.hpp>
00040 #include <cstring>
00041 #include <map>
00042 #include <vector>
00043 #include <algorithm>
00044
00045 namespace vl
00046 {
00047
00048
00049
00059 class Uniform: public Object
00060 {
00061 VL_INSTRUMENT_CLASS(vl::Uniform, Object)
00062
00063 friend class GLSLProgram;
00064
00065 public:
00066
00067 Uniform(): mType(UT_NONE)
00068 {
00069 VL_DEBUG_SET_OBJECT_NAME()
00070 }
00071
00072 Uniform(const char* name): mType(UT_NONE)
00073 {
00074 VL_DEBUG_SET_OBJECT_NAME()
00075 mName = name;
00076 }
00077
00078 ref<Uniform> clone() const
00079 {
00080 ref<Uniform> uniform = new Uniform;
00081 *uniform = *this;
00082 return uniform;
00083 }
00084
00086 const std::string& name() const { return mName; }
00087
00089 std::string& name() { return mName; }
00090
00092 void setName(const char* name) { mName = name; }
00093
00094
00095
00096 void setUniform1i(int count, const int* value) { initData(count*1); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_INT; VL_CHECK(Has_GLSL); }
00097 void setUniform2i(int count, const int* value) { initData(count*2); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_INT_VEC2; VL_CHECK(Has_GLSL); }
00098 void setUniform3i(int count, const int* value) { initData(count*3); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_INT_VEC3; VL_CHECK(Has_GLSL); }
00099 void setUniform4i(int count, const int* value) { initData(count*4); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_INT_VEC4; VL_CHECK(Has_GLSL); }
00100
00101 void setUniform1ui(int count, const unsigned int* value) { initData(count*1); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_UNSIGNED_INT; VL_CHECK(Has_GL_EXT_gpu_shader4||Has_GL_Version_3_0||Has_GL_Version_4_0); }
00102 void setUniform2ui(int count, const unsigned int* value) { initData(count*2); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_UNSIGNED_INT_VEC2; VL_CHECK(Has_GL_EXT_gpu_shader4||Has_GL_Version_3_0||Has_GL_Version_4_0); }
00103 void setUniform3ui(int count, const unsigned int* value) { initData(count*3); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_UNSIGNED_INT_VEC3; VL_CHECK(Has_GL_EXT_gpu_shader4||Has_GL_Version_3_0||Has_GL_Version_4_0); }
00104 void setUniform4ui(int count, const unsigned int* value) { initData(count*4); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_UNSIGNED_INT_VEC4; VL_CHECK(Has_GL_EXT_gpu_shader4||Has_GL_Version_3_0||Has_GL_Version_4_0); }
00105
00106 void setUniform1f(int count, const float* value) { initData(count*1); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_FLOAT; VL_CHECK(Has_GLSL); }
00107 void setUniform2f(int count, const float* value) { initData(count*2); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_FLOAT_VEC2; VL_CHECK(Has_GLSL); }
00108 void setUniform3f(int count, const float* value) { initData(count*3); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_FLOAT_VEC3; VL_CHECK(Has_GLSL); }
00109 void setUniform4f(int count, const float* value) { initData(count*4); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_FLOAT_VEC4; VL_CHECK(Has_GLSL); }
00110
00111 void setUniform1d(int count, const double* value) { initDouble(count*1); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_DOUBLE; VL_CHECK(Has_GL_Version_4_0); }
00112 void setUniform2d(int count, const double* value) { initDouble(count*2); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_DOUBLE_VEC2; VL_CHECK(Has_GL_Version_4_0); }
00113 void setUniform3d(int count, const double* value) { initDouble(count*3); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_DOUBLE_VEC3; VL_CHECK(Has_GL_Version_4_0); }
00114 void setUniform4d(int count, const double* value) { initDouble(count*4); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_DOUBLE_VEC4; VL_CHECK(Has_GL_Version_4_0); }
00115
00116
00117
00118 void setUniformMatrix2f(int count, const float* value) { initData(count*2*2); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_FLOAT_MAT2; VL_CHECK(Has_GLSL); }
00119 void setUniformMatrix3f(int count, const float* value) { initData(count*3*3); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_FLOAT_MAT3; VL_CHECK(Has_GLSL); }
00120 void setUniformMatrix4f(int count, const float* value) { initData(count*4*4); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_FLOAT_MAT4; VL_CHECK(Has_GLSL); }
00121
00122 void setUniformMatrix2x3f(int count, const float* value) { initData(count*2*3); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_FLOAT_MAT2x3; VL_CHECK(Has_GLSL_120_Or_More); }
00123 void setUniformMatrix3x2f(int count, const float* value) { initData(count*3*2); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_FLOAT_MAT3x2; VL_CHECK(Has_GLSL_120_Or_More); }
00124 void setUniformMatrix2x4f(int count, const float* value) { initData(count*2*4); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_FLOAT_MAT2x4; VL_CHECK(Has_GLSL_120_Or_More); }
00125 void setUniformMatrix4x2f(int count, const float* value) { initData(count*4*2); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_FLOAT_MAT4x2; VL_CHECK(Has_GLSL_120_Or_More); }
00126 void setUniformMatrix3x4f(int count, const float* value) { initData(count*3*4); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_FLOAT_MAT3x4; VL_CHECK(Has_GLSL_120_Or_More); }
00127 void setUniformMatrix4x3f(int count, const float* value) { initData(count*4*3); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_FLOAT_MAT4x3; VL_CHECK(Has_GLSL_120_Or_More); }
00128
00129 void setUniformMatrix2d(int count, const double* value) { initDouble(count*2*2); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_DOUBLE_MAT2; VL_CHECK(Has_GL_Version_4_0); }
00130 void setUniformMatrix3d(int count, const double* value) { initDouble(count*3*3); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_DOUBLE_MAT3; VL_CHECK(Has_GL_Version_4_0); }
00131 void setUniformMatrix4d(int count, const double* value) { initDouble(count*4*4); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_DOUBLE_MAT4; VL_CHECK(Has_GL_Version_4_0); }
00132
00133 void setUniformMatrix2x3d(int count, const double* value) { initDouble(count*2*3); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_DOUBLE_MAT2x3; VL_CHECK(Has_GL_Version_4_0); }
00134 void setUniformMatrix3x2d(int count, const double* value) { initDouble(count*3*2); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_DOUBLE_MAT3x2; VL_CHECK(Has_GL_Version_4_0); }
00135 void setUniformMatrix2x4d(int count, const double* value) { initDouble(count*2*4); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_DOUBLE_MAT2x4; VL_CHECK(Has_GL_Version_4_0); }
00136 void setUniformMatrix4x2d(int count, const double* value) { initDouble(count*4*2); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_DOUBLE_MAT4x2; VL_CHECK(Has_GL_Version_4_0); }
00137 void setUniformMatrix3x4d(int count, const double* value) { initDouble(count*3*4); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_DOUBLE_MAT3x4; VL_CHECK(Has_GL_Version_4_0); }
00138 void setUniformMatrix4x3d(int count, const double* value) { initDouble(count*4*3); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_DOUBLE_MAT4x3; VL_CHECK(Has_GL_Version_4_0); }
00139
00140
00141
00142 void setUniform(int count, const int* value) { setUniform1i(count, value); }
00143 void setUniform(int count, const ivec2* value) { setUniform2i(count, value->ptr()); }
00144 void setUniform(int count, const ivec3* value) { setUniform3i(count, value->ptr()); }
00145 void setUniform(int count, const ivec4* value) { setUniform4i(count, value->ptr()); }
00146
00147 void setUniform(int count, const unsigned int* value) { setUniform1ui(count, value); }
00148 void setUniform(int count, const uvec2* value) { setUniform2ui(count, value->ptr()); }
00149 void setUniform(int count, const uvec3* value) { setUniform3ui(count, value->ptr()); }
00150 void setUniform(int count, const uvec4* value) { setUniform4ui(count, value->ptr()); }
00151
00152 void setUniform(int count, const float* value) { setUniform1f(count, value); }
00153 void setUniform(int count, const fvec2* value) { setUniform2f(count, value->ptr()); }
00154 void setUniform(int count, const fvec3* value) { setUniform3f(count, value->ptr()); }
00155 void setUniform(int count, const fvec4* value) { setUniform4f(count, value->ptr()); }
00156
00157 void setUniform(int count, const fmat2* value) { setUniformMatrix2f(count, value->ptr()); }
00158 void setUniform(int count, const fmat3* value) { setUniformMatrix3f(count, value->ptr()); }
00159 void setUniform(int count, const fmat4* value) { setUniformMatrix4f(count, value->ptr()); }
00160
00161 void setUniform(int count, const double* value) { setUniform1d(count, value); }
00162 void setUniform(int count, const dvec2* value) { setUniform2d(count, value->ptr()); }
00163 void setUniform(int count, const dvec3* value) { setUniform3d(count, value->ptr()); }
00164 void setUniform(int count, const dvec4* value) { setUniform4d(count, value->ptr()); }
00165
00166 void setUniform(int count, const dmat2* value) { setUniformMatrix2d(count, value->ptr()); }
00167 void setUniform(int count, const dmat3* value) { setUniformMatrix3d(count, value->ptr()); }
00168 void setUniform(int count, const dmat4* value) { setUniformMatrix4d(count, value->ptr()); }
00169
00170
00171
00172 void setUniformI(const int& value) { setUniform1i(1, &value); }
00173 void setUniform(const ivec2& value) { setUniform2i(1, value.ptr()); }
00174 void setUniform(const ivec3& value) { setUniform3i(1, value.ptr()); }
00175 void setUniform(const ivec4& value) { setUniform4i(1, value.ptr()); }
00176
00177 void setUniformU(const unsigned int& value) { setUniform1ui(1, &value); }
00178 void setUniform(const uvec2& value) { setUniform2ui(1, value.ptr()); }
00179 void setUniform(const uvec3& value) { setUniform3ui(1, value.ptr()); }
00180 void setUniform(const uvec4& value) { setUniform4ui(1, value.ptr()); }
00181
00182 void setUniformF(const float& value) { setUniform1f(1, &value); }
00183 void setUniform(const fvec2& value) { setUniform2f(1, value.ptr()); }
00184 void setUniform(const fvec3& value) { setUniform3f(1, value.ptr()); }
00185 void setUniform(const fvec4& value) { setUniform4f(1, value.ptr()); }
00186
00187 void setUniform(const fmat2& value) { setUniformMatrix2f(1, value.ptr()); }
00188 void setUniform(const fmat3& value) { setUniformMatrix3f(1, value.ptr()); }
00189 void setUniform(const fmat4& value) { setUniformMatrix4f(1, value.ptr()); }
00190
00191 void setUniformD(const double& value) { setUniform1d(1, &value); }
00192 void setUniform(const dvec2& value) { setUniform2d(1, value.ptr()); }
00193 void setUniform(const dvec3& value) { setUniform3d(1, value.ptr()); }
00194 void setUniform(const dvec4& value) { setUniform4d(1, value.ptr()); }
00195
00196 void setUniform(const dmat2& value) { setUniformMatrix2d(1, value.ptr()); }
00197 void setUniform(const dmat3& value) { setUniformMatrix3d(1, value.ptr()); }
00198 void setUniform(const dmat4& value) { setUniformMatrix4d(1, value.ptr()); }
00199
00200
00201
00202 void getUniform(double* value) const { VL_CHECK(type() != UT_NONE); VL_CHECK(mData.size()); memcpy( value, &mData[0], sizeof(mData[0]) * mData.size()); }
00203 void getUniform(float* value) const { VL_CHECK(type() != UT_NONE); VL_CHECK(mData.size()); memcpy( value, &mData[0], sizeof(mData[0]) * mData.size()); }
00204 void getUniform(int* value) const { VL_CHECK(type() != UT_NONE); VL_CHECK(mData.size()); memcpy( value, &mData[0], sizeof(mData[0]) * mData.size()); }
00205 void getUniform(unsigned int* value) const { VL_CHECK(type() != UT_NONE); VL_CHECK(mData.size()); memcpy( value, &mData[0], sizeof(mData[0]) * mData.size()); }
00206
00207 void getUniform(ivec2* value) const { getUniform(value->ptr()); }
00208 void getUniform(ivec3* value) const { getUniform(value->ptr()); }
00209 void getUniform(ivec4* value) const { getUniform(value->ptr()); }
00210
00211 void getUniform(uvec2* value) const { getUniform(value->ptr()); }
00212 void getUniform(uvec3* value) const { getUniform(value->ptr()); }
00213 void getUniform(uvec4* value) const { getUniform(value->ptr()); }
00214
00215 void getUniform(fvec2* value) const { getUniform(value->ptr()); }
00216 void getUniform(fvec3* value) const { getUniform(value->ptr()); }
00217 void getUniform(fvec4* value) const { getUniform(value->ptr()); }
00218
00219 void getUniform(fmat2* value) const { getUniform(value->ptr()); }
00220 void getUniform(fmat3* value) const { getUniform(value->ptr()); }
00221 void getUniform(fmat4* value) const { getUniform(value->ptr()); }
00222
00223 void getUniform(dvec2* value) const { getUniform(value->ptr()); }
00224 void getUniform(dvec3* value) const { getUniform(value->ptr()); }
00225 void getUniform(dvec4* value) const { getUniform(value->ptr()); }
00226
00227 void getUniform(dmat2* value) const { getUniform(value->ptr()); }
00228 void getUniform(dmat3* value) const { getUniform(value->ptr()); }
00229 void getUniform(dmat4* value) const { getUniform(value->ptr()); }
00230
00231 EUniformType type() const { return mType; }
00232
00233 int count() const
00234 {
00235 if (mData.empty())
00236 return 0;
00237
00238 switch(mType)
00239 {
00240 case UT_INT: return singleCount();
00241 case UT_INT_VEC2: return singleCount() / 2;
00242 case UT_INT_VEC3: return singleCount() / 3;
00243 case UT_INT_VEC4: return singleCount() / 4;
00244
00245 case UT_UNSIGNED_INT: return singleCount();
00246 case UT_UNSIGNED_INT_VEC2: return singleCount() / 2;
00247 case UT_UNSIGNED_INT_VEC3: return singleCount() / 3;
00248 case UT_UNSIGNED_INT_VEC4: return singleCount() / 4;
00249
00250 case UT_FLOAT: return singleCount();
00251 case UT_FLOAT_VEC2: return singleCount() / 2;
00252 case UT_FLOAT_VEC3: return singleCount() / 3;
00253 case UT_FLOAT_VEC4: return singleCount() / 4;
00254
00255 case UT_FLOAT_MAT2: return singleCount() / (2*2);
00256 case UT_FLOAT_MAT3: return singleCount() / (3*3);
00257 case UT_FLOAT_MAT4: return singleCount() / (4*4);
00258
00259 case UT_FLOAT_MAT2x3: return singleCount() / (2*3);
00260 case UT_FLOAT_MAT3x2: return singleCount() / (3*2);
00261 case UT_FLOAT_MAT2x4: return singleCount() / (2*4);
00262 case UT_FLOAT_MAT4x2: return singleCount() / (4*2);
00263 case UT_FLOAT_MAT3x4: return singleCount() / (3*4);
00264 case UT_FLOAT_MAT4x3: return singleCount() / (4*3);
00265
00266 case UT_DOUBLE: return doubleCount();
00267 case UT_DOUBLE_VEC2: return doubleCount() / 2;
00268 case UT_DOUBLE_VEC3: return doubleCount() / 3;
00269 case UT_DOUBLE_VEC4: return doubleCount() / 4;
00270
00271 case UT_DOUBLE_MAT2: return doubleCount() / (2*2);
00272 case UT_DOUBLE_MAT3: return doubleCount() / (3*3);
00273 case UT_DOUBLE_MAT4: return doubleCount() / (4*4);
00274
00275 case UT_DOUBLE_MAT2x3: return doubleCount() / (2*3);
00276 case UT_DOUBLE_MAT3x2: return doubleCount() / (3*2);
00277 case UT_DOUBLE_MAT2x4: return doubleCount() / (2*4);
00278 case UT_DOUBLE_MAT4x2: return doubleCount() / (4*2);
00279 case UT_DOUBLE_MAT3x4: return doubleCount() / (3*4);
00280 case UT_DOUBLE_MAT4x3: return doubleCount() / (4*3);
00281
00282 default:
00283 VL_TRAP()
00284 return -1;
00285 }
00286 }
00287
00288 void* rawData() { if (mData.empty()) return NULL; else return &mData[0]; }
00289
00290 const void* rawData() const { if (mData.empty()) return NULL; else return &mData[0]; }
00291
00292 protected:
00293 VL_COMPILE_TIME_CHECK( sizeof(int) == sizeof(float) )
00294 void initData(int count) { mData.resize(count); }
00295 void initDouble(int count) { mData.resize(count*2); }
00296 int singleCount() const { return (int)mData.size(); }
00297 int doubleCount() const { VL_CHECK((mData.size() & 0x1) == 0 ); return (int)(mData.size() >> 1); }
00298 const double* doubleData() const { VL_CHECK(!mData.empty()); VL_CHECK((mData.size() & 0x1) == 0 ); return (double*)&mData[0]; }
00299 const float* floatData() const { VL_CHECK(!mData.empty()); return (float*)&mData[0]; }
00300 const int* intData() const { VL_CHECK(!mData.empty()); return (int*)&mData[0]; }
00301 const unsigned int* uintData() const { VL_CHECK(!mData.empty()); return (unsigned int*)&mData[0]; }
00302
00303 EUniformType mType;
00304 std::vector<int> mData;
00305 std::string mName;
00306 };
00307 }
00308
00309 #endif