diff src/video/win32/SDL_gdirender.c @ 3054:8d93bfecb9dc

Fixed alpha blending textures with the GDI renderer
author Sam Lantinga <slouken@libsdl.org>
date Sat, 07 Feb 2009 17:56:08 +0000
parents 81fc47035302
children cd863dd2082b
line wrap: on
line diff
--- a/src/video/win32/SDL_gdirender.c	Fri Jan 30 06:40:16 2009 +0000
+++ b/src/video/win32/SDL_gdirender.c	Sat Feb 07 17:56:08 2009 +0000
@@ -26,6 +26,7 @@
 #include "SDL_win32video.h"
 #include "../SDL_rect_c.h"
 #include "../SDL_yuv_sw_c.h"
+#include "../SDL_alphamult.h"
 
 /* GDI renderer implementation */
 
@@ -120,6 +121,7 @@
     HBITMAP hbm;
     void *pixels;
     int pitch;
+    SDL_bool premultiplied;
 } GDI_TextureData;
 
 static void
@@ -463,10 +465,36 @@
 static int
 GDI_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture)
 {
+    GDI_TextureData *data = (GDI_TextureData *) texture->driverdata;
+
     switch (texture->blendMode) {
     case SDL_BLENDMODE_NONE:
+        if (data->premultiplied) {
+            /* Crap, we've lost the original pixel data... *sigh* */
+        }
+        return 0;
     case SDL_BLENDMODE_MASK:
     case SDL_BLENDMODE_BLEND:
+        if (!data->premultiplied && data->pixels) {
+            switch (texture->format) {
+            case SDL_PIXELFORMAT_ARGB8888:
+                SDL_PreMultiplyAlphaARGB8888(texture->w, texture->h, (Uint32 *)data->pixels, data->pitch);
+                data->premultiplied = SDL_TRUE;
+                break;
+            case SDL_PIXELFORMAT_RGBA8888:
+                SDL_PreMultiplyAlphaRGBA8888(texture->w, texture->h, (Uint32 *)data->pixels, data->pitch);
+                data->premultiplied = SDL_TRUE;
+                break;
+            case SDL_PIXELFORMAT_ABGR8888:
+                SDL_PreMultiplyAlphaABGR8888(texture->w, texture->h, (Uint32 *)data->pixels, data->pitch);
+                data->premultiplied = SDL_TRUE;
+                break;
+            case SDL_PIXELFORMAT_BGRA8888:
+                SDL_PreMultiplyAlphaBGRA8888(texture->w, texture->h, (Uint32 *)data->pixels, data->pitch);
+                data->premultiplied = SDL_TRUE;
+                break;
+            }
+        }
         return 0;
     default:
         SDL_Unsupported();
@@ -525,6 +553,23 @@
                 src += pitch;
                 dst += data->pitch;
             }
+            if (data->premultiplied) {
+                Uint32 *pixels = (Uint32 *) data->pixels + rect->y * (data->pitch / 4) + rect->x;
+                switch (texture->format) {
+                case SDL_PIXELFORMAT_ARGB8888:
+                    SDL_PreMultiplyAlphaARGB8888(rect->w, rect->h, pixels, data->pitch);
+                    break;
+                case SDL_PIXELFORMAT_RGBA8888:
+                    SDL_PreMultiplyAlphaRGBA8888(rect->w, rect->h, pixels, data->pitch);
+                    break;
+                case SDL_PIXELFORMAT_ABGR8888:
+                    SDL_PreMultiplyAlphaABGR8888(rect->w, rect->h, pixels, data->pitch);
+                    break;
+                case SDL_PIXELFORMAT_BGRA8888:
+                    SDL_PreMultiplyAlphaBGRA8888(rect->w, rect->h, pixels, data->pitch);
+                    break;
+                }
+            }
         } else if (rect->w == texture->w && pitch == data->pitch) {
             if (!SetDIBits
                 (renderdata->window_hdc, data->hbm, rect->y, rect->h, pixels,
@@ -700,16 +745,13 @@
         SelectPalette(data->memory_hdc, texturedata->hpal, TRUE);
         RealizePalette(data->memory_hdc);
     }
-    if (texture->blendMode & SDL_BLENDMODE_MASK) {
+    if (texture->blendMode & (SDL_BLENDMODE_MASK|SDL_BLENDMODE_BLEND)) {
         BLENDFUNCTION blendFunc = {
             AC_SRC_OVER,
             0,
             texture->a,
             AC_SRC_ALPHA
         };
-        /* FIXME: GDI uses premultiplied alpha!
-         *        Once we solve this and somehow support blended drawing we can enable SDL_BLENDMODE_BLEND
-         */
         if (!AlphaBlend
             (data->current_hdc, dstrect->x, dstrect->y, dstrect->w,
              dstrect->h, data->memory_hdc, srcrect->x, srcrect->y, srcrect->w,