From b1ee1371774fa6e412d1f2d144c22ab3406c67d8 Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Wed, 24 Jan 2024 15:24:25 +0100 Subject: [PATCH 1/3] Minor documentation fixes --- doc/lua_api.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/doc/lua_api.md b/doc/lua_api.md index d5a25ed9ff..a38b5be0d0 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -506,8 +506,8 @@ Example: * ``: width * ``: height -* ``: x position -* ``: y position +* ``: x position, negative numbers allowed +* ``: y position, negative numbers allowed * ``: texture to combine Creates a texture of size `` times `` and blits the listed files to their @@ -613,13 +613,13 @@ Creates an inventorycube with `grass.png`, `dirt.png^grass_side.png` and * ``: y position * ``: a `ColorString`. -Creates a texture of the given size and color, optionally with an , +Creates a texture of the given size and color, optionally with an `,` position. An alpha value may be specified in the `Colorstring`. -The optional , position is only used if the [fill is being overlaid +The optional `,` position is only used if the `[fill` is being overlaid onto another texture with '^'. -When [fill is overlaid onto another texture it will not upscale or change +When `[fill` is overlaid onto another texture it will not upscale or change the resolution of the texture, the base texture will determine the output resolution. @@ -8402,6 +8402,7 @@ Player properties need to be saved manually. pointable = true, -- Can be `true` if it is pointable, `false` if it can be pointed through, -- or `"blocking"` if it is pointable but not selectable. + -- Clients older than 5.9.0 interpret `pointable = "blocking"` as `pointable = true`. -- Can be overridden by the `pointabilities` of the held item. visual = "cube" / "sprite" / "upright_sprite" / "mesh" / "wielditem" / "item", @@ -9015,6 +9016,7 @@ Used by `minetest.register_node`. pointable = true, -- Can be `true` if it is pointable, `false` if it can be pointed through, -- or `"blocking"` if it is pointable but not selectable. + -- Clients older than 5.9.0 interpret `pointable = "blocking"` as `pointable = true`. -- Can be overridden by the `pointabilities` of the held item. -- A client may be able to point non-pointable nodes, since it isn't checked server-side. From ffec698d3ea707f521fc6ac66a2c786d3851ae60 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Sat, 27 Jan 2024 20:26:43 +0100 Subject: [PATCH 2/3] Change how [combine parameters are checked the old checks were too strict --- src/client/tile.cpp | 54 +++++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/src/client/tile.cpp b/src/client/tile.cpp index cc6b3273c7..757c504941 100644 --- a/src/client/tile.cpp +++ b/src/client/tile.cpp @@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "guiscalingfilter.h" #include "renderingengine.h" #include "util/base64.h" +#include "irrlicht_changes/printing.h" /* A cache from texture name to texture path @@ -1323,37 +1324,45 @@ bool TextureSource::generateImagePart(std::string part_of_name, sf.next(":"); u32 w0 = stoi(sf.next("x")); u32 h0 = stoi(sf.next(":")); - CHECK_DIM(w0, h0); - core::dimension2d dim(w0,h0); - if (baseimg == NULL) { - baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); + if (!baseimg) { + CHECK_DIM(w0, h0); + baseimg = driver->createImage(video::ECF_A8R8G8B8, {w0, h0}); baseimg->fill(video::SColor(0,0,0,0)); } + while (!sf.at_end()) { - u32 x = stoi(sf.next(",")); - u32 y = stoi(sf.next("=")); + v2s32 pos_base; + pos_base.X = stoi(sf.next(",")); + pos_base.Y = stoi(sf.next("=")); std::string filename = unescape_string(sf.next_esc(":", escape), escape); - if (x >= w0 || y >= h0) - COMPLAIN_INVALID("X or Y offset"); - infostream<<"Adding \""<getDimension(); + if (pos_base.X > (s32)basedim.Width || pos_base.Y > (s32)basedim.Height) { + warningstream << "generateImagePart(): Skipping \"" + << filename << "\" as it's out-of-bounds " << pos_base + << " for [combine" << std::endl; + continue; + } + infostream << "Adding \"" << filename<< "\" to combined " + << pos_base << std::endl; video::IImage *img = generateImage(filename, source_image_names); - if (img) { - core::dimension2d dim = img->getDimension(); - core::position2d pos_base(x, y); - video::IImage *img2 = - driver->createImage(video::ECF_A8R8G8B8, dim); - img->copyTo(img2); - img->drop(); - blit_with_alpha(img2, baseimg, v2s32(0,0), pos_base, dim); - img2->drop(); - } else { + if (!img) { errorstream << "generateImagePart(): Failed to load image \"" << filename << "\" for [combine" << std::endl; + continue; } + const auto dim = img->getDimension(); + if (pos_base.X + dim.Width <= 0 || pos_base.Y + dim.Height <= 0) { + warningstream << "generateImagePart(): Skipping \"" + << filename << "\" as it's out-of-bounds " << pos_base + << " for [combine" << std::endl; + img->drop(); + continue; + } + + blit_with_alpha(img, baseimg, v2s32(0,0), pos_base, dim); + img->drop(); } } /* @@ -2036,6 +2045,8 @@ static inline video::SColor blitPixel(const video::SColor src_c, const video::SC static void blit_with_alpha(video::IImage *src, video::IImage *dst, v2s32 src_pos, v2s32 dst_pos, v2u32 size) { + // FIXME: loop should be restricted to actual overlap + // (if dst smaller than size or dst_pos negative) for (u32 y0=0; y0 Date: Sat, 27 Jan 2024 22:59:27 +0100 Subject: [PATCH 3/3] Performance: Limit blitting work to overlapping area --- src/client/tile.cpp | 79 +++++++++------------------------------------ 1 file changed, 15 insertions(+), 64 deletions(-) diff --git a/src/client/tile.cpp b/src/client/tile.cpp index 757c504941..c708211510 100644 --- a/src/client/tile.cpp +++ b/src/client/tile.cpp @@ -539,14 +539,11 @@ u32 TextureSource::getTextureId(const std::string &name) // Draw an image on top of another one, using the alpha channel of the // source image +// overlay: only modify destination pixels that are fully opaque. +template static void blit_with_alpha(video::IImage *src, video::IImage *dst, v2s32 src_pos, v2s32 dst_pos, v2u32 size); -// Like blit_with_alpha, but only modifies destination pixels that -// are fully opaque -static void blit_with_alpha_overlay(video::IImage *src, video::IImage *dst, - v2s32 src_pos, v2s32 dst_pos, v2u32 size); - // Apply a color to an image. Uses an int (0-255) to calculate the ratio. // If the ratio is 255 or -1 and keep_alpha is true, then it multiples the // color alpha with the destination alpha. @@ -2042,35 +2039,21 @@ static inline video::SColor blitPixel(const video::SColor src_c, const video::SC This exists because IImage::copyToWithAlpha() doesn't seem to always work. */ +template static void blit_with_alpha(video::IImage *src, video::IImage *dst, v2s32 src_pos, v2s32 dst_pos, v2u32 size) { - // FIXME: loop should be restricted to actual overlap - // (if dst smaller than size or dst_pos negative) - for (u32 y0=0; y0getPixel(src_x, src_y); - video::SColor dst_c = dst->getPixel(dst_x, dst_y); - dst_c = blitPixel(src_c, dst_c, src_c.getAlpha()); - dst->setPixel(dst_x, dst_y, dst_c); - } -} + auto src_dim = src->getDimension(); + auto dst_dim = dst->getDimension(); -/* - Draw an image on top of another one, using the alpha channel of the - source image; only modify fully opaque pixels in destinaion -*/ -static void blit_with_alpha_overlay(video::IImage *src, video::IImage *dst, - v2s32 src_pos, v2s32 dst_pos, v2u32 size) -{ - // FIXME: same as above here - for (u32 y0=0; y0({size.Y, src_dim.Height, dst_dim.Height - (s64) dst_pos.Y}); + ++y0) + for (u32 x0 = std::max(0, -dst_pos.X); + x0 < std::min({size.X, src_dim.Width, dst_dim.Width - (s64) dst_pos.X}); + ++x0) { s32 src_x = src_pos.X + x0; s32 src_y = src_pos.Y + y0; @@ -2078,45 +2061,13 @@ static void blit_with_alpha_overlay(video::IImage *src, video::IImage *dst, 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() == 255 && src_c.getAlpha() != 0) - { + if (!overlay || (dst_c.getAlpha() == 255 && src_c.getAlpha() != 0)) { dst_c = blitPixel(src_c, dst_c, src_c.getAlpha()); dst->setPixel(dst_x, dst_y, dst_c); } } } -// This function has been disabled because it is currently unused. -// Feel free to re-enable if you find it handy. -#if 0 -/* - Draw an image on top of 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); - } - } -} -#endif - /* Apply color to destination, using a weighted interpolation blend */ @@ -2455,7 +2406,7 @@ static void draw_crack(video::IImage *crack, video::IImage *dst, if (!crack_scaled) return; - auto blit = use_overlay ? blit_with_alpha_overlay : blit_with_alpha; + auto blit = use_overlay ? blit_with_alpha : blit_with_alpha; for (s32 i = 0; i < frame_count; ++i) { v2s32 dst_pos(0, frame_size.Height * i); blit(crack_scaled, dst, v2s32(0,0), dst_pos, frame_size);