summaryrefslogtreecommitdiff
path: root/src/nodedef.cpp
diff options
context:
space:
mode:
authorsfan5 <sfan5@live.de>2021-01-17 01:56:50 +0100
committersfan5 <sfan5@live.de>2021-01-29 17:34:41 +0100
commit83229921e5f378625d9ef63ede3dffbe778e1798 (patch)
tree8189436795cad017e2eb858b5d2cc23c16a55f46 /src/nodedef.cpp
parentedd8c3c664ad005eb32e1968ce80091851ffb817 (diff)
downloadminetest-83229921e5f378625d9ef63ede3dffbe778e1798.tar.gz
minetest-83229921e5f378625d9ef63ede3dffbe778e1798.tar.bz2
minetest-83229921e5f378625d9ef63ede3dffbe778e1798.zip
Rework use_texture_alpha to provide three opaque/clip/blend modes
The change that turns nodeboxes and meshes opaque when possible is kept, as is the compatibility code that warns modders to adjust their nodedefs.
Diffstat (limited to 'src/nodedef.cpp')
-rw-r--r--src/nodedef.cpp110
1 files changed, 73 insertions, 37 deletions
diff --git a/src/nodedef.cpp b/src/nodedef.cpp
index b2cfd1f87..57d4c008f 100644
--- a/src/nodedef.cpp
+++ b/src/nodedef.cpp
@@ -360,7 +360,7 @@ void ContentFeatures::reset()
i = TileDef();
for (auto &j : tiledef_special)
j = TileDef();
- alpha = 255;
+ alpha = ALPHAMODE_OPAQUE;
post_effect_color = video::SColor(0, 0, 0, 0);
param_type = CPT_NONE;
param_type_2 = CPT2_NONE;
@@ -405,6 +405,31 @@ void ContentFeatures::reset()
node_dig_prediction = "air";
}
+void ContentFeatures::setAlphaFromLegacy(u8 legacy_alpha)
+{
+ // No special handling for nodebox/mesh here as it doesn't make sense to
+ // throw warnings when the server is too old to support the "correct" way
+ switch (drawtype) {
+ case NDT_NORMAL:
+ alpha = legacy_alpha == 255 ? ALPHAMODE_OPAQUE : ALPHAMODE_CLIP;
+ break;
+ case NDT_LIQUID:
+ case NDT_FLOWINGLIQUID:
+ alpha = legacy_alpha == 255 ? ALPHAMODE_OPAQUE : ALPHAMODE_BLEND;
+ break;
+ default:
+ alpha = legacy_alpha == 255 ? ALPHAMODE_CLIP : ALPHAMODE_BLEND;
+ break;
+ }
+}
+
+u8 ContentFeatures::getAlphaForLegacy() const
+{
+ // This is so simple only because 255 and 0 mean wildly different things
+ // depending on drawtype...
+ return alpha == ALPHAMODE_OPAQUE ? 255 : 0;
+}
+
void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
{
const u8 version = CONTENTFEATURES_VERSION;
@@ -433,7 +458,7 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
for (const TileDef &td : tiledef_special) {
td.serialize(os, protocol_version);
}
- writeU8(os, alpha);
+ writeU8(os, getAlphaForLegacy());
writeU8(os, color.getRed());
writeU8(os, color.getGreen());
writeU8(os, color.getBlue());
@@ -489,6 +514,7 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
os << serializeString16(node_dig_prediction);
writeU8(os, leveled_max);
+ writeU8(os, alpha);
}
void ContentFeatures::deSerialize(std::istream &is)
@@ -524,7 +550,7 @@ void ContentFeatures::deSerialize(std::istream &is)
throw SerializationError("unsupported CF_SPECIAL_COUNT");
for (TileDef &td : tiledef_special)
td.deSerialize(is, version, drawtype);
- alpha = readU8(is);
+ setAlphaFromLegacy(readU8(is));
color.setRed(readU8(is));
color.setGreen(readU8(is));
color.setBlue(readU8(is));
@@ -582,10 +608,16 @@ void ContentFeatures::deSerialize(std::istream &is)
try {
node_dig_prediction = deSerializeString16(is);
- u8 tmp_leveled_max = readU8(is);
+
+ u8 tmp = readU8(is);
if (is.eof()) /* readU8 doesn't throw exceptions so we have to do this */
throw SerializationError("");
- leveled_max = tmp_leveled_max;
+ leveled_max = tmp;
+
+ tmp = readU8(is);
+ if (is.eof())
+ throw SerializationError("");
+ alpha = static_cast<enum AlphaMode>(tmp);
} catch(SerializationError &e) {};
}
@@ -677,6 +709,7 @@ bool ContentFeatures::textureAlphaCheck(ITextureSource *tsrc, const TileDef *til
video::IVideoDriver *driver = RenderingEngine::get_video_driver();
static thread_local bool long_warning_printed = false;
std::set<std::string> seen;
+
for (int i = 0; i < length; i++) {
if (seen.find(tiles[i].name) != seen.end())
continue;
@@ -701,20 +734,21 @@ bool ContentFeatures::textureAlphaCheck(ITextureSource *tsrc, const TileDef *til
break_loop:
image->drop();
- if (!ok) {
- warningstream << "Texture \"" << tiles[i].name << "\" of "
- << name << " has transparent pixels, assuming "
- "use_texture_alpha = true." << std::endl;
- if (!long_warning_printed) {
- warningstream << " This warning can be a false-positive if "
- "unused pixels in the texture are transparent. However if "
- "it is meant to be transparent, you *MUST* update the "
- "nodedef and set use_texture_alpha = true! This compatibility "
- "code will be removed in a few releases." << std::endl;
- long_warning_printed = true;
- }
- return true;
+ if (ok)
+ continue;
+ warningstream << "Texture \"" << tiles[i].name << "\" of "
+ << name << " has transparency, assuming "
+ "use_texture_alpha = \"clip\"." << std::endl;
+ if (!long_warning_printed) {
+ warningstream << " This warning can be a false-positive if "
+ "unused pixels in the texture are transparent. However if "
+ "it is meant to be transparent, you *MUST* update the "
+ "nodedef and set use_texture_alpha = \"clip\"! This "
+ "compatibility code will be removed in a few releases."
+ << std::endl;
+ long_warning_printed = true;
}
+ return true;
}
return false;
}
@@ -759,14 +793,18 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
bool is_liquid = false;
- MaterialType material_type = (alpha == 255) ?
- TILE_MATERIAL_BASIC : TILE_MATERIAL_ALPHA;
+ if (alpha == ALPHAMODE_LEGACY_COMPAT) {
+ // Before working with the alpha mode, resolve any legacy kludges
+ alpha = textureAlphaCheck(tsrc, tdef, 6) ? ALPHAMODE_CLIP : ALPHAMODE_OPAQUE;
+ }
+
+ MaterialType material_type = alpha == ALPHAMODE_OPAQUE ?
+ TILE_MATERIAL_OPAQUE : (alpha == ALPHAMODE_CLIP ? TILE_MATERIAL_BASIC :
+ TILE_MATERIAL_ALPHA);
switch (drawtype) {
default:
case NDT_NORMAL:
- material_type = (alpha == 255) ?
- TILE_MATERIAL_OPAQUE : TILE_MATERIAL_ALPHA;
solidness = 2;
break;
case NDT_AIRLIKE:
@@ -774,14 +812,14 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
break;
case NDT_LIQUID:
if (tsettings.opaque_water)
- alpha = 255;
+ alpha = ALPHAMODE_OPAQUE;
solidness = 1;
is_liquid = true;
break;
case NDT_FLOWINGLIQUID:
solidness = 0;
if (tsettings.opaque_water)
- alpha = 255;
+ alpha = ALPHAMODE_OPAQUE;
is_liquid = true;
break;
case NDT_GLASSLIKE:
@@ -833,19 +871,16 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
break;
case NDT_MESH:
case NDT_NODEBOX:
- if (alpha == 255 && textureAlphaCheck(tsrc, tdef, 6))
- alpha = 0;
-
solidness = 0;
- if (waving == 1)
+ if (waving == 1) {
material_type = TILE_MATERIAL_WAVING_PLANTS;
- else if (waving == 2)
+ } else if (waving == 2) {
material_type = TILE_MATERIAL_WAVING_LEAVES;
- else if (waving == 3)
- material_type = (alpha == 255) ? TILE_MATERIAL_WAVING_LIQUID_OPAQUE :
- TILE_MATERIAL_WAVING_LIQUID_BASIC;
- else if (alpha == 255)
- material_type = TILE_MATERIAL_OPAQUE;
+ } else if (waving == 3) {
+ material_type = alpha == ALPHAMODE_OPAQUE ?
+ TILE_MATERIAL_WAVING_LIQUID_OPAQUE : (alpha == ALPHAMODE_CLIP ?
+ TILE_MATERIAL_WAVING_LIQUID_BASIC : TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT);
+ }
break;
case NDT_TORCHLIKE:
case NDT_SIGNLIKE:
@@ -860,10 +895,11 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
if (is_liquid) {
if (waving == 3) {
- material_type = (alpha == 255) ? TILE_MATERIAL_WAVING_LIQUID_OPAQUE :
- TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT;
+ material_type = alpha == ALPHAMODE_OPAQUE ?
+ TILE_MATERIAL_WAVING_LIQUID_OPAQUE : (alpha == ALPHAMODE_CLIP ?
+ TILE_MATERIAL_WAVING_LIQUID_BASIC : TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT);
} else {
- material_type = (alpha == 255) ? TILE_MATERIAL_LIQUID_OPAQUE :
+ material_type = alpha == ALPHAMODE_OPAQUE ? TILE_MATERIAL_LIQUID_OPAQUE :
TILE_MATERIAL_LIQUID_TRANSPARENT;
}
}