X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fnodedef.cpp;h=57d4c008f4243eef34bf6cfffba7004fc1020b50;hb=83229921e5f378625d9ef63ede3dffbe778e1798;hp=1740b010a1b21e3c80b0da6047f4747506c87958;hpb=7f25823bd4f1a822449eb783ee555651a89ce9de;p=minetest.git diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 1740b010a..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,21 +514,7 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const os << serializeString16(node_dig_prediction); writeU8(os, leveled_max); -} - -void ContentFeatures::correctAlpha(TileDef *tiles, int length) -{ - // alpha == 0 means that the node is using texture alpha - if (alpha == 0 || alpha == 255) - return; - - for (int i = 0; i < length; i++) { - if (tiles[i].name.empty()) - continue; - std::stringstream s; - s << tiles[i].name << "^[noalpha^[opacity:" << ((int)alpha); - tiles[i].name = s.str(); - } + writeU8(os, alpha); } void ContentFeatures::deSerialize(std::istream &is) @@ -539,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)); @@ -597,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(tmp); } catch(SerializationError &e) {}; } @@ -692,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 seen; + for (int i = 0; i < length; i++) { if (seen.find(tiles[i].name) != seen.end()) continue; @@ -716,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; } @@ -774,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: @@ -789,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: @@ -848,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: @@ -874,16 +894,12 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc } if (is_liquid) { - // Vertex alpha is no longer supported, correct if necessary. - correctAlpha(tdef, 6); - correctAlpha(tdef_overlay, 6); - correctAlpha(tdef_spec, CF_SPECIAL_COUNT); - 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; } }