Visualization Library v1.0.3A lightweight C++ OpenGL middleware for 2D/3D graphics |
[Download] [Tutorials] [All Classes] [Grouped Classes] |
00001 /**************************************************************************************/ 00002 /* */ 00003 /* Visualization Library */ 00004 /* http://visualizationlibrary.org */ 00005 /* */ 00006 /* Copyright (c) 2005-2010, Michele Bosi */ 00007 /* All rights reserved. */ 00008 /* */ 00009 /* Redistribution and use in source and binary forms, with or without modification, */ 00010 /* are permitted provided that the following conditions are met: */ 00011 /* */ 00012 /* - Redistributions of source code must retain the above copyright notice, this */ 00013 /* list of conditions and the following disclaimer. */ 00014 /* */ 00015 /* - Redistributions in binary form must reproduce the above copyright notice, this */ 00016 /* list of conditions and the following disclaimer in the documentation and/or */ 00017 /* other materials provided with the distribution. */ 00018 /* */ 00019 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */ 00020 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */ 00021 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ 00022 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */ 00023 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */ 00024 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ 00025 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */ 00026 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 00027 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ 00028 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 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 // Uniform 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 // generic array setters 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 // generic matrix array setters 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 // vector/matrix array setters 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 // single value setters 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 // getters 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