Re: [AD] subtractive blending

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


On Thu, 2010-02-25 at 13:15 -0500, Evert Glebbeek wrote:
> On 25 Feb 2010, at 12:24 , Elias Pschernig wrote:
> > Thought a bit more about this and talked to Trent yesterday in IRC and
> > it's actually almost trivial to add. Took me about an hour making the
> > attached patch which allows subtractive blending for A5.
> 
> You didn't attach.Hm, I think I need to switch back to Thunderbird for its forgot-attachment addon :) Attached now.

> > We're also expecting a patch for a shaders addon from Dario FF any day
> > now so the whole blenders are obsolete - but if we are to keep them I'll
> > apply the patch and fix up the memory blenders as well.
> 
> I have a PM on ACC from him about it (haven't looked it over in detail yet).
> We should keep the simple blenders that we have now. I for one don't want to have to use a shader addon if all I want is blit a sprite with an alpha channel or change the colour of my font, to name just a few things.
> 

Ok, I see that as my signal to go on with it and work on the memory
implementation.


-- 
Elias Pschernig <elias.pschernig@xxxxxxxxxx>
diff --git a/addons/primitives/line_soft.c b/addons/primitives/line_soft.c
index f3b7619..ab18a19 100644
--- a/addons/primitives/line_soft.c
+++ b/addons/primitives/line_soft.c
@@ -487,10 +487,10 @@ void _al_line_2d(ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2
 {
    int shade = 1;
    int grad = 1;
-   int src_mode, dst_mode, src_alpha, dst_alpha;
+   int op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha;
    ALLEGRO_COLOR ic;
    
-   al_get_separate_blender(&src_mode, &dst_mode, &src_alpha, &dst_alpha, &ic);
+   al_get_separate_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha, &ic);
    if (src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE &&
       dst_mode == ALLEGRO_ZERO && dst_alpha == ALLEGRO_ZERO &&
          ic.r == 1.0f && ic.g == 1.0f && ic.b == 1.0f && ic.a == 1.0f) {
diff --git a/addons/primitives/point_soft.c b/addons/primitives/point_soft.c
index 07e8bfa..13cf295 100644
--- a/addons/primitives/point_soft.c
+++ b/addons/primitives/point_soft.c
@@ -36,10 +36,10 @@ static int fix_var(float var, int max_var)
 void _al_point_2d(ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX* v)
 {
    int shade = 1;
-   int src_mode, dst_mode;
+   int op, src_mode, dst_mode;
    ALLEGRO_COLOR ic;
 
-   al_get_blender(&src_mode, &dst_mode, &ic);
+   al_get_blender(&op, &src_mode, &dst_mode, &ic);
    if (src_mode == ALLEGRO_ONE && dst_mode == ALLEGRO_ZERO &&
          ic.r == 1.0f && ic.g == 1.0f && ic.b == 1.0f && ic.a == 1.0f) {
       shade = 0;
diff --git a/addons/primitives/prim_directx.c b/addons/primitives/prim_directx.c
index 15477c7..c8b45d9 100644
--- a/addons/primitives/prim_directx.c
+++ b/addons/primitives/prim_directx.c
@@ -69,11 +69,11 @@ static int al_blender_to_d3d(int al_mode)
 
 static void set_blender(ALLEGRO_DISPLAY *display)
 {
-   int src, dst, alpha_src, alpha_dst;
+   int op, src, dst, alpha_op, alpha_src, alpha_dst;
    ALLEGRO_COLOR color;
    LPDIRECT3DDEVICE9 device = al_d3d_get_device(display);
 
-   al_get_separate_blender(&src, &dst, &alpha_src, &alpha_dst, &color);
+   al_get_separate_blender(&op, &src, &dst, &alpha_op, &alpha_src, &alpha_dst, &color);
 
    src = al_blender_to_d3d(src);
    dst = al_blender_to_d3d(dst);
diff --git a/addons/primitives/prim_opengl.c b/addons/primitives/prim_opengl.c
index 0fbf388..5f81dc6 100644
--- a/addons/primitives/prim_opengl.c
+++ b/addons/primitives/prim_opengl.c
@@ -34,12 +34,12 @@ static void setup_blending(void)
    const int blend_modes[4] = {
       GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
    };
-   int src_color, dst_color, src_alpha, dst_alpha;
+   int op, src_color, dst_color, op_alpha, src_alpha, dst_alpha;
    ALLEGRO_DISPLAY *d = al_get_current_display();
    (void)d;
 
-   al_get_separate_blender(&src_color, &dst_color, &src_alpha,
-      &dst_alpha, NULL);
+   al_get_separate_blender(&op, &src_color, &dst_color,
+      &op_alpha, &src_alpha, &dst_alpha, NULL);
 #if !defined ALLEGRO_GP2XWIZ && !defined ALLEGRO_IPHONE
    if (d->ogl_extras->ogl_info.version >= 1.4) {
       glEnable(GL_BLEND);
diff --git a/addons/primitives/tri_soft.c b/addons/primitives/tri_soft.c
index 828588f..855b67d 100644
--- a/addons/primitives/tri_soft.c
+++ b/addons/primitives/tri_soft.c
@@ -836,10 +836,10 @@ void _al_triangle_2d(ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX
 {
    int shade = 1;
    int grad = 1;
-   int src_mode, dst_mode;
+   int op, src_mode, dst_mode;
    ALLEGRO_COLOR ic;
 
-   al_get_blender(&src_mode, &dst_mode, &ic);
+   al_get_blender(&op, &src_mode, &dst_mode, &ic);
    if (src_mode == ALLEGRO_ONE && dst_mode == ALLEGRO_ZERO &&
          ic.r == 1.0f && ic.g == 1.0f && ic.b == 1.0f && ic.a == 1.0f) {
       shade = 0;
diff --git a/demo/src/GUI.cpp b/demo/src/GUI.cpp
index 3ec4b83..bf71b98 100644
--- a/demo/src/GUI.cpp
+++ b/demo/src/GUI.cpp
@@ -36,10 +36,10 @@ int do_gui(std::vector<Widget *>& widgets, unsigned int selected)
          0);
       al_draw_rotated_bitmap(logo, lw/2, lh/2, BB_W/2, BB_H/4, 0.0f, 0);
 
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
          al_map_rgb(255, 255, 0));
       al_draw_textf(myfont, BB_W/2, BB_H/2, ALLEGRO_ALIGN_CENTRE, "z/y to start");
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
          al_map_rgb(255, 255, 255));
 
       for (unsigned int i = 0; i < widgets.size(); i++) {
diff --git a/demo/src/render.cpp b/demo/src/render.cpp
index 60a819a..fcbb87c 100644
--- a/demo/src/render.cpp
+++ b/demo/src/render.cpp
@@ -100,9 +100,9 @@ void render(int step)
       Entity *e = *it;
       e->render_four();
       if (e->isHighlighted()) {
-         al_set_blender(ALLEGRO_ALPHA, ALLEGRO_ONE, al_map_rgb(150, 150, 150));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_ONE, al_map_rgb(150, 150, 150));
          e->render_four();
-         al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
             al_map_rgb(255, 255, 255));
       }
       rendered++;
diff --git a/examples/ex_bitmap_flip.c b/examples/ex_bitmap_flip.c
index abf26eb..2998850 100644
--- a/examples/ex_bitmap_flip.c
+++ b/examples/ex_bitmap_flip.c
@@ -121,17 +121,17 @@ int main(void)
 
    /* opaque: software version matches hardware version */
    /*
-   al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
    */
 
    /* XXX dest zero: software version much darker */
    /*
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_ZERO,
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_ZERO,
       al_map_rgba_f(1, 1, 1, 0.5));
    */
 
    /* XXX: software version darker */
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
       al_map_rgba_f(1, 1, 1, 0.5));
 
    while (!done) {
diff --git a/examples/ex_bitmap_target.c b/examples/ex_bitmap_target.c
index 5b724e2..ecb639e 100644
--- a/examples/ex_bitmap_target.c
+++ b/examples/ex_bitmap_target.c
@@ -31,10 +31,10 @@ static void print(int x, int y, char const *format, ...)
    vsnprintf(message, sizeof message, format, list);
    va_end(list);
 
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgb(0, 0, 0));
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgb(0, 0, 0));
    al_draw_text(myfont, x + 2, y + 2, 0, message);
 
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
       al_map_rgb(255, 255, 255));
    al_draw_text(myfont, x, y, 0, message);
 }
@@ -51,7 +51,7 @@ static void draw(void)
    last_time = t;
 
    al_set_target_bitmap(target);
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
       al_map_rgba_f(1, 1, 1, 1));
 
    al_draw_filled_rectangle(x, y, x + RW, y + RH, al_map_rgba_f(1, 0, 0, 1));
@@ -77,7 +77,7 @@ static void draw(void)
    }
 
    al_set_target_bitmap(al_get_backbuffer());
-   al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
    al_clear_to_color(al_map_rgba_f(0, 0, 1, 1));
    xs = 1 + 0.2 * sin(t * ALLEGRO_PI * 2);
    ys = 1 + 0.2 * sin(t * ALLEGRO_PI * 2);
diff --git a/examples/ex_blend.c b/examples/ex_blend.c
index e72fd86..c303536 100644
--- a/examples/ex_blend.c
+++ b/examples/ex_blend.c
@@ -48,7 +48,7 @@ static void print(int x, int y, bool vertical, char const *format, ...)
       else
          color = al_map_rgb(255, 255, 255);
 
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, color);
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, color);
       if (vertical) {
          int i;
          ALLEGRO_USTR_INFO ui;
@@ -141,7 +141,7 @@ static void draw(void)
       print(20, y + i * 110, true, blend_vnames[i]);
    }
 
