VBO-related optimizations and improvements (#14395)

This commit is contained in:
sfan5 2024-02-19 19:04:20 +01:00
parent d85c842ce9
commit bb7f57b095
22 changed files with 439 additions and 322 deletions

@ -0,0 +1,17 @@
uniform vec4 fogColor;
uniform float fogDistance;
uniform float fogShadingParameter;
varying vec3 eyeVec;
varying lowp vec4 varColor;
void main(void)
{
vec4 col = varColor;
float clarity = clamp(fogShadingParameter
- fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0);
col.rgb = mix(fogColor.rgb, col.rgb, clarity);
gl_FragColor = col;
}

@ -0,0 +1,21 @@
uniform vec4 emissiveColor;
varying lowp vec4 varColor;
varying vec3 eyeVec;
void main(void)
{
gl_Position = mWorldViewProj * inVertexPosition;
#ifdef GL_ES
vec4 color = inVertexColor.bgra;
#else
vec4 color = inVertexColor;
#endif
color *= emissiveColor;
varColor = color;
eyeVec = -(mWorldView * inVertexPosition).xyz;
}

@ -1,6 +1,6 @@
uniform vec4 starColor;
uniform vec4 emissiveColor;
void main(void)
{
gl_FragColor = starColor;
gl_FragColor = emissiveColor;
}

@ -39,53 +39,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <algorithm>
#include "client/renderingengine.h"
/*
CAOShaderConstantSetter
*/
//! Shader constant setter for passing material emissive color to the CAO object_shader
class CAOShaderConstantSetter : public IShaderConstantSetter
{
public:
~CAOShaderConstantSetter() override = default;
void onSetConstants(video::IMaterialRendererServices *services) override
{
// Ambient color
video::SColorf emissive_color(m_emissive_color);
float as_array[4] = {
emissive_color.r,
emissive_color.g,
emissive_color.b,
emissive_color.a,
};
m_emissive_color_setting.set(as_array, services);
}
void onSetMaterial(const video::SMaterial& material) override
{
m_emissive_color = material.EmissiveColor;
}
private:
video::SColor m_emissive_color;
CachedPixelShaderSetting<float, 4>
m_emissive_color_setting{"emissiveColor"};
};
class CAOShaderConstantSetterFactory : public IShaderConstantSetterFactory
{
public:
CAOShaderConstantSetterFactory()
{}
virtual IShaderConstantSetter* create()
{
return new CAOShaderConstantSetter();
}
};
/*
ClientEnvironment
*/
@ -97,8 +50,6 @@ ClientEnvironment::ClientEnvironment(ClientMap *map,
m_texturesource(texturesource),
m_client(client)
{
auto *shdrsrc = m_client->getShaderSource();
shdrsrc->addShaderConstantSetterFactory(new CAOShaderConstantSetterFactory());
}
ClientEnvironment::~ClientEnvironment()

@ -107,7 +107,7 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
return false;
}
if (m_rendering_engine->get_video_driver() == NULL) {
if (!m_rendering_engine->get_video_driver()) {
errorstream << "Could not initialize video driver." << std::endl;
return false;
}
@ -125,51 +125,16 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true);
guienv = m_rendering_engine->get_gui_env();
skin = guienv->getSkin();
skin->setColor(gui::EGDC_WINDOW_SYMBOL, video::SColor(255, 255, 255, 255));
skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255, 255, 255, 255));
skin->setColor(gui::EGDC_3D_LIGHT, video::SColor(0, 0, 0, 0));
skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(255, 30, 30, 30));
skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(255, 0, 0, 0));
skin->setColor(gui::EGDC_HIGH_LIGHT, video::SColor(255, 70, 120, 50));
skin->setColor(gui::EGDC_HIGH_LIGHT_TEXT, video::SColor(255, 255, 255, 255));
float density = rangelim(g_settings->getFloat("gui_scaling"), 0.5, 20) *
RenderingEngine::getDisplayDensity();
skin->setSize(gui::EGDS_CHECK_BOX_WIDTH, (s32)(17.0f * density));
skin->setSize(gui::EGDS_SCROLLBAR_SIZE, (s32)(14.0f * density));
skin->setSize(gui::EGDS_WINDOW_BUTTON_WIDTH, (s32)(15.0f * density));
if (density > 1.5f) {
std::string sprite_path = porting::path_share + "/textures/base/pack/";
if (density > 3.5f)
sprite_path.append("checkbox_64.png");
else if (density > 2.0f)
sprite_path.append("checkbox_32.png");
else
sprite_path.append("checkbox_16.png");
// Texture dimensions should be a power of 2
gui::IGUISpriteBank *sprites = skin->getSpriteBank();
video::IVideoDriver *driver = m_rendering_engine->get_video_driver();
video::ITexture *sprite_texture = driver->getTexture(sprite_path.c_str());
if (sprite_texture) {
s32 sprite_id = sprites->addTextureAsSprite(sprite_texture);
if (sprite_id != -1)
skin->setIcon(gui::EGDI_CHECK_BOX_CHECKED, sprite_id);
}
}
init_guienv(guienv);
g_fontengine = new FontEngine(guienv);
FATAL_ERROR_IF(g_fontengine == NULL, "Font engine creation failed.");
// Irrlicht 1.8 input colours
skin->setColor(gui::EGDC_EDITABLE, video::SColor(255, 128, 128, 128));
skin->setColor(gui::EGDC_FOCUSED_EDITABLE, video::SColor(255, 96, 134, 49));
FATAL_ERROR_IF(!g_fontengine, "Font engine creation failed.");
// Create the menu clouds
if (!g_menucloudsmgr)
g_menucloudsmgr = m_rendering_engine->get_scene_manager()->createNewSceneManager();
if (!g_menuclouds)
g_menuclouds = new Clouds(g_menucloudsmgr, -1, rand());
// This is only global so it can be used by RenderingEngine::draw_load_screen().
assert(!g_menucloudsmgr && !g_menuclouds);
g_menucloudsmgr = m_rendering_engine->get_scene_manager()->createNewSceneManager();
g_menuclouds = new Clouds(g_menucloudsmgr, nullptr, -1, rand());
g_menuclouds->setHeight(100.0f);
g_menuclouds->update(v3f(0, 0, 0), video::SColor(255, 240, 240, 255));
scene::ICameraSceneNode* camera;
@ -223,7 +188,7 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
guiroot = m_rendering_engine->get_gui_env()->addStaticText(L"",
core::rect<s32>(0, 0, 10000, 10000));
bool game_has_run = launch_game(error_message, reconnect_requested,
bool should_run_game = launch_game(error_message, reconnect_requested,
start_data, cmd_args);
// Reset the reconnect_requested flag
@ -232,13 +197,11 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
// If skip_main_menu, we only want to startup once
if (skip_main_menu && !first_loop)
break;
first_loop = false;
if (!game_has_run) {
if (!should_run_game) {
if (skip_main_menu)
break;
continue;
}
@ -246,9 +209,6 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
if (!m_rendering_engine->run() || *kill)
break;
m_rendering_engine->get_video_driver()->setTextureCreationFlag(
video::ETCF_CREATE_MIP_MAPS, g_settings->getBool("mip_map"));
if (g_settings->getBool("enable_touch")) {
receiver->m_touchscreengui = new TouchScreenGUI(m_rendering_engine->get_raw_device(), receiver);
g_touchscreengui = receiver->m_touchscreengui;
@ -301,17 +261,18 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
// If no main menu, show error and exit
if (skip_main_menu) {
if (!error_message.empty()) {
verbosestream << "error_message = "
<< error_message << std::endl;
if (!error_message.empty())
retval = false;
}
break;
}
} // Menu-game loop
assert(g_menuclouds->getReferenceCount() == 1);
g_menuclouds->drop();
g_menuclouds = nullptr;
assert(g_menucloudsmgr->getReferenceCount() == 1);
g_menucloudsmgr->drop();
g_menucloudsmgr = nullptr;
return retval;
}
@ -373,6 +334,45 @@ void ClientLauncher::init_input()
}
}
void ClientLauncher::init_guienv(gui::IGUIEnvironment *guienv)
{
gui::IGUISkin *skin = guienv->getSkin();
skin->setColor(gui::EGDC_WINDOW_SYMBOL, video::SColor(255, 255, 255, 255));
skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255, 255, 255, 255));
skin->setColor(gui::EGDC_3D_LIGHT, video::SColor(0, 0, 0, 0));
skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(255, 30, 30, 30));
skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(255, 0, 0, 0));
skin->setColor(gui::EGDC_HIGH_LIGHT, video::SColor(255, 70, 120, 50));
skin->setColor(gui::EGDC_HIGH_LIGHT_TEXT, video::SColor(255, 255, 255, 255));
skin->setColor(gui::EGDC_EDITABLE, video::SColor(255, 128, 128, 128));
skin->setColor(gui::EGDC_FOCUSED_EDITABLE, video::SColor(255, 96, 134, 49));
float density = rangelim(g_settings->getFloat("gui_scaling"), 0.5f, 20) *
RenderingEngine::getDisplayDensity();
skin->setSize(gui::EGDS_CHECK_BOX_WIDTH, (s32)(17.0f * density));
skin->setSize(gui::EGDS_SCROLLBAR_SIZE, (s32)(14.0f * density));
skin->setSize(gui::EGDS_WINDOW_BUTTON_WIDTH, (s32)(15.0f * density));
if (density > 1.5f) {
std::string sprite_path = porting::path_share + "/textures/base/pack/";
if (density > 3.5f)
sprite_path.append("checkbox_64.png");
else if (density > 2.0f)
sprite_path.append("checkbox_32.png");
else
sprite_path.append("checkbox_16.png");
// Texture dimensions should be a power of 2
gui::IGUISpriteBank *sprites = skin->getSpriteBank();
video::IVideoDriver *driver = m_rendering_engine->get_video_driver();
video::ITexture *sprite_texture = driver->getTexture(sprite_path.c_str());
if (sprite_texture) {
s32 sprite_id = sprites->addTextureAsSprite(sprite_texture);
if (sprite_id != -1)
skin->setIcon(gui::EGDI_CHECK_BOX_CHECKED, sprite_id);
}
}
}
bool ClientLauncher::launch_game(std::string &error_message,
bool reconnect_requested, GameStartData &start_data,
const Settings &cmd_args)

