diff --git a/doc/lua_api.txt b/doc/lua_api.txt index d25cd741c..74487edee 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -258,6 +258,10 @@ Advanced texture modifiers: Crops the texture to a frame of a vertical animation. Example: default_torch_animated.png^[verticalframe:16:8 + [mask: + Apply a mask to the base image. + The mask is applied using binary AND. + Sounds ------- Only OGG Vorbis files are supported. diff --git a/src/tile.cpp b/src/tile.cpp index d16d135f5..06d89393c 100644 --- a/src/tile.cpp +++ b/src/tile.cpp @@ -537,6 +537,10 @@ static void blit_with_alpha(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); +// Apply a mask to an image +static void apply_mask(video::IImage *mask, video::IImage *dst, + v2s32 mask_pos, v2s32 dst_pos, v2u32 size); + // Draw or overlay a crack static void draw_crack(video::IImage *crack, video::IImage *dst, bool use_overlay, s32 frame_count, s32 progression, @@ -1557,6 +1561,31 @@ bool TextureSource::generateImagePart(std::string part_of_name, baseimg->drop(); baseimg = img; } + /* + [mask:filename + Applies a mask to an image + */ + else if(part_of_name.substr(0,6) == "[mask:") + { + if (baseimg == NULL) { + errorstream << "generateImage(): baseimg == NULL " + << "for part_of_name=\"" << part_of_name + << "\", cancelling." << std::endl; + return false; + } + Strfnd sf(part_of_name); + sf.next(":"); + std::string filename = sf.next(":"); + + video::IImage *img = m_sourcecache.getOrLoad(filename, m_device); + if (img) { + apply_mask(img, baseimg, v2s32(0, 0), v2s32(0, 0), + img->getDimension()); + } else { + errorstream << "generateImage(): Failed to load \"" + << filename << "\"."; + } + } else { errorstream<<"generateImagePart(): Invalid " @@ -1615,6 +1644,26 @@ static void blit_with_alpha_overlay(video::IImage *src, video::IImage *dst, } } +/* + Apply mask to destination +*/ +static void apply_mask(video::IImage *mask, video::IImage *dst, + v2s32 mask_pos, v2s32 dst_pos, v2u32 size) +{ + for(u32 y0 = 0; y0 < size.Y; y0++) { + for(u32 x0 = 0; x0 < size.X; x0++) { + s32 mask_x = x0 + mask_pos.X; + s32 mask_y = y0 + mask_pos.Y; + s32 dst_x = x0 + dst_pos.X; + s32 dst_y = y0 + dst_pos.Y; + video::SColor mask_c = mask->getPixel(mask_x, mask_y); + video::SColor dst_c = dst->getPixel(dst_x, dst_y); + dst_c.color &= mask_c.color; + dst->setPixel(dst_x, dst_y, dst_c); + } + } +} + static void draw_crack(video::IImage *crack, video::IImage *dst, bool use_overlay, s32 frame_count, s32 progression, video::IVideoDriver *driver)