1 module gfm.opengl.uniform; 2 3 import std.conv, 4 std..string, 5 core.stdc..string; 6 7 import derelict.opengl3.gl3; 8 9 import gfm.core.log, 10 gfm.math.vector, 11 gfm.math.matrix, 12 gfm.opengl.opengl; 13 14 15 /// Represents an OpenGL program uniform. Owned by a GLProgram. 16 /// Both uniform locations and values are cached, to minimize OpenGL calls. 17 final class GLUniform 18 { 19 public 20 { 21 /// Creates a GLUniform. 22 /// This is done automatically after linking a GLProgram. 23 /// See_also: GLProgram. 24 /// Throws: $(D OpenGLException) on error. 25 this(OpenGL gl, GLuint program, GLenum type, string name, GLsizei size) 26 { 27 _gl = gl; 28 _type = type; 29 _size = size; 30 _name = name; 31 32 _location = glGetUniformLocation(program, toStringz(name)); 33 if (_location == -1) 34 { 35 // probably rare: the driver said explicitely this variable was active, and there it's not. 36 throw new OpenGLException(format("can't get uniform %s location", name)); 37 } 38 39 size_t cacheSize = sizeOfUniformType(type) * size; 40 if (cacheSize > 0) 41 { 42 _value = new ubyte[cacheSize]; // relying on zero initialization here 43 _valueChanged = false; 44 45 _firstSet = true; 46 _disabled = false; 47 } 48 else 49 { 50 _gl._logger.warningf("uniform %s is unrecognized or has size 0, disabled", _name); 51 _disabled = true; 52 } 53 } 54 55 /// Creates a fake disabled uniform variable, designed to cope with variables 56 /// that have been optimized out by the OpenGL driver, or those which do not exist. 57 this(OpenGL gl, string name) 58 { 59 _gl = gl; 60 _disabled = true; 61 _gl._logger.warningf("creating fake uniform '%s' which either does not exist in the shader program, or was discarded by the driver as unused", name); 62 } 63 64 /// Sets a uniform variable value. 65 /// T should be the exact type needed, checked at runtime. 66 /// Throws: $(D OpenGLException) on error. 67 void set(T)(T newValue) 68 { 69 set!T(&newValue, 1u); 70 } 71 72 /// Sets multiple uniform variables. 73 /// Throws: $(D OpenGLException) on error. 74 void set(T)(T[] newValues) 75 { 76 set!T(newValues.ptr, newValues.length); 77 } 78 79 /// Sets multiple uniform variables. 80 /// Throws: $(D OpenGLException) on error. 81 void set(T)(T* newValues, size_t count) 82 { 83 if (_disabled) 84 return; 85 86 if (!typeIsCompliant!T(_type)) 87 throw new OpenGLException(format("using type %s for setting uniform '%s' which has GLSL type '%s'", 88 T.stringof, _name, GLSLTypeNameArray(_type, _size))); 89 90 if (count != _size) 91 throw new OpenGLException(format("cannot set uniform '%s' of size %s with a value of size %s", 92 _name, _size, count)); 93 94 // if first time or different value incoming 95 if (_firstSet || (0 != memcmp(newValues, _value.ptr, _value.length))) 96 { 97 memcpy(_value.ptr, newValues, _value.length); 98 _valueChanged = true; 99 100 if (_shouldUpdateImmediately) 101 update(); 102 } 103 104 _firstSet = false; 105 } 106 107 /// Updates the uniform value. 108 void use() 109 { 110 _shouldUpdateImmediately = true; 111 update(); 112 } 113 114 /// Unuses this uniform.. 115 void unuse() 116 { 117 _shouldUpdateImmediately = false; 118 } 119 } 120 121 private 122 { 123 OpenGL _gl; 124 GLint _location; 125 GLenum _type; 126 GLsizei _size; 127 ubyte[] _value; 128 bool _valueChanged; 129 bool _firstSet; // force update to ensure we do not relie on the driver initializing uniform to zero 130 bool _disabled; // allow transparent usage while not doing anything 131 bool _shouldUpdateImmediately; 132 string _name; 133 134 void update() 135 { 136 if (_disabled) 137 return; 138 139 // safety check to prevent defaults values in uniforms 140 if (_firstSet) 141 { 142 _gl._logger.warningf("uniform '%s' left to default value, driver will probably zero it", _name); 143 _firstSet = false; 144 } 145 146 // has value changed? 147 // if so, set OpenGL value 148 if (_valueChanged) 149 { 150 setUniform(); 151 _valueChanged = false; 152 } 153 } 154 155 void setUniform() 156 { 157 switch(_type) 158 { 159 case GL_FLOAT: glUniform1fv(_location, _size, cast(GLfloat*)_value); break; 160 case GL_FLOAT_VEC2: glUniform2fv(_location, _size, cast(GLfloat*)_value); break; 161 case GL_FLOAT_VEC3: glUniform3fv(_location, _size, cast(GLfloat*)_value); break; 162 case GL_FLOAT_VEC4: glUniform4fv(_location, _size, cast(GLfloat*)_value); break; 163 case GL_DOUBLE: glUniform1dv(_location, _size, cast(GLdouble*)_value); break; 164 case GL_DOUBLE_VEC2: glUniform2dv(_location, _size, cast(GLdouble*)_value); break; 165 case GL_DOUBLE_VEC3: glUniform3dv(_location, _size, cast(GLdouble*)_value); break; 166 case GL_DOUBLE_VEC4: glUniform4dv(_location, _size, cast(GLdouble*)_value); break; 167 case GL_INT: glUniform1iv(_location, _size, cast(GLint*)_value); break; 168 case GL_INT_VEC2: glUniform2iv(_location, _size, cast(GLint*)_value); break; 169 case GL_INT_VEC3: glUniform3iv(_location, _size, cast(GLint*)_value); break; 170 case GL_INT_VEC4: glUniform4iv(_location, _size, cast(GLint*)_value); break; 171 case GL_UNSIGNED_INT: glUniform1uiv(_location, _size, cast(GLuint*)_value); break; 172 case GL_UNSIGNED_INT_VEC2: glUniform2uiv(_location, _size, cast(GLuint*)_value); break; 173 case GL_UNSIGNED_INT_VEC3: glUniform3uiv(_location, _size, cast(GLuint*)_value); break; 174 case GL_UNSIGNED_INT_VEC4: glUniform4uiv(_location, _size, cast(GLuint*)_value); break; 175 case GL_BOOL: glUniform1iv(_location, _size, cast(GLint*)_value); break; 176 case GL_BOOL_VEC2: glUniform2iv(_location, _size, cast(GLint*)_value); break; 177 case GL_BOOL_VEC3: glUniform3iv(_location, _size, cast(GLint*)_value); break; 178 case GL_BOOL_VEC4: glUniform4iv(_location, _size, cast(GLint*)_value); break; 179 case GL_FLOAT_MAT2: glUniformMatrix2fv(_location, _size, GL_TRUE, cast(GLfloat*)_value); break; 180 case GL_FLOAT_MAT3: glUniformMatrix3fv(_location, _size, GL_TRUE, cast(GLfloat*)_value); break; 181 case GL_FLOAT_MAT4: glUniformMatrix4fv(_location, _size, GL_TRUE, cast(GLfloat*)_value); break; 182 case GL_FLOAT_MAT2x3: glUniformMatrix2x3fv(_location, _size, GL_TRUE, cast(GLfloat*)_value); break; 183 case GL_FLOAT_MAT2x4: glUniformMatrix3x2fv(_location, _size, GL_TRUE, cast(GLfloat*)_value); break; 184 case GL_FLOAT_MAT3x2: glUniformMatrix2x4fv(_location, _size, GL_TRUE, cast(GLfloat*)_value); break; 185 case GL_FLOAT_MAT3x4: glUniformMatrix4x2fv(_location, _size, GL_TRUE, cast(GLfloat*)_value); break; 186 case GL_FLOAT_MAT4x2: glUniformMatrix3x4fv(_location, _size, GL_TRUE, cast(GLfloat*)_value); break; 187 case GL_FLOAT_MAT4x3: glUniformMatrix4x3fv(_location, _size, GL_TRUE, cast(GLfloat*)_value); break; 188 case GL_DOUBLE_MAT2: glUniformMatrix2dv(_location, _size, GL_TRUE, cast(GLdouble*)_value); break; 189 case GL_DOUBLE_MAT3: glUniformMatrix3dv(_location, _size, GL_TRUE, cast(GLdouble*)_value); break; 190 case GL_DOUBLE_MAT4: glUniformMatrix4dv(_location, _size, GL_TRUE, cast(GLdouble*)_value); break; 191 case GL_DOUBLE_MAT2x3: glUniformMatrix2x3dv(_location, _size, GL_TRUE, cast(GLdouble*)_value); break; 192 case GL_DOUBLE_MAT2x4: glUniformMatrix3x2dv(_location, _size, GL_TRUE, cast(GLdouble*)_value); break; 193 case GL_DOUBLE_MAT3x2: glUniformMatrix2x4dv(_location, _size, GL_TRUE, cast(GLdouble*)_value); break; 194 case GL_DOUBLE_MAT3x4: glUniformMatrix4x2dv(_location, _size, GL_TRUE, cast(GLdouble*)_value); break; 195 case GL_DOUBLE_MAT4x2: glUniformMatrix3x4dv(_location, _size, GL_TRUE, cast(GLdouble*)_value); break; 196 case GL_DOUBLE_MAT4x3: glUniformMatrix4x3dv(_location, _size, GL_TRUE, cast(GLdouble*)_value); break; 197 198 // image samplers 199 case GL_IMAGE_1D: .. case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY: 200 glUniform1iv(_location, _size, cast(GLint*)_value); 201 break; 202 203 case GL_UNSIGNED_INT_ATOMIC_COUNTER: 204 glUniform1uiv(_location, _size, cast(GLuint*)_value); 205 break; 206 207 case GL_SAMPLER_1D: 208 case GL_SAMPLER_2D: 209 case GL_SAMPLER_3D: 210 case GL_SAMPLER_CUBE: 211 case GL_SAMPLER_1D_SHADOW: 212 case GL_SAMPLER_2D_SHADOW: 213 case GL_SAMPLER_1D_ARRAY: 214 case GL_SAMPLER_2D_ARRAY: 215 case GL_SAMPLER_1D_ARRAY_SHADOW: 216 case GL_SAMPLER_2D_ARRAY_SHADOW: 217 case GL_SAMPLER_2D_MULTISAMPLE: 218 case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: 219 case GL_SAMPLER_CUBE_SHADOW: 220 case GL_SAMPLER_BUFFER: 221 case GL_SAMPLER_2D_RECT: 222 case GL_SAMPLER_2D_RECT_SHADOW: 223 case GL_INT_SAMPLER_1D: 224 case GL_INT_SAMPLER_2D: 225 case GL_INT_SAMPLER_3D: 226 case GL_INT_SAMPLER_CUBE: 227 case GL_INT_SAMPLER_1D_ARRAY: 228 case GL_INT_SAMPLER_2D_ARRAY: 229 case GL_INT_SAMPLER_2D_MULTISAMPLE: 230 case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: 231 case GL_INT_SAMPLER_BUFFER: 232 case GL_INT_SAMPLER_2D_RECT: 233 case GL_UNSIGNED_INT_SAMPLER_1D: 234 case GL_UNSIGNED_INT_SAMPLER_2D: 235 case GL_UNSIGNED_INT_SAMPLER_3D: 236 case GL_UNSIGNED_INT_SAMPLER_CUBE: 237 case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: 238 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: 239 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: 240 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: 241 case GL_UNSIGNED_INT_SAMPLER_BUFFER: 242 case GL_UNSIGNED_INT_SAMPLER_2D_RECT: 243 glUniform1iv(_location, _size, cast(GLint*)_value); 244 break; 245 246 default: 247 break; 248 } 249 _gl.runtimeCheck(); 250 } 251 252 public static bool typeIsCompliant(T)(GLenum type) 253 { 254 switch (type) 255 { 256 case GL_FLOAT: return is(T == float); 257 case GL_FLOAT_VEC2: return is(T == vec2f); 258 case GL_FLOAT_VEC3: return is(T == vec3f); 259 case GL_FLOAT_VEC4: return is(T == vec4f); 260 case GL_DOUBLE: return is(T == double); 261 case GL_DOUBLE_VEC2: return is(T == vec2d); 262 case GL_DOUBLE_VEC3: return is(T == vec3d); 263 case GL_DOUBLE_VEC4: return is(T == vec4d); 264 case GL_INT: return is(T == int); 265 case GL_INT_VEC2: return is(T == vec2i); 266 case GL_INT_VEC3: return is(T == vec3i); 267 case GL_INT_VEC4: return is(T == vec4i); 268 case GL_UNSIGNED_INT: return is(T == uint); 269 case GL_UNSIGNED_INT_VEC2: return is(T == vec2ui); 270 case GL_UNSIGNED_INT_VEC3: return is(T == vec3ui); 271 case GL_UNSIGNED_INT_VEC4: return is(T == vec4ui); 272 case GL_BOOL: return is(T == int); // int because bool type is 1 byte 273 case GL_BOOL_VEC2: return is(T == vec2i); 274 case GL_BOOL_VEC3: return is(T == vec3i); 275 case GL_BOOL_VEC4: return is(T == vec4i); 276 case GL_FLOAT_MAT2: return is(T == mat2f); 277 case GL_FLOAT_MAT3: return is(T == mat3f); 278 case GL_FLOAT_MAT4: return is(T == mat4f); 279 case GL_FLOAT_MAT2x3: return is(T == mat3x2f); 280 case GL_FLOAT_MAT2x4: return is(T == mat4x2f); 281 case GL_FLOAT_MAT3x2: return is(T == mat2x3f); 282 case GL_FLOAT_MAT3x4: return is(T == mat4x3f); 283 case GL_FLOAT_MAT4x2: return is(T == mat2x4f); 284 case GL_FLOAT_MAT4x3: return is(T == mat3x4f); 285 case GL_DOUBLE_MAT2: return is(T == mat2d); 286 case GL_DOUBLE_MAT3: return is(T == mat3d); 287 case GL_DOUBLE_MAT4: return is(T == mat4d); 288 case GL_DOUBLE_MAT2x3: return is(T == mat3x2d); 289 case GL_DOUBLE_MAT2x4: return is(T == mat4x2d); 290 case GL_DOUBLE_MAT3x2: return is(T == mat2x3d); 291 case GL_DOUBLE_MAT3x4: return is(T == mat4x3d); 292 case GL_DOUBLE_MAT4x2: return is(T == mat2x4d); 293 case GL_DOUBLE_MAT4x3: return is(T == mat3x4d); 294 295 // image samplers 296 case GL_IMAGE_1D: .. case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY: 297 return is(T == int); 298 299 case GL_UNSIGNED_INT_ATOMIC_COUNTER: 300 return is(T == uint); 301 302 case GL_SAMPLER_1D: 303 case GL_SAMPLER_2D: 304 case GL_SAMPLER_3D: 305 case GL_SAMPLER_CUBE: 306 case GL_SAMPLER_1D_SHADOW: 307 case GL_SAMPLER_2D_SHADOW: 308 case GL_SAMPLER_1D_ARRAY: 309 case GL_SAMPLER_2D_ARRAY: 310 case GL_SAMPLER_1D_ARRAY_SHADOW: 311 case GL_SAMPLER_2D_ARRAY_SHADOW: 312 case GL_SAMPLER_2D_MULTISAMPLE: 313 case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: 314 case GL_SAMPLER_CUBE_SHADOW: 315 case GL_SAMPLER_BUFFER: 316 case GL_SAMPLER_2D_RECT: 317 case GL_SAMPLER_2D_RECT_SHADOW: 318 case GL_INT_SAMPLER_1D: 319 case GL_INT_SAMPLER_2D: 320 case GL_INT_SAMPLER_3D: 321 case GL_INT_SAMPLER_CUBE: 322 case GL_INT_SAMPLER_1D_ARRAY: 323 case GL_INT_SAMPLER_2D_ARRAY: 324 case GL_INT_SAMPLER_2D_MULTISAMPLE: 325 case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: 326 case GL_INT_SAMPLER_BUFFER: 327 case GL_INT_SAMPLER_2D_RECT: 328 case GL_UNSIGNED_INT_SAMPLER_1D: 329 case GL_UNSIGNED_INT_SAMPLER_2D: 330 case GL_UNSIGNED_INT_SAMPLER_3D: 331 case GL_UNSIGNED_INT_SAMPLER_CUBE: 332 case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: 333 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: 334 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: 335 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: 336 case GL_UNSIGNED_INT_SAMPLER_BUFFER: 337 case GL_UNSIGNED_INT_SAMPLER_2D_RECT: 338 return is(T == int); 339 340 default: 341 // unrecognized type, in release mode return true 342 debug 343 { 344 assert(false); 345 } 346 else 347 { 348 return true; 349 } 350 } 351 } 352 353 public static size_t sizeOfUniformType(GLenum type) 354 { 355 switch (type) 356 { 357 case GL_FLOAT: return float.sizeof; 358 case GL_FLOAT_VEC2: return vec2f.sizeof; 359 case GL_FLOAT_VEC3: return vec3f.sizeof; 360 case GL_FLOAT_VEC4: return vec4f.sizeof; 361 case GL_DOUBLE: return double.sizeof; 362 case GL_DOUBLE_VEC2: return vec2d.sizeof; 363 case GL_DOUBLE_VEC3: return vec3d.sizeof; 364 case GL_DOUBLE_VEC4: return vec4d.sizeof; 365 case GL_INT: return int.sizeof; 366 case GL_INT_VEC2: return vec2i.sizeof; 367 case GL_INT_VEC3: return vec3i.sizeof; 368 case GL_INT_VEC4: return vec4i.sizeof; 369 case GL_UNSIGNED_INT: return uint.sizeof; 370 case GL_UNSIGNED_INT_VEC2: return vec2ui.sizeof; 371 case GL_UNSIGNED_INT_VEC3: return vec3ui.sizeof; 372 case GL_UNSIGNED_INT_VEC4: return vec4ui.sizeof; 373 case GL_BOOL: return int.sizeof; // int because D bool type is 1 byte 374 case GL_BOOL_VEC2: return vec2i.sizeof; 375 case GL_BOOL_VEC3: return vec3i.sizeof; 376 case GL_BOOL_VEC4: return vec4i.sizeof; 377 case GL_FLOAT_MAT2: return mat2f.sizeof; 378 case GL_FLOAT_MAT3: return mat3f.sizeof; 379 case GL_FLOAT_MAT4: return mat4f.sizeof; 380 case GL_FLOAT_MAT2x3: return mat3x2f.sizeof; 381 case GL_FLOAT_MAT2x4: return mat4x2f.sizeof; 382 case GL_FLOAT_MAT3x2: return mat2x3f.sizeof; 383 case GL_FLOAT_MAT3x4: return mat4x3f.sizeof; 384 case GL_FLOAT_MAT4x2: return mat2x4f.sizeof; 385 case GL_FLOAT_MAT4x3: return mat3x4f.sizeof; 386 case GL_DOUBLE_MAT2: return mat2d.sizeof; 387 case GL_DOUBLE_MAT3: return mat3d.sizeof; 388 case GL_DOUBLE_MAT4: return mat4d.sizeof; 389 case GL_DOUBLE_MAT2x3: return mat3x2d.sizeof; 390 case GL_DOUBLE_MAT2x4: return mat4x2d.sizeof; 391 case GL_DOUBLE_MAT3x2: return mat2x3d.sizeof; 392 case GL_DOUBLE_MAT3x4: return mat4x3d.sizeof; 393 case GL_DOUBLE_MAT4x2: return mat2x4d.sizeof; 394 case GL_DOUBLE_MAT4x3: return mat3x4d.sizeof; 395 396 // image samplers 397 case GL_IMAGE_1D: .. case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY: 398 return int.sizeof; 399 400 case GL_UNSIGNED_INT_ATOMIC_COUNTER: 401 return uint.sizeof; 402 403 case GL_SAMPLER_1D: 404 case GL_SAMPLER_2D: 405 case GL_SAMPLER_3D: 406 case GL_SAMPLER_CUBE: 407 case GL_SAMPLER_1D_SHADOW: 408 case GL_SAMPLER_2D_SHADOW: 409 case GL_SAMPLER_1D_ARRAY: 410 case GL_SAMPLER_2D_ARRAY: 411 case GL_SAMPLER_1D_ARRAY_SHADOW: 412 case GL_SAMPLER_2D_ARRAY_SHADOW: 413 case GL_SAMPLER_2D_MULTISAMPLE: 414 case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: 415 case GL_SAMPLER_CUBE_SHADOW: 416 case GL_SAMPLER_BUFFER: 417 case GL_SAMPLER_2D_RECT: 418 case GL_SAMPLER_2D_RECT_SHADOW: 419 case GL_INT_SAMPLER_1D: 420 case GL_INT_SAMPLER_2D: 421 case GL_INT_SAMPLER_3D: 422 case GL_INT_SAMPLER_CUBE: 423 case GL_INT_SAMPLER_1D_ARRAY: 424 case GL_INT_SAMPLER_2D_ARRAY: 425 case GL_INT_SAMPLER_2D_MULTISAMPLE: 426 case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: 427 case GL_INT_SAMPLER_BUFFER: 428 case GL_INT_SAMPLER_2D_RECT: 429 case GL_UNSIGNED_INT_SAMPLER_1D: 430 case GL_UNSIGNED_INT_SAMPLER_2D: 431 case GL_UNSIGNED_INT_SAMPLER_3D: 432 case GL_UNSIGNED_INT_SAMPLER_CUBE: 433 case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: 434 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: 435 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: 436 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: 437 case GL_UNSIGNED_INT_SAMPLER_BUFFER: 438 case GL_UNSIGNED_INT_SAMPLER_2D_RECT: 439 return int.sizeof; 440 441 default: 442 // unrecognized type 443 // in debug mode assert, in release mode return 0 to disable this uniform 444 debug 445 { 446 assert(false); 447 } 448 else 449 { 450 return 0; 451 } 452 } 453 } 454 455 static string GLSLTypeName(GLenum type) 456 { 457 switch (type) 458 { 459 case GL_FLOAT: return "float"; 460 case GL_FLOAT_VEC2: return "vec2"; 461 case GL_FLOAT_VEC3: return "vec3"; 462 case GL_FLOAT_VEC4: return "vec4"; 463 case GL_DOUBLE: return "double"; 464 case GL_DOUBLE_VEC2: return "dvec2"; 465 case GL_DOUBLE_VEC3: return "dvec3"; 466 case GL_DOUBLE_VEC4: return "dvec4"; 467 case GL_INT: return "int"; 468 case GL_INT_VEC2: return "ivec2"; 469 case GL_INT_VEC3: return "ivec3"; 470 case GL_INT_VEC4: return "ivec4"; 471 case GL_UNSIGNED_INT: return "uint"; 472 case GL_UNSIGNED_INT_VEC2: return "uvec2"; 473 case GL_UNSIGNED_INT_VEC3: return "uvec3"; 474 case GL_UNSIGNED_INT_VEC4: return "uvec4"; 475 case GL_BOOL: return "bool"; 476 case GL_BOOL_VEC2: return "bvec2"; 477 case GL_BOOL_VEC3: return "bvec3"; 478 case GL_BOOL_VEC4: return "bvec4"; 479 case GL_FLOAT_MAT2: return "mat2"; 480 case GL_FLOAT_MAT3: return "mat3"; 481 case GL_FLOAT_MAT4: return "mat4"; 482 case GL_FLOAT_MAT2x3: return "mat2x3"; 483 case GL_FLOAT_MAT2x4: return "mat2x4"; 484 case GL_FLOAT_MAT3x2: return "mat3x2"; 485 case GL_FLOAT_MAT3x4: return "mat3x4"; 486 case GL_FLOAT_MAT4x2: return "mat4x2"; 487 case GL_FLOAT_MAT4x3: return "mat4x3"; 488 case GL_DOUBLE_MAT2: return "dmat2"; 489 case GL_DOUBLE_MAT3: return "dmat3"; 490 case GL_DOUBLE_MAT4: return "dmat4"; 491 case GL_DOUBLE_MAT2x3: return "dmat2x3"; 492 case GL_DOUBLE_MAT2x4: return "dmat2x4"; 493 case GL_DOUBLE_MAT3x2: return "dmat3x2"; 494 case GL_DOUBLE_MAT3x4: return "dmat3x4"; 495 case GL_DOUBLE_MAT4x2: return "dmat4x2"; 496 case GL_DOUBLE_MAT4x3: return "dmat4x3"; 497 case GL_SAMPLER_1D: return "sampler1D"; 498 case GL_SAMPLER_2D: return "sampler2D"; 499 case GL_SAMPLER_3D: return "sampler3D"; 500 case GL_SAMPLER_CUBE: return "samplerCube"; 501 case GL_SAMPLER_1D_SHADOW: return "sampler1DShadow"; 502 case GL_SAMPLER_2D_SHADOW: return "sampler2DShadow"; 503 case GL_SAMPLER_1D_ARRAY: return "sampler1DArray"; 504 case GL_SAMPLER_2D_ARRAY: return "sampler2DArray"; 505 case GL_SAMPLER_1D_ARRAY_SHADOW: return "sampler1DArrayShadow"; 506 case GL_SAMPLER_2D_ARRAY_SHADOW: return "sampler2DArrayShadow"; 507 case GL_SAMPLER_2D_MULTISAMPLE: return "sampler2DMS"; 508 case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: return "sampler2DMSArray"; 509 case GL_SAMPLER_CUBE_SHADOW: return "samplerCubeShadow"; 510 case GL_SAMPLER_BUFFER: return "samplerBuffer"; 511 case GL_SAMPLER_2D_RECT: return "sampler2DRect"; 512 case GL_SAMPLER_2D_RECT_SHADOW: return "sampler2DRectShadow"; 513 case GL_INT_SAMPLER_1D: return "isampler1D"; 514 case GL_INT_SAMPLER_2D: return "isampler2D"; 515 case GL_INT_SAMPLER_3D: return "isampler3D"; 516 case GL_INT_SAMPLER_CUBE: return "isamplerCube"; 517 case GL_INT_SAMPLER_1D_ARRAY: return "isampler1DArray"; 518 case GL_INT_SAMPLER_2D_ARRAY: return "isampler2DArray"; 519 case GL_INT_SAMPLER_2D_MULTISAMPLE: return "isampler2DMS"; 520 case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: return "isampler2DMSArray"; 521 case GL_INT_SAMPLER_BUFFER: return "isamplerBuffer"; 522 case GL_INT_SAMPLER_2D_RECT: return "isampler2DRect"; 523 case GL_UNSIGNED_INT_SAMPLER_1D: return "usampler1D"; 524 case GL_UNSIGNED_INT_SAMPLER_2D: return "usampler2D"; 525 case GL_UNSIGNED_INT_SAMPLER_3D: return "usampler3D"; 526 case GL_UNSIGNED_INT_SAMPLER_CUBE: return "usamplerCube"; 527 case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: return "usampler2DArray"; 528 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: return "usampler2DArray"; 529 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: return "usampler2DMS"; 530 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: return "usampler2DMSArray"; 531 case GL_UNSIGNED_INT_SAMPLER_BUFFER: return "usamplerBuffer"; 532 case GL_UNSIGNED_INT_SAMPLER_2D_RECT: return "usampler2DRect"; 533 case GL_IMAGE_1D: return "image1D"; 534 case GL_IMAGE_2D: return "image2D"; 535 case GL_IMAGE_3D: return "image3D"; 536 case GL_IMAGE_2D_RECT: return "image2DRect"; 537 case GL_IMAGE_CUBE: return "imageCube"; 538 case GL_IMAGE_BUFFER: return "imageBuffer"; 539 case GL_IMAGE_1D_ARRAY: return "image1DArray"; 540 case GL_IMAGE_2D_ARRAY: return "image2DArray"; 541 case GL_IMAGE_2D_MULTISAMPLE: return "image2DMS"; 542 case GL_IMAGE_2D_MULTISAMPLE_ARRAY: return "image2DMSArray"; 543 case GL_INT_IMAGE_1D: return "iimage1D"; 544 case GL_INT_IMAGE_2D: return "iimage2D"; 545 case GL_INT_IMAGE_3D: return "iimage3D"; 546 case GL_INT_IMAGE_2D_RECT: return "iimage2DRect"; 547 case GL_INT_IMAGE_CUBE: return "iimageCube"; 548 case GL_INT_IMAGE_BUFFER: return "iimageBuffer"; 549 case GL_INT_IMAGE_1D_ARRAY: return "iimage1DArray"; 550 case GL_INT_IMAGE_2D_ARRAY: return "iimage2DArray"; 551 case GL_INT_IMAGE_2D_MULTISAMPLE: return "iimage2DMS"; 552 case GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY: return "iimage2DMSArray"; 553 case GL_UNSIGNED_INT_IMAGE_1D: return "uimage1D"; 554 case GL_UNSIGNED_INT_IMAGE_2D: return "uimage2D"; 555 case GL_UNSIGNED_INT_IMAGE_3D: return "uimage3D"; 556 case GL_UNSIGNED_INT_IMAGE_2D_RECT: return "uimage2DRect"; 557 case GL_UNSIGNED_INT_IMAGE_CUBE: return "uimageCube"; 558 case GL_UNSIGNED_INT_IMAGE_BUFFER: return "uimageBuffer"; 559 case GL_UNSIGNED_INT_IMAGE_1D_ARRAY: return "uimage1DArray"; 560 case GL_UNSIGNED_INT_IMAGE_2D_ARRAY: return "uimage2DArray"; 561 case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE: return "uimage2DMS"; 562 case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY: return "uimage2DMSArray"; 563 case GL_UNSIGNED_INT_ATOMIC_COUNTER: return "atomic_uint"; 564 default: 565 return "unknown"; 566 } 567 } 568 569 static string GLSLTypeNameArray(GLenum type, size_t multiplicity) 570 { 571 assert(multiplicity > 0); 572 if (multiplicity == 1) 573 return GLSLTypeName(type); 574 else 575 return format("%s[%s]", GLSLTypeName(type), multiplicity); 576 } 577 } 578 } 579 580 static assert(is(GLint == int)); 581 static assert(is(GLuint == uint)); 582 static assert(is(GLfloat == float)); 583 static assert(is(GLdouble == double));