|   |  | 
| Shader Puzzle aka Reverse Engineering cool effect | 
| Edgar Reynaldo Major Reynaldo May 2007  | I recently came across a cool demo by SilverTES but sadly there is no source file with it, only a static exe and the shader source. I tried to recreate the effect using the latest code he posted in that thread, but all it does is draw an expanding white circle. The shockwave effect doesn't work with my source code. Funny thing is, they're using the same shader, so in theory only the parameters being passed to the shader are different. Here's the code I tried :    1// -----------------------------------------------------------------------
   2// --- Includes ---
   3// -----------------------------------------------------------------------
   4
   5#include <iostream>
   6#include <allegro5/allegro.h>
   7#include <allegro5/allegro_image.h>
   8#include <allegro5/allegro_primitives.h>
   9
  10// -----------------------------------------------------------------------
  11// --- Global variables ---
  12// -----------------------------------------------------------------------
  13
  14ALLEGRO_KEYBOARD_STATE keyState;
  15ALLEGRO_MOUSE_STATE mouseState;
  16ALLEGRO_DISPLAY * windowDisplay(NULL);
  17ALLEGRO_BITMAP * windowBuffer(NULL);
  18
  19ALLEGRO_EVENT_QUEUE * eventQueue(NULL);
  20ALLEGRO_TIMER * framerateTimer(NULL);
  21int framerate(0);
  22
  23// User data
  24ALLEGRO_SHADER * myShader(NULL);
  25const char * myShaderVertFileName("myShaderVert.glsl");
  26const char * myShaderFragFileName("myShaderFrag.glsl");
  27
  28ALLEGRO_BITMAP * myImage(NULL);
  29const char * myImageFileName("bg0.png");
  30// Window setting
  31int screenW(640);
  32int screenH(360);
  33int zoom(2);
  34// Absolute mouse position
  35int mouseXi(0);
  36int mouseYi(0);
  37// Relative mouse position
  38float mouseXf(0);
  39float mouseYf(0);
  40// Window  position in the desktop
  41int xWindow(0);
  42int yWindow(0);
  43
  44// -----------------------------------------------------------------------
  45// --- Global Methods ---
  46// -----------------------------------------------------------------------
  47
  48template <class M>
  49int log (int error, M msg)
  50{
  51    std::cout << msg;
  52
  53    return error;
  54}
  55
  56void setFramerate(int fps)
  57{
  58    eventQueue = al_create_event_queue();
  59    framerate = fps;
  60    framerateTimer = al_create_timer(1.000/framerate);
  61
  62    al_register_event_source (eventQueue,al_get_timer_event_source(framerateTimer));
  63    al_start_timer(framerateTimer);
  64}
  65
  66void drawGrid(int screenW, int screenH,
  67              int sizeX, int sizeY,
  68              ALLEGRO_COLOR color)
  69{
  70    for (int i(0); i<(screenW/sizeX); i++)
  71    {
  72        al_draw_line(i*sizeX+.5, .5, i*sizeX+.5, screenH+.5, color,0);
  73    }
  74
  75    for (int i(0); i<(screenH/sizeY)+1; i++)
  76    {
  77        al_draw_line(.5, i*sizeY+.5, screenW+.5, i*sizeY+.5, color,0);
  78    }
  79}
  80
  81ALLEGRO_SHADER* create_shader(const char* fileNameVert, const char* fileNameFrag )
  82{
  83    ALLEGRO_SHADER* shader = al_create_shader(ALLEGRO_SHADER_GLSL);
  84//    if(!al_attach_shader_source(shader,
  85//                                ALLEGRO_VERTEX_SHADER,
  86//                                al_get_default_shader_source(ALLEGRO_SHADER_GLSL, ALLEGRO_VERTEX_SHADER)))
  87    if(!al_attach_shader_source_file(shader, ALLEGRO_VERTEX_SHADER, fileNameVert))
  88    {
  89        printf("%s\n", al_get_shader_log(shader));
  90        return NULL;
  91    }
  92    if(!al_attach_shader_source_file(shader, ALLEGRO_PIXEL_SHADER, fileNameFrag))
  93    {
  94        printf("%s\n", al_get_shader_log(shader));
  95        return NULL;
  96    }
  97    if(!al_build_shader(shader))
  98    {
  99        printf("%s\n", al_get_shader_log(shader));
 100        return NULL;
 101    }
 102    std::cout << " >>> "<< al_get_shader_log(shader) << " \n";
 103
 104    return shader;
 105}
 106
 107// -----------------------------------------------------------------------
 108// ---- INIT ---
 109// -----------------------------------------------------------------------
 110int init()
 111{
 112// Init Allegro 5
 113    if (!al_init())
 114        return log(1,"Unable to Init ALLEGRO_5 ! \n");
 115
 116// Init & Install : Modules & Addon
 117    if (!al_install_keyboard())
 118        return log(1,"Unable to Install Keyboard ! \n");
 119
 120    if (!al_install_mouse())
 121        return log(1,"Unable to Install Keyboard ! \n");
 122
 123    if (!al_init_image_addon())
 124        return log(1,"Unable to Init Image addon ! \n");
 125
 126    if (!al_init_primitives_addon())
 127        return log(1,"Unable to Init Primitives addon ! \n");
 128
 129// Settings
 130    al_set_new_display_flags(ALLEGRO_WINDOWED);
 131    al_set_new_display_flags(ALLEGRO_OPENGL);
 132    //al_set_new_display_flags(ALLEGRO_PROGRAMMABLE_PIPELINE | ALLEGRO_OPENGL);
 133
 134    setFramerate(60);
 135
 136// Create All
 137    windowDisplay = al_create_display(screenW*zoom, screenH*zoom);
 138    if (!windowDisplay)
 139        return log(1,"Unable to Create display ! \n");
 140
 141    windowBuffer = al_create_bitmap(screenW, screenH);
 142    if (!windowDisplay)
 143        return log(1,"Unable to Create Buffer ! \n");
 144
 145    al_show_mouse_cursor(windowDisplay);
 146
 147    myImage = al_load_bitmap(myImageFileName);
 148
 149
 150    myShader = create_shader(myShaderVertFileName,myShaderFragFileName);
 151
 152    if(!myShader)
 153        return log(1," Error in create myShader !\n");
 154
 155    return log(0,"--- init OK !\n");
 156}
 157// -----------------------------------------------------------------------
 158// --- DONE ---
 159// -----------------------------------------------------------------------
 160int done()
 161{
 162// Destroy All
 163    al_destroy_bitmap(myImage);
 164    al_destroy_event_queue(eventQueue);
 165    al_destroy_timer(framerateTimer);
 166    al_destroy_shader(myShader);
 167    al_destroy_bitmap(windowBuffer);
 168    al_destroy_display(windowDisplay);
 169
 170    return log(0,"--- done OK !\n");
 171}
 172// -----------------------------------------------------------------------
 173// --- RUN ---
 174// -----------------------------------------------------------------------
 175int run()
 176{
 177
 178    bool quit(false);
 179
 180    float centerX(0);
 181    float centerY(0);
 182    float radius(0);
 183    float maxRadius(200);
 184    float speed(0);
 185
 186    while (!quit)
 187    {
 188    // --- Update ---
 189
 190        ALLEGRO_EVENT event;
 191        al_wait_for_event(eventQueue, &event);
 192
 193        // Keyboard Input !
 194        al_get_keyboard_state(&keyState);
 195        if (al_key_down(&keyState, ALLEGRO_KEY_ESCAPE))
 196            quit = true;
 197
 198        // Mouse Input !
 199        al_get_mouse_state(&mouseState);
 200        al_get_window_position (windowDisplay, &xWindow, &yWindow);
 201        al_get_mouse_cursor_position(&mouseXi, &mouseYi);
 202        mouseXf = (float(mouseXi-xWindow)-2)/zoom;
 203        mouseYf = (float(mouseYi-yWindow)-24)/zoom;
 204
 205        if (mouseState.buttons & 1)
 206        {
 207            centerX = mouseXf;
 208            centerY = mouseYf;
 209            radius = 0;
 210            speed = 4;
 211        }
 212
 213        // ShockWave Update !
 214        radius += speed;
 215        if (radius > maxRadius)
 216        {
 217            radius = 0;
 218            speed = 0;
 219        }
 220
 221    // --- Render ---
 222
 223        // clear windowbuffer !
 224        al_set_target_bitmap(windowBuffer);
 225        al_clear_to_color(al_map_rgb(0,25,40));
 226
 227        // Begin drawing !
 228
 229        // Use shader here before blit buffer to display !!
 230        al_use_shader(myShader);
 231        al_set_shader_sampler("texture", myImage, 0);
 232
 233        float center[2] = { centerX, centerY };
 234        float shockParams[3] = {10.0, 0.8, 0.1};
 235
 236        al_set_shader_float("time", radius);
 237        al_set_shader_float_vector("center", 2, ¢er[0], 1);
 238        al_set_shader_float_vector("shockParams", 3, &shockParams[0], 1);
 239
 240        al_draw_bitmap(myImage, 0,0,0);
 241
 242        al_use_shader(NULL);
 243
 244        drawGrid(screenW, screenH,32,32,al_map_rgba(0,45,80,50));
 245        al_draw_rectangle(0.5, 0.5,
 246                          screenW-.5, screenH-.5,
 247                          al_map_rgb(250,120,180),0);
 248
 249        al_draw_line(0, mouseYf, screenW, mouseYf, al_map_rgba(10,100,155,50), 0);
 250        al_draw_line(mouseXf, 0, mouseXf, screenH, al_map_rgba(10,100,155,50), 0);
 251
 252        al_draw_circle(centerX, centerY, radius, al_map_rgba(250,200,210,50),0);
 253
 254
 255        /// End drawing !
 256
 257        // Blit buffer to display !
 258        al_set_target_backbuffer(windowDisplay);
 259        al_clear_to_color(al_map_rgb(0,0,0));
 260
 261
 262        al_draw_scaled_bitmap(windowBuffer,
 263                              0, 0, screenW, screenH,
 264                              0, 0, screenW*zoom, screenH*zoom,
 265                              0),
 266
 267
 268        // Flip display !
 269        al_flip_display();
 270
 271
 272    }
 273
 274    return log(0,"--- run OK !\n");
 275}
 276// -----------------------------------------------------------------------
 277// --- MAIN ---
 278// -----------------------------------------------------------------------
 279int main()
 280{
 281    if (init())
 282        return log(1, "Error in init() \n");
 283    if (run())
 284        return log(1, "Error in run() \n");
 285    if (done())
 286        return log(1, "Error in done() \n");
 287
 288    return log(0,"--- Terminated normally ! \n");;
 289}
 Cookies and kudos to anyone who can help me figure this out. EDIT // ShockWave Update ! radius += speed; if (radius > maxRadius) { speed = -speed; } if (radius < 0) { radius = 0; speed = 0; } 
