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