1 /* 2 * DSFML - The Simple and Fast Multimedia Library for D 3 * 4 * Copyright (c) 2013 - 2018 Jeremy DeHaan (dehaan.jeremiah@gmail.com) 5 * 6 * This software is provided 'as-is', without any express or implied warranty. 7 * In no event will the authors be held liable for any damages arising from the 8 * use of this software. 9 * 10 * Permission is granted to anyone to use this software for any purpose, 11 * including commercial applications, and to alter it and redistribute it 12 * freely, subject to the following restrictions: 13 * 14 * 1. The origin of this software must not be misrepresented; you must not claim 15 * that you wrote the original software. If you use this software in a product, 16 * an acknowledgment in the product documentation would be appreciated but is 17 * not required. 18 * 19 * 2. Altered source versions must be plainly marked as such, and must not be 20 * misrepresented as being the original software. 21 * 22 * 3. This notice may not be removed or altered from any source distribution 23 * 24 * 25 * DSFML is based on SFML (Copyright Laurent Gomila) 26 */ 27 28 /** 29 * Shaders are programs written using a specific language, executed directly by 30 * the graphics card and allowing one to apply real-time operations to the 31 * rendered entities. 32 * 33 * There are three kinds of shaders: 34 * $(UL 35 * $(LI Vertex shaders, that process vertices) 36 * $(LI Geometry shaders, that process primitives) 37 * $(LI Fragment (pixel) shaders, that process pixels)) 38 * 39 * $(PARA 40 * A $(U Shader) can be composed of either a vertex shader alone, a geometry 41 * shader alone, a fragment shader alone, or any combination of them. (see the 42 * variants of the load functions). 43 * 44 * Shaders are written in GLSL, which is a C-like language dedicated to OpenGL 45 * shaders. You'll probably need to learn its basics before writing your own 46 * shaders for DSFML. 47 * 48 * Like any D/C/C++ program, a GLSL shader has its own variables called uniforms 49 * that you can set from your D application. $(U Shader) handles different types 50 * of uniforms:) 51 * $(UL 52 * $(LI scalars: float, int, bool) 53 * $(LI vectors (2, 3 or 4 components)) 54 * $(LI matrices (3x3 or 4x4)) 55 * $(LI samplers (textures))) 56 * 57 * $(PARA Some DSFML-specific types can be converted:) 58 * $(UL 59 * $(LI $(COLOR_LINK) as a 4D vector (`vec4`)) 60 * $(LI $(TRANSFORM_LINK) as matrices (`mat3` or `mat4`))) 61 * 62 * $(PARA Every uniform variable in a shader can be set through one of the 63 * `setUniform()` or `setUniformArray()` overloads. For example, if you have a 64 * shader with the following uniforms:) 65 * --- 66 * uniform float offset; 67 * uniform vec3 point; 68 * uniform vec4 color; 69 * uniform mat4 matrix; 70 * uniform sampler2D overlay; 71 * uniform sampler2D current; 72 * --- 73 * 74 * $(PARA You can set their values from D code as follows, using the types 75 * defined in the `dsfml.graphics.glsl` module:) 76 * --- 77 * shader.setUniform("offset", 2.f); 78 * shader.setUniform("point", Vector3f(0.5f, 0.8f, 0.3f)); 79 * shader.setUniform("color", Vec4(color)); 80 * shader.setUniform("matrix", Mat4(transform)); 81 * shader.setUniform("overlay", texture); 82 * shader.setUniform("current", Shader.CurrentTexture); 83 * --- 84 * 85 * $(PARA The old `setParameter()` overloads are deprecated and will be removed 86 * in a future version. You should use their `setUniform()` equivalents instead. 87 * 88 * It is also worth noting that DSFML supports index overloads for 89 * setting uniforms:) 90 * --- 91 * shader["offset"] = 2.f; 92 * shader["point"] = Vector3f(0.5f, 0.8f, 0.3f); 93 * shader["color"] = Vec4(color); 94 * shader["matrix"] = Mat4(transform); 95 * shader["overlay"] = texture; 96 * shader["current"] = Shader.CurrentTexture; 97 * --- 98 * 99 * $(PARA The special `Shader.CurrentTexture` argument maps the given 100 * `sampler2D` uniform to the current texture of the object being drawn (which 101 * cannot be known in advance). 102 * 103 * To apply a shader to a drawable, you must pass it as part of an additional 104 * parameter to the `Window.draw()` function:) 105 * --- 106 * RenderStates states; 107 * states.shader = shader; 108 * window.draw(sprite, states); 109 * --- 110 * 111 * $(PARA In the code above we pass a reference to the shader, because it may be 112 * null (which means "no shader"). 113 * 114 * Shaders can be used on any drawable, but some combinations are not 115 * interesting. For example, using a vertex shader on a $(SPRITE_LINK) is 116 * limited because there are only 4 vertices, the sprite would have to be 117 * subdivided in order to apply wave effects. 118 * Another bad example is a fragment shader with $(TEXT_LINK): the texture of 119 * the text is not the actual text that you see on screen, it is a big texture 120 * containing all the characters of the font in an arbitrary order; thus, 121 * texture lookups on pixels other than the current one may not give you the 122 * expected result. 123 * 124 * Shaders can also be used to apply global post-effects to the current contents 125 * of the target. This can be done in two different ways:) 126 * $(UL 127 * $(LI draw everything to a $(RENDERTEXTURE_LINK), then draw it to the main 128 * target using the shader) 129 * $(LI draw everything directly to the main target, then use `Texture.update` 130 * to copy its contents to a texture and draw it to the main target using 131 * the shader)) 132 * 133 * $(PARA The first technique is more optimized because it doesn't involve 134 * retrieving the target's pixels to system memory, but the second one doesn't 135 * impact the rendering process and can be easily inserted anywhere without 136 * impacting all the code. 137 * 138 * Like $(TEXTURE_LINK) that can be used as a raw OpenGL texture, $(U Shader) 139 * can also be used directly as a raw shader for custom OpenGL geometry.) 140 * --- 141 * Shader.bind(shader); 142 * ... render OpenGL geometry ... 143 * Shader.bind(null); 144 * --- 145 * 146 * See_Also: 147 * $(GLSL_LINK) 148 */ 149 module dsfml.graphics.shader; 150 151 import dsfml.graphics.texture; 152 import dsfml.graphics.transform; 153 import dsfml.graphics.color; 154 import dsfml.graphics.glsl; 155 156 import dsfml.system.inputstream; 157 import dsfml.system.vector2; 158 import dsfml.system.vector3; 159 import dsfml.system.err; 160 161 162 /** 163 * Shader class (vertex and fragment). 164 */ 165 class Shader 166 { 167 /// Types of shaders. 168 enum Type 169 { 170 Vertex, /// Vertex shader 171 Geometry,/// Geometry shader 172 Fragment /// Fragment (pixel) shader. 173 } 174 175 package sfShader* sfPtr; 176 177 /** 178 * Special type/value that can be passed to `setParameter`, and that 179 * represents the texture of the object being drawn. 180 */ 181 struct CurrentTextureType {} 182 /// ditto 183 static CurrentTextureType CurrentTexture; 184 185 /// Default constructor. 186 this() 187 { 188 //creates an empty shader 189 sfPtr=sfShader_construct(); 190 } 191 192 package this(sfShader* shader) 193 { 194 sfPtr = shader; 195 } 196 197 /// Destructor. 198 ~this() 199 { 200 import dsfml.system.config; 201 mixin(destructorOutput); 202 sfShader_destroy(sfPtr); 203 } 204 205 /** 206 * Load the vertex, geometry, or fragment shader from a file. 207 * 208 * This function loads a single shader, vertex, geometry, or fragment, 209 * identified by the second argument. The source must be a text file 210 * containing a valid shader in GLSL language. GLSL is a C-like language 211 * dedicated to OpenGL shaders; you'll probably need to read a good 212 * documentation for it before writing your own shaders. 213 * 214 * Params: 215 * filename = Path of the vertex, geometry, or fragment shader file to load 216 * type = Type of shader (vertex geometry, or fragment) 217 * 218 * Returns: true if loading succeeded, false if it failed. 219 */ 220 bool loadFromFile(const(char)[] filename, Type type) 221 { 222 return sfShader_loadTypeFromFile(sfPtr, filename.ptr, filename.length, type); 223 } 224 225 /** 226 * Load both the vertex and fragment shaders from files. 227 * 228 * This function loads both the vertex and the fragment shaders. If one of 229 * them fails to load, the shader is left empty (the valid shader is 230 * unloaded). The sources must be text files containing valid shaders in 231 * GLSL language. GLSL is a C-like language dedicated to OpenGL shaders; 232 * you'll probably need to read a good documentation for it before writing 233 * your own shaders. 234 * 235 * Params: 236 * vertexShaderFilename = Path of the vertex shader file to load 237 * fragmentShaderFilename = Path of the fragment shader file to load 238 * 239 * Returns: true if loading succeeded, false if it failed. 240 */ 241 bool loadFromFile(const(char)[] vertexShaderFilename, const(char)[] fragmentShaderFilename) 242 { 243 return sfShader_loadVertexAndFragmentFromFile(sfPtr, vertexShaderFilename.ptr, vertexShaderFilename.length, 244 fragmentShaderFilename.ptr, fragmentShaderFilename.length); 245 } 246 247 /** 248 * Load the vertex, geometry, and fragment shaders from files. 249 * 250 * This function loads the vertex, geometry and the fragment shaders. If one 251 * of them fails to load, the shader is left empty (the valid shader is 252 * unloaded). The sources must be text files containing valid shaders in 253 * GLSL language. GLSL is a C-like language dedicated to OpenGL shaders; 254 * you'll probably need to read a good documentation for it before writing 255 * your own shaders. 256 * 257 * Params: 258 * vertexShaderFilename = Path of the vertex shader file to load 259 * geometryShaderFilename = Path of the geometry shader file to load 260 * fragmentShaderFilename = Path of the fragment shader file to load 261 * 262 * Returns: true if loading succeeded, false if it failed. 263 */ 264 bool loadFromFile(const(char)[] vertexShaderFilename, const(char)[] geometryShaderFilename, const(char)[] fragmentShaderFilename) 265 { 266 return sfShader_loadAllFromFile(sfPtr, vertexShaderFilename.ptr, vertexShaderFilename.length, 267 geometryShaderFilename.ptr, geometryShaderFilename.length, 268 fragmentShaderFilename.ptr, fragmentShaderFilename.length); 269 } 270 271 /** 272 * Load the vertex, geometry, or fragment shader from a source code in memory. 273 * 274 * This function loads a single shader, vertex, geometry, or fragment, 275 * identified by the second argument. The source code must be a valid shader 276 * in GLSL language. GLSL is a C-like language dedicated to OpenGL shaders; 277 * you'll probably need to read a good documentation for it before writing 278 * your own shaders. 279 * 280 * Params: 281 * shader = String containing the source code of the shader 282 * type = Type of shader (vertex geometry, or fragment) 283 * 284 * Returns: true if loading succeeded, false if it failed. 285 */ 286 bool loadFromMemory(const(char)[] shader, Type type) 287 { 288 return sfShader_loadTypeFromMemory(sfPtr, shader.ptr, shader.length, type); 289 } 290 291 /** 292 * Load both the vertex and fragment shaders from source codes in memory. 293 * 294 * This function loads both the vertex and the fragment shaders. If one of 295 * them fails to load, the shader is left empty (the valid shader is 296 * unloaded). The sources must be valid shaders in GLSL language. GLSL is a 297 * C-like language dedicated to OpenGL shaders; you'll probably need to read 298 * a good documentation for it before writing your own shaders. 299 * 300 * Params: 301 * vertexShader = String containing the source code of the vertex shader 302 * fragmentShader = String containing the source code of the fragment 303 shader 304 * 305 * Returns: true if loading succeeded, false if it failed. 306 */ 307 bool loadFromMemory(const(char)[] vertexShader, const(char)[] fragmentShader) 308 { 309 return sfShader_loadVertexAndFragmentFromMemory(sfPtr, vertexShader.ptr, vertexShader.length, fragmentShader.ptr, fragmentShader.length); 310 } 311 312 /** 313 * Load the vertex, geometry and fragment shaders from source codes in memory. 314 * 315 * This function loads the vertex, geometry and the fragment shaders. If one of 316 * them fails to load, the shader is left empty (the valid shader is 317 * unloaded). The sources must be valid shaders in GLSL language. GLSL is a 318 * C-like language dedicated to OpenGL shaders; you'll probably need to read 319 * a good documentation for it before writing your own shaders. 320 * 321 * Params: 322 * vertexShader = String containing the source code of the vertex shader 323 * geometryShader = String containing the source code of the geometry shader 324 * fragmentShader = String containing the source code of the fragment 325 shader 326 * 327 * Returns: true if loading succeeded, false if it failed. 328 */ 329 bool loadFromMemory(const(char)[] vertexShader, const(char)[] geometryShader, const(char)[] fragmentShader) 330 { 331 return sfShader_loadAllFromMemory(sfPtr, vertexShader.ptr, vertexShader.length, 332 geometryShader.ptr, geometryShader.length, 333 fragmentShader.ptr, fragmentShader.length); 334 } 335 /** 336 * Load the vertex, geometry or fragment shader from a custom stream. 337 * 338 * This function loads a single shader, either vertex, geometry or fragment, 339 * identified by the second argument. The source code must be a valid shader 340 * in GLSL language. GLSL is a C-like language dedicated to OpenGL shaders; 341 * you'll probably need to read a good documentation for it before writing 342 * your own shaders. 343 * 344 * Params: 345 * stream = Source stream to read from 346 * type = Type of shader (vertex, geometry or fragment) 347 * 348 * Returns: true if loading succeeded, false if it failed. 349 */ 350 bool loadFromStream(InputStream stream, Type type) 351 { 352 return sfShader_loadTypeFromStream(sfPtr, new shaderStream(stream), type); 353 354 } 355 356 /** 357 * Load both the vertex and fragment shaders from custom streams. 358 * 359 * This function loads a single shader, either vertex or fragment, 360 * identified by the second argument. The source code must be a valid shader 361 * in GLSL language. GLSL is a C-like language dedicated to OpenGL shaders; 362 * you'll probably need to read a good documentation for it before writing 363 * your own shaders. 364 * 365 * Params: 366 * vertexShaderStream = Source stream to read the vertex shader from 367 * fragmentShaderStream = Source stream to read the fragment shader from 368 * 369 * Returns: true if loading succeeded, false if it failed. 370 */ 371 bool loadFromStream(InputStream vertexShaderStream, InputStream fragmentShaderStream) 372 { 373 return sfShader_loadVertexAndFragmentFromStream(sfPtr, new shaderStream(vertexShaderStream), 374 new shaderStream(fragmentShaderStream)); 375 } 376 377 /** 378 * Load the vertex, geometry and fragment shaders from custom streams. 379 * 380 * This function loads a single shader, either vertex, geometry or fragment, 381 * identified by the second argument. The source code must be a valid shader 382 * in GLSL language. GLSL is a C-like language dedicated to OpenGL shaders; 383 * you'll probably need to read a good documentation for it before writing 384 * your own shaders. 385 * 386 * Params: 387 * vertexShaderStream = Source stream to read the vertex shader from 388 * geometryShaderStream = Source stream to read the geometry shader from 389 * fragmentShaderStream = Source stream to read the fragment shader from 390 * 391 * Returns: true if loading succeeded, false if it failed. 392 */ 393 bool loadFromStream(InputStream vertexShaderStream, InputStream geometryShaderStream, InputStream fragmentShaderStream) 394 { 395 return sfShader_loadAllFromStream(sfPtr, new shaderStream(vertexShaderStream), 396 new shaderStream(geometryShaderStream), 397 new shaderStream(fragmentShaderStream)); 398 } 399 400 /** 401 * Specify value for float uniform. 402 * 403 * Params: 404 * name = Name of the uniform variable in GLSL 405 * x = Value of the float scalar 406 */ 407 void setUniform(const(char)[] name, float x) 408 { 409 sfShader_setFloatUniform(sfPtr, name.ptr, name.length, x); 410 } 411 412 ///ditto 413 void opIndexAssign(float x, const(char)[] name) 414 { 415 setUniform(name, x); 416 } 417 418 /** 419 * Specify value for vec2 uniform. 420 * 421 * Params: 422 * name = Name of the uniform variable in GLSL 423 * vector = Value of the vec2 vector 424 */ 425 void setUniform(const(char)[] name, ref const(Vec2) vector) 426 { 427 sfShader_setVec2Uniform(sfPtr, name.ptr, name.length, &vector); 428 } 429 430 ///ditto 431 void opIndexAssign(ref const(Vec2) vector, const(char)[] name) 432 { 433 setUniform(name, vector); 434 } 435 436 /** 437 * Specify value for vec3 uniform. 438 * 439 * Params: 440 * name = Name of the uniform variable in GLSL 441 * vector = Value of the vec3 vector 442 */ 443 void setUniform(const(char)[] name, ref const(Vec3) vector) 444 { 445 sfShader_setVec3Uniform(sfPtr, name.ptr, name.length, &vector); 446 } 447 448 ///ditto 449 void opIndexAssign(ref const(Vec3) vector, const(char)[] name) 450 { 451 setUniform(name, vector); 452 } 453 454 /** 455 * Specify value for vec4 uniform. 456 * 457 * Params: 458 * name = Name of the uniform variable in GLSL 459 * vector = Value of the vec4 vector 460 */ 461 void setUniform(const(char)[] name, ref const(Vec4) vector) 462 { 463 sfShader_setVec4Uniform(sfPtr, name.ptr, name.length, &vector); 464 } 465 466 ///ditto 467 void opIndexAssign(ref const(Vec4) vector, const(char)[] name) 468 { 469 setUniform(name, vector); 470 } 471 472 /** 473 * Specify value for int uniform. 474 * 475 * Params: 476 * name = Name of the uniform variable in GLSL 477 * x = Value of the int scalar 478 */ 479 void setUniform(const(char)[] name, int x) 480 { 481 sfShader_setIntUniform(sfPtr, name.ptr, name.length, x); 482 } 483 484 ///ditto 485 void opIndexAssign(int x, const(char)[] name) 486 { 487 setUniform(name, x); 488 } 489 490 /** 491 * Specify value for ivec2 uniform. 492 * 493 * Params: 494 * name = Name of the uniform variable in GLSL 495 * vector = Value of the ivec2 vector 496 */ 497 void setUniform(const(char)[] name, ref const(Ivec2) vector) 498 { 499 sfShader_setIvec2Uniform(sfPtr, name.ptr, name.length, &vector); 500 } 501 502 ///ditto 503 void opIndexAssign(ref const(Ivec2) vector, const(char)[] name) 504 { 505 setUniform(name, vector); 506 } 507 508 /** 509 * Specify value for ivec3 uniform. 510 * 511 * Params: 512 * name = Name of the uniform variable in GLSL 513 * vector = Value of the ivec3 vector 514 */ 515 void setUniform(const(char)[] name, ref const(Ivec3) vector) 516 { 517 sfShader_setIvec3Uniform(sfPtr, name.ptr, name.length, &vector); 518 } 519 520 ///ditto 521 void opIndexAssign(ref const(Ivec3) vector, const(char)[] name) 522 { 523 setUniform(name, vector); 524 } 525 526 /** 527 * Specify value for ivec4 uniform. 528 * 529 * Params: 530 * name = Name of the uniform variable in GLSL 531 * vector = Value of the ivec4 vector 532 */ 533 void setUniform(const(char)[] name, ref const(Ivec4) vector) 534 { 535 sfShader_setIvec4Uniform(sfPtr, name.ptr, name.length, &vector); 536 } 537 538 ///ditto 539 void opIndexAssign(ref const(Ivec4) vector, const(char)[] name) 540 { 541 setUniform(name, vector); 542 } 543 544 /** 545 * Specify value for bool uniform. 546 * 547 * Params: 548 * name = Name of the uniform variable in GLSL 549 * x = Value of the bool scalar 550 */ 551 void setUniform(const(char)[] name, bool x) 552 { 553 sfShader_setBoolUniform(sfPtr, name.ptr, name.length, x); 554 } 555 556 ///ditto 557 void opIndexAssign(bool x, const(char)[] name) 558 { 559 setUniform(name, x); 560 } 561 562 /** 563 * Specify value for bvec2 uniform. 564 * 565 * Params: 566 * name = Name of the uniform variable in GLSL 567 * vector = Value of the bvec2 vector 568 */ 569 void setUniform(const(char)[] name, ref const(Bvec2) vector) 570 { 571 sfShader_setBvec2Uniform(sfPtr, name.ptr, name.length, 572 vector.x, vector.y); 573 } 574 575 ///ditto 576 void opIndexAssign(ref const(Bvec2) vector, const(char)[] name) 577 { 578 setUniform(name, vector); 579 } 580 581 /** 582 * Specify value for bvec3 uniform. 583 * 584 * Params: 585 * name = Name of the uniform variable in GLSL 586 * vector = Value of the bvec3 vector 587 */ 588 void setUniform(const(char)[] name, ref const(Bvec3) vector) 589 { 590 sfShader_setBvec3Uniform(sfPtr, name.ptr, name.length, vector.x, 591 vector.y, vector.z); 592 } 593 594 ///ditto 595 void opIndexAssign(ref const(Bvec3) vector, const(char)[] name) 596 { 597 setUniform(name, vector); 598 } 599 600 601 /** 602 * Specify value for bvec4 uniform. 603 * 604 * Params: 605 * name = Name of the uniform variable in GLSL 606 * vector = Value of the bvec4 vector 607 */ 608 void setUniform(const(char)[] name, ref const(Bvec4) vector) 609 { 610 sfShader_setBvec4Uniform(sfPtr, name.ptr, name.length, vector.x, 611 vector.y, vector.z, vector.w); 612 } 613 614 ///ditto 615 void opIndexAssign(ref const(Bvec4) vector, const(char)[] name) 616 { 617 setUniform(name, vector); 618 } 619 620 /** 621 * Specify value for mat3 matrix. 622 * 623 * Params: 624 * name = Name of the uniform variable in GLSL 625 * matrix = Value of the mat3 vector 626 */ 627 void setUniform(const(char)[] name, ref const(Mat3) matrix) 628 { 629 sfShader_setMat3Uniform(sfPtr, name.ptr, name.length, &matrix); 630 } 631 632 ///ditto 633 void opIndexAssign(ref const(Mat3) matrix, const(char)[] name) 634 { 635 setUniform(name, matrix); 636 } 637 638 /** 639 * Specify value for mat4 matrix. 640 * 641 * Params: 642 * name = Name of the uniform variable in GLSL 643 * matrix = Value of the mat4 vector 644 */ 645 void setUniform(const(char)[] name, ref const(Mat4) matrix) 646 { 647 sfShader_setMat4Uniform(sfPtr, name.ptr, name.length, &matrix); 648 } 649 650 ///ditto 651 void opIndexAssign(ref const(Mat4) matrix, const(char)[] name) 652 { 653 setUniform(name, matrix); 654 } 655 656 /** 657 * Specify a texture as sampler2D uniform. 658 * 659 * 'name' is the name of the variable to change in the shader. The 660 * corresponding parameter in the shader must be a 2D texture (sampler2D 661 * GLSL type). 662 * 663 * It is important to note that texture must remain alive as long as the 664 * shader uses it, no copy is made internally. 665 * 666 * To use the texture of the object being drawn, which cannot be known in 667 * advance, you can pass the special value CurrentTexture. 668 * 669 * Params: 670 * name = Name of the texture in the shader 671 * texture = Texture to assign 672 */ 673 void setUniform(const(char)[] name, const(Texture) texture) 674 { 675 sfShader_setTextureUniform(sfPtr, name.ptr, name.length, 676 texture?texture.sfPtr:null); 677 } 678 679 ///ditto 680 void opIndexAssign(const(Texture) texture, const(char)[] name) 681 { 682 sfShader_setTextureUniform(sfPtr, name.ptr, name.length, 683 texture?texture.sfPtr:null); 684 } 685 686 /** 687 * Specify current texture as sampler2D uniform. 688 * 689 * This overload maps a shader texture variable to the texture of the object 690 * being drawn, which cannot be known in advance. The second argument must 691 * be CurrentTexture. The corresponding parameter in the shader must be a 2D 692 * texture (sampler2D GLSL type). 693 * 694 * Params: 695 * name = Name of the texture in the shader 696 */ 697 void setUniform(const(char)[] name, CurrentTextureType) 698 { 699 sfShader_setCurrentTextureUniform(sfPtr, name.ptr, name.length); 700 } 701 702 ///ditto 703 void opIndexAssign(CurrentTextureType, const(char)[] name) 704 { 705 sfShader_setCurrentTextureUniform(sfPtr, name.ptr, name.length); 706 } 707 708 /** 709 * Specify values for float[] array uniform. 710 * 711 * Params: 712 * name = Name of the uniform variable in GLSL 713 * scalarArray = array of float values 714 */ 715 void setUniformArray(const(char)[] name, const(float)[] scalarArray) 716 { 717 sfShader_setFloatArrayUniform(sfPtr, name.ptr, name.length, 718 scalarArray.ptr, scalarArray.length); 719 } 720 721 ///ditto 722 void opIndexAssign(const(float)[] scalars, const(char)[] name) 723 { 724 setUniformArray(name, scalars); 725 } 726 727 /** 728 * Specify values for vec2[] array uniform. 729 * 730 * Params: 731 * name = Name of the uniform variable in GLSL 732 * vectorArray = array of vec2 values 733 */ 734 void setUniformArray(const(char)[] name, const(Vec2)[] vectorArray) 735 { 736 sfShader_setVec2ArrayUniform(sfPtr, name.ptr, name.length, 737 vectorArray.ptr, vectorArray.length); 738 } 739 740 ///ditto 741 void opIndexAssign(const(Vec2)[] vectors, const(char)[] name) 742 { 743 setUniformArray(name, vectors); 744 } 745 746 /** 747 * Specify values for vec3[] array uniform. 748 * 749 * Params: 750 * name = Name of the uniform variable in GLSL 751 * vectorArray = array of vec3 values 752 */ 753 void setUniformArray(const(char)[] name, const(Vec3)[] vectorArray) 754 { 755 sfShader_setVec3ArrayUniform(sfPtr, name.ptr, name.length, 756 vectorArray.ptr, vectorArray.length); 757 } 758 759 ///ditto 760 void opIndexAssign(const(Vec3)[] vectors, const(char)[] name) 761 { 762 setUniformArray(name, vectors); 763 } 764 765 /** 766 * Specify values for vec4[] array uniform. 767 * 768 * Params: 769 * name = Name of the uniform variable in GLSL 770 * vectorArray = array of vec4 values 771 */ 772 void setUniformArray(const(char)[] name, const(Vec4)[] vectorArray) 773 { 774 sfShader_setVec4ArrayUniform(sfPtr, name.ptr, name.length, 775 vectorArray.ptr, vectorArray.length); 776 } 777 778 ///ditto 779 void opIndexAssign(const(Vec4)[] vectors, const(char)[] name) 780 { 781 setUniformArray(name, vectors); 782 } 783 784 /** 785 * Specify values for mat3[] array uniform. 786 * 787 * Params: 788 * name = Name of the uniform variable in GLSL 789 * matrixArray = array of mat3 values 790 */ 791 void setUniformArray(const(char)[] name, const(Mat3)[] matrixArray) 792 { 793 sfShader_setMat3ArrayUniform(sfPtr, name.ptr, name.length, 794 matrixArray.ptr, matrixArray.length); 795 } 796 797 ///ditto 798 void opIndexAssign(const(Mat3)[] matrices, const(char)[] name) 799 { 800 setUniformArray(name, matrices); 801 } 802 803 /** 804 * Specify values for mat4[] array uniform. 805 * 806 * Params: 807 * name = Name of the uniform variable in GLSL 808 * matrixArray = array of mat4 values 809 */ 810 void setUniformArray(const(char)[] name, const(Mat4)[] matrixArray) 811 { 812 sfShader_setMat4ArrayUniform(sfPtr, name.ptr, name.length, 813 matrixArray.ptr, matrixArray.length); 814 } 815 816 ///ditto 817 void opIndexAssign(const(Mat4)[] matrices, const(char)[] name) 818 { 819 setUniformArray(name, matrices); 820 } 821 822 /** 823 * Change a float parameter of the shader. 824 * 825 * Params: 826 * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a float (float GLSL type). 827 * x = Value to assign 828 */ 829 deprecated("Use setUniform(const(char)[], float) instead.") 830 void setParameter(const(char)[] name, float x) 831 { 832 import dsfml.system..string; 833 sfShader_setFloatParameter(sfPtr, name.ptr, name.length, x); 834 } 835 836 /** 837 * Change a 2-components vector parameter of the shader. 838 * 839 * Params: 840 * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a 2x1 vector (vec2 GLSL type). 841 * x = First component of the value to assign 842 * y = Second component of the value to assign 843 */ 844 deprecated("Use setUniform(const(char)[] , ref const(Vec2)) instead.") 845 void setParameter(const(char)[] name, float x, float y) 846 { 847 import dsfml.system..string; 848 sfShader_setFloat2Parameter(sfPtr, name.ptr, name.length, x, y); 849 } 850 851 /** 852 * Change a 3-components vector parameter of the shader. 853 * 854 * Params: 855 * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a 3x1 vector (vec3 GLSL type). 856 * x = First component of the value to assign 857 * y = Second component of the value to assign 858 * z = Third component of the value to assign 859 */ 860 deprecated("Use setUniform(const(char)[] , ref const(Vec3)) instead.") 861 void setParameter(const(char)[] name, float x, float y, float z) 862 { 863 import dsfml.system..string; 864 sfShader_setFloat3Parameter(sfPtr, name.ptr, name.length, x,y,z); 865 } 866 867 /** 868 * Change a 4-components vector parameter of the shader. 869 * 870 * Params: 871 * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a 4x1 vector (vec4 GLSL type). 872 * x = First component of the value to assign 873 * y = Second component of the value to assign 874 * z = Third component of the value to assign 875 * w = Fourth component of the value to assign 876 */ 877 deprecated("Use setUniform(const(char)[] , ref const(Vec4)) instead.") 878 void setParameter(const(char)[] name, float x, float y, float z, float w) 879 { 880 import dsfml.system..string; 881 sfShader_setFloat4Parameter(sfPtr, name.ptr, name.length, x, y, z, w); 882 } 883 884 /** 885 * Change a 2-components vector parameter of the shader. 886 * 887 * Params: 888 * name = The name of the variable to change in the shader. The corresponding parameter in the shader must be a 2x1 vector (vec2 GLSL type). 889 * vector = Vector to assign 890 */ 891 deprecated("Use setUniform(const(char)[] , ref const(Vec2)) instead.") 892 void setParameter(const(char)[] name, Vector2f vector) 893 { 894 import dsfml.system..string; 895 sfShader_setFloat2Parameter(sfPtr, name.ptr, name.length, vector.x, vector.y); 896 } 897 898 /** 899 * Change a 3-components vector parameter of the shader. 900 * 901 * Params: 902 * name = The name of the variable to change in the shader. 903 * The corresponding parameter in the shader must be a 3x1 904 vector (vec3 GLSL type) 905 * vector = Vector to assign 906 */ 907 deprecated("Use setUniform(const(char)[] , ref const(Vec3)) instead.") 908 void setParameter(const(char)[] name, Vector3f vector) 909 { 910 import dsfml.system..string; 911 sfShader_setFloat3Parameter(sfPtr, name.ptr, name.length, vector.x, vector.y, vector.z); 912 } 913 914 /** 915 * Change a color vector parameter of the shader. 916 * 917 * It is important to note that the components of the color are normalized 918 * before being passed to the shader. Therefore, they are converted from 919 * range [0 .. 255] to range [0 .. 1]. For example, a 920 * Color(255, 125, 0, 255) will be transformed to a vec4(1.0, 0.5, 0.0, 1.0) 921 * in the shader. 922 * 923 * Params: 924 * name = The name of the variable to change in the shader. The 925 * corresponding parameter in the shader must be a 4x1 vector 926 * (vec4 GLSL type). 927 * color = Color to assign 928 */ 929 deprecated("Use setUniform(const(char)[] , ref const(Vec4)) instead.") 930 void setParameter(const(char)[] name, Color color) 931 { 932 import dsfml.system..string; 933 sfShader_setColorParameter(sfPtr, name.ptr, name.length, color.r, color.g, color.b, color.a); 934 } 935 936 ///ditto 937 deprecated("Use shader[\"name\"] = Vec4(color) instead.") 938 void opIndexAssign(Color color, const(char)[] name) 939 { 940 import dsfml.system..string; 941 sfShader_setColorParameter(sfPtr, name.ptr, name.length, color.r, color.g, color.b, color.a); 942 } 943 944 /** 945 * Change a matrix parameter of the shader. 946 * 947 * Params: 948 * name = The name of the variable to change in the shader. The 949 * corresponding parameter in the shader must be a 4x4 950 matrix (mat4 GLSL type) 951 * transform = Transform to assign 952 */ 953 deprecated("Use setUniform(const(char)[] , ref const(Mat4)) instead.") 954 void setParameter(const(char)[] name, Transform transform) 955 { 956 import dsfml.system..string; 957 sfShader_setTransformParameter(sfPtr, name.ptr, name.length, transform.m_matrix.ptr); 958 } 959 960 ///ditto 961 deprecated("Use shader[\"name\"] = Mat4(transform) instead.") 962 void opIndexAssign(Transform transform, const(char)[] name) 963 { 964 import dsfml.system..string; 965 sfShader_setTransformParameter(sfPtr, name.ptr, name.length, transform.m_matrix.ptr); 966 } 967 968 /** 969 * Change a texture parameter of the shader. 970 * 971 * It is important to note that the texture parameter must remain alive as 972 * long as the shader uses it - no copoy is made internally. 973 * 974 * To use the texture of the object being draw, which cannot be known in 975 * advance, you can pass the special value Shader.CurrentTexture. 976 * 977 * Params: 978 * name = The name of the variable to change in the shader. The 979 * corresponding parameter in the shader must be a 2D texture 980 * (sampler2D GLSL type) 981 * texture = Texture to assign 982 */ 983 deprecated("Use setUniform(const(char)[] , const(Texture)) instead.") 984 void setParameter(const(char)[] name, const(Texture) texture) 985 { 986 sfShader_setTextureParameter(sfPtr, name.ptr, name.length, texture?texture.sfPtr:null); 987 } 988 989 /** 990 * Change a texture parameter of the shader. 991 * 992 * This overload maps a shader texture variable to the texture of the object 993 * being drawn, which cannot be known in advance. The second argument must 994 * be Shader.CurrentTexture. 995 * 996 * Params: 997 * name = The name of the variable to change in the shader. 998 * The corresponding parameter in the shader must be a 2D texture 999 * (sampler2D GLSL type) 1000 * currentTexture = Dummy variable to denote the texture of the object 1001 */ 1002 deprecated("Use setUniform(const(char)[] , CurrentTextureType) instead.") 1003 void setParameter(const(char)[] name, CurrentTextureType currentTexture) 1004 { 1005 import dsfml.system..string; 1006 sfShader_setCurrentTextureParameter(sfPtr, name.ptr, name.length); 1007 } 1008 1009 /** 1010 * Bind a shader for rendering. 1011 * 1012 * This function is not part of the graphics API, it mustn't be used when drawing SFML entities. It must be used only if you mix Shader with OpenGL code. 1013 * 1014 * Params: 1015 * shader = Shader to bind. Can be null to use no shader. 1016 */ 1017 static void bind(Shader shader) 1018 { 1019 (shader is null)?sfShader_bind(null):sfShader_bind(shader.sfPtr); 1020 } 1021 1022 /** 1023 * Tell whether or not the system supports shaders. 1024 * 1025 * This function should always be called before using the shader features. 1026 * If it returns false, then any attempt to use DSFML Shader will fail. 1027 * 1028 * Returns: true if shaders are supported, false otherwise. 1029 */ 1030 static bool isAvailable() 1031 { 1032 return sfShader_isAvailable(); 1033 } 1034 1035 /** 1036 * Tell whether or not the system supports geometry shaders. 1037 * 1038 * Returns: true if geometry shaders are supported, false otherwise. 1039 */ 1040 static bool isGeometryAvailable() 1041 { 1042 return sfShader_isGeometryAvailable(); 1043 } 1044 } 1045 1046 unittest 1047 { 1048 //find some examples of interesting shaders and use them here? 1049 } 1050 1051 private extern(C++) interface shaderInputStream 1052 { 1053 long read(void* data, long size); 1054 1055 long seek(long position); 1056 1057 long tell(); 1058 1059 long getSize(); 1060 } 1061 1062 1063 private class shaderStream:shaderInputStream 1064 { 1065 private InputStream myStream; 1066 1067 this(InputStream stream) 1068 { 1069 myStream = stream; 1070 } 1071 1072 extern(C++)long read(void* data, long size) 1073 { 1074 return myStream.read(data[0..cast(size_t)size]); 1075 } 1076 1077 extern(C++)long seek(long position) 1078 { 1079 return myStream.seek(position); 1080 } 1081 1082 extern(C++)long tell() 1083 { 1084 return myStream.tell(); 1085 } 1086 1087 extern(C++)long getSize() 1088 { 1089 return myStream.getSize(); 1090 } 1091 } 1092 1093 package extern(C): 1094 struct sfShader; 1095 1096 private extern(C): 1097 1098 //Construct a new shader 1099 sfShader* sfShader_construct(); 1100 1101 //Load a single shader type from file 1102 bool sfShader_loadTypeFromFile(sfShader* shader, const(char)* shaderFilename, size_t shaderFilenameLength, int type); 1103 1104 //Load both the vertex and fragment shaders from files 1105 bool sfShader_loadVertexAndFragmentFromFile(sfShader* shader, const(char)* vertexFilename, size_t vertexFilenameLength, const(char)* fragmentFilename, size_t fragmentFilenameLength); 1106 1107 //Load the vertex, geometry, and fragment shaders from files 1108 bool sfShader_loadAllFromFile(sfShader* shader, const(char)* vertexFilename, size_t vertexFilenameLength, const(char)* geometryFilename, size_t geometryFilenameLength, const(char)* fragmentFilename, size_t fragmentFilenameLength); 1109 1110 //Load a single shader type from source code in memory 1111 bool sfShader_loadTypeFromMemory(sfShader* shader, const(char)* shaderSource, size_t shaderSourceLength, int type); 1112 1113 //Load both the vertex and fragment shaders from source code in memory 1114 bool sfShader_loadVertexAndFragmentFromMemory(sfShader* shader, const(char)* vertexSource, size_t vertexSourceLength, const(char)* fragmentSource, size_t fragmentSourceLength); 1115 1116 //Load the vertex, geometry, and fragment shaders from source code in memory 1117 bool sfShader_loadAllFromMemory(sfShader* shader, const(char)* vertexSource, size_t vertexSourceLength, const(char)* geometrySource, size_t geometrySourceLength,const(char)* fragmentSource, size_t fragmentSourceLength); 1118 1119 //Load a single shader type from custom stream 1120 bool sfShader_loadTypeFromStream(sfShader* shader, shaderInputStream shaderStream, int type); 1121 1122 //Load both the vertex and fragment shaders from custom streams 1123 bool sfShader_loadVertexAndFragmentFromStream(sfShader* shader, shaderInputStream vertexStream, shaderInputStream fragmentStream); 1124 1125 //Load the vertex, geometry, and fragment shaders from custom streams 1126 bool sfShader_loadAllFromStream(sfShader* shader, shaderInputStream vertexStream, shaderInputStream geometryStream, shaderInputStream fragmentStream); 1127 1128 //Destroy an existing shader 1129 void sfShader_destroy(sfShader* shader); 1130 1131 //Specify value for float uniform 1132 void sfShader_setFloatUniform(sfShader* shader, const char* name, size_t length, float x); 1133 1134 //Specify value for vec2 uniform 1135 void sfShader_setVec2Uniform(sfShader* shader, const char* name, size_t length, const(Vec2)* vec2); 1136 1137 //Specify value for vec3 uniform 1138 void sfShader_setVec3Uniform(sfShader* shader, const char* name, size_t length, const(Vec3)* vec3); 1139 1140 //Specify value for vec4 uniform 1141 void sfShader_setVec4Uniform(sfShader* shader, const char* name, size_t length, const(Vec4)* vec4); 1142 1143 //Specify value for int uniform 1144 void sfShader_setIntUniform(sfShader* shader, const char* name, size_t length, int x); 1145 1146 //Specify value for ivec2 uniform 1147 void sfShader_setIvec2Uniform(sfShader* shader, const char* name, size_t length, const(Ivec2)* ivec2); 1148 1149 //Specify value for ivec3 uniform 1150 void sfShader_setIvec3Uniform(sfShader* shader, const char* name, size_t length, const(Ivec3)* ivec3); 1151 1152 //Specify value for ivec4 uniform 1153 void sfShader_setIvec4Uniform(sfShader* shader, const char* name, size_t length, const(Ivec4)* ivec4); 1154 1155 //Specify value for bool uniform 1156 void sfShader_setBoolUniform(sfShader* shader, const char* name, size_t length, bool x); 1157 1158 //Specify value for bvec2 uniform 1159 void sfShader_setBvec2Uniform(sfShader* shader, const char* name, size_t length, bool x, bool y); 1160 1161 //Specify value for bvec3 uniform 1162 void sfShader_setBvec3Uniform(sfShader* shader, const char* name, size_t length, bool x, bool y, bool z); 1163 1164 //Specify value for bvec4 uniform 1165 void sfShader_setBvec4Uniform(sfShader* shader, const char* name, size_t length, bool x, bool y, bool z, bool w); 1166 1167 //Specify value for mat3 matrix. 1168 void sfShader_setMat3Uniform(sfShader* shader, const char* name, size_t length, const(Mat3)* mat3); 1169 1170 //Specify value for mat4 matrix. 1171 void sfShader_setMat4Uniform(sfShader* shader, const char* name, size_t length, const(Mat4)* mat4); 1172 1173 //Specify a texture as sampler2D uniform 1174 void sfShader_setTextureUniform(sfShader* shader, const char* name, size_t length, const(sfTexture)* texture); 1175 1176 //Specify current texture as sampler2D uniform. 1177 void sfShader_setCurrentTextureUniform(sfShader* shader, const char* name, size_t length); 1178 1179 //Specify values for float[] array uniform. 1180 void sfShader_setFloatArrayUniform(sfShader* shader, const char* name, size_t nlength, const(float)* array, size_t alength); 1181 1182 //Specify values for vec2[] array uniform. 1183 void sfShader_setVec2ArrayUniform(sfShader* shader, const char* name, size_t nlength, const(Vec2)*, size_t alength); 1184 1185 //Specify values for vec3[] array uniform. 1186 void sfShader_setVec3ArrayUniform(sfShader* shader, const char* name, size_t nlength, const(Vec3)*, size_t alength); 1187 1188 //Specify values for vec4[] array uniform. 1189 void sfShader_setVec4ArrayUniform(sfShader* shader, const char* name, size_t nlength, const(Vec4)*, size_t alength); 1190 1191 //Specify values for mat3[] array uniform. 1192 void sfShader_setMat3ArrayUniform(sfShader* shader, const char* name, size_t nlength, const(Mat3)*, size_t alength); 1193 1194 //Specify values for mat4[] array uniform. 1195 void sfShader_setMat4ArrayUniform(sfShader* shader, const char* name, size_t nlength, const(Mat4)*, size_t alength); 1196 1197 //Bind a shader for rendering (activate it) 1198 void sfShader_bind(const sfShader* shader); 1199 1200 //Tell whether or not the system supports shaders 1201 bool sfShader_isAvailable(); 1202 1203 //Tell whether or not the system supports geometry shaders 1204 bool sfShader_isGeometryAvailable(); 1205 1206 //DEPRECATED 1207 1208 //Change a float parameter of a shader 1209 void sfShader_setFloatParameter(sfShader* shader, const char* name, size_t length, float x); 1210 1211 //Change a 2-components vector parameter of a shader 1212 void sfShader_setFloat2Parameter(sfShader* shader, const char* name, size_t length, float x, float y); 1213 1214 //Change a 3-components vector parameter of a shader 1215 void sfShader_setFloat3Parameter(sfShader* shader, const char* name, size_t length, float x, float y, float z); 1216 1217 //Change a 4-components vector parameter of a shader 1218 void sfShader_setFloat4Parameter(sfShader* shader, const char* name, size_t length, float x, float y, float z, float w); 1219 1220 //Change a color parameter of a shader 1221 void sfShader_setColorParameter(sfShader* shader, const char* name, size_t length, ubyte r, ubyte g, ubyte b, ubyte a); 1222 1223 //Change a matrix parameter of a shader 1224 void sfShader_setTransformParameter(sfShader* shader, const char* name, size_t length, float* transform); 1225 1226 //Change a texture parameter of a shader 1227 void sfShader_setTextureParameter(sfShader* shader, const char* name, size_t length, const sfTexture* texture); 1228 1229 //Change a texture parameter of a shader 1230 void sfShader_setCurrentTextureParameter(sfShader* shader, const char* name, size_t length);