Re: [AD] blender operations SRC and DST

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


Actually looks like I forgot about the memory blenders. I updated the reference implementation in src/blenders.c. I didn't understand the comment about 'NaN or Inf * 0 is not 0'. Not that I don't believe this statement but I don't see why any Nan's or Inf's should be floating around.

On 06/06/2011 11:27 PM, Jon Rafkind wrote:
Any problems if I commit this?

On 06/06/2011 05:39 PM, Jon Rafkind wrote:
This patch adds source and destination color as factors for opengl/d3d
blending. I haven't tested the d3d code because I don't have a windows
environment set up. Also the documents aren't updated in this patch but
I can do so after the patch is applied.
------------------------------------------------------------------------------ EditLive Enterprise is the world's most technically advanced content authoring tool. Experience the power of Track Changes, Inline Image Editing and ensure content is compliant with Accessibility Checking. http://p.sf.net/sfu/ephox-dev2dev

------------------------------------------------------------------------------ EditLive Enterprise is the world's most technically advanced content authoring tool. Experience the power of Track Changes, Inline Image Editing and ensure content is compliant with Accessibility Checking. http://p.sf.net/sfu/ephox-dev2dev

Index: include/allegro5/bitmap.h
===================================================================
--- include/allegro5/bitmap.h	(revision 14764)
+++ include/allegro5/bitmap.h	(working copy)
@@ -91,7 +91,9 @@
    ALLEGRO_ZERO = 0,
    ALLEGRO_ONE = 1,
    ALLEGRO_ALPHA = 2,
