Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » To get shaders going.

This thread is locked; no one can reply to it. rss feed Print
To get shaders going.
A. van Patmos
Member #15,349
October 2013

I took the example program from thread 617536 and get it to work OK.
Then I try to use a shader on a bitmap so I change the code:

#SelectExpand
1#include <stdio.h> 2#include "allegro5/allegro5.h" 3#include "allegro5/allegro_image.h" 4#include "allegro5/allegro_primitives.h" 5 6int main(int argc, char **argv) 7{ 8 ALLEGRO_DISPLAY *display; 9 10 ALLEGRO_BITMAP *bmp; 11 ALLEGRO_SHADER *shader; 12// char *vsource = "data/ex_shader_vertex.glsl"; 13// char *psource = "data/ex_shader_pixel.glsl"; 14 char *vsource = "data/vertex.glsl"; 15 char *psource = "data/fragment.glsl"; 16 17 if (!al_init()) { 18 printf("Could not init Allegro.\n"); 19 } 20 al_install_keyboard(); 21 al_init_image_addon(); 22 23 al_set_new_display_flags(ALLEGRO_PROGRAMMABLE_PIPELINE | ALLEGRO_OPENGL); 24 25 display = al_create_display(640, 640); 26 if (!display) { 27 printf("Could not create display.\n"); 28 } 29 30 bmp = al_load_bitmap("data/MAR0DST.bmp"); 31// float tints[3] = {0.0, 1.0, 0.0}; 32 33 shader = al_create_shader(ALLEGRO_SHADER_AUTO); 34 35 if(!al_attach_shader_source_file(shader, ALLEGRO_VERTEX_SHADER, vsource)) 36 {printf("al_attach_shader_source_file failed: %s\n", al_get_shader_log(shader));} 37 if(!al_attach_shader_source_file(shader, ALLEGRO_PIXEL_SHADER, psource)) 38 {printf("al_attach_shader_source_file failed: %s\n", al_get_shader_log(shader));} 39 40 if(!al_build_shader(shader)) { 41 printf("al_build_shader failed: %s\n", al_get_shader_log(shader)); 42 } 43 44 while (1) 45 { 46 ALLEGRO_KEYBOARD_STATE s; 47 al_get_keyboard_state(&s); 48 if (al_key_down(&s, ALLEGRO_KEY_F8)) 49 break; 50 51 al_set_target_bitmap(bmp); 52 al_use_shader(shader); 53// al_set_shader_float_vector("tint", 3, &tints[0], 1); 54 al_draw_bitmap(bmp, 0, 0, 0); 55 al_use_shader(NULL); 56 al_set_target_backbuffer(display); 57 al_clear_to_color(al_map_rgb(215, 255, 255)); 58 al_draw_bitmap(bmp, 0, 0, 0); 59 al_draw_bitmap(bmp, 256, 0, 0); 60 al_draw_bitmap(bmp, 0, 256, 0); 61 al_draw_bitmap(bmp, 256, 256, 0); 62 al_flip_display(); 63 64 al_rest(0.01); 65 } 66 67 al_destroy_shader(shader); 68 69 return 0; 70}

As new vertex.glsl and fragment.glsl I wanted to use these at 2/3 of the page under "Example: Swapping Color Channels".

edit: changing those shaders to this:

attribute vec2 al_texcoord;
attribute vec4 al_pos;
varying vec2 varying_texcoord;
uniform mat4 al_projview_matrix;

void main(void)
{
   varying_texcoord = al_texcoord;
   gl_Position = al_projview_matrix * al_pos;
}

uniform sampler2D al_tex;
varying vec2 varying_texcoord;

void main(void)  
{   
   gl_FragColor = texture2D(al_tex, varying_texcoord).bgra;
}

helps but introduces a flicker to the screen. Why would that be?

MikiZX
Member #17,092
June 2019

You seem to be drawing bitmap 'bmp' onto itself using the shader.

Possibly this is something you would like to do by design (though I would half expect this to be causing an undefined behavior in OpenGl).

Usually what we do is draw the original bitmap ('bmp' in your case) onto the 'display' using the shader effect. This way 'bmp' remains the same at all times.

Change your code from:

 51      al_set_target_bitmap(bmp);
 52      al_use_shader(shader);
 53//      al_set_shader_float_vector("tint", 3, &tints[0], 1);
 54      al_draw_bitmap(bmp, 0, 0, 0);
 55      al_use_shader(NULL);
 56      al_set_target_backbuffer(display);
 57      al_clear_to_color(al_map_rgb(215, 255, 255));
 58      al_draw_bitmap(bmp, 0, 0, 0);