-   al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, white);
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, white);
    if (ex.mode >= 1 && ex.mode <= 5) {
       al_set_target_bitmap(ex.offscreen);
       al_clear_to_color(test[ex.mode - 1]);
@@ -153,7 +153,7 @@ static void draw(void)
 
    for (j = 0; j < 4; j++) {
       for (i = 0; i < 4; i++) {
-         al_set_blender(blend_modes[j], blend_modes[i], blendcolor);
+         al_set_blender(ALLEGRO_ADD, blend_modes[j], blend_modes[i], blendcolor);
          if (ex.image == 0)
             al_draw_bitmap(ex.example, x + i * 110, y + j * 110, 0);
          else if (ex.image >= 1 && ex.image <= 6) {
@@ -164,12 +164,12 @@ static void draw(void)
    }
 
    if (ex.mode >= 1 && ex.mode <= 5) {
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, white);
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, white);
       al_set_target_bitmap(target);
       al_draw_bitmap_region(ex.offscreen, x, y, 430, 430, x, y, 0);
    }
    if (ex.mode >= 6 && ex.mode <= 10) {
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, white);
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, white);
       al_set_target_bitmap(target);
       al_draw_bitmap_region(ex.memory, x, y, 430, 430, x, y, 0);
    }
diff --git a/examples/ex_blend2.cpp b/examples/ex_blend2.cpp
index cec845a..1034ffa 100644
--- a/examples/ex_blend2.cpp
+++ b/examples/ex_blend2.cpp
@@ -31,8 +31,8 @@ private:
    Label blending_label;
    List source_image;
    List destination_image;
-   Label operation_label[4];
-   List operations[4];
+   Label operation_label[6];
+   List operations[6];
    VSlider r[3];
    VSlider g[3];
    VSlider b[3];
@@ -72,14 +72,21 @@ Prog::Prog(const Theme & theme, ALLEGRO_DISPLAY *display) :
       d.add(image, 1 + i * 6, 21, 4, 4);
    }
 
-   for (int i = 0; i < 4; i++) {
+   for (int i = 0; i < 6; i++) {
       operation_label[i] = Label(i % 2 == 0 ? "Color" : "Alpha", false);
       d.add(operation_label[i], 1 + i * 3, 25, 3, 2);
       List &l = operations[i];
-      l.append_item("ONE");
-      l.append_item("ZERO");
-      l.append_item("ALPHA");
-      l.append_item("INVERSE");
+      if (i < 4) {
+         l.append_item("ONE");
+         l.append_item("ZERO");
+         l.append_item("ALPHA");
+         l.append_item("INVERSE");
+      }
+      else {
+         l.append_item("ADD");
+         l.append_item("SRC_MINUS_DEST");
+         l.append_item("DEST_MINUS_SRC");
+      }
       d.add(l, 1 + i * 3, 27, 3, 6);
    }
 
@@ -121,6 +128,12 @@ int str_to_blend_mode(const std::string & str)
       return ALLEGRO_ALPHA;
    if (str == "INVERSE")
       return ALLEGRO_INVERSE_ALPHA;
+   if (str == "ADD")
+      return ALLEGRO_ADD;
+   if (str == "SRC_MINUS_DEST")
+      return ALLEGRO_SRC_MINUS_DEST;
+   if (str == "DEST_MINUS_SRC")
+      return ALLEGRO_DEST_MINUS_SRC;
 
    ALLEGRO_ASSERT(false);
    return ALLEGRO_ONE;
@@ -163,6 +176,8 @@ void Prog::draw_bitmap(const std::string & str, bool memory,
 void Prog::blending_test(bool memory)
 {
    ALLEGRO_COLOR opaque_white = al_map_rgba_f(1, 1, 1, 1);
+   int op = str_to_blend_mode(operations[4].get_selected_item_text());
+   int aop = str_to_blend_mode(operations[5].get_selected_item_text());
    int src = str_to_blend_mode(operations[0].get_selected_item_text());
    int asrc = str_to_blend_mode(operations[1].get_selected_item_text());
    int dst = str_to_blend_mode(operations[2].get_selected_item_text());
@@ -174,11 +189,11 @@ void Prog::blending_test(bool memory)
 
    /* Initialize with destination. */
    al_clear_to_color(opaque_white); // Just in case.
-   al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, opaque_white);
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, opaque_white);
    draw_bitmap(destination_image.get_selected_item_text(), memory, true);
 
    /* Now draw the blended source over it. */
-   al_set_separate_blender(src, dst, asrc, adst,
+   al_set_separate_blender(op, src, dst, aop, asrc, adst,
       al_map_rgba(rv, gv, bv, av));
    draw_bitmap(source_image.get_selected_item_text(), memory, false);
 }
@@ -203,7 +218,7 @@ void Prog::draw_samples()
 
    /* Display results. */
    al_set_target_bitmap(al_get_backbuffer());
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
       al_map_rgba(255, 255, 255, 255));
    al_draw_bitmap(target, 0, 20, 0);
    al_draw_bitmap(target_bmp, 320, 20, 0);
diff --git a/examples/ex_blend_bench.c b/examples/ex_blend_bench.c
index 9c5bd32..820640c 100644
--- a/examples/ex_blend_bench.c
+++ b/examples/ex_blend_bench.c
@@ -101,14 +101,14 @@ int main(int argc, const char *argv[])
    }
 
    al_set_target_bitmap(b1);
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
       al_map_rgba_f(1, 1, 1, 0.5));
    step(mode, b2);
 
    /* Display the blended bitmap to the screen so we can see something. */
    al_store_state(&state, ALLEGRO_STATE_ALL);
    al_set_target_bitmap(al_get_backbuffer());
-   al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
    al_draw_bitmap(b1, 0, 0, 0);
    al_flip_display();
    al_restore_state(&state);
diff --git a/examples/ex_blend_test.c b/examples/ex_blend_test.c
index 15becc2..3af477a 100644
--- a/examples/ex_blend_test.c
+++ b/examples/ex_blend_test.c
@@ -26,7 +26,7 @@ static ALLEGRO_COLOR test(ALLEGRO_COLOR src_col, ALLEGRO_COLOR dst_col,
 
    al_set_new_bitmap_format(dst_format);
    al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
-   al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgb_f(1, 1, 1));
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgb_f(1, 1, 1));
    dst_bmp = al_create_bitmap(1, 1);
    al_set_target_bitmap(dst_bmp);
    al_clear_to_color(dst_col);
@@ -37,16 +37,16 @@ static ALLEGRO_COLOR test(ALLEGRO_COLOR src_col, ALLEGRO_COLOR dst_col,
       al_set_target_bitmap(src_bmp);
       al_clear_to_color(src_col);
       al_set_target_bitmap(dst_bmp);
-      al_set_separate_blender(src, dst, src_a, dst_a, blend);
+      al_set_separate_blender(ALLEGRO_ADD, src, dst, ALLEGRO_ADD, src_a, dst_a, blend);
       al_draw_bitmap(src_bmp, 0, 0, 0);
       al_destroy_bitmap(src_bmp);
    }
    else  if (operation == 1) {
-      al_set_separate_blender(src, dst, src_a, dst_a, blend);
+      al_set_separate_blender(ALLEGRO_ADD, src, dst, ALLEGRO_ADD, src_a, dst_a, blend);
       al_draw_pixel(0, 0, src_col);
    }
    else  if (operation == 2) {
-      al_set_separate_blender(src, dst, src_a, dst_a, blend);
+      al_set_separate_blender(ALLEGRO_ADD, src, dst, ALLEGRO_ADD, src_a, dst_a, blend);
       al_draw_line(0, 0, 1, 1, src_col, 0);
    }
 
@@ -54,7 +54,7 @@ static ALLEGRO_COLOR test(ALLEGRO_COLOR src_col, ALLEGRO_COLOR dst_col,
 
    if (test_display) {
       al_set_target_bitmap(al_get_backbuffer());
-      al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgb_f(1, 1, 1));
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgb_f(1, 1, 1));
       al_draw_bitmap(dst_bmp, 0, 0, 0);
    }
 
diff --git a/examples/ex_blit.c b/examples/ex_blit.c
index 32b895f..c878958 100644
--- a/examples/ex_blit.c
+++ b/examples/ex_blit.c
@@ -72,7 +72,7 @@ static void print(char const *format, ...)
    vsnprintf(message, sizeof message, format, list);
    va_end(list);
    
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ex.text);
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ex.text);
    al_draw_textf(ex.font, ex.text_x, ex.text_y, 0, "%s", message);
    al_restore_state(&state);
    
@@ -107,7 +107,7 @@ static void draw(void)
    void *data;
    int size, i, format;
    
-   al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, ex.white);
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, ex.white);
 
    al_clear_to_color(ex.background);
 
diff --git a/examples/ex_clip.c b/examples/ex_clip.c
index b90b4b1..f4c29d8 100644
--- a/examples/ex_clip.c
+++ b/examples/ex_clip.c
@@ -80,7 +80,7 @@ static void print(char const *format, ...)
    vsnprintf(message, sizeof message, format, list);
    va_end(list);
    
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ex.text);
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ex.text);
    al_draw_textf(ex.font, ex.text_x, ex.text_y, 0, "%s", message);
    al_restore_state(&state);
    
@@ -115,7 +115,7 @@ static void draw(void)
    
    al_get_clipping_rectangle(&cx, &cy, &cw, &ch);
    
-   al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, ex.white);
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, ex.white);
 
    al_clear_to_color(ex.background);
 
diff --git a/examples/ex_color.cpp b/examples/ex_color.cpp
index 1b619d0..2e6c5ae 100644
--- a/examples/ex_color.cpp
+++ b/examples/ex_color.cpp
@@ -139,7 +139,7 @@ void Prog::run()
          al_color_rgb_to_html(v[0], v[1], v[2], html);
          ALLEGRO_STATE state;
          al_store_state(&state, ALLEGRO_STATE_ALL);
-         al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
             al_map_rgb(0, 0, 0));
          al_draw_text(d.get_theme().font, 0, 380, 0, name);
          al_draw_text(d.get_theme().font, 0, 360, 0, html);