-   ALLEGRO_INVERSE_ALPHA = 3
+   ALLEGRO_INVERSE_ALPHA = 3,
+   ALLEGRO_SRC_COLOR = 4,
+   ALLEGRO_DST_COLOR = 5
 };
 
 enum ALLEGRO_BLEND_OPERATIONS {
Index: src/blenders.c
===================================================================
--- src/blenders.c	(revision 14764)
+++ src/blenders.c	(working copy)
@@ -25,16 +25,38 @@
 #define MAX _ALLEGRO_MAX
 
 
-static float get_factor(int operation, float alpha)
+static void get_factor(int operation, ALLEGRO_COLOR * source, ALLEGRO_COLOR * dest, ALLEGRO_COLOR * factor)
 {
    switch(operation) {
-       case ALLEGRO_ZERO: return 0;
-       case ALLEGRO_ONE: return 1;
-       case ALLEGRO_ALPHA: return alpha;
-       case ALLEGRO_INVERSE_ALPHA: return 1 - alpha;
+       case ALLEGRO_ZERO: {
+          factor->r = factor->g = factor->b = factor->a = 0;
+          break;
+       }
+       case ALLEGRO_ONE: {
+          factor->r = factor->g = factor->b = factor->a = 1;
+          break;
+       }
+       case ALLEGRO_ALPHA: {
+          factor->r = factor->g = factor->b = factor->a = source->a;
+          break;
+       }
+       case ALLEGRO_INVERSE_ALPHA: {
+          factor->r = factor->g = factor->b = factor->a = 1 - source->a;
+          break;
+       }
+       case ALLEGRO_SRC_COLOR: {
+           *factor = *source;
+           break;
+       }
+       case ALLEGRO_DST_COLOR: {
+           *factor = *dest;
+           break;
+       }
+       default: {
+           ASSERT(false);
+           break;
+       }
    }
-   ASSERT(false);
-   return 0; /* silence warning in release build */
 }
 
 
@@ -43,34 +65,36 @@
    ALLEGRO_BITMAP *dest,
    int dx, int dy, ALLEGRO_COLOR *result)
 {
-   float src, dst, asrc, adst;
-   int op, src_, dst_, aop, asrc_, adst_;
+   ALLEGRO_COLOR src_factor, dest_factor;
+   ALLEGRO_COLOR alpha_src_factor, alpha_dest_factor;
+   int op, src_blend, dest_blend, alpha_op, alpha_src_blend, alpha_dest_blend;
    ALLEGRO_COLOR dcol;
 
    dcol = al_get_pixel(dest, dx, dy);
-   al_get_separate_blender(&op, &src_, &dst_, &aop, &asrc_, &adst_);
+   al_get_separate_blender(&op, &src_blend, &dest_blend, &alpha_op, &alpha_src_blend, &alpha_dest_blend);
    result->r = scol->r;
    result->g = scol->g;
    result->b = scol->b;
    result->a = scol->a;
-   src = get_factor(src_, result->a);
-   dst = get_factor(dst_, result->a);
-   asrc = get_factor(asrc_, result->a);
-   adst = get_factor(adst_, result->a);
+   get_factor(src_blend, scol, &dcol, &src_factor);
+   get_factor(dest_blend, scol, &dcol, &dest_factor);
+   get_factor(alpha_src_blend, scol, &dcol, &alpha_src_factor);
+   get_factor(alpha_dest_blend, scol, &dcol, &alpha_dest_factor);
 
    // FIXME: Better not do all those checks for each pixel but already
    // at the caller.
    // Note: Multiplying NaN or Inf with 0 doesn't give 0.
-   if (dst == 0) {
+   /*
+   if (dest == 0) {
       if (src == 0 || op == ALLEGRO_DEST_MINUS_SRC) {
          result->r = 0;
          result->g = 0;
          result->b = 0;
       }
       else {
-         result->r = result->r * src;
-         result->g = result->g * src;
-         result->b = result->b * src;
+         result->r = result->r * src_factor.r;
+         result->g = result->g * src_factor.g;
+         result->b = result->b * src_factor.b;
       }
    } else if (src == 0) {
       if (op == ALLEGRO_SRC_MINUS_DEST) {
@@ -79,40 +103,45 @@
          result->b = 0;
       }
       else {
-         result->r = dcol.r * dst;
-         result->g = dcol.g * dst;
-         result->b = dcol.b * dst;
+         result->r = dcol.r * dest_factor.r;
+         result->g = dcol.g * dest_factor.g;
+         result->b = dcol.b * dest_factor.b;
       }
-   } else if (op == ALLEGRO_ADD) {
-      result->r = MIN(1, result->r * src + dcol.r * dst);
-      result->g = MIN(1, result->g * src + dcol.g * dst);
-      result->b = MIN(1, result->b * src + dcol.b * dst);
+   } else
+   */
+   if (op == ALLEGRO_ADD) {
+      result->r = MIN(1, result->r * src_factor.r + dcol.r * dest_factor.r);
+      result->g = MIN(1, result->g * src_factor.g + dcol.g * dest_factor.g);
+      result->b = MIN(1, result->b * src_factor.b + dcol.b * dest_factor.b);
    }
    else if (op == ALLEGRO_SRC_MINUS_DEST) {
-      result->r = MAX(0, result->r * src - dcol.r * dst);
-      result->g = MAX(0, result->g * src - dcol.g * dst);
-      result->b = MAX(0, result->b * src - dcol.b * dst);
+      result->r = MAX(0, result->r * src_factor.r - dcol.r * dest_factor.r);
+      result->g = MAX(0, result->g * src_factor.g - dcol.g * dest_factor.g);
+      result->b = MAX(0, result->b * src_factor.b - dcol.b * dest_factor.b);
    }
    else if (op == ALLEGRO_DEST_MINUS_SRC) {
-      result->r = MAX(0, dcol.r * dst - result->r * src);
-      result->g = MAX(0, dcol.g * dst - result->g * src);
-      result->b = MAX(0, dcol.b * dst - result->b * src);
+      result->r = MAX(0, dcol.r * dest_factor.r - result->r * src_factor.r);
+      result->g = MAX(0, dcol.g * dest_factor.g - result->g * src_factor.g);
+      result->b = MAX(0, dcol.b * dest_factor.b - result->b * src_factor.b);
    }
 
+   /*
    if (adst == 0)
       if (asrc == 0 || aop == ALLEGRO_DEST_MINUS_SRC)
          result->a = 0;
       else
-         result->a = result->a * asrc;
+         result->a = result->a * alpha_src_factor.a;
    else if (asrc == 0)
       if (aop == ALLEGRO_SRC_MINUS_DEST)
          result->a = 0;
       else
-         result->a = dcol.a * adst;
-   else if (aop == ALLEGRO_ADD)
-      result->a = MIN(1, result->a * asrc + dcol.a * adst);
-   else if (aop == ALLEGRO_SRC_MINUS_DEST)
-      result->a = MAX(0, result->a * asrc - dcol.a * adst);
-   else if (aop == ALLEGRO_DEST_MINUS_SRC)
-      result->a = MAX(0, dcol.a * adst - result->a * asrc);
+         result->a = dcol.a * alpha_dest_factor.a;
+   else
+   */
+   if (alpha_op == ALLEGRO_ADD)
+      result->a = MIN(1, result->a * alpha_src_factor.a + dcol.a * alpha_dest_factor.a);
+   else if (alpha_op == ALLEGRO_SRC_MINUS_DEST)
+      result->a = MAX(0, result->a * alpha_src_factor.a - dcol.a * alpha_dest_factor.a);
+   else if (alpha_op == ALLEGRO_DEST_MINUS_SRC)
+      result->a = MAX(0, dcol.a * alpha_dest_factor.a - result->a * alpha_src_factor.a);
 }
Index: src/opengl/ogl_bitmap.c
===================================================================
--- src/opengl/ogl_bitmap.c	(revision 14764)
+++ src/opengl/ogl_bitmap.c	(working copy)
@@ -173,8 +173,9 @@
 static INLINE bool setup_blending(ALLEGRO_DISPLAY *ogl_disp)
 {
    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_modes[6] = {
+      GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
+      GL_SRC_COLOR, GL_DST_COLOR
    };
    const int blend_equations[3] = {
       GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT
Index: src/win/d3d_disp.cpp
===================================================================
--- src/win/d3d_disp.cpp	(revision 14764)
+++ src/win/d3d_disp.cpp	(working copy)
@@ -2049,20 +2049,24 @@
 
 static int d3d_al_blender_to_d3d(int al_mode)
 {
-   int num_modes = 4;
+   int num_modes = 6;
 
    int allegro_modes[] = {
       ALLEGRO_ZERO,
       ALLEGRO_ONE,
       ALLEGRO_ALPHA,
-      ALLEGRO_INVERSE_ALPHA
+      ALLEGRO_INVERSE_ALPHA,
+      ALLEGRO_SRC_COLOR,
+      ALLEGRO_DST_COLOR
    };
 
    int d3d_modes[] = {
       D3DBLEND_ZERO,
       D3DBLEND_ONE,
       D3DBLEND_SRCALPHA,
-      D3DBLEND_INVSRCALPHA
+      D3DBLEND_INVSRCALPHA,
+      D3DBLEND_SRCCOLOR,
+      D3DBLEND_DESTCCOLOR
    };
 
    int i;


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