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