Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Why some Shaders don't work !

This thread is locked; no one can reply to it. rss feed Print
Why some Shaders don't work !
SilverTES
Member #16,572
October 2016

#SelectExpand
1---[Vertex_Shader] 2void main(void) 3{ 4 gl_Position = ftransform(); 5 gl_TexCoord[0] = gl_MultiTexCoord0; 6} 7 8---[Pixel_Shader] 9uniform sampler2D al_tex; // 0 10uniform vec2 center; // Mouse position 11uniform float time; // effect elapsed time 12uniform vec3 shockParams; // 10.0, 0.8, 0.1 13void main() 14{ 15 vec2 uv = gl_TexCoord[0].xy; 16 vec2 texCoord = uv; 17 float distance = distance(uv, center); 18 if ( (distance <= (time + shockParams.z)) && 19 (distance >= (time - shockParams.z)) ) 20 { 21 float diff = (distance - time); 22 float powDiff = 1.0 - pow(abs(diff*shockParams.x), 23 shockParams.y); 24 float diffTime = diff * powDiff; 25 vec2 diffUV = normalize(uv - center); 26 texCoord = uv + (diffUV * diffTime); 27 } 28 gl_FragColor = texture2D(al_tex, texCoord); 29}

Effect : It's just a simple shockwave effect but don't work!

but this one work fine :

#SelectExpand
1---[Vertex_Shader] 2I use "al_get_default_shader_source(ALLEGRO_SHADER_GLSL, ALLEGRO_VERTEX_SHADER)" 3 4---[Pixel_Shader] 5uniform sampler2D al_tex; 6uniform float radius; 7varying vec2 varying_texcoord; 8 9void main () 10{ 11 vec2 pos = mod(gl_FragCoord.xy, vec2(40.0)) - vec2(20.0); 12 float dist_squared = dot(pos, pos); 13 vec4 tmp = texture2D(al_tex, varying_texcoord); 14 15 if (dist_squared < radius && (tmp.r>0 || tmp.g>0 || tmp.b>0) ) 16 gl_FragColor = vec4(.0+tmp.r, .0+tmp.g, .0+tmp.b, 1.0); 17 else 18 gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); 19}

Effect : tile of filled circles with settable radius !
why ???

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

SilverTES
Member #16,572
October 2016

I don't have any errors.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

SilverTES
Member #16,572
October 2016

Yes I checked them, step by step.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

SilverTES
Member #16,572
October 2016

I do exactly the same method with the Two Shaders above ( Shockwave & Tile circle).
One works the other not.

Unfortunately, It's really really hard to find some shader's tutorials using with Allegro 5.

The examples are not really explicative. I have to guess when I read.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

SilverTES
Member #16,572
October 2016

Vertex Shader : "myShaderVert.glsl"

#SelectExpand
1void main(void) 2{ 3 gl_Position = ftransform(); 4 gl_TexCoord[0] = gl_MultiTexCoord0; 5 gl_FrontColor = gl_Color; 6}

Fragment Shader : "myShaderFrag.glsl"

#SelectExpand
1uniform sampler2D texture; // 0 2uniform vec2 center; // Mouse position 3uniform float time; // effect elapsed time 4uniform vec3 shockParams; // 10.0, 0.8, 0.1 5void main() 6{ 7 vec2 uv = gl_TexCoord[0].xy; 8 vec2 texCoord = uv; 9 float distance = distance(uv, center); 10 if ( (distance <= (time + shockParams.z)) && 11 (distance >= (time - shockParams.z)) ) 12 { 13 float diff = (distance - time); 14 float powDiff = 1.0 - pow(abs(diff*shockParams.x), 15 shockParams.y); 16 float diffTime = diff * powDiff; 17 vec2 diffUV = normalize(uv - center); 18 texCoord = uv + (diffUV * diffTime); 19 } 20 gl_FragColor = texture2D(texture, texCoord); 21}

Here is my Simple Shader code : "simple_Shader_Allegro_5.cpp"

#SelectExpand
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, &center[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}

And it don't works ! :(

relpatseht
Member #5,034
September 2004
avatar

