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