Fixed bug 4903 - Lack of color multiply with alpha (SDL_BLENDMODE_MOD + SDL_BLENDMODE_BLEND) blending mode for all renderers

Konrad

This kind of blending is rather quite useful and in my opinion should be available for all renderers. I do need it myself, but since I didn't want to use a custom blending mode which is supported only by certain renderers (e.g. not in software which is quite important for me) I did write implementation of SDL_BLENDMODE_MUL for all renderers altogether.

SDL_BLENDMODE_MUL implements following equation:

dstRGB = (srcRGB * dstRGB) + (dstRGB * (1-srcA))
dstA = (srcA * dstA) + (dstA * (1-srcA))

Background:

https://i.imgur.com/UsYhydP.png

Blended texture:

https://i.imgur.com/0juXQcV.png

Result for SDL_BLENDMODE_MOD:

https://i.imgur.com/wgNSgUl.png

Result for SDL_BLENDMODE_MUL:

https://i.imgur.com/Veokzim.png

I think I did cover all possibilities within included patch, but I didn't write any tests for SDL_BLENDMODE_MUL, so it would be lovely if someone could do it.
This commit is contained in:
Sam Lantinga
2020-01-16 08:52:59 -08:00
parent 669729a8a0
commit 981e0d367c
19 changed files with 819 additions and 159 deletions

View File

@@ -75,6 +75,10 @@
SDL_COMPOSE_BLENDMODE(SDL_BLENDFACTOR_ZERO, SDL_BLENDFACTOR_SRC_COLOR, SDL_BLENDOPERATION_ADD, \
SDL_BLENDFACTOR_ZERO, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_ADD)
#define SDL_BLENDMODE_MUL_FULL \
SDL_COMPOSE_BLENDMODE(SDL_BLENDFACTOR_DST_COLOR, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD, \
SDL_BLENDFACTOR_DST_ALPHA, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD)
#if !SDL_RENDER_DISABLED
static const SDL_RenderDriver *render_drivers[] = {
#if SDL_VIDEO_RENDER_D3D
@@ -970,6 +974,7 @@ IsSupportedBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
case SDL_BLENDMODE_BLEND:
case SDL_BLENDMODE_ADD:
case SDL_BLENDMODE_MOD:
case SDL_BLENDMODE_MUL:
return SDL_TRUE;
default:
@@ -3288,6 +3293,9 @@ SDL_GetShortBlendMode(SDL_BlendMode blendMode)
if (blendMode == SDL_BLENDMODE_MOD_FULL) {
return SDL_BLENDMODE_MOD;
}
if (blendMode == SDL_BLENDMODE_MUL_FULL) {
return SDL_BLENDMODE_MUL;
}
return blendMode;
}
@@ -3306,6 +3314,9 @@ SDL_GetLongBlendMode(SDL_BlendMode blendMode)
if (blendMode == SDL_BLENDMODE_MOD) {
return SDL_BLENDMODE_MOD_FULL;
}
if (blendMode == SDL_BLENDMODE_MUL) {
return SDL_BLENDMODE_MUL_FULL;
}
return blendMode;
}

View File

@@ -636,7 +636,8 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer)
/* Create blending states: */
if (!D3D11_CreateBlendState(renderer, SDL_BLENDMODE_BLEND) ||
!D3D11_CreateBlendState(renderer, SDL_BLENDMODE_ADD) ||
!D3D11_CreateBlendState(renderer, SDL_BLENDMODE_MOD)) {
!D3D11_CreateBlendState(renderer, SDL_BLENDMODE_MOD) ||
!D3D11_CreateBlendState(renderer, SDL_BLENDMODE_MUL)) {
/* D3D11_CreateBlendMode will set the SDL error, if it fails */
goto done;
}

View File

@@ -357,6 +357,7 @@ MakePipelineCache(METAL_RenderData *data, METAL_PipelineCache *cache, const char
MakePipelineState(data, cache, @" (blend=blend)", SDL_BLENDMODE_BLEND);
MakePipelineState(data, cache, @" (blend=add)", SDL_BLENDMODE_ADD);
MakePipelineState(data, cache, @" (blend=mod)", SDL_BLENDMODE_MOD);
MakePipelineState(data, cache, @" (blend=mul)", SDL_BLENDMODE_MUL);
}
static void