"Doesn't work" is a really terrible way of describing the problem. I'm guessing you mean no shockwave happens and everything draws correctly.

If I understand the code correctly, your problem is one incorrect numerical spaces. In your pixel shader, center is based off the mouse coordinates in pixel space and it is being compared against texture coordinates which are in UV space.
Put another way, on the line "float distance = distance(uv, center);", center is ([0, windowWidth], [0, windowHeight]) while uv is ([0, 1], [0, 1]).

FYI, you can actually debug shaders on PC if you have an nVidia card. NSight is your friend.

SilverTES
Member #16,572
October 2016

You guessing right, nothing happens, I just have my bitmap on the screen.

My another question is if my shader code(cpp) is correct or not.

relpatseht
Member #5,034
September 2004
avatar

I don't see anything immediately wrong with your shader code, just the numbers you're passing into it.

Center needs to be in UV space [0, 1] and it isn't. Divide your mouse coords by the window size.

SilverTES
Member #16,572
October 2016

I don't know if I pass texture correctly :

al_set_shader_sampler("tex", myImage, 0);

Ok I tried to divide by the texture/bitmap size (not the window here).
But nothing happens any more.

#SelectExpand
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 16 vec2 texCoord = uv; 17 18 float dist = distance(uv, vec2(center.x/surface.x, center.y/surface.y) ); 19 20 if ((dist <= (time + shockParams.z)) && (dist >= (time - shockParams.z))) 21 { 22 float diff = (dist - time); 23 float powDiff = 1.0 - pow(abs(diff*shockParams.x), shockParams.y); 24 float diffTime = diff * powDiff; 25 vec2 diffUV = normalize(uv - center); 26 texCoord = uv + (diffUV * diffTime); 27 } 28 29 gl_FragColor = texture2D(tex, texCoord); 30 31 //gl_FragColor = vec4(1.0,1.0,0.0,0.1); 32}

I've got the shader here :
http://www.geeks3d.com/20091116/shader-library-2d-shockwave-post-processing-filter-glsl/

I simply wanted to test it on a ALLEGRO_BITMAP with Allegro 5 shader functions.

relpatseht
Member #5,034
September 2004
avatar

GLSL has a nice vector library, you can just say center/surface, you don't need to separate the x and y parameters.

That said, I have no idea what the dimensions of surface are to tell you if they're correct given your input for center.

An an exercise, print out the smallest value for mouseXf and mouseYf, as well as the largest value for each, as you move the mouse around the window.
You need to write a function so that the smallest number will be converted to 0 and the largest converted to 1.

You really shouldn't be using al_get_mouse_position either. Coordinates relative to the desktop then guessing if you're within the window is silly. Get your coordinates relative to the window, which you already have in mouseState.

SilverTES
Member #16,572
October 2016

Ok I finally did it ;), thank you very much for your help !

#SelectExpand
1uniform sampler2D tex; // 0 2uniform vec2 center; // Mouse position 3uniform float time; // effect elapsed time 4uniform vec3 shockParams; // 10.0, 0.8, 0.1 5 6uniform vec2 surface; // texture resolution 7 8void main() 9{ 10 vec2 uv = gl_TexCoord[0].xy; 11 vec2 texCoord = uv; 12 13 //float square = min(surface.x,surface.y); 14 //vec2 position = vec2(center.x/square, center.y/square); 15 16 vec2 position = center/surface; 17 float dist = distance(uv, position); 18 19 //float dist = distance(vec2(uv.x,uv.y), vec2(position.x,position.y)); 20 21 if ((dist <= (time + shockParams.z)) && (dist >= (time - shockParams.z)) ) 22 { 23 float diff = (dist - time); 24 float powDiff = 1.0 - pow(abs(diff*shockParams.x), shockParams.y); 25 float diffTime = diff * powDiff; 26 vec2 diffUV = normalize(uv - position); 27 texCoord = uv + (diffUV * diffTime); 28 } 29 30 gl_FragColor = texture2D(tex, texCoord); 31}

You can test the program here: https://www.allegro.cc/files/attachment/610651

Go to: