mirror of
https://github.com/encounter/SDL.git
synced 2025-12-17 08:57:01 +00:00
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:
@@ -1430,7 +1430,7 @@ SDL_RLESurface(SDL_Surface * surface)
|
||||
/* Pass on combinations not supported */
|
||||
if ((flags & SDL_COPY_MODULATE_COLOR) ||
|
||||
((flags & SDL_COPY_MODULATE_ALPHA) && surface->format->Amask) ||
|
||||
(flags & (SDL_COPY_ADD | SDL_COPY_MOD)) ||
|
||||
(flags & (SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_MUL)) ||
|
||||
(flags & SDL_COPY_NEAREST)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ SDL_ChooseBlitFunc(Uint32 src_format, Uint32 dst_format, int flags,
|
||||
/* Check blend flags */
|
||||
flagcheck =
|
||||
(flags &
|
||||
(SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD));
|
||||
(SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_MUL));
|
||||
if ((flagcheck & entries[i].flags) != flagcheck) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ extern Uint8* SDL_expand_byte[9];
|
||||
#define SDL_COPY_BLEND 0x00000010
|
||||
#define SDL_COPY_ADD 0x00000020
|
||||
#define SDL_COPY_MOD 0x00000040
|
||||
#define SDL_COPY_MUL 0x00000080
|
||||
#define SDL_COPY_COLORKEY 0x00000100
|
||||
#define SDL_COPY_NEAREST 0x00000200
|
||||
#define SDL_COPY_RLE_DESIRED 0x00001000
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -118,7 +118,7 @@ SDL_Blit_Slow(SDL_BlitInfo * info)
|
||||
srcB = (srcB * srcA) / 255;
|
||||
}
|
||||
}
|
||||
switch (flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD)) {
|
||||
switch (flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_MUL)) {
|
||||
case 0:
|
||||
dstR = srcR;
|
||||
dstG = srcG;
|
||||
@@ -147,6 +147,20 @@ SDL_Blit_Slow(SDL_BlitInfo * info)
|
||||
dstG = (srcG * dstG) / 255;
|
||||
dstB = (srcB * dstB) / 255;
|
||||
break;
|
||||
case SDL_COPY_MUL:
|
||||
dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255;
|
||||
if (dstR > 255)
|
||||
dstR = 255;
|
||||
dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255;
|
||||
if (dstG > 255)
|
||||
dstG = 255;
|
||||
dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255;
|
||||
if (dstB > 255)
|
||||
dstB = 255;
|
||||
dstA = ((srcA * dstA) + (dstA * (255 - srcA))) / 255;
|
||||
if (dstA > 255)
|
||||
dstA = 255;
|
||||
break;
|
||||
}
|
||||
if (dst_fmt->Amask) {
|
||||
ASSEMBLE_RGBA(dst, dstbpp, dst_fmt, dstR, dstG, dstB, dstA);
|
||||
|
||||
@@ -495,7 +495,7 @@ SDL_SetSurfaceBlendMode(SDL_Surface * surface, SDL_BlendMode blendMode)
|
||||
status = 0;
|
||||
flags = surface->map->info.flags;
|
||||
surface->map->info.flags &=
|
||||
~(SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD);
|
||||
~(SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_MUL);
|
||||
switch (blendMode) {
|
||||
case SDL_BLENDMODE_NONE:
|
||||
break;
|
||||
@@ -508,6 +508,9 @@ SDL_SetSurfaceBlendMode(SDL_Surface * surface, SDL_BlendMode blendMode)
|
||||
case SDL_BLENDMODE_MOD:
|
||||
surface->map->info.flags |= SDL_COPY_MOD;
|
||||
break;
|
||||
case SDL_BLENDMODE_MUL:
|
||||
surface->map->info.flags |= SDL_COPY_MUL;
|
||||
break;
|
||||
default:
|
||||
status = SDL_Unsupported();
|
||||
break;
|
||||
@@ -532,7 +535,7 @@ SDL_GetSurfaceBlendMode(SDL_Surface * surface, SDL_BlendMode *blendMode)
|
||||
}
|
||||
|
||||
switch (surface->map->
|
||||
info.flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD)) {
|
||||
info.flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_MUL)) {
|
||||
case SDL_COPY_BLEND:
|
||||
*blendMode = SDL_BLENDMODE_BLEND;
|
||||
break;
|
||||
@@ -542,6 +545,9 @@ SDL_GetSurfaceBlendMode(SDL_Surface * surface, SDL_BlendMode *blendMode)
|
||||
case SDL_COPY_MOD:
|
||||
*blendMode = SDL_BLENDMODE_MOD;
|
||||
break;
|
||||
case SDL_COPY_MUL:
|
||||
*blendMode = SDL_BLENDMODE_MUL;
|
||||
break;
|
||||
default:
|
||||
*blendMode = SDL_BLENDMODE_NONE;
|
||||
break;
|
||||
@@ -874,7 +880,7 @@ SDL_LowerBlitScaled(SDL_Surface * src, SDL_Rect * srcrect,
|
||||
{
|
||||
static const Uint32 complex_copy_flags = (
|
||||
SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA |
|
||||
SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD |
|
||||
SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_MUL |
|
||||
SDL_COPY_COLORKEY
|
||||
);
|
||||
|
||||
|
||||
@@ -199,6 +199,14 @@ SetBlendMode(DirectFB_RenderData * data, int blendMode,
|
||||
|
||||
break;
|
||||
}
|
||||
case SDL_BLENDMODE_MUL:
|
||||
data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
|
||||
data->drawFlags = DSDRAW_BLEND;
|
||||
SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_DSTCOLOR));
|
||||
SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_INVSRCALPHA));
|
||||
|
||||
break;
|
||||
}
|
||||
data->lastBlendMode = blendMode;
|
||||
}
|
||||
}
|
||||
@@ -223,6 +231,7 @@ PrepareDraw(SDL_Renderer * renderer, const SDL_RenderCommand *cmd)
|
||||
break;
|
||||
case SDL_BLENDMODE_ADD:
|
||||
case SDL_BLENDMODE_MOD:
|
||||
case SDL_BLENDMODE_MUL:
|
||||
r = ((int) r * (int) a) / 255;
|
||||
g = ((int) g * (int) a) / 255;
|
||||
b = ((int) b * (int) a) / 255;
|
||||
|
||||
@@ -267,7 +267,7 @@ __EOF__
|
||||
__EOF__
|
||||
}
|
||||
print FILE <<__EOF__;
|
||||
switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
|
||||
switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD|SDL_COPY_MUL)) {
|
||||
case SDL_COPY_BLEND:
|
||||
__EOF__
|
||||
if ($A_is_const_FF) {
|
||||
@@ -307,6 +307,35 @@ __EOF__
|
||||
${d}G = (${s}G * ${d}G) / 255;
|
||||
${d}B = (${s}B * ${d}B) / 255;
|
||||
break;
|
||||
case SDL_COPY_MUL:
|
||||
__EOF__
|
||||
if ($A_is_const_FF) {
|
||||
print FILE <<__EOF__;
|
||||
${d}R = (${s}R * ${d}R) / 255;
|
||||
${d}G = (${s}G * ${d}G) / 255;
|
||||
${d}B = (${s}B * ${d}B) / 255;
|
||||
__EOF__
|
||||
} else {
|
||||
print FILE <<__EOF__;
|
||||
${d}R = ((${s}R * ${d}R) + (${d}R * (255 - ${s}A))) / 255; if (${d}R > 255) ${d}R = 255;
|
||||
${d}G = ((${s}G * ${d}G) + (${d}G * (255 - ${s}A))) / 255; if (${d}G > 255) ${d}G = 255;
|
||||
${d}B = ((${s}B * ${d}B) + (${d}B * (255 - ${s}A))) / 255; if (${d}B > 255) ${d}B = 255;
|
||||
__EOF__
|
||||
}
|
||||
if ( $dst_has_alpha ) {
|
||||
if ($A_is_const_FF) {
|
||||
print FILE <<__EOF__;
|
||||
${d}A = 0xFF;
|
||||
__EOF__
|
||||
} else {
|
||||
print FILE <<__EOF__;
|
||||
${d}A = ((${s}A * ${d}A) + (${d}A * (255 - ${s}A))) / 255; if (${d}A > 255) ${d}A = 255;
|
||||
__EOF__
|
||||
}
|
||||
}
|
||||
|
||||
print FILE <<__EOF__;
|
||||
break;
|
||||
}
|
||||
__EOF__
|
||||
}
|
||||
@@ -524,7 +553,7 @@ __EOF__
|
||||
}
|
||||
}
|
||||
if ( $blend ) {
|
||||
$flag = "SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD";
|
||||
$flag = "SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_MUL";
|
||||
if ( $flags eq "" ) {
|
||||
$flags = $flag;
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user