View File

@@ -676,7 +676,12 @@ PSP_SetBlendMode(SDL_Renderer * renderer, int blendMode)
case SDL_BLENDMODE_MOD:
sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
sceGuEnable(GU_BLEND);
sceGuBlendFunc( GU_ADD, GU_FIX, GU_SRC_COLOR, 0, 0);
sceGuBlendFunc(GU_ADD, GU_FIX, GU_SRC_COLOR, 0, 0);
break;
case SDL_BLENDMODE_MUL:
sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
sceGuEnable(GU_BLEND);
sceGuBlendFunc(GU_ADD, GU_DST_COLOR, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
break;
}
data->currentBlendMode = blendMode;

View File

@@ -42,6 +42,9 @@ SDL_BlendFillRect_RGB555(SDL_Surface * dst, const SDL_Rect * rect,
case SDL_BLENDMODE_MOD:
FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB555);
break;
case SDL_BLENDMODE_MUL:
FILLRECT(Uint16, DRAW_SETPIXEL_MUL_RGB555);
break;
default:
FILLRECT(Uint16, DRAW_SETPIXEL_RGB555);
break;
@@ -65,6 +68,9 @@ SDL_BlendFillRect_RGB565(SDL_Surface * dst, const SDL_Rect * rect,
case SDL_BLENDMODE_MOD:
FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB565);
break;
case SDL_BLENDMODE_MUL:
FILLRECT(Uint16, DRAW_SETPIXEL_MUL_RGB565);
break;
default:
FILLRECT(Uint16, DRAW_SETPIXEL_RGB565);
break;
@@ -88,6 +94,9 @@ SDL_BlendFillRect_RGB888(SDL_Surface * dst, const SDL_Rect * rect,
case SDL_BLENDMODE_MOD:
FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGB888);
break;
case SDL_BLENDMODE_MUL:
FILLRECT(Uint32, DRAW_SETPIXEL_MUL_RGB888);
break;
default:
FILLRECT(Uint32, DRAW_SETPIXEL_RGB888);
break;
@@ -111,6 +120,9 @@ SDL_BlendFillRect_ARGB8888(SDL_Surface * dst, const SDL_Rect * rect,
case SDL_BLENDMODE_MOD:
FILLRECT(Uint32, DRAW_SETPIXEL_MOD_ARGB8888);
break;
case SDL_BLENDMODE_MUL:
FILLRECT(Uint32, DRAW_SETPIXEL_MUL_ARGB8888);
break;
default:
FILLRECT(Uint32, DRAW_SETPIXEL_ARGB8888);
break;
@@ -137,6 +149,9 @@ SDL_BlendFillRect_RGB(SDL_Surface * dst, const SDL_Rect * rect,
case SDL_BLENDMODE_MOD:
FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB);
break;
case SDL_BLENDMODE_MUL:
FILLRECT(Uint16, DRAW_SETPIXEL_MUL_RGB);
break;
default:
FILLRECT(Uint16, DRAW_SETPIXEL_RGB);
break;
@@ -153,6 +168,9 @@ SDL_BlendFillRect_RGB(SDL_Surface * dst, const SDL_Rect * rect,
case SDL_BLENDMODE_MOD:
FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGB);
break;
case SDL_BLENDMODE_MUL:
FILLRECT(Uint32, DRAW_SETPIXEL_MUL_RGB);
break;
default:
FILLRECT(Uint32, DRAW_SETPIXEL_RGB);
break;
@@ -182,6 +200,9 @@ SDL_BlendFillRect_RGBA(SDL_Surface * dst, const SDL_Rect * rect,
case SDL_BLENDMODE_MOD:
FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGBA);
break;
case SDL_BLENDMODE_MUL:
FILLRECT(Uint32, DRAW_SETPIXEL_MUL_RGBA);
break;
default:
FILLRECT(Uint32, DRAW_SETPIXEL_RGBA);
break;

View File

@@ -59,6 +59,9 @@ SDL_BlendLine_RGB2(SDL_Surface * dst, int x1, int y1, int x2, int y2,
case SDL_BLENDMODE_MOD:
HLINE(Uint16, DRAW_SETPIXEL_MOD_RGB, draw_end);
break;
case SDL_BLENDMODE_MUL:
HLINE(Uint16, DRAW_SETPIXEL_MUL_RGB, draw_end);
break;
default:
HLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end);
break;
@@ -74,6 +77,9 @@ SDL_BlendLine_RGB2(SDL_Surface * dst, int x1, int y1, int x2, int y2,
case SDL_BLENDMODE_MOD:
VLINE(Uint16, DRAW_SETPIXEL_MOD_RGB, draw_end);
break;
case SDL_BLENDMODE_MUL:
VLINE(Uint16, DRAW_SETPIXEL_MUL_RGB, draw_end);
break;
default:
VLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end);
break;
@@ -89,6 +95,9 @@ SDL_BlendLine_RGB2(SDL_Surface * dst, int x1, int y1, int x2, int y2,
case SDL_BLENDMODE_MOD:
DLINE(Uint16, DRAW_SETPIXEL_MOD_RGB, draw_end);
break;
case SDL_BLENDMODE_MUL:
DLINE(Uint16, DRAW_SETPIXEL_MUL_RGB, draw_end);
break;
default:
DLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end);
break;
@@ -110,6 +119,11 @@ SDL_BlendLine_RGB2(SDL_Surface * dst, int x1, int y1, int x2, int y2,
DRAW_SETPIXELXY2_MOD_RGB, DRAW_SETPIXELXY2_MOD_RGB,
draw_end);
break;
case SDL_BLENDMODE_MUL:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY2_MUL_RGB, DRAW_SETPIXELXY2_MUL_RGB,
draw_end);
break;
default:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY2_RGB, DRAW_SETPIXELXY2_BLEND_RGB,
@@ -150,6 +164,9 @@ SDL_BlendLine_RGB555(SDL_Surface * dst, int x1, int y1, int x2, int y2,
case SDL_BLENDMODE_MOD:
HLINE(Uint16, DRAW_SETPIXEL_MOD_RGB555, draw_end);
break;
case SDL_BLENDMODE_MUL:
HLINE(Uint16, DRAW_SETPIXEL_MUL_RGB555, draw_end);
break;
default:
HLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end);
break;
@@ -165,6 +182,9 @@ SDL_BlendLine_RGB555(SDL_Surface * dst, int x1, int y1, int x2, int y2,
case SDL_BLENDMODE_MOD:
VLINE(Uint16, DRAW_SETPIXEL_MOD_RGB555, draw_end);
break;
case SDL_BLENDMODE_MUL:
VLINE(Uint16, DRAW_SETPIXEL_MUL_RGB555, draw_end);
break;
default:
VLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end);
break;
@@ -180,6 +200,9 @@ SDL_BlendLine_RGB555(SDL_Surface * dst, int x1, int y1, int x2, int y2,
case SDL_BLENDMODE_MOD:
DLINE(Uint16, DRAW_SETPIXEL_MOD_RGB555, draw_end);
break;
case SDL_BLENDMODE_MUL:
DLINE(Uint16, DRAW_SETPIXEL_MUL_RGB555, draw_end);
break;
default:
DLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end);
break;
@@ -201,6 +224,11 @@ SDL_BlendLine_RGB555(SDL_Surface * dst, int x1, int y1, int x2, int y2,
DRAW_SETPIXELXY_MOD_RGB555, DRAW_SETPIXELXY_MOD_RGB555,
draw_end);
break;
case SDL_BLENDMODE_MUL:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_MUL_RGB555, DRAW_SETPIXELXY_MUL_RGB555,
draw_end);
break;
default:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_RGB555, DRAW_SETPIXELXY_BLEND_RGB555,
@@ -241,6 +269,9 @@ SDL_BlendLine_RGB565(SDL_Surface * dst, int x1, int y1, int x2, int y2,
case SDL_BLENDMODE_MOD:
HLINE(Uint16, DRAW_SETPIXEL_MOD_RGB565, draw_end);
break;
case SDL_BLENDMODE_MUL:
HLINE(Uint16, DRAW_SETPIXEL_MUL_RGB565, draw_end);
break;
default:
HLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end);
break;
@@ -256,6 +287,9 @@ SDL_BlendLine_RGB565(SDL_Surface * dst, int x1, int y1, int x2, int y2,
case SDL_BLENDMODE_MOD:
VLINE(Uint16, DRAW_SETPIXEL_MOD_RGB565, draw_end);
break;
case SDL_BLENDMODE_MUL:
VLINE(Uint16, DRAW_SETPIXEL_MUL_RGB565, draw_end);
break;
default:
VLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end);
break;
@@ -271,6 +305,9 @@ SDL_BlendLine_RGB565(SDL_Surface * dst, int x1, int y1, int x2, int y2,
case SDL_BLENDMODE_MOD:
DLINE(Uint16, DRAW_SETPIXEL_MOD_RGB565, draw_end);
break;
case SDL_BLENDMODE_MUL:
DLINE(Uint16, DRAW_SETPIXEL_MUL_RGB565, draw_end);
break;
default:
DLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end);
break;
@@ -292,6 +329,11 @@ SDL_BlendLine_RGB565(SDL_Surface * dst, int x1, int y1, int x2, int y2,
DRAW_SETPIXELXY_MOD_RGB565, DRAW_SETPIXELXY_MOD_RGB565,
draw_end);
break;
case SDL_BLENDMODE_MUL:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_MUL_RGB565, DRAW_SETPIXELXY_MUL_RGB565,
draw_end);
break;
default:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_RGB565, DRAW_SETPIXELXY_BLEND_RGB565,
@@ -333,6 +375,9 @@ SDL_BlendLine_RGB4(SDL_Surface * dst, int x1, int y1, int x2, int y2,
case SDL_BLENDMODE_MOD:
HLINE(Uint32, DRAW_SETPIXEL_MOD_RGB, draw_end);
break;
case SDL_BLENDMODE_MUL:
HLINE(Uint32, DRAW_SETPIXEL_MUL_RGB, draw_end);
break;
default:
HLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end);
break;
@@ -348,6 +393,9 @@ SDL_BlendLine_RGB4(SDL_Surface * dst, int x1, int y1, int x2, int y2,
case SDL_BLENDMODE_MOD:
VLINE(Uint32, DRAW_SETPIXEL_MOD_RGB, draw_end);
break;
case SDL_BLENDMODE_MUL:
VLINE(Uint32, DRAW_SETPIXEL_MUL_RGB, draw_end);
break;
default:
VLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end);
break;
@@ -363,6 +411,9 @@ SDL_BlendLine_RGB4(SDL_Surface * dst, int x1, int y1, int x2, int y2,
case SDL_BLENDMODE_MOD:
DLINE(Uint32, DRAW_SETPIXEL_MOD_RGB, draw_end);
break;
case SDL_BLENDMODE_MUL:
DLINE(Uint32, DRAW_SETPIXEL_MUL_RGB, draw_end);
break;
default:
DLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end);
break;
@@ -384,6 +435,11 @@ SDL_BlendLine_RGB4(SDL_Surface * dst, int x1, int y1, int x2, int y2,
DRAW_SETPIXELXY4_MOD_RGB, DRAW_SETPIXELXY4_MOD_RGB,
draw_end);
break;
case SDL_BLENDMODE_MUL:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY4_MUL_RGB, DRAW_SETPIXELXY4_MUL_RGB,
draw_end);
break;
default:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY4_RGB, DRAW_SETPIXELXY4_BLEND_RGB,
@@ -425,6 +481,9 @@ SDL_BlendLine_RGBA4(SDL_Surface * dst, int x1, int y1, int x2, int y2,
case SDL_BLENDMODE_MOD:
HLINE(Uint32, DRAW_SETPIXEL_MOD_RGBA, draw_end);
break;
case SDL_BLENDMODE_MUL:
HLINE(Uint32, DRAW_SETPIXEL_MUL_RGBA, draw_end);
break;
default:
HLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end);
break;
@@ -440,6 +499,9 @@ SDL_BlendLine_RGBA4(SDL_Surface * dst, int x1, int y1, int x2, int y2,
case SDL_BLENDMODE_MOD:
VLINE(Uint32, DRAW_SETPIXEL_MOD_RGBA, draw_end);
break;
case SDL_BLENDMODE_MUL:
VLINE(Uint32, DRAW_SETPIXEL_MUL_RGBA, draw_end);
break;
default:
VLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end);
break;
@@ -455,6 +517,9 @@ SDL_BlendLine_RGBA4(SDL_Surface * dst, int x1, int y1, int x2, int y2,
case SDL_BLENDMODE_MOD:
DLINE(Uint32, DRAW_SETPIXEL_MOD_RGBA, draw_end);
break;
case SDL_BLENDMODE_MUL:
DLINE(Uint32, DRAW_SETPIXEL_MUL_RGBA, draw_end);
break;
default:
DLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end);
break;
@@ -476,6 +541,11 @@ SDL_BlendLine_RGBA4(SDL_Surface * dst, int x1, int y1, int x2, int y2,
DRAW_SETPIXELXY4_MOD_RGBA, DRAW_SETPIXELXY4_MOD_RGBA,
draw_end);
break;
case SDL_BLENDMODE_MUL:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY4_MUL_RGBA, DRAW_SETPIXELXY4_MUL_RGBA,
draw_end);
break;
default:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY4_RGBA, DRAW_SETPIXELXY4_BLEND_RGBA,
@@ -516,6 +586,9 @@ SDL_BlendLine_RGB888(SDL_Surface * dst, int x1, int y1, int x2, int y2,
case SDL_BLENDMODE_MOD:
HLINE(Uint32, DRAW_SETPIXEL_MOD_RGB888, draw_end);
break;
case SDL_BLENDMODE_MUL:
HLINE(Uint32, DRAW_SETPIXEL_MUL_RGB888, draw_end);
break;
default:
HLINE(Uint32, DRAW_SETPIXEL_RGB888, draw_end);
break;
@@ -531,6 +604,9 @@ SDL_BlendLine_RGB888(SDL_Surface * dst, int x1, int y1, int x2, int y2,
case SDL_BLENDMODE_MOD:
VLINE(Uint32, DRAW_SETPIXEL_MOD_RGB888, draw_end);
break;
case SDL_BLENDMODE_MUL:
VLINE(Uint32, DRAW_SETPIXEL_MUL_RGB888, draw_end);
break;
default:
VLINE(Uint32, DRAW_SETPIXEL_RGB888, draw_end);
break;
@@ -546,6 +622,9 @@ SDL_BlendLine_RGB888(SDL_Surface * dst, int x1, int y1, int x2, int y2,
case SDL_BLENDMODE_MOD:
DLINE(Uint32, DRAW_SETPIXEL_MOD_RGB888, draw_end);
break;
case SDL_BLENDMODE_MUL:
DLINE(Uint32, DRAW_SETPIXEL_MUL_RGB888, draw_end);
break;
default:
DLINE(Uint32, DRAW_SETPIXEL_RGB888, draw_end);
break;
@@ -567,6 +646,11 @@ SDL_BlendLine_RGB888(SDL_Surface * dst, int x1, int y1, int x2, int y2,
DRAW_SETPIXELXY_MOD_RGB888, DRAW_SETPIXELXY_MOD_RGB888,
draw_end);
break;
case SDL_BLENDMODE_MUL:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_MUL_RGB888, DRAW_SETPIXELXY_MUL_RGB888,
draw_end);
break;
default:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_RGB888, DRAW_SETPIXELXY_BLEND_RGB888,
@@ -607,6 +691,9 @@ SDL_BlendLine_ARGB8888(SDL_Surface * dst, int x1, int y1, int x2, int y2,
case SDL_BLENDMODE_MOD:
HLINE(Uint32, DRAW_SETPIXEL_MOD_ARGB8888, draw_end);
break;
case SDL_BLENDMODE_MUL:
HLINE(Uint32, DRAW_SETPIXEL_MUL_ARGB8888, draw_end);
break;
default:
HLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end);
break;
@@ -622,6 +709,9 @@ SDL_BlendLine_ARGB8888(SDL_Surface * dst, int x1, int y1, int x2, int y2,
case SDL_BLENDMODE_MOD:
VLINE(Uint32, DRAW_SETPIXEL_MOD_ARGB8888, draw_end);
break;
case SDL_BLENDMODE_MUL:
VLINE(Uint32, DRAW_SETPIXEL_MUL_ARGB8888, draw_end);
break;
default:
VLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end);
break;
@@ -637,6 +727,9 @@ SDL_BlendLine_ARGB8888(SDL_Surface * dst, int x1, int y1, int x2, int y2,
case SDL_BLENDMODE_MOD:
DLINE(Uint32, DRAW_SETPIXEL_MOD_ARGB8888, draw_end);
break;
case SDL_BLENDMODE_MUL:
DLINE(Uint32, DRAW_SETPIXEL_MUL_ARGB8888, draw_end);
break;
default:
DLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end);
break;
@@ -658,6 +751,11 @@ SDL_BlendLine_ARGB8888(SDL_Surface * dst, int x1, int y1, int x2, int y2,
DRAW_SETPIXELXY_MOD_ARGB8888, DRAW_SETPIXELXY_MOD_ARGB8888,
draw_end);
break;
case SDL_BLENDMODE_MUL:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_MUL_ARGB8888, DRAW_SETPIXELXY_MUL_ARGB8888,
draw_end);
break;
default:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_ARGB8888, DRAW_SETPIXELXY_BLEND_ARGB8888,

View File

@@ -42,6 +42,9 @@ SDL_BlendPoint_RGB555(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode,
case SDL_BLENDMODE_MOD:
DRAW_SETPIXELXY_MOD_RGB555(x, y);
break;
case SDL_BLENDMODE_MUL:
DRAW_SETPIXELXY_MUL_RGB555(x, y);
break;
default:
DRAW_SETPIXELXY_RGB555(x, y);
break;
@@ -65,6 +68,9 @@ SDL_BlendPoint_RGB565(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode,
case SDL_BLENDMODE_MOD:
DRAW_SETPIXELXY_MOD_RGB565(x, y);
break;
case SDL_BLENDMODE_MUL:
DRAW_SETPIXELXY_MUL_RGB565(x, y);
break;
default:
DRAW_SETPIXELXY_RGB565(x, y);
break;
@@ -88,6 +94,9 @@ SDL_BlendPoint_RGB888(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode,
case SDL_BLENDMODE_MOD:
DRAW_SETPIXELXY_MOD_RGB888(x, y);
break;
case SDL_BLENDMODE_MUL:
DRAW_SETPIXELXY_MUL_RGB888(x, y);
break;
default:
DRAW_SETPIXELXY_RGB888(x, y);
break;
@@ -111,6 +120,9 @@ SDL_BlendPoint_ARGB8888(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode
case SDL_BLENDMODE_MOD:
DRAW_SETPIXELXY_MOD_ARGB8888(x, y);
break;
case SDL_BLENDMODE_MUL:
DRAW_SETPIXELXY_MUL_ARGB8888(x, y);
break;
default:
DRAW_SETPIXELXY_ARGB8888(x, y);
break;
@@ -137,6 +149,9 @@ SDL_BlendPoint_RGB(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uin
case SDL_BLENDMODE_MOD:
DRAW_SETPIXELXY2_MOD_RGB(x, y);
break;
case SDL_BLENDMODE_MUL:
DRAW_SETPIXELXY2_MUL_RGB(x, y);
break;
default:
DRAW_SETPIXELXY2_RGB(x, y);
break;
@@ -153,6 +168,9 @@ SDL_BlendPoint_RGB(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uin
case SDL_BLENDMODE_MOD:
DRAW_SETPIXELXY4_MOD_RGB(x, y);
break;
case SDL_BLENDMODE_MUL:
DRAW_SETPIXELXY4_MUL_RGB(x, y);
break;
default:
DRAW_SETPIXELXY4_RGB(x, y);
break;
@@ -182,6 +200,9 @@ SDL_BlendPoint_RGBA(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Ui
case SDL_BLENDMODE_MOD:
DRAW_SETPIXELXY4_MOD_RGBA(x, y);
break;
case SDL_BLENDMODE_MUL:
DRAW_SETPIXELXY4_MUL_RGBA(x, y);
break;
default:
DRAW_SETPIXELXY4_RGBA(x, y);
break;

View File

@@ -80,6 +80,17 @@ do { \
setpixel; \
} while (0)
#define DRAW_SETPIXEL_MUL(getpixel, setpixel) \
do { \
unsigned sr, sg, sb, sa; sa = 0xFF; \
getpixel; \
sr = DRAW_MUL(sr, r) + DRAW_MUL(inva, sr); if (sr > 0xff) sr = 0xff; \
sg = DRAW_MUL(sg, g) + DRAW_MUL(inva, sg); if (sg > 0xff) sg = 0xff; \
sb = DRAW_MUL(sb, b) + DRAW_MUL(inva, sb); if (sb > 0xff) sb = 0xff; \
sa = DRAW_MUL(sa, a) + DRAW_MUL(inva, sa); if (sa > 0xff) sa = 0xff; \
setpixel; \
} while (0)
#define DRAW_SETPIXELXY(x, y, type, bpp, op) \
do { \
type *pixel = (type *)((Uint8 *)dst->pixels + (y) * dst->pitch \
@@ -106,6 +117,10 @@ do { \
DRAW_SETPIXEL_MOD(RGB_FROM_RGB555(*pixel, sr, sg, sb), \
RGB555_FROM_RGB(*pixel, sr, sg, sb))
#define DRAW_SETPIXEL_MUL_RGB555 \
DRAW_SETPIXEL_MUL(RGB_FROM_RGB555(*pixel, sr, sg, sb), \
RGB555_FROM_RGB(*pixel, sr, sg, sb))
#define DRAW_SETPIXELXY_RGB555(x, y) \
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_RGB555)
@@ -118,6 +133,9 @@ do { \
#define DRAW_SETPIXELXY_MOD_RGB555(x, y) \
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MOD_RGB555)
#define DRAW_SETPIXELXY_MUL_RGB555(x, y) \
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MUL_RGB555)
/*
* Define draw operators for RGB565
*/
@@ -137,6 +155,10 @@ do { \
DRAW_SETPIXEL_MOD(RGB_FROM_RGB565(*pixel, sr, sg, sb), \
RGB565_FROM_RGB(*pixel, sr, sg, sb))
#define DRAW_SETPIXEL_MUL_RGB565 \
DRAW_SETPIXEL_MUL(RGB_FROM_RGB565(*pixel, sr, sg, sb), \
RGB565_FROM_RGB(*pixel, sr, sg, sb))
#define DRAW_SETPIXELXY_RGB565(x, y) \
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_RGB565)
@@ -149,6 +171,9 @@ do { \
#define DRAW_SETPIXELXY_MOD_RGB565(x, y) \
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MOD_RGB565)
#define DRAW_SETPIXELXY_MUL_RGB565(x, y) \
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MUL_RGB565)
/*
* Define draw operators for RGB888
*/
@@ -168,6 +193,10 @@ do { \
DRAW_SETPIXEL_MOD(RGB_FROM_RGB888(*pixel, sr, sg, sb), \
RGB888_FROM_RGB(*pixel, sr, sg, sb))
#define DRAW_SETPIXEL_MUL_RGB888 \
DRAW_SETPIXEL_MUL(RGB_FROM_RGB888(*pixel, sr, sg, sb), \
RGB888_FROM_RGB(*pixel, sr, sg, sb))
#define DRAW_SETPIXELXY_RGB888(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_RGB888)
@@ -180,6 +209,9 @@ do { \
#define DRAW_SETPIXELXY_MOD_RGB888(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MOD_RGB888)
#define DRAW_SETPIXELXY_MUL_RGB888(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MUL_RGB888)
/*
* Define draw operators for ARGB8888
*/
@@ -199,6 +231,10 @@ do { \
DRAW_SETPIXEL_MOD(RGBA_FROM_ARGB8888(*pixel, sr, sg, sb, sa), \
ARGB8888_FROM_RGBA(*pixel, sr, sg, sb, sa))
#define DRAW_SETPIXEL_MUL_ARGB8888 \
DRAW_SETPIXEL_MUL(RGBA_FROM_ARGB8888(*pixel, sr, sg, sb, sa), \
ARGB8888_FROM_RGBA(*pixel, sr, sg, sb, sa))
#define DRAW_SETPIXELXY_ARGB8888(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ARGB8888)
@@ -211,6 +247,9 @@ do { \
#define DRAW_SETPIXELXY_MOD_ARGB8888(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MOD_ARGB8888)
#define DRAW_SETPIXELXY_MUL_ARGB8888(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MUL_ARGB8888)
/*
* Define draw operators for general RGB
*/
@@ -230,6 +269,10 @@ do { \
DRAW_SETPIXEL_MOD(RGB_FROM_PIXEL(*pixel, fmt, sr, sg, sb), \
PIXEL_FROM_RGB(*pixel, fmt, sr, sg, sb))
#define DRAW_SETPIXEL_MUL_RGB \
DRAW_SETPIXEL_MUL(RGB_FROM_PIXEL(*pixel, fmt, sr, sg, sb), \
PIXEL_FROM_RGB(*pixel, fmt, sr, sg, sb))
#define DRAW_SETPIXELXY2_RGB(x, y) \
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_RGB)
@@ -254,6 +297,12 @@ do { \
#define DRAW_SETPIXELXY4_MOD_RGB(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MOD_RGB)
#define DRAW_SETPIXELXY2_MUL_RGB(x, y) \
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MUL_RGB)
#define DRAW_SETPIXELXY4_MUL_RGB(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MUL_RGB)
/*
* Define draw operators for general RGBA
@@ -274,6 +323,10 @@ do { \
DRAW_SETPIXEL_MOD(RGBA_FROM_PIXEL(*pixel, fmt, sr, sg, sb, sa), \
PIXEL_FROM_RGBA(*pixel, fmt, sr, sg, sb, sa))
#define DRAW_SETPIXEL_MUL_RGBA \
DRAW_SETPIXEL_MUL(RGBA_FROM_PIXEL(*pixel, fmt, sr, sg, sb, sa), \
PIXEL_FROM_RGBA(*pixel, fmt, sr, sg, sb, sa))
#define DRAW_SETPIXELXY4_RGBA(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_RGBA)
@@ -286,6 +339,9 @@ do { \
#define DRAW_SETPIXELXY4_MOD_RGBA(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MOD_RGBA)
#define DRAW_SETPIXELXY4_MUL_RGBA(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MUL_RGBA)
/*
* Define line drawing macro
*/

View File

@@ -399,8 +399,8 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex
blitRequired = SDL_TRUE;
}
/* The color and alpha modulation has to be applied before the rotation when using the NONE and MOD blend modes. */
if ((blendmode == SDL_BLENDMODE_NONE || blendmode == SDL_BLENDMODE_MOD) && (alphaMod & rMod & gMod & bMod) != 255) {
/* The color and alpha modulation has to be applied before the rotation when using the NONE, MOD or MUL blend modes. */
if ((blendmode == SDL_BLENDMODE_NONE || blendmode == SDL_BLENDMODE_MOD || blendmode == SDL_BLENDMODE_MUL) && (alphaMod & rMod & gMod & bMod) != 255) {
applyModulation = SDL_TRUE;
SDL_SetSurfaceAlphaMod(src_clone, alphaMod);
SDL_SetSurfaceColorMod(src_clone, rMod, gMod, bMod);
@@ -573,7 +573,7 @@ PrepTextureForCopy(const SDL_RenderCommand *cmd)
SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
const SDL_bool colormod = ((r & g & b) != 0xFF);
const SDL_bool alphamod = (a != 0xFF);
const SDL_bool blending = ((blend == SDL_BLENDMODE_ADD) || (blend == SDL_BLENDMODE_MOD));
const SDL_bool blending = ((blend == SDL_BLENDMODE_ADD) || (blend == SDL_BLENDMODE_MOD) || (blend == SDL_BLENDMODE_MUL));
if (colormod || alphamod || blending) {
SDL_SetSurfaceRLE(surface, 0);

View File

@@ -474,8 +474,8 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery,
SDL_FillRect(rz_dst, NULL, colorkey);
} else if (blendmode == SDL_BLENDMODE_NONE) {
blendmode = SDL_BLENDMODE_BLEND;
} else if (blendmode == SDL_BLENDMODE_MOD) {
/* Without a colorkey, the target texture has to be white for the MOD blend mode so
} else if (blendmode == SDL_BLENDMODE_MOD || blendmode == SDL_BLENDMODE_MUL) {
/* Without a colorkey, the target texture has to be white for the MOD and MUL blend mode so
* that the pixels outside the rotated area don't affect the destination surface.
*/
colorkey = SDL_MapRGBA(rz_dst->format, 255, 255, 255, 0);