diff --git a/examples/ex_display_options.c b/examples/ex_display_options.c
index 5293411..3fb695a 100644
--- a/examples/ex_display_options.c
+++ b/examples/ex_display_options.c
@@ -62,7 +62,7 @@ static void display_options(void)
 
    ALLEGRO_COLOR c;
    c = al_map_rgb_f(0.8, 0.8, 1);
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, c);
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, c);
    al_draw_textf(font, x, y, 0, "Create new display");
    y += font_h;
    for (i = 0; i < modes_count + 1; i++) {
@@ -78,11 +78,11 @@ static void display_options(void)
       }
       if (selected_column == 0 && selected_mode == i) {
          c = al_map_rgb_f(1, 1, 0);
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, white);
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, white);
          al_draw_filled_rectangle(x, y, x + 300, y + font_h, c);
       }
       c = al_map_rgb_f(0, 0, 0);
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, c);
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, c);
       al_draw_textf(font, x, y, 0, "%s %d x %d (%d, %d)",
          i < modes_count ? "Fullscreen" : "Windowed",
          mode.width,
@@ -93,14 +93,14 @@ static void display_options(void)
    x = dw / 2 + 10;
    y = 10;
    c = al_map_rgb_f(0.8, 0.8, 1);
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, c);
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, c);
    al_draw_textf(font, x, y, 0, "Options for new display");
    al_draw_textf(font, dw - 10, y, ALLEGRO_ALIGN_RIGHT, "(current display)");
    y += font_h;
    for (i = 0; i < n; i++) {
       if (selected_column == 1 && selected_option == i) {
          c = al_map_rgb_f(1, 1, 0);
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, white);
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, white);
          al_draw_filled_rectangle(x, y, x + 300, y + font_h, c);
       }
 
@@ -109,7 +109,7 @@ static void display_options(void)
          case ALLEGRO_SUGGEST: c = al_map_rgb_f(0, 0, 0); break;
          case ALLEGRO_DONTCARE: c = al_map_rgb_f(0.5, 0.5, 0.5); break;
       }
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, c);
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, c);
       al_draw_textf(font, x, y, 0, "%s: %d (%s)", options[i].name,
          options[i].value,
             options[i].required == ALLEGRO_REQUIRE ? "required" :
@@ -117,14 +117,14 @@ static void display_options(void)
             "ignored");
             
       c = al_map_rgb_f(0.9, 0.5, 0.3);
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, c);
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, c);
       al_draw_textf(font, dw - 10, y, ALLEGRO_ALIGN_RIGHT, "%d",
          al_get_display_option(options[i].option));
       y += font_h;
    }
    
    c = al_map_rgb_f(0, 0, 0.8);
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, c);
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, c);
    x = 10;
    y = dh - font_h - 10;
    y -= font_h;
@@ -135,7 +135,7 @@ static void display_options(void)
    al_draw_textf(font, x, y, 0, "Cursor keys: change selection");
    
    c = al_map_rgb_f(1, 0, 0);
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, c);
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, c);
    al_draw_text(font, dw / 2, dh - font_h, ALLEGRO_ALIGN_CENTRE, status);
 }
 
diff --git a/examples/ex_draw.c b/examples/ex_draw.c
index d323c5b..f5712d4 100644
--- a/examples/ex_draw.c
+++ b/examples/ex_draw.c
@@ -81,7 +81,7 @@ static void print(char const *format, ...)
    vsnprintf(message, sizeof message, format, list);
    va_end(list);
    
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ex.text);
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ex.text);
    al_draw_textf(ex.font, ex.text_x, ex.text_y, 0, "%s", message);
    al_restore_state(&state);
    
@@ -137,7 +137,7 @@ static void draw(void)
    set_xy(80, 16);
    print("Enlarged x 16");
 
-   al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, ex.white);
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, ex.white);
 
    if (ex.software) {
       al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
@@ -156,7 +156,7 @@ static void draw(void)
 
    /* Draw the test scene. */
 
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
       al_map_rgba_f(1, 1, 1, 0.5));
    for (i = 0; i < rects_num; i++) {
       primitive(
@@ -167,7 +167,7 @@ static void draw(void)
          ex.foreground, false);
    }
 
-   al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, ex.white);
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, ex.white);
 
    if (ex.software) {
       al_set_target_bitmap(screen);
diff --git a/examples/ex_draw_bitmap.c b/examples/ex_draw_bitmap.c
index 70da789..a1828b0 100644
--- a/examples/ex_draw_bitmap.c
+++ b/examples/ex_draw_bitmap.c
@@ -121,7 +121,7 @@ static void change_size(int size)
    example.bitmap = al_create_bitmap(size, size);
    example.bitmap_size = size;
    al_set_target_bitmap(example.bitmap);
-   al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, example.white);
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, example.white);
    al_clear_to_color(al_map_rgba_f(0, 0, 0, 0));
    bw = al_get_bitmap_width(example.mysha);
    bh = al_get_bitmap_height(example.mysha);
@@ -177,20 +177,20 @@ static void redraw(void)
    char const *binfo[] = {"alpha", "additive", "tinted", "solid"};
 
    if (example.blending == 0)
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, example.half_white);
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, example.half_white);
    else if (example.blending == 1)
-      al_set_blender(ALLEGRO_ONE, ALLEGRO_ONE, example.dark);
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, example.dark);
    else if (example.blending == 2)
-      al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, example.red);
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, example.red);
    else if (example.blending == 3)
-      al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, example.white);
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, example.white);
 
    for (i = 0; i < example.sprite_count; i++) {
       Sprite *s = example.sprites + i;
       al_draw_bitmap(example.bitmap, s->x, s->y, 0);
    }
 
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, example.white);
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, example.white);
    if (example.show_help) {
       for (i = 0; i < 5; i++)
          al_draw_text(example.font, 0, h - 5 * fh + i * fh, 0, text[i]);
diff --git a/examples/ex_expose.c b/examples/ex_expose.c
index bbf0e9a..f76831a 100644
--- a/examples/ex_expose.c
+++ b/examples/ex_expose.c
@@ -67,14 +67,14 @@ int main(void)
             w = event.display.width,
             h = event.display.height;
          /* Draw a red rectangle over the damaged area. */
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
          al_draw_filled_rectangle(x, y, x + w, y + h, al_map_rgba_f(1, 0, 0, 1));
          al_flip_display();
       }
       if (event.type == ALLEGRO_EVENT_TIMER) {
          /* Slowly restore the original bitmap. */
          int x, y;
-         al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
             al_map_rgba_f(1, 1, 1, 0.1));
          for (y = 0; y < al_get_display_height(); y += 200) {
             for (x = 0; x < al_get_display_width(); x += 320) {
diff --git a/examples/ex_font.c b/examples/ex_font.c
index 3eff2e9..f1751db 100644
--- a/examples/ex_font.c
+++ b/examples/ex_font.c
@@ -27,7 +27,7 @@ static void wait_for_esc(void)
          int y = event.display.y;
          int w = event.display.width;
          int h = event.display.height;
-         al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
             al_map_rgb_f(1, 1, 1));
          al_draw_bitmap_region(screen_clone, x, y, w, h,
             x, y, 0);
@@ -87,17 +87,17 @@ int main(void)
     al_draw_bitmap(bitmap, 0, 0, 0);
 
     /* Draw red text */
-    al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+    al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
       al_map_rgb(255, 0, 0));
     al_draw_textf(f, 10, 10, 0, "red");
 
     /* Draw green text */
-    al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+    al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
       al_map_rgb(0, 255, 0));
     al_draw_textf(f, 10, 50, 0, "green");
     
     /* Draw a unicode symbol */
-    al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+    al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
       al_map_rgb(0, 0, 255));
     al_draw_textf(a4f, 10, 90, 0, "Mysha's 0.02€");
 
diff --git a/examples/ex_gldepth.c b/examples/ex_gldepth.c
index ba09144..9f34cf6 100644
--- a/examples/ex_gldepth.c
+++ b/examples/ex_gldepth.c
@@ -159,7 +159,7 @@ static void setup_textures(void)
    al_draw_scaled_bitmap(tmp_bmp,
                          0, 0, al_get_bitmap_width(bmp), al_get_bitmap_height(bmp),
                          0, 0, w, h, 0);
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgb(255, 0, 0));
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgb(255, 0, 0));
    depth = al_get_display_option(ALLEGRO_DEPTH_SIZE);
    if (!depth)
       al_draw_textf(font, 0, 5, 0, "No Z-buffer!");
diff --git a/examples/ex_keyboard_events.c b/examples/ex_keyboard_events.c
index acb0536..5469507 100644
--- a/examples/ex_keyboard_events.c
+++ b/examples/ex_keyboard_events.c
@@ -62,7 +62,7 @@ static void draw_message_log(void)
    int y;
    int i;
 
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, black);
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, black);
 
    al_draw_text(myfont, 5, th * 0.5, 0, "EVENT KEY CHR UNICODE  [MODIFIERS]  KEY NAME");
 
@@ -84,7 +84,7 @@ static void draw_message_log(void)
       }
    }
 
-   al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, white);
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, white);
 }
 
 
diff --git a/examples/ex_lines.c b/examples/ex_lines.c
index 85d6ce1..53cef65 100644
--- a/examples/ex_lines.c
+++ b/examples/ex_lines.c
@@ -35,7 +35,7 @@ int last_y = -1;
 
 static void fade(void)
 {
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, background);
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, background);
    al_draw_filled_rectangle(0, 0, W, H, al_map_rgba_f(0.5, 0.5, 0.6, 0.2));
 }
 
@@ -68,7 +68,7 @@ static void plonk(const int x, const int y, bool blend)
 #endif
 
    fade();
-   al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, white);
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, white);
    draw_clip_rect();
    red_dot(x, y);
 
@@ -79,7 +79,7 @@ static void plonk(const int x, const int y, bool blend)
    else {
       my_set_clip_rect();
       if (blend) {
-         al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
             al_map_rgb_f(0.5, 1, 1));
       }
       al_draw_line(last_x, last_y, x, y, white, 0);
@@ -106,13 +106,13 @@ static void splat(const int x, const int y, bool blend)
 #endif
 
    fade();
