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);