Re: [AD] getpixel conflict with alpha blended sprites

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


> I'd rather not end up doing it manually with a switch statement for each
> colour depth and then _getpixelXX, because that would be slower than using
> the vtable as at present.

Here's a patch (mostly borrowed from Sven) that adds is_inside_bitmap() to 
test whether a point lies inside a bitmap.  The function is inline so any 
reasonably good compiler should be able to optimize it down to a couple of 
tests in the common case ('clip' argument passed as FALSE).

The only difference with Sven (apart from the name) is that it returns TRUE 
if 'clip' is passed as TRUE and clipping has been disabled for the bitmap.

-- 
Eric Botcazou
--- /home/eric/cvs/allegro/include/allegro/inline/gfx.inl	Sat Nov 29 08:25:22 2003
+++ allegro/include/allegro/inline/gfx.inl	Sat Dec 13 15:03:22 2003
@@ -223,6 +223,23 @@
 #endif
 
 
+AL_INLINE(int, is_inside_bitmap, (BITMAP *bmp, int x, int y, int clip),
+{
+   ASSERT(bmp);
+
+   if (clip) {
+      if (bmp->clip)
+         /* internal clipping is inclusive-exclusive */
+         return (x >= bmp->cl) && (y >= bmp->ct) && (x < bmp->cr) && (y < bmp->cb);
+      else
+         return TRUE;
+   }
+   else
+      /* bitmap dimensions are always non-negative */
+      return (unsigned int)x < (unsigned int)bmp->w && (unsigned int)y < (unsigned int)bmp->h;
+})
+
+
 AL_INLINE(void, get_clip_rect, (BITMAP *bitmap, int *x1, int *y1, int *x2, int *y2),
 {
    ASSERT(bitmap);
--- /home/eric/cvs/allegro/docs/src/allegro._tx	Sat Nov 29 08:25:22 2003
+++ allegro/docs/src/allegro._tx	Sat Dec 13 15:07:23 2003
@@ -3786,6 +3786,15 @@
    Returns non-zero if clipping is turned on for the specified bitmap and
    zero otherwise.
 
+@@int @is_inside_bitmap(BITMAP *bmp, int x, int y, int clip);
+@xref set_clip_rect, set_clip_state, getpixel
+   Returns non-zero if point (x, y) lies inside the bitmap. If `clip' is
+   non-zero, the function compares the coordinates with the clipping
+   rectangle, that is it returns non-zero if the point lies inside the
+   clipping rectangle or if clipping is disabled for the bitmap. If `clip'
+   is zero, the function compares the coordinates with the actual dimensions
+   of the bitmap.
+
 
 
 @heading
@@ -4313,11 +4322,16 @@
    mode.
 
 @@int @getpixel(BITMAP *bmp, int x, int y);
-@domain.hid putpixel, _getpixel
+@xref putpixel, _getpixel, is_inside_bitmap
 @eref ex12bit, exalpha, exflame, exlights
-   Reads a pixel from point x, y in the bitmap. Returns -1 if the point lies 
-   outside the bitmap.
+   Reads a pixel from point (x, y) in the bitmap. Returns -1 if the point
+   lies outside the bitmap (ignoring the clipping rectangle).
 
+   Warning: -1 is also a valid value for pixels contained in 32-bit bitmaps
+   with alpha channel (when R,G,B,A are all equal to 255) so you can't use
+   the test against -1 it as a predicate for such bitmaps. In this case, the
+   only reliable predicate is is_inside_bitmap().
+ 
 @@int @_getpixel(BITMAP *bmp, int x, int y);
 @@int @_getpixel15(BITMAP *bmp, int x, int y);
 @@int @_getpixel16(BITMAP *bmp, int x, int y);


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