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 friend class GLSLProgram;
00062 public:
00063 virtual const char* className() { return "vl::Uniform"; }
00064
00065 Uniform(): mType(UT_NONE)
00066 {
00067 VL_DEBUG_SET_OBJECT_NAME()
00068 }
00069
00070 Uniform(const std::string& name): mType(UT_NONE)
00071 {
00072 VL_DEBUG_SET_OBJECT_NAME()
00073 mName = name;
00074 }
00075
00077 const std::string& name() const { return mName; }
00079 std::string& name() { return mName; }
00081 void setName(const std::string& name) { mName = name; }
00082
00083
00084
00085 void setUniform1i(int count, const int* value) { initData(count*1); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Int; VL_CHECK(GLEW_Has_Shading_Language_20); }
00086 void setUniform2i(int count, const int* value) { initData(count*2); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Int2; VL_CHECK(GLEW_Has_Shading_Language_20); }
00087 void setUniform3i(int count, const int* value) { initData(count*3); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Int3; VL_CHECK(GLEW_Has_Shading_Language_20); }
00088 void setUniform4i(int count, const int* value) { initData(count*4); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Int4; VL_CHECK(GLEW_Has_Shading_Language_20); }
00089
00090 void setUniform1ui(int count, const unsigned int* value) { initData(count*1); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_UInt; VL_CHECK(GLEW_EXT_gpu_shader4||GLEW_VERSION_3_0||GLEW_VERSION_4_0); }
00091 void setUniform2ui(int count, const unsigned int* value) { initData(count*2); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_UInt2; VL_CHECK(GLEW_EXT_gpu_shader4||GLEW_VERSION_3_0||GLEW_VERSION_4_0); }
00092 void setUniform3ui(int count, const unsigned int* value) { initData(count*3); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_UInt3; VL_CHECK(GLEW_EXT_gpu_shader4||GLEW_VERSION_3_0||GLEW_VERSION_4_0); }
00093 void setUniform4ui(int count, const unsigned int* value) { initData(count*4); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_UInt4; VL_CHECK(GLEW_EXT_gpu_shader4||GLEW_VERSION_3_0||GLEW_VERSION_4_0); }
00094
00095 void setUniform1f(int count, const float* value) { initData(count*1); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Float; VL_CHECK(GLEW_Has_Shading_Language_20); }
00096 void setUniform2f(int count, const float* value) { initData(count*2); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Float2; VL_CHECK(GLEW_Has_Shading_Language_20); }
00097 void setUniform3f(int count, const float* value) { initData(count*3); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Float3; VL_CHECK(GLEW_Has_Shading_Language_20); }
00098 void setUniform4f(int count, const float* value) { initData(count*4); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Float4; VL_CHECK(GLEW_Has_Shading_Language_20); }
00099
00100 void setUniform1d(int count, const double* value) { initDouble(count*1); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Double; VL_CHECK(GLEW_VERSION_4_0); }
00101 void setUniform2d(int count, const double* value) { initDouble(count*2); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Double2; VL_CHECK(GLEW_VERSION_4_0); }
00102 void setUniform3d(int count, const double* value) { initDouble(count*3); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Double3; VL_CHECK(GLEW_VERSION_4_0); }
00103 void setUniform4d(int count, const double* value) { initDouble(count*4); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Double4; VL_CHECK(GLEW_VERSION_4_0); }
00104
00105
00106
00107 void setUniformMatrix2f(int count, const float* value) { initData(count*2*2); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Mat2F; VL_CHECK(GLEW_Has_Shading_Language_20); }
00108 void setUniformMatrix3f(int count, const float* value) { initData(count*3*3); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Mat3F; VL_CHECK(GLEW_Has_Shading_Language_20); }
00109 void setUniformMatrix4f(int count, const float* value) { initData(count*4*4); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Mat4F; VL_CHECK(GLEW_Has_Shading_Language_20); }
00110
00111 void setUniformMatrix2x3f(int count, const float* value) { initData(count*2*3); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Mat2x3F; VL_CHECK(GLEW_Has_Shading_Language_21); }
00112 void setUniformMatrix3x2f(int count, const float* value) { initData(count*3*2); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Mat3x2F; VL_CHECK(GLEW_Has_Shading_Language_21); }
00113 void setUniformMatrix2x4f(int count, const float* value) { initData(count*2*4); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Mat2x4F; VL_CHECK(GLEW_Has_Shading_Language_21); }
00114 void setUniformMatrix4x2f(int count, const float* value) { initData(count*4*2); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Mat4x2F; VL_CHECK(GLEW_Has_Shading_Language_21); }
00115 void setUniformMatrix3x4f(int count, const float* value) { initData(count*3*4); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Mat3x4F; VL_CHECK(GLEW_Has_Shading_Language_21); }
00116 void setUniformMatrix4x3f(int count, const float* value) { initData(count*4*3); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Mat4x3F; VL_CHECK(GLEW_Has_Shading_Language_21); }
00117
00118 void setUniformMatrix2d(int count, const double* value) { initDouble(count*2*2); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Mat2D; VL_CHECK(GLEW_VERSION_4_0); }
00119 void setUniformMatrix3d(int count, const double* value) { initDouble(count*3*3); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Mat3D; VL_CHECK(GLEW_VERSION_4_0); }
00120 void setUniformMatrix4d(int count, const double* value) { initDouble(count*4*4); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Mat4D; VL_CHECK(GLEW_VERSION_4_0); }
00121
00122 void setUniformMatrix2x3d(int count, const double* value) { initDouble(count*2*3); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Mat2x3D; VL_CHECK(GLEW_VERSION_4_0); }
00123 void setUniformMatrix3x2d(int count, const double* value) { initDouble(count*3*2); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Mat3x2D; VL_CHECK(GLEW_VERSION_4_0); }
00124 void setUniformMatrix2x4d(int count, const double* value) { initDouble(count*2*4); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Mat2x4D; VL_CHECK(GLEW_VERSION_4_0); }
00125 void setUniformMatrix4x2d(int count, const double* value) { initDouble(count*4*2); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Mat4x2D; VL_CHECK(GLEW_VERSION_4_0); }
00126 void setUniformMatrix3x4d(int count, const double* value) { initDouble(count*3*4); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Mat3x4D; VL_CHECK(GLEW_VERSION_4_0); }
00127 void setUniformMatrix4x3d(int count, const double* value) { initDouble(count*4*3); memcpy(&mData[0], value, sizeof(mData[0]) * mData.size()); mType = UT_Mat4x3D; VL_CHECK(GLEW_VERSION_4_0); }
00128
00129
00130
00131 void setUniform(int count, const ivec2* value) { setUniform2i(count, value->ptr()); }
00132 void setUniform(int count, const ivec3* value) { setUniform3i(count, value->ptr()); }
00133 void setUniform(int count, const ivec4* value) { setUniform4i(count, value->ptr()); }
00134
00135 void setUniform(int count, const uvec2* value) { setUniform2ui(count, value->ptr()); }
00136 void setUniform(int count, const uvec3* value) { setUniform3ui(count, value->ptr()); }
00137 void setUniform(int count, const uvec4* value) { setUniform4ui(count, value->ptr()); }
00138
00139 void setUniform(int count, const fvec2* value) { setUniform2f(count, value->ptr()); }
00140 void setUniform(int count, const fvec3* value) { setUniform3f(count, value->ptr()); }
00141 void setUniform(int count, const fvec4* value) { setUniform4f(count, value->ptr()); }
00142
00143 void setUniform(int count, const fmat2* value) { setUniformMatrix2f(count, value->ptr()); }
00144 void setUniform(int count, const fmat3* value) { setUniformMatrix3f(count, value->ptr()); }
00145 void setUniform(int count, const fmat4* value) { setUniformMatrix4f(count, value->ptr()); }
00146
00147 void setUniform(int count, const dvec2* value) { setUniform2d(count, value->ptr()); }
00148 void setUniform(int count, const dvec3* value) { setUniform3d(count, value->ptr()); }
00149 void setUniform(int count, const dvec4* value) { setUniform4d(count, value->ptr()); }
00150
00151 void setUniform(int count, const dmat2* value) { setUniformMatrix2d(count, value->ptr()); }
00152 void setUniform(int count, const dmat3* value) { setUniformMatrix3d(count, value->ptr()); }
00153 void setUniform(int count, const dmat4* value) { setUniformMatrix4d(count, value->ptr()); }
00154
00155
00156
00157 void setUniformI(const int& value) { setUniform1i(1, &value); }
00158 void setUniform(const ivec2& value) { setUniform2i(1, value.ptr()); }
00159 void setUniform(const ivec3& value) { setUniform3i(1, value.ptr()); }
00160 void setUniform(const ivec4& value) { setUniform4i(1, value.ptr()); }
00161
00162 void setUniformU(const unsigned int& value){ setUniform1ui(1, &value); }
00163 void setUniform(const uvec2& value) { setUniform2ui(1, value.ptr()); }
00164 void setUniform(const uvec3& value) { setUniform3ui(1, value.ptr()); }
00165 void setUniform(const uvec4& value) { setUniform4ui(1, value.ptr()); }
00166
00167 void setUniformF(const float& value) { setUniform1f(1, &value); }
00168 void setUniform(const fvec2& value) { setUniform2f(1, value.ptr()); }
00169 void setUniform(const fvec3& value) { setUniform3f(1, value.ptr()); }
00170 void setUniform(const fvec4& value) { setUniform4f(1, value.ptr()); }
00171
00172 void setUniform(const fmat2& value) { setUniformMatrix2f(1, value.ptr()); }
00173 void setUniform(const fmat3& value) { setUniformMatrix3f(1, value.ptr()); }
00174 void setUniform(const fmat4& value) { setUniformMatrix4f(1, value.ptr()); }
00175
00176 void setUniformD(const double& value) { setUniform1d(1, &value); }
00177 void setUniform(const dvec2& value) { setUniform2d(1, value.ptr()); }
00178 void setUniform(const dvec3& value) { setUniform3d(1, value.ptr()); }
00179 void setUniform(const dvec4& value) { setUniform4d(1, value.ptr()); }
00180
00181 void setUniform(const dmat2& value) { setUniformMatrix2d(1, value.ptr()); }
00182 void setUniform(const dmat3& value) { setUniformMatrix3d(1, value.ptr()); }
00183 void setUniform(const dmat4& value) { setUniformMatrix4d(1, value.ptr()); }
00184
00185
00186
00187 void getUniform(double* value) { VL_CHECK(type() != UT_NONE); VL_CHECK(mData.size()); memcpy( value, &mData[0], sizeof(mData[0]) * mData.size()); }
00188 void getUniform(float* value) { VL_CHECK(type() != UT_NONE); VL_CHECK(mData.size()); memcpy( value, &mData[0], sizeof(mData[0]) * mData.size()); }
00189 void getUniform(int* value) { VL_CHECK(type() != UT_NONE); VL_CHECK(mData.size()); memcpy( value, &mData[0], sizeof(mData[0]) * mData.size()); }
00190 void getUniform(unsigned int* value) { VL_CHECK(type() != UT_NONE); VL_CHECK(mData.size()); memcpy( value, &mData[0], sizeof(mData[0]) * mData.size()); }
00191
00192 void getUniform(ivec2* value) { getUniform(value->ptr()); }
00193 void getUniform(ivec3* value) { getUniform(value->ptr()); }
00194 void getUniform(ivec4* value) { getUniform(value->ptr()); }
00195
00196 void getUniform(uvec2* value) { getUniform(value->ptr()); }
00197 void getUniform(uvec3* value) { getUniform(value->ptr()); }
00198 void getUniform(uvec4* value) { getUniform(value->ptr()); }
00199
00200 void getUniform(fvec2* value) { getUniform(value->ptr()); }
00201 void getUniform(fvec3* value) { getUniform(value->ptr()); }
00202 void getUniform(fvec4* value) { getUniform(value->ptr()); }
00203
00204 void getUniform(fmat2* value) { getUniform(value->ptr()); }
00205 void getUniform(fmat3* value) { getUniform(value->ptr()); }
00206 void getUniform(fmat4* value) { getUniform(value->ptr()); }
00207
00208 void getUniform(dvec2* value) { getUniform(value->ptr()); }
00209 void getUniform(dvec3* value) { getUniform(value->ptr()); }
00210 void getUniform(dvec4* value) { getUniform(value->ptr()); }
00211
00212 void getUniform(dmat2* value) { getUniform(value->ptr()); }
00213 void getUniform(dmat3* value) { getUniform(value->ptr()); }
00214 void getUniform(dmat4* value) { getUniform(value->ptr()); }
00215
00216 EUniformType type() const { return mType; }
00217
00218 int count() const
00219 {
00220 switch(mType)
00221 {
00222 case UT_Int: return singleCount();
00223 case UT_Int2: return singleCount() / 2;
00224 case UT_Int3: return singleCount() / 3;
00225 case UT_Int4: return singleCount() / 4;
00226
00227 case UT_UInt: return singleCount();
00228 case UT_UInt2: return singleCount() / 2;
00229 case UT_UInt3: return singleCount() / 3;
00230 case UT_UInt4: return singleCount() / 4;
00231
00232 case UT_Float: return singleCount();
00233 case UT_Float2: return singleCount() / 2;
00234 case UT_Float3: return singleCount() / 3;
00235 case UT_Float4: return singleCount() / 4;
00236
00237 case UT_Mat2F: return singleCount() / (2*2);
00238 case UT_Mat3F: return singleCount() / (3*3);
00239 case UT_Mat4F: return singleCount() / (4*4);
00240
00241 case UT_Mat2x3F: return singleCount() / (2*3);
00242 case UT_Mat3x2F: return singleCount() / (3*2);
00243 case UT_Mat2x4F: return singleCount() / (2*4);
00244 case UT_Mat4x2F: return singleCount() / (4*2);
00245 case UT_Mat3x4F: return singleCount() / (3*4);
00246 case UT_Mat4x3F: return singleCount() / (4*3);
00247
00248 case UT_Double: return doubleCount();
00249 case UT_Double2: return doubleCount() / 2;
00250 case UT_Double3: return doubleCount() / 3;
00251 case UT_Double4: return doubleCount() / 4;
00252
00253 case UT_Mat2D: return doubleCount() / (2*2);
00254 case UT_Mat3D: return doubleCount() / (3*3);
00255 case UT_Mat4D: return doubleCount() / (4*4);
00256
00257 case UT_Mat2x3D: return doubleCount() / (2*3);
00258 case UT_Mat3x2D: return doubleCount() / (3*2);
00259 case UT_Mat2x4D: return doubleCount() / (2*4);
00260 case UT_Mat4x2D: return doubleCount() / (4*2);
00261 case UT_Mat3x4D: return doubleCount() / (3*4);
00262 case UT_Mat4x3D: return doubleCount() / (4*3);
00263
00264 default:
00265 VL_TRAP()
00266 return -1;
00267 }
00268 }
00269
00270 protected:
00271 VL_COMPILE_TIME_CHECK( sizeof(int) == sizeof(float) )
00272 void initData(int count) { mData.resize(count); }
00273 void initDouble(int count) { mData.resize(count*2); }
00274 int singleCount() const { return (int)mData.size(); }
00275 int doubleCount() const { VL_CHECK((mData.size() & 0x1) == 0 ); return (int)(mData.size() >> 1); }
00276 double* doubleData() { VL_CHECK(!mData.empty()); VL_CHECK((mData.size() & 0x1) == 0 ); return (double*)&mData[0]; }
00277 float* floatData() { VL_CHECK(!mData.empty()); return (float*)&mData[0]; }
00278 int* intData() { VL_CHECK(!mData.empty()); return (int*)&mData[0]; }
00279 unsigned int* uintData() { VL_CHECK(!mData.empty()); return (unsigned int*)&mData[0]; }
00280
00281 EUniformType mType;
00282 std::vector<int> mData;
00283 std::string mName;
00284 };
00285 }
00286
00287 #endif