Mercurial > sdl-ios-xcode
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()"); |