The thread I'm referring to is here : The effect looks like this (it's much better in action) : It's a spherical distortion of some sort. Here's the vertex shader SilverTES used. (You can download them above) :   1#ifdef GL_ES
  2precision mediump float;
  3#endif
  4
  5uniform sampler2D tex; // 0
  6uniform vec2 center; // Mouse position
  7uniform float time; // effect elapsed time
  8uniform vec3 shockParams; // 10.0, 0.8, 0.1
  9
 10uniform vec2 surface; // texture resolution
 11
 12void main()
 13{
 14    vec2 uv = gl_TexCoord[0].xy;
 15    vec2 texCoord = uv;
 16
 17    //float square = min(surface.x,surface.y);
 18    //vec2 position = vec2(center.x/square, center.y/square);
 19
 20    vec2 position = center/surface;
 21    float dist = distance(uv, position);
 22
 23    //float dist = distance(vec2(uv.x,uv.y), vec2(position.x,position.y));
 24
 25    if ((dist <= (time + shockParams.z)) && (dist >= (time - shockParams.z)) )
 26    {
 27        float diff = (dist - time);
 28        float powDiff = 1.0 - pow(abs(diff*shockParams.x), shockParams.y);
 29        float diffTime = diff  * powDiff;
 30        vec2 diffUV = normalize(uv - position);
 31        texCoord = uv + (diffUV * diffTime);
 32    }
 33
 34    gl_FragColor = texture2D(tex, texCoord);
 35}
 
