Added ratio argument to colorize, removed the weird alpha-based ratio.

master
TriBlade9 2015-01-19 14:15:20 +08:00 committed by Craig Robbins
parent 60d745126f
commit db481e7232
2 changed files with 137 additions and 98 deletions

View File

@ -337,9 +337,11 @@ Apply a mask to the base image.
The mask is applied using binary AND. The mask is applied using binary AND.
#### `[colorize:<color>` #### `[colorize:<color>:<ratio>`
Colorize the textures with the given color. Colorize the textures with the given color.
`<color>` is specified as a `ColorString`. `<color>` is specified as a `ColorString`.
`<ratio>` is an int ranging from 0 to 255, and specifies how much of the
color to apply. If ommitted, the alpha will be used.
Sounds Sounds
------ ------
@ -3259,4 +3261,3 @@ Definition tables
playername = "singleplayer" playername = "singleplayer"
-- ^ Playername is optional, if specified spawns particle only on the player's client -- ^ Playername is optional, if specified spawns particle only on the player's client
} }

View File

@ -540,6 +540,11 @@ static void blit_with_alpha(video::IImage *src, video::IImage *dst,
static void blit_with_alpha_overlay(video::IImage *src, video::IImage *dst, static void blit_with_alpha_overlay(video::IImage *src, video::IImage *dst,
v2s32 src_pos, v2s32 dst_pos, v2u32 size); v2s32 src_pos, v2s32 dst_pos, v2u32 size);
// Like blit_with_alpha overlay, but uses an int to calculate the ratio
// and modifies any destination pixels that are not fully transparent
static void blit_with_interpolate_overlay(video::IImage *src, video::IImage *dst,
v2s32 src_pos, v2s32 dst_pos, v2u32 size, int ratio);
// Apply a mask to an image // Apply a mask to an image
static void apply_mask(video::IImage *mask, video::IImage *dst, static void apply_mask(video::IImage *mask, video::IImage *dst,
v2s32 mask_pos, v2s32 dst_pos, v2u32 size); v2s32 mask_pos, v2s32 dst_pos, v2u32 size);
@ -1598,6 +1603,7 @@ bool TextureSource::generateImagePart(std::string part_of_name,
Strfnd sf(part_of_name); Strfnd sf(part_of_name);
sf.next(":"); sf.next(":");
std::string color_str = sf.next(":"); std::string color_str = sf.next(":");
std::string ratio_str = sf.next(":");
if (baseimg == NULL) { if (baseimg == NULL) {
errorstream << "generateImagePart(): baseimg != NULL " errorstream << "generateImagePart(): baseimg != NULL "
@ -1607,9 +1613,14 @@ bool TextureSource::generateImagePart(std::string part_of_name,
} }
video::SColor color; video::SColor color;
int ratio = -1;
if (!parseColorString(color_str, color, false)) if (!parseColorString(color_str, color, false))
return false; return false;
if (is_number(ratio_str))
ratio = mystoi(ratio_str, 0, 255);
core::dimension2d<u32> dim = baseimg->getDimension(); core::dimension2d<u32> dim = baseimg->getDimension();
video::IImage *img = driver->createImage(video::ECF_A8R8G8B8, dim); video::IImage *img = driver->createImage(video::ECF_A8R8G8B8, dim);
@ -1622,7 +1633,7 @@ bool TextureSource::generateImagePart(std::string part_of_name,
img->fill(video::SColor(color)); img->fill(video::SColor(color));
// Overlay the colored image // Overlay the colored image
blit_with_alpha_overlay(img, baseimg, v2s32(0,0), v2s32(0,0), dim); blit_with_interpolate_overlay(img, baseimg, v2s32(0,0), v2s32(0,0), dim, ratio);
img->drop(); img->drop();
} }
else else
@ -1683,6 +1694,33 @@ static void blit_with_alpha_overlay(video::IImage *src, video::IImage *dst,
} }
} }
/*
Draw an image on top of an another one, using the specified ratio
modify all partially-opaque pixels in the destination.
*/
static void blit_with_interpolate_overlay(video::IImage *src, video::IImage *dst,
v2s32 src_pos, v2s32 dst_pos, v2u32 size, int ratio)
{
for (u32 y0 = 0; y0 < size.Y; y0++)
for (u32 x0 = 0; x0 < size.X; x0++)
{
s32 src_x = src_pos.X + x0;
s32 src_y = src_pos.Y + y0;
s32 dst_x = dst_pos.X + x0;
s32 dst_y = dst_pos.Y + y0;
video::SColor src_c = src->getPixel(src_x, src_y);
video::SColor dst_c = dst->getPixel(dst_x, dst_y);
if (dst_c.getAlpha() > 0 && src_c.getAlpha() != 0)
{
if (ratio == -1)
dst_c = src_c.getInterpolated(dst_c, (float)src_c.getAlpha()/255.0f);
else
dst_c = src_c.getInterpolated(dst_c, (float)ratio/255.0f);
dst->setPixel(dst_x, dst_y, dst_c);
}
}
}
/* /*
Apply mask to destination Apply mask to destination
*/ */