diff --git a/doc/lua_api.md b/doc/lua_api.md index 2d8e345c8..e77410eaa 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -8789,9 +8789,10 @@ child will follow movement and rotation of that bone. bottom texture and the bottom edge of the top texture touch the east face). Some top and bottom textures expect to be aligned with the north face and will need to be rotated by -90 and 90 degrees, respectively, to fit the eastward orientation. - * `textures_front`: Used by the `"skybox"` type. Enable to draw a skybox with an alpha channel in - front of the sun / moon / stars rather than behind them. The sky color will always be shown - behind the alpha channel (default: `false`) + * `transparency`: Used by the `"skybox"` type. The type of transparency to use. (default: `"solid"`) + * `"solid"`: For textures without an alpha channel, `sky_color` is not used. + * `"transparent_back"`: Show stars / sun / moon over the alpha channel, `sky_color` is used. + * `"transparent_front"`: Show stars / sun / moon behind the alpha channel, `sky_color` is used. * `clouds`: Boolean for whether clouds appear. (default: `true`) * `sky_color`: A table used in `"regular"` and `"skybox"` types only. If used with the later, the `textures` should have an alpha channel. Contains the following values (alpha is ignored): diff --git a/src/client/game.cpp b/src/client/game.cpp index 5143bbfcd..0cfdfab12 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -2850,7 +2850,7 @@ void Game::handleClientEvent_SetSky(ClientEvent *event, CameraOrientation *cam) sky->setVisible(false); // Whether clouds are visible in front of a custom skybox. sky->setCloudsEnabled(event->set_sky->clouds); - sky->setTexturesFront(event->set_sky->textures_front); + sky->setTransparency(event->set_sky->transparency); // Clear the old textures out in case we switch rendering type. sky->clearSkyboxTextures(); @@ -2867,10 +2867,17 @@ void Game::handleClientEvent_SetSky(ClientEvent *event, CameraOrientation *cam) ); } else if (event->set_sky->type == "skybox" && event->set_sky->textures.size() == 6) { - // Shows the mesh skybox - sky->setVisible(true); - // Update mesh based skybox colours if applicable. - sky->setSkyColors(event->set_sky->sky_color); + const bool transparent = event->set_sky->transparency != "solid"; + + // Show the mesh and sky colors only if transparency is used. + if(transparent) { + sky->setVisible(true); + sky->setSkyColors(event->set_sky->sky_color); + } else { + sky->setVisible(false); + sky->setFallbackBgColor(event->set_sky->bgcolor); + } + // Set sunrise and sunset fog tinting: sky->setHorizonTint( event->set_sky->fog_sun_tint, event->set_sky->fog_moon_tint, @@ -2878,7 +2885,7 @@ void Game::handleClientEvent_SetSky(ClientEvent *event, CameraOrientation *cam) ); // Add textures to skybox. for (int i = 0; i < 6; i++) - sky->addTextureToSkybox(event->set_sky->textures[i], i, texture_src); + sky->addTextureToSkybox(event->set_sky->textures[i], i, texture_src, transparent); } else { // Handle everything else as plain color. if (event->set_sky->type != "plain") diff --git a/src/client/sky.cpp b/src/client/sky.cpp index 3a12d1baa..7a7652661 100644 --- a/src/client/sky.cpp +++ b/src/client/sky.cpp @@ -210,8 +210,8 @@ void Sky::render() if (m_in_clouds) return; - // Draw the six sided skybox, in the background. - if(has_tex && !m_textures_front) + // Draw the six sided skybox, solid or transparent background. + if(has_tex && (m_transparency == "solid" || m_transparency == "transparent_back")) renderTextures(driver); // Draw far cloudy fog thing blended with skycolor @@ -316,8 +316,8 @@ void Sky::render() driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2); } - // Draw the six sided skybox, in the foreground. - if(has_tex && m_textures_front) + // Draw the six sided skybox, transparent foreground. + if(has_tex && m_transparency == "transparent_front") renderTextures(driver); } } @@ -886,7 +886,7 @@ void Sky::setHorizonTint(video::SColor sun_tint, video::SColor moon_tint, } void Sky::addTextureToSkybox(const std::string &texture, int material_id, - ITextureSource *tsrc) + ITextureSource *tsrc, bool transparent) { // Sanity check for more than six textures. if (material_id + 5 >= SKY_MATERIAL_COUNT) @@ -896,7 +896,7 @@ void Sky::addTextureToSkybox(const std::string &texture, int material_id, video::ITexture *result = tsrc->getTextureForMesh(texture); m_materials[material_id+5] = baseMaterial(); m_materials[material_id+5].setTexture(0, result); - m_materials[material_id+5].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + m_materials[material_id+5].MaterialType = transparent ? video::EMT_TRANSPARENT_ALPHA_CHANNEL : video::EMT_SOLID; } float getWickedTimeOfDay(float time_of_day) diff --git a/src/client/sky.h b/src/client/sky.h index cbf065b38..00eb29256 100644 --- a/src/client/sky.h +++ b/src/client/sky.h @@ -85,6 +85,7 @@ public: void setVisible(bool visible) { m_visible = visible; } // Set only from set_sky API + void setTransparency(std::string transparency) { m_transparency = transparency; } void setCloudsEnabled(bool clouds_enabled) { m_clouds_enabled = clouds_enabled; } void setFallbackBgColor(video::SColor fallback_bg_color) { @@ -104,10 +105,9 @@ public: void setHorizonTint(video::SColor sun_tint, video::SColor moon_tint, const std::string &use_sun_tint); void setInClouds(bool clouds) { m_in_clouds = clouds; } - void setTexturesFront(bool textures_front) { m_textures_front = textures_front; } void clearSkyboxTextures() { m_sky_params.textures.clear(); } void addTextureToSkybox(const std::string &texture, int material_id, - ITextureSource *tsrc); + ITextureSource *tsrc, bool transparent); // Note: the Sky class doesn't use these values. It just stores them. void setFogDistance(s16 fog_distance) { m_sky_params.fog_distance = fog_distance; } @@ -176,7 +176,7 @@ private: bool m_clouds_enabled = true; // Initialised to true, reset only by set_sky API bool m_directional_colored_fog; bool m_in_clouds = true; // Prevent duplicating bools to remember old values - bool m_textures_front = false; // Whether textures are rendered behind the default sky + std::string m_transparency = "solid"; // Type of transparency used video::SColorf m_bgcolor_bright_f = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f); video::SColorf m_skycolor_bright_f = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f); diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 9d3a504ab..e9207d4b5 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -1290,12 +1290,12 @@ void Client::handleCommand_HudSetSky(NetworkPacket* pkt) SkyboxParams skybox; skybox.bgcolor = video::SColor(readARGB8(is)); skybox.type = std::string(deSerializeString16(is)); + skybox.transparency = std::string("solid"); u16 count = readU16(is); for (size_t i = 0; i < count; i++) skybox.textures.emplace_back(deSerializeString16(is)); - skybox.textures_front = false; skybox.clouds = readU8(is) != 0; // Use default skybox settings: @@ -1341,7 +1341,7 @@ void Client::handleCommand_HudSetSky(NetworkPacket* pkt) SkyboxParams skybox; - *pkt >> skybox.bgcolor >> skybox.type >> skybox.textures_front >> skybox.clouds >> + *pkt >> skybox.bgcolor >> skybox.type >> skybox.transparency >> skybox.clouds >> skybox.fog_sun_tint >> skybox.fog_moon_tint >> skybox.fog_tint_type; if (skybox.type == "skybox") { diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index ebf7b27d6..8c35c4212 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -2044,6 +2044,11 @@ int ObjectRef::l_set_sky(lua_State *L) sky_params.type = luaL_checkstring(L, -1); lua_pop(L, 1); + lua_getfield(L, 2, "transparency"); + if (!lua_isnil(L, -1)) + sky_params.transparency = luaL_checkstring(L, -1); + lua_pop(L, 1); + lua_getfield(L, 2, "textures"); sky_params.textures.clear(); if (lua_istable(L, -1) && sky_params.type == "skybox") { @@ -2061,7 +2066,6 @@ int ObjectRef::l_set_sky(lua_State *L) if (sky_params.textures.size() != 6 && !sky_params.textures.empty()) throw LuaError("Skybox expects 6 textures!"); - sky_params.textures_front = getboolfield_default(L, 2, "textures_front", sky_params.textures_front); sky_params.clouds = getboolfield_default(L, 2, "clouds", sky_params.clouds); lua_getfield(L, 2, "sky_color"); @@ -2239,6 +2243,8 @@ int ObjectRef::l_get_sky(lua_State *L) lua_setfield(L, -2, "base_color"); lua_pushlstring(L, skybox_params.type.c_str(), skybox_params.type.size()); lua_setfield(L, -2, "type"); + lua_pushlstring(L, skybox_params.transparency.c_str(), skybox_params.transparency.size()); + lua_setfield(L, -2, "transparency"); if (skybox_params.body_orbit_tilt != SkyboxParams::INVALID_SKYBOX_TILT) { lua_pushnumber(L, skybox_params.body_orbit_tilt); @@ -2251,8 +2257,6 @@ int ObjectRef::l_get_sky(lua_State *L) lua_rawseti(L, -2, i++); } lua_setfield(L, -2, "textures"); - lua_pushboolean(L, skybox_params.textures_front); - lua_setfield(L, -2, "textures_front"); lua_pushboolean(L, skybox_params.clouds); lua_setfield(L, -2, "clouds"); diff --git a/src/server.cpp b/src/server.cpp index 6a681acbf..49bd41661 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1852,16 +1852,15 @@ void Server::SendSetSky(session_t peer_id, const SkyboxParams ¶ms) // Handle prior clients here if (m_clients.getProtocolVersion(peer_id) < 39) { - pkt << params.bgcolor << params.type << (u16) params.textures.size(); + pkt << params.bgcolor << params.type << std::string("solid") << (u16) params.textures.size(); for (const std::string& texture : params.textures) pkt << texture; - pkt << false; pkt << params.clouds; } else { // Handle current clients and future clients - pkt << params.bgcolor << params.type - << params.textures_front << params.clouds << params.fog_sun_tint + pkt << params.bgcolor << params.type << params.transparency + << params.clouds << params.fog_sun_tint << params.fog_moon_tint << params.fog_tint_type; if (params.type == "skybox") { diff --git a/src/skyparams.h b/src/skyparams.h index 84f74db84..74e30a5be 100644 --- a/src/skyparams.h +++ b/src/skyparams.h @@ -28,8 +28,8 @@ struct SkyboxParams video::SColor bgcolor; std::string type; + std::string transparency; std::vector textures; - bool textures_front; bool clouds; SkyColor sky_color; video::SColor fog_sun_tint; @@ -90,7 +90,7 @@ public: SkyboxParams sky; sky.bgcolor = video::SColor(255, 255, 255, 255); sky.type = "regular"; - sky.textures_front = false; + sky.transparency = "solid"; sky.clouds = true; sky.sky_color = getSkyColorDefaults(); sky.fog_sun_tint = video::SColor(255, 244, 125, 29);