mirror of
https://github.com/luanti-org/luanti.git
synced 2025-11-06 10:15:19 +01:00
Merge branch 'master' into doc-refactor-2
This commit is contained in:
@@ -497,8 +497,8 @@ Example:
|
|||||||
|
|
||||||
* `<w>`: width
|
* `<w>`: width
|
||||||
* `<h>`: height
|
* `<h>`: height
|
||||||
* `<x>`: x position
|
* `<x>`: x position, negative numbers allowed
|
||||||
* `<y>`: y position
|
* `<y>`: y position, negative numbers allowed
|
||||||
* `<file>`: texture to combine
|
* `<file>`: texture to combine
|
||||||
|
|
||||||
Creates a texture of size `<w>` times `<h>` and blits the listed files to their
|
Creates a texture of size `<w>` times `<h>` and blits the listed files to their
|
||||||
@@ -606,13 +606,13 @@ Creates an inventorycube with `grass.png`, `dirt.png^grass_side.png` and
|
|||||||
* `<y>`: y position
|
* `<y>`: y position
|
||||||
* `<color>`: a `ColorString`.
|
* `<color>`: a `ColorString`.
|
||||||
|
|
||||||
Creates a texture of the given size and color, optionally with an <x>,<y>
|
Creates a texture of the given size and color, optionally with an `<x>,<y>`
|
||||||
position. An alpha value may be specified in the `Colorstring`.
|
position. An alpha value may be specified in the `Colorstring`.
|
||||||
|
|
||||||
The optional <x>,<y> position is only used if the [fill is being overlaid
|
The optional `<x>,<y>` position is only used if the `[fill` is being overlaid
|
||||||
onto another texture with '^'.
|
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
|
the resolution of the texture, the base texture will determine the output
|
||||||
resolution.
|
resolution.
|
||||||
|
|
||||||
@@ -8296,6 +8296,7 @@ Player properties need to be saved manually.
|
|||||||
pointable = true,
|
pointable = true,
|
||||||
-- Can be `true` if it is pointable, `false` if it can be pointed through,
|
-- Can be `true` if it is pointable, `false` if it can be pointed through,
|
||||||
-- or `"blocking"` if it is pointable but not selectable.
|
-- 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.
|
-- Can be overridden by the `pointabilities` of the held item.
|
||||||
|
|
||||||
visual = "cube" / "sprite" / "upright_sprite" / "mesh" / "wielditem" / "item",
|
visual = "cube" / "sprite" / "upright_sprite" / "mesh" / "wielditem" / "item",
|
||||||
@@ -8902,6 +8903,7 @@ Used by `minetest.register_node`.
|
|||||||
pointable = true,
|
pointable = true,
|
||||||
-- Can be `true` if it is pointable, `false` if it can be pointed through,
|
-- Can be `true` if it is pointable, `false` if it can be pointed through,
|
||||||
-- or `"blocking"` if it is pointable but not selectable.
|
-- 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.
|
-- 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.
|
-- A client may be able to point non-pointable nodes, since it isn't checked server-side.
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "guiscalingfilter.h"
|
#include "guiscalingfilter.h"
|
||||||
#include "renderingengine.h"
|
#include "renderingengine.h"
|
||||||
#include "util/base64.h"
|
#include "util/base64.h"
|
||||||
|
#include "irrlicht_changes/printing.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
A cache from texture name to texture path
|
A cache from texture name to texture path
|
||||||
@@ -538,14 +539,11 @@ u32 TextureSource::getTextureId(const std::string &name)
|
|||||||
|
|
||||||
// Draw an image on top of another one, using the alpha channel of the
|
// Draw an image on top of another one, using the alpha channel of the
|
||||||
// source image
|
// source image
|
||||||
|
// overlay: only modify destination pixels that are fully opaque.
|
||||||
|
template<bool overlay = false>
|
||||||
static void blit_with_alpha(video::IImage *src, video::IImage *dst,
|
static void blit_with_alpha(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, 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.
|
// 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
|
// If the ratio is 255 or -1 and keep_alpha is true, then it multiples the
|
||||||
// color alpha with the destination alpha.
|
// color alpha with the destination alpha.
|
||||||
@@ -1323,37 +1321,45 @@ bool TextureSource::generateImagePart(std::string part_of_name,
|
|||||||
sf.next(":");
|
sf.next(":");
|
||||||
u32 w0 = stoi(sf.next("x"));
|
u32 w0 = stoi(sf.next("x"));
|
||||||
u32 h0 = stoi(sf.next(":"));
|
u32 h0 = stoi(sf.next(":"));
|
||||||
CHECK_DIM(w0, h0);
|
if (!baseimg) {
|
||||||
core::dimension2d<u32> dim(w0,h0);
|
CHECK_DIM(w0, h0);
|
||||||
if (baseimg == NULL) {
|
baseimg = driver->createImage(video::ECF_A8R8G8B8, {w0, h0});
|
||||||
baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
|
|
||||||
baseimg->fill(video::SColor(0,0,0,0));
|
baseimg->fill(video::SColor(0,0,0,0));
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!sf.at_end()) {
|
while (!sf.at_end()) {
|
||||||
u32 x = stoi(sf.next(","));
|
v2s32 pos_base;
|
||||||
u32 y = stoi(sf.next("="));
|
pos_base.X = stoi(sf.next(","));
|
||||||
|
pos_base.Y = stoi(sf.next("="));
|
||||||
std::string filename = unescape_string(sf.next_esc(":", escape), escape);
|
std::string filename = unescape_string(sf.next_esc(":", escape), escape);
|
||||||
|
|
||||||
if (x >= w0 || y >= h0)
|
auto basedim = baseimg->getDimension();
|
||||||
COMPLAIN_INVALID("X or Y offset");
|
if (pos_base.X > (s32)basedim.Width || pos_base.Y > (s32)basedim.Height) {
|
||||||
infostream<<"Adding \""<<filename
|
warningstream << "generateImagePart(): Skipping \""
|
||||||
<<"\" to combined ("<<x<<","<<y<<")"
|
<< filename << "\" as it's out-of-bounds " << pos_base
|
||||||
<<std::endl;
|
<< " for [combine" << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
infostream << "Adding \"" << filename<< "\" to combined "
|
||||||
|
<< pos_base << std::endl;
|
||||||
|
|
||||||
video::IImage *img = generateImage(filename, source_image_names);
|
video::IImage *img = generateImage(filename, source_image_names);
|
||||||
if (img) {
|
if (!img) {
|
||||||
core::dimension2d<u32> dim = img->getDimension();
|
|
||||||
core::position2d<s32> 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 {
|
|
||||||
errorstream << "generateImagePart(): Failed to load image \""
|
errorstream << "generateImagePart(): Failed to load image \""
|
||||||
<< filename << "\" for [combine" << std::endl;
|
<< 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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -2033,32 +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
|
This exists because IImage::copyToWithAlpha() doesn't seem to always
|
||||||
work.
|
work.
|
||||||
*/
|
*/
|
||||||
|
template<bool overlay>
|
||||||
static void blit_with_alpha(video::IImage *src, video::IImage *dst,
|
static void blit_with_alpha(video::IImage *src, video::IImage *dst,
|
||||||
v2s32 src_pos, v2s32 dst_pos, v2u32 size)
|
v2s32 src_pos, v2s32 dst_pos, v2u32 size)
|
||||||
{
|
{
|
||||||
for (u32 y0=0; y0<size.Y; y0++)
|
auto src_dim = src->getDimension();
|
||||||
for (u32 x0=0; x0<size.X; x0++)
|
auto dst_dim = dst->getDimension();
|
||||||
{
|
|
||||||
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);
|
|
||||||
dst_c = blitPixel(src_c, dst_c, src_c.getAlpha());
|
|
||||||
dst->setPixel(dst_x, dst_y, dst_c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
// Limit y and x to the overlapping ranges
|
||||||
Draw an image on top of another one, using the alpha channel of the
|
// s.t. the positions are all in bounds after offsetting.
|
||||||
source image; only modify fully opaque pixels in destinaion
|
for (u32 y0 = std::max(0, -dst_pos.Y);
|
||||||
*/
|
y0 < std::min<s64>({size.Y, src_dim.Height, dst_dim.Height - (s64) dst_pos.Y});
|
||||||
static void blit_with_alpha_overlay(video::IImage *src, video::IImage *dst,
|
++y0)
|
||||||
v2s32 src_pos, v2s32 dst_pos, v2u32 size)
|
for (u32 x0 = std::max(0, -dst_pos.X);
|
||||||
{
|
x0 < std::min<s64>({size.X, src_dim.Width, dst_dim.Width - (s64) dst_pos.X});
|
||||||
for (u32 y0=0; y0<size.Y; y0++)
|
++x0)
|
||||||
for (u32 x0=0; x0<size.X; x0++)
|
|
||||||
{
|
{
|
||||||
s32 src_x = src_pos.X + x0;
|
s32 src_x = src_pos.X + x0;
|
||||||
s32 src_y = src_pos.Y + y0;
|
s32 src_y = src_pos.Y + y0;
|
||||||
@@ -2066,45 +2061,13 @@ static void blit_with_alpha_overlay(video::IImage *src, video::IImage *dst,
|
|||||||
s32 dst_y = dst_pos.Y + y0;
|
s32 dst_y = dst_pos.Y + y0;
|
||||||
video::SColor src_c = src->getPixel(src_x, src_y);
|
video::SColor src_c = src->getPixel(src_x, src_y);
|
||||||
video::SColor dst_c = dst->getPixel(dst_x, dst_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_c = blitPixel(src_c, dst_c, src_c.getAlpha());
|
||||||
dst->setPixel(dst_x, dst_y, dst_c);
|
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
|
Apply color to destination, using a weighted interpolation blend
|
||||||
*/
|
*/
|
||||||
@@ -2443,7 +2406,7 @@ static void draw_crack(video::IImage *crack, video::IImage *dst,
|
|||||||
if (!crack_scaled)
|
if (!crack_scaled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto blit = use_overlay ? blit_with_alpha_overlay : blit_with_alpha;
|
auto blit = use_overlay ? blit_with_alpha<true> : blit_with_alpha<false>;
|
||||||
for (s32 i = 0; i < frame_count; ++i) {
|
for (s32 i = 0; i < frame_count; ++i) {
|
||||||
v2s32 dst_pos(0, frame_size.Height * i);
|
v2s32 dst_pos(0, frame_size.Height * i);
|
||||||
blit(crack_scaled, dst, v2s32(0,0), dst_pos, frame_size);
|
blit(crack_scaled, dst, v2s32(0,0), dst_pos, frame_size);
|
||||||
|
|||||||
Reference in New Issue
Block a user