aboutsummaryrefslogtreecommitdiff
path: root/examples/shaders
diff options
context:
space:
mode:
authorDarkElvenAngel <jb_rotavele@yahoo.com>2019-06-10 16:12:06 -0400
committerGitHub <noreply@github.com>2019-06-10 16:12:06 -0400
commitd7f4be071579e6f00974c0940f021272f22fbc54 (patch)
tree6ee389e6617c494d272e9bc82415fbc3618e7a28 /examples/shaders
parent8a21830b77eaa76ffe0c31df5f96aecd6bd2eecc (diff)
parentbaf7d7d19ad8d6bfbfc201169e4ed4f49a9576a6 (diff)
downloadraylib-d7f4be071579e6f00974c0940f021272f22fbc54.tar.gz
raylib-d7f4be071579e6f00974c0940f021272f22fbc54.zip
Merge pull request #1 from raysan5/master
Update
Diffstat (limited to 'examples/shaders')
-rw-r--r--examples/shaders/resources/shaders/glsl100/cubes_panning.fs60
-rw-r--r--examples/shaders/resources/shaders/glsl100/depth.fs26
-rw-r--r--examples/shaders/resources/shaders/glsl100/eratosthenes.fs58
-rw-r--r--examples/shaders/resources/shaders/glsl100/julia_set.fs81
-rw-r--r--examples/shaders/resources/shaders/glsl100/palette_switch.fs (renamed from examples/shaders/resources/shaders/glsl100/palette-switch.fs)58
-rw-r--r--examples/shaders/resources/shaders/glsl100/raymarching.fs431
-rw-r--r--examples/shaders/resources/shaders/glsl100/wave.fs36
-rw-r--r--examples/shaders/resources/shaders/glsl120/palette_switch.fs (renamed from examples/shaders/resources/shaders/glsl120/palette-switch.fs)54
-rw-r--r--examples/shaders/resources/shaders/glsl330/cubes_panning.fs61
-rw-r--r--examples/shaders/resources/shaders/glsl330/eratosthenes.fs59
-rw-r--r--examples/shaders/resources/shaders/glsl330/julia_set.fs81
-rw-r--r--examples/shaders/resources/shaders/glsl330/palette_switch.fs (renamed from examples/shaders/resources/shaders/glsl330/palette-switch.fs)60
-rw-r--r--examples/shaders/resources/shaders/glsl330/raymarching.fs23
-rw-r--r--examples/shaders/resources/shaders/glsl330/wave.fs37
-rw-r--r--examples/shaders/resources/space.pngbin0 -> 22517 bytes
-rw-r--r--examples/shaders/shaders_custom_uniform.c40
-rw-r--r--examples/shaders/shaders_eratosthenes.c94
-rw-r--r--examples/shaders/shaders_eratosthenes.pngbin0 -> 619472 bytes
-rw-r--r--examples/shaders/shaders_julia_set.c190
-rw-r--r--examples/shaders/shaders_julia_set.pngbin0 -> 357391 bytes
-rw-r--r--examples/shaders/shaders_model_shader.c23
-rw-r--r--examples/shaders/shaders_palette_switch.c70
-rw-r--r--examples/shaders/shaders_palette_switch.pngbin0 -> 15463 bytes
-rw-r--r--examples/shaders/shaders_postprocessing.c50
-rw-r--r--examples/shaders/shaders_raymarching.c20
-rw-r--r--examples/shaders/shaders_shapes_textures.c36
-rw-r--r--examples/shaders/shaders_texture_drawing.c80
-rw-r--r--examples/shaders/shaders_texture_drawing.pngbin0 -> 16865 bytes
-rw-r--r--examples/shaders/shaders_texture_waves.c110
-rw-r--r--examples/shaders/shaders_texture_waves.pngbin0 -> 86453 bytes
30 files changed, 1624 insertions, 214 deletions
diff --git a/examples/shaders/resources/shaders/glsl100/cubes_panning.fs b/examples/shaders/resources/shaders/glsl100/cubes_panning.fs
new file mode 100644
index 00000000..1b1ab15c
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl100/cubes_panning.fs
@@ -0,0 +1,60 @@
+#version 100
+
+precision mediump float;
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Custom variables
+#define PI 3.14159265358979323846
+uniform float uTime = 0.0;
+
+float divisions = 5.0;
+float angle = 0.0;
+
+vec2 VectorRotateTime(vec2 v, float speed)
+{
+ float time = uTime*speed;
+ float localTime = fract(time); // The time domain this works on is 1 sec.
+
+ if ((localTime >= 0.0) && (localTime < 0.25)) angle = 0.0;
+ else if ((localTime >= 0.25) && (localTime < 0.50)) angle = PI/4*sin(2*PI*localTime - PI/2);
+ else if ((localTime >= 0.50) && (localTime < 0.75)) angle = PI*0.25;
+ else if ((localTime >= 0.75) && (localTime < 1.00)) angle = PI/4*sin(2*PI*localTime);
+
+ // Rotate vector by angle
+ v -= 0.5;
+ v = mat2(cos(angle), -sin(angle), sin(angle), cos(angle))*v;
+ v += 0.5;
+
+ return v;
+}
+
+float Rectangle(in vec2 st, in float size, in float fill)
+{
+ float roundSize = 0.5 - size/2.0;
+ float left = step(roundSize, st.x);
+ float top = step(roundSize, st.y);
+ float bottom = step(roundSize, 1.0 - st.y);
+ float right = step(roundSize, 1.0 - st.x);
+
+ return (left*bottom*right*top)*fill;
+}
+
+void main()
+{
+ vec2 fragPos = fragTexCoord;
+ fragPos.xy += uTime/9.0;
+
+ fragPos *= divisions;
+ vec2 ipos = floor(fragPos); // Get the integer coords
+ vec2 fpos = fract(fragPos); // Get the fractional coords
+
+ fpos = VectorRotateTime(fpos, 0.2);
+
+ float alpha = Rectangle(fpos, 0.216, 1.0);
+ vec3 color = vec3(0.3, 0.3, 0.3);
+
+ gl_FragColor = vec4(color, alpha);
+} \ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl100/depth.fs b/examples/shaders/resources/shaders/glsl100/depth.fs
new file mode 100644
index 00000000..f6a14eb2
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl100/depth.fs
@@ -0,0 +1,26 @@
+#version 100
+
+precision mediump float;
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0; // Depth texture
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+void main()
+{
+ float zNear = 0.01; // camera z near
+ float zFar = 10.0; // camera z far
+ float z = texture2D(texture0, fragTexCoord).x;
+
+ // Linearize depth value
+ float depth = (2.0*zNear)/(zFar + zNear - z*(zFar - zNear));
+
+ // Calculate final fragment color
+ gl_FragColor = vec4(depth, depth, depth, 1.0f);
+} \ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl100/eratosthenes.fs b/examples/shaders/resources/shaders/glsl100/eratosthenes.fs
new file mode 100644
index 00000000..0d598cac
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl100/eratosthenes.fs
@@ -0,0 +1,58 @@
+#version 100
+
+precision mediump float;
+
+/*************************************************************************************
+
+ The Sieve of Eratosthenes -- a simple shader by ProfJski
+ An early prime number sieve: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
+
+ The screen is divided into a square grid of boxes, each representing an integer value.
+ Each integer is tested to see if it is a prime number. Primes are colored white.
+ Non-primes are colored with a color that indicates the smallest factor which evenly divdes our integer.
+
+ You can change the scale variable to make a larger or smaller grid.
+ Total number of integers displayed = scale squared, so scale = 100 tests the first 10,000 integers.
+
+ WARNING: If you make scale too large, your GPU may bog down!
+
+***************************************************************************************/
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Make a nice spectrum of colors based on counter and maxSize
+vec4 Colorizer(float counter, float maxSize)
+{
+ float red = 0.0, green = 0.0, blue = 0.0;
+ float normsize = counter/maxSize;
+
+ red = smoothstep(0.3, 0.7, normsize);
+ green = sin(3.14159*normsize);
+ blue = 1.0 - smoothstep(0.0, 0.4, normsize);
+
+ return vec4(0.8*red, 0.8*green, 0.8*blue, 1.0);
+}
+
+void main()
+{
+ vec4 color = vec4(1.0);
+ float scale = 1000.0; // Makes 100x100 square grid. Change this variable to make a smaller or larger grid.
+ int value = int(scale*floor(fragTexCoord.y*scale) + floor(fragTexCoord.x*scale)); // Group pixels into boxes representing integer values
+
+ if ((value == 0) || (value == 1) || (value == 2)) gl_FragColor = vec4(1.0);
+ else
+ {
+ for (int i = 2; (i < max(2, sqrt(value) + 1)); i++)
+ {
+ if ((value - i*floor(value/i)) == 0)
+ {
+ color = Colorizer(float(i), scale);
+ //break; // Uncomment to color by the largest factor instead
+ }
+ }
+
+ gl_FragColor = color;
+ }
+}
diff --git a/examples/shaders/resources/shaders/glsl100/julia_set.fs b/examples/shaders/resources/shaders/glsl100/julia_set.fs
new file mode 100644
index 00000000..149a559c
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl100/julia_set.fs
@@ -0,0 +1,81 @@
+#version 100
+
+precision mediump float;
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+uniform vec2 screenDims; // Dimensions of the screen
+uniform vec2 c; // c.x = real, c.y = imaginary component. Equation done is z^2 + c
+uniform vec2 offset; // Offset of the scale.
+uniform float zoom; // Zoom of the scale.
+
+const int MAX_ITERATIONS = 255; // Max iterations to do.
+
+// Square a complex number
+vec2 ComplexSquare(vec2 z)
+{
+ return vec2(
+ z.x * z.x - z.y * z.y,
+ z.x * z.y * 2.0
+ );
+}
+
+// Convert Hue Saturation Value (HSV) color into RGB
+vec3 Hsv2rgb(vec3 c)
+{
+ vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
+ vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
+ return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
+}
+
+
+void main()
+{
+ /**********************************************************************************************
+ Julia sets use a function z^2 + c, where c is a constant.
+ This function is iterated until the nature of the point is determined.
+
+ If the magnitude of the number becomes greater than 2, then from that point onward
+ the number will get bigger and bigger, and will never get smaller (tends towards infinity).
+ 2^2 = 4, 4^2 = 8 and so on.
+ So at 2 we stop iterating.
+
+ If the number is below 2, we keep iterating.
+ But when do we stop iterating if the number is always below 2 (it converges)?
+ That is what MAX_ITERATIONS is for.
+ Then we can divide the iterations by the MAX_ITERATIONS value to get a normalized value that we can
+ then map to a color.
+
+ We use dot product (z.x * z.x + z.y * z.y) to determine the magnitude (length) squared.
+ And once the magnitude squared is > 4, then magnitude > 2 is also true (saves computational power).
+ *************************************************************************************************/
+
+ // The pixel coordinates are scaled so they are on the mandelbrot scale
+ // NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom
+ vec2 z = vec2((fragTexCoord.x + offset.x/screenDims.x)*2.5/zoom, (fragTexCoord.y + offset.y/screenDims.y)*1.5/zoom);
+
+ int iterations = 0;
+ for (iterations = 0; iterations < MAX_ITERATIONS; iterations++)
+ {
+ z = ComplexSquare(z) + c; // Iterate function
+
+ if (dot(z, z) > 4.0) break;
+ }
+
+ // Another few iterations decreases errors in the smoothing calculation.
+ // See http://linas.org/art-gallery/escape/escape.html for more information.
+ z = ComplexSquare(z) + c;
+ z = ComplexSquare(z) + c;
+
+ // This last part smooths the color (again see link above).
+ float smoothVal = float(iterations) + 1.0 - (log(log(length(z)))/log(2.0));
+
+ // Normalize the value so it is between 0 and 1.
+ float norm = smoothVal/float(MAX_ITERATIONS);
+
+ // If in set, color black. 0.999 allows for some float accuracy error.
+ if (norm > 0.999) gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+ else gl_FragColor = vec4(Hsv2rgb(vec3(norm, 1.0, 1.0)), 1.0);
+}
diff --git a/examples/shaders/resources/shaders/glsl100/palette-switch.fs b/examples/shaders/resources/shaders/glsl100/palette_switch.fs
index 65a7bd29..3861d4c1 100644
--- a/examples/shaders/resources/shaders/glsl100/palette-switch.fs
+++ b/examples/shaders/resources/shaders/glsl100/palette_switch.fs
@@ -1,29 +1,29 @@
-#version 100
-
-precision mediump float;
-
-const int colors = 8;
-
-// Input vertex attributes (from vertex shader)
-varying vec2 fragTexCoord;
-varying vec4 fragColor;
-
-// Input uniform values
-uniform sampler2D texture0;
-uniform ivec3 palette[colors];
-
-void main()
-{
- // Texel color fetching from texture sampler
- vec4 texelColor = texture(texture0, fragTexCoord) * fragColor;
-
- // Convert the (normalized) texel color RED component (GB would work, too)
- // to the palette index by scaling up from [0, 1] to [0, 255].
- int index = int(texelColor.r * 255.0);
- ivec3 color = palette[index];
-
- // Calculate final fragment color. Note that the palette color components
- // are defined in the range [0, 255] and need to be normalized to [0, 1]
- // for OpenGL to work.
- gl_FragColor = vec4(color / 255.0, texelColor.a);
-}
+#version 100
+
+precision mediump float;
+
+const int colors = 8;
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform ivec3 palette[colors];
+
+void main()
+{
+ // Texel color fetching from texture sampler
+ vec4 texelColor = texture2D(texture0, fragTexCoord) * fragColor;
+
+ // Convert the (normalized) texel color RED component (GB would work, too)
+ // to the palette index by scaling up from [0, 1] to [0, 255].
+ int index = int(texelColor.r * 255.0);
+ ivec3 color = palette[index];
+
+ // Calculate final fragment color. Note that the palette color components
+ // are defined in the range [0, 255] and need to be normalized to [0, 1]
+ // for OpenGL to work.
+ gl_FragColor = vec4(color / 255.0, texelColor.a);
+}
diff --git a/examples/shaders/resources/shaders/glsl100/raymarching.fs b/examples/shaders/resources/shaders/glsl100/raymarching.fs
new file mode 100644
index 00000000..4ae71297
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl100/raymarching.fs
@@ -0,0 +1,431 @@
+#version 100
+
+precision mediump float;
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+uniform vec3 viewEye;
+uniform vec3 viewCenter;
+uniform vec3 viewUp;
+uniform float deltaTime;
+uniform float runTime;
+uniform vec2 resolution;
+
+// The MIT License
+// Copyright © 2013 Inigo Quilez
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+// A list of useful distance function to simple primitives, and an example on how to
+// do some interesting boolean operations, repetition and displacement.
+//
+// More info here: http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
+
+#define AA 1 // make this 1 is your machine is too slow
+
+//------------------------------------------------------------------
+
+float sdPlane( vec3 p )
+{
+ return p.y;
+}
+
+float sdSphere( vec3 p, float s )
+{
+ return length(p)-s;
+}
+
+float sdBox( vec3 p, vec3 b )
+{
+ vec3 d = abs(p) - b;
+ return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));
+}
+
+float sdEllipsoid( in vec3 p, in vec3 r )
+{
+ return (length( p/r ) - 1.0) * min(min(r.x,r.y),r.z);
+}
+
+float udRoundBox( vec3 p, vec3 b, float r )
+{
+ return length(max(abs(p)-b,0.0))-r;
+}
+
+float sdTorus( vec3 p, vec2 t )
+{
+ return length( vec2(length(p.xz)-t.x,p.y) )-t.y;
+}
+
+float sdHexPrism( vec3 p, vec2 h )
+{
+ vec3 q = abs(p);
+#if 0
+ return max(q.z-h.y,max((q.x*0.866025+q.y*0.5),q.y)-h.x);
+#else
+ float d1 = q.z-h.y;
+ float d2 = max((q.x*0.866025+q.y*0.5),q.y)-h.x;
+ return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
+#endif
+}
+
+float sdCapsule( vec3 p, vec3 a, vec3 b, float r )
+{
+ vec3 pa = p-a, ba = b-a;
+ float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
+ return length( pa - ba*h ) - r;
+}
+
+float sdEquilateralTriangle( in vec2 p )
+{
+ const float k = sqrt(3.0);
+ p.x = abs(p.x) - 1.0;
+ p.y = p.y + 1.0/k;
+ if( p.x + k*p.y > 0.0 ) p = vec2( p.x - k*p.y, -k*p.x - p.y )/2.0;
+ p.x += 2.0 - 2.0*clamp( (p.x+2.0)/2.0, 0.0, 1.0 );
+ return -length(p)*sign(p.y);
+}
+
+float sdTriPrism( vec3 p, vec2 h )
+{
+ vec3 q = abs(p);
+ float d1 = q.z-h.y;
+#if 1
+ // distance bound
+ float d2 = max(q.x*0.866025+p.y*0.5,-p.y)-h.x*0.5;
+#else
+ // correct distance
+ h.x *= 0.866025;
+ float d2 = sdEquilateralTriangle(p.xy/h.x)*h.x;
+#endif
+ return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
+}
+
+float sdCylinder( vec3 p, vec2 h )
+{
+ vec2 d = abs(vec2(length(p.xz),p.y)) - h;
+ return min(max(d.x,d.y),0.0) + length(max(d,0.0));
+}
+
+float sdCone( in vec3 p, in vec3 c )
+{
+ vec2 q = vec2( length(p.xz), p.y );
+ float d1 = -q.y-c.z;
+ float d2 = max( dot(q,c.xy), q.y);
+ return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
+}
+
+float sdConeSection( in vec3 p, in float h, in float r1, in float r2 )
+{
+ float d1 = -p.y - h;
+ float q = p.y - h;
+ float si = 0.5*(r1-r2)/h;
+ float d2 = max( sqrt( dot(p.xz,p.xz)*(1.0-si*si)) + q*si - r2, q );
+ return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
+}
+
+float sdPryamid4(vec3 p, vec3 h ) // h = { cos a, sin a, height }
+{
+ // Tetrahedron = Octahedron - Cube
+ float box = sdBox( p - vec3(0,-2.0*h.z,0), vec3(2.0*h.z) );
+
+ float d = 0.0;
+ d = max( d, abs( dot(p, vec3( -h.x, h.y, 0 )) ));
+ d = max( d, abs( dot(p, vec3( h.x, h.y, 0 )) ));
+ d = max( d, abs( dot(p, vec3( 0, h.y, h.x )) ));
+ d = max( d, abs( dot(p, vec3( 0, h.y,-h.x )) ));
+ float octa = d - h.z;
+ return max(-box,octa); // Subtraction
+ }
+
+float length2( vec2 p )
+{
+ return sqrt( p.x*p.x + p.y*p.y );
+}
+
+float length6( vec2 p )
+{
+ p = p*p*p; p = p*p;
+ return pow( p.x + p.y, 1.0/6.0 );
+}
+
+float length8( vec2 p )
+{
+ p = p*p; p = p*p; p = p*p;
+ return pow( p.x + p.y, 1.0/8.0 );
+}
+
+float sdTorus82( vec3 p, vec2 t )
+{
+ vec2 q = vec2(length2(p.xz)-t.x,p.y);
+ return length8(q)-t.y;
+}
+
+float sdTorus88( vec3 p, vec2 t )
+{
+ vec2 q = vec2(length8(p.xz)-t.x,p.y);
+ return length8(q)-t.y;
+}
+
+float sdCylinder6( vec3 p, vec2 h )
+{
+ return max( length6(p.xz)-h.x, abs(p.y)-h.y );
+}
+
+//------------------------------------------------------------------
+
+float opS( float d1, float d2 )
+{
+ return max(-d2,d1);
+}
+
+vec2 opU( vec2 d1, vec2 d2 )
+{
+ return (d1.x<d2.x) ? d1 : d2;
+}
+
+vec3 opRep( vec3 p, vec3 c )
+{
+ return mod(p,c)-0.5*c;
+}
+
+vec3 opTwist( vec3 p )
+{
+ float c = cos(10.0*p.y+10.0);
+ float s = sin(10.0*p.y+10.0);
+ mat2 m = mat2(c,-s,s,c);
+ return vec3(m*p.xz,p.y);
+}
+
+//------------------------------------------------------------------
+
+vec2 map( in vec3 pos )
+{
+ vec2 res = opU( vec2( sdPlane( pos), 1.0 ),
+ vec2( sdSphere( pos-vec3( 0.0,0.25, 0.0), 0.25 ), 46.9 ) );
+ res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.25) ), 3.0 ) );
+ res = opU( res, vec2( udRoundBox( pos-vec3( 1.0,0.25, 1.0), vec3(0.15), 0.1 ), 41.0 ) );
+ res = opU( res, vec2( sdTorus( pos-vec3( 0.0,0.25, 1.0), vec2(0.20,0.05) ), 25.0 ) );
+ res = opU( res, vec2( sdCapsule( pos,vec3(-1.3,0.10,-0.1), vec3(-0.8,0.50,0.2), 0.1 ), 31.9 ) );
+ res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.25,-1.0), vec2(0.25,0.05) ),43.5 ) );
+ res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.30,-1.0), vec2(0.1,0.2) ), 8.0 ) );
+ res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.50,-1.0), vec3(0.8,0.6,0.3) ), 55.0 ) );
+ res = opU( res, vec2( sdTorus82( pos-vec3( 0.0,0.25, 2.0), vec2(0.20,0.05) ),50.0 ) );
+ res = opU( res, vec2( sdTorus88( pos-vec3(-1.0,0.25, 2.0), vec2(0.20,0.05) ),43.0 ) );
+ res = opU( res, vec2( sdCylinder6( pos-vec3( 1.0,0.30, 2.0), vec2(0.1,0.2) ), 12.0 ) );
+ res = opU( res, vec2( sdHexPrism( pos-vec3(-1.0,0.20, 1.0), vec2(0.25,0.05) ),17.0 ) );
+ res = opU( res, vec2( sdPryamid4( pos-vec3(-1.0,0.15,-2.0), vec3(0.8,0.6,0.25) ),37.0 ) );
+ res = opU( res, vec2( opS( udRoundBox( pos-vec3(-2.0,0.2, 1.0), vec3(0.15),0.05),
+ sdSphere( pos-vec3(-2.0,0.2, 1.0), 0.25)), 13.0 ) );
+ res = opU( res, vec2( opS( sdTorus82( pos-vec3(-2.0,0.2, 0.0), vec2(0.20,0.1)),
+ sdCylinder( opRep( vec3(atan(pos.x+2.0,pos.z)/6.2831, pos.y, 0.02+0.5*length(pos-vec3(-2.0,0.2, 0.0))), vec3(0.05,1.0,0.05)), vec2(0.02,0.6))), 51.0 ) );
+ res = opU( res, vec2( 0.5*sdSphere( pos-vec3(-2.0,0.25,-1.0), 0.2 ) + 0.03*sin(50.0*pos.x)*sin(50.0*pos.y)*sin(50.0*pos.z), 65.0 ) );
+ res = opU( res, vec2( 0.5*sdTorus( opTwist(pos-vec3(-2.0,0.25, 2.0)),vec2(0.20,0.05)), 46.7 ) );
+ res = opU( res, vec2( sdConeSection( pos-vec3( 0.0,0.35,-2.0), 0.15, 0.2, 0.1 ), 13.67 ) );
+ res = opU( res, vec2( sdEllipsoid( pos-vec3( 1.0,0.35,-2.0), vec3(0.15, 0.2, 0.05) ), 43.17 ) );
+
+ return res;
+}
+
+vec2 castRay( in vec3 ro, in vec3 rd )
+{
+ float tmin = 0.2;
+ float tmax = 30.0;
+
+#if 1
+ // bounding volume
+ float tp1 = (0.0-ro.y)/rd.y; if( tp1>0.0 ) tmax = min( tmax, tp1 );
+ float tp2 = (1.6-ro.y)/rd.y; if( tp2>0.0 ) { if( ro.y>1.6 ) tmin = max( tmin, tp2 );
+ else tmax = min( tmax, tp2 ); }
+#endif
+
+ float t = tmin;
+ float m = -1.0;
+ for( int i=0; i<64; i++ )
+ {
+ float precis = 0.0005*t;
+ vec2 res = map( ro+rd*t );
+ if( res.x<precis || t>tmax ) break;
+ t += res.x;
+ m = res.y;
+ }
+
+ if( t>tmax ) m=-1.0;
+ return vec2( t, m );
+}
+
+
+float calcSoftshadow( in vec3 ro, in vec3 rd, in float mint, in float tmax )
+{
+ float res = 1.0;
+ float t = mint;
+ for( int i=0; i<16; i++ )
+ {
+ float h = map( ro + rd*t ).x;
+ res = min( res, 8.0*h/t );
+ t += clamp( h, 0.02, 0.10 );
+ if( h<0.001 || t>tmax ) break;
+ }
+ return clamp( res, 0.0, 1.0 );
+}
+
+vec3 calcNormal( in vec3 pos )
+{
+ vec2 e = vec2(1.0,-1.0)*0.5773*0.0005;
+ return normalize( e.xyy*map( pos + e.xyy ).x +
+ e.yyx*map( pos + e.yyx ).x +
+ e.yxy*map( pos + e.yxy ).x +
+ e.xxx*map( pos + e.xxx ).x );
+ /*
+ vec3 eps = vec3( 0.0005, 0.0, 0.0 );
+ vec3 nor = vec3(
+ map(pos+eps.xyy).x - map(pos-eps.xyy).x,
+ map(pos+eps.yxy).x - map(pos-eps.yxy).x,
+ map(pos+eps.yyx).x - map(pos-eps.yyx).x );
+ return normalize(nor);
+ */
+}
+
+float calcAO( in vec3 pos, in vec3 nor )
+{
+ float occ = 0.0;
+ float sca = 1.0;
+ for( int i=0; i<5; i++ )
+ {
+ float hr = 0.01 + 0.12*float(i)/4.0;
+ vec3 aopos = nor * hr + pos;
+ float dd = map( aopos ).x;
+ occ += -(dd-hr)*sca;
+ sca *= 0.95;
+ }
+ return clamp( 1.0 - 3.0*occ, 0.0, 1.0 );
+}
+
+// http://iquilezles.org/www/articles/checkerfiltering/checkerfiltering.htm
+float checkersGradBox( in vec2 p )
+{
+ // filter kernel
+ vec2 w = fwidth(p) + 0.001;
+ // analytical integral (box filter)
+ vec2 i = 2.0*(abs(fract((p-0.5*w)*0.5)-0.5)-abs(fract((p+0.5*w)*0.5)-0.5))/w;
+ // xor pattern
+ return 0.5 - 0.5*i.x*i.y;
+}
+
+vec3 render( in vec3 ro, in vec3 rd )
+{
+ vec3 col = vec3(0.7, 0.9, 1.0) +rd.y*0.8;
+ vec2 res = castRay(ro,rd);
+ float t = res.x;
+ float m = res.y;
+ if( m>-0.5 )
+ {
+ vec3 pos = ro + t*rd;
+ vec3 nor = calcNormal( pos );
+ vec3 ref = reflect( rd, nor );
+
+ // material
+ col = 0.45 + 0.35*sin( vec3(0.05,0.08,0.10)*(m-1.0) );
+ if( m<1.5 )
+ {
+
+ float f = checkersGradBox( 5.0*pos.xz );
+ col = 0.3 + f*vec3(0.1);
+ }
+
+ // lighting
+ float occ = calcAO( pos, nor );
+ vec3 lig = normalize( vec3(cos(-0.4 * runTime), sin(0.7 * runTime), -0.6) );
+ vec3 hal = normalize( lig-rd );
+ float amb = clamp( 0.5+0.5*nor.y, 0.0, 1.0 );
+ float dif = clamp( dot( nor, lig ), 0.0, 1.0 );
+ float bac = clamp( dot( nor, normalize(vec3(-lig.x,0.0,-lig.z))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0);
+ float dom = smoothstep( -0.1, 0.1, ref.y );
+ float fre = pow( clamp(1.0+dot(nor,rd),0.0,1.0), 2.0 );
+
+ dif *= calcSoftshadow( pos, lig, 0.02, 2.5 );
+ dom *= calcSoftshadow( pos, ref, 0.02, 2.5 );
+
+ float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0)*
+ dif *
+ (0.04 + 0.96*pow( clamp(1.0+dot(hal,rd),0.0,1.0), 5.0 ));
+
+ vec3 lin = vec3(0.0);
+ lin += 1.30*dif*vec3(1.00,0.80,0.55);
+ lin += 0.40*amb*vec3(0.40,0.60,1.00)*occ;
+ lin += 0.50*dom*vec3(0.40,0.60,1.00)*occ;
+ lin += 0.50*bac*vec3(0.25,0.25,0.25)*occ;
+ lin += 0.25*fre*vec3(1.00,1.00,1.00)*occ;
+ col = col*lin;
+ col += 10.00*spe*vec3(1.00,0.90,0.70);
+
+ col = mix( col, vec3(0.8,0.9,1.0), 1.0-exp( -0.0002*t*t*t ) );
+ }
+
+ return vec3( clamp(col,0.0,1.0) );
+}
+
+mat3 setCamera( in vec3 ro, in vec3 ta, float cr )
+{
+ vec3 cw = normalize(ta-ro);
+ vec3 cp = vec3(sin(cr), cos(cr),0.0);
+ vec3 cu = normalize( cross(cw,cp) );
+ vec3 cv = normalize( cross(cu,cw) );
+ return mat3( cu, cv, cw );
+}
+
+void main()
+{
+ vec3 tot = vec3(0.0);
+#if AA>1
+ for( int m=0; m<AA; m++ )
+ for( int n=0; n<AA; n++ )
+ {
+ // pixel coordinates
+ vec2 o = vec2(float(m),float(n)) / float(AA) - 0.5;
+ vec2 p = (-resolution.xy + 2.0*(gl_FragCoord.xy+o))/resolution.y;
+#else
+ vec2 p = (-resolution.xy + 2.0*gl_FragCoord.xy)/resolution.y;
+#endif
+
+ // RAY: Camera is provided from raylib
+ //vec3 ro = vec3( -0.5+3.5*cos(0.1*time + 6.0*mo.x), 1.0 + 2.0*mo.y, 0.5 + 4.0*sin(0.1*time + 6.0*mo.x) );
+
+ vec3 ro = viewEye;
+ vec3 ta = viewCenter;
+
+ // camera-to-world transformation
+ mat3 ca = setCamera( ro, ta, 0.0 );
+ // ray direction
+ vec3 rd = ca * normalize( vec3(p.xy,2.0) );
+
+ // render
+ vec3 col = render( ro, rd );
+
+ // gamma
+ col = pow( col, vec3(0.4545) );
+
+ tot += col;
+#if AA>1
+ }
+ tot /= float(AA*AA);
+#endif
+
+ gl_FragColor = vec4( tot, 1.0 );
+} \ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl100/wave.fs b/examples/shaders/resources/shaders/glsl100/wave.fs
new file mode 100644
index 00000000..bcc156cc
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl100/wave.fs
@@ -0,0 +1,36 @@
+#version 100
+
+precision mediump float;
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+uniform float secondes;
+
+uniform vec2 size;
+
+uniform float freqX;
+uniform float freqY;
+uniform float ampX;
+uniform float ampY;
+uniform float speedX;
+uniform float speedY;
+
+void main() {
+ float pixelWidth = 1.0 / size.x;
+ float pixelHeight = 1.0 / size.y;
+ float aspect = pixelHeight / pixelWidth;
+ float boxLeft = 0.0;
+ float boxTop = 0.0;
+
+ vec2 p = fragTexCoord;
+ p.x += cos((fragTexCoord.y - boxTop) * freqX / ( pixelWidth * 750.0) + (secondes * speedX)) * ampX * pixelWidth;
+ p.y += sin((fragTexCoord.x - boxLeft) * freqY * aspect / ( pixelHeight * 750.0) + (secondes * speedY)) * ampY * pixelHeight;
+
+ gl_FragColor = texture2D(texture0, p)*colDiffuse*fragColor;
+}
diff --git a/examples/shaders/resources/shaders/glsl120/palette-switch.fs b/examples/shaders/resources/shaders/glsl120/palette_switch.fs
index b4384502..ab3f79c7 100644
--- a/examples/shaders/resources/shaders/glsl120/palette-switch.fs
+++ b/examples/shaders/resources/shaders/glsl120/palette_switch.fs
@@ -1,27 +1,27 @@
-#version 120
-
-const int colors = 8;
-
-// Input fragment attributes (from fragment shader)
-varying vec2 fragTexCoord;
-varying vec4 fragColor;
-
-// Input uniform values
-uniform sampler2D texture0;
-uniform ivec3 palette[colors];
-
-void main()
-{
- // Texel color fetching from texture sampler
- vec4 texelColor = texture(texture0, fragTexCoord) * fragColor;
-
- // Convert the (normalized) texel color RED component (GB would work, too)
- // to the palette index by scaling up from [0, 1] to [0, 255].
- int index = int(texelColor.r * 255.0);
- ivec3 color = palette[index];
-
- // Calculate final fragment color. Note that the palette color components
- // are defined in the range [0, 255] and need to be normalized to [0, 1]
- // for OpenGL to work.
- gl_FragColor = vec4(color / 255.0, texelColor.a);
-}
+#version 120
+
+const int colors = 8;
+
+// Input fragment attributes (from fragment shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform ivec3 palette[colors];
+
+void main()
+{
+ // Texel color fetching from texture sampler
+ vec4 texelColor = texture(texture0, fragTexCoord) * fragColor;
+
+ // Convert the (normalized) texel color RED component (GB would work, too)
+ // to the palette index by scaling up from [0, 1] to [0, 255].
+ int index = int(texelColor.r * 255.0);
+ ivec3 color = palette[index];
+
+ // Calculate final fragment color. Note that the palette color components
+ // are defined in the range [0, 255] and need to be normalized to [0, 1]
+ // for OpenGL to work.
+ gl_FragColor = vec4(color / 255.0, texelColor.a);
+}
diff --git a/examples/shaders/resources/shaders/glsl330/cubes_panning.fs b/examples/shaders/resources/shaders/glsl330/cubes_panning.fs
new file mode 100644
index 00000000..c92418a4
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl330/cubes_panning.fs
@@ -0,0 +1,61 @@
+#version 330
+
+// Input vertex attributes (from vertex shader)
+in vec2 fragTexCoord;
+in vec4 fragColor;
+
+// Output fragment color
+out vec4 finalColor;
+
+// Custom variables
+#define PI 3.14159265358979323846
+uniform float uTime = 0.0;
+
+float divisions = 5.0;
+float angle = 0.0;
+
+vec2 VectorRotateTime(vec2 v, float speed)
+{
+ float time = uTime*speed;
+ float localTime = fract(time); // The time domain this works on is 1 sec.
+
+ if ((localTime >= 0.0) && (localTime < 0.25)) angle = 0.0;
+ else if ((localTime >= 0.25) && (localTime < 0.50)) angle = PI/4*sin(2*PI*localTime - PI/2);
+ else if ((localTime >= 0.50) && (localTime < 0.75)) angle = PI*0.25;
+ else if ((localTime >= 0.75) && (localTime < 1.00)) angle = PI/4*sin(2*PI*localTime);
+
+ // Rotate vector by angle
+ v -= 0.5;
+ v = mat2(cos(angle), -sin(angle), sin(angle), cos(angle))*v;
+ v += 0.5;
+
+ return v;
+}
+
+float Rectangle(in vec2 st, in float size, in float fill)
+{
+ float roundSize = 0.5 - size/2.0;
+ float left = step(roundSize, st.x);
+ float top = step(roundSize, st.y);
+ float bottom = step(roundSize, 1.0 - st.y);
+ float right = step(roundSize, 1.0 - st.x);
+
+ return (left*bottom*right*top)*fill;
+}
+
+void main()
+{
+ vec2 fragPos = fragTexCoord;
+ fragPos.xy += uTime/9.0;
+
+ fragPos *= divisions;
+ vec2 ipos = floor(fragPos); // Get the integer coords
+ vec2 fpos = fract(fragPos); // Get the fractional coords
+
+ fpos = VectorRotateTime(fpos, 0.2);
+
+ float alpha = Rectangle(fpos, 0.216, 1.0);
+ vec3 color = vec3(0.3, 0.3, 0.3);
+
+ finalColor = vec4(color, alpha);
+} \ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl330/eratosthenes.fs b/examples/shaders/resources/shaders/glsl330/eratosthenes.fs
new file mode 100644
index 00000000..a6390b74
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl330/eratosthenes.fs
@@ -0,0 +1,59 @@
+#version 330
+
+/*************************************************************************************
+
+ The Sieve of Eratosthenes -- a simple shader by ProfJski
+ An early prime number sieve: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
+
+ The screen is divided into a square grid of boxes, each representing an integer value.
+ Each integer is tested to see if it is a prime number. Primes are colored white.
+ Non-primes are colored with a color that indicates the smallest factor which evenly divdes our integer.
+
+ You can change the scale variable to make a larger or smaller grid.
+ Total number of integers displayed = scale squared, so scale = 100 tests the first 10,000 integers.
+
+ WARNING: If you make scale too large, your GPU may bog down!
+
+***************************************************************************************/
+
+// Input vertex attributes (from vertex shader)
+in vec2 fragTexCoord;
+in vec4 fragColor;
+
+// Output fragment color
+out vec4 finalColor;
+
+// Make a nice spectrum of colors based on counter and maxSize
+vec4 Colorizer(float counter, float maxSize)
+{
+ float red = 0.0, green = 0.0, blue = 0.0;
+ float normsize = counter/maxSize;
+
+ red = smoothstep(0.3, 0.7, normsize);
+ green = sin(3.14159*normsize);
+ blue = 1.0 - smoothstep(0.0, 0.4, normsize);
+
+ return vec4(0.8*red, 0.8*green, 0.8*blue, 1.0);
+}
+
+void main()
+{
+ vec4 color = vec4(1.0);
+ float scale = 1000.0; // Makes 100x100 square grid. Change this variable to make a smaller or larger grid.
+ int value = int(scale*floor(fragTexCoord.y*scale)+floor(fragTexCoord.x*scale)); // Group pixels into boxes representing integer values
+
+ if ((value == 0) || (value == 1) || (value == 2)) finalColor = vec4(1.0);
+ else
+ {
+ for (int i = 2; (i < max(2, sqrt(value) + 1)); i++)
+ {
+ if ((value - i*floor(value/i)) == 0)
+ {
+ color = Colorizer(float(i), scale);
+ //break; // Uncomment to color by the largest factor instead
+ }
+ }
+
+ finalColor = color;
+ }
+}
diff --git a/examples/shaders/resources/shaders/glsl330/julia_set.fs b/examples/shaders/resources/shaders/glsl330/julia_set.fs
new file mode 100644
index 00000000..f68367ea
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl330/julia_set.fs
@@ -0,0 +1,81 @@
+#version 330
+
+// Input vertex attributes (from vertex shader)
+in vec2 fragTexCoord;
+in vec4 fragColor;
+
+// Output fragment color
+out vec4 finalColor;
+
+uniform vec2 screenDims; // Dimensions of the screen
+uniform vec2 c; // c.x = real, c.y = imaginary component. Equation done is z^2 + c
+uniform vec2 offset; // Offset of the scale.
+uniform float zoom; // Zoom of the scale.
+
+const int MAX_ITERATIONS = 255; // Max iterations to do.
+
+// Square a complex number
+vec2 ComplexSquare(vec2 z)
+{
+ return vec2(
+ z.x * z.x - z.y * z.y,
+ z.x * z.y * 2.0
+ );
+}
+
+// Convert Hue Saturation Value (HSV) color into RGB
+vec3 Hsv2rgb(vec3 c)
+{
+ vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
+ vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
+ return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
+}
+
+void main()
+{
+ /**********************************************************************************************
+ Julia sets use a function z^2 + c, where c is a constant.
+ This function is iterated until the nature of the point is determined.
+
+ If the magnitude of the number becomes greater than 2, then from that point onward
+ the number will get bigger and bigger, and will never get smaller (tends towards infinity).
+ 2^2 = 4, 4^2 = 8 and so on.
+ So at 2 we stop iterating.
+
+ If the number is below 2, we keep iterating.
+ But when do we stop iterating if the number is always below 2 (it converges)?
+ That is what MAX_ITERATIONS is for.
+ Then we can divide the iterations by the MAX_ITERATIONS value to get a normalized value that we can
+ then map to a color.
+
+ We use dot product (z.x * z.x + z.y * z.y) to determine the magnitude (length) squared.
+ And once the magnitude squared is > 4, then magnitude > 2 is also true (saves computational power).
+ *************************************************************************************************/
+
+ // The pixel coordinates are scaled so they are on the mandelbrot scale
+ // NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom
+ vec2 z = vec2((fragTexCoord.x + offset.x/screenDims.x)*2.5/zoom, (fragTexCoord.y + offset.y/screenDims.y)*1.5/zoom);
+
+ int iterations = 0;
+ for (iterations = 0; iterations < MAX_ITERATIONS; iterations++)
+ {
+ z = ComplexSquare(z) + c; // Iterate function
+
+ if (dot(z, z) > 4.0) break;
+ }
+
+ // Another few iterations decreases errors in the smoothing calculation.
+ // See http://linas.org/art-gallery/escape/escape.html for more information.
+ z = ComplexSquare(z) + c;
+ z = ComplexSquare(z) + c;
+
+ // This last part smooths the color (again see link above).
+ float smoothVal = float(iterations) + 1.0 - (log(log(length(z)))/log(2.0));
+
+ // Normalize the value so it is between 0 and 1.
+ float norm = smoothVal/float(MAX_ITERATIONS);
+
+ // If in set, color black. 0.999 allows for some float accuracy error.
+ if (norm > 0.999) finalColor = vec4(0.0, 0.0, 0.0, 1.0);
+ else finalColor = vec4(Hsv2rgb(vec3(norm, 1.0, 1.0)), 1.0);
+}
diff --git a/examples/shaders/resources/shaders/glsl330/palette-switch.fs b/examples/shaders/resources/shaders/glsl330/palette_switch.fs
index 61b532ed..7c8a488c 100644
--- a/examples/shaders/resources/shaders/glsl330/palette-switch.fs
+++ b/examples/shaders/resources/shaders/glsl330/palette_switch.fs
@@ -1,30 +1,30 @@
-#version 330
-
-const int colors = 8;
-
-// Input fragment attributes (from fragment shader)
-in vec2 fragTexCoord;
-in vec4 fragColor;
-
-// Input uniform values
-uniform sampler2D texture0;
-uniform ivec3 palette[colors];
-
-// Output fragment color
-out vec4 finalColor;
-
-void main()
-{
- // Texel color fetching from texture sampler
- vec4 texelColor = texture(texture0, fragTexCoord)*fragColor;
-
- // Convert the (normalized) texel color RED component (GB would work, too)
- // to the palette index by scaling up from [0, 1] to [0, 255].
- int index = int(texelColor.r * 255.0);
- ivec3 color = palette[index];
-
- // Calculate final fragment color. Note that the palette color components
- // are defined in the range [0, 255] and need to be normalized to [0, 1]
- // for OpenGL to work.
- finalColor = vec4(color / 255.0, texelColor.a);
-}
+#version 330
+
+const int colors = 8;
+
+// Input fragment attributes (from fragment shader)
+in vec2 fragTexCoord;
+in vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform ivec3 palette[colors];
+
+// Output fragment color
+out vec4 finalColor;
+
+void main()
+{
+ // Texel color fetching from texture sampler
+ vec4 texelColor = texture(texture0, fragTexCoord)*fragColor;
+
+ // Convert the (normalized) texel color RED component (GB would work, too)
+ // to the palette index by scaling up from [0, 1] to [0, 255].
+ int index = int(texelColor.r*255.0);
+ ivec3 color = palette[index];
+
+ // Calculate final fragment color. Note that the palette color components
+ // are defined in the range [0, 255] and need to be normalized to [0, 1]
+ // for OpenGL to work.
+ finalColor = vec4(color/255.0, texelColor.a);
+}
diff --git a/examples/shaders/resources/shaders/glsl330/raymarching.fs b/examples/shaders/resources/shaders/glsl330/raymarching.fs
index 5ec9a02a..7c9fbcb1 100644
--- a/examples/shaders/resources/shaders/glsl330/raymarching.fs
+++ b/examples/shaders/resources/shaders/glsl330/raymarching.fs
@@ -1,5 +1,10 @@
#version 330
+// Input vertex attributes (from vertex shader)
+in vec2 fragTexCoord;
+in vec4 fragColor;
+
+// Output fragment color
out vec4 finalColor;
uniform vec3 viewEye;
@@ -11,7 +16,23 @@ uniform vec2 resolution;
// The MIT License
// Copyright © 2013 Inigo Quilez
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
// A list of useful distance function to simple primitives, and an example on how to
// do some interesting boolean operations, repetition and displacement.
diff --git a/examples/shaders/resources/shaders/glsl330/wave.fs b/examples/shaders/resources/shaders/glsl330/wave.fs
new file mode 100644
index 00000000..f139f395
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl330/wave.fs
@@ -0,0 +1,37 @@
+#version 330
+
+// Input vertex attributes (from vertex shader)
+in vec2 fragTexCoord;
+in vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// Output fragment color
+out vec4 finalColor;
+
+uniform float secondes;
+
+uniform vec2 size;
+
+uniform float freqX;
+uniform float freqY;
+uniform float ampX;
+uniform float ampY;
+uniform float speedX;
+uniform float speedY;
+
+void main() {
+ float pixelWidth = 1.0 / size.x;
+ float pixelHeight = 1.0 / size.y;
+ float aspect = pixelHeight / pixelWidth;
+ float boxLeft = 0.0;
+ float boxTop = 0.0;
+
+ vec2 p = fragTexCoord;
+ p.x += cos((fragTexCoord.y - boxTop) * freqX / ( pixelWidth * 750.0) + (secondes * speedX)) * ampX * pixelWidth;
+ p.y += sin((fragTexCoord.x - boxLeft) * freqY * aspect / ( pixelHeight * 750.0) + (secondes * speedY)) * ampY * pixelHeight;
+
+ finalColor = texture(texture0, p)*colDiffuse*fragColor;
+}
diff --git a/examples/shaders/resources/space.png b/examples/shaders/resources/space.png
new file mode 100644
index 00000000..41129739
--- /dev/null
+++ b/examples/shaders/resources/space.png
Binary files differ
diff --git a/examples/shaders/shaders_custom_uniform.c b/examples/shaders/shaders_custom_uniform.c
index fbfd82d0..1c82bba2 100644
--- a/examples/shaders/shaders_custom_uniform.c
+++ b/examples/shaders/shaders_custom_uniform.c
@@ -24,13 +24,13 @@
#define GLSL_VERSION 100
#endif
-int main()
+int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
- int screenWidth = 800;
- int screenHeight = 450;
-
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
SetConfigFlags(FLAG_MSAA_4X_HINT); // Enable Multi Sampling Anti Aliasing 4x (if available)
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - custom uniform variable");
@@ -45,23 +45,23 @@ int main()
Model model = LoadModel("resources/models/barracks.obj"); // Load OBJ model
Texture2D texture = LoadTexture("resources/models/barracks_diffuse.png"); // Load model texture (diffuse map)
- model.material.maps[MAP_DIFFUSE].texture = texture; // Set model diffuse texture
+ model.materials[0].maps[MAP_DIFFUSE].texture = texture; // Set model diffuse texture
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
-
+
// Load postprocessing shader
// NOTE: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader
Shader shader = LoadShader(0, FormatText("resources/shaders/glsl%i/swirl.fs", GLSL_VERSION));
-
+
// Get variable (uniform) location on the shader to connect with the program
// NOTE: If uniform variable could not be found in the shader, function returns -1
int swirlCenterLoc = GetShaderLocation(shader, "center");
-
+
float swirlCenter[2] = { (float)screenWidth/2, (float)screenHeight/2 };
-
+
// Create a RenderTexture2D to be used for render to texture
RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight);
-
+
// Setup orbital camera
SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode
@@ -80,7 +80,7 @@ int main()
// Send new value to the shader to be used on drawing
SetShaderValue(shader, swirlCenterLoc, swirlCenter, UNIFORM_VEC2);
-
+
UpdateCamera(&camera); // Update camera
//----------------------------------------------------------------------------------
@@ -89,9 +89,9 @@ int main()
BeginDrawing();
ClearBackground(RAYWHITE);
-
+
BeginTextureMode(target); // Enable drawing to texture
-
+
ClearBackground(RAYWHITE); // Clear texture background
BeginMode3D(camera); // Begin 3d mode drawing
@@ -101,21 +101,21 @@ int main()
DrawGrid(10, 1.0f); // Draw a grid
EndMode3D(); // End 3d mode drawing, returns to orthographic 2d mode
-
+
DrawText("TEXT DRAWN IN RENDER TEXTURE", 200, 10, 30, RED);
-
+
EndTextureMode(); // End drawing to texture (now we have a texture available for next passes)
-
+
BeginShaderMode(shader);
-
+
// NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
DrawTextureRec(target.texture, (Rectangle){ 0, 0, target.texture.width, -target.texture.height }, (Vector2){ 0, 0 }, WHITE);
-
+
EndShaderMode();
-
+
// Draw some 2d text over drawn texture
DrawText("(c) Barracks 3D model by Alberto Cano", screenWidth - 220, screenHeight - 20, 10, GRAY);
-
+
DrawFPS(10, 10);
EndDrawing();
diff --git a/examples/shaders/shaders_eratosthenes.c b/examples/shaders/shaders_eratosthenes.c
new file mode 100644
index 00000000..068fc26c
--- /dev/null
+++ b/examples/shaders/shaders_eratosthenes.c
@@ -0,0 +1,94 @@
+/*******************************************************************************************
+*
+* raylib [shaders] example - Sieve of Eratosthenes
+*
+* Sieve of Eratosthenes, the earliest known (ancient Greek) prime number sieve.
+*
+* "Sift the twos and sift the threes,
+* The Sieve of Eratosthenes.
+* When the multiples sublime,
+* the numbers that are left are prime."
+*
+* NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support,
+* OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version.
+*
+* NOTE: Shaders used in this example are #version 330 (OpenGL 3.3).
+*
+* This example has been created using raylib 2.5 (www.raylib.com)
+* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+* Example contributed by ProfJski and reviewed by Ramon Santamaria (@raysan5)
+*
+* Copyright (c) 2019 ProfJski and Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#if defined(PLATFORM_DESKTOP)
+ #define GLSL_VERSION 330
+#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
+ #define GLSL_VERSION 100
+#endif
+
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [shaders] example - Sieve of Eratosthenes");
+
+ RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight);
+
+ // Load Eratosthenes shader
+ // NOTE: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader
+ Shader shader = LoadShader(0, FormatText("resources/shaders/glsl%i/eratosthenes.fs", GLSL_VERSION));
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ // Nothing to do here, everything is happening in the shader
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ BeginTextureMode(target); // Enable drawing to texture
+ ClearBackground(BLACK); // Clear the render texture
+
+ // Draw a rectangle in shader mode to be used as shader canvas
+ // NOTE: Rectangle uses font white character texture coordinates,
+ // so shader can not be applied here directly because input vertexTexCoord
+ // do not represent full screen coordinates (space where want to apply shader)
+ DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), BLACK);
+ EndTextureMode(); // End drawing to texture (now we have a blank texture available for the shader)
+
+ BeginShaderMode(shader);
+ // NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
+ DrawTextureRec(target.texture, (Rectangle){ 0, 0, target.texture.width, -target.texture.height }, (Vector2){ 0.0f, 0.0f }, WHITE);
+ EndShaderMode();
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadShader(shader); // Unload shader
+ UnloadRenderTexture(target); // Unload texture
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
diff --git a/examples/shaders/shaders_eratosthenes.png b/examples/shaders/shaders_eratosthenes.png
new file mode 100644
index 00000000..acd7fc75
--- /dev/null
+++ b/examples/shaders/shaders_eratosthenes.png
Binary files differ
diff --git a/examples/shaders/shaders_julia_set.c b/examples/shaders/shaders_julia_set.c
new file mode 100644
index 00000000..e64b622b
--- /dev/null
+++ b/examples/shaders/shaders_julia_set.c
@@ -0,0 +1,190 @@
+/*******************************************************************************************
+*
+* raylib [shaders] example - julia sets
+*
+* NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support,
+* OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version.
+*
+* NOTE: Shaders used in this example are #version 330 (OpenGL 3.3).
+*
+* This example has been created using raylib 2.5 (www.raylib.com)
+* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+* Example contributed by eggmund (@eggmund) and reviewed by Ramon Santamaria (@raysan5)
+*
+* Copyright (c) 2019 eggmund (@eggmund) and Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#if defined(PLATFORM_DESKTOP)
+ #define GLSL_VERSION 330
+#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
+ #define GLSL_VERSION 100
+#endif
+
+// A few good julia sets
+const float POINTS_OF_INTEREST[6][2] =
+{
+ { -0.348827, 0.607167 },
+ { -0.786268, 0.169728 },
+ { -0.8, 0.156 },
+ { 0.285, 0.0 },
+ { -0.835, -0.2321 },
+ { -0.70176, -0.3842 },
+};
+
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [shaders] example - julia sets");
+
+ // Load julia set shader
+ // NOTE: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader
+ Shader shader = LoadShader(0, FormatText("resources/shaders/glsl%i/julia_set.fs", GLSL_VERSION));
+
+ // c constant to use in z^2 + c
+ float c[2] = { POINTS_OF_INTEREST[0][0], POINTS_OF_INTEREST[0][1] };
+
+ // Offset and zoom to draw the julia set at. (centered on screen and default size)
+ float offset[2] = { -(float)screenWidth/2, -(float)screenHeight/2 };
+ float zoom = 1.0f;
+
+ Vector2 offsetSpeed = { 0.0f, 0.0f };
+
+ // Get variable (uniform) locations on the shader to connect with the program
+ // NOTE: If uniform variable could not be found in the shader, function returns -1
+ int cLoc = GetShaderLocation(shader, "c");
+ int zoomLoc = GetShaderLocation(shader, "zoom");
+ int offsetLoc = GetShaderLocation(shader, "offset");
+
+ // Tell the shader what the screen dimensions, zoom, offset and c are
+ float screenDims[2] = { (float)screenWidth, (float)screenHeight };
+ SetShaderValue(shader, GetShaderLocation(shader, "screenDims"), screenDims, UNIFORM_VEC2);
+
+ SetShaderValue(shader, cLoc, c, UNIFORM_VEC2);
+ SetShaderValue(shader, zoomLoc, &zoom, UNIFORM_FLOAT);
+ SetShaderValue(shader, offsetLoc, offset, UNIFORM_VEC2);
+
+ // Create a RenderTexture2D to be used for render to texture
+ RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight);
+
+ int incrementSpeed = 0; // Multiplier of speed to change c value
+ bool showControls = true; // Show controls
+ bool pause = false; // Pause animation
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ // Press [1 - 6] to reset c to a point of interest
+ if (IsKeyPressed(KEY_ONE) ||
+ IsKeyPressed(KEY_TWO) ||
+ IsKeyPressed(KEY_THREE) ||
+ IsKeyPressed(KEY_FOUR) ||
+ IsKeyPressed(KEY_FIVE) ||
+ IsKeyPressed(KEY_SIX))
+ {
+ if (IsKeyPressed(KEY_ONE)) c[0] = POINTS_OF_INTEREST[0][0], c[1] = POINTS_OF_INTEREST[0][1];
+ else if (IsKeyPressed(KEY_TWO)) c[0] = POINTS_OF_INTEREST[1][0], c[1] = POINTS_OF_INTEREST[1][1];
+ else if (IsKeyPressed(KEY_THREE)) c[0] = POINTS_OF_INTEREST[2][0], c[1] = POINTS_OF_INTEREST[2][1];
+ else if (IsKeyPressed(KEY_FOUR)) c[0] = POINTS_OF_INTEREST[3][0], c[1] = POINTS_OF_INTEREST[3][1];
+ else if (IsKeyPressed(KEY_FIVE)) c[0] = POINTS_OF_INTEREST[4][0], c[1] = POINTS_OF_INTEREST[4][1];
+ else if (IsKeyPressed(KEY_SIX)) c[0] = POINTS_OF_INTEREST[5][0], c[1] = POINTS_OF_INTEREST[5][1];
+
+ SetShaderValue(shader, cLoc, c, UNIFORM_VEC2);
+ }
+
+ if (IsKeyPressed(KEY_SPACE)) pause = !pause; // Pause animation (c change)
+ if (IsKeyPressed(KEY_F1)) showControls = !showControls; // Toggle whether or not to show controls
+
+ if (!pause)
+ {
+ if (IsKeyPressed(KEY_RIGHT)) incrementSpeed++;
+ else if (IsKeyPressed(KEY_LEFT)) incrementSpeed--;
+
+ // TODO: The idea is to zoom and move around with mouse
+ // Probably offset movement should be proportional to zoom level
+ if (IsMouseButtonDown(MOUSE_LEFT_BUTTON) || IsMouseButtonDown(MOUSE_RIGHT_BUTTON))
+ {
+ if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) zoom += zoom*0.003f;
+ if (IsMouseButtonDown(MOUSE_RIGHT_BUTTON)) zoom -= zoom*0.003f;
+
+ Vector2 mousePos = GetMousePosition();
+
+ offsetSpeed.x = mousePos.x -(float)screenWidth/2;
+ offsetSpeed.y = mousePos.y -(float)screenHeight/2;
+
+ // Slowly move camera to targetOffset
+ offset[0] += GetFrameTime()*offsetSpeed.x*0.8f;
+ offset[1] += GetFrameTime()*offsetSpeed.y*0.8f;
+ }
+ else offsetSpeed = (Vector2){ 0.0f, 0.0f };
+
+ SetShaderValue(shader, zoomLoc, &zoom, UNIFORM_FLOAT);
+ SetShaderValue(shader, offsetLoc, offset, UNIFORM_VEC2);
+
+ // Increment c value with time
+ float amount = GetFrameTime()*incrementSpeed*0.0005f;
+ c[0] += amount;
+ c[1] += amount;
+
+ SetShaderValue(shader, cLoc, c, UNIFORM_VEC2);
+ }
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(BLACK); // Clear the screen of the previous frame.
+
+ // Using a render texture to draw Julia set
+ BeginTextureMode(target); // Enable drawing to texture
+ ClearBackground(BLACK); // Clear the render texture
+
+ // Draw a rectangle in shader mode to be used as shader canvas
+ // NOTE: Rectangle uses font white character texture coordinates,
+ // so shader can not be applied here directly because input vertexTexCoord
+ // do not represent full screen coordinates (space where want to apply shader)
+ DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), BLACK);
+ EndTextureMode();
+
+ // Draw the saved texture and rendered julia set with shader
+ // NOTE: We do not invert texture on Y, already considered inside shader
+ BeginShaderMode(shader);
+ DrawTexture(target.texture, 0, 0, WHITE);
+ EndShaderMode();
+
+ if (showControls)
+ {
+ DrawText("Press Mouse buttons right/left to zoom in/out and move", 10, 15, 10, RAYWHITE);
+ DrawText("Press KEY_F1 to toggle these controls", 10, 30, 10, RAYWHITE);
+ DrawText("Press KEYS [1 - 6] to change point of interest", 10, 45, 10, RAYWHITE);
+ DrawText("Press KEY_LEFT | KEY_RIGHT to change speed", 10, 60, 10, RAYWHITE);
+ DrawText("Press KEY_SPACE to pause movement animation", 10, 75, 10, RAYWHITE);
+ }
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadShader(shader); // Unload shader
+ UnloadRenderTexture(target); // Unload render texture
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
diff --git a/examples/shaders/shaders_julia_set.png b/examples/shaders/shaders_julia_set.png
new file mode 100644
index 00000000..b769c3f6
--- /dev/null
+++ b/examples/shaders/shaders_julia_set.png
Binary files differ
diff --git a/examples/shaders/shaders_model_shader.c b/examples/shaders/shaders_model_shader.c
index 6c64f0ef..8224a337 100644
--- a/examples/shaders/shaders_model_shader.c
+++ b/examples/shaders/shaders_model_shader.c
@@ -24,13 +24,13 @@
#define GLSL_VERSION 100
#endif
-int main()
+int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
- int screenWidth = 800;
- int screenHeight = 450;
-
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
SetConfigFlags(FLAG_MSAA_4X_HINT); // Enable Multi Sampling Anti Aliasing 4x (if available)
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - model shader");
@@ -45,16 +45,16 @@ int main()
Model model = LoadModel("resources/models/watermill.obj"); // Load OBJ model
Texture2D texture = LoadTexture("resources/models/watermill_diffuse.png"); // Load model texture
-
+
// Load shader for model
// NOTE: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader
Shader shader = LoadShader(0, FormatText("resources/shaders/glsl%i/grayscale.fs", GLSL_VERSION));
- model.material.shader = shader; // Set shader effect to 3d model
- model.material.maps[MAP_DIFFUSE].texture = texture; // Bind texture to model
-
+ model.materials[0].shader = shader; // Set shader effect to 3d model
+ model.materials[0].maps[MAP_DIFFUSE].texture = texture; // Bind texture to model
+
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
-
+
SetCameraMode(camera, CAMERA_FREE); // Set an orbital camera mode
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
@@ -81,11 +81,8 @@ int main()
DrawGrid(10, 1.0f); // Draw a grid
EndMode3D();
-
+
DrawText("(c) Watermill 3D model by Alberto Cano", screenWidth - 210, screenHeight - 20, 10, GRAY);
-
- DrawText(FormatText("Camera position: (%.2f, %.2f, %.2f)", camera.position.x, camera.position.y, camera.position.z), 600, 20, 10, BLACK);
- DrawText(FormatText("Camera target: (%.2f, %.2f, %.2f)", camera.target.x, camera.target.y, camera.target.z), 600, 40, 10, GRAY);
DrawFPS(10, 10);
diff --git a/examples/shaders/shaders_palette_switch.c b/examples/shaders/shaders_palette_switch.c
index d0b56190..6bc27827 100644
--- a/examples/shaders/shaders_palette_switch.c
+++ b/examples/shaders/shaders_palette_switch.c
@@ -12,7 +12,9 @@
* This example has been created using raylib 2.3 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
-* Copyright (c) 2019 Ramon Santamaria (@raysan5)
+* Example contributed by Marco Lizza (@MarcoLizza) and reviewed by Ramon Santamaria (@raysan5)
+*
+* Copyright (c) 2019 Marco Lizza (@MarcoLizza) and Ramon Santamaria (@raysan5)
*
********************************************************************************************/
@@ -29,7 +31,7 @@
#define VALUES_PER_COLOR 3
static const int palettes[MAX_PALETTES][COLORS_PER_PALETTE*VALUES_PER_COLOR] = {
- {
+ { // 3-BIT RGB
0, 0, 0,
255, 0, 0,
0, 255, 0,
@@ -39,7 +41,7 @@ static const int palettes[MAX_PALETTES][COLORS_PER_PALETTE*VALUES_PER_COLOR] = {
255, 255, 0,
255, 255, 255,
},
- {
+ { // AMMO-8 (GameBoy-like)
4, 12, 6,
17, 35, 24,
30, 58, 41,
@@ -49,7 +51,7 @@ static const int palettes[MAX_PALETTES][COLORS_PER_PALETTE*VALUES_PER_COLOR] = {
190, 220, 127,
238, 255, 204,
},
- {
+ { // RKBV (2-strip film)
21, 25, 26,
138, 76, 88,
217, 98, 117,
@@ -67,26 +69,26 @@ static const char *paletteText[] = {
"RKBV (2-strip film)"
};
-int main()
+int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
- int screenWidth = 800;
- int screenHeight = 450;
+ const int screenWidth = 800;
+ const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - color palette switch");
// Load shader to be used on some parts drawing
// NOTE 1: Using GLSL 330 shader version, on OpenGL ES 2.0 use GLSL 100 shader version
// NOTE 2: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader
- Shader shader = LoadShader(0, FormatText("resources/shaders/glsl%i/palette-switch.fs", GLSL_VERSION));
+ Shader shader = LoadShader(0, FormatText("resources/shaders/glsl%i/palette_switch.fs", GLSL_VERSION));
// Get variable (uniform) location on the shader to connect with the program
// NOTE: If uniform variable could not be found in the shader, function returns -1
int paletteLoc = GetShaderLocation(shader, "palette");
- // Initial index not set, will be automatically bounded below.
- int currentPalette = -1;
+ int currentPalette = 0;
+ int lineHeight = screenHeight/COLORS_PER_PALETTE;
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
@@ -96,21 +98,15 @@ int main()
{
// Update
//----------------------------------------------------------------------------------
- int paletteIndex = currentPalette;
- if (IsKeyPressed(KEY_RIGHT)) paletteIndex++;
- else if (IsKeyPressed(KEY_LEFT)) paletteIndex--;
+ if (IsKeyPressed(KEY_RIGHT)) currentPalette++;
+ else if (IsKeyPressed(KEY_LEFT)) currentPalette--;
- if (paletteIndex >= MAX_PALETTES) paletteIndex = 0;
- else if (paletteIndex < 0) paletteIndex = MAX_PALETTES - 1;
+ if (currentPalette >= MAX_PALETTES) currentPalette = 0;
+ else if (currentPalette < 0) currentPalette = MAX_PALETTES - 1;
// Send new value to the shader to be used on drawing.
- // Note that we are sending RGB triplets w/o the alpha channel *only* if the current
- // palette index has changed (in order to save performances).
- if (currentPalette != paletteIndex)
- {
- currentPalette = paletteIndex;
- SetShaderValueV(shader, paletteLoc, palettes[currentPalette], UNIFORM_IVEC3, COLORS_PER_PALETTE);
- }
+ // NOTE: We are sending RGB triplets w/o the alpha channel
+ SetShaderValueV(shader, paletteLoc, palettes[currentPalette], UNIFORM_IVEC3, COLORS_PER_PALETTE);
//----------------------------------------------------------------------------------
// Draw
@@ -121,32 +117,18 @@ int main()
BeginShaderMode(shader);
- // Draw horizontal screen-wide rectangles with increasing "palette index".
- // The used palette index is encoded in the RGB components of the pixel.
- int linesPerRectangle = screenHeight / COLORS_PER_PALETTE;
- int leftover = screenHeight % COLORS_PER_PALETTE;
- int y = 0;
-
- for (int i = 0; i < COLORS_PER_PALETTE; ++i)
+ for (int i = 0; i < COLORS_PER_PALETTE; i++)
{
- int height = linesPerRectangle;
-
- if (leftover > 0)
- {
- height += 1;
- leftover -= 1;
- }
-
- DrawRectangle(0, y, screenWidth, height, (Color){ i, i, i, 255 });
-
- y += height;
+ // Draw horizontal screen-wide rectangles with increasing "palette index"
+ // The used palette index is encoded in the RGB components of the pixel
+ DrawRectangle(0, lineHeight*i, GetScreenWidth(), lineHeight, (Color){ i, i, i, 255 });
}
EndShaderMode();
- DrawText("CURRENT PALETTE:", 10, 15, 20, RAYWHITE);
- DrawText(paletteText[currentPalette], 240, 15, 20, RED);
- DrawText("< >", 540, 10, 30, DARKBLUE);
+ DrawText("< >", 10, 10, 30, DARKBLUE);
+ DrawText("CURRENT PALETTE:", 60, 15, 20, RAYWHITE);
+ DrawText(paletteText[currentPalette], 300, 15, 20, RED);
DrawFPS(700, 15);
@@ -158,7 +140,7 @@ int main()
//--------------------------------------------------------------------------------------
UnloadShader(shader); // Unload shader
- CloseWindow(); // Close window and OpenGL context
+ CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
diff --git a/examples/shaders/shaders_palette_switch.png b/examples/shaders/shaders_palette_switch.png
new file mode 100644
index 00000000..7eb3eaf3
--- /dev/null
+++ b/examples/shaders/shaders_palette_switch.png
Binary files differ
diff --git a/examples/shaders/shaders_postprocessing.c b/examples/shaders/shaders_postprocessing.c
index f8483563..ed9da8bb 100644
--- a/examples/shaders/shaders_postprocessing.c
+++ b/examples/shaders/shaders_postprocessing.c
@@ -58,31 +58,31 @@ static const char *postproShaderText[] = {
//"FXAA"
};
-int main()
+int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
- int screenWidth = 800;
- int screenHeight = 450;
-
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
SetConfigFlags(FLAG_MSAA_4X_HINT); // Enable Multi Sampling Anti Aliasing 4x (if available)
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - postprocessing shader");
// Define the camera to look into our 3d world
- Camera camera = {{ 2.0f, 3.0f, 2.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 };
-
+ Camera camera = { { 2.0f, 3.0f, 2.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 };
+
Model model = LoadModel("resources/models/church.obj"); // Load OBJ model
Texture2D texture = LoadTexture("resources/models/church_diffuse.png"); // Load model texture (diffuse map)
- model.material.maps[MAP_DIFFUSE].texture = texture; // Set model diffuse texture
+ model.materials[0].maps[MAP_DIFFUSE].texture = texture; // Set model diffuse texture
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
-
+
// Load all postpro shaders
// NOTE 1: All postpro shader use the base vertex shader (DEFAULT_VERTEX_SHADER)
// NOTE 2: We load the correct shader depending on GLSL version
- Shader shaders[MAX_POSTPRO_SHADERS];
-
+ Shader shaders[MAX_POSTPRO_SHADERS] = { 0 };
+
// NOTE: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader
shaders[FX_GRAYSCALE] = LoadShader(0, FormatText("resources/shaders/glsl%i/grayscale.fs", GLSL_VERSION));
shaders[FX_POSTERIZATION] = LoadShader(0, FormatText("resources/shaders/glsl%i/posterization.fs", GLSL_VERSION));
@@ -96,12 +96,12 @@ int main()
shaders[FX_SOBEL] = LoadShader(0, FormatText("resources/shaders/glsl%i/sobel.fs", GLSL_VERSION));
shaders[FX_BLOOM] = LoadShader(0, FormatText("resources/shaders/glsl%i/bloom.fs", GLSL_VERSION));
shaders[FX_BLUR] = LoadShader(0, FormatText("resources/shaders/glsl%i/blur.fs", GLSL_VERSION));
-
+
int currentShader = FX_GRAYSCALE;
// Create a RenderTexture2D to be used for render to texture
RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight);
-
+
// Setup orbital camera
SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode
@@ -114,10 +114,10 @@ int main()
// Update
//----------------------------------------------------------------------------------
UpdateCamera(&camera); // Update camera
-
+
if (IsKeyPressed(KEY_RIGHT)) currentShader++;
else if (IsKeyPressed(KEY_LEFT)) currentShader--;
-
+
if (currentShader >= MAX_POSTPRO_SHADERS) currentShader = 0;
else if (currentShader < 0) currentShader = MAX_POSTPRO_SHADERS - 1;
//----------------------------------------------------------------------------------
@@ -129,7 +129,7 @@ int main()
ClearBackground(RAYWHITE);
BeginTextureMode(target); // Enable drawing to texture
-
+
ClearBackground(RAYWHITE); // Clear texture background
BeginMode3D(camera); // Begin 3d mode drawing
@@ -139,26 +139,26 @@ int main()
DrawGrid(10, 1.0f); // Draw a grid
EndMode3D(); // End 3d mode drawing, returns to orthographic 2d mode
-
+
EndTextureMode(); // End drawing to texture (now we have a texture available for next passes)
-
+
// Render previously generated texture using selected postpro shader
BeginShaderMode(shaders[currentShader]);
-
+
// NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
DrawTextureRec(target.texture, (Rectangle){ 0, 0, target.texture.width, -target.texture.height }, (Vector2){ 0, 0 }, WHITE);
-
+
EndShaderMode();
-
+
// Draw 2d shapes and text over drawn texture
DrawRectangle(0, 9, 580, 30, Fade(LIGHTGRAY, 0.7f));
-
+
DrawText("(c) Church 3D model by Alberto Cano", screenWidth - 200, screenHeight - 20, 10, GRAY);
-
+
DrawText("CURRENT POSTPRO SHADER:", 10, 15, 20, BLACK);
DrawText(postproShaderText[currentShader], 330, 15, 20, RED);
DrawText("< >", 540, 10, 30, DARKBLUE);
-
+
DrawFPS(700, 15);
EndDrawing();
@@ -167,10 +167,10 @@ int main()
// De-Initialization
//--------------------------------------------------------------------------------------
-
+
// Unload all postpro shaders
for (int i = 0; i < MAX_POSTPRO_SHADERS; i++) UnloadShader(shaders[i]);
-
+
UnloadTexture(texture); // Unload texture
UnloadModel(model); // Unload model
UnloadRenderTexture(target); // Unload render texture
diff --git a/examples/shaders/shaders_raymarching.c b/examples/shaders/shaders_raymarching.c
index e5c58a1d..34091792 100644
--- a/examples/shaders/shaders_raymarching.c
+++ b/examples/shaders/shaders_raymarching.c
@@ -18,13 +18,19 @@
#include "raylib.h"
-int main()
+#if defined(PLATFORM_DESKTOP)
+ #define GLSL_VERSION 330
+#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
+ #define GLSL_VERSION 100
+#endif
+
+int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
- int screenWidth = 800;
- int screenHeight = 450;
-
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - raymarching shapes");
Camera camera = { 0 };
@@ -37,8 +43,8 @@ int main()
// Load raymarching shader
// NOTE: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader
- Shader shader = LoadShader(0, "resources/shaders/glsl330/raymarching.fs");
-
+ Shader shader = LoadShader(0, FormatText("resources/shaders/glsl%i/raymarching.fs", GLSL_VERSION));
+
// Get shader locations for required uniforms
int viewEyeLoc = GetShaderLocation(shader, "viewEye");
int viewCenterLoc = GetShaderLocation(shader, "viewCenter");
@@ -66,7 +72,7 @@ int main()
float cameraTarget[3] = { camera.target.x, camera.target.y, camera.target.z };
float cameraUp[3] = { camera.up.x, camera.up.y, camera.up.z };
- float deltaTime = GetFrameTime();
+ float deltaTime = GetFrameTime();
runTime += deltaTime;
// Set shader required uniform values
diff --git a/examples/shaders/shaders_shapes_textures.c b/examples/shaders/shaders_shapes_textures.c
index 5ee5d560..cf53bf99 100644
--- a/examples/shaders/shaders_shapes_textures.c
+++ b/examples/shaders/shaders_shapes_textures.c
@@ -24,23 +24,23 @@
#define GLSL_VERSION 100
#endif
-int main()
+int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
- int screenWidth = 800;
- int screenHeight = 450;
+ const int screenWidth = 800;
+ const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - shapes and texture shaders");
-
+
Texture2D fudesumi = LoadTexture("resources/fudesumi.png");
// Load shader to be used on some parts drawing
- // NOTE 1: Using GLSL 330 shader version, on OpenGL ES 2.0 use GLSL 100 shader version
+ // NOTE 1: Using GLSL 330 shader version, on OpenGL ES 2.0 use GLSL 100 shader version
// NOTE 2: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader
Shader shader = LoadShader(0, FormatText("resources/shaders/glsl%i/grayscale.fs", GLSL_VERSION));
- SetTargetFPS(60);
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
@@ -56,19 +56,19 @@ int main()
BeginDrawing();
ClearBackground(RAYWHITE);
-
+
// Start drawing with default shader
DrawText("USING DEFAULT SHADER", 20, 40, 10, RED);
-
+
DrawCircle(80, 120, 35, DARKBLUE);
DrawCircleGradient(80, 220, 60, GREEN, SKYBLUE);
DrawCircleLines(80, 340, 80, DARKBLUE);
-
+
// Activate our custom shader to be applied on next shapes/textures drawings
BeginShaderMode(shader);
-
+
DrawText("USING CUSTOM SHADER", 190, 40, 10, RED);
DrawRectangle(250 - 60, 90, 120, 60, RED);
@@ -77,29 +77,29 @@ int main()
// Activate our default shader for next drawings
EndShaderMode();
-
+
DrawText("USING DEFAULT SHADER", 370, 40, 10, RED);
-
+
DrawTriangle((Vector2){430, 80},
(Vector2){430 - 60, 150},
(Vector2){430 + 60, 150}, VIOLET);
-
+
DrawTriangleLines((Vector2){430, 160},
(Vector2){430 - 20, 230},
(Vector2){430 + 20, 230}, DARKBLUE);
DrawPoly((Vector2){430, 320}, 6, 80, 0, BROWN);
-
+
// Activate our custom shader to be applied on next shapes/textures drawings
BeginShaderMode(shader);
DrawTexture(fudesumi, 500, -30, WHITE); // Using custom shader
-
+
// Activate our default shader for next drawings
EndShaderMode();
-
+
DrawText("(c) Fudesumi sprite by Eiden Marsal", 380, screenHeight - 20, 10, GRAY);
-
+
EndDrawing();
//----------------------------------------------------------------------------------
}
@@ -108,7 +108,7 @@ int main()
//--------------------------------------------------------------------------------------
UnloadShader(shader); // Unload shader
UnloadTexture(fudesumi); // Unload texture
-
+
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
diff --git a/examples/shaders/shaders_texture_drawing.c b/examples/shaders/shaders_texture_drawing.c
new file mode 100644
index 00000000..697000bc
--- /dev/null
+++ b/examples/shaders/shaders_texture_drawing.c
@@ -0,0 +1,80 @@
+/*******************************************************************************************
+*
+* raylib [textures] example - Texture drawing
+*
+* This example illustrates how to draw on a blank texture using a shader
+*
+* This example has been created using raylib 2.0 (www.raylib.com)
+* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+* Example contributed by Michał Ciesielski and reviewed by Ramon Santamaria (@raysan5)
+*
+* Copyright (c) 2019 Michał Ciesielski and Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#if defined(PLATFORM_DESKTOP)
+ #define GLSL_VERSION 330
+#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
+ #define GLSL_VERSION 100
+#endif
+
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [shaders] example - texture drawing");
+
+ Image imBlank = GenImageColor(1024, 1024, BLANK);
+ Texture2D texture = LoadTextureFromImage(imBlank); // Load blank texture to fill on shader
+ UnloadImage(imBlank);
+
+ // NOTE: Using GLSL 330 shader version, on OpenGL ES 2.0 use GLSL 100 shader version
+ Shader shader = LoadShader(0, FormatText("resources/shaders/glsl%i/cubes_panning.fs", GLSL_VERSION));
+
+ float time = 0.0f;
+ int timeLoc = GetShaderLocation(shader, "uTime");
+ SetShaderValue(shader, timeLoc, &time, UNIFORM_FLOAT);
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ // -------------------------------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ time = GetTime();
+ SetShaderValue(shader, timeLoc, &time, UNIFORM_FLOAT);
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ BeginShaderMode(shader); // Enable our custom shader for next shapes/textures drawings
+ DrawTexture(texture, 0, 0, WHITE); // Drawing BLANK texture, all magic happens on shader
+ EndShaderMode(); // Disable our custom shader, return to default shader
+
+ DrawText("BACKGROUND is PAINTED and ANIMATED on SHADER!", 10, 10, 20, MAROON);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadShader(shader);
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
diff --git a/examples/shaders/shaders_texture_drawing.png b/examples/shaders/shaders_texture_drawing.png
new file mode 100644
index 00000000..12df6fae
--- /dev/null
+++ b/examples/shaders/shaders_texture_drawing.png
Binary files differ
diff --git a/examples/shaders/shaders_texture_waves.c b/examples/shaders/shaders_texture_waves.c
new file mode 100644
index 00000000..07186d37
--- /dev/null
+++ b/examples/shaders/shaders_texture_waves.c
@@ -0,0 +1,110 @@
+/*******************************************************************************************
+*
+* raylib [shaders] example - Texture Waves
+*
+* NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support,
+* OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version.
+*
+* NOTE: Shaders used in this example are #version 330 (OpenGL 3.3), to test this example
+* on OpenGL ES 2.0 platforms (Android, Raspberry Pi, HTML5), use #version 100 shaders
+* raylib comes with shaders ready for both versions, check raylib/shaders install folder
+*
+* This example has been created using raylib 2.5 (www.raylib.com)
+* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+* Example contributed by Anata (@anatagawa) and reviewed by Ramon Santamaria (@raysan5)
+*
+* Copyright (c) 2019 Anata (@anatagawa) and Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#if defined(PLATFORM_DESKTOP)
+ #define GLSL_VERSION 330
+#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
+ #define GLSL_VERSION 100
+#endif
+
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [shaders] example - texture waves");
+
+ // Load texture texture to apply shaders
+ Texture2D texture = LoadTexture("resources/space.png");
+
+ // Load shader and setup location points and values
+ Shader shader = LoadShader(0, FormatText("resources/shaders/glsl%i/wave.fs", GLSL_VERSION));
+
+ int secondsLoc = GetShaderLocation(shader, "secondes");
+ int freqXLoc = GetShaderLocation(shader, "freqX");
+ int freqYLoc = GetShaderLocation(shader, "freqY");
+ int ampXLoc = GetShaderLocation(shader, "ampX");
+ int ampYLoc = GetShaderLocation(shader, "ampY");
+ int speedXLoc = GetShaderLocation(shader, "speedX");
+ int speedYLoc = GetShaderLocation(shader, "speedY");
+
+ // Shader uniform values that can be updated at any time
+ float freqX = 25.0f;
+ float freqY = 25.0f;
+ float ampX = 5.0f;
+ float ampY = 5.0f;
+ float speedX = 8.0f;
+ float speedY = 8.0f;
+
+ float screenSize[2] = { (float)GetScreenWidth(), (float)GetScreenHeight() };
+ SetShaderValue(shader, GetShaderLocation(shader, "size"), &screenSize, UNIFORM_VEC2);
+ SetShaderValue(shader, freqXLoc, &freqX, UNIFORM_FLOAT);
+ SetShaderValue(shader, freqYLoc, &freqY, UNIFORM_FLOAT);
+ SetShaderValue(shader, ampXLoc, &ampX, UNIFORM_FLOAT);
+ SetShaderValue(shader, ampYLoc, &ampY, UNIFORM_FLOAT);
+ SetShaderValue(shader, speedXLoc, &speedX, UNIFORM_FLOAT);
+ SetShaderValue(shader, speedYLoc, &speedY, UNIFORM_FLOAT);
+
+ float seconds = 0.0f;
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ // -------------------------------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ seconds += GetFrameTime();
+
+ SetShaderValue(shader, secondsLoc, &seconds, UNIFORM_FLOAT);
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ BeginShaderMode(shader);
+
+ DrawTexture(texture, 0, 0, WHITE);
+ DrawTexture(texture, texture.width, 0, WHITE);
+
+ EndShaderMode();
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadShader(shader); // Unload shader
+ UnloadTexture(texture); // Unload texture
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
diff --git a/examples/shaders/shaders_texture_waves.png b/examples/shaders/shaders_texture_waves.png
new file mode 100644
index 00000000..99781a17
--- /dev/null
+++ b/examples/shaders/shaders_texture_waves.png
Binary files differ