UPDATE Here's the new code - I redid most of it.    1// -----------------------------------------------------------------------
   2// --- Includes ---
   3// -----------------------------------------------------------------------
   4
   5#include <iostream>
   6#include <allegro5/allegro.h>
   7#include <allegro5/allegro_image.h>
   8#include <allegro5/allegro_primitives.h>
   9#include <allegro5/allegro_opengl.h>
  10
  11#include <cmath>
  12
  13// -----------------------------------------------------------------------
  14// --- Global variables ---
  15// -----------------------------------------------------------------------
  16
  17ALLEGRO_DISPLAY * d(NULL);
  18ALLEGRO_BITMAP * windowBuffer(NULL);
  19
  20ALLEGRO_EVENT_QUEUE* q(NULL);
  21ALLEGRO_TIMER * t(NULL);
  22
  23
  24ALLEGRO_SHADER * myShader(NULL);
  25const char * myShaderVertFileName("myShaderVert.glsl");
  26const char * myShaderFragFileName("myShaderFrag.glsl");
  27
  28ALLEGRO_BITMAP * myImage(NULL);
  29const char * myImageFileName("bg0.png");
  30// Window setting
  31int screenW(800);
  32int screenH(600);
  33
  34// -----------------------------------------------------------------------
  35// --- Global Methods ---
  36// -----------------------------------------------------------------------
  37
  38template <class M>
  39int log (int error, M msg)
  40{
  41    std::cout << msg;
  42
  43    return error;
  44}
  45
  46void drawGrid(int screenW, int screenH,
  47              int sizeX, int sizeY,
  48              ALLEGRO_COLOR color)
  49{
  50    for (int i(0); i<(screenW/sizeX); i++)
  51    {
  52        al_draw_line(i*sizeX+.5, .5, i*sizeX+.5, screenH+.5, color,0);
  53    }
  54
  55    for (int i(0); i<(screenH/sizeY)+1; i++)
  56    {
  57        al_draw_line(.5, i*sizeY+.5, screenW+.5, i*sizeY+.5, color,0);
  58    }
  59}
  60
  61ALLEGRO_SHADER* create_shader(const char* fileNameVert, const char* fileNameFrag )
  62{
  63    ALLEGRO_SHADER* shader = al_create_shader(ALLEGRO_SHADER_GLSL);
  64//    if(!al_attach_shader_source(shader,
  65//                                ALLEGRO_VERTEX_SHADER,
  66//                                al_get_default_shader_source(ALLEGRO_SHADER_GLSL, ALLEGRO_VERTEX_SHADER)))
  67    if(!al_attach_shader_source_file(shader, ALLEGRO_VERTEX_SHADER, fileNameVert))
  68    {
  69        printf("%s\n", al_get_shader_log(shader));
  70        return NULL;
  71    }
  72    if(!al_attach_shader_source_file(shader, ALLEGRO_PIXEL_SHADER, fileNameFrag))
  73    {
  74        printf("%s\n", al_get_shader_log(shader));
  75        return NULL;
  76    }
  77    if(!al_build_shader(shader))
  78    {
  79        printf("%s\n", al_get_shader_log(shader));
  80        return NULL;
  81    }
  82    std::cout << " >>> "<< al_get_shader_log(shader) << " \n";
  83
  84    return shader;
  85}
  86
  87// -----------------------------------------------------------------------
  88// ---- INIT ---
  89// -----------------------------------------------------------------------
  90int init()
  91{
  92// Init Allegro 5
  93    if (!al_init())
  94        return log(1,"Unable to Init ALLEGRO_5 ! \n");
  95
  96// Init & Install : Modules & Addon
  97    if (!al_install_keyboard())
  98        return log(1,"Unable to Install Keyboard ! \n");
  99
 100    if (!al_install_mouse())
 101        return log(1,"Unable to Install Keyboard ! \n");
 102
 103    if (!al_init_image_addon())
 104        return log(1,"Unable to Init Image addon ! \n");
 105
 106    if (!al_init_primitives_addon())
 107        return log(1,"Unable to Init Primitives addon ! \n");
 108
 109// Settings
 110///    al_set_new_display_flags(ALLEGRO_PROGRAMMABLE_PIPELINE | ALLEGRO_OPENGL | ALLEGRO_WINDOWED);
 111    al_set_new_display_flags(ALLEGRO_OPENGL | ALLEGRO_WINDOWED);
 112
 113// Create All
 114    d = al_create_display(screenW, screenH);
 115    if (!d)
 116        return log(1,"Unable to Create display ! \n");
 117
 118    windowBuffer = al_create_bitmap(screenW, screenH);
 119    myImage = al_create_bitmap(screenW, screenH);
 120    if (!windowBuffer)
 121        return log(1,"Unable to Create Buffer ! \n");
 122
 123    q = al_create_event_queue();
 124    t = al_create_timer(1.0/60.0);
 125        
 126    al_register_event_source(q , al_get_display_event_source(d));
 127    al_register_event_source(q , al_get_mouse_event_source());
 128    al_register_event_source(q , al_get_timer_event_source(t));
 129    al_register_event_source(q , al_get_keyboard_event_source());
 130        
 131    al_show_mouse_cursor(d);
 132
 133    ALLEGRO_BITMAP* image = al_load_bitmap(myImageFileName);
 134    al_set_target_bitmap(myImage);
 135    al_set_blender(ALLEGRO_ADD , ALLEGRO_ONE , ALLEGRO_ZERO);
 136    al_draw_scaled_bitmap(image , 0 , 0 , al_get_bitmap_width(image) , al_get_bitmap_height(image) , 0 , 0 , screenW , screenH , 0);
 137    al_set_blender(ALLEGRO_ADD , ALLEGRO_ONE , ALLEGRO_INVERSE_ALPHA);
 138    al_destroy_bitmap(image);
 139
 140    myShader = create_shader(myShaderVertFileName,myShaderFragFileName);
 141
 142    if(!myShader)
 143        return log(1," Error in create myShader !\n");
 144
 145    return log(0,"--- init OK !\n");
 146}
 147// -----------------------------------------------------------------------
 148// --- DONE ---
 149// -----------------------------------------------------------------------
 150int done()
 151{
 152   al_uninstall_system();
 153
 154    return log(0,"--- done OK !\n");
 155}
 156// -----------------------------------------------------------------------
 157// --- RUN ---
 158// -----------------------------------------------------------------------
 159int run()
 160{
 161
 162    bool quit = false;
 163    bool redraw = true;
 164
 165    float radius(0);
 166    float maxRadius(300);
 167    float speed(0);
 168    float dt = 0.0f;
 169
 170    int mx = 0 , my = 0;
 171    
 172    bool warp = false;
 173    
 174    al_start_timer(t);
 175    
 176    while (!quit)
 177    {
 178    // --- Update ---
 179
 180        ALLEGRO_EVENT ev;
 181        al_wait_for_event(q, &ev);
 182
 183        // Keyboard Input !
 184        if (ev.type == ALLEGRO_EVENT_KEY_DOWN && ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) {
 185            quit = true;
 186        }
 187        if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
 188            quit = true;
 189        }
 190        if (ev.type == ALLEGRO_EVENT_MOUSE_AXES) {
 191            mx = ev.mouse.x;
 192            my = ev.mouse.y;
 193        }
 194        if (ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN && ev.mouse.button & 1) {
 195           // Mouse Input !
 196            warp = true;
 197            radius = 0;
 198            speed = 5;
 199        }
 200
 201        if (ev.type == ALLEGRO_EVENT_TIMER) {
 202            redraw = true;
 203           // ShockWave Update !
 204           radius += speed;
 205           if (radius > maxRadius)
 206           {
 207               speed = -speed;
 208           }
 209           if (radius < 0) {
 210              radius = 0;
 211               speed = 0;
 212               warp = false;
 213           }
 214
 215           dt = 2.0*M_PI*(radius/maxRadius);
 216        }
 217        
 218         if (redraw) {
 219            redraw = false;
 220            // --- Render ---
 221
 222            // clear windowbuffer !
 223            al_set_target_bitmap(windowBuffer);
 224            al_clear_to_color(al_map_rgb(0,0,255));
 225
 226            // Begin drawing !
 227
 228            // Use shader here before blit buffer to display !!
 229            al_use_shader(myShader);
 230            al_set_shader_sampler("tex", myImage, 0);
 231
 232            int tw = 0;
 233            int th = 0;
 234            al_get_opengl_texture_size(myImage , &tw , &th);
 235
 236            float dim[2] = {(float)al_get_bitmap_width(myImage) , (float)al_get_bitmap_height(myImage)};
 237
 238            float ms[2] = {(float)mx,(float)(screenH - my)};
 239
 240            float r = radius;
 241            
 242            al_set_shader_bool("warp" , warp);
 243            al_set_shader_float("radius", r);
 244            al_set_shader_float("dt", dt);
 245            al_set_shader_float_vector("mouse" , 2 , &ms[0] , 1);
 246            al_set_shader_float_vector("dim", 2, &dim[0], 1);
 247
 248            al_draw_bitmap(myImage, 0,0,0);
 249
 250            al_use_shader(NULL);
 251
 252            drawGrid(screenW, screenH,32,32,al_map_rgba(0,45,80,50));
 253                     al_draw_rectangle(0.5, 0.5,
 254                     screenW-.5, screenH-.5,
 255                     al_map_rgb(250,120,180),0);
 256
 257
 258
 259            /// End drawing !
 260
 261            // Blit buffer to display !
 262            al_set_target_backbuffer(d);
 263            al_clear_to_color(al_map_rgb(0,0,0));
 264            
 265            
 266            al_draw_bitmap(windowBuffer , 0 , 0 , 0);
 267
 268            // Flip display !
 269            al_flip_display();
 270         }
 271      
 272
 273    }
 274
 275    return log(0,"--- run OK !\n");
 276}
 277// -----------------------------------------------------------------------
 278// --- MAIN ---
 279// -----------------------------------------------------------------------
 280int main()
 281{
 282    if (init())
 283        return log(1, "Error in init() \n");
 284    if (run())
 285        return log(1, "Error in run() \n");
 286    if (done())
 287        return log(1, "Error in done() \n");
 288
 289    return log(0,"--- Terminated normally ! \n");;
 290}
 And here's the vertex shader :   1#version 110
  2
  3
  4
  5uniform sampler2D tex; // 0
  6uniform float dt;
  7uniform vec2 mouse; // Mouse position
  8uniform vec2 dim;
  9uniform float radius;
 10uniform bool warp;
 11
 12void main()
 13{
 14   vec2 uv = gl_TexCoord[0].xy;
 15   if (warp) {
 16   ///   gl_FragColor = texture2D(tex , uv);
 17
 18      vec2 uvP = vec2(uv.x*dim.x , uv.y*dim.y);
 19      
 20      vec2 dist = mouse - uvP;
 21      float theta = atan(dist.y , dist.x);
 22   ///   dist += (dist / (1.0 + (1.0 + cos(dist*dt/300.0))/2.0));
 23      float d = distance(dist , vec2(0.0,0.0));
 24
 25      if ((d < (radius + 50.0)) && (d > (radius - 50.0))) {
 26         float diff = d - radius;
 27         diff = sin((diff + 50.0)*3.14159265*2.0/100.0);
 28         dist /= diff;
 29         uv = uv + vec2(dist.x/dim.x , dist.y/dim.y);
 30      }
 31
 32
 33   ///   dist /= (1.0 + (1.0 + cos(dist*dt/300.0))/2.0);
 34   }
 35   gl_FragColor = texture2D(tex , uv);
 36//   dist = dist*(1.0f + .25*sin(dt));
 37//   float theta = atan(mouse.y - uv.y , mouse.x - uv.x);
 38//   uv = uv + dist*vec2(cos(theta) , sin(theta));
 39}
 40
 41
 42/**
 43void main()
 44{
 45    vec2 uv = gl_TexCoord[0].xy;
 46
 47    vec2 texPixel = vec2(uv.x*dim.x , uv.y*dim.y);
 48
 49    vec2 position = center/surface;
 50    
 51    position = vec2(position.x*dim.x , position.y*dim.y);
 52
 53    float dist = distance(texPixel, position);
 54    
 55    vec2 diff = position - texPixel;
 56    float theta = atan(diff.y , diff.x);
 57    
 58    texPixel = uv + vec2(dist*cos(theta) , dist*sin(theta));
 59    texPixel = vec2(texPixel.x/dim.x , texPixel.y/dim.y);
 60    if ((dist <= (radius + shockParams.z)) && (dist >= (radius - shockParams.z)) )
 61    {
 62        float diff = (dist - radius);
 63        float powDiff = 1.0 - pow(abs(diff*shockParams.x), shockParams.y);
 64        float diffTime = diff  * powDiff;
 65        vec2 diffUV = normalize(uv - position);
 66        texCoord = uv + (diffUV * diffTime);
 67    }
 68    gl_FragColor = texture2D(tex, texPixel);
 69}
 70
 71//*/
 
EDIT Download a zip of the source and image and executables here ! My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide | 
| Rodolfo Lam Member #16,045 August 2015 | This might be a very good example on the usage of the shaders and the programable pipeline in allegro. Nice job! 
 | 
|  |