...

to:

 51
 52      al_set_target_backbuffer(display);
 53      al_clear_to_color(al_map_rgb(215, 255, 255));
 54      al_use_shader(shader); 
 55//      al_set_shader_float_vector("tint", 3, &tints[0], 1);
 56      
 57
 58      al_draw_bitmap(bmp, 0, 0, 0);
...

if that helps?

A. van Patmos
Member #15,349
October 2013

Yes, that's what it should do. Introducing a timer helps, a bit. Its behaviour is very consistent, the flickering part moves bottom-to-top over the screen, only when using a shader.

#SelectExpand
1#include <stdio.h> 2#include "allegro5/allegro5.h" 3#include "allegro5/allegro_image.h" 4#include "allegro5/allegro_primitives.h" 5 6int main(int argc, char **argv) 7{ 8 ALLEGRO_DISPLAY *display; 9 ALLEGRO_EVENT_QUEUE *event_queue = NULL; 10 ALLEGRO_EVENT ev; 11 ALLEGRO_TIMER *timer = NULL; 12 13 ALLEGRO_BITMAP *bmp; 14 ALLEGRO_SHADER *shader; 15// char *vsource = "data/ex_shader_vertex.glsl"; 16// char *psource = "data/ex_shader_pixel.glsl"; 17 char *vsource = "data/vertex.glsl"; 18 char *psource = "data/fragment.glsl"; 19 20 if (!al_init()) { 21 printf("Could not init Allegro.\n"); 22 } 23 al_install_keyboard(); 24 al_init_image_addon(); 25 26 al_set_new_display_flags(ALLEGRO_PROGRAMMABLE_PIPELINE | ALLEGRO_OPENGL); 27 28 display = al_create_display(640, 640); 29 if (!display) { 30 printf("Could not create display.\n"); 31 } 32 33 bmp = al_load_bitmap("data/MAR0DST.bmp"); 34// float tints[3] = {0.0, 1.0, 0.0}; 35 36 shader = al_create_shader(ALLEGRO_SHADER_AUTO); 37 38 if(!al_attach_shader_source_file(shader, ALLEGRO_VERTEX_SHADER, vsource)) 39 {printf("al_attach_shader_source_file failed: %s\n", al_get_shader_log(shader));} 40 if(!al_attach_shader_source_file(shader, ALLEGRO_PIXEL_SHADER, psource)) 41 {printf("al_attach_shader_source_file failed: %s\n", al_get_shader_log(shader));} 42 43 if(!al_build_shader(shader)) { 44 printf("al_build_shader failed: %s\n", al_get_shader_log(shader)); 45 } 46 47 event_queue = al_create_event_queue(); 48 timer = al_create_timer(0.016666); 49 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 50 al_start_timer(timer); 51 52 while (1) 53 { 54 al_wait_for_event(event_queue, &ev); 55 ALLEGRO_KEYBOARD_STATE s; 56 al_get_keyboard_state(&s); 57 if (al_key_down(&s, ALLEGRO_KEY_F8)) 58 break; 59 60 al_set_target_bitmap(bmp); 61 al_use_shader(shader); 62// al_set_shader_float_vector("tint", 3, &tints[0], 1); 63 al_draw_bitmap(bmp, 0, 0, 0); 64 al_use_shader(NULL); 65 al_set_target_backbuffer(display); 66 al_clear_to_color(al_map_rgb(215, 255, 255)); 67 al_draw_bitmap(bmp, 0, 0, 0); 68 al_draw_bitmap(bmp, 256, 0, 0); 69 al_draw_bitmap(bmp, 0, 256, 0); 70 al_draw_bitmap(bmp, 256, 256, 0); 71 al_flip_display(); 72 73 al_rest(0.01); 74 } 75 76 al_destroy_shader(shader); 77 78 return 0; 79}

MikiZX
Member #17,092
June 2019

Interesting to know that drawing a bitmap onto itself works; using a shader too. I would have used a temporary bitmap for that. 'Live and learn' as they say.

As for synchronizing your program to the refresh rate of your screen please have a look at https://wiki.allegro.cc/index.php?title=Allegro_5_Tutorial/Timers for an example of using timers to redraw the display.

Go to: