Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Pixel shader- how do I get the source coordinate?

Credits go to Edgar Reynaldo for helping out!
This thread is locked; no one can reply to it. rss feed Print
Pixel shader- how do I get the source coordinate?
Benedict
Member #16,937
January 2019

Hi- I'm just starting with Allegro, playing around with the basic features before jumping into building a simple 2D game engine, and I'm getting stuck on writing a simple shader- I'm getting "Fragment shader contains a user varying, but is linked without a vertex shader. Out of resource error." when I try to run the game. Things are otherwise working- I'm able to get the shader running and applying, but the actual behavior I want depends on access to the varying_texcoord value- I need to be able to actually sample the sampler.

The behavior I want here is to draw a solid outline a few pixels thick around the visible pixels of a transparent bitmap being drawn. I have a (fairly inefficient since I'm just messing around and GLSL doesn't allow recursion) function to determine whether a pixel should be outlined, and for the rest of it I'm pretty much just going off the example code in liballeg.

Here's my shader file and Source.cpp:

#SelectExpand
1#ifdef GL_ES 2precision mediump float; 3#endif 4uniform sampler2D al_tex; 5varying vec4 varying_color; 6varying vec2 varying_texcoord; 7uniform float bitmapWidth; 8uniform float bitmapHeight; 9 10void main(); 11bool areNeighborsInRange(int thick); 12vec4 imgPixelAt(float x,float y); 13 14void main() 15{ 16 if(areNeighborsInRange(3)){ 17 gl_FragColor = varying_color; 18 }else{ 19 gl_FragColor = texture2D(al_tex, varying_texcoord); 20 } 21} 22bool areNeighborsInRange(int thick){ 23 int range = (thick*2)+1; 24 for(int i = 0; i<range; i++){ 25 for(int j = 0; j<range; j++){ 26 int x = j - thick; 27 int y = i - thick; 28 bool check = (abs(x)+abs(y)) <= thick; 29 if(check){ 30 if(imgPixelAt(varying_texcoord.x+ (x/bitmapWidth),varying_texcoord.y+ (y/bitmapHeight)).a != 0.0){ 31 return true; 32 } 33 } 34 } 35 } 36 return false; 37} 38vec4 imgPixelAt(float x,float y){ 39 return texture2D(al_tex,vec2(x,y)); 40}

#SelectExpand
1#include <iostream> 2#include <math.h> 3#include <allegro5/allegro.h> 4#include <allegro5/allegro_font.h> 5#include <allegro5/allegro_ttf.h> 6#include <allegro5/allegro_image.h> 7#include <allegro5/allegro_opengl.h> 8int gameclose; 9int textredness; 10 11ALLEGRO_DISPLAY* display; 12ALLEGRO_EVENT_QUEUE* e_queue; 13ALLEGRO_FONT* sansation; 14ALLEGRO_TIMER* timer; 15ALLEGRO_BITMAP* img; 16ALLEGRO_SHADER* hilite; 17 18void update(); 19 20int main(int argc, char **argv) { 21 22 al_init(); 23 al_init_font_addon(); 24 al_init_ttf_addon(); 25 al_init_image_addon(); 26 al_set_new_display_flags(ALLEGRO_OPENGL); 27 28 display = al_create_display(1040, 550); 29 e_queue = al_create_event_queue(); 30 sansation = al_load_ttf_font("Fonts/Sansation_Regular.ttf", 24, 0); 31 img = al_load_bitmap("Img/stickanimation.png"); 32 33 hilite = al_create_shader(ALLEGRO_SHADER_AUTO); 34 bool shaderworks = al_attach_shader_source_file(hilite,ALLEGRO_PIXEL_SHADER,"Shaders/outlineshader.glsl"); 35 shaderworks = shaderworks && al_build_shader(hilite); 36 if (!shaderworks) { 37 std::cout << al_get_shader_log(hilite); 38 return -1; 39 } 40 41 timer = al_create_timer(1.0 / 60.0); 42 al_start_timer(timer); 43 al_install_keyboard(); 44 al_register_event_source(e_queue, al_get_keyboard_event_source()); 45 al_register_event_source(e_queue, al_get_display_event_source(display)); 46 al_register_event_source(e_queue, al_get_timer_event_source(timer)); 47 48 while (gameclose == 0) { 49 ALLEGRO_EVENT event; 50 al_wait_for_event(e_queue, &event); 51 if (event.type == ALLEGRO_EVENT_TIMER) { 52 update(); 53 }else { 54 if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { 55 gameclose = 1; 56 al_destroy_font(sansation); 57 } 58 else { 59 textredness++; 60 if (textredness > 255) 61 textredness = 255; 62 } 63 } 64 } 65 al_destroy_shader(hilite); 66 al_destroy_timer(timer); 67 al_destroy_display(display); 68 al_destroy_bitmap(img); 69 al_uninstall_keyboard(); 70 al_shutdown_image_addon(); 71 al_shutdown_ttf_addon(); 72 al_shutdown_font_addon(); 73 return 0; 74} 75void update() { 76 al_clear_to_color(al_map_rgb(0, 0, 0)); 77 al_draw_text(sansation, al_map_rgb(255, 255 - textredness, 255 - textredness), 5, 5, 0, "Hey, it looks like the window opened!"); 78 al_use_shader(hilite); 79 al_set_shader_float("bitmapHeight", al_get_bitmap_height(img)); 80 al_set_shader_float("bitmapWidth", al_get_bitmap_width(img)); 81 al_draw_bitmap(img,200,200,0); 82 al_use_shader(NULL); 83 al_flip_display(); 84 return; 85}

Any idea what this error message means or what I'm supposed to do about it? My guess is that the example code I'm trying to use is doing some kind of combined vertex shader/fragment shader thing, which is what the varying keyword is for- but I'm just writing a straight pixel shader to modify how a single bitmap is drawn to the screen. That example code, then, isn't exactly applicable, and I'm pretty sure the way I'm accessing source image pixels is wrong. I can use gl_FragCoord to get the coordinate of the target I'm drawing to, but what's the right way to tell which pixel of the source image is being drawn?

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Benedict
Member #16,937
January 2019

Thanks! That did it- I kind of ignored the vertex half of the example, since I assumed I wouldn't need it because I wasn't doing any 3D stuff. I don't totally understand why it works that way, but I'm happy enough to have it working.

Neil Roy
Member #2,229
April 2002
avatar

It works that way because there is a pipeline which all your graphics have to go through before they are displayed. When you use them you have to supply at least two of the shaders, the vertex and the fragment. There are actually more than that you can use as well. But those two are required if you use them.

---
“I love you too.” - last words of Wanda Roy

Go to: