diff --git a/doc/lua_api.txt b/doc/lua_api.txt index aa4f129f0..41e7c00eb 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -318,6 +318,15 @@ Example: default_sandstone.png^[opacity:127 +#### `[invert:` +Inverts the given channels of the base image. +Mode may contain the characters "r", "g", "b", "a". +Only the channels that are mentioned in the mode string will be inverted. + +Example: + + default_apple.png^[invert:rgb + #### `[brighten` Brightens the texture. diff --git a/src/client/tile.cpp b/src/client/tile.cpp index 67d5d8d1a..8f0c39465 100644 --- a/src/client/tile.cpp +++ b/src/client/tile.cpp @@ -1783,9 +1783,48 @@ bool TextureSource::generateImagePart(std::string part_of_name, for (u32 y = 0; y < dim.Height; y++) for (u32 x = 0; x < dim.Width; x++) { - video::SColor c = baseimg->getPixel(x,y); + video::SColor c = baseimg->getPixel(x, y); c.setAlpha(floor((c.getAlpha() * ratio) / 255 + 0.5)); - baseimg->setPixel(x,y,c); + baseimg->setPixel(x, y, c); + } + } + /* + [invert:mode + Inverts the given channels of the base image. + Mode may contain the characters "r", "g", "b", "a". + Only the channels that are mentioned in the mode string + will be inverted. + */ + else if (str_starts_with(part_of_name, "[invert:")) { + if (baseimg == NULL) { + errorstream << "generateImagePart(): baseimg == NULL " + << "for part_of_name=\"" << part_of_name + << "\", cancelling." << std::endl; + return false; + } + + Strfnd sf(part_of_name); + sf.next(":"); + + std::string mode = sf.next(""); + u32 mask = 0; + if (mode.find("a") != std::string::npos) + mask |= 0xff000000UL; + if (mode.find("r") != std::string::npos) + mask |= 0x00ff0000UL; + if (mode.find("g") != std::string::npos) + mask |= 0x0000ff00UL; + if (mode.find("b") != std::string::npos) + mask |= 0x000000ffUL; + + core::dimension2d dim = baseimg->getDimension(); + + for (u32 y = 0; y < dim.Height; y++) + for (u32 x = 0; x < dim.Width; x++) + { + video::SColor c = baseimg->getPixel(x, y); + c.color ^= mask; + baseimg->setPixel(x, y, c); } } else