diff --git a/builtin/game/features.lua b/builtin/game/features.lua index ef85fbbc3..e6787a564 100644 --- a/builtin/game/features.lua +++ b/builtin/game/features.lua @@ -11,6 +11,7 @@ core.features = { area_store_custom_ids = true, add_entity_with_staticdata = true, no_chat_message_prediction = true, + object_use_texture_alpha = true, } function core.has_feature(arg) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 15036848b..946340cb3 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -2660,7 +2660,7 @@ Strings that need to be translated can contain several escapes, preceded by `@`. chat_send_player_param3 = true, get_all_craft_recipes_works = true, use_texture_alpha = true, - -- ^ The transparency channel of textures can be used optionally + -- ^ The transparency channel of textures can optionally be used on nodes no_legacy_abms = true, -- ^ Tree and grass ABMs are no longer done from C++ texture_names_parens = true, @@ -2671,6 +2671,9 @@ Strings that need to be translated can contain several escapes, preceded by `@`. -- ^ add_entity supports passing initial staticdata to on_activate no_chat_message_prediction = true, -- ^ Chat messages are no longer predicted + object_use_texture_alpha = true + -- ^ The transparency channel of textures can optionally be used on + -- objects (ie: players and lua entities) } * `minetest.has_feature(arg)`: returns `boolean, missing_features` * `arg`: string or table in format `{foo=true, bar=true}` @@ -4957,6 +4960,10 @@ Definition tables -- ^ "wielditem" expects 'textures = {itemname}' (see 'visual' above). colors = {}, -- ^ Number of required colors depends on visual. + use_texture_alpha = false, + -- ^ Use texture's alpha channel, excludes "upright_sprite" and "wielditem" + -- ^ Note: currently causes visual issues when viewed through other + -- ^ semi-transparent materials such as water. spritediv = {x = 1, y = 1}, -- ^ Used with spritesheet textures for animation and/or frame selection -- according to position relative to player. diff --git a/src/content_cao.cpp b/src/content_cao.cpp index 1dec95839..92b0ddfbd 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -477,6 +477,9 @@ void GenericCAO::addToScene(ITextureSource *tsrc) return; } + video::E_MATERIAL_TYPE material_type = (m_prop.use_texture_alpha) ? + video::EMT_TRANSPARENT_ALPHA_CHANNEL : video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + if (m_prop.visual == "sprite") { infostream<<"GenericCAO::addToScene(): single_sprite"<addBillboardSceneNode( @@ -486,7 +489,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc) tsrc->getTextureForMesh("unknown_node.png")); m_spritenode->setMaterialFlag(video::EMF_LIGHTING, false); m_spritenode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false); - m_spritenode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF); + m_spritenode->setMaterialType(material_type); m_spritenode->setMaterialFlag(video::EMF_FOG_ENABLE, true); u8 li = m_last_light; m_spritenode->setColor(video::SColor(255,li,li,li)); @@ -564,7 +567,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc) m_meshnode->setMaterialFlag(video::EMF_LIGHTING, false); m_meshnode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false); - m_meshnode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF); + m_meshnode->setMaterialType(material_type); m_meshnode->setMaterialFlag(video::EMF_FOG_ENABLE, true); } else if(m_prop.visual == "mesh") { @@ -587,15 +590,12 @@ void GenericCAO::addToScene(ITextureSource *tsrc) setAnimatedMeshColor(m_animated_meshnode, video::SColor(255,li,li,li)); - bool backface_culling = m_prop.backface_culling; - if (m_is_player) - backface_culling = false; - m_animated_meshnode->setMaterialFlag(video::EMF_LIGHTING, true); m_animated_meshnode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false); - m_animated_meshnode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF); + m_animated_meshnode->setMaterialType(material_type); m_animated_meshnode->setMaterialFlag(video::EMF_FOG_ENABLE, true); - m_animated_meshnode->setMaterialFlag(video::EMF_BACK_FACE_CULLING, backface_culling); + m_animated_meshnode->setMaterialFlag(video::EMF_BACK_FACE_CULLING, + m_prop.backface_culling); } else errorstream<<"GenericCAO::addToScene(): Could not load mesh "<getMaterial(0).MaterialType = material_type; m_spritenode->setMaterialTexture(0, tsrc->getTextureForMesh(texturestring)); @@ -1034,9 +1038,11 @@ void GenericCAO::updateTextures(std::string mod) // Set material flags and texture video::SMaterial& material = m_animated_meshnode->getMaterial(i); + material.MaterialType = material_type; material.TextureLayer[0].Texture = texture; material.setFlag(video::EMF_LIGHTING, true); material.setFlag(video::EMF_BILINEAR_FILTER, false); + material.setFlag(video::EMF_BACK_FACE_CULLING, m_prop.backface_culling); // don't filter low-res textures, makes them look blurry // player models have a res of 64 @@ -1078,6 +1084,7 @@ void GenericCAO::updateTextures(std::string mod) // Set material flags and texture video::SMaterial& material = m_meshnode->getMaterial(i); + material.MaterialType = material_type; material.setFlag(video::EMF_LIGHTING, false); material.setFlag(video::EMF_BILINEAR_FILTER, false); material.setTexture(0, diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 4959ec569..1dc05cd22 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -803,6 +803,7 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, session_t p m_prop.eye_height = 1.625f; // End of default appearance m_prop.is_visible = true; + m_prop.backface_culling = false; m_prop.makes_footstep_sound = true; m_prop.stepheight = PLAYER_DEFAULT_STEPHEIGHT * BS; m_hp = m_prop.hp_max; diff --git a/src/object_properties.cpp b/src/object_properties.cpp index e330bc24a..d42fbcc6c 100644 --- a/src/object_properties.cpp +++ b/src/object_properties.cpp @@ -68,6 +68,7 @@ std::string ObjectProperties::dump() os << ", static_save=" << static_save; os << ", eye_height=" << eye_height; os << ", zoom_fov=" << zoom_fov; + os << ", use_texture_alpha=" << use_texture_alpha; return os.str(); } @@ -113,6 +114,7 @@ void ObjectProperties::serialize(std::ostream &os) const writeU16(os, breath_max); writeF1000(os, eye_height); writeF1000(os, zoom_fov); + writeU8(os, use_texture_alpha); // Add stuff only at the bottom. // Never remove anything, because we don't want new versions of this @@ -164,4 +166,5 @@ void ObjectProperties::deSerialize(std::istream &is) breath_max = readU16(is); eye_height = readF1000(is); zoom_fov = readF1000(is); + use_texture_alpha = readU8(is); } diff --git a/src/object_properties.h b/src/object_properties.h index 140770998..d273b52f4 100644 --- a/src/object_properties.h +++ b/src/object_properties.h @@ -60,6 +60,7 @@ struct ObjectProperties bool static_save = true; float eye_height = 1.625f; float zoom_fov = 0.0f; + bool use_texture_alpha = false; ObjectProperties(); std::string dump(); diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 5229572f1..889b94660 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -304,6 +304,7 @@ void read_object_properties(lua_State *L, int index, lua_pop(L, 1); getfloatfield(L, -1, "zoom_fov", prop->zoom_fov); + getboolfield(L, -1, "use_texture_alpha", prop->use_texture_alpha); } /******************************************************************************/ @@ -386,6 +387,8 @@ void push_object_properties(lua_State *L, ObjectProperties *prop) lua_setfield(L, -2, "wield_item"); lua_pushnumber(L, prop->zoom_fov); lua_setfield(L, -2, "zoom_fov"); + lua_pushboolean(L, prop->use_texture_alpha); + lua_setfield(L, -2, "use_texture_alpha"); } /******************************************************************************/