mirror of
https://github.com/luanti-org/luanti.git
synced 2025-07-02 16:38:41 +00:00
Support drawing the skybox in front of the default sky
This commit is contained in:
parent
6f17876e86
commit
d4e0dfa5f6
8 changed files with 62 additions and 35 deletions
|
@ -8789,6 +8789,9 @@ child will follow movement and rotation of that bone.
|
||||||
bottom texture and the bottom edge of the top texture touch the east face).
|
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
|
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.
|
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`)
|
||||||
* `clouds`: Boolean for whether clouds appear. (default: `true`)
|
* `clouds`: Boolean for whether clouds appear. (default: `true`)
|
||||||
* `sky_color`: A table used in `"regular"` and `"skybox"` types only. If used with the later,
|
* `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):
|
the `textures` should have an alpha channel. Contains the following values (alpha is ignored):
|
||||||
|
|
|
@ -2850,6 +2850,7 @@ void Game::handleClientEvent_SetSky(ClientEvent *event, CameraOrientation *cam)
|
||||||
sky->setVisible(false);
|
sky->setVisible(false);
|
||||||
// Whether clouds are visible in front of a custom skybox.
|
// Whether clouds are visible in front of a custom skybox.
|
||||||
sky->setCloudsEnabled(event->set_sky->clouds);
|
sky->setCloudsEnabled(event->set_sky->clouds);
|
||||||
|
sky->setTexturesFront(event->set_sky->textures_front);
|
||||||
|
|
||||||
// Clear the old textures out in case we switch rendering type.
|
// Clear the old textures out in case we switch rendering type.
|
||||||
sky->clearSkyboxTextures();
|
sky->clearSkyboxTextures();
|
||||||
|
|
|
@ -93,6 +93,45 @@ void Sky::OnRegisterSceneNode()
|
||||||
scene::ISceneNode::OnRegisterSceneNode();
|
scene::ISceneNode::OnRegisterSceneNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Sky::renderTextures(video::IVideoDriver *driver)
|
||||||
|
{
|
||||||
|
const f32 t = 1.0f;
|
||||||
|
const f32 o = 0.0f;
|
||||||
|
static const u16 indices[6] = {0, 1, 2, 0, 2, 3};
|
||||||
|
video::S3DVertex vertices[4];
|
||||||
|
|
||||||
|
for (u32 j = 5; j < 11; j++) {
|
||||||
|
video::SColor c(255, 255, 255, 255);
|
||||||
|
driver->setMaterial(m_materials[j]);
|
||||||
|
// Use 1.05 rather than 1.0 to avoid colliding with the
|
||||||
|
// sun, moon and stars, as this is a background skybox.
|
||||||
|
vertices[0] = video::S3DVertex(-1.05, -1.05, -1.05, 0, 0, 1, c, t, t);
|
||||||
|
vertices[1] = video::S3DVertex( 1.05, -1.05, -1.05, 0, 0, 1, c, o, t);
|
||||||
|
vertices[2] = video::S3DVertex( 1.05, 1.05, -1.05, 0, 0, 1, c, o, o);
|
||||||
|
vertices[3] = video::S3DVertex(-1.05, 1.05, -1.05, 0, 0, 1, c, t, o);
|
||||||
|
for (video::S3DVertex &vertex : vertices) {
|
||||||
|
if (j == 5) { // Top texture
|
||||||
|
vertex.Pos.rotateYZBy(90);
|
||||||
|
vertex.Pos.rotateXZBy(90);
|
||||||
|
} else if (j == 6) { // Bottom texture
|
||||||
|
vertex.Pos.rotateYZBy(-90);
|
||||||
|
vertex.Pos.rotateXZBy(90);
|
||||||
|
} else if (j == 7) { // Left texture
|
||||||
|
vertex.Pos.rotateXZBy(90);
|
||||||
|
} else if (j == 8) { // Right texture
|
||||||
|
vertex.Pos.rotateXZBy(-90);
|
||||||
|
} else if (j == 9) { // Front texture, do nothing
|
||||||
|
// Irrlicht doesn't like it when vertexes are left
|
||||||
|
// alone and not rotated for some reason.
|
||||||
|
vertex.Pos.rotateXZBy(0);
|
||||||
|
} else {// Back texture
|
||||||
|
vertex.Pos.rotateXZBy(180);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Sky::render()
|
void Sky::render()
|
||||||
{
|
{
|
||||||
video::IVideoDriver *driver = SceneManager->getVideoDriver();
|
video::IVideoDriver *driver = SceneManager->getVideoDriver();
|
||||||
|
@ -171,39 +210,9 @@ void Sky::render()
|
||||||
if (m_in_clouds)
|
if (m_in_clouds)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Draw the six sided skybox,
|
// Draw the six sided skybox, in the background.
|
||||||
if (has_tex) {
|
if(has_tex && !m_textures_front)
|
||||||
for (u32 j = 5; j < 11; j++) {
|
renderTextures(driver);
|
||||||
video::SColor c(255, 255, 255, 255);
|
|
||||||
driver->setMaterial(m_materials[j]);
|
|
||||||
// Use 1.05 rather than 1.0 to avoid colliding with the
|
|
||||||
// sun, moon and stars, as this is a background skybox.
|
|
||||||
vertices[0] = video::S3DVertex(-1.05, -1.05, -1.05, 0, 0, 1, c, t, t);
|
|
||||||
vertices[1] = video::S3DVertex( 1.05, -1.05, -1.05, 0, 0, 1, c, o, t);
|
|
||||||
vertices[2] = video::S3DVertex( 1.05, 1.05, -1.05, 0, 0, 1, c, o, o);
|
|
||||||
vertices[3] = video::S3DVertex(-1.05, 1.05, -1.05, 0, 0, 1, c, t, o);
|
|
||||||
for (video::S3DVertex &vertex : vertices) {
|
|
||||||
if (j == 5) { // Top texture
|
|
||||||
vertex.Pos.rotateYZBy(90);
|
|
||||||
vertex.Pos.rotateXZBy(90);
|
|
||||||
} else if (j == 6) { // Bottom texture
|
|
||||||
vertex.Pos.rotateYZBy(-90);
|
|
||||||
vertex.Pos.rotateXZBy(90);
|
|
||||||
} else if (j == 7) { // Left texture
|
|
||||||
vertex.Pos.rotateXZBy(90);
|
|
||||||
} else if (j == 8) { // Right texture
|
|
||||||
vertex.Pos.rotateXZBy(-90);
|
|
||||||
} else if (j == 9) { // Front texture, do nothing
|
|
||||||
// Irrlicht doesn't like it when vertexes are left
|
|
||||||
// alone and not rotated for some reason.
|
|
||||||
vertex.Pos.rotateXZBy(0);
|
|
||||||
} else {// Back texture
|
|
||||||
vertex.Pos.rotateXZBy(180);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw far cloudy fog thing blended with skycolor
|
// Draw far cloudy fog thing blended with skycolor
|
||||||
// Disabled when using a textured skybox to prevent clipping
|
// Disabled when using a textured skybox to prevent clipping
|
||||||
|
@ -306,6 +315,10 @@ void Sky::render()
|
||||||
vertices[3] = video::S3DVertex(-1, -1.0, 1, 0, 1, 0, c, t, o);
|
vertices[3] = video::S3DVertex(-1, -1.0, 1, 0, 1, 0, c, t, o);
|
||||||
driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2);
|
driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw the six sided skybox, in the foreground.
|
||||||
|
if(has_tex && m_textures_front)
|
||||||
|
renderTextures(driver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ public:
|
||||||
virtual void OnRegisterSceneNode();
|
virtual void OnRegisterSceneNode();
|
||||||
|
|
||||||
//! renders the node.
|
//! renders the node.
|
||||||
|
virtual void renderTextures(video::IVideoDriver *driver);
|
||||||
virtual void render();
|
virtual void render();
|
||||||
|
|
||||||
virtual const aabb3f &getBoundingBox() const { return m_box; }
|
virtual const aabb3f &getBoundingBox() const { return m_box; }
|
||||||
|
@ -103,6 +104,7 @@ public:
|
||||||
void setHorizonTint(video::SColor sun_tint, video::SColor moon_tint,
|
void setHorizonTint(video::SColor sun_tint, video::SColor moon_tint,
|
||||||
const std::string &use_sun_tint);
|
const std::string &use_sun_tint);
|
||||||
void setInClouds(bool clouds) { m_in_clouds = clouds; }
|
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 clearSkyboxTextures() { m_sky_params.textures.clear(); }
|
||||||
void addTextureToSkybox(const std::string &texture, int material_id,
|
void addTextureToSkybox(const std::string &texture, int material_id,
|
||||||
ITextureSource *tsrc);
|
ITextureSource *tsrc);
|
||||||
|
@ -174,6 +176,7 @@ private:
|
||||||
bool m_clouds_enabled = true; // Initialised to true, reset only by set_sky API
|
bool m_clouds_enabled = true; // Initialised to true, reset only by set_sky API
|
||||||
bool m_directional_colored_fog;
|
bool m_directional_colored_fog;
|
||||||
bool m_in_clouds = true; // Prevent duplicating bools to remember old values
|
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
|
||||||
|
|
||||||
video::SColorf m_bgcolor_bright_f = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
|
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);
|
video::SColorf m_skycolor_bright_f = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
|
|
@ -1295,6 +1295,7 @@ void Client::handleCommand_HudSetSky(NetworkPacket* pkt)
|
||||||
for (size_t i = 0; i < count; i++)
|
for (size_t i = 0; i < count; i++)
|
||||||
skybox.textures.emplace_back(deSerializeString16(is));
|
skybox.textures.emplace_back(deSerializeString16(is));
|
||||||
|
|
||||||
|
skybox.textures_front = false;
|
||||||
skybox.clouds = readU8(is) != 0;
|
skybox.clouds = readU8(is) != 0;
|
||||||
|
|
||||||
// Use default skybox settings:
|
// Use default skybox settings:
|
||||||
|
@ -1340,7 +1341,7 @@ void Client::handleCommand_HudSetSky(NetworkPacket* pkt)
|
||||||
|
|
||||||
SkyboxParams skybox;
|
SkyboxParams skybox;
|
||||||
|
|
||||||
*pkt >> skybox.bgcolor >> skybox.type >> skybox.clouds >>
|
*pkt >> skybox.bgcolor >> skybox.type >> skybox.textures_front >> skybox.clouds >>
|
||||||
skybox.fog_sun_tint >> skybox.fog_moon_tint >> skybox.fog_tint_type;
|
skybox.fog_sun_tint >> skybox.fog_moon_tint >> skybox.fog_tint_type;
|
||||||
|
|
||||||
if (skybox.type == "skybox") {
|
if (skybox.type == "skybox") {
|
||||||
|
|
|
@ -2061,6 +2061,7 @@ int ObjectRef::l_set_sky(lua_State *L)
|
||||||
if (sky_params.textures.size() != 6 && !sky_params.textures.empty())
|
if (sky_params.textures.size() != 6 && !sky_params.textures.empty())
|
||||||
throw LuaError("Skybox expects 6 textures!");
|
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);
|
sky_params.clouds = getboolfield_default(L, 2, "clouds", sky_params.clouds);
|
||||||
|
|
||||||
lua_getfield(L, 2, "sky_color");
|
lua_getfield(L, 2, "sky_color");
|
||||||
|
@ -2250,6 +2251,8 @@ int ObjectRef::l_get_sky(lua_State *L)
|
||||||
lua_rawseti(L, -2, i++);
|
lua_rawseti(L, -2, i++);
|
||||||
}
|
}
|
||||||
lua_setfield(L, -2, "textures");
|
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_pushboolean(L, skybox_params.clouds);
|
||||||
lua_setfield(L, -2, "clouds");
|
lua_setfield(L, -2, "clouds");
|
||||||
|
|
||||||
|
|
|
@ -1857,10 +1857,11 @@ void Server::SendSetSky(session_t peer_id, const SkyboxParams ¶ms)
|
||||||
for (const std::string& texture : params.textures)
|
for (const std::string& texture : params.textures)
|
||||||
pkt << texture;
|
pkt << texture;
|
||||||
|
|
||||||
|
pkt << false;
|
||||||
pkt << params.clouds;
|
pkt << params.clouds;
|
||||||
} else { // Handle current clients and future clients
|
} else { // Handle current clients and future clients
|
||||||
pkt << params.bgcolor << params.type
|
pkt << params.bgcolor << params.type
|
||||||
<< params.clouds << params.fog_sun_tint
|
<< params.textures_front << params.clouds << params.fog_sun_tint
|
||||||
<< params.fog_moon_tint << params.fog_tint_type;
|
<< params.fog_moon_tint << params.fog_tint_type;
|
||||||
|
|
||||||
if (params.type == "skybox") {
|
if (params.type == "skybox") {
|
||||||
|
|
|
@ -29,6 +29,7 @@ struct SkyboxParams
|
||||||
video::SColor bgcolor;
|
video::SColor bgcolor;
|
||||||
std::string type;
|
std::string type;
|
||||||
std::vector<std::string> textures;
|
std::vector<std::string> textures;
|
||||||
|
bool textures_front;
|
||||||
bool clouds;
|
bool clouds;
|
||||||
SkyColor sky_color;
|
SkyColor sky_color;
|
||||||
video::SColor fog_sun_tint;
|
video::SColor fog_sun_tint;
|
||||||
|
@ -89,6 +90,7 @@ public:
|
||||||
SkyboxParams sky;
|
SkyboxParams sky;
|
||||||
sky.bgcolor = video::SColor(255, 255, 255, 255);
|
sky.bgcolor = video::SColor(255, 255, 255, 255);
|
||||||
sky.type = "regular";
|
sky.type = "regular";
|
||||||
|
sky.textures_front = false;
|
||||||
sky.clouds = true;
|
sky.clouds = true;
|
||||||
sky.sky_color = getSkyColorDefaults();
|
sky.sky_color = getSkyColorDefaults();
|
||||||
sky.fog_sun_tint = video::SColor(255, 244, 125, 29);
|
sky.fog_sun_tint = video::SColor(255, 244, 125, 29);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue