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