-   al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, white);
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, white);
    draw_clip_rect();
    red_dot(x, y);
 
    my_set_clip_rect();
    if (blend) {
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
          al_map_rgb_f(0.5, 1, 1));
    }
    for (theta = 0.0; theta < 2.0 * ALLEGRO_PI; theta += ALLEGRO_PI/16.0) {
diff --git a/examples/ex_logo.c b/examples/ex_logo.c
index 6957a99..d2589e2 100644
--- a/examples/ex_logo.c
+++ b/examples/ex_logo.c
@@ -99,8 +99,8 @@ static ALLEGRO_BITMAP *generate_logo(char const *text,
    br = blur_radius;
    bw = br * 2 + 1;
    c = al_map_rgba_f(1, 1, 1, 1.0 / (bw * bw * blur_factor));
-   al_set_separate_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
-                           ALLEGRO_ONE, ALLEGRO_ONE, c);
+   al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+                           ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, c);
    for (i = -br; i <= br; i++) {
       for (j = -br; j <= br; j++) {
          al_draw_text(logofont,
@@ -159,8 +159,8 @@ static ALLEGRO_BITMAP *generate_logo(char const *text,
 
    /* Draw a shadow. */
    c = al_map_rgba_f(0, 0, 0, 0.5 / 9);
-   al_set_separate_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
-                           ALLEGRO_ONE, ALLEGRO_ONE, c);
+   al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+                           ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, c);
    for (i = -1; i <= 1; i++)
       for (j = -1; j <= 1; j++)
          al_draw_text(logofont,
@@ -169,8 +169,8 @@ static ALLEGRO_BITMAP *generate_logo(char const *text,
                          0, text);
 
    /* Then draw the lit text we made before on top. */
-   al_set_separate_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
-                           ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, white);
+   al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+                           ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, white);
    al_draw_bitmap(light, 0, 0, 0);
    al_destroy_bitmap(light);
 
@@ -211,29 +211,29 @@ static void print_parameters(void)
 
    th = al_get_font_line_height(font) + 3;
    for (i = 0; param_names[i]; i++) {
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, label);
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, label);
       al_draw_textf(font, 2, 2 + i * th, 0, "%s", param_names[i]);
    }
    for (i = 0; param_names[i]; i++) {
       int y = 2 + i * th;
       // FIXME: additive blending seems broken here when using
       // memory blenders (i.e. no FBO available)
-      // al_set_blender(ALLEGRO_ONE, ALLEGRO_ONE, white)
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, white);
+      // al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, white)
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, white);
       al_draw_filled_rectangle(75, y, 375, y + th - 2,
                         al_map_rgba_f(1, 1, 1, 0.5));
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
                      i == selection ? light : normal);
       al_draw_textf(font, 75, y, 0, "%s", param_values[i]);
       if (i == selection && editing &&
          (((int)(al_current_time() * 2)) & 1)) {
          int x = 75 + al_get_text_width(font, param_values[i]);
-         al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, normal);
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, normal);
          al_draw_line(x, y, x, y + th, white, 0);
       }
    }
 
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, normal);
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, normal);
    al_draw_textf(font, 400, 2, 0, "%s", "R - Randomize");
    al_draw_textf(font, 400, 2 + th, 0, "%s", "S - Save as logo.png");
 
@@ -372,10 +372,10 @@ static void render(void)
       w = al_get_bitmap_width(logo);
       h = al_get_bitmap_height(logo);
       al_store_state(&state, ALLEGRO_STATE_BLENDER);
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
                      al_map_rgba_f(1, 1, 1, 1 - f));
       al_draw_bitmap(logo, logo_x, logo_y, 0);
-      al_set_blender(ALLEGRO_ONE, ALLEGRO_ONE, c);
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, c);
       for (j = -2; j <= 2; j += 2) {
          for (i = -2; i <= 2; i += 2) {
             al_draw_bitmap(logo_flash, logo_x + i, logo_y + j, 0);
diff --git a/examples/ex_membmp.c b/examples/ex_membmp.c
index 828aa19..05fad72 100644
--- a/examples/ex_membmp.c
+++ b/examples/ex_membmp.c
@@ -8,10 +8,10 @@
 
 static void print(ALLEGRO_FONT *myfont, char *message, int x, int y)
 {
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgb(0, 0, 0));
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgb(0, 0, 0));
    al_draw_text(myfont, x+2, y+2, 0, message);
 
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
       al_map_rgb(255, 255, 255));
    al_draw_text(myfont, x, y, 0, message);
 }
@@ -44,7 +44,7 @@ static bool test(ALLEGRO_BITMAP *bitmap, ALLEGRO_FONT *font, char *message)
          }
       }
 
