comparison 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
comparison
equal deleted inserted replaced
3053:aa34d1180d30 3054:8d93bfecb9dc
24 #if SDL_VIDEO_RENDER_GDI 24 #if SDL_VIDEO_RENDER_GDI
25 25
26 #include "SDL_win32video.h" 26 #include "SDL_win32video.h"
27 #include "../SDL_rect_c.h" 27 #include "../SDL_rect_c.h"
28 #include "../SDL_yuv_sw_c.h" 28 #include "../SDL_yuv_sw_c.h"
29 #include "../SDL_alphamult.h"
29 30
30 /* GDI renderer implementation */ 31 /* GDI renderer implementation */
31 32
32 static SDL_Renderer *GDI_CreateRenderer(SDL_Window * window, Uint32 flags); 33 static SDL_Renderer *GDI_CreateRenderer(SDL_Window * window, Uint32 flags);
33 static int GDI_DisplayModeChanged(SDL_Renderer * renderer); 34 static int GDI_DisplayModeChanged(SDL_Renderer * renderer);
118 Uint32 format; 119 Uint32 format;
119 HPALETTE hpal; 120 HPALETTE hpal;
120 HBITMAP hbm; 121 HBITMAP hbm;
121 void *pixels; 122 void *pixels;
122 int pitch; 123 int pitch;
124 SDL_bool premultiplied;
123 } GDI_TextureData; 125 } GDI_TextureData;
124 126
125 static void 127 static void
126 UpdateYUVTextureData(SDL_Texture * texture) 128 UpdateYUVTextureData(SDL_Texture * texture)
127 { 129 {
461 } 463 }
462 464
463 static int 465 static int
464 GDI_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture) 466 GDI_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture)
465 { 467 {
468 GDI_TextureData *data = (GDI_TextureData *) texture->driverdata;
469
466 switch (texture->blendMode) { 470 switch (texture->blendMode) {
467 case SDL_BLENDMODE_NONE: 471 case SDL_BLENDMODE_NONE:
472 if (data->premultiplied) {
473 /* Crap, we've lost the original pixel data... *sigh* */
474 }
475 return 0;
468 case SDL_BLENDMODE_MASK: 476 case SDL_BLENDMODE_MASK:
469 case SDL_BLENDMODE_BLEND: 477 case SDL_BLENDMODE_BLEND:
478 if (!data->premultiplied && data->pixels) {
479 switch (texture->format) {
480 case SDL_PIXELFORMAT_ARGB8888:
481 SDL_PreMultiplyAlphaARGB8888(texture->w, texture->h, (Uint32 *)data->pixels, data->pitch);
482 data->premultiplied = SDL_TRUE;
483 break;
484 case SDL_PIXELFORMAT_RGBA8888:
485 SDL_PreMultiplyAlphaRGBA8888(texture->w, texture->h, (Uint32 *)data->pixels, data->pitch);
486 data->premultiplied = SDL_TRUE;
487 break;
488 case SDL_PIXELFORMAT_ABGR8888:
489 SDL_PreMultiplyAlphaABGR8888(texture->w, texture->h, (Uint32 *)data->pixels, data->pitch);
490 data->premultiplied = SDL_TRUE;
491 break;
492 case SDL_PIXELFORMAT_BGRA8888:
493 SDL_PreMultiplyAlphaBGRA8888(texture->w, texture->h, (Uint32 *)data->pixels, data->pitch);
494 data->premultiplied = SDL_TRUE;
495 break;
496 }
497 }
470 return 0; 498 return 0;
471 default: 499 default:
472 SDL_Unsupported(); 500 SDL_Unsupported();
473 texture->blendMode = SDL_BLENDMODE_NONE; 501 texture->blendMode = SDL_BLENDMODE_NONE;
474 return -1; 502 return -1;
522 length = rect->w * SDL_BYTESPERPIXEL(texture->format); 550 length = rect->w * SDL_BYTESPERPIXEL(texture->format);
523 for (row = 0; row < rect->h; ++row) { 551 for (row = 0; row < rect->h; ++row) {
524 SDL_memcpy(dst, src, length); 552 SDL_memcpy(dst, src, length);
525 src += pitch; 553 src += pitch;
526 dst += data->pitch; 554 dst += data->pitch;
555 }
556 if (data->premultiplied) {
557 Uint32 *pixels = (Uint32 *) data->pixels + rect->y * (data->pitch / 4) + rect->x;
558 switch (texture->format) {
559 case SDL_PIXELFORMAT_ARGB8888:
560 SDL_PreMultiplyAlphaARGB8888(rect->w, rect->h, pixels, data->pitch);
561 break;
562 case SDL_PIXELFORMAT_RGBA8888:
563 SDL_PreMultiplyAlphaRGBA8888(rect->w, rect->h, pixels, data->pitch);
564 break;
565 case SDL_PIXELFORMAT_ABGR8888:
566 SDL_PreMultiplyAlphaABGR8888(rect->w, rect->h, pixels, data->pitch);
567 break;
568 case SDL_PIXELFORMAT_BGRA8888:
569 SDL_PreMultiplyAlphaBGRA8888(rect->w, rect->h, pixels, data->pitch);
570 break;
571 }
527 } 572 }
528 } else if (rect->w == texture->w && pitch == data->pitch) { 573 } else if (rect->w == texture->w && pitch == data->pitch) {
529 if (!SetDIBits 574 if (!SetDIBits
530 (renderdata->window_hdc, data->hbm, rect->y, rect->h, pixels, 575 (renderdata->window_hdc, data->hbm, rect->y, rect->h, pixels,
531 renderdata->bmi, DIB_RGB_COLORS)) { 576 renderdata->bmi, DIB_RGB_COLORS)) {
698 SelectObject(data->memory_hdc, texturedata->hbm); 743 SelectObject(data->memory_hdc, texturedata->hbm);
699 if (texturedata->hpal) { 744 if (texturedata->hpal) {
700 SelectPalette(data->memory_hdc, texturedata->hpal, TRUE); 745 SelectPalette(data->memory_hdc, texturedata->hpal, TRUE);
701 RealizePalette(data->memory_hdc); 746 RealizePalette(data->memory_hdc);
702 } 747 }
703 if (texture->blendMode & SDL_BLENDMODE_MASK) { 748 if (texture->blendMode & (SDL_BLENDMODE_MASK|SDL_BLENDMODE_BLEND)) {
704 BLENDFUNCTION blendFunc = { 749 BLENDFUNCTION blendFunc = {
705 AC_SRC_OVER, 750 AC_SRC_OVER,
706 0, 751 0,
707 texture->a, 752 texture->a,
708 AC_SRC_ALPHA 753 AC_SRC_ALPHA
709 }; 754 };
710 /* FIXME: GDI uses premultiplied alpha!
711 * Once we solve this and somehow support blended drawing we can enable SDL_BLENDMODE_BLEND
712 */
713 if (!AlphaBlend 755 if (!AlphaBlend
714 (data->current_hdc, dstrect->x, dstrect->y, dstrect->w, 756 (data->current_hdc, dstrect->x, dstrect->y, dstrect->w,
715 dstrect->h, data->memory_hdc, srcrect->x, srcrect->y, srcrect->w, 757 dstrect->h, data->memory_hdc, srcrect->x, srcrect->y, srcrect->w,
716 srcrect->h, blendFunc)) { 758 srcrect->h, blendFunc)) {
717 WIN_SetError("AlphaBlend()"); 759 WIN_SetError("AlphaBlend()");