@ -38,6 +38,7 @@ private:
void init_args(GameStartData &start_data, const Settings &cmd_args);
bool init_engine();
void init_input();
void init_guienv(gui::IGUIEnvironment *guienv);
bool launch_game(std::string &error_message, bool reconnect_requested,
GameStartData &start_data, const Settings &cmd_args);
@ -49,5 +50,4 @@ private:
RenderingEngine *m_rendering_engine = nullptr;
InputHandler *input = nullptr;
MyEventReceiver *receiver = nullptr;
gui::IGUISkin *skin = nullptr;
};

@ -18,10 +18,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/
#include "client/renderingengine.h"
#include "client/shader.h"
#include "clouds.h"
#include "noise.h"
#include "constants.h"
#include "debug.h"
#include "irrlicht_changes/printing.h"
#include "noise.h"
#include "profiler.h"
#include "settings.h"
#include <cmath>
@ -40,35 +42,38 @@ static void cloud_3d_setting_changed(const std::string &settingname, void *data)
((Clouds *)data)->readSettings();
}
Clouds::Clouds(scene::ISceneManager* mgr,
Clouds::Clouds(scene::ISceneManager* mgr, IShaderSource *ssrc,
s32 id,
u32 seed
):
scene::ISceneNode(mgr->getRootSceneNode(), mgr, id),
m_seed(seed)
{
m_enable_shaders = g_settings->getBool("enable_shaders");
// menu clouds use shader-less clouds for simplicity (ssrc == NULL)
m_enable_shaders = m_enable_shaders && ssrc;
m_material.Lighting = false;
m_material.BackfaceCulling = true;
m_material.FogEnable = true;
m_material.AntiAliasing = video::EAAM_SIMPLE;
m_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
m_material.forEachTexture([] (auto &tex) {
tex.MinFilter = video::ETMINF_NEAREST_MIPMAP_NEAREST;
tex.MagFilter = video::ETMAGF_NEAREST;
});
if (m_enable_shaders) {
auto sid = ssrc->getShader("cloud_shader", TILE_MATERIAL_ALPHA);
m_material.MaterialType = ssrc->getShaderInfo(sid).material;
} else {
m_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
}
m_params.height = 120;
m_params.density = 0.4f;
m_params.thickness = 16.0f;
m_params.color_bright = video::SColor(229, 240, 240, 255);
m_params.color_ambient = video::SColor(255, 0, 0, 0);
m_params.speed = v2f(0.0f, -2.0f);
m_params = SkyboxDefaults::getCloudDefaults();
readSettings();
g_settings->registerChangedCallback("enable_3d_clouds",
&cloud_3d_setting_changed, this);
updateBox();
m_meshbuffer.reset(new scene::SMeshBuffer());
m_meshbuffer->setHardwareMappingHint(scene::EHM_DYNAMIC);
}
Clouds::~Clouds()
@ -82,38 +87,14 @@ void Clouds::OnRegisterSceneNode()
if(IsVisible)
{
SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT);
//SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID);
}
ISceneNode::OnRegisterSceneNode();
}
void Clouds::render()
void Clouds::updateMesh()
{
if (m_params.density <= 0.0f)
return; // no need to do anything
video::IVideoDriver* driver = SceneManager->getVideoDriver();
if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_TRANSPARENT)
//if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_SOLID)
return;
ScopeProfiler sp(g_profiler, "Clouds::render()", SPT_AVG);
int num_faces_to_draw = m_enable_3d ? 6 : 1;
m_material.BackfaceCulling = m_enable_3d;
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->setMaterial(m_material);
/*
Clouds move from Z+ towards Z-
*/
const float cloud_full_radius = cloud_size * m_cloud_radius_i;
// Clouds move from Z+ towards Z-
v2f camera_pos_2d(m_camera_pos.X, m_camera_pos.Z);
// Position of cloud noise origin from the camera
@ -126,56 +107,61 @@ void Clouds::render()
std::floor(center_of_drawing_in_noise_f.Y / cloud_size)
);
// Only update mesh if it has moved enough, this saves lots of GPU buffer uploads.
constexpr float max_d = 5 * BS;
if (!m_mesh_valid) {
// mesh was never created or invalidated
} else if (m_mesh_origin.getDistanceFrom(m_origin) >= max_d) {
// clouds moved
} else if (center_of_drawing_in_noise_i != m_last_noise_center) {
// noise offset changed
// I think in practice this never happens due to the camera offset
// being smaller than the cloud size.(?)
} else {
return;
}
ScopeProfiler sp(g_profiler, "Clouds::updateMesh()", SPT_AVG);
m_mesh_origin = m_origin;
m_last_noise_center = center_of_drawing_in_noise_i;
m_mesh_valid = true;
const u32 num_faces_to_draw = m_enable_3d ? 6 : 1;
// The world position of the integer center point of drawing in the noise
v2f world_center_of_drawing_in_noise_f = v2f(
center_of_drawing_in_noise_i.X * cloud_size,
center_of_drawing_in_noise_i.Y * cloud_size
) + m_origin;
/*video::SColor c_top(128,b*240,b*240,b*255);
video::SColor c_side_1(128,b*230,b*230,b*255);
video::SColor c_side_2(128,b*220,b*220,b*245);
video::SColor c_bottom(128,b*205,b*205,b*230);*/
// Colors with primitive shading
video::SColorf c_top_f(m_color);
video::SColorf c_side_1_f(m_color);
video::SColorf c_side_2_f(m_color);
video::SColorf c_bottom_f(m_color);
c_side_1_f.r *= 0.95;
c_side_1_f.g *= 0.95;
c_side_1_f.b *= 0.95;
c_side_2_f.r *= 0.90;
c_side_2_f.g *= 0.90;
c_side_2_f.b *= 0.90;
c_bottom_f.r *= 0.80;
c_bottom_f.g *= 0.80;
c_bottom_f.b *= 0.80;
if (m_enable_shaders) {
// shader mixes the base color, set via EmissiveColor
c_top_f = c_side_1_f = c_side_2_f = c_bottom_f = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
}
c_side_1_f.r *= 0.95f;
c_side_1_f.g *= 0.95f;
c_side_1_f.b *= 0.95f;
c_side_2_f.r *= 0.90f;
c_side_2_f.g *= 0.90f;
c_side_2_f.b *= 0.90f;
c_bottom_f.r *= 0.80f;
c_bottom_f.g *= 0.80f;
c_bottom_f.b *= 0.80f;
video::SColor c_top = c_top_f.toSColor();
video::SColor c_side_1 = c_side_1_f.toSColor();
video::SColor c_side_2 = c_side_2_f.toSColor();
video::SColor c_bottom = c_bottom_f.toSColor();
// Get fog parameters for setting them back later
video::SColor fog_color(0,0,0,0);
video::E_FOG_TYPE fog_type = video::EFT_FOG_LINEAR;
f32 fog_start = 0;
f32 fog_end = 0;
f32 fog_density = 0;
bool fog_pixelfog = false;
bool fog_rangefog = false;
driver->getFog(fog_color, fog_type, fog_start, fog_end, fog_density,
fog_pixelfog, fog_rangefog);
// Set our own fog, unless it was already disabled
if (fog_start < FOG_RANGE_ALL) {
driver->setFog(fog_color, fog_type, cloud_full_radius * 0.5,
cloud_full_radius*1.2, fog_density, fog_pixelfog, fog_rangefog);
}
// Read noise
std::vector<bool> grid(m_cloud_radius_i * 2 * m_cloud_radius_i * 2);
std::vector<video::S3DVertex> vertices;
vertices.reserve(16 * m_cloud_radius_i * m_cloud_radius_i);
for(s16 zi = -m_cloud_radius_i; zi < m_cloud_radius_i; zi++) {
u32 si = (zi + m_cloud_radius_i) * m_cloud_radius_i * 2 + m_cloud_radius_i;
@ -190,10 +176,23 @@ void Clouds::render()
}
}
auto *mb = m_meshbuffer.get();
{
const u32 vertex_count = num_faces_to_draw * 16 * m_cloud_radius_i * m_cloud_radius_i;
const u32 quad_count = vertex_count / 4;
const u32 index_count = quad_count * 6;
// reserve memory
mb->Vertices.reallocate(vertex_count);
mb->Indices.reallocate(index_count);
}
#define GETINDEX(x, z, radius) (((z)+(radius))*(radius)*2 + (x)+(radius))
#define INAREA(x, z, radius) \
((x) >= -(radius) && (x) < (radius) && (z) >= -(radius) && (z) < (radius))
mb->Vertices.set_used(0);
for (s16 zi0= -m_cloud_radius_i; zi0 < m_cloud_radius_i; zi0++)
for (s16 xi0= -m_cloud_radius_i; xi0 < m_cloud_radius_i; xi0++)
{
@ -224,7 +223,7 @@ void Clouds::render()
const f32 ry = m_enable_3d ? m_params.thickness * BS : 0.0f;
const f32 rz = cloud_size / 2;
for(int i=0; i<num_faces_to_draw; i++)
for(u32 i = 0; i < num_faces_to_draw; i++)
{
switch(i)
{
@ -310,27 +309,87 @@ void Clouds::render()
}
v3f pos(p0.X, m_params.height * BS, p0.Y);
pos -= intToFloat(m_camera_offset, BS);
for (video::S3DVertex &vertex : v) {
vertex.Pos += pos;
vertices.push_back(vertex);
mb->Vertices.push_back(vertex);
}
}
}
int quad_count = vertices.size() / 4;
std::vector<u16> indices;
indices.reserve(quad_count * 6);
for (int k = 0; k < quad_count; k++) {
indices.push_back(4 * k + 0);
indices.push_back(4 * k + 1);
indices.push_back(4 * k + 2);
indices.push_back(4 * k + 2);
indices.push_back(4 * k + 3);
indices.push_back(4 * k + 0);
mb->setDirty(scene::EBT_VERTEX);
const u32 quad_count = mb->getVertexCount() / 4;
const u32 index_count = quad_count * 6;
// rewrite index array as needed
if (mb->getIndexCount() > index_count) {
mb->Indices.set_used(index_count);
mb->setDirty(scene::EBT_INDEX);
} else if (mb->getIndexCount() < index_count) {
const u32 start = mb->getIndexCount() / 6;
assert(start * 6 == mb->getIndexCount());
for (u32 k = start; k < quad_count; k++) {
mb->Indices.push_back(4 * k + 0);
mb->Indices.push_back(4 * k + 1);
mb->Indices.push_back(4 * k + 2);
mb->Indices.push_back(4 * k + 2);
mb->Indices.push_back(4 * k + 3);
mb->Indices.push_back(4 * k + 0);
}
mb->setDirty(scene::EBT_INDEX);
}
driver->drawVertexPrimitiveList(vertices.data(), vertices.size(), indices.data(), 2 * quad_count,
video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT);
tracestream << "Cloud::updateMesh(): " << mb->getVertexCount() << " vertices"
<< std::endl;
}
void Clouds::render()
{
if (m_params.density <= 0.0f)
return; // no need to do anything
video::IVideoDriver* driver = SceneManager->getVideoDriver();
if (SceneManager->getSceneNodeRenderPass() != scene::ESNRP_TRANSPARENT)
return;
updateMesh();
// Update position
{
v2f off_origin = m_origin - m_mesh_origin;
v3f rel(off_origin.X, 0, off_origin.Y);
rel -= intToFloat(m_camera_offset, BS);
setPosition(rel);
updateAbsolutePosition();
}
m_material.BackfaceCulling = m_enable_3d;
if (m_enable_shaders)
m_material.EmissiveColor = m_color.toSColor();
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->setMaterial(m_material);
const float cloud_full_radius = cloud_size * m_cloud_radius_i;
// Get fog parameters for setting them back later
video::SColor fog_color(0,0,0,0);
video::E_FOG_TYPE fog_type = video::EFT_FOG_LINEAR;
f32 fog_start = 0;
f32 fog_end = 0;
f32 fog_density = 0;
bool fog_pixelfog = false;
bool fog_rangefog = false;
driver->getFog(fog_color, fog_type, fog_start, fog_end, fog_density,
fog_pixelfog, fog_rangefog);
// Set our own fog, unless it was already disabled
if (fog_start < FOG_RANGE_ALL) {
driver->setFog(fog_color, fog_type, cloud_full_radius * 0.5,
cloud_full_radius*1.2, fog_density, fog_pixelfog, fog_rangefog);
}
driver->drawMeshBuffer(m_meshbuffer.get());
// Restore fog settings
driver->setFog(fog_color, fog_type, fog_start, fog_end, fog_density,
@ -346,13 +405,13 @@ void Clouds::update(const v3f &camera_p, const video::SColorf &color_diffuse)
{
video::SColorf ambient(m_params.color_ambient);
video::SColorf bright(m_params.color_bright);
m_camera_pos = camera_p;
m_color.r = core::clamp(color_diffuse.r * bright.r, ambient.r, 1.0f);
m_color.g = core::clamp(color_diffuse.g * bright.g, ambient.g, 1.0f);
m_color.b = core::clamp(color_diffuse.b * bright.b, ambient.b, 1.0f);
m_color.a = bright.a;
// is the camera inside the cloud mesh?
m_camera_pos = camera_p;
m_camera_inside_cloud = false; // default
if (m_enable_3d) {
float camera_height = camera_p.Y - BS * m_camera_offset.Y;
@ -369,9 +428,14 @@ void Clouds::update(const v3f &camera_p, const video::SColorf &color_diffuse)
void Clouds::readSettings()
{
// Upper limit was chosen due to posible render bugs
m_cloud_radius_i = rangelim(g_settings->getU16("cloud_radius"), 1, 62);
// The code isn't designed to go over 64k vertices so the upper limits were
// chosen to avoid exactly that.
// refer to vertex_count in updateMesh()
m_enable_3d = g_settings->getBool("enable_3d_clouds");
const u16 maximum = m_enable_3d ? 62 : 25;
m_cloud_radius_i = rangelim(g_settings->getU16("cloud_radius"), 1, maximum);
invalidateMesh();
}
bool Clouds::gridFilled(int x, int y) const

@ -19,10 +19,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#pragma once
#include "irrlichttypes_extrabloated.h"
#include <iostream>
#include "constants.h"
#include "irr_ptr.h"
#include "irrlichttypes_extrabloated.h"
#include "skyparams.h"
#include <iostream>
class IShaderSource;
// Menu clouds
class Clouds;
@ -34,7 +37,7 @@ extern scene::ISceneManager *g_menucloudsmgr;
class Clouds : public scene::ISceneNode
{
public:
Clouds(scene::ISceneManager* mgr,
Clouds(scene::ISceneManager* mgr, IShaderSource *ssrc,
s32 id,
u32 seed
);
@ -72,7 +75,7 @@ public:
void update(const v3f &camera_p, const video::SColorf &color);
void updateCameraOffset(const v3s16 &camera_offset)
void updateCameraOffset(v3s16 camera_offset)
{
m_camera_offset = camera_offset;
updateBox();
@ -82,24 +85,29 @@ public:
void setDensity(float density)
{
if (m_params.density == density)
return;
m_params.density = density;
// currently does not need bounding
invalidateMesh();
}
void setColorBright(const video::SColor &color_bright)
void setColorBright(video::SColor color_bright)
{
m_params.color_bright = color_bright;
}
void setColorAmbient(const video::SColor &color_ambient)
void setColorAmbient(video::SColor color_ambient)
{
m_params.color_ambient = color_ambient;
}
void setHeight(float height)
{
m_params.height = height; // add bounding when necessary
if (m_params.height == height)
return;
m_params.height = height;
updateBox();
invalidateMesh();
}
void setSpeed(v2f speed)
@ -109,8 +117,11 @@ public:
void setThickness(float thickness)
{
if (m_params.thickness == thickness)
return;
m_params.thickness = thickness;
updateBox();
invalidateMesh();
}
bool isCameraInsideCloud() const { return m_camera_inside_cloud; }
@ -126,18 +137,33 @@ private:
BS * 1000000.0f, height_bs + thickness_bs - BS * m_camera_offset.Y, BS * 1000000.0f);
}
void updateMesh();
void invalidateMesh()
{
m_mesh_valid = false;
}
bool gridFilled(int x, int y) const;
video::SMaterial m_material;
irr_ptr<scene::SMeshBuffer> m_meshbuffer;
// Value of m_origin at the time the mesh was last updated
v2f m_mesh_origin;
// Value of center_of_drawing_in_noise_i at the time the mesh was last updated
v2s16 m_last_noise_center;
// Was the mesh ever generated?
bool m_mesh_valid = false;
aabb3f m_box;
v2f m_origin;
u16 m_cloud_radius_i;
bool m_enable_3d;
u32 m_seed;
v3f m_camera_pos;
v2f m_origin;
v3s16 m_camera_offset;
video::SColorf m_color = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
CloudParams m_params;
bool m_camera_inside_cloud = false;
bool m_enable_shaders, m_enable_3d;
video::SColorf m_color = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
CloudParams m_params;
};

@ -812,7 +812,6 @@ void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
(m_prop.visual == "wielditem"));
m_wield_meshnode->setScale(m_prop.visual_size / 2.0f);
m_wield_meshnode->setColor(video::SColor(0xFFFFFFFF));
} else {
infostream<<"GenericCAO::addToScene(): \""<<m_prop.visual
<<"\" not supported"<<std::endl;

@ -379,7 +379,6 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter
CachedPixelShaderSetting<float>
m_animation_timer_delta_pixel{"animationTimerDelta"};
CachedPixelShaderSetting<float, 3> m_day_light{"dayLight"};
CachedPixelShaderSetting<float, 4> m_star_color{"starColor"};
CachedPixelShaderSetting<float, 3> m_eye_position_pixel{"eyePosition"};
CachedVertexShaderSetting<float, 3> m_eye_position_vertex{"eyePosition"};
CachedPixelShaderSetting<float, 3> m_minimap_yaw{"yawVec"};
@ -473,10 +472,6 @@ public:
get_sunlight_color(&sunlight, daynight_ratio);
m_day_light.set(sunlight, services);
video::SColorf star_color = m_sky->getCurrentStarColor();
float clr[4] = {star_color.r, star_color.g, star_color.b, star_color.a};
m_star_color.set(clr, services);
u32 animation_timer = m_client->getEnv().getFrameTime() % 1000000;
float animation_timer_f = (float)animation_timer / 100000.f;
m_animation_timer_vertex.set(&animation_timer_f, services);
@ -529,7 +524,9 @@ public:
m_bloom_radius_pixel.set(&m_bloom_radius, services);
m_bloom_strength_pixel.set(&m_bloom_strength, services);
}
float saturation = m_client->getEnv().getLocalPlayer()->getLighting().saturation;
const auto &lighting = m_client->getEnv().getLocalPlayer()->getLighting();
float saturation = lighting.saturation;
m_saturation_pixel.set(&saturation, services);
if (m_volumetric_light_enabled) {
@ -540,13 +537,13 @@ public:
if (m_sky->getSunVisible()) {
v3f sun_position = camera_node->getAbsolutePosition() +
10000. * m_sky->getSunDirection();
10000.f * m_sky->getSunDirection();
transform.transformVect(sun_position);
sun_position.normalize();
m_sun_position_pixel.set(sun_position, services);
float sun_brightness = rangelim(107.143f * m_sky->getSunDirection().dotProduct(v3f(0.f, 1.f, 0.f)), 0.f, 1.f);
float sun_brightness = core::clamp(107.143f * m_sky->getSunDirection().Y, 0.f, 1.f);
m_sun_brightness_pixel.set(&sun_brightness, services);
} else {
m_sun_position_pixel.set(v3f(0.f, 0.f, -1.f), services);
@ -557,13 +554,13 @@ public:
if (m_sky->getMoonVisible()) {
v3f moon_position = camera_node->getAbsolutePosition() +
10000. * m_sky->getMoonDirection();
10000.f * m_sky->getMoonDirection();
transform.transformVect(moon_position);
moon_position.normalize();
m_moon_position_pixel.set(moon_position, services);
float moon_brightness = rangelim(107.143f * m_sky->getMoonDirection().dotProduct(v3f(0.f, 1.f, 0.f)), 0.f, 1.f);
float moon_brightness = core::clamp(107.143f * m_sky->getMoonDirection().Y, 0.f, 1.f);
m_moon_brightness_pixel.set(&moon_brightness, services);
} else {
m_moon_position_pixel.set(v3f(0.f, 0.f, -1.f), services);
@ -571,7 +568,8 @@ public:
float moon_brightness = 0.f;
m_moon_brightness_pixel.set(&moon_brightness, services);
}
float volumetric_light_strength = m_client->getEnv().getLocalPlayer()->getLighting().volumetric_light_strength;
float volumetric_light_strength = lighting.volumetric_light_strength;
m_volumetric_light_strength_pixel.set(&volumetric_light_strength, services);
}
}
@ -1099,6 +1097,8 @@ bool Game::startup(bool *kill,
driver = device->getVideoDriver();
smgr = m_rendering_engine->get_scene_manager();
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, g_settings->getBool("mip_map"));
smgr->getParameters()->setAttribute(scene::OBJ_LOADER_IGNORE_MATERIAL_FILES, true);
// Reinit runData
@ -1454,7 +1454,7 @@ bool Game::createClient(const GameStartData &start_data)
/* Clouds
*/
if (m_cache_enable_clouds)
clouds = new Clouds(smgr, -1, time(0));
clouds = new Clouds(smgr, shader_src, -1, rand());
/* Skybox
*/

@ -97,7 +97,7 @@ Hud::Hud(Client *client, LocalPlayer *player,
if (g_settings->getBool("enable_shaders")) {
IShaderSource *shdrsrc = client->getShaderSource();
u16 shader_id = shdrsrc->getShader(
auto shader_id = shdrsrc->getShader(
m_mode == HIGHLIGHT_HALO ? "selection_shader" : "default_shader", TILE_MATERIAL_ALPHA);
m_selection_material.MaterialType = shdrsrc->getShaderInfo(shader_id).material;
} else {
@ -1100,24 +1100,23 @@ void drawItemStack(
video::SColor basecolor =
client->idef()->getItemstackColor(item, client);
u32 mc = mesh->getMeshBufferCount();
const u32 mc = mesh->getMeshBufferCount();
if (mc > imesh->buffer_colors.size())
imesh->buffer_colors.resize(mc);
for (u32 j = 0; j < mc; ++j) {
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
// we can modify vertices relatively fast,
// because these meshes are not buffered.
assert(buf->getHardwareMappingHint_Vertex() == scene::EHM_NEVER);
video::SColor c = basecolor;
if (imesh->buffer_colors.size() > j) {
ItemPartColor *p = &imesh->buffer_colors[j];
if (p->override_base)
c = p->color;
}
auto &p = imesh->buffer_colors[j];
p.applyOverride(c);
if (imesh->needs_shading)
colorizeMeshBuffer(buf, &c);
else
setMeshBufferColor(buf, c);
if (p.needColorize(c)) {
buf->setDirty(scene::EBT_VERTEX);
if (imesh->needs_shading)
colorizeMeshBuffer(buf, &c);
else
setMeshBufferColor(buf, c);
}
video::SMaterial &material = buf->getMaterial();
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;

@ -615,7 +615,7 @@ void Minimap::drawMinimap(core::rect<s32> rect)
material.TextureLayers[1].Texture = data->heightmap_texture;
if (m_enable_shaders && data->mode.type == MINIMAP_TYPE_SURFACE) {
u16 sid = m_shdrsrc->getShader("minimap_shader", TILE_MATERIAL_ALPHA);
auto sid = m_shdrsrc->getShader("minimap_shader", TILE_MATERIAL_ALPHA);
material.MaterialType = m_shdrsrc->getShaderInfo(sid).material;
} else {
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;

@ -94,7 +94,7 @@ class FogShaderConstantSetter : public IShaderConstantSetter
public:
void onSetConstants(video::IMaterialRendererServices *services) override
{
auto *driver = RenderingEngine::get_video_driver();
auto *driver = services->getVideoDriver();
assert(driver);
video::SColor fog_color(0);
@ -314,15 +314,17 @@ void RenderingEngine::draw_load_screen(const std::wstring &text,
gui::StaticText::add(guienv, text, textrect, false, false);
guitext->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
if (sky && g_settings->getBool("menu_clouds")) {
g_menuclouds->step(dtime * 3);
g_menuclouds->render();
get_video_driver()->beginScene(true, true, RenderingEngine::MENU_SKY_COLOR);
g_menucloudsmgr->drawAll();
} else if (sky)
get_video_driver()->beginScene(true, true, RenderingEngine::MENU_SKY_COLOR);
else
get_video_driver()->beginScene(true, true, video::SColor(255, 0, 0, 0));
auto *driver = get_video_driver();
if (sky) {
driver->beginScene(true, true, RenderingEngine::MENU_SKY_COLOR);
if (g_settings->getBool("menu_clouds")) {
g_menuclouds->step(dtime * 3);
g_menucloudsmgr->drawAll();
}
} else {
driver->beginScene(true, true, video::SColor(255, 0, 0, 0));
}
// draw progress bar
if ((percent >= 0) && (percent <= 100)) {
@ -367,7 +369,7 @@ void RenderingEngine::draw_load_screen(const std::wstring &text,
}
guienv->drawAll();
get_video_driver()->endScene();
driver->endScene();
guitext->remove();
}

@ -90,7 +90,6 @@ public:
bool setupTopLevelWindow();
bool setWindowIcon();
static bool print_video_modes();
void cleanupMeshCache();
void removeMesh(const scene::IMesh* mesh);

@ -217,13 +217,22 @@ class MainShaderConstantSetter : public IShaderConstantSetter
// Texture matrix
CachedVertexShaderSetting<float, 16> m_texture{"mTexture"};
// commonly used way to pass material color to shader
video::SColor m_emissive_color;
CachedPixelShaderSetting<float, 4> m_emissive_color_setting{"emissiveColor"};
public:
~MainShaderConstantSetter() = default;
virtual void onSetMaterial(const video::SMaterial& material) override
{
m_emissive_color = material.EmissiveColor;
}
virtual void onSetConstants(video::IMaterialRendererServices *services) override
{
video::IVideoDriver *driver = services->getVideoDriver();
sanity_check(driver);
assert(driver);
// Set world matrix
core::matrix4 world = driver->getTransform(video::ETS_WORLD);
@ -244,6 +253,9 @@ public:
m_world_view.set(worldView, services);
m_texture.set(texture, services);
}
video::SColorf emissive_color(m_emissive_color);
m_emissive_color_setting.set(emissive_color, services);
}
};
@ -545,11 +557,11 @@ ShaderInfo ShaderSource::generateShader(const std::string &name,
return shaderinfo;
video::IVideoDriver *driver = RenderingEngine::get_video_driver();
if (!driver->queryFeature(video::EVDF_ARB_GLSL)) {
video::IGPUProgrammingServices *gpu = driver->getGPUProgrammingServices();
if (!driver->queryFeature(video::EVDF_ARB_GLSL) || !gpu) {
throw ShaderException(gettext("Shaders are enabled but GLSL is not "
"supported by the driver."));
}
video::IGPUProgrammingServices *gpu = driver->getGPUProgrammingServices();
// Create shaders header
bool fully_programmable = driver->getDriverType() == video::EDT_OGLES2 || driver->getDriverType() == video::EDT_OPENGL3;
@ -610,14 +622,6 @@ ShaderInfo ShaderSource::generateShader(const std::string &name,
#define textureFlags texture2
)";
// Since this is the first time we're using the GL bindings be extra careful.
// This should be removed before 5.6.0 or similar.
if (!GL.GetString) {
errorstream << "OpenGL procedures were not loaded correctly, "
"please open a bug report with details about your platform/OS." << std::endl;
abort();
}
bool use_discard = fully_programmable;
// For renderers that should use discard instead of GL_ALPHA_TEST
const char *renderer = reinterpret_cast<const char*>(GL.GetString(GL.RENDERER));

@ -77,6 +77,7 @@ Sky::Sky(s32 id, RenderingEngine *rendering_engine, ITextureSource *tsrc, IShade
// Create materials
m_materials[0] = baseMaterial();
// FIXME: shouldn't this check m_enable_shaders?
m_materials[0].MaterialType = ssrc->getShaderInfo(ssrc->getShader("stars_shader", TILE_MATERIAL_ALPHA)).material;
m_materials[0].Lighting = true;
m_materials[0].ColorMaterial = video::ECM_NONE;
@ -683,11 +684,12 @@ void Sky::draw_stars(video::IVideoDriver * driver, float wicked_time_of_day)
float starbrightness = (0.25f - std::abs(tod)) * 20.0f;
float alpha = clamp(starbrightness, day_opacity, 1.0f);
m_star_color = m_star_params.starcolor;
m_star_color.a *= alpha;
if (m_star_color.a <= 0.0f) // Stars are only drawn when not fully transparent
video::SColorf color(m_star_params.starcolor);
color.a *= alpha;
if (color.a <= 0.0f) // Stars are only drawn when not fully transparent
return;
m_materials[0].DiffuseColor = m_materials[0].EmissiveColor = m_star_color.toSColor();
m_materials[0].EmissiveColor = color.toSColor();
auto sky_rotation = core::matrix4().setRotationAxisRadians(2.0f * M_PI * (wicked_time_of_day - 0.25f), v3f(0.0f, 0.0f, 1.0f));
auto world_matrix = driver->getTransform(video::ETS_WORLD);
driver->setTransform(video::ETS_WORLD, world_matrix * sky_rotation);

@ -114,7 +114,6 @@ public:
void clearSkyboxTextures() { m_sky_params.textures.clear(); }
void addTextureToSkybox(const std::string &texture, int material_id,
ITextureSource *tsrc);
const video::SColorf &getCurrentStarColor() const { return m_star_color; }
// 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; }
@ -210,7 +209,6 @@ private:
u64 m_seed = 0;
irr_ptr<scene::SMeshBuffer> m_stars;
video::SColorf m_star_color;
video::ITexture *m_sun_texture;
video::ITexture *m_moon_texture;

@ -508,21 +508,26 @@ void WieldMeshSceneNode::setColor(video::SColor c)
u8 red = c.getRed();
u8 green = c.getGreen();
u8 blue = c.getBlue();
u32 mc = mesh->getMeshBufferCount();
const u32 mc = mesh->getMeshBufferCount();
if (mc > m_colors.size())
m_colors.resize(mc);
for (u32 j = 0; j < mc; j++) {
video::SColor bc(m_base_color);
if ((m_colors.size() > j) && (m_colors[j].override_base))
bc = m_colors[j].color;
m_colors[j].applyOverride(bc);
video::SColor buffercolor(255,
bc.getRed() * red / 255,
bc.getGreen() * green / 255,
bc.getBlue() * blue / 255);
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
if (m_enable_shaders)
setMeshBufferColor(buf, buffercolor);
else
colorizeMeshBuffer(buf, &buffercolor);
if (m_colors[j].needColorize(buffercolor)) {
buf->setDirty(scene::EBT_VERTEX);
if (m_enable_shaders)
setMeshBufferColor(buf, buffercolor);
else
colorizeMeshBuffer(buf, &buffercolor);
}
}
}
@ -536,8 +541,7 @@ void WieldMeshSceneNode::setNodeLightColor(video::SColor color)
video::SMaterial &material = m_meshnode->getMaterial(i);
material.EmissiveColor = color;
}
}
else {
} else {
setColor(color);
}
}
@ -557,6 +561,12 @@ void WieldMeshSceneNode::changeToMesh(scene::IMesh *mesh)
dummymesh->drop(); // m_meshnode grabbed it
} else {
m_meshnode->setMesh(mesh);
// without shaders recolored often for lighting
// otherwise only once
if (m_enable_shaders)
mesh->setHardwareMappingHint(scene::EHM_STATIC);
else
mesh->setHardwareMappingHint(scene::EHM_DYNAMIC);
}
m_meshnode->forEachMaterial([this] (auto &mat) {
@ -651,8 +661,7 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result)
}
}
u32 mc = mesh->getMeshBufferCount();
for (u32 i = 0; i < mc; ++i) {
for (u32 i = 0; i < mesh->getMeshBufferCount(); ++i) {
scene::IMeshBuffer *buf = mesh->getMeshBuffer(i);
video::SMaterial &material = buf->getMaterial();
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
@ -668,6 +677,12 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result)
rotateMeshXZby(mesh, -45);
rotateMeshYZby(mesh, -30);
}
// might need to be re-colorized, this is done only when needed
if (mesh) {
mesh->setHardwareMappingHint(scene::EHM_DYNAMIC, scene::EBT_VERTEX);
mesh->setHardwareMappingHint(scene::EHM_STATIC, scene::EBT_INDEX);
}
result->mesh = mesh;
}
@ -722,11 +737,10 @@ void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f,
bool use_shaders, bool set_material, const video::E_MATERIAL_TYPE *mattype,
std::vector<ItemPartColor> *colors, bool apply_scale)
{
u32 mc = mesh->getMeshBufferCount();
const u32 mc = mesh->getMeshBufferCount();
// Allocate colors for existing buffers
colors->clear();
for (u32 i = 0; i < mc; ++i)
colors->push_back(ItemPartColor());
colors->resize(mc);
for (u32 i = 0; i < mc; ++i) {
const TileSpec *tile = &(f.tiles[i]);
@ -741,11 +755,11 @@ void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f,
mesh->addMeshBuffer(copy);
copy->drop();
buf = copy;
colors->push_back(
ItemPartColor(layer->has_color, layer->color));
colors->emplace_back(layer->has_color, layer->color);
} else {
(*colors)[i] = ItemPartColor(layer->has_color, layer->color);
}
video::SMaterial &material = buf->getMaterial();
if (set_material)
layer->applyMaterialOptions(material);
@ -768,6 +782,7 @@ void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f,
}
material.setTexture(2, layer->flags_texture);
}
if (apply_scale && tile->world_aligned) {
u32 n = buf->getVertexCount();
for (u32 k = 0; k != n; ++k)

@ -29,38 +29,54 @@ class ITextureSource;
struct ContentFeatures;
class ShadowRenderer;
/*!
/*
* Holds color information of an item mesh's buffer.
*/
struct ItemPartColor
class ItemPartColor
{
/*!
* If this is false, the global base color of the item
* will be used instead of the specific color of the
* buffer.
/*
* Optional color that overrides the global base color.
*/
bool override_base = false;
/*!
* The color of the buffer.
video::SColor override_color;
/*
* Stores the last color this mesh buffer was colorized as.
*/
video::SColor color = 0;
video::SColor last_colorized;
// saves some bytes compared to two std::optionals
bool override_color_set = false;
bool last_colorized_set = false;
public:
ItemPartColor() = default;
ItemPartColor(bool override, video::SColor color) :
override_base(override), color(color)
{
override_color(color), override_color_set(override)
{}
void applyOverride(video::SColor &dest) const {
if (override_color_set)
dest = override_color;
}
bool needColorize(video::SColor target) {
if (last_colorized_set && target == last_colorized)
return false;
last_colorized_set = true;
last_colorized = target;
return true;
}
};
struct ItemMesh
{
scene::IMesh *mesh = nullptr;
/*!
/*
* Stores the color of each mesh buffer.
*/
std::vector<ItemPartColor> buffer_colors;
/*!
/*
* If false, all faces of the item should have the same brightness.
* Disables shading based on normal vectors.
*/

@ -19,25 +19,26 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "guiEngine.h"
#include <IGUIStaticText.h>
#include <ICameraSceneNode.h>
#include "client/renderingengine.h"
#include "scripting_mainmenu.h"
#include "config.h"
#include "version.h"
#include "porting.h"
#include "filesys.h"
#include "settings.h"
#include "guiMainMenu.h"
#include "sound.h"
#include "httpfetch.h"
#include "log.h"
#include "client/fontengine.h"
#include "client/guiscalingfilter.h"
#include "irrlicht_changes/static_text.h"
#include "client/renderingengine.h"
#include "client/shader.h"
#include "client/tile.h"
#include "config.h"
#include "content/content.h"
#include "content/mods.h"
#include "filesys.h"
#include "guiMainMenu.h"
#include "httpfetch.h"
#include "irrlicht_changes/static_text.h"
#include "log.h"
#include "porting.h"
#include "scripting_mainmenu.h"
#include "settings.h"
#include "sound.h"
#include "version.h"
#include <ICameraSceneNode.h>
#include <IGUIStaticText.h>
#if USE_SOUND
#include "client/sound/sound_openal.h"
@ -139,6 +140,10 @@ GUIEngine::GUIEngine(JoystickController *joystick,
// create texture source
m_texture_source = std::make_unique<MenuTextureSource>(rendering_engine->get_video_driver());
// create shader source
// (currently only used by clouds)
m_shader_source.reset(createShaderSource());
// create soundmanager
#if USE_SOUND
if (g_settings->getBool("enable_sound") && g_sound_manager_singleton.get()) {
@ -285,10 +290,10 @@ bool GUIEngine::loadMainMenuScript()
void GUIEngine::run()
{
IrrlichtDevice *device = m_rendering_engine->get_raw_device();
video::IVideoDriver *driver = device->getVideoDriver();
// Always create clouds because they may or may not be
// needed based on the game selected
video::IVideoDriver *driver = m_rendering_engine->get_video_driver();
cloudInit();
unsigned int text_height = g_fontengine->getTextHeight();
@ -375,23 +380,24 @@ GUIEngine::~GUIEngine()
m_sound_manager.reset();
m_irr_toplefttext->setText(L"");
m_irr_toplefttext->remove();
//clean up texture pointers
m_cloud.clouds.reset();
// delete textures
for (image_definition &texture : m_textures) {
if (texture.texture)
m_rendering_engine->get_video_driver()->removeTexture(texture.texture);
}
m_texture_source.reset();
m_cloud.clouds.reset();
}
/******************************************************************************/
void GUIEngine::cloudInit()
{
m_cloud.clouds = make_irr<Clouds>(m_smgr, -1, rand());
m_shader_source->addShaderConstantSetterFactory(
new FogShaderConstantSetterFactory());
m_cloud.clouds = make_irr<Clouds>(m_smgr, m_shader_source.get(), -1, rand());
m_cloud.clouds->setHeight(100.0f);
m_cloud.clouds->update(v3f(0, 0, 0), video::SColor(255,240,240,255));
@ -404,7 +410,6 @@ void GUIEngine::cloudInit()
void GUIEngine::drawClouds(float dtime)
{
m_cloud.clouds->step(dtime*3);
m_cloud.clouds->render();
m_smgr->drawAll();
}

@ -54,6 +54,7 @@ struct image_definition {
class GUIEngine;
class RenderingEngine;
class MainMenuScripting;
class IWritableShaderSource;
struct MainMenuData;
/******************************************************************************/
@ -203,7 +204,9 @@ private:
MainMenuData *m_data = nullptr;
/** texture source */
std::unique_ptr<ISimpleTextureSource> m_texture_source;
/** sound manager*/
/** shader source */
std::unique_ptr<IWritableShaderSource> m_shader_source;
/** sound manager */
std::unique_ptr<ISoundManager> m_sound_manager;
/** representation of form source to be used in mainmenu formspec */

@ -466,10 +466,6 @@ public:
if (!inventory_image.empty())
cc->inventory_texture = tsrc->getTexture(inventory_image);
getItemMesh(client, item, &(cc->wield_mesh));
// note: vertices are modified frequently (see hud.cpp) so only indices
// can be mapped
if (auto mesh = cc->wield_mesh.mesh)
mesh->setHardwareMappingHint(scene::EHM_STATIC, scene::EBT_INDEX);
cc->palette = tsrc->getPalette(def.palette_image);