-      al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO,
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO,
          al_map_rgb(255, 255, 255));
 
       /* Clear the backbuffer with red so we can tell if the bitmap does not
diff --git a/examples/ex_mouse_cursor.c b/examples/ex_mouse_cursor.c
index 84f900e..4cfbf70 100644
--- a/examples/ex_mouse_cursor.c
+++ b/examples/ex_mouse_cursor.c
@@ -55,7 +55,7 @@ static void draw_display(ALLEGRO_FONT *font)
    al_set_target_bitmap(al_get_backbuffer());
    al_clear_to_color(al_map_rgb(128, 128, 128));
 
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgba_f(0, 0, 0, 1));
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgba_f(0, 0, 0, 1));
    th = al_get_font_line_height(font);
    for (i = 0; i < NUM_CURSORS; i++) {
       al_draw_text(font, MARGIN_LEFT, MARGIN_TOP + i * th, 0, cursor_list[i].label);
diff --git a/examples/ex_mouse_events.c b/examples/ex_mouse_events.c
index 48398ef..c5c8410 100644
--- a/examples/ex_mouse_events.c
+++ b/examples/ex_mouse_events.c
@@ -90,12 +90,12 @@ int main(void)
             draw_mouse_button(i, buttons[i]);
          }
          al_draw_bitmap(cursor, mx, my, 0);
-         al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
             al_map_rgb_f(0, 0, 0));
          al_draw_textf(font, 5, 5, 0, "dx %i, dy %i, dz %i, dw %i", mmx, mmy, mmz, mmw);
          al_draw_textf(font, 5, 15, 0, "x %i, y %i, z %i, w %i", mx, my, mz, mw);
          al_draw_textf(font, 5, 25, 0, "%s", in ? "in" : "out");
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA,
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA,
             al_map_rgb_f(1, 1, 1));
          mmx = mmy = mmz = 0;
          al_flip_display();
diff --git a/examples/ex_native_filechooser.c b/examples/ex_native_filechooser.c
index f77cfaf..02c0965 100644
--- a/examples/ex_native_filechooser.c
+++ b/examples/ex_native_filechooser.c
@@ -157,7 +157,7 @@ static void show_files_list(ALLEGRO_NATIVE_DIALOG *dialog,
 
       path = al_get_native_file_dialog_path(dialog, i);
       name = al_path_cstr(path, '/');
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, info);
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, info);
       al_draw_textf(font, x, y + i * th, ALLEGRO_ALIGN_CENTRE, name, 0, 0);
    }
 }
@@ -277,7 +277,7 @@ restart:
          float y = 0;
          redraw = false;
          al_clear_to_color(background);
-         al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
                         cur_dialog ? inactive : active);
          al_draw_textf(font, x, y, ALLEGRO_ALIGN_CENTRE, "Open");
          if (old_dialog)
diff --git a/examples/ex_pixelformat.cpp b/examples/ex_pixelformat.cpp
index 4b5859f..4f6b62d 100644
--- a/examples/ex_pixelformat.cpp
+++ b/examples/ex_pixelformat.cpp
@@ -161,7 +161,7 @@ void Prog::draw_sample()
       printf("Could not create bitmap, format = %d\n", formats[j].format);
    }
 
-   al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgb(255, 255, 255));
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgb(255, 255, 255));
 
    if (bitmap1 && bitmap2) {
       al_set_target_bitmap(bitmap2);
diff --git a/examples/ex_prim.c b/examples/ex_prim.c
index 60620c0..570069e 100644
--- a/examples/ex_prim.c
+++ b/examples/ex_prim.c
@@ -85,14 +85,14 @@ static void CustomVertexFormatPrimitives(int mode)
       Theta += Speed;
       al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta);
    } else if (mode == DRAW) {
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgba_f(1, 1, 1, 1));
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgba_f(1, 1, 1, 1));
       
       al_draw_textf(Font, ScreenW / 2, ScreenH - 20, ALLEGRO_ALIGN_CENTRE, "Custom Vertex Format");
       
       if (Blend)
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ONE, al_map_rgba_f(1, 1, 1, 1));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, al_map_rgba_f(1, 1, 1, 1));
       else
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
       
       al_use_transform(&MainTrans);
       
@@ -130,14 +130,14 @@ static void TexturePrimitives(int mode)
       Theta += Speed;
       al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta);
    } else if (mode == DRAW) {
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgba_f(1, 1, 1, 1));
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgba_f(1, 1, 1, 1));
       
       al_draw_textf(Font, ScreenW / 2, ScreenH - 20, ALLEGRO_ALIGN_CENTRE, "Textured Primitives");
       
       if (Blend)
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ONE, al_map_rgba_f(1, 1, 1, 1));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, al_map_rgba_f(1, 1, 1, 1));
       else
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
       
       al_use_transform(&MainTrans);
       
@@ -184,14 +184,14 @@ static void FilledTexturePrimitives(int mode)
       Theta += Speed;
       al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta);
    } else if (mode == DRAW) {
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgba_f(1, 1, 1, 1));
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgba_f(1, 1, 1, 1));
       
       al_draw_textf(Font, ScreenW / 2, ScreenH - 20, ALLEGRO_ALIGN_CENTRE, "Filled Textured Primitives");
       
       if (Blend)
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ONE, al_map_rgba_f(1, 1, 1, 1));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, al_map_rgba_f(1, 1, 1, 1));
       else
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
   
       al_use_transform(&MainTrans);
       
@@ -232,14 +232,14 @@ static void FilledPrimitives(int mode)
       Theta += Speed;
       al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta);
    } else if (mode == DRAW) {
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgba_f(1, 1, 1, 1));
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgba_f(1, 1, 1, 1));
       
       al_draw_textf(Font, ScreenW / 2, ScreenH - 20, ALLEGRO_ALIGN_CENTRE, "Low Level Filled Primitives");
       
       if (Blend)
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ONE, al_map_rgba_f(1, 1, 1, 1));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, al_map_rgba_f(1, 1, 1, 1));
       else
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
       
       al_use_transform(&MainTrans);
       
@@ -291,14 +291,14 @@ static void IndexedFilledPrimitives(int mode)
       
       al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta);
    } else if (mode == DRAW) {
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgba_f(1, 1, 1, 1));
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgba_f(1, 1, 1, 1));
       
       al_draw_textf(Font, ScreenW / 2, ScreenH - 20, ALLEGRO_ALIGN_CENTRE, "Indexed Filled Primitives");
       
       if (Blend)
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ONE, al_map_rgba_f(1, 1, 1, 1));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, al_map_rgba_f(1, 1, 1, 1));
       else
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
       
       al_use_transform(&MainTrans);
       
@@ -325,14 +325,14 @@ static void HighPrimitives(int mode)
          300, -200
       };
 
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgba_f(1, 1, 1, 1));
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgba_f(1, 1, 1, 1));
       
       al_draw_textf(Font, ScreenW / 2, ScreenH - 20, ALLEGRO_ALIGN_CENTRE, "High Level Primitives");
       
       if (Blend)
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ONE, al_map_rgba_f(1, 1, 1, 1));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, al_map_rgba_f(1, 1, 1, 1));
       else
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
       
       al_use_transform(&MainTrans);
       
@@ -357,14 +357,14 @@ static void HighFilledPrimitives(int mode)
       Theta += Speed;
       al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta);
    } else if (mode == DRAW) {
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgba_f(1, 1, 1, 1));
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgba_f(1, 1, 1, 1));
       
       al_draw_textf(Font, ScreenW / 2, ScreenH - 20, ALLEGRO_ALIGN_CENTRE, "High Level Filled Primitives");
       
       if (Blend)
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ONE, al_map_rgba_f(1, 1, 1, 1));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, al_map_rgba_f(1, 1, 1, 1));
       else
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
       
       al_use_transform(&MainTrans);
       
@@ -394,14 +394,14 @@ static void ShadePrimitives(int mode)
          -700, 200,
          300, -200
       };
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgba_f(1, 1, 1, 1));
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgba_f(1, 1, 1, 1));
       
       al_draw_textf(Font, ScreenW / 2, ScreenH - 20, ALLEGRO_ALIGN_CENTRE, "Shaded Primitives");
       
       if (Blend)
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ONE, shade_color);
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, shade_color);
       else
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
       
       al_use_transform(&MainTrans);
       
@@ -433,14 +433,14 @@ static void TransformationsPrimitives(int mode)
          -700, 200,
          300, -200
       };
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgba_f(1, 1, 1, 1));
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgba_f(1, 1, 1, 1));
       
       al_draw_textf(Font, ScreenW / 2, ScreenH - 20, ALLEGRO_ALIGN_CENTRE, "Transformations");
       
       if (Blend)
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ONE, al_map_rgba_f(1, 1, 1, 1));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, al_map_rgba_f(1, 1, 1, 1));
       else
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
       
       al_use_transform(&MainTrans);
       
@@ -480,14 +480,14 @@ static void LowPrimitives(int mode)
       Theta += Speed;
       al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta);
    } else if (mode == DRAW) {
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgba_f(1, 1, 1, 1));
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgba_f(1, 1, 1, 1));
       
       al_draw_textf(Font, ScreenW / 2, ScreenH - 20, ALLEGRO_ALIGN_CENTRE, "Low Level Primitives");
       
       if (Blend)
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ONE, al_map_rgba_f(1, 1, 1, 1));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, al_map_rgba_f(1, 1, 1, 1));
       else
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
       
       al_use_transform(&MainTrans);
       
@@ -533,14 +533,14 @@ static void IndexedPrimitives(int mode)
       
       al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta);
    } else if (mode == DRAW) {
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgba_f(1, 1, 1, 1));
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgba_f(1, 1, 1, 1));
       
       al_draw_textf(Font, ScreenW / 2, ScreenH - 20, ALLEGRO_ALIGN_CENTRE, "Indexed Primitives");
       
       if (Blend)
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ONE, al_map_rgba_f(1, 1, 1, 1));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, al_map_rgba_f(1, 1, 1, 1));
       else
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
       
       al_use_transform(&MainTrans);
       
@@ -743,19 +743,19 @@ int main(void)
       }
       
       if (Background && bkg) {
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, white);
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, white);
          al_draw_scaled_bitmap(bkg, 0, 0, al_get_bitmap_width(bkg), al_get_bitmap_height(bkg), 0, 0, ScreenW, ScreenH, 0);
       }
       
       Screens[cur_screen](DRAW);
 
       if (Soft == 1) {
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, white);
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, white);
          al_set_target_bitmap(al_get_backbuffer());
          al_draw_bitmap(Buffer, 0, 0, 0);
       }
 
-      al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, white);
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, white);
       al_draw_textf(Font, 0, 0, 0, "FPS: %f", (float)frames_done / (al_current_time() - time_diff));
       al_draw_textf(Font, 0, 20, 0, "Change Screen (Up/Down). Esc to Quit.");
       al_draw_textf(Font, 0, 40, 0, "Rotation (Left/Right/Space): %f", Speed);
diff --git a/examples/ex_rotate.c b/examples/ex_rotate.c
index c86f60c..48c2f1c 100644
--- a/examples/ex_rotate.c
+++ b/examples/ex_rotate.c
@@ -117,14 +117,14 @@ int main(void)
       src_bmp = (mem_src_mode) ? mem_bmp : bmp;
       k = (wide_mode) ? 2.0 : 1.0;
 
-      al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
       if (mode == 0)
          al_clear_to_color(al_map_rgba_f(1, 0, 0, 1));
       else
          al_clear_to_color(al_map_rgba_f(0, 0, 1, 1));
 
       if (trans_mode) {
-         al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
             al_map_rgba_f(1, 1, 1, 0.5));
       }
 
@@ -146,7 +146,7 @@ int main(void)
          al_set_target_bitmap(al_get_backbuffer());
          al_set_clipping_rectangle(0, 0,
             al_get_display_width(), al_get_display_height());
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
          al_draw_bitmap(buf, 0, 0, 0);
       }
 
diff --git a/examples/ex_scale.c b/examples/ex_scale.c
index fff643a..3b2e204 100644
--- a/examples/ex_scale.c
+++ b/examples/ex_scale.c
@@ -117,14 +117,14 @@ int main(void)
       src_bmp = (mem_src_mode) ? mem_bmp : bmp;
       k = (wide_mode) ? 2.0 : 1.0;
 
-      al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
+      al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
       if (mode == 0)
          al_clear_to_color(al_map_rgba_f(1, 0, 0, 1));
       else
          al_clear_to_color(al_map_rgba_f(0, 0, 1, 1));
 
       if (trans_mode) {
-         al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
             al_map_rgba_f(1, 1, 1, 0.5));
       }
 
@@ -147,7 +147,7 @@ int main(void)
          al_set_target_bitmap(al_get_backbuffer());
          al_set_clipping_rectangle(0, 0,
             al_get_display_width(), al_get_display_height());
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgba_f(1, 1, 1, 1));
          al_draw_bitmap(buf, 0, 0, 0);
       }
 
diff --git a/examples/ex_stream_seek.c b/examples/ex_stream_seek.c
index 10c544f..d050c62 100644
--- a/examples/ex_stream_seek.c
+++ b/examples/ex_stream_seek.c
@@ -110,7 +110,7 @@ static void render(void)
    al_clear_to_color(al_map_rgb(64, 64, 128));
    
    /* render "music player" */
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgb(255, 255, 255));
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgb(255, 255, 255));
    al_draw_textf(basic_font, 0, 0, 0, "Playing %s", stream_filename);
    print_time(8, 24, pos);
    al_draw_textf(basic_font, 100, 24, 0, "/");
diff --git a/examples/ex_threads2.c b/examples/ex_threads2.c
index 3aab766..b51705d 100644
--- a/examples/ex_threads2.c
+++ b/examples/ex_threads2.c
@@ -212,7 +212,7 @@ static void show_images(void)
    int y = 0;
    int i;
 
-   al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgb_f(1, 1, 1));
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgb_f(1, 1, 1));
    for (i = 0; i < NUM_THREADS; i++) {
       /* for lots of threads, this is not good enough */
       al_lock_mutex(thread_info[i].mutex);
diff --git a/examples/ex_timer.c b/examples/ex_timer.c
index 0e8e0de..dc3a306 100644
--- a/examples/ex_timer.c
+++ b/examples/ex_timer.c
@@ -60,7 +60,7 @@ static void print(int x, int y, char const *format, ...)
    va_end(list);
 
    /* Actual text. */
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
       al_map_rgb_f(0, 0, 0));
    al_draw_text(ex.myfont, x, y, 0, message);
 }
diff --git a/examples/ex_ttf.c b/examples/ex_ttf.c
index 2428149..4e29a37 100644
--- a/examples/ex_ttf.c
+++ b/examples/ex_ttf.c
@@ -23,7 +23,7 @@ static void render(void)
 
     al_clear_to_color(white);
 
-    al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, black);
+    al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, black);
 
     al_hold_bitmap_drawing(true);
    
@@ -35,14 +35,14 @@ static void render(void)
     al_hold_bitmap_drawing(false);
     al_hold_bitmap_drawing(true);
 
-    al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, red);
+    al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, red);
     al_draw_textf(ex.f3, 50, 220, 0, "The color can be changed simply "
         "by using a different blender.");
         
     al_hold_bitmap_drawing(false);
     al_hold_bitmap_drawing(true);
         
-    al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, green);
+    al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, green);
     al_draw_textf(ex.f3, 50, 240, 0, "Some unicode symbols:");
     al_draw_textf(ex.f3, 50, 260, 0, "■□▢▣▤▥▦▧▨▩▪▫▬▭▮▯▰▱");
     al_draw_textf(ex.f3, 50, 280, 0, "▲△▴▵▶▷▸▹►▻▼▽▾▿◀◁◂◃◄◅◆◇◈◉◊");
@@ -70,17 +70,17 @@ static void render(void)
     ypos -= h;
     x += xpos;
     y += ypos;
-    al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, white);
+    al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, white);
     al_draw_rectangle(x, y, x + w, y + h, black, 0);
     al_draw_line(x, y + as, x + w, y + as, black, 0);
     al_draw_line(x, y + as + de, x + w, y + as + de, black, 0);
-    al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, blue);
+    al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, blue);
     
     al_hold_bitmap_drawing(true);
     al_draw_textf(ex.f4, xpos, ypos, 0, "Allegro");
     al_hold_bitmap_drawing(false);
 
