![]() |
|
A shader that sets transparancy |
A. van Patmos
Member #15,349
October 2013
|
I'd like to use a shader to find out if vertices are inside a circle. If not make the vertex transparant. The following compiles and runs but simply shows the full image as I made it. 1// Fragment
2#version 420
3uniform sampler2D tex; // used texture unit
4varying vec2 v_texCoord; // x,y coordinates of point tested
5uniform float mx, my; // x,y coordinates of circle's centre
6
7// (x-mx)2+(y-my)2=r2 - points on circle
8// x2 - 2mx*x + mx2 + y2 - 2my*y + my2 = r2 - rewritten
9
10float Cirkel( vec2 p, float mx, float my )
11{
12// radius is 23px, r squared is 529
13 if(pow(p.x, 2) - 2*mx*p.x + pow(mx, 2) + pow(p.y, 2) - 2*my*p.y + pow(my, 2) < 529)
14 return 1.0;
15 else
16 return 0.0;
17}
18
19void main()
20{
21 gl_FragColor = texture2D(tex, v_texCoord);
22 gl_FragColor.a = Cirkel(v_texCoord, mx, my);
23}
and // Vertex #version 420 varying vec2 v_texCoord; void main() { v_texCoord = gl_MultiTexCoord0;// * 0.5;// kleinere factor vergroot meer gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; } Is this any good at all? Is it possible to use a mask image (white circle in black square) and let a shader do the filling in of the .a component? |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
The backbuffer alpha is undefined. Try drawing to a buffer first, then draw using normal alpha blender to the backbuffer. 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 |
Dizzy Egg
Member #10,824
March 2009
![]() |
This is the shader I use to achieve what you are asking for, but it's an Allegro shader not a pure openGl one - the circle function may be some help though: 1uniform sampler2D al_tex;
2varying vec4 varying_color;
3varying vec2 varying_texcoord;
4
5vec4 pixel;
6
7
8float circle(in vec2 coord, in float r){
9 vec2 dist = coord - vec2(0.5);
10 return 1.-smoothstep(r - (r * 0.01), r + (r * 0.01), dot(dist, dist) * 4.0);
11}
12
13void main()
14{
15 pixel = texture2D(al_tex, varying_texcoord);
16 pixel.a = circle(varying_texcoord, 0.9);
17
18 if(pixel.a == 0) {
19 pixel.r = 0;
20 pixel.g = 0;
21 pixel.b = 0;
22 }
23
24 gl_FragColor = pixel;
25}
This will draw a circle in a bitmap of any size, with the other pixels transparent.
---------------------------------------------------- |
A. van Patmos
Member #15,349
October 2013
|
The backbuffer alpha should be known and filled already I think. I have this: wtr = al_load_bitmap("data/voor.bmp"); tmp = al_create_bitmap(al_get_bitmap_width(wtr)*2, al_get_bitmap_height(wtr)*2); and 1while (1)
2{
3 al_wait_for_event(event_queue, &ev);
4
5 ALLEGRO_KEYBOARD_STATE s;
6 al_get_keyboard_state(&s);
7 if (al_key_down(&s, ALLEGRO_KEY_F8))
8 break;
9
10 al_set_target_bitmap(tmp);
11 al_use_shader(kijker);
12 al_set_shader_sampler("tex", wtr, 0);
13 al_set_shader_float("x" , x);
14 al_set_shader_float("y" , y);
15 al_draw_scaled_bitmap(wtr, 0, 0, al_get_bitmap_width(wtr), al_get_bitmap_height(wtr), 0, 0, al_get_bitmap_width(tmp), al_get_bitmap_height(tmp), 0);
16 al_use_shader(NULL);
17
18 al_set_target_backbuffer(display);
19 al_clear_to_color(al_map_rgb(215, 255, 255));
20 al_draw_bitmap(achtergrond, 64, 64, 0);
21 al_draw_bitmap(tmp, 120, 120, 0);
22 al_flip_display();
23
24 al_rest(0.01);
25}
I didn't occur to me to post this code. So wtr goes to the shader and it's result will be written to a four times larger bitmap tmp (yes, simulating a scope). I'll try Dizzy Eggs function for sure but I'd like to know what I'm doing wrong. - And it does the resize OK, but draws the full square. |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
>The backbuffer alpha should be known and filled already I think. I have this: No, it's not defined. The backbuffer may or may not have alpha, depending on the driver and how you set it up, so you can't draw alpha directly to the backbuffer and expect it to work. 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 |
Dizzy Egg
Member #10,824
March 2009
![]() |
You need to respect that the coordinates are 1.0/1.0 for the image in openGl, so you should probably use something like this (this assumes that wtr is 23x23 and tmp is 46x46): float Cirkel( vec2 p, float mx, float my ) { // mx and my will be 23,23 the centre of tmp p.x *= 46; //multiply by the size of tmp p.y *= 46; //multiply by the size of tmp p.y = 46-p.y; //offset for openGl coords if(pow(p.x, 2) - 2*mx*p.x + pow(mx, 2) + pow(p.y, 2) - 2*my*p.y + pow(my, 2) < 529) return 1.0; else return 0.0; } You always want to multiply p.x and p.y by the size of tmp, and set mx and my to the centre of tmp... EDIT: Also, make sure you set: al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); Before drawing, to make sure alpha will work properly with the shader.
---------------------------------------------------- |
A. van Patmos
Member #15,349
October 2013
|
I already had al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); before Edgar's second reply but forgot to post that. And I had done al_get_bitmap_format(al_get_target_bitmap() which reports 9, it is ALLEGRO_PIXEL_FORMAT_ARGB_8888 if read it right. It creates a bigger cirkle now always on a 93x93 bitmap. float Cirkel( vec2 p)//, float mx, float my ) { // mx and my will be 46.5,46.5 the centre of tmp, radius too is 46.5 p.x *= 93; //multiply by the size of tmp p.y *= 93; //multiply by the size of tmp p.y = 93-p.y; //offset for openGl coords //if(pow(p.x, 2) - 2*mx*p.x + pow(mx, 2) + pow(p.y, 2) - 2*my*p.y + pow(my, 2) < 529) if(pow(p.x, 2) - 93*p.x + pow(p.y, 2) - 93*p.y < -2162.25) return 1.0; else return 0.01; } But this is a great function, thanks. I can feed it a smaller image for more magnification. -edit: I redid the whole thing in a simpler program, now paying attention to do an al_clear_to_color(al_map_rgba_f(0.0, 0.0, 0.0, 0.0)); after setting tmp as target. That did it. |
|