-    al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, black);
+    al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, black);
     
     al_hold_bitmap_drawing(true);
 
diff --git a/examples/ex_windows.c b/examples/ex_windows.c
index 5b94f93..1fa0047 100644
--- a/examples/ex_windows.c
+++ b/examples/ex_windows.c
@@ -62,12 +62,12 @@ int main(void)
    for (;;) {
       for (i = 0; i < 2; i++) {
         al_set_current_display(displays[i]);
-        al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgb(255, 255, 255));
+        al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgb(255, 255, 255));
         if (i == 0)
            al_clear_to_color(al_map_rgb(255, 0, 255));
         else
            al_clear_to_color(al_map_rgb(155, 255, 0));
-        al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgb(0, 0, 0));
+        al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgb(0, 0, 0));
         al_draw_textf(myfont, 50, 50, ALLEGRO_ALIGN_CENTRE, "Click me..");
         al_flip_display();
       }
diff --git a/examples/nihgui.cpp b/examples/nihgui.cpp
index 6720445..25e7343 100644
--- a/examples/nihgui.cpp
+++ b/examples/nihgui.cpp
@@ -371,7 +371,7 @@ void Label::draw()
    const Theme & theme = this->dialog->get_theme();
    SaveState state;
 
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, theme.fg);
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, theme.fg);
    if (centred) {
       al_draw_text(theme.font, (this->x1 + this->x2 + 1)/2,
          this->y1, ALLEGRO_ALIGN_CENTRE, this->text.c_str());
@@ -430,7 +430,7 @@ void Button::draw()
       fg, 0);
    al_draw_filled_rectangle(this->x1 + 1, this->y1 + 1, this->x2 - 1, this->y2 - 1,
       bg);
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, fg);
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, fg);
    al_draw_text(theme.font, (this->x1 + this->x2 + 1)/2,
       this->y1, ALLEGRO_ALIGN_CENTRE, this->text.c_str());
 }
@@ -522,16 +522,16 @@ void List::draw()
 
    al_draw_filled_rectangle(x1 + 1, y1 + 1, x2 - 1, y2 - 1, theme.bg);
 
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, theme.fg);
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, theme.fg);
    const int font_height = al_get_font_line_height(theme.font);
    for (unsigned i = 0; i < items.size(); i++) {
       int yi = y1 + i * font_height;
 
       if (i == selected_item) {
-         al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgb(255, 255, 255));
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgb(255, 255, 255));
          al_draw_filled_rectangle(x1 + 1, yi, x2 - 1, yi + font_height - 1,
             theme.highlight);
-         al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, theme.fg);
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, theme.fg);
       }
 
       al_draw_text(theme.font, x1, yi, 0, items.at(i).c_str());
@@ -753,7 +753,7 @@ void TextEntry::draw()
 
    al_draw_filled_rectangle(x1, y1, x2, y2, theme.bg);
 
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, theme.fg);
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, theme.fg);
 
    if (!focused) {
       al_draw_ustr(theme.font, x1, y1, 0, UString(text, left_pos));
@@ -773,11 +773,11 @@ void TextEntry::draw()
       }
       else {
          UString sub(text, cursor_pos, 1);
-         al_set_blender(ALLEGRO_INVERSE_ALPHA, ALLEGRO_ALPHA, theme.fg);
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ALPHA, theme.fg);
          al_draw_ustr(theme.font, x, y1, 0, sub);
          x += al_get_ustr_width(theme.font, sub);
 
-         al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, theme.fg);
+         al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, theme.fg);
          al_draw_ustr(theme.font, x, y1, 0, UString(text, cursor_pos + 1));
       }
    }
diff --git a/include/allegro5/bitmap_new.h b/include/allegro5/bitmap_new.h
index efd2c19..676cae2 100644
--- a/include/allegro5/bitmap_new.h
+++ b/include/allegro5/bitmap_new.h
@@ -96,6 +96,12 @@ enum ALLEGRO_BLEND_MODE {
    ALLEGRO_INVERSE_ALPHA = 3
 };
 
+enum ALLEGRO_BLEND_OPERATIONS {
+   ALLEGRO_ADD = 0,
+   ALLEGRO_SRC_MINUS_DEST = 1,
+   ALLEGRO_DEST_MINUS_SRC = 2
+};
+
 
 /* Type: ALLEGRO_LOCKED_REGION
  */
@@ -166,10 +172,12 @@ AL_FUNC(ALLEGRO_BITMAP *, al_clone_bitmap, (ALLEGRO_BITMAP *bitmap));
 AL_FUNC(bool, al_is_bitmap_locked, (ALLEGRO_BITMAP *bitmap));
 
 /* Blending */
-AL_FUNC(void, al_set_blender, (int source, int dest, ALLEGRO_COLOR color));
-AL_FUNC(void, al_get_blender, (int *source, int *dest, ALLEGRO_COLOR *color));
-AL_FUNC(void, al_set_separate_blender, (int source, int dest, int alpha_source, int alpha_dest, ALLEGRO_COLOR color));
-AL_FUNC(void, al_get_separate_blender, (int *source, int *dest, int *alpha_src, int *alpha_dest, ALLEGRO_COLOR *color));
+AL_FUNC(void, al_set_blender, (int op, int source, int dest, ALLEGRO_COLOR color));
+AL_FUNC(void, al_get_blender, (int *op, int *source, int *dest, ALLEGRO_COLOR *color));
+AL_FUNC(void, al_set_separate_blender, (int op, int source, int dest,
+   int alpha_op, int alpha_source, int alpha_dest, ALLEGRO_COLOR color));
+AL_FUNC(void, al_get_separate_blender, (int *op, int *source, int *dest,
+   int *alpha_op, int *alpha_src, int *alpha_dest, ALLEGRO_COLOR *color));
 AL_FUNC(ALLEGRO_COLOR *, _al_get_blend_color, (void));
 
 AL_FUNC(void, _al_put_pixel, (ALLEGRO_BITMAP *bitmap, int x, int y, ALLEGRO_COLOR color));
diff --git a/include/allegro5/opengl/GLext/gl_ext_alias.h b/include/allegro5/opengl/GLext/gl_ext_alias.h
index f618008..d002b1a 100644
--- a/include/allegro5/opengl/GLext/gl_ext_alias.h
+++ b/include/allegro5/opengl/GLext/gl_ext_alias.h
@@ -167,6 +167,7 @@
 
 
 #if defined _ALLEGRO_GL_VERSION_2_0
+#define glBlendEquationSeparate _al_glBlendEquationSeparate
 #define glCreateProgram _al_glCreateProgram
 #define glCreateShader _al_glCreateShader
 #define glDeleteProgram _al_glDeleteProgram
@@ -1977,7 +1978,7 @@
 #define glGetTransformFeedbackVaryingNV _al_glGetTransformFeedbackVaryingNV
 #if !defined _ALLEGRO_GL_EXT_draw_buffers2
 #define glGetBooleanIndexedvEXT _al_glGetBooleanIndexedvEXT
-#define glGetIntegerIndexedvEXT _al_glGetIntegerIndexedvEXT
+//AGL_API(void,GetIntegerIndexedvEXT,(GLenum,GLuint,GLint*))
 #endif
 #endif
 
diff --git a/include/allegro5/opengl/GLext/gl_ext_api.h b/include/allegro5/opengl/GLext/gl_ext_api.h
index 235351e..792b55f 100644
--- a/include/allegro5/opengl/GLext/gl_ext_api.h
+++ b/include/allegro5/opengl/GLext/gl_ext_api.h
@@ -166,6 +166,7 @@ AGL_API(void, GetQueryObjectuiv, (GLuint, GLenum, GLuint *))
 
 
 #if defined _ALLEGRO_GL_VERSION_2_0
+AGL_API(void, BlendEquationSeparate, (GLenum, GLenum))
 AGL_API(GLuint, CreateProgram, (void))
 AGL_API(GLuint, CreateShader, (GLenum))
 AGL_API(void,   DeleteProgram, (GLuint))
diff --git a/src/bitmap_new.c b/src/bitmap_new.c
index 29335f6..cdc1c78 100644
--- a/src/bitmap_new.c
+++ b/src/bitmap_new.c
@@ -661,7 +661,7 @@ void _al_convert_to_display_bitmap(ALLEGRO_BITMAP *bitmap)
    _al_vector_find_and_delete(&d->bitmaps, &tmp);
 
    /* Preserve bitmap contents. */
-   al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgb(255, 255, 255));
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgb(255, 255, 255));
    al_set_target_bitmap(tmp);
    al_draw_bitmap(bitmap, 0, 0, 0);
    tmp->cb_excl = bitmap->cb_excl;
@@ -716,7 +716,7 @@ void _al_convert_to_memory_bitmap(ALLEGRO_BITMAP *bitmap)
    tmp = al_create_bitmap(bitmap->w, bitmap->h);
 
    /* Preserve bitmap contents. */
-   al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgb(255, 255, 255));
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgb(255, 255, 255));
    al_set_target_bitmap(tmp);
    al_draw_bitmap(bitmap, 0, 0, 0);
    tmp->cb_excl = bitmap->cb_excl;
diff --git a/src/blenders.c b/src/blenders.c
index 2027cb9..4e4c278 100644
--- a/src/blenders.c
+++ b/src/blenders.c
@@ -284,12 +284,12 @@ void _al_blend(ALLEGRO_COLOR *scol,
    int dx, int dy, ALLEGRO_COLOR *result)
 {
    float src, dst, asrc, adst;
-   int src_, dst_, asrc_, adst_;
+   int op_, src_, dst_, aop_, asrc_, adst_;
    ALLEGRO_COLOR dcol;
    ALLEGRO_COLOR bc;
 
    dcol = al_get_pixel(dest, dx, dy);
-   al_get_separate_blender(&src_, &dst_, &asrc_, &adst_, &bc);
+   al_get_separate_blender(&op_, &src_, &dst_, &aop_, &asrc_, &adst_, &bc);
    result->r = scol->r * bc.r;
    result->g = scol->g * bc.g;
    result->b = scol->b * bc.b;
diff --git a/src/memblit.c b/src/memblit.c
index 6e19fcd..2bd245b 100644
--- a/src/memblit.c
+++ b/src/memblit.c
@@ -94,15 +94,18 @@ void _al_draw_bitmap_region_memory(ALLEGRO_BITMAP *bitmap,
    int x, y;
    int src_mode, dst_mode;
    int src_alpha, dst_alpha;
+   int op, op_alpha;
    ALLEGRO_COLOR *ic;
    int xinc, yinc;
    int yd;
    int sxd;
 
-   al_get_separate_blender(&src_mode, &dst_mode, &src_alpha, &dst_alpha, NULL);
+   al_get_separate_blender(&op, &src_mode, &dst_mode,
+      &op_alpha, &src_alpha, &dst_alpha, NULL);
    ic = _al_get_blend_color();
 
-   if (src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE &&
+   if (op == ALLEGRO_ADD && op_alpha == ALLEGRO_ADD &&
+      src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE &&
       dst_mode == ALLEGRO_ZERO && dst_alpha == ALLEGRO_ZERO &&
       ic->r == 1.0f && ic->g == 1.0f && ic->b == 1.0f && ic->a == 1.0f)
    {
@@ -223,10 +226,10 @@ void _al_draw_bitmap_region_memory(ALLEGRO_BITMAP *bitmap,
       ALLEGRO_COLOR src_color = {0, 0, 0, 0};   /* avoid bogus warnings */
       ALLEGRO_COLOR dst_color = {0, 0, 0, 0};
       ALLEGRO_COLOR result;
-      int src_, dst_, asrc_, adst_;
+      int op_, src_, dst_, aop_, asrc_, adst_;
       ALLEGRO_COLOR bc;
 
-      al_get_separate_blender(&src_, &dst_, &asrc_, &adst_, &bc);
+      al_get_separate_blender(&op_, &src_, &dst_, &aop_, &asrc_, &adst_, &bc);
 
       for (y = 0; y < sh; y++, yd += yinc) {
          char *dest_data =
@@ -290,7 +293,7 @@ void _al_draw_scaled_bitmap_memory(ALLEGRO_BITMAP *src,
    ALLEGRO_BITMAP *dest = al_get_target_bitmap();
    ALLEGRO_LOCKED_REGION *src_region;
    ALLEGRO_LOCKED_REGION *dst_region;
-   int src_mode, dst_mode;
+   int op, src_mode, dst_mode;
    ALLEGRO_COLOR bc;
 
    float sxinc;
@@ -304,9 +307,10 @@ void _al_draw_scaled_bitmap_memory(ALLEGRO_BITMAP *src,
    int xend;
    int yend;
 
-   al_get_blender(&src_mode, &dst_mode, &bc);
+   al_get_blender(&op, &src_mode, &dst_mode, &bc);
 
-   if (src_mode == ALLEGRO_ONE && dst_mode == ALLEGRO_ZERO &&
+   if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE &&
+      dst_mode == ALLEGRO_ZERO &&
       bc.r == 1.0f && bc.g == 1.0f && bc.b == 1.0f && bc.a == 1.0f) {
       _al_draw_scaled_bitmap_memory_fast(src,
             sx, sy, sw, sh, dx, dy, dw, dh, flags);
@@ -381,10 +385,10 @@ void _al_draw_scaled_bitmap_memory(ALLEGRO_BITMAP *src,
 
       ALLEGRO_COLOR src_color = {0, 0, 0, 0};   /* avoid bogus warnings */
       ALLEGRO_COLOR dst_color = {0, 0, 0, 0};
-      int src_, dst_, asrc_, adst_;
+      int op_, src_, dst_, aop_, asrc_, adst_;
       ALLEGRO_COLOR bc;
 
-      al_get_separate_blender(&src_, &dst_, &asrc_, &adst_, &bc);
+      al_get_separate_blender(&op_, &src_, &dst_, &aop_, &asrc_, &adst_, &bc);
 
       for (y = 0; y < yend; y++) {
          const char *src_row =
@@ -871,14 +875,14 @@ do {                                                                         \
       const int my_l_bmp_x_i = l_bmp_x_rounded >> 16;                        \
       al_fixed my_l_spr_x = l_spr_x_rounded;                                 \
       al_fixed my_l_spr_y = l_spr_y_rounded;                                 \
-      int src_, dst_, asrc_, adst_;                                          \
+      int op_, src_, dst_, aop_, asrc_, adst_;                                          \
       ALLEGRO_COLOR bc;                                                      \
       const int src_size = al_get_pixel_size(src->format);                   \
       char *dst_data;                                                        \
       ALLEGRO_COLOR dst_color = {0, 0, 0, 0};   /* avoid bogus warning */    \
       int x;                                                                 \
                                                                              \
-      al_get_separate_blender(&src_, &dst_, &asrc_, &adst_, &bc);            \
+      al_get_separate_blender(&op_, &src_, &dst_, &aop_, &asrc_, &adst_, &bc);            \
                                                                              \
       dst_data = (char*)dst_region->data                                     \
          + dst_region->pitch * (bmp_y_i - clip_top_i)                        \
@@ -973,10 +977,10 @@ void _al_draw_rotated_scaled_bitmap_memory(ALLEGRO_BITMAP *src,
    float angle, int flags)
 {
    ALLEGRO_BITMAP *dst = al_get_target_bitmap();
-   int src_mode, dst_mode;
+   int op, src_mode, dst_mode;
    ALLEGRO_COLOR *ic;
 
-   al_get_blender(&src_mode, &dst_mode, NULL);
+   al_get_blender(&op, &src_mode, &dst_mode, NULL);
    ic = _al_get_blend_color();
 
    if (src_mode == ALLEGRO_ONE && dst_mode == ALLEGRO_ZERO &&
diff --git a/src/memdraw.c b/src/memdraw.c
index 05c4b58..7400b89 100644
--- a/src/memdraw.c
+++ b/src/memdraw.c
@@ -203,13 +203,14 @@ void _al_draw_filled_rectangle_memory(int x1, int y1, int x2, int y2,
    ALLEGRO_LOCKED_REGION *lr;
    int w, h;
    int tmp;
-   int src_mode, dst_mode;
+   int op, src_mode, dst_mode;
    ALLEGRO_COLOR *ic;
 
-   al_get_blender(&src_mode, &dst_mode, NULL);
+   al_get_blender(&op, &src_mode, &dst_mode, NULL);
    ic = _al_get_blend_color();
-   if (src_mode == ALLEGRO_ONE && dst_mode == ALLEGRO_ZERO &&
-         ic->r == 1.0f && ic->g == 1.0f && ic->b == 1.0f && ic->a == 1.0f)
+   if (op == ALLEGRO_ADD &&
+      src_mode == ALLEGRO_ONE && dst_mode == ALLEGRO_ZERO &&
+      ic->r == 1.0f && ic->g == 1.0f && ic->b == 1.0f && ic->a == 1.0f)
    {
       _al_draw_filled_rectangle_memory_fast(x1, y1, x2, y2, color);
       return;
diff --git a/src/opengl/ogl_bitmap.c b/src/opengl/ogl_bitmap.c
index 8f3ccad..1f96d84 100644
--- a/src/opengl/ogl_bitmap.c
+++ b/src/opengl/ogl_bitmap.c
@@ -172,15 +172,18 @@ static char const *error_string(GLenum e)
 
 static INLINE bool setup_blending(ALLEGRO_DISPLAY *ogl_disp)
 {
-   int src_color, dst_color, src_alpha, dst_alpha;
-   int blend_modes[4] = {
+   int op, src_color, dst_color, op_alpha, src_alpha, dst_alpha;
+   const int blend_modes[4] = {
       GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
    };
+   const int blend_equations[3] = {
+      GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT
+   };
 
    (void)ogl_disp;
 
-   al_get_separate_blender(&src_color, &dst_color, &src_alpha,
-      &dst_alpha, NULL);
+   al_get_separate_blender(&op, &src_color, &dst_color,
+      &op_alpha, &src_alpha, &dst_alpha, NULL);
    /* glBlendFuncSeparate was only included with OpenGL 1.4 */
    /* (And not in OpenGL ES) */
 #if !defined ALLEGRO_GP2XWIZ && !defined ALLEGRO_IPHONE
@@ -188,6 +191,14 @@ static INLINE bool setup_blending(ALLEGRO_DISPLAY *ogl_disp)
       glEnable(GL_BLEND);
       glBlendFuncSeparate(blend_modes[src_color], blend_modes[dst_color],
          blend_modes[src_alpha], blend_modes[dst_alpha]);
+      if (ogl_disp->ogl_extras->ogl_info.version >= 2.0) {
+         printf("%d %d\n", op, op_alpha);
+         glBlendEquationSeparate(
+            blend_equations[op],
+            blend_equations[op_alpha]);
+      }
+      else
+         glBlendEquation(blend_equations[op]);
    }
    else {
       if (src_color == src_alpha && dst_color == dst_alpha) {
@@ -198,6 +209,14 @@ static INLINE bool setup_blending(ALLEGRO_DISPLAY *ogl_disp)
          return false;
       }
    }
+/* OpenGL ES 1.0 has both functions */
+#elif defined(ALLEGRO_IPHONE)
+   glEnable(GL_BLEND);
+   glBlendFuncSeparate(blend_modes[src_color], blend_modes[dst_color],
+      blend_modes[src_alpha], blend_modes[dst_alpha]);
+   glBlendEquationSeparate(
+      blend_equations[op],
+      blend_equations[alpha_op]);
 #else
    glEnable(GL_BLEND);
    glBlendFunc(blend_modes[src_color], blend_modes[dst_color]);
diff --git a/src/opengl/ogl_draw.c b/src/opengl/ogl_draw.c
index c638416..985f499 100644
--- a/src/opengl/ogl_draw.c
+++ b/src/opengl/ogl_draw.c
@@ -26,22 +26,32 @@ static bool set_opengl_blending(ALLEGRO_DISPLAY *d,
    const int blend_modes[4] = {
       GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
    };
+   const int blend_equations[3] = {
+      GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT
+   };
    ALLEGRO_COLOR *bc;
-   int src_color, dst_color, src_alpha, dst_alpha;
+   int op, src_color, dst_color, op_alpha, src_alpha, dst_alpha;
    float r, g, b, a;
 
    (void)d;
 
    al_unmap_rgba_f(*color, &r, &g, &b, &a);
 
-   al_get_separate_blender(&src_color, &dst_color, &src_alpha,
-      &dst_alpha, NULL);
-#if !defined ALLEGRO_GP2XWIZ && !defined ALLEGRO_IPHONE
+   al_get_separate_blender(&op, &src_color, &dst_color, &op_alpha,
+      &src_alpha, &dst_alpha, NULL);
+#if !defined ALLEGRO_GP2XWIZ
    if (d->ogl_extras->ogl_info.version >= 1.4) {
       glEnable(GL_BLEND);
       glBlendFuncSeparate(blend_modes[src_color],
          blend_modes[dst_color], blend_modes[src_alpha],
          blend_modes[dst_alpha]);
+      if (d->ogl_extras->ogl_info.version >= 2.0) {
+         glBlendEquationSeparate(
+            blend_equations[op],
+            blend_equations[op_alpha]);
+      }
+      else
+         glBlendEquation(blend_equations[op]);
       bc = _al_get_blend_color();
       glColor4f(r * bc->r, g * bc->g, b * bc->b, a * bc->a);
       return true;
@@ -50,11 +60,23 @@ static bool set_opengl_blending(ALLEGRO_DISPLAY *d,
       if (src_color == src_alpha && dst_color == dst_alpha) {
          glEnable(GL_BLEND);
          glBlendFunc(blend_modes[src_color], blend_modes[dst_color]);
+         glBlendEquation(blend_equations[op]);
          bc = _al_get_blend_color();
          glColor4f(r * bc->r, g * bc->g, b * bc->b, a * bc->a);
          return true;
       }
    }
+#elif defined ALLEGRO_IPHONE
+   glEnable(GL_BLEND);
+   glBlendFuncSeparate(blend_modes[src_color],
+      blend_modes[dst_color], blend_modes[src_alpha],
+      blend_modes[dst_alpha]);
+   glBlendEquationSeparate(
+      blend_equations[op],
+      blend_equations[alpha_op]);
+   bc = _al_get_blend_color();
+   glColor4f(r * bc->r, g * bc->g, b * bc->b, a * bc->a);
+   return true;
 #else
    glEnable(GL_BLEND);
    glBlendFunc(blend_modes[src_color], blend_modes[dst_color]);
diff --git a/src/system_new.c b/src/system_new.c
index 7748ac3..70e961d 100644
--- a/src/system_new.c
+++ b/src/system_new.c
@@ -213,7 +213,7 @@ bool al_install_system(int (*atexit_ptr)(void (*)(void)))
 
    _al_init_pixels();
 
-   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgb(255, 255, 255));
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgb(255, 255, 255));
 
    if (atexit_ptr && atexit_virgin) {
       atexit_ptr(al_uninstall_system);
diff --git a/src/tls.c b/src/tls.c
index 9c74a70..dcb0276 100644
--- a/src/tls.c
+++ b/src/tls.c
@@ -48,8 +48,10 @@ typedef struct thread_local_state {
    int new_bitmap_format;
    int new_bitmap_flags;
    /* Blending modes and color */
+   int blend_op;
    int blend_source;
    int blend_dest;
+   int blend_alpha_op;
    int blend_alpha_source;
    int blend_alpha_dest;
    ALLEGRO_COLOR blend_color;
@@ -117,8 +119,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
              memset(data, 0, sizeof(*data));
 
              data->new_bitmap_format = ALLEGRO_PIXEL_FORMAT_ANY;
+             data->blend_op = ALLEGRO_ADD;
              data->blend_source = ALLEGRO_ALPHA;
              data->blend_dest = ALLEGRO_INVERSE_ALPHA;
+             data->blend_alpha_op = ALLEGRO_ADD;
              data->blend_alpha_source = ALLEGRO_ONE;
              data->blend_alpha_dest = ALLEGRO_ONE;
              data->blend_color.r = data->blend_color.g = data->blend_color.b
@@ -221,8 +225,10 @@ static THREAD_LOCAL thread_local_state _tls = {
    NULL,                                  /* target_bitmap */
    ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA,   /* new_bitmap_format */
    0,                                     /* new_bitmap_flags */
+   ALLEGRO_ADD,                           /* blend_op */
    ALLEGRO_ALPHA,                         /* blend_source */
    ALLEGRO_INVERSE_ALPHA,                 /* blend_dest */
+   ALLEGRO_ADD,                           /* blend_alpha_op */
    ALLEGRO_ONE,                           /* blend_alpha_source */
    ALLEGRO_ONE,                           /* blend_alpha_dest */
    { 1.0f, 1.0f, 1.0f, 1.0f },            /* blend_color  */
@@ -488,8 +494,10 @@ void al_store_state(ALLEGRO_STATE *state, int flags)
    }
 
    if (flags & ALLEGRO_STATE_BLENDER) {
+      _STORE(blend_op);
       _STORE(blend_source);
       _STORE(blend_dest);
+      _STORE(blend_alpha_op);
       _STORE(blend_alpha_source);
       _STORE(blend_alpha_dest);
       _STORE(blend_color);
@@ -541,8 +549,10 @@ void al_restore_state(ALLEGRO_STATE const *state)
    }
    
    if (flags & ALLEGRO_STATE_BLENDER) {
+      _STORE(blend_op);
       _STORE(blend_source);
       _STORE(blend_dest);
+      _STORE(blend_alpha_op);
       _STORE(blend_alpha_source);
       _STORE(blend_alpha_dest);
       _STORE(blend_color);
@@ -560,25 +570,27 @@ void al_restore_state(ALLEGRO_STATE const *state)
 
 /* Function: al_set_blender
  */
-void al_set_blender(int src, int dst, ALLEGRO_COLOR color)
+void al_set_blender(int op, int src, int dst, ALLEGRO_COLOR color)
 {
-   al_set_separate_blender(src, dst, src, dst, color);
+   al_set_separate_blender(op, src, dst, op, src, dst, color);
 }
 
 
 
 /* Function: al_set_separate_blender
  */
-void al_set_separate_blender(int src, int dst, int alpha_src,
-   int alpha_dst, ALLEGRO_COLOR color)
+void al_set_separate_blender(int op, int src, int dst,
+   int alpha_op, int alpha_src, int alpha_dst, ALLEGRO_COLOR color)
 {
    thread_local_state *tls;
 
    if ((tls = tls_get()) == NULL)
       return;
 
+   tls->blend_op = op;
    tls->blend_source = src;
    tls->blend_dest = dst;
+   tls->blend_alpha_op = alpha_op;
    tls->blend_alpha_source = alpha_src;
    tls->blend_alpha_dest = alpha_dst;
 
@@ -591,28 +603,34 @@ void al_set_separate_blender(int src, int dst, int alpha_src,
 
 /* Function: al_get_blender
  */
-void al_get_blender(int *src, int *dst, ALLEGRO_COLOR *color)
+void al_get_blender(int *op, int *src, int *dst, ALLEGRO_COLOR *color)
 {
-   al_get_separate_blender(src, dst, NULL, NULL, color);
+   al_get_separate_blender(op, src, dst, NULL, NULL, NULL, color);
 }
 
 
 
 /* Function: al_get_separate_blender
  */
-void al_get_separate_blender(int *src, int *dst, int *alpha_src,
-   int *alpha_dst, ALLEGRO_COLOR *color)
+void al_get_separate_blender(int *op, int *src, int *dst,
+   int *alpha_op, int *alpha_src, int *alpha_dst, ALLEGRO_COLOR *color)
 {
    thread_local_state *tls;
 
    if ((tls = tls_get()) == NULL)
       return;
+   
+   if (op)
+      *op = tls->blend_op;
 
    if (src)
       *src = tls->blend_source;
 
    if (dst)
       *dst = tls->blend_dest;
+   
+   if (alpha_op)
+      *alpha_op = tls->blend_alpha_op;
 
    if (alpha_src)
       *alpha_src = tls->blend_alpha_source;
diff --git a/src/win/d3d_bmp.cpp b/src/win/d3d_bmp.cpp
index 679bd90..197ace8 100644
--- a/src/win/d3d_bmp.cpp
+++ b/src/win/d3d_bmp.cpp
@@ -662,7 +662,7 @@ static void d3d_blit_real(ALLEGRO_BITMAP *src,
 
    _al_d3d_set_bitmap_clip(dest);
 
-   al_get_blender(NULL, NULL, &bc);
+   al_get_blender(NULL, NULL, NULL, &bc);
    al_unmap_rgba(bc, &r, &g, &b, &a);
    color = D3DCOLOR_ARGB(a, r, g, b);
 
diff --git a/src/win/d3d_disp.cpp b/src/win/d3d_disp.cpp
index ac701f0..8686082 100644
--- a/src/win/d3d_disp.cpp
+++ b/src/win/d3d_disp.cpp
@@ -1969,10 +1969,11 @@ static int d3d_al_blender_to_d3d(int al_mode)
 
 void _al_d3d_set_blender(ALLEGRO_DISPLAY_D3D *d3d_display)
 {
-   int src, dst, alpha_src, alpha_dst;
+   int op, src, dst, alpha_op, alpha_src, alpha_dst;
    ALLEGRO_COLOR color;
 
-   al_get_separate_blender(&src, &dst, &alpha_src, &alpha_dst, &color);
+   al_get_separate_blender(&op, &src, &dst,
+      &alpha_op, &alpha_src, &alpha_dst, &color);
 
    src = d3d_al_blender_to_d3d(src);
    dst = d3d_al_blender_to_d3d(dst);
diff --git a/src/win/wnewwin.c b/src/win/wnewwin.c
index 6e8bd9d..646bfb7 100644
--- a/src/win/wnewwin.c
+++ b/src/win/wnewwin.c
@@ -715,7 +715,7 @@ void _al_win_set_display_icon(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bmp)
    al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ARGB_8888);
    scaled_bmp = al_create_bitmap(32, 32);
    al_set_target_bitmap(scaled_bmp);
-   al_set_blender(ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgb(255, 255, 255));
+   al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgb(255, 255, 255));
    al_draw_scaled_bitmap(bmp, 0, 0,
       al_get_bitmap_width(bmp),
       al_get_bitmap_height(bmp),


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/