aboutsummaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
Diffstat (limited to 'src/client')
-rw-r--r--src/client/camera.cpp6
-rw-r--r--src/client/camera.h3
-rw-r--r--src/client/client.cpp55
-rw-r--r--src/client/client.h6
-rw-r--r--src/client/clientenvironment.cpp28
-rw-r--r--src/client/clientlauncher.cpp59
-rw-r--r--src/client/clientlauncher.h1
-rw-r--r--src/client/clientmap.cpp16
-rw-r--r--src/client/clientmap.h1
-rw-r--r--src/client/clientmedia.cpp8
-rw-r--r--src/client/clientmedia.h1
-rw-r--r--src/client/clientobject.h2
-rw-r--r--src/client/clouds.cpp4
-rw-r--r--src/client/clouds.h3
-rw-r--r--src/client/content_cao.cpp41
-rw-r--r--src/client/content_cao.h4
-rw-r--r--src/client/content_mapblock.cpp32
-rw-r--r--src/client/content_mapblock.h5
-rw-r--r--src/client/fontengine.cpp95
-rw-r--r--src/client/fontengine.h8
-rw-r--r--src/client/game.cpp134
-rw-r--r--src/client/game.h31
-rw-r--r--src/client/gameui.cpp15
-rw-r--r--src/client/guiscalingfilter.cpp5
-rw-r--r--src/client/hud.cpp122
-rw-r--r--src/client/hud.h27
-rw-r--r--src/client/imagefilters.cpp107
-rw-r--r--src/client/imagefilters.h6
-rw-r--r--src/client/inputhandler.cpp1
-rw-r--r--src/client/keycode.cpp2
-rw-r--r--src/client/keys.h1
-rw-r--r--src/client/mapblock_mesh.cpp4
-rw-r--r--src/client/mesh.cpp8
-rw-r--r--src/client/minimap.cpp5
-rw-r--r--src/client/particles.cpp4
-rw-r--r--src/client/render/core.cpp1
-rw-r--r--src/client/renderingengine.cpp32
-rw-r--r--src/client/renderingengine.h85
-rw-r--r--src/client/shader.cpp12
-rw-r--r--src/client/sky.cpp35
-rw-r--r--src/client/sky.h24
-rw-r--r--src/client/tile.cpp46
-rw-r--r--src/client/tile.h3
-rw-r--r--src/client/wieldmesh.cpp27
44 files changed, 599 insertions, 516 deletions
diff --git a/src/client/camera.cpp b/src/client/camera.cpp
index 854d9eae8..52bedcba9 100644
--- a/src/client/camera.cpp
+++ b/src/client/camera.cpp
@@ -44,11 +44,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define WIELDMESH_AMPLITUDE_X 7.0f
#define WIELDMESH_AMPLITUDE_Y 10.0f
-Camera::Camera(MapDrawControl &draw_control, Client *client):
+Camera::Camera(MapDrawControl &draw_control, Client *client, RenderingEngine *rendering_engine):
m_draw_control(draw_control),
m_client(client)
{
- scene::ISceneManager *smgr = RenderingEngine::get_scene_manager();
+ auto smgr = rendering_engine->get_scene_manager();
// note: making the camera node a child of the player node
// would lead to unexpected behaviour, so we don't do that.
m_playernode = smgr->addEmptySceneNode(smgr->getRootSceneNode());
@@ -542,7 +542,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, f32 tool_r
m_curr_fov_degrees = rangelim(m_curr_fov_degrees, 1.0f, 160.0f);
// FOV and aspect ratio
- const v2u32 &window_size = RenderingEngine::get_instance()->getWindowSize();
+ const v2u32 &window_size = RenderingEngine::getWindowSize();
m_aspect = (f32) window_size.X / (f32) window_size.Y;
m_fov_y = m_curr_fov_degrees * M_PI / 180.0;
// Increase vertical FOV on lower aspect ratios (<16:10)
diff --git a/src/client/camera.h b/src/client/camera.h
index c162df515..30fac5289 100644
--- a/src/client/camera.h
+++ b/src/client/camera.h
@@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
class LocalPlayer;
struct MapDrawControl;
class Client;
+class RenderingEngine;
class WieldMeshSceneNode;
struct Nametag
@@ -104,7 +105,7 @@ enum CameraMode {CAMERA_MODE_FIRST, CAMERA_MODE_THIRD, CAMERA_MODE_THIRD_FRONT};
class Camera
{
public:
- Camera(MapDrawControl &draw_control, Client *client);
+ Camera(MapDrawControl &draw_control, Client *client, RenderingEngine *rendering_engine);
~Camera();
// Get camera scene node.
diff --git a/src/client/client.cpp b/src/client/client.cpp
index e6025ed7b..57f8e6593 100644
--- a/src/client/client.cpp
+++ b/src/client/client.cpp
@@ -98,6 +98,7 @@ Client::Client(
NodeDefManager *nodedef,
ISoundManager *sound,
MtEventManager *event,
+ RenderingEngine *rendering_engine,
bool ipv6,
GameUI *game_ui
):
@@ -108,8 +109,9 @@ Client::Client(
m_nodedef(nodedef),
m_sound(sound),
m_event(event),
+ m_rendering_engine(rendering_engine),
m_env(
- new ClientMap(this, control, 666),
+ new ClientMap(this, rendering_engine, control, 666),
tsrc, this
),
m_particle_manager(&m_env),
@@ -301,12 +303,7 @@ Client::~Client()
}
// cleanup 3d model meshes on client shutdown
- while (RenderingEngine::get_mesh_cache()->getMeshCount() != 0) {
- scene::IAnimatedMesh *mesh = RenderingEngine::get_mesh_cache()->getMeshByIndex(0);
-
- if (mesh)
- RenderingEngine::get_mesh_cache()->removeMesh(mesh);
- }
+ m_rendering_engine->cleanupMeshCache();
delete m_minimap;
m_minimap = nullptr;
@@ -663,18 +660,11 @@ bool Client::loadMedia(const std::string &data, const std::string &filename,
TRACESTREAM(<< "Client: Attempting to load image "
<< "file \"" << filename << "\"" << std::endl);
- io::IFileSystem *irrfs = RenderingEngine::get_filesystem();
- video::IVideoDriver *vdrv = RenderingEngine::get_video_driver();
+ io::IFileSystem *irrfs = m_rendering_engine->get_filesystem();
+ video::IVideoDriver *vdrv = m_rendering_engine->get_video_driver();
-#if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR > 8
io::IReadFile *rfile = irrfs->createMemoryReadFile(
data.c_str(), data.size(), "_tempreadfile");
-#else
- // Silly irrlicht's const-incorrectness
- Buffer<char> data_rw(data.c_str(), data.size());
- io::IReadFile *rfile = irrfs->createMemoryReadFile(
- *data_rw, data_rw.getSize(), "_tempreadfile");
-#endif
FATAL_ERROR_IF(!rfile, "Could not create irrlicht memory file.");
@@ -1430,6 +1420,11 @@ bool Client::updateWieldedItem()
return true;
}
+scene::ISceneManager* Client::getSceneManager()
+{
+ return m_rendering_engine->get_scene_manager();
+}
+
Inventory* Client::getInventory(const InventoryLocation &loc)
{
switch(loc.type){
@@ -1692,7 +1687,7 @@ typedef struct TextureUpdateArgs {
ITextureSource *tsrc;
} TextureUpdateArgs;
-void texture_update_progress(void *args, u32 progress, u32 max_progress)
+void Client::showUpdateProgressTexture(void *args, u32 progress, u32 max_progress)
{
TextureUpdateArgs* targs = (TextureUpdateArgs*) args;
u16 cur_percent = ceil(progress / (double) max_progress * 100.);
@@ -1711,7 +1706,7 @@ void texture_update_progress(void *args, u32 progress, u32 max_progress)
targs->last_time_ms = time_ms;
std::basic_stringstream<wchar_t> strm;
strm << targs->text_base << " " << targs->last_percent << "%...";
- RenderingEngine::draw_load_screen(strm.str(), targs->guienv, targs->tsrc, 0,
+ m_rendering_engine->draw_load_screen(strm.str(), targs->guienv, targs->tsrc, 0,
72 + (u16) ((18. / 100.) * (double) targs->last_percent), true);
}
}
@@ -1732,21 +1727,21 @@ void Client::afterContentReceived()
// Rebuild inherited images and recreate textures
infostream<<"- Rebuilding images and textures"<<std::endl;
- RenderingEngine::draw_load_screen(text, guienv, m_tsrc, 0, 70);
+ m_rendering_engine->draw_load_screen(text, guienv, m_tsrc, 0, 70);
m_tsrc->rebuildImagesAndTextures();
delete[] text;
// Rebuild shaders
infostream<<"- Rebuilding shaders"<<std::endl;
text = wgettext("Rebuilding shaders...");
- RenderingEngine::draw_load_screen(text, guienv, m_tsrc, 0, 71);
+ m_rendering_engine->draw_load_screen(text, guienv, m_tsrc, 0, 71);
m_shsrc->rebuildShaders();
delete[] text;
// Update node aliases
infostream<<"- Updating node aliases"<<std::endl;
text = wgettext("Initializing nodes...");
- RenderingEngine::draw_load_screen(text, guienv, m_tsrc, 0, 72);
+ m_rendering_engine->draw_load_screen(text, guienv, m_tsrc, 0, 72);
m_nodedef->updateAliases(m_itemdef);
for (const auto &path : getTextureDirs()) {
TextureOverrideSource override_source(path + DIR_DELIM + "override.txt");
@@ -1765,7 +1760,7 @@ void Client::afterContentReceived()
tu_args.last_percent = 0;
tu_args.text_base = wgettext("Initializing nodes");
tu_args.tsrc = m_tsrc;
- m_nodedef->updateTextures(this, texture_update_progress, &tu_args);
+ m_nodedef->updateTextures(this, &tu_args);
delete[] tu_args.text_base;
// Start mesh update thread after setting up content definitions
@@ -1779,7 +1774,7 @@ void Client::afterContentReceived()
m_script->on_client_ready(m_env.getLocalPlayer());
text = wgettext("Done!");
- RenderingEngine::draw_load_screen(text, guienv, m_tsrc, 0, 100);
+ m_rendering_engine->draw_load_screen(text, guienv, m_tsrc, 0, 100);
infostream<<"Client::afterContentReceived() done"<<std::endl;
delete[] text;
}
@@ -1797,7 +1792,7 @@ float Client::getCurRate()
void Client::makeScreenshot()
{
- irr::video::IVideoDriver *driver = RenderingEngine::get_video_driver();
+ irr::video::IVideoDriver *driver = m_rendering_engine->get_video_driver();
irr::video::IImage* const raw_image = driver->createScreenShot();
if (!raw_image)
@@ -1947,23 +1942,17 @@ scene::IAnimatedMesh* Client::getMesh(const std::string &filename, bool cache)
// Create the mesh, remove it from cache and return it
// This allows unique vertex colors and other properties for each instance
-#if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR > 8
- io::IReadFile *rfile = RenderingEngine::get_filesystem()->createMemoryReadFile(
+ io::IReadFile *rfile = m_rendering_engine->get_filesystem()->createMemoryReadFile(
data.c_str(), data.size(), filename.c_str());
-#else
- Buffer<char> data_rw(data.c_str(), data.size()); // Const-incorrect Irrlicht
- io::IReadFile *rfile = RenderingEngine::get_filesystem()->createMemoryReadFile(
- *data_rw, data_rw.getSize(), filename.c_str());
-#endif
FATAL_ERROR_IF(!rfile, "Could not create/open RAM file");
- scene::IAnimatedMesh *mesh = RenderingEngine::get_scene_manager()->getMesh(rfile);
+ scene::IAnimatedMesh *mesh = m_rendering_engine->get_scene_manager()->getMesh(rfile);
rfile->drop();
if (!mesh)
return nullptr;
mesh->grab();
if (!cache)
- RenderingEngine::get_mesh_cache()->removeMesh(mesh);
+ m_rendering_engine->removeMesh(mesh);
return mesh;
}
diff --git a/src/client/client.h b/src/client/client.h
index 3e346369b..8d7f63c0c 100644
--- a/src/client/client.h
+++ b/src/client/client.h
@@ -45,6 +45,7 @@ struct ClientEvent;
struct MeshMakeData;
struct ChatMessage;
class MapBlockMesh;
+class RenderingEngine;
class IWritableTextureSource;
class IWritableShaderSource;
class ISoundManager;
@@ -122,6 +123,7 @@ public:
NodeDefManager *nodedef,
ISoundManager *sound,
MtEventManager *event,
+ RenderingEngine *rendering_engine,
bool ipv6,
GameUI *game_ui
);
@@ -346,6 +348,7 @@ public:
float mediaReceiveProgress();
void afterContentReceived();
+ void showUpdateProgressTexture(void *args, u32 progress, u32 max_progress);
float getRTT();
float getCurRate();
@@ -354,6 +357,7 @@ public:
void setCamera(Camera* camera) { m_camera = camera; }
Camera* getCamera () { return m_camera; }
+ scene::ISceneManager *getSceneManager();
bool shouldShowMinimap() const;
@@ -381,6 +385,7 @@ public:
// Insert a media file appropriately into the appropriate manager
bool loadMedia(const std::string &data, const std::string &filename,
bool from_media_push = false);
+
// Send a request for conventional media transfer
void request_media(const std::vector<std::string> &file_requests);
@@ -476,6 +481,7 @@ private:
NodeDefManager *m_nodedef;
ISoundManager *m_sound;
MtEventManager *m_event;
+ RenderingEngine *m_rendering_engine;
ClientEnvironment m_env;
diff --git a/src/client/clientenvironment.cpp b/src/client/clientenvironment.cpp
index 8e0d00bc9..f9c20b2df 100644
--- a/src/client/clientenvironment.cpp
+++ b/src/client/clientenvironment.cpp
@@ -235,7 +235,16 @@ void ClientEnvironment::step(float dtime)
&player_collisions);
}
- bool player_immortal = lplayer->getCAO() && lplayer->getCAO()->isImmortal();
+ bool player_immortal = false;
+ f32 player_fall_factor = 1.0f;
+ GenericCAO *playercao = lplayer->getCAO();
+ if (playercao) {
+ player_immortal = playercao->isImmortal();
+ int addp_p = itemgroup_get(playercao->getGroups(),
+ "fall_damage_add_percent");
+ // convert armor group into an usable fall damage factor
+ player_fall_factor = 1.0f + (float)addp_p / 100.0f;
+ }
for (const CollisionInfo &info : player_collisions) {
v3f speed_diff = info.new_speed - info.old_speed;;
@@ -248,17 +257,20 @@ void ClientEnvironment::step(float dtime)
speed_diff.Z = 0;
f32 pre_factor = 1; // 1 hp per node/s
f32 tolerance = BS*14; // 5 without damage
- f32 post_factor = 1; // 1 hp per node/s
if (info.type == COLLISION_NODE) {
const ContentFeatures &f = m_client->ndef()->
get(m_map->getNode(info.node_p));
- // Determine fall damage multiplier
- int addp = itemgroup_get(f.groups, "fall_damage_add_percent");
- pre_factor = 1.0f + (float)addp / 100.0f;
+ // Determine fall damage modifier
+ int addp_n = itemgroup_get(f.groups, "fall_damage_add_percent");
+ // convert node group to an usable fall damage factor
+ f32 node_fall_factor = 1.0f + (float)addp_n / 100.0f;
+ // combine both player fall damage modifiers
+ pre_factor = node_fall_factor * player_fall_factor;
}
float speed = pre_factor * speed_diff.getLength();
- if (speed > tolerance && !player_immortal) {
- f32 damage_f = (speed - tolerance) / BS * post_factor;
+
+ if (speed > tolerance && !player_immortal && pre_factor > 0.0f) {
+ f32 damage_f = (speed - tolerance) / BS;
u16 damage = (u16)MYMIN(damage_f + 0.5, U16_MAX);
if (damage != 0) {
damageLocalPlayer(damage, true);
@@ -340,7 +352,7 @@ u16 ClientEnvironment::addActiveObject(ClientActiveObject *object)
if (!m_ao_manager.registerObject(object))
return 0;
- object->addToScene(m_texturesource);
+ object->addToScene(m_texturesource, m_client->getSceneManager());
// Update lighting immediately
object->updateLight(getDayNightRatio());
diff --git a/src/client/clientlauncher.cpp b/src/client/clientlauncher.cpp
index 2bb0bc385..6db5f2e70 100644
--- a/src/client/clientlauncher.cpp
+++ b/src/client/clientlauncher.cpp
@@ -80,7 +80,7 @@ ClientLauncher::~ClientLauncher()
delete g_fontengine;
delete g_gamecallback;
- delete RenderingEngine::get_instance();
+ delete m_rendering_engine;
#if USE_SOUND
g_sound_manager_singleton.reset();
@@ -101,7 +101,7 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
// List video modes if requested
if (list_video_modes)
- return RenderingEngine::print_video_modes();
+ return m_rendering_engine->print_video_modes();
#if USE_SOUND
if (g_settings->getBool("enable_sound"))
@@ -120,12 +120,12 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
return true;
}
- if (RenderingEngine::get_video_driver() == NULL) {
+ if (m_rendering_engine->get_video_driver() == NULL) {
errorstream << "Could not initialize video driver." << std::endl;
return false;
}
- RenderingEngine::get_instance()->setupTopLevelWindow(PROJECT_NAME_C);
+ m_rendering_engine->setupTopLevelWindow(PROJECT_NAME_C);
/*
This changes the minimum allowed number of vertices in a VBO.
@@ -136,15 +136,15 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
// Create game callback for menus
g_gamecallback = new MainGameCallback();
- RenderingEngine::get_instance()->setResizable(true);
+ m_rendering_engine->setResizable(true);
init_input();
- RenderingEngine::get_scene_manager()->getParameters()->
+ m_rendering_engine->get_scene_manager()->getParameters()->
setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true);
- guienv = RenderingEngine::get_gui_env();
- skin = RenderingEngine::get_gui_env()->getSkin();
+ guienv = m_rendering_engine->get_gui_env();
+ skin = guienv->getSkin();
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));
@@ -166,7 +166,7 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
sprite_path.append("checkbox_16.png");
// Texture dimensions should be a power of 2
gui::IGUISpriteBank *sprites = skin->getSpriteBank();
- video::IVideoDriver *driver = RenderingEngine::get_video_driver();
+ 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);
@@ -178,15 +178,13 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
g_fontengine = new FontEngine(guienv);
FATAL_ERROR_IF(g_fontengine == NULL, "Font engine creation failed.");
-#if (IRRLICHT_VERSION_MAJOR >= 1 && IRRLICHT_VERSION_MINOR >= 8) || IRRLICHT_VERSION_MAJOR >= 2
// 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));
-#endif
// Create the menu clouds
if (!g_menucloudsmgr)
- g_menucloudsmgr = RenderingEngine::get_scene_manager()->createNewSceneManager();
+ g_menucloudsmgr = m_rendering_engine->get_scene_manager()->createNewSceneManager();
if (!g_menuclouds)
g_menuclouds = new Clouds(g_menucloudsmgr, -1, rand());
g_menuclouds->setHeight(100.0f);
@@ -214,11 +212,11 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
bool retval = true;
bool *kill = porting::signal_handler_killstatus();
- while (RenderingEngine::run() && !*kill &&
+ while (m_rendering_engine->run() && !*kill &&
!g_gamecallback->shutdown_requested) {
// Set the window caption
const wchar_t *text = wgettext("Main Menu");
- RenderingEngine::get_raw_device()->
+ m_rendering_engine->get_raw_device()->
setWindowCaption((utf8_to_wide(PROJECT_NAME_C) +
L" " + utf8_to_wide(g_version_hash) +
L" [" + text + L"]").c_str());
@@ -226,14 +224,14 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
try { // This is used for catching disconnects
- RenderingEngine::get_gui_env()->clear();
+ m_rendering_engine->get_gui_env()->clear();
/*
We need some kind of a root node to be able to add
custom gui elements directly on the screen.
Otherwise they won't be automatically drawn.
*/
- guiroot = RenderingEngine::get_gui_env()->addStaticText(L"",
+ 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,
@@ -256,29 +254,30 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
}
// Break out of menu-game loop to shut down cleanly
- if (!RenderingEngine::get_raw_device()->run() || *kill) {
+ if (!m_rendering_engine->run() || *kill) {
if (!g_settings_path.empty())
g_settings->updateConfigFile(g_settings_path.c_str());
break;
}
- RenderingEngine::get_video_driver()->setTextureCreationFlag(
+ m_rendering_engine->get_video_driver()->setTextureCreationFlag(
video::ETCF_CREATE_MIP_MAPS, g_settings->getBool("mip_map"));
#ifdef HAVE_TOUCHSCREENGUI
- receiver->m_touchscreengui = new TouchScreenGUI(RenderingEngine::get_raw_device(), receiver);
+ receiver->m_touchscreengui = new TouchScreenGUI(m_rendering_engine->get_raw_device(), receiver);
g_touchscreengui = receiver->m_touchscreengui;
#endif
the_game(
kill,
input,
+ m_rendering_engine,
start_data,
error_message,
chat_backend,
&reconnect_requested
);
- RenderingEngine::get_scene_manager()->clear();
+ m_rendering_engine->get_scene_manager()->clear();
#ifdef HAVE_TOUCHSCREENGUI
delete g_touchscreengui;
@@ -346,8 +345,8 @@ void ClientLauncher::init_args(GameStartData &start_data, const Settings &cmd_ar
bool ClientLauncher::init_engine()
{
receiver = new MyEventReceiver();
- new RenderingEngine(receiver);
- return RenderingEngine::get_raw_device() != nullptr;
+ m_rendering_engine = new RenderingEngine(receiver);
+ return m_rendering_engine->get_raw_device() != nullptr;
}
void ClientLauncher::init_input()
@@ -364,7 +363,7 @@ void ClientLauncher::init_input()
// Make sure this is called maximum once per
// irrlicht device, otherwise it will give you
// multiple events for the same joystick.
- if (RenderingEngine::get_raw_device()->activateJoysticks(infos)) {
+ if (m_rendering_engine->get_raw_device()->activateJoysticks(infos)) {
infostream << "Joystick support enabled" << std::endl;
joystick_infos.reserve(infos.size());
for (u32 i = 0; i < infos.size(); i++) {
@@ -471,7 +470,7 @@ bool ClientLauncher::launch_game(std::string &error_message,
start_data.address.empty() && !start_data.name.empty();
}
- if (!RenderingEngine::run())
+ if (!m_rendering_engine->run())
return false;
if (!start_data.isSinglePlayer() && start_data.name.empty()) {
@@ -543,14 +542,14 @@ bool ClientLauncher::launch_game(std::string &error_message,
void ClientLauncher::main_menu(MainMenuData *menudata)
{
bool *kill = porting::signal_handler_killstatus();
- video::IVideoDriver *driver = RenderingEngine::get_video_driver();
+ video::IVideoDriver *driver = m_rendering_engine->get_video_driver();
infostream << "Waiting for other menus" << std::endl;
- while (RenderingEngine::get_raw_device()->run() && !*kill) {
+ while (m_rendering_engine->run() && !*kill) {
if (!isMenuActive())
break;
driver->beginScene(true, true, video::SColor(255, 128, 128, 128));
- RenderingEngine::get_gui_env()->drawAll();
+ m_rendering_engine->get_gui_env()->drawAll();
driver->endScene();
// On some computers framerate doesn't seem to be automatically limited
sleep_ms(25);
@@ -559,14 +558,14 @@ void ClientLauncher::main_menu(MainMenuData *menudata)
// Cursor can be non-visible when coming from the game
#ifndef ANDROID
- RenderingEngine::get_raw_device()->getCursorControl()->setVisible(true);
+ m_rendering_engine->get_raw_device()->getCursorControl()->setVisible(true);
#endif
/* show main menu */
- GUIEngine mymenu(&input->joystick, guiroot, &g_menumgr, menudata, *kill);
+ GUIEngine mymenu(&input->joystick, guiroot, m_rendering_engine, &g_menumgr, menudata, *kill);
/* leave scene manager in a clean state */
- RenderingEngine::get_scene_manager()->clear();
+ m_rendering_engine->get_scene_manager()->clear();
}
void ClientLauncher::speed_tests()
diff --git a/src/client/clientlauncher.h b/src/client/clientlauncher.h
index b280d8e6b..79727e1fe 100644
--- a/src/client/clientlauncher.h
+++ b/src/client/clientlauncher.h
@@ -49,6 +49,7 @@ private:
bool list_video_modes = false;
bool skip_main_menu = false;
bool random_input = false;
+ RenderingEngine *m_rendering_engine = nullptr;
InputHandler *input = nullptr;
MyEventReceiver *receiver = nullptr;
gui::IGUISkin *skin = nullptr;
diff --git a/src/client/clientmap.cpp b/src/client/clientmap.cpp
index 6110c90e3..29a7fd3ba 100644
--- a/src/client/clientmap.cpp
+++ b/src/client/clientmap.cpp
@@ -64,12 +64,13 @@ void MeshBufListList::add(scene::IMeshBuffer *buf, v3s16 position, u8 layer)
ClientMap::ClientMap(
Client *client,
+ RenderingEngine *rendering_engine,
MapDrawControl &control,
s32 id
):
Map(client),
- scene::ISceneNode(RenderingEngine::get_scene_manager()->getRootSceneNode(),
- RenderingEngine::get_scene_manager(), id),
+ scene::ISceneNode(rendering_engine->get_scene_manager()->getRootSceneNode(),
+ rendering_engine->get_scene_manager(), id),
m_client(client),
m_control(control)
{
@@ -317,7 +318,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
v3f block_pos_r = intToFloat(block->getPosRelative() + MAP_BLOCKSIZE / 2, BS);
float d = camera_position.getDistanceFrom(block_pos_r);
d = MYMAX(0,d - BLOCK_MAX_RADIUS);
-
+
// Mesh animation
if (pass == scene::ESNRP_SOLID) {
//MutexAutoLock lock(block->mesh_mutex);
@@ -499,12 +500,12 @@ int ClientMap::getBackgroundBrightness(float max_d, u32 daylight_factor,
static v3f z_directions[50] = {
v3f(-100, 0, 0)
};
- static f32 z_offsets[sizeof(z_directions)/sizeof(*z_directions)] = {
+ static f32 z_offsets[50] = {
-1000,
};
- if(z_directions[0].X < -99){
- for(u32 i=0; i<sizeof(z_directions)/sizeof(*z_directions); i++){
+ if (z_directions[0].X < -99) {
+ for (u32 i = 0; i < ARRLEN(z_directions); i++) {
// Assumes FOV of 72 and 16/9 aspect ratio
z_directions[i] = v3f(
0.02 * myrand_range(-100, 100),
@@ -520,7 +521,8 @@ int ClientMap::getBackgroundBrightness(float max_d, u32 daylight_factor,
if(sunlight_min_d > 35*BS)
sunlight_min_d = 35*BS;
std::vector<int> values;
- for(u32 i=0; i<sizeof(z_directions)/sizeof(*z_directions); i++){
+ values.reserve(ARRLEN(z_directions));
+ for (u32 i = 0; i < ARRLEN(z_directions); i++) {
v3f z_dir = z_directions[i];
core::CMatrix4<f32> a;
a.buildRotateFromTo(v3f(0,1,0), z_dir);
diff --git a/src/client/clientmap.h b/src/client/clientmap.h
index 57cc4427e..80add4a44 100644
--- a/src/client/clientmap.h
+++ b/src/client/clientmap.h
@@ -68,6 +68,7 @@ class ClientMap : public Map, public scene::ISceneNode
public:
ClientMap(
Client *client,
+ RenderingEngine *rendering_engine,
MapDrawControl &control,
s32 id
);
diff --git a/src/client/clientmedia.cpp b/src/client/clientmedia.cpp
index c4c08c05d..0f9ba5356 100644
--- a/src/client/clientmedia.cpp
+++ b/src/client/clientmedia.cpp
@@ -216,7 +216,6 @@ void ClientMediaDownloader::initialStep(Client *client)
// This is the first time we use httpfetch, so alloc a caller ID
m_httpfetch_caller = httpfetch_caller_alloc();
- m_httpfetch_timeout = g_settings->getS32("curl_timeout");
// Set the active fetch limit to curl_parallel_limit or 84,
// whichever is greater. This gives us some leeway so that
@@ -258,8 +257,6 @@ void ClientMediaDownloader::initialStep(Client *client)
remote->baseurl + MTHASHSET_FILE_NAME;
fetch_request.caller = m_httpfetch_caller;
fetch_request.request_id = m_httpfetch_next_id; // == i
- fetch_request.timeout = m_httpfetch_timeout;
- fetch_request.connect_timeout = m_httpfetch_timeout;
fetch_request.method = HTTP_POST;
fetch_request.raw_data = required_hash_set;
fetch_request.extra_headers.emplace_back(
@@ -432,9 +429,8 @@ void ClientMediaDownloader::startRemoteMediaTransfers()
fetch_request.url = url;
fetch_request.caller = m_httpfetch_caller;
fetch_request.request_id = m_httpfetch_next_id;
- fetch_request.timeout = 0; // no data timeout!
- fetch_request.connect_timeout =
- m_httpfetch_timeout;
+ fetch_request.timeout =
+ g_settings->getS32("curl_file_download_timeout");
httpfetch_async(fetch_request);
m_remote_file_transfers.insert(std::make_pair(
diff --git a/src/client/clientmedia.h b/src/client/clientmedia.h
index 5a918535b..e97a0f24b 100644
--- a/src/client/clientmedia.h
+++ b/src/client/clientmedia.h
@@ -137,7 +137,6 @@ private:
// Status of remote transfers
unsigned long m_httpfetch_caller;
unsigned long m_httpfetch_next_id = 0;
- long m_httpfetch_timeout = 0;
s32 m_httpfetch_active = 0;
s32 m_httpfetch_active_limit = 0;
s32 m_outstanding_hash_sets = 0;
diff --git a/src/client/clientobject.h b/src/client/clientobject.h
index 4a1743d72..c0b14497c 100644
--- a/src/client/clientobject.h
+++ b/src/client/clientobject.h
@@ -44,7 +44,7 @@ public:
ClientActiveObject(u16 id, Client *client, ClientEnvironment *env);
virtual ~ClientActiveObject();
- virtual void addToScene(ITextureSource *tsrc) {}
+ virtual void addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr) = 0;
virtual void removeFromScene(bool permanent) {}
virtual void updateLight(u32 day_night_ratio) {}
diff --git a/src/client/clouds.cpp b/src/client/clouds.cpp
index 253dee8b9..5008047af 100644
--- a/src/client/clouds.cpp
+++ b/src/client/clouds.cpp
@@ -30,7 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
// Menu clouds are created later
class Clouds;
Clouds *g_menuclouds = NULL;
-irr::scene::ISceneManager *g_menucloudsmgr = NULL;
+scene::ISceneManager *g_menucloudsmgr = NULL;
// Constant for now
static constexpr const float cloud_size = BS * 64.0f;
@@ -170,7 +170,7 @@ void Clouds::render()
// Read noise
- std::vector<char> grid(m_cloud_radius_i * 2 * m_cloud_radius_i * 2); // vector<bool> is broken
+ 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);
diff --git a/src/client/clouds.h b/src/client/clouds.h
index a4d810faa..c009a05b7 100644
--- a/src/client/clouds.h
+++ b/src/client/clouds.h
@@ -29,8 +29,7 @@ class Clouds;
extern Clouds *g_menuclouds;
// Scene manager used for menu clouds
-namespace irr{namespace scene{class ISceneManager;}}
-extern irr::scene::ISceneManager *g_menucloudsmgr;
+extern scene::ISceneManager *g_menucloudsmgr;
class Clouds : public scene::ISceneNode
{
diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp
index 5e9060fc8..1259fcbd3 100644
--- a/src/client/content_cao.cpp
+++ b/src/client/content_cao.cpp
@@ -24,7 +24,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <IMeshManipulator.h>
#include <IAnimatedMeshSceneNode.h>
#include "client/client.h"
-#include "client/renderingengine.h"
#include "client/sound.h"
#include "client/tile.h"
#include "util/basic_macros.h"
@@ -190,7 +189,7 @@ public:
static ClientActiveObject* create(Client *client, ClientEnvironment *env);
- void addToScene(ITextureSource *tsrc);
+ void addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr);
void removeFromScene(bool permanent);
void updateLight(u32 day_night_ratio);
void updateNodePos();
@@ -221,7 +220,7 @@ ClientActiveObject* TestCAO::create(Client *client, ClientEnvironment *env)
return new TestCAO(client, env);
}
-void TestCAO::addToScene(ITextureSource *tsrc)
+void TestCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
{
if(m_node != NULL)
return;
@@ -250,7 +249,7 @@ void TestCAO::addToScene(ITextureSource *tsrc)
// Add to mesh
mesh->addMeshBuffer(buf);
buf->drop();
- m_node = RenderingEngine::get_scene_manager()->addMeshSceneNode(mesh, NULL);
+ m_node = smgr->addMeshSceneNode(mesh, NULL);
mesh->drop();
updateNodePos();
}
@@ -595,9 +594,9 @@ void GenericCAO::removeFromScene(bool permanent)
m_client->getMinimap()->removeMarker(&m_marker);
}
-void GenericCAO::addToScene(ITextureSource *tsrc)
+void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
{
- m_smgr = RenderingEngine::get_scene_manager();
+ m_smgr = smgr;
if (getSceneNode() != NULL) {
return;
@@ -629,8 +628,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc)
}
auto grabMatrixNode = [this] {
- m_matrixnode = RenderingEngine::get_scene_manager()->
- addDummyTransformationSceneNode();
+ m_matrixnode = m_smgr->addDummyTransformationSceneNode();
m_matrixnode->grab();
};
@@ -648,7 +646,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc)
if (m_prop.visual == "sprite") {
grabMatrixNode();
- m_spritenode = RenderingEngine::get_scene_manager()->addBillboardSceneNode(
+ m_spritenode = m_smgr->addBillboardSceneNode(
m_matrixnode, v2f(1, 1), v3f(0,0,0), -1);
m_spritenode->grab();
m_spritenode->setMaterialTexture(0,
@@ -733,8 +731,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc)
mesh->addMeshBuffer(buf);
buf->drop();
}
- m_meshnode = RenderingEngine::get_scene_manager()->
- addMeshSceneNode(mesh, m_matrixnode);
+ m_meshnode = m_smgr->addMeshSceneNode(mesh, m_matrixnode);
m_meshnode->grab();
mesh->drop();
// Set it to use the materials of the meshbuffers directly.
@@ -743,8 +740,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc)
} else if (m_prop.visual == "cube") {
grabMatrixNode();
scene::IMesh *mesh = createCubeMesh(v3f(BS,BS,BS));
- m_meshnode = RenderingEngine::get_scene_manager()->
- addMeshSceneNode(mesh, m_matrixnode);
+ m_meshnode = m_smgr->addMeshSceneNode(mesh, m_matrixnode);
m_meshnode->grab();
mesh->drop();
@@ -757,8 +753,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc)
grabMatrixNode();
scene::IAnimatedMesh *mesh = m_client->getMesh(m_prop.mesh, true);
if (mesh) {
- m_animated_meshnode = RenderingEngine::get_scene_manager()->
- addAnimatedMeshSceneNode(mesh, m_matrixnode);
+ m_animated_meshnode = m_smgr->addAnimatedMeshSceneNode(mesh, m_matrixnode);
m_animated_meshnode->grab();
mesh->drop(); // The scene node took hold of it
@@ -799,8 +794,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc)
infostream << "serialized form: " << m_prop.wield_item << std::endl;
item.deSerialize(m_prop.wield_item, m_client->idef());
}
- m_wield_meshnode = new WieldMeshSceneNode(
- RenderingEngine::get_scene_manager(), -1);
+ m_wield_meshnode = new WieldMeshSceneNode(m_smgr, -1);
m_wield_meshnode->setItem(item, m_client,
(m_prop.visual == "wielditem"));
@@ -1089,7 +1083,7 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
}
removeFromScene(false);
- addToScene(m_client->tsrc());
+ addToScene(m_client->tsrc(), m_smgr);
// Attachments, part 2: Now that the parent has been refreshed, put its attachments back
for (u16 cao_id : m_attachment_child_ids) {
@@ -1488,11 +1482,8 @@ void GenericCAO::updateAnimation()
if (m_animated_meshnode->getAnimationSpeed() != m_animation_speed)
m_animated_meshnode->setAnimationSpeed(m_animation_speed);
m_animated_meshnode->setTransitionTime(m_animation_blend);
-// Requires Irrlicht 1.8 or greater
-#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR >= 8) || IRRLICHT_VERSION_MAJOR > 1
if (m_animated_meshnode->getLoopMode() != m_animation_loop)
m_animated_meshnode->setLoopMode(m_animation_loop);
-#endif
}
void GenericCAO::updateAnimationSpeed()
@@ -1508,10 +1499,10 @@ void GenericCAO::updateBonePosition()
if (m_bone_position.empty() || !m_animated_meshnode)
return;
- m_animated_meshnode->setJointMode(irr::scene::EJUOR_CONTROL); // To write positions to the mesh on render
+ m_animated_meshnode->setJointMode(scene::EJUOR_CONTROL); // To write positions to the mesh on render
for (auto &it : m_bone_position) {
std::string bone_name = it.first;
- irr::scene::IBoneSceneNode* bone = m_animated_meshnode->getJointNode(bone_name.c_str());
+ scene::IBoneSceneNode* bone = m_animated_meshnode->getJointNode(bone_name.c_str());
if (bone) {
bone->setPosition(it.second.X);
bone->setRotation(it.second.Y);
@@ -1520,7 +1511,7 @@ void GenericCAO::updateBonePosition()
// search through bones to find mistakenly rotated bones due to bug in Irrlicht
for (u32 i = 0; i < m_animated_meshnode->getJointCount(); ++i) {
- irr::scene::IBoneSceneNode *bone = m_animated_meshnode->getJointNode(i);
+ scene::IBoneSceneNode *bone = m_animated_meshnode->getJointNode(i);
if (!bone)
continue;
@@ -1965,7 +1956,7 @@ void GenericCAO::updateMeshCulling()
return;
}
- irr::scene::ISceneNode *node = getSceneNode();
+ scene::ISceneNode *node = getSceneNode();
if (!node)
return;
diff --git a/src/client/content_cao.h b/src/client/content_cao.h
index 450023d19..7e9bb6671 100644
--- a/src/client/content_cao.h
+++ b/src/client/content_cao.h
@@ -189,6 +189,8 @@ public:
const bool isImmortal();
+ inline const ObjectProperties &getProperties() const { return m_prop; }
+
scene::ISceneNode *getSceneNode() const;
scene::IAnimatedMeshSceneNode *getAnimatedMeshSceneNode() const;
@@ -260,7 +262,7 @@ public:
void removeFromScene(bool permanent);
- void addToScene(ITextureSource *tsrc);
+ void addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr);
inline void expireVisuals()
{
diff --git a/src/client/content_mapblock.cpp b/src/client/content_mapblock.cpp
index 90284ecce..810c57138 100644
--- a/src/client/content_mapblock.cpp
+++ b/src/client/content_mapblock.cpp
@@ -60,18 +60,16 @@ static constexpr u16 quad_indices[] = {0, 1, 2, 2, 3, 0};
const std::string MapblockMeshGenerator::raillike_groupname = "connect_to_raillike";
-MapblockMeshGenerator::MapblockMeshGenerator(MeshMakeData *input, MeshCollector *output)
+MapblockMeshGenerator::MapblockMeshGenerator(MeshMakeData *input, MeshCollector *output,
+ scene::IMeshManipulator *mm):
+ data(input),
+ collector(output),
+ nodedef(data->m_client->ndef()),
+ meshmanip(mm),
+ blockpos_nodes(data->m_blockpos * MAP_BLOCKSIZE)
{
- data = input;
- collector = output;
-
- nodedef = data->m_client->ndef();
- meshmanip = RenderingEngine::get_scene_manager()->getMeshManipulator();
-
enable_mesh_cache = g_settings->getBool("enable_mesh_cache") &&
!data->m_smooth_lighting; // Mesh cache is not supported with smooth lighting
-
- blockpos_nodes = data->m_blockpos * MAP_BLOCKSIZE;
}
void MapblockMeshGenerator::useTile(int index, u8 set_flags, u8 reset_flags, bool special)
@@ -968,7 +966,7 @@ void MapblockMeshGenerator::drawPlantlike()
draw_style = PLANT_STYLE_CROSS;
scale = BS / 2 * f->visual_scale;
offset = v3f(0, 0, 0);
- rotate_degree = 0;
+ rotate_degree = 0.0f;
random_offset_Y = false;
face_num = 0;
plant_height = 1.0;
@@ -988,7 +986,8 @@ void MapblockMeshGenerator::drawPlantlike()
break;
case CPT2_DEGROTATE:
- rotate_degree = n.param2 * 2;
+ case CPT2_COLORED_DEGROTATE:
+ rotate_degree = 1.5f * n.getDegRotate(nodedef);
break;
case CPT2_LEVELED:
@@ -1343,6 +1342,7 @@ void MapblockMeshGenerator::drawMeshNode()
u8 facedir = 0;
scene::IMesh* mesh;
bool private_mesh; // as a grab/drop pair is not thread-safe
+ int degrotate = 0;
if (f->param_type_2 == CPT2_FACEDIR ||
f->param_type_2 == CPT2_COLORED_FACEDIR) {
@@ -1354,9 +1354,12 @@ void MapblockMeshGenerator::drawMeshNode()
facedir = n.getWallMounted(nodedef);
if (!enable_mesh_cache)
facedir = wallmounted_to_facedir[facedir];
+ } else if (f->param_type_2 == CPT2_DEGROTATE ||
+ f->param_type_2 == CPT2_COLORED_DEGROTATE) {
+ degrotate = n.getDegRotate(nodedef);
}
- if (!data->m_smooth_lighting && f->mesh_ptr[facedir]) {
+ if (!data->m_smooth_lighting && f->mesh_ptr[facedir] && !degrotate) {
// use cached meshes
private_mesh = false;
mesh = f->mesh_ptr[facedir];
@@ -1364,7 +1367,10 @@ void MapblockMeshGenerator::drawMeshNode()
// no cache, clone and rotate mesh
private_mesh = true;
mesh = cloneMesh(f->mesh_ptr[0]);
- rotateMeshBy6dFacedir(mesh, facedir);
+ if (facedir)
+ rotateMeshBy6dFacedir(mesh, facedir);
+ else if (degrotate)
+ rotateMeshXZby(mesh, 1.5f * degrotate);
recalculateBoundingBox(mesh);
meshmanip->recalculateNormals(mesh, true, false);
} else
diff --git a/src/client/content_mapblock.h b/src/client/content_mapblock.h
index 487d84a07..237cc7847 100644
--- a/src/client/content_mapblock.h
+++ b/src/client/content_mapblock.h
@@ -139,7 +139,7 @@ public:
// plantlike-specific
PlantlikeStyle draw_style;
v3f offset;
- int rotate_degree;
+ float rotate_degree;
bool random_offset_Y;
int face_num;
float plant_height;
@@ -172,7 +172,8 @@ public:
void drawNode();
public:
- MapblockMeshGenerator(MeshMakeData *input, MeshCollector *output);
+ MapblockMeshGenerator(MeshMakeData *input, MeshCollector *output,
+ scene::IMeshManipulator *mm);
void generate();
void renderSingle(content_t node, u8 param2 = 0x00);
};
diff --git a/src/client/fontengine.cpp b/src/client/fontengine.cpp
index 47218c0d9..0382c2f18 100644
--- a/src/client/fontengine.cpp
+++ b/src/client/fontengine.cpp
@@ -56,7 +56,7 @@ FontEngine::FontEngine(gui::IGUIEnvironment* env) :
readSettings();
- if (m_currentMode == FM_Standard) {
+ if (m_currentMode != FM_Simple) {
g_settings->registerChangedCallback("font_size", font_setting_changed, NULL);
g_settings->registerChangedCallback("font_bold", font_setting_changed, NULL);
g_settings->registerChangedCallback("font_italic", font_setting_changed, NULL);
@@ -66,12 +66,7 @@ FontEngine::FontEngine(gui::IGUIEnvironment* env) :
g_settings->registerChangedCallback("font_path_bolditalic", font_setting_changed, NULL);
g_settings->registerChangedCallback("font_shadow", font_setting_changed, NULL);
g_settings->registerChangedCallback("font_shadow_alpha", font_setting_changed, NULL);
- }
- else if (m_currentMode == FM_Fallback) {
- g_settings->registerChangedCallback("fallback_font_size", font_setting_changed, NULL);
g_settings->registerChangedCallback("fallback_font_path", font_setting_changed, NULL);
- g_settings->registerChangedCallback("fallback_font_shadow", font_setting_changed, NULL);
- g_settings->registerChangedCallback("fallback_font_shadow_alpha", font_setting_changed, NULL);
}
g_settings->registerChangedCallback("mono_font_path", font_setting_changed, NULL);
@@ -102,6 +97,11 @@ void FontEngine::cleanCache()
/******************************************************************************/
irr::gui::IGUIFont *FontEngine::getFont(FontSpec spec)
{
+ return getFont(spec, false);
+}
+
+irr::gui::IGUIFont *FontEngine::getFont(FontSpec spec, bool may_fail)
+{
if (spec.mode == FM_Unspecified) {
spec.mode = m_currentMode;
} else if (m_currentMode == FM_Simple) {
@@ -112,6 +112,10 @@ irr::gui::IGUIFont *FontEngine::getFont(FontSpec spec)
// Support for those could be added, but who cares?
spec.bold = false;
spec.italic = false;
+ } else if (spec.mode == _FM_Fallback) {
+ // Fallback font doesn't support these either
+ spec.bold = false;
+ spec.italic = false;
}
// Fallback to default size
@@ -130,6 +134,13 @@ irr::gui::IGUIFont *FontEngine::getFont(FontSpec spec)
else
font = initFont(spec);
+ if (!font && !may_fail) {
+ errorstream << "Minetest cannot continue without a valid font. "
+ "Please correct the 'font_path' setting or install the font "
+ "file in the proper location." << std::endl;
+ abort();
+ }
+
m_font_cache[spec.getHash()][spec.size] = font;
return font;
@@ -204,20 +215,9 @@ unsigned int FontEngine::getFontSize(FontMode mode)
void FontEngine::readSettings()
{
if (USE_FREETYPE && g_settings->getBool("freetype")) {
- m_default_size[FM_Standard] = g_settings->getU16("font_size");
- m_default_size[FM_Fallback] = g_settings->getU16("fallback_font_size");
- m_default_size[FM_Mono] = g_settings->getU16("mono_font_size");
-
- /*~ DO NOT TRANSLATE THIS LITERALLY!
- This is a special string. Put either "no" or "yes"
- into the translation field (literally).
- Choose "yes" if the language requires use of the fallback
- font, "no" otherwise.
- The fallback font is (normally) required for languages with
- non-Latin script, like Chinese.
- When in doubt, test your translation. */
- m_currentMode = is_yes(gettext("needs_fallback_font")) ?
- FM_Fallback : FM_Standard;
+ m_default_size[FM_Standard] = g_settings->getU16("font_size");
+ m_default_size[_FM_Fallback] = g_settings->getU16("font_size");
+ m_default_size[FM_Mono] = g_settings->getU16("mono_font_size");
m_default_bold = g_settings->getBool("font_bold");
m_default_italic = g_settings->getBool("font_italic");
@@ -271,18 +271,8 @@ gui::IGUIFont *FontEngine::initFont(const FontSpec &spec)
assert(spec.size != FONT_SIZE_UNSPECIFIED);
std::string setting_prefix = "";
-
- switch (spec.mode) {
- case FM_Fallback:
- setting_prefix = "fallback_";
- break;
- case FM_Mono:
- case FM_SimpleMono:
- setting_prefix = "mono_";
- break;
- default:
- break;
- }
+ if (spec.mode == FM_Mono)
+ setting_prefix = "mono_";
std::string setting_suffix = "";
if (spec.bold)
@@ -305,38 +295,41 @@ gui::IGUIFont *FontEngine::initFont(const FontSpec &spec)
g_settings->getU16NoEx(setting_prefix + "font_shadow_alpha",
font_shadow_alpha);
- std::string wanted_font_path;
- wanted_font_path = g_settings->get(setting_prefix + "font_path" + setting_suffix);
+ std::string path_setting;
+ if (spec.mode == _FM_Fallback)
+ path_setting = "fallback_font_path";
+ else
+ path_setting = setting_prefix + "font_path" + setting_suffix;
std::string fallback_settings[] = {
- wanted_font_path,
- g_settings->get("fallback_font_path"),
- Settings::getLayer(SL_DEFAULTS)->get(setting_prefix + "font_path")
+ g_settings->get(path_setting),
+ Settings::getLayer(SL_DEFAULTS)->get(path_setting)
};
#if USE_FREETYPE
for (const std::string &font_path : fallback_settings) {
- irr::gui::IGUIFont *font = gui::CGUITTFont::createTTFont(m_env,
+ gui::CGUITTFont *font = gui::CGUITTFont::createTTFont(m_env,
font_path.c_str(), size, true, true, font_shadow,
font_shadow_alpha);
- if (font)
- return font;
-
- errorstream << "FontEngine: Cannot load '" << font_path <<
+ if (!font) {
+ errorstream << "FontEngine: Cannot load '" << font_path <<
"'. Trying to fall back to another path." << std::endl;
- }
-
+ continue;
+ }
- // give up
- errorstream << "minetest can not continue without a valid font. "
- "Please correct the 'font_path' setting or install the font "
- "file in the proper location" << std::endl;
+ if (spec.mode != _FM_Fallback) {
+ FontSpec spec2(spec);
+ spec2.mode = _FM_Fallback;
+ font->setFallback(getFont(spec2, true));
+ }
+ return font;
+ }
#else
- errorstream << "FontEngine: Tried to load freetype fonts but Minetest was"
- " not compiled with that library." << std::endl;
+ errorstream << "FontEngine: Tried to load TTF font but Minetest was"
+ " compiled without Freetype." << std::endl;
#endif
- abort();
+ return nullptr;
}
/** initialize a font without freetype */
diff --git a/src/client/fontengine.h b/src/client/fontengine.h
index e27ef60e9..3d389ea48 100644
--- a/src/client/fontengine.h
+++ b/src/client/fontengine.h
@@ -33,7 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
enum FontMode : u8 {
FM_Standard = 0,
FM_Mono,
- FM_Fallback,
+ _FM_Fallback, // do not use directly
FM_Simple,
FM_SimpleMono,
FM_MaxMode,
@@ -47,7 +47,7 @@ struct FontSpec {
bold(bold),
italic(italic) {}
- u16 getHash()
+ u16 getHash() const
{
return (mode << 2) | (static_cast<u8>(bold) << 1) | static_cast<u8>(italic);
}
@@ -132,10 +132,12 @@ public:
void readSettings();
private:
+ irr::gui::IGUIFont *getFont(FontSpec spec, bool may_fail);
+
/** update content of font cache in case of a setting change made it invalid */
void updateFontCache();
- /** initialize a new font */
+ /** initialize a new TTF font */
gui::IGUIFont *initFont(const FontSpec &spec);
/** initialize a font without freetype */
diff --git a/src/client/game.cpp b/src/client/game.cpp
index e1f2fbe75..5bfe55e66 100644
--- a/src/client/game.cpp
+++ b/src/client/game.cpp
@@ -153,7 +153,7 @@ Game::~Game()
delete itemdef_manager;
delete draw_control;
- extendedResourceCleanup();
+ clearTextureNameCache();
g_settings->deregisterChangedCallback("doubletap_jump",
&settingChangedCallback, this);
@@ -191,6 +191,7 @@ Game::~Game()
bool Game::startup(bool *kill,
InputHandler *input,
+ RenderingEngine *rendering_engine,
const GameStartData &start_data,
std::string &error_message,
bool *reconnect,
@@ -198,21 +199,21 @@ bool Game::startup(bool *kill,
{
// "cache"
- this->device = RenderingEngine::get_raw_device();
+ m_rendering_engine = rendering_engine;
+ device = m_rendering_engine->get_raw_device();
this->kill = kill;
this->error_message = &error_message;
- this->reconnect_requested = reconnect;
+ reconnect_requested = reconnect;
this->input = input;
this->chat_backend = chat_backend;
- this->simple_singleplayer_mode = start_data.isSinglePlayer();
+ simple_singleplayer_mode = start_data.isSinglePlayer();
input->keycache.populate();
driver = device->getVideoDriver();
- smgr = RenderingEngine::get_scene_manager();
+ smgr = m_rendering_engine->get_scene_manager();
- RenderingEngine::get_scene_manager()->getParameters()->
- setAttribute(scene::OBJ_LOADER_IGNORE_MATERIAL_FILES, true);
+ smgr->getParameters()->setAttribute(scene::OBJ_LOADER_IGNORE_MATERIAL_FILES, true);
// Reinit runData
runData = GameRunData();
@@ -233,7 +234,7 @@ bool Game::startup(bool *kill,
if (!createClient(start_data))
return false;
- RenderingEngine::initialize(client, hud);
+ m_rendering_engine->initialize(client, hud);
return true;
}
@@ -250,7 +251,7 @@ void Game::run()
Profiler::GraphValues dummyvalues;
g_profiler->graphGet(dummyvalues);
- draw_times.last_time = RenderingEngine::get_timer_time();
+ draw_times.last_time = m_rendering_engine->get_timer_time();
set_light_table(g_settings->getFloat("display_gamma"));
@@ -262,12 +263,12 @@ void Game::run()
irr::core::dimension2d<u32> previous_screen_size(g_settings->getU16("screen_w"),
g_settings->getU16("screen_h"));
- while (RenderingEngine::run()
+ while (m_rendering_engine->run()
&& !(*kill || g_gamecallback->shutdown_requested
|| (server && server->isShutdownRequested()))) {
const irr::core::dimension2d<u32> &current_screen_size =
- RenderingEngine::get_video_driver()->getScreenSize();
+ m_rendering_engine->get_video_driver()->getScreenSize();
// Verify if window size has changed and save it if it's the case
// Ensure evaluating settings->getBool after verifying screensize
// First condition is cheaper
@@ -280,7 +281,7 @@ void Game::run()
}
// Calculate dtime =
- // RenderingEngine::run() from this iteration
+ // m_rendering_engine->run() from this iteration
// + Sleep time until the wanted FPS are reached
limitFps(&draw_times, &dtime);
@@ -329,7 +330,7 @@ void Game::run()
void Game::shutdown()
{
- RenderingEngine::finalize();
+ m_rendering_engine->finalize();
#if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR <= 8
if (g_settings->get("3d_mode") == "pageflip") {
driver->setRenderTarget(irr::video::ERT_STEREO_BOTH_BUFFERS);
@@ -488,7 +489,7 @@ bool Game::createClient(const GameStartData &start_data)
{
showOverlayMessage(N_("Creating client..."), 0, 10);
- draw_control = new MapDrawControl;
+ draw_control = new MapDrawControl();
if (!draw_control)
return false;
@@ -529,7 +530,7 @@ bool Game::createClient(const GameStartData &start_data)
/* Camera
*/
- camera = new Camera(*draw_control, client);
+ camera = new Camera(*draw_control, client, m_rendering_engine);
if (!camera->successfullyCreated(*error_message))
return false;
client->setCamera(camera);
@@ -541,7 +542,7 @@ bool Game::createClient(const GameStartData &start_data)
/* Skybox
*/
- sky = new Sky(-1, texture_src, shader_src);
+ sky = new Sky(-1, m_rendering_engine, texture_src, shader_src);
scsf->setSky(sky);
skybox = NULL; // This is used/set later on in the main run loop
@@ -563,16 +564,28 @@ bool Game::createClient(const GameStartData &start_data)
std::wstring str = utf8_to_wide(PROJECT_NAME_C);
str += L" ";
str += utf8_to_wide(g_version_hash);
+ {
+ const wchar_t *text = nullptr;
+ if (simple_singleplayer_mode)
+ text = wgettext("Singleplayer");
+ else
+ text = wgettext("Multiplayer");
+ str += L" [";
+ str += text;
+ str += L"]";
+ delete text;
+ }
str += L" [";
str += L"Minetest Hackclient";
str += L"]";
+
device->setWindowCaption(str.c_str());
LocalPlayer *player = client->getEnv().getLocalPlayer();
player->hurt_tilt_timer = 0;
player->hurt_tilt_strength = 0;
- hud = new Hud(guienv, client, player, &player->inventory);
+ hud = new Hud(client, player, &player->inventory);
mapper = client->getMinimap();
@@ -663,7 +676,7 @@ bool Game::connectToServer(const GameStartData &start_data,
start_data.password, start_data.address,
*draw_control, texture_src, shader_src,
itemdef_manager, nodedef_manager, sound, eventmgr,
- connect_address.isIPv6(), m_game_ui.get());
+ m_rendering_engine, connect_address.isIPv6(), m_game_ui.get());
client->m_simple_singleplayer_mode = simple_singleplayer_mode;
@@ -685,9 +698,9 @@ bool Game::connectToServer(const GameStartData &start_data,
f32 dtime;
f32 wait_time = 0; // in seconds
- fps_control.last_time = RenderingEngine::get_timer_time();
+ fps_control.last_time = m_rendering_engine->get_timer_time();
- while (RenderingEngine::run()) {
+ while (m_rendering_engine->run()) {
limitFps(&fps_control, &dtime);
@@ -724,7 +737,7 @@ bool Game::connectToServer(const GameStartData &start_data,
if (client->m_is_registration_confirmation_state) {
if (registration_confirmation_shown) {
// Keep drawing the GUI
- RenderingEngine::draw_menu_scene(guienv, dtime, true);
+ m_rendering_engine->draw_menu_scene(guienv, dtime, true);
} else {
registration_confirmation_shown = true;
(new GUIConfirmRegistration(guienv, guienv->getRootGUIElement(), -1,
@@ -734,7 +747,7 @@ bool Game::connectToServer(const GameStartData &start_data,
} else {
wait_time += dtime;
// Only time out if we aren't waiting for the server we started
- if (!start_data.local_server && !start_data.isSinglePlayer() && wait_time > 10) {
+ if (!start_data.address.empty() && wait_time > 10) {
*error_message = "Connection timed out.";
errorstream << *error_message << std::endl;
break;
@@ -760,9 +773,9 @@ bool Game::getServerContent(bool *aborted)
FpsControl fps_control = { 0 };
f32 dtime; // in seconds
- fps_control.last_time = RenderingEngine::get_timer_time();
+ fps_control.last_time = m_rendering_engine->get_timer_time();
- while (RenderingEngine::run()) {
+ while (m_rendering_engine->run()) {
limitFps(&fps_control, &dtime);
@@ -800,13 +813,13 @@ bool Game::getServerContent(bool *aborted)
if (!client->itemdefReceived()) {
const wchar_t *text = wgettext("Item definitions...");
progress = 25;
- RenderingEngine::draw_load_screen(text, guienv, texture_src,
+ m_rendering_engine->draw_load_screen(text, guienv, texture_src,
dtime, progress);
delete[] text;
} else if (!client->nodedefReceived()) {
const wchar_t *text = wgettext("Node definitions...");
progress = 30;
- RenderingEngine::draw_load_screen(text, guienv, texture_src,
+ m_rendering_engine->draw_load_screen(text, guienv, texture_src,
dtime, progress);
delete[] text;
} else {
@@ -833,7 +846,7 @@ bool Game::getServerContent(bool *aborted)
}
progress = 30 + client->mediaReceiveProgress() * 35 + 0.5;
- RenderingEngine::draw_load_screen(utf8_to_wide(message.str()), guienv,
+ m_rendering_engine->draw_load_screen(utf8_to_wide(message.str()), guienv,
texture_src, dtime, progress);
}
}
@@ -1150,6 +1163,8 @@ void Game::processKeyInput()
toggleCinematic();
} else if (wasKeyDown(KeyType::SCREENSHOT)) {
client->makeScreenshot();
+ } else if (wasKeyDown(KeyType::TOGGLE_BLOCK_BOUNDS)) {
+ hud->toggleBlockBounds();
} else if (wasKeyDown(KeyType::TOGGLE_HUD)) {
m_game_ui->toggleHud();
} else if (wasKeyDown(KeyType::MINIMAP)) {
@@ -1264,8 +1279,8 @@ void Game::openInventory()
|| !client->getScript()->on_inventory_open(fs_src->m_client->getInventory(inventoryloc))) {
TextDest *txt_dst = new TextDestPlayerInventory(client);
auto *&formspec = m_game_ui->updateFormspec("");
- GUIFormSpecMenu::create(formspec, client, &input->joystick, fs_src,
- txt_dst, client->getFormspecPrepend(), sound);
+ GUIFormSpecMenu::create(formspec, client, m_rendering_engine->get_gui_env(),
+ &input->joystick, fs_src, txt_dst, client->getFormspecPrepend(), sound);
formspec->setFormSpec(fs_src->getForm(), inventoryloc);
}
@@ -1838,14 +1853,18 @@ void Game::handleClientEvent_PlayerDamage(ClientEvent *event, CameraOrientation
// Damage flash and hurt tilt are not used at death
if (client->getHP() > 0) {
- runData.damage_flash += 95.0f + 3.2f * event->player_damage.amount;
- runData.damage_flash = MYMIN(runData.damage_flash, 127.0f);
-
LocalPlayer *player = client->getEnv().getLocalPlayer();
+ f32 hp_max = player->getCAO() ?
+ player->getCAO()->getProperties()->hp_max : PLAYER_MAX_HP_DEFAULT;
+ f32 damage_ratio = event->player_damage.amount / hp_max;
+
+ runData.damage_flash += 95.0f + 64.f * damage_ratio;
+ runData.damage_flash = MYMIN(runData.damage_flash, 127.0f);
+
player->hurt_tilt_timer = 1.5f;
player->hurt_tilt_strength =
- rangelim(event->player_damage.amount / 4.0f, 1.0f, 4.0f);
+ rangelim(damage_ratio * 5.0f, 1.0f, 4.0f);
}
// Play damage sound
@@ -1889,8 +1908,8 @@ void Game::handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation
new TextDestPlayerInventory(client, *(event->show_formspec.formname));
auto *&formspec = m_game_ui->updateFormspec(*(event->show_formspec.formname));
- GUIFormSpecMenu::create(formspec, client, &input->joystick,
- fs_src, txt_dst, client->getFormspecPrepend(), sound);
+ GUIFormSpecMenu::create(formspec, client, m_rendering_engine->get_gui_env(),
+ &input->joystick, fs_src, txt_dst, client->getFormspecPrepend(), sound);
}
delete event->show_formspec.formspec;
@@ -1909,7 +1928,7 @@ void Game::handleClientEvent_ShowLocalFormSpec(ClientEvent *event, CameraOrienta
FormspecFormSource *fs_src = new FormspecFormSource(*event->show_formspec.formspec);
LocalFormspecHandler *txt_dst =
new LocalFormspecHandler(*event->show_formspec.formname, client);
- GUIFormSpecMenu::create(m_game_ui->getFormspecGUI(), client, &input->joystick,
+ GUIFormSpecMenu::create(m_game_ui->getFormspecGUI(), client, m_rendering_engine->get_gui_env(), &input->joystick,
fs_src, txt_dst, client->getFormspecPrepend(), sound);
}
@@ -2075,6 +2094,7 @@ void Game::handleClientEvent_SetSky(ClientEvent *event, CameraOrientation *cam)
"custom"
);
}
+
delete event->set_sky;
}
@@ -2607,8 +2627,8 @@ bool Game::nodePlacement(const ItemDefinition &selected_def,
TextDest *txt_dst = new TextDestNodeMetadata(nodepos, client);
auto *&formspec = m_game_ui->updateFormspec("");
- GUIFormSpecMenu::create(formspec, client, &input->joystick, fs_src,
- txt_dst, client->getFormspecPrepend(), sound);
+ GUIFormSpecMenu::create(formspec, client, m_rendering_engine->get_gui_env(),
+ &input->joystick, fs_src, txt_dst, client->getFormspecPrepend(), sound);
formspec->setFormSpec(meta->getString("formspec"), inventoryloc);
return false;
@@ -3170,7 +3190,7 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
} catch (SettingNotFoundException) {
}
#endif
- RenderingEngine::draw_scene(skycolor, m_game_ui->m_flags.show_hud,
+ m_rendering_engine->draw_scene(skycolor, m_game_ui->m_flags.show_hud,
m_game_ui->m_flags.show_minimap, draw_wield_tool, draw_crosshair);
/*
@@ -3309,7 +3329,7 @@ inline void Game::limitFps(FpsControl *fps_timings, f32 *dtime)
void Game::showOverlayMessage(const char *msg, float dtime, int percent, bool draw_clouds)
{
const wchar_t *wmsg = wgettext(msg);
- RenderingEngine::draw_load_screen(wmsg, guienv, texture_src, dtime, percent,
+ m_rendering_engine->draw_load_screen(wmsg, guienv, texture_src, dtime, percent,
draw_clouds);
delete[] wmsg;
}
@@ -3392,27 +3412,6 @@ bool Game::wasKeyReleased(GameKeyType k)
****************************************************************************/
/****************************************************************************/
-void Game::extendedResourceCleanup()
-{
- // Extended resource accounting
- infostream << "Irrlicht resources after cleanup:" << std::endl;
- infostream << "\tRemaining meshes : "
- << RenderingEngine::get_mesh_cache()->getMeshCount() << std::endl;
- infostream << "\tRemaining textures : "
- << driver->getTextureCount() << std::endl;
-
- for (unsigned int i = 0; i < driver->getTextureCount(); i++) {
- irr::video::ITexture *texture = driver->getTextureByIndex(i);
- infostream << "\t\t" << i << ":" << texture->getName().getPath().c_str()
- << std::endl;
- }
-
- clearTextureNameCache();
- infostream << "\tRemaining materials: "
- << driver-> getMaterialRendererCount()
- << " (note: irrlicht doesn't support removing renderers)" << std::endl;
-}
-
void Game::showDeathFormspec()
{
static std::string formspec_str =
@@ -3430,8 +3429,8 @@ void Game::showDeathFormspec()
LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_DEATH_SCREEN", client);
auto *&formspec = m_game_ui->getFormspecGUI();
- GUIFormSpecMenu::create(formspec, client, &input->joystick,
- fs_src, txt_dst, client->getFormspecPrepend(), sound);
+ GUIFormSpecMenu::create(formspec, client, m_rendering_engine->get_gui_env(),
+ &input->joystick, fs_src, txt_dst, client->getFormspecPrepend(), sound);
formspec->setFocus("btn_respawn");
}
@@ -3572,8 +3571,8 @@ void Game::showPauseMenu()
LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_PAUSE_MENU");
auto *&formspec = m_game_ui->getFormspecGUI();
- GUIFormSpecMenu::create(formspec, client, &input->joystick,
- fs_src, txt_dst, client->getFormspecPrepend(), sound);
+ GUIFormSpecMenu::create(formspec, client, m_rendering_engine->get_gui_env(),
+ &input->joystick, fs_src, txt_dst, client->getFormspecPrepend(), sound);
formspec->setFocus("btn_continue");
formspec->doPause = true;
@@ -3591,6 +3590,7 @@ Game *g_game;
void the_game(bool *kill,
InputHandler *input,
+ RenderingEngine *rendering_engine,
const GameStartData &start_data,
std::string &error_message,
ChatBackend &chat_backend,
@@ -3607,8 +3607,8 @@ void the_game(bool *kill,
try {
- if (game.startup(kill, input, start_data, error_message,
- reconnect_requested, &chat_backend)) {
+ if (game.startup(kill, input, rendering_engine, start_data,
+ error_message, reconnect_requested, &chat_backend)) {
game.run();
}
diff --git a/src/client/game.h b/src/client/game.h
index 4a5b829d5..8197b9a9b 100644
--- a/src/client/game.h
+++ b/src/client/game.h
@@ -76,7 +76,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <string>
class InputHandler;
-class ChatBackend; /* to avoid having to include chat.h */
+class ChatBackend;
+class RenderingEngine;
struct SubgameSpec;
struct GameStartData;
@@ -417,12 +418,7 @@ public:
};
-// before 1.8 there isn't a "integer interface", only float
-#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
-typedef f32 SamplerLayer_t;
-#else
typedef s32 SamplerLayer_t;
-#endif
class GameGlobalShaderConstantSetter : public IShaderConstantSetter
@@ -530,38 +526,20 @@ public:
float eye_position_array[3];
v3f epos = m_client->getEnv().getLocalPlayer()->getEyePosition();
-#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
- eye_position_array[0] = epos.X;
- eye_position_array[1] = epos.Y;
- eye_position_array[2] = epos.Z;
-#else
epos.getAs3Values(eye_position_array);
-#endif
m_eye_position_pixel.set(eye_position_array, services);
m_eye_position_vertex.set(eye_position_array, services);
if (m_client->getMinimap()) {
float minimap_yaw_array[3];
v3f minimap_yaw = m_client->getMinimap()->getYawVec();
-#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
- minimap_yaw_array[0] = minimap_yaw.X;
- minimap_yaw_array[1] = minimap_yaw.Y;
- minimap_yaw_array[2] = minimap_yaw.Z;
-#else
minimap_yaw.getAs3Values(minimap_yaw_array);
-#endif
m_minimap_yaw.set(minimap_yaw_array, services);
}
float camera_offset_array[3];
v3f offset = intToFloat(m_client->getCamera()->getOffset(), BS);
-#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
- camera_offset_array[0] = offset.X;
- camera_offset_array[1] = offset.Y;
- camera_offset_array[2] = offset.Z;
-#else
offset.getAs3Values(camera_offset_array);
-#endif
m_camera_offset_pixel.set(camera_offset_array, services);
m_camera_offset_vertex.set(camera_offset_array, services);
@@ -673,6 +651,7 @@ public:
bool startup(bool *kill,
InputHandler *input,
+ RenderingEngine *rendering_engine,
const GameStartData &game_params,
std::string &error_message,
bool *reconnect,
@@ -682,8 +661,6 @@ public:
void run();
void shutdown();
- void extendedResourceCleanup();
-
// Basic initialisation
bool init(const std::string &map_dir, const std::string &address,
u16 port, const SubgameSpec &gamespec);
@@ -881,6 +858,7 @@ public:
these items (e.g. device)
*/
IrrlichtDevice *device;
+ RenderingEngine *m_rendering_engine;
video::IVideoDriver *driver;
scene::ISceneManager *smgr;
bool *kill;
@@ -936,6 +914,7 @@ extern Game *g_game;
void the_game(bool *kill,
InputHandler *input,
+ RenderingEngine *rendering_engine,
const GameStartData &start_data,
std::string &error_message,
ChatBackend &chat_backend,
diff --git a/src/client/gameui.cpp b/src/client/gameui.cpp
index 0c1da3915..c97ae93b8 100644
--- a/src/client/gameui.cpp
+++ b/src/client/gameui.cpp
@@ -55,7 +55,7 @@ void GameUI::init()
{
m_guitext_coords = gui::StaticText::add(guienv, L"", core::rect<s32>(0, 0, 0, 0), false,
false, guiroot);
-
+
// First line of debug text
m_guitext = gui::StaticText::add(guienv, utf8_to_wide(PROJECT_NAME_C).c_str(),
core::rect<s32>(0, 0, 0, 0), false, false, guiroot);
@@ -102,7 +102,8 @@ void GameUI::update(const RunStats &stats, Client *client, MapDrawControl *draw_
{
LocalPlayer *player = client->getEnv().getLocalPlayer();
v3f player_position = player->getPosition();
- v2u32 screensize = RenderingEngine::get_instance()->getWindowSize();
+
+ v2u32 screensize = RenderingEngine::getWindowSize();
bool show_coords = g_settings->getBool("coords");
@@ -115,7 +116,7 @@ void GameUI::update(const RunStats &stats, Client *client, MapDrawControl *draw_
setStaticText(m_guitext_coords, utf8_to_wide(os.str()).c_str());
m_guitext_coords->setRelativePosition(core::rect<s32>(5, screensize.Y - 5 - g_fontengine->getTextHeight(), screensize.X, screensize.Y));
}
-
+
m_guitext_coords->setVisible(show_coords);
if (m_flags.show_debug) {
@@ -238,9 +239,9 @@ void GameUI::setChatText(const EnrichedString &chat_text, u32 recent_chat_count)
{
// Update gui element size and position
-
- const v2u32 &window_size = RenderingEngine::get_instance()->getWindowSize();
-
+
+ const v2u32 &window_size = RenderingEngine::getWindowSize();
+
s32 chat_y = window_size.Y - 150 - m_guitext_chat->getTextHeight();
if (m_flags.show_debug)
@@ -276,7 +277,7 @@ void GameUI::updateProfiler()
core::position2di upper_left(6, 50);
core::position2di lower_right = upper_left;
lower_right.X += size.Width + 10;
- lower_right.Y += size.Height;
+ lower_right.Y += size.Height;
m_guitext_profiler->setRelativePosition(core::rect<s32>(upper_left, lower_right));
}
diff --git a/src/client/guiscalingfilter.cpp b/src/client/guiscalingfilter.cpp
index 8c565a52f..232219237 100644
--- a/src/client/guiscalingfilter.cpp
+++ b/src/client/guiscalingfilter.cpp
@@ -23,7 +23,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "util/numeric.h"
#include <cstdio>
#include "client/renderingengine.h"
-#include "client/tile.h" // hasNPotSupport()
/* Maintain a static cache to store the images that correspond to textures
* in a format that's manipulable by code. Some platforms exhibit issues
@@ -102,7 +101,7 @@ video::ITexture *guiScalingResizeCached(video::IVideoDriver *driver,
if (!g_settings->getBool("gui_scaling_filter_txr2img"))
return src;
srcimg = driver->createImageFromData(src->getColorFormat(),
- src->getSize(), src->lock(), false);
+ src->getSize(), src->lock(video::ETLM_READ_ONLY), false);
src->unlock();
g_imgCache[origname] = srcimg;
}
@@ -117,7 +116,7 @@ video::ITexture *guiScalingResizeCached(video::IVideoDriver *driver,
#if ENABLE_GLES
// Some platforms are picky about textures being powers of 2, so expand
// the image dimensions to the next power of 2, if necessary.
- if (!hasNPotSupport()) {
+ if (!driver->queryFeature(video::EVDF_TEXTURE_NPOT)) {
video::IImage *po2img = driver->createImage(src->getColorFormat(),
core::dimension2d<u32>(npot2((u32)destrect.getWidth()),
npot2((u32)destrect.getHeight())));
diff --git a/src/client/hud.cpp b/src/client/hud.cpp
index 5971948fd..391af0995 100644
--- a/src/client/hud.cpp
+++ b/src/client/hud.cpp
@@ -45,11 +45,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define OBJECT_CROSSHAIR_LINE_SIZE 8
#define CROSSHAIR_LINE_SIZE 10
-Hud::Hud(gui::IGUIEnvironment *guienv, Client *client, LocalPlayer *player,
+Hud::Hud(Client *client, LocalPlayer *player,
Inventory *inventory)
{
driver = RenderingEngine::get_video_driver();
- this->guienv = guienv;
this->client = client;
this->player = player;
this->inventory = inventory;
@@ -315,7 +314,7 @@ bool Hud::calculateScreenPos(const v3s16 &camera_offset, HudElement *e, v2s32 *p
{
v3f w_pos = e->world_pos * BS;
scene::ICameraSceneNode* camera =
- RenderingEngine::get_scene_manager()->getActiveCamera();
+ client->getSceneManager()->getActiveCamera();
w_pos -= intToFloat(camera_offset, BS);
core::matrix4 trans = camera->getProjectionMatrix();
trans *= camera->getViewMatrix();
@@ -336,22 +335,22 @@ void Hud::drawLuaElements(const v3s16 &camera_offset)
irr::gui::IGUIFont* font = g_fontengine->getFont();
// Reorder elements by z_index
- std::vector<size_t> ids;
+ std::vector<HudElement*> elems;
+ elems.reserve(player->maxHudId());
for (size_t i = 0; i != player->maxHudId(); i++) {
HudElement *e = player->getHud(i);
if (!e)
continue;
- auto it = ids.begin();
- while (it != ids.end() && player->getHud(*it)->z_index <= e->z_index)
+ auto it = elems.begin();
+ while (it != elems.end() && (*it)->z_index <= e->z_index)
++it;
- ids.insert(it, i);
+ elems.insert(it, e);
}
- for (size_t i : ids) {
- HudElement *e = player->getHud(i);
+ for (HudElement *e : elems) {
v2s32 pos(floor(e->pos.X * (float) m_screensize.X + 0.5),
floor(e->pos.Y * (float) m_screensize.Y + 0.5));
@@ -475,7 +474,7 @@ void Hud::drawLuaElements(const v3s16 &camera_offset)
// Angle according to camera view
v3f fore(0.f, 0.f, 1.f);
- scene::ICameraSceneNode *cam = RenderingEngine::get_scene_manager()->getActiveCamera();
+ scene::ICameraSceneNode *cam = client->getSceneManager()->getActiveCamera();
cam->getAbsoluteTransformation().rotateVect(fore);
int angle = - fore.getHorizontalAngle().Y;
@@ -522,8 +521,8 @@ void Hud::drawLuaElements(const v3s16 &camera_offset)
client->getMinimap()->drawMinimap(rect);
break; }
default:
- infostream << "Hud::drawLuaElements: ignoring drawform " << e->type <<
- " of hud element ID " << i << " due to unrecognized type" << std::endl;
+ infostream << "Hud::drawLuaElements: ignoring drawform " << e->type
+ << " due to unrecognized type" << std::endl;
}
}
}
@@ -747,7 +746,7 @@ void Hud::drawHotbar(u16 playeritem) {
s32 width = hotbar_itemcount * (m_hotbar_imagesize + m_padding * 2);
v2s32 pos = centerlowerpos - v2s32(width / 2, m_hotbar_imagesize + m_padding * 3);
- const v2u32 &window_size = RenderingEngine::get_instance()->getWindowSize();
+ const v2u32 &window_size = RenderingEngine::getWindowSize();
if ((float) width / (float) window_size.X <=
g_settings->getFloat("hud_hotbar_max_width")) {
if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) {
@@ -862,6 +861,54 @@ void Hud::drawSelectionMesh()
}
}
+void Hud::toggleBlockBounds()
+{
+ m_block_bounds_mode = static_cast<BlockBoundsMode>(m_block_bounds_mode + 1);
+
+ if (m_block_bounds_mode >= BLOCK_BOUNDS_MAX) {
+ m_block_bounds_mode = BLOCK_BOUNDS_OFF;
+ }
+}
+
+void Hud::drawBlockBounds()
+{
+ if (m_block_bounds_mode == BLOCK_BOUNDS_OFF) {
+ return;
+ }
+
+ video::SMaterial old_material = driver->getMaterial2D();
+ driver->setMaterial(m_selection_material);
+
+ v3s16 pos = player->getStandingNodePos();
+
+ v3s16 blockPos(
+ floorf((float) pos.X / MAP_BLOCKSIZE),
+ floorf((float) pos.Y / MAP_BLOCKSIZE),
+ floorf((float) pos.Z / MAP_BLOCKSIZE)
+ );
+
+ v3f offset = intToFloat(client->getCamera()->getOffset(), BS);
+
+ s8 radius = m_block_bounds_mode == BLOCK_BOUNDS_ALL ? 2 : 0;
+
+ v3f halfNode = v3f(BS, BS, BS) / 2.0f;
+
+ for (s8 x = -radius; x <= radius; x++)
+ for (s8 y = -radius; y <= radius; y++)
+ for (s8 z = -radius; z <= radius; z++) {
+ v3s16 blockOffset(x, y, z);
+
+ aabb3f box(
+ intToFloat((blockPos + blockOffset) * MAP_BLOCKSIZE, BS) - offset - halfNode,
+ intToFloat(((blockPos + blockOffset) * MAP_BLOCKSIZE) + (MAP_BLOCKSIZE - 1), BS) - offset + halfNode
+ );
+
+ driver->draw3DBox(box, video::SColor(255, 255, 0, 0));
+ }
+
+ driver->setMaterial(old_material);
+}
+
void Hud::updateSelectionMesh(const v3s16 &camera_offset)
{
m_camera_offset = camera_offset;
@@ -908,7 +955,7 @@ void Hud::updateSelectionMesh(const v3s16 &camera_offset)
}
void Hud::resizeHotbar() {
- const v2u32 &window_size = RenderingEngine::get_instance()->getWindowSize();
+ const v2u32 &window_size = RenderingEngine::getWindowSize();
if (m_screensize != window_size) {
m_hotbar_imagesize = floor(HOTBAR_IMAGE_SIZE *
@@ -945,10 +992,18 @@ void drawItemStack(
return;
}
+ const static thread_local bool enable_animations =
+ g_settings->getBool("inventory_items_animations");
+
const ItemDefinition &def = item.getDefinition(client->idef());
- ItemMesh *imesh = client->idef()->getWieldMesh(def.name, client);
- if (imesh && imesh->mesh) {
+ bool draw_overlay = false;
+
+ // Render as mesh if animated or no inventory image
+ if ((enable_animations && rotation_kind < IT_ROT_NONE) || def.inventory_image.empty()) {
+ ItemMesh *imesh = client->idef()->getWieldMesh(def.name, client);
+ if (!imesh || !imesh->mesh)
+ return;
scene::IMesh *mesh = imesh->mesh;
driver->clearBuffers(video::ECBF_DEPTH);
s32 delta = 0;
@@ -992,9 +1047,6 @@ void drawItemStack(
core::matrix4 matrix;
matrix.makeIdentity();
- static thread_local bool enable_animations =
- g_settings->getBool("inventory_items_animations");
-
if (enable_animations) {
float timer_f = (float) delta / 5000.f;
matrix.setRotationDegrees(v3f(
@@ -1040,15 +1092,29 @@ void drawItemStack(
driver->setTransform(video::ETS_PROJECTION, oldProjMat);
driver->setViewPort(oldViewPort);
- // draw the inventory_overlay
- if (def.type == ITEM_NODE && def.inventory_image.empty() &&
- !def.inventory_overlay.empty()) {
- ITextureSource *tsrc = client->getTextureSource();
- video::ITexture *overlay_texture = tsrc->getTexture(def.inventory_overlay);
- core::dimension2d<u32> dimens = overlay_texture->getOriginalSize();
- core::rect<s32> srcrect(0, 0, dimens.Width, dimens.Height);
- draw2DImageFilterScaled(driver, overlay_texture, rect, srcrect, clip, 0, true);
- }
+ draw_overlay = def.type == ITEM_NODE && def.inventory_image.empty();
+ } else { // Otherwise just draw as 2D
+ video::ITexture *texture = client->idef()->getInventoryTexture(def.name, client);
+ if (!texture)
+ return;
+ video::SColor color =
+ client->idef()->getItemstackColor(item, client);
+ const video::SColor colors[] = { color, color, color, color };
+
+ draw2DImageFilterScaled(driver, texture, rect,
+ core::rect<s32>({0, 0}, core::dimension2di(texture->getOriginalSize())),
+ clip, colors, true);
+
+ draw_overlay = true;
+ }
+
+ // draw the inventory_overlay
+ if (!def.inventory_overlay.empty() && draw_overlay) {
+ ITextureSource *tsrc = client->getTextureSource();
+ video::ITexture *overlay_texture = tsrc->getTexture(def.inventory_overlay);
+ core::dimension2d<u32> dimens = overlay_texture->getOriginalSize();
+ core::rect<s32> srcrect(0, 0, dimens.Width, dimens.Height);
+ draw2DImageFilterScaled(driver, overlay_texture, rect, srcrect, clip, 0, true);
}
if (def.type == ITEM_TOOL && item.wear != 0) {
diff --git a/src/client/hud.h b/src/client/hud.h
index d46545d71..d341105d2 100644
--- a/src/client/hud.h
+++ b/src/client/hud.h
@@ -35,14 +35,6 @@ struct ItemStack;
class Hud
{
public:
- video::IVideoDriver *driver;
- scene::ISceneManager *smgr;
- gui::IGUIEnvironment *guienv;
- Client *client;
- LocalPlayer *player;
- Inventory *inventory;
- ITextureSource *tsrc;
-
video::SColor crosshair_argb;
video::SColor selectionbox_argb;
@@ -55,10 +47,13 @@ public:
bool pointing_at_object = false;
- Hud(gui::IGUIEnvironment *guienv, Client *client, LocalPlayer *player,
+ Hud(Client *client, LocalPlayer *player,
Inventory *inventory);
~Hud();
+ void toggleBlockBounds();
+ void drawBlockBounds();
+
void drawHotbar(u16 playeritem);
void resizeHotbar();
void drawCrosshair();
@@ -103,6 +98,12 @@ private:
void drawCompassRotate(HudElement *e, video::ITexture *texture,
const core::rect<s32> &rect, int way);
+ Client *client = nullptr;
+ video::IVideoDriver *driver = nullptr;
+ LocalPlayer *player = nullptr;
+ Inventory *inventory = nullptr;
+ ITextureSource *tsrc = nullptr;
+
float m_hud_scaling; // cached minetest setting
float m_scale_factor;
v3s16 m_camera_offset;
@@ -125,6 +126,14 @@ private:
scene::SMeshBuffer m_rotation_mesh_buffer;
+ enum BlockBoundsMode
+ {
+ BLOCK_BOUNDS_OFF,
+ BLOCK_BOUNDS_CURRENT,
+ BLOCK_BOUNDS_ALL,
+ BLOCK_BOUNDS_MAX
+ } m_block_bounds_mode = BLOCK_BOUNDS_OFF;
+
enum
{
HIGHLIGHT_BOX,
diff --git a/src/client/imagefilters.cpp b/src/client/imagefilters.cpp
index 0fa501410..7b2ef9822 100644
--- a/src/client/imagefilters.cpp
+++ b/src/client/imagefilters.cpp
@@ -19,63 +19,134 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "imagefilters.h"
#include "util/numeric.h"
#include <cmath>
+#include <cassert>
+#include <vector>
+
+// Simple 2D bitmap class with just the functionality needed here
+class Bitmap {
+ u32 linesize, lines;
+ std::vector<u8> data;
+
+ static inline u32 bytepos(u32 index) { return index >> 3; }
+ static inline u8 bitpos(u32 index) { return index & 7; }
+
+public:
+ Bitmap(u32 width, u32 height) : linesize(width), lines(height),
+ data(bytepos(width * height) + 1) {}
+
+ inline bool get(u32 x, u32 y) const {
+ u32 index = y * linesize + x;
+ return data[bytepos(index)] & (1 << bitpos(index));
+ }
+
+ inline void set(u32 x, u32 y) {
+ u32 index = y * linesize + x;
+ data[bytepos(index)] |= 1 << bitpos(index);
+ }
+
+ inline bool all() const {
+ for (u32 i = 0; i < data.size() - 1; i++) {
+ if (data[i] != 0xff)
+ return false;
+ }
+ // last byte not entirely filled
+ for (u8 i = 0; i < bitpos(linesize * lines); i++) {
+ bool value_of_bit = data.back() & (1 << i);
+ if (!value_of_bit)
+ return false;
+ }
+ return true;
+ }
+
+ inline void copy(Bitmap &to) const {
+ assert(to.linesize == linesize && to.lines == lines);
+ to.data = data;
+ }
+};
/* Fill in RGB values for transparent pixels, to correct for odd colors
* appearing at borders when blending. This is because many PNG optimizers
* like to discard RGB values of transparent pixels, but when blending then
- * with non-transparent neighbors, their RGB values will shpw up nonetheless.
+ * with non-transparent neighbors, their RGB values will show up nonetheless.
*
* This function modifies the original image in-place.
*
* Parameter "threshold" is the alpha level below which pixels are considered
- * transparent. Should be 127 for 3d where alpha is threshold, but 0 for
- * 2d where alpha is blended.
+ * transparent. Should be 127 when the texture is used with ALPHA_CHANNEL_REF,
+ * 0 when alpha blending is used.
*/
void imageCleanTransparent(video::IImage *src, u32 threshold)
{
core::dimension2d<u32> dim = src->getDimension();
- // Walk each pixel looking for fully transparent ones.
+ Bitmap bitmap(dim.Width, dim.Height);
+
+ // First pass: Mark all opaque pixels
// Note: loop y around x for better cache locality.
for (u32 ctry = 0; ctry < dim.Height; ctry++)
for (u32 ctrx = 0; ctrx < dim.Width; ctrx++) {
+ if (src->getPixel(ctrx, ctry).getAlpha() > threshold)
+ bitmap.set(ctrx, ctry);
+ }
+
+ // Exit early if all pixels opaque
+ if (bitmap.all())
+ return;
+
+ Bitmap newmap = bitmap;
+
+ // Then repeatedly look for transparent pixels, filling them in until
+ // we're finished (capped at 50 iterations).
+ for (u32 iter = 0; iter < 50; iter++) {
- // Ignore opaque pixels.
- irr::video::SColor c = src->getPixel(ctrx, ctry);
- if (c.getAlpha() > threshold)
+ for (u32 ctry = 0; ctry < dim.Height; ctry++)
+ for (u32 ctrx = 0; ctrx < dim.Width; ctrx++) {
+ // Skip pixels we have already processed
+ if (bitmap.get(ctrx, ctry))
continue;
- // Sample size and total weighted r, g, b values.
+ video::SColor c = src->getPixel(ctrx, ctry);
+
+ // Sample size and total weighted r, g, b values
u32 ss = 0, sr = 0, sg = 0, sb = 0;
- // Walk each neighbor pixel (clipped to image bounds).
+ // Walk each neighbor pixel (clipped to image bounds)
for (u32 sy = (ctry < 1) ? 0 : (ctry - 1);
sy <= (ctry + 1) && sy < dim.Height; sy++)
for (u32 sx = (ctrx < 1) ? 0 : (ctrx - 1);
sx <= (ctrx + 1) && sx < dim.Width; sx++) {
-
- // Ignore transparent pixels.
- irr::video::SColor d = src->getPixel(sx, sy);
- if (d.getAlpha() <= threshold)
+ // Ignore pixels we haven't processed
+ if (!bitmap.get(sx, sy))
continue;
-
- // Add RGB values weighted by alpha.
- u32 a = d.getAlpha();
+
+ // Add RGB values weighted by alpha IF the pixel is opaque, otherwise
+ // use full weight since we want to propagate colors.
+ video::SColor d = src->getPixel(sx, sy);
+ u32 a = d.getAlpha() <= threshold ? 255 : d.getAlpha();
ss += a;
sr += a * d.getRed();
sg += a * d.getGreen();
sb += a * d.getBlue();
}
- // If we found any neighbor RGB data, set pixel to average
- // weighted by alpha.
+ // Set pixel to average weighted by alpha
if (ss > 0) {
c.setRed(sr / ss);
c.setGreen(sg / ss);
c.setBlue(sb / ss);
src->setPixel(ctrx, ctry, c);
+ newmap.set(ctrx, ctry);
}
}
+
+ if (newmap.all())
+ return;
+
+ // Apply changes to bitmap for next run. This is done so we don't introduce
+ // a bias in color propagation in the direction pixels are processed.
+ newmap.copy(bitmap);
+
+ }
}
/* Scale a region of an image into another image, using nearest-neighbor with
diff --git a/src/client/imagefilters.h b/src/client/imagefilters.h
index 5676faf85..c9bdefbb6 100644
--- a/src/client/imagefilters.h
+++ b/src/client/imagefilters.h
@@ -23,13 +23,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
/* Fill in RGB values for transparent pixels, to correct for odd colors
* appearing at borders when blending. This is because many PNG optimizers
* like to discard RGB values of transparent pixels, but when blending then
- * with non-transparent neighbors, their RGB values will shpw up nonetheless.
+ * with non-transparent neighbors, their RGB values will show up nonetheless.
*
* This function modifies the original image in-place.
*
* Parameter "threshold" is the alpha level below which pixels are considered
- * transparent. Should be 127 for 3d where alpha is threshold, but 0 for
- * 2d where alpha is blended.
+ * transparent. Should be 127 when the texture is used with ALPHA_CHANNEL_REF,
+ * 0 when alpha blending is used.
*/
void imageCleanTransparent(video::IImage *src, u32 threshold);
diff --git a/src/client/inputhandler.cpp b/src/client/inputhandler.cpp
index 8b9cb64f5..d833db2f1 100644
--- a/src/client/inputhandler.cpp
+++ b/src/client/inputhandler.cpp
@@ -61,6 +61,7 @@ void KeyCache::populate()
key[KeyType::DEC_VOLUME] = getKeySetting("keymap_decrease_volume");
key[KeyType::CINEMATIC] = getKeySetting("keymap_cinematic");
key[KeyType::SCREENSHOT] = getKeySetting("keymap_screenshot");
+ key[KeyType::TOGGLE_BLOCK_BOUNDS] = getKeySetting("keymap_toggle_block_bounds");
key[KeyType::TOGGLE_HUD] = getKeySetting("keymap_toggle_hud");
key[KeyType::TOGGLE_CHAT] = getKeySetting("keymap_toggle_chat");
key[KeyType::TOGGLE_FOG] = getKeySetting("keymap_toggle_fog");
diff --git a/src/client/keycode.cpp b/src/client/keycode.cpp
index ce5214f54..fac077f0f 100644
--- a/src/client/keycode.cpp
+++ b/src/client/keycode.cpp
@@ -197,7 +197,6 @@ static const struct table_key table[] = {
DEFINEKEY1(KEY_MODECHANGE, N_("IME Mode Change"))
DEFINEKEY1(KEY_APPS, N_("Apps"))
DEFINEKEY1(KEY_SLEEP, N_("Sleep"))
-#if !(IRRLICHT_VERSION_MAJOR <= 1 && IRRLICHT_VERSION_MINOR <= 7 && IRRLICHT_VERSION_REVISION < 3)
DEFINEKEY1(KEY_OEM_1, "OEM 1") // KEY_OEM_[0-9] and KEY_OEM_102 are assigned to multiple
DEFINEKEY1(KEY_OEM_2, "OEM 2") // different chars (on different platforms too) and thus w/o char
DEFINEKEY1(KEY_OEM_3, "OEM 3")
@@ -208,7 +207,6 @@ static const struct table_key table[] = {
DEFINEKEY1(KEY_OEM_8, "OEM 8")
DEFINEKEY1(KEY_OEM_AX, "OEM AX")
DEFINEKEY1(KEY_OEM_102, "OEM 102")
-#endif
DEFINEKEY1(KEY_ATTN, "Attn")
DEFINEKEY1(KEY_CRSEL, "CrSel")
DEFINEKEY1(KEY_EXSEL, "ExSel")
diff --git a/src/client/keys.h b/src/client/keys.h
index 1be398ff3..b81b571b2 100644
--- a/src/client/keys.h
+++ b/src/client/keys.h
@@ -60,6 +60,7 @@ public:
DEC_VOLUME,
CINEMATIC,
SCREENSHOT,
+ TOGGLE_BLOCK_BOUNDS,
TOGGLE_HUD,
TOGGLE_CHAT,
TOGGLE_FOG,
diff --git a/src/client/mapblock_mesh.cpp b/src/client/mapblock_mesh.cpp
index 25f734f0e..8877e0549 100644
--- a/src/client/mapblock_mesh.cpp
+++ b/src/client/mapblock_mesh.cpp
@@ -1140,8 +1140,8 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
*/
{
- MapblockMeshGenerator generator(data, &collector);
- generator.generate();
+ MapblockMeshGenerator(data, &collector,
+ data->m_client->getSceneManager()->getMeshManipulator()).generate();
}
/*
diff --git a/src/client/mesh.cpp b/src/client/mesh.cpp
index 2400a374c..e43139218 100644
--- a/src/client/mesh.cpp
+++ b/src/client/mesh.cpp
@@ -27,14 +27,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <SAnimatedMesh.h>
#include <IAnimatedMeshSceneNode.h>
-// In Irrlicht 1.8 the signature of ITexture::lock was changed from
-// (bool, u32) to (E_TEXTURE_LOCK_MODE, u32).
-#if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR <= 7
-#define MY_ETLM_READ_ONLY true
-#else
-#define MY_ETLM_READ_ONLY video::ETLM_READ_ONLY
-#endif
-
inline static void applyShadeFactor(video::SColor& color, float factor)
{
color.setRed(core::clamp(core::round32(color.getRed()*factor), 0, 255));
diff --git a/src/client/minimap.cpp b/src/client/minimap.cpp
index 165fa80bd..3013e1406 100644
--- a/src/client/minimap.cpp
+++ b/src/client/minimap.cpp
@@ -491,7 +491,8 @@ video::ITexture *Minimap::getMinimapTexture()
// Want to use texture source, to : 1 find texture, 2 cache it
video::ITexture* texture = m_tsrc->getTexture(data->mode.texture);
video::IImage* image = driver->createImageFromData(
- texture->getColorFormat(), texture->getSize(), texture->lock(), true, false);
+ texture->getColorFormat(), texture->getSize(),
+ texture->lock(video::ETLM_READ_ONLY), true, false);
texture->unlock();
auto dim = image->getDimension();
@@ -576,7 +577,7 @@ scene::SMeshBuffer *Minimap::getMinimapMeshBuffer()
void Minimap::drawMinimap()
{
// Non hud managed minimap drawing (legacy minimap)
- v2u32 screensize = RenderingEngine::get_instance()->getWindowSize();
+ v2u32 screensize = RenderingEngine::getWindowSize();
const u32 size = 0.25 * screensize.Y;
drawMinimap(core::rect<s32>(
diff --git a/src/client/particles.cpp b/src/client/particles.cpp
index 7acd996dc..288826a5f 100644
--- a/src/client/particles.cpp
+++ b/src/client/particles.cpp
@@ -64,8 +64,8 @@ Particle::Particle(
v2f texsize,
video::SColor color
):
- scene::ISceneNode(RenderingEngine::get_scene_manager()->getRootSceneNode(),
- RenderingEngine::get_scene_manager())
+ scene::ISceneNode(((Client *)gamedef)->getSceneManager()->getRootSceneNode(),
+ ((Client *)gamedef)->getSceneManager())
{
// Misc
m_gamedef = gamedef;
diff --git a/src/client/render/core.cpp b/src/client/render/core.cpp
index 794ec0186..99af085f9 100644
--- a/src/client/render/core.cpp
+++ b/src/client/render/core.cpp
@@ -163,6 +163,7 @@ void RenderingCore::draw3D()
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
if (!show_hud)
return;
+ hud->drawBlockBounds();
hud->drawSelectionMesh();
if (draw_entity_esp || draw_entity_tracers || draw_player_esp || draw_player_tracers || draw_node_esp || draw_node_tracers)
drawTracersAndESP();
diff --git a/src/client/renderingengine.cpp b/src/client/renderingengine.cpp
index 703a988b5..138012414 100644
--- a/src/client/renderingengine.cpp
+++ b/src/client/renderingengine.cpp
@@ -159,7 +159,7 @@ RenderingEngine::~RenderingEngine()
s_singleton = nullptr;
}
-v2u32 RenderingEngine::getWindowSize() const
+v2u32 RenderingEngine::_getWindowSize() const
{
if (core)
return core->getVirtualSize();
@@ -225,6 +225,20 @@ bool RenderingEngine::print_video_modes()
return videomode_list != NULL;
}
+void RenderingEngine::removeMesh(const scene::IMesh* mesh)
+{
+ m_device->getSceneManager()->getMeshCache()->removeMesh(mesh);
+}
+
+void RenderingEngine::cleanupMeshCache()
+{
+ auto mesh_cache = m_device->getSceneManager()->getMeshCache();
+ while (mesh_cache->getMeshCount() != 0) {
+ if (scene::IAnimatedMesh *mesh = mesh_cache->getMeshByIndex(0))
+ mesh_cache->removeMesh(mesh);
+ }
+}
+
bool RenderingEngine::setupTopLevelWindow(const std::string &name)
{
// FIXME: It would make more sense for there to be a switch of some
@@ -335,6 +349,10 @@ static bool getWindowHandle(irr::video::IVideoDriver *driver, HWND &hWnd)
case video::EDT_DIRECT3D9:
hWnd = reinterpret_cast<HWND>(exposedData.D3D9.HWnd);
break;
+#if ENABLE_GLES
+ case video::EDT_OGLES1:
+ case video::EDT_OGLES2:
+#endif
case video::EDT_OPENGL:
hWnd = reinterpret_cast<HWND>(exposedData.OpenGLWin32.HWnd);
break;
@@ -474,11 +492,11 @@ bool RenderingEngine::setXorgWindowIconFromPath(const std::string &icon_file)
Text will be removed when the screen is drawn the next time.
Additionally, a progressbar can be drawn when percent is set between 0 and 100.
*/
-void RenderingEngine::_draw_load_screen(const std::wstring &text,
+void RenderingEngine::draw_load_screen(const std::wstring &text,
gui::IGUIEnvironment *guienv, ITextureSource *tsrc, float dtime,
int percent, bool clouds)
{
- v2u32 screensize = RenderingEngine::get_instance()->getWindowSize();
+ v2u32 screensize = getWindowSize();
v2s32 textsize(g_fontengine->getTextWidth(text), g_fontengine->getLineHeight());
v2s32 center(screensize.X / 2, screensize.Y / 2);
@@ -546,7 +564,7 @@ void RenderingEngine::_draw_load_screen(const std::wstring &text,
/*
Draws the menu scene including (optional) cloud background.
*/
-void RenderingEngine::_draw_menu_scene(gui::IGUIEnvironment *guienv,
+void RenderingEngine::draw_menu_scene(gui::IGUIEnvironment *guienv,
float dtime, bool clouds)
{
bool cloud_menu_background = clouds && g_settings->getBool("menu_clouds");
@@ -594,19 +612,19 @@ std::vector<irr::video::E_DRIVER_TYPE> RenderingEngine::getSupportedVideoDrivers
return drivers;
}
-void RenderingEngine::_initialize(Client *client, Hud *hud)
+void RenderingEngine::initialize(Client *client, Hud *hud)
{
const std::string &draw_mode = g_settings->get("3d_mode");
core.reset(createRenderingCore(draw_mode, m_device, client, hud));
core->initialize();
}
-void RenderingEngine::_finalize()
+void RenderingEngine::finalize()
{
core.reset();
}
-void RenderingEngine::_draw_scene(video::SColor skycolor, bool show_hud,
+void RenderingEngine::draw_scene(video::SColor skycolor, bool show_hud,
bool show_minimap, bool draw_wield_tool, bool draw_crosshair)
{
core->draw(skycolor, show_hud, show_minimap, draw_wield_tool, draw_crosshair);
diff --git a/src/client/renderingengine.h b/src/client/renderingengine.h
index 34cc60630..28ddc8652 100644
--- a/src/client/renderingengine.h
+++ b/src/client/renderingengine.h
@@ -41,7 +41,6 @@ public:
RenderingEngine(IEventReceiver *eventReceiver);
~RenderingEngine();
- v2u32 getWindowSize() const;
void setResizable(bool resize);
video::IVideoDriver *getVideoDriver() { return driver; }
@@ -56,31 +55,30 @@ public:
bool setWindowIcon();
bool setXorgWindowIconFromPath(const std::string &icon_file);
static bool print_video_modes();
+ void cleanupMeshCache();
- static RenderingEngine *get_instance() { return s_singleton; }
+ void removeMesh(const scene::IMesh* mesh);
- static io::IFileSystem *get_filesystem()
+ static v2u32 getWindowSize()
{
- sanity_check(s_singleton && s_singleton->m_device);
- return s_singleton->m_device->getFileSystem();
+ sanity_check(s_singleton);
+ return s_singleton->_getWindowSize();
}
- static video::IVideoDriver *get_video_driver()
+ io::IFileSystem *get_filesystem()
{
- sanity_check(s_singleton && s_singleton->m_device);
- return s_singleton->m_device->getVideoDriver();
+ return m_device->getFileSystem();
}
- static scene::IMeshCache *get_mesh_cache()
+ static video::IVideoDriver *get_video_driver()
{
sanity_check(s_singleton && s_singleton->m_device);
- return s_singleton->m_device->getSceneManager()->getMeshCache();
+ return s_singleton->m_device->getVideoDriver();
}
- static scene::ISceneManager *get_scene_manager()
+ scene::ISceneManager *get_scene_manager()
{
- sanity_check(s_singleton && s_singleton->m_device);
- return s_singleton->m_device->getSceneManager();
+ return m_device->getSceneManager();
}
static irr::IrrlichtDevice *get_raw_device()
@@ -89,70 +87,37 @@ public:
return s_singleton->m_device;
}
- static u32 get_timer_time()
+ u32 get_timer_time()
{
- sanity_check(s_singleton && s_singleton->m_device &&
- s_singleton->m_device->getTimer());
- return s_singleton->m_device->getTimer()->getTime();
+ return m_device->getTimer()->getTime();
}
- static gui::IGUIEnvironment *get_gui_env()
+ gui::IGUIEnvironment *get_gui_env()
{
- sanity_check(s_singleton && s_singleton->m_device);
- return s_singleton->m_device->getGUIEnvironment();
+ return m_device->getGUIEnvironment();
}
- inline static void draw_load_screen(const std::wstring &text,
+ void draw_load_screen(const std::wstring &text,
gui::IGUIEnvironment *guienv, ITextureSource *tsrc,
- float dtime = 0, int percent = 0, bool clouds = true)
- {
- s_singleton->_draw_load_screen(
- text, guienv, tsrc, dtime, percent, clouds);
- }
+ float dtime = 0, int percent = 0, bool clouds = true);
- inline static void draw_menu_scene(
- gui::IGUIEnvironment *guienv, float dtime, bool clouds)
- {
- s_singleton->_draw_menu_scene(guienv, dtime, clouds);
- }
+ void draw_menu_scene(gui::IGUIEnvironment *guienv, float dtime, bool clouds);
+ void draw_scene(video::SColor skycolor, bool show_hud,
+ bool show_minimap, bool draw_wield_tool, bool draw_crosshair);
- inline static void draw_scene(video::SColor skycolor, bool show_hud,
- bool show_minimap, bool draw_wield_tool, bool draw_crosshair)
- {
- s_singleton->_draw_scene(skycolor, show_hud, show_minimap,
- draw_wield_tool, draw_crosshair);
- }
+ void initialize(Client *client, Hud *hud);
+ void finalize();
- inline static void initialize(Client *client, Hud *hud)
+ bool run()
{
- s_singleton->_initialize(client, hud);
- }
-
- inline static void finalize() { s_singleton->_finalize(); }
-
- static bool run()
- {
- sanity_check(s_singleton && s_singleton->m_device);
- return s_singleton->m_device->run();
+ return m_device->run();
}
static std::vector<core::vector3d<u32>> getSupportedVideoModes();
static std::vector<irr::video::E_DRIVER_TYPE> getSupportedVideoDrivers();
private:
- void _draw_load_screen(const std::wstring &text, gui::IGUIEnvironment *guienv,
- ITextureSource *tsrc, float dtime = 0, int percent = 0,
- bool clouds = true);
-
- void _draw_menu_scene(gui::IGUIEnvironment *guienv, float dtime = 0,
- bool clouds = true);
-
- void _draw_scene(video::SColor skycolor, bool show_hud, bool show_minimap,
- bool draw_wield_tool, bool draw_crosshair);
-
- void _initialize(Client *client, Hud *hud);
-
- void _finalize();
+ v2u32 _getWindowSize() const;
std::unique_ptr<RenderingCore> core;
irr::IrrlichtDevice *m_device = nullptr;
diff --git a/src/client/shader.cpp b/src/client/shader.cpp
index b3e4911f4..58946b90f 100644
--- a/src/client/shader.cpp
+++ b/src/client/shader.cpp
@@ -579,8 +579,10 @@ ShaderInfo ShaderSource::generateShader(const std::string &name,
if (use_gles) {
shaders_header << R"(
#version 100
- )";
+ )";
vertex_header = R"(
+ precision mediump float;
+
uniform highp mat4 mWorldView;
uniform highp mat4 mWorldViewProj;
uniform mediump mat4 mTexture;
@@ -592,17 +594,17 @@ ShaderInfo ShaderSource::generateShader(const std::string &name,
attribute mediump vec3 inVertexNormal;
attribute mediump vec4 inVertexTangent;
attribute mediump vec4 inVertexBinormal;
- )";
+ )";
fragment_header = R"(
precision mediump float;
- )";
+ )";
} else {
shaders_header << R"(
#version 120
#define lowp
#define mediump
#define highp
- )";
+ )";
vertex_header = R"(
#define mWorldView gl_ModelViewMatrix
#define mWorldViewProj gl_ModelViewProjectionMatrix
@@ -615,7 +617,7 @@ ShaderInfo ShaderSource::generateShader(const std::string &name,
#define inVertexNormal gl_Normal
#define inVertexTangent gl_MultiTexCoord1
#define inVertexBinormal gl_MultiTexCoord2
- )";
+ )";
}
bool use_discard = use_gles;
diff --git a/src/client/sky.cpp b/src/client/sky.cpp
index caf695e7a..47296a7a5 100644
--- a/src/client/sky.cpp
+++ b/src/client/sky.cpp
@@ -53,10 +53,12 @@ static video::SMaterial baseMaterial()
return mat;
};
-Sky::Sky(s32 id, ITextureSource *tsrc, IShaderSource *ssrc) :
- scene::ISceneNode(RenderingEngine::get_scene_manager()->getRootSceneNode(),
- RenderingEngine::get_scene_manager(), id)
+Sky::Sky(s32 id, RenderingEngine *rendering_engine, ITextureSource *tsrc, IShaderSource *ssrc) :
+ scene::ISceneNode(rendering_engine->get_scene_manager()->getRootSceneNode(),
+ rendering_engine->get_scene_manager(), id)
{
+ m_seed = (u64)myrand() << 32 | myrand();
+
setAutomaticCulling(scene::EAC_OFF);
m_box.MaxEdge.set(0, 0, 0);
m_box.MinEdge.set(0, 0, 0);
@@ -82,13 +84,13 @@ Sky::Sky(s32 id, ITextureSource *tsrc, IShaderSource *ssrc) :
// Ensures that sun and moon textures and tonemaps are correct.
setSkyDefaults();
m_sun_texture = tsrc->isKnownSourceImage(m_sun_params.texture) ?
- tsrc->getTextureForMesh(m_sun_params.texture) : NULL;
+ tsrc->getTextureForMesh(m_sun_params.texture) : nullptr;
m_moon_texture = tsrc->isKnownSourceImage(m_moon_params.texture) ?
- tsrc->getTextureForMesh(m_moon_params.texture) : NULL;
+ tsrc->getTextureForMesh(m_moon_params.texture) : nullptr;
m_sun_tonemap = tsrc->isKnownSourceImage(m_sun_params.tonemap) ?
- tsrc->getTexture(m_sun_params.tonemap) : NULL;
+ tsrc->getTexture(m_sun_params.tonemap) : nullptr;
m_moon_tonemap = tsrc->isKnownSourceImage(m_moon_params.tonemap) ?
- tsrc->getTexture(m_moon_params.tonemap) : NULL;
+ tsrc->getTexture(m_moon_params.tonemap) : nullptr;
if (m_sun_texture) {
m_materials[3] = baseMaterial();
@@ -744,14 +746,14 @@ void Sky::place_sky_body(
}
}
-void Sky::setSunTexture(std::string sun_texture,
- std::string sun_tonemap, ITextureSource *tsrc)
+void Sky::setSunTexture(const std::string &sun_texture,
+ const std::string &sun_tonemap, ITextureSource *tsrc)
{
// Ignore matching textures (with modifiers) entirely,
// but lets at least update the tonemap before hand.
m_sun_params.tonemap = sun_tonemap;
m_sun_tonemap = tsrc->isKnownSourceImage(m_sun_params.tonemap) ?
- tsrc->getTexture(m_sun_params.tonemap) : NULL;
+ tsrc->getTexture(m_sun_params.tonemap) : nullptr;
m_materials[3].Lighting = !!m_sun_tonemap;
if (m_sun_params.texture == sun_texture)
@@ -780,7 +782,7 @@ void Sky::setSunTexture(std::string sun_texture,
}
}
-void Sky::setSunriseTexture(std::string sunglow_texture,
+void Sky::setSunriseTexture(const std::string &sunglow_texture,
ITextureSource* tsrc)
{
// Ignore matching textures (with modifiers) entirely.
@@ -792,14 +794,14 @@ void Sky::setSunriseTexture(std::string sunglow_texture,
);
}
-void Sky::setMoonTexture(std::string moon_texture,
- std::string moon_tonemap, ITextureSource *tsrc)
+void Sky::setMoonTexture(const std::string &moon_texture,
+ const std::string &moon_tonemap, ITextureSource *tsrc)
{
// Ignore matching textures (with modifiers) entirely,
// but lets at least update the tonemap before hand.
m_moon_params.tonemap = moon_tonemap;
m_moon_tonemap = tsrc->isKnownSourceImage(m_moon_params.tonemap) ?
- tsrc->getTexture(m_moon_params.tonemap) : NULL;
+ tsrc->getTexture(m_moon_params.tonemap) : nullptr;
m_materials[4].Lighting = !!m_moon_tonemap;
if (m_moon_params.texture == moon_texture)
@@ -833,7 +835,6 @@ void Sky::setStarCount(u16 star_count, bool force_update)
// Allow force updating star count at game init.
if (m_star_params.count != star_count || force_update) {
m_star_params.count = star_count;
- m_seed = (u64)myrand() << 32 | myrand();
updateStars();
}
}
@@ -893,7 +894,7 @@ void Sky::setSkyColors(const SkyColor &sky_color)
}
void Sky::setHorizonTint(video::SColor sun_tint, video::SColor moon_tint,
- std::string use_sun_tint)
+ const std::string &use_sun_tint)
{
// Change sun and moon tinting:
m_sky_params.fog_sun_tint = sun_tint;
@@ -907,7 +908,7 @@ void Sky::setHorizonTint(video::SColor sun_tint, video::SColor moon_tint,
m_default_tint = true;
}
-void Sky::addTextureToSkybox(std::string texture, int material_id,
+void Sky::addTextureToSkybox(const std::string &texture, int material_id,
ITextureSource *tsrc)
{
// Sanity check for more than six textures.
diff --git a/src/client/sky.h b/src/client/sky.h
index 342a97596..121a16bb7 100644
--- a/src/client/sky.h
+++ b/src/client/sky.h
@@ -36,7 +36,7 @@ class Sky : public scene::ISceneNode
{
public:
//! constructor
- Sky(s32 id, ITextureSource *tsrc, IShaderSource *ssrc);
+ Sky(s32 id, RenderingEngine *rendering_engine, ITextureSource *tsrc, IShaderSource *ssrc);
virtual void OnRegisterSceneNode();
@@ -65,15 +65,15 @@ public:
}
void setSunVisible(bool sun_visible) { m_sun_params.visible = sun_visible; }
- void setSunTexture(std::string sun_texture,
- std::string sun_tonemap, ITextureSource *tsrc);
+ void setSunTexture(const std::string &sun_texture,
+ const std::string &sun_tonemap, ITextureSource *tsrc);
void setSunScale(f32 sun_scale) { m_sun_params.scale = sun_scale; }
void setSunriseVisible(bool glow_visible) { m_sun_params.sunrise_visible = glow_visible; }
- void setSunriseTexture(std::string sunglow_texture, ITextureSource* tsrc);
+ void setSunriseTexture(const std::string &sunglow_texture, ITextureSource* tsrc);
void setMoonVisible(bool moon_visible) { m_moon_params.visible = moon_visible; }
- void setMoonTexture(std::string moon_texture,
- std::string moon_tonemap, ITextureSource *tsrc);
+ void setMoonTexture(const std::string &moon_texture,
+ const std::string &moon_tonemap, ITextureSource *tsrc);
void setMoonScale(f32 moon_scale) { m_moon_params.scale = moon_scale; }
void setStarsVisible(bool stars_visible) { m_star_params.visible = stars_visible; }
@@ -87,21 +87,21 @@ public:
void setVisible(bool visible) { m_visible = visible; }
// Set only from set_sky API
void setCloudsEnabled(bool clouds_enabled) { m_clouds_enabled = clouds_enabled; }
- void setFallbackBgColor(const video::SColor &fallback_bg_color)
+ void setFallbackBgColor(video::SColor fallback_bg_color)
{
m_fallback_bg_color = fallback_bg_color;
}
- void overrideColors(const video::SColor &bgcolor, const video::SColor &skycolor)
+ void overrideColors(video::SColor bgcolor, video::SColor skycolor)
{
m_bgcolor = bgcolor;
m_skycolor = skycolor;
}
void setSkyColors(const SkyColor &sky_color);
void setHorizonTint(video::SColor sun_tint, video::SColor moon_tint,
- std::string use_sun_tint);
+ const std::string &use_sun_tint);
void setInClouds(bool clouds) { m_in_clouds = clouds; }
void clearSkyboxTextures() { m_sky_params.textures.clear(); }
- void addTextureToSkybox(std::string texture, int material_id,
+ void addTextureToSkybox(const std::string &texture, int material_id,
ITextureSource *tsrc);
const video::SColorf &getCurrentStarColor() const { return m_star_color; }
@@ -126,7 +126,7 @@ private:
}
// Mix two colors by a given amount
- video::SColor m_mix_scolor(video::SColor col1, video::SColor col2, f32 factor)
+ static video::SColor m_mix_scolor(video::SColor col1, video::SColor col2, f32 factor)
{
video::SColor result = video::SColor(
col1.getAlpha() * (1 - factor) + col2.getAlpha() * factor,
@@ -135,7 +135,7 @@ private:
col1.getBlue() * (1 - factor) + col2.getBlue() * factor);
return result;
}
- video::SColorf m_mix_scolorf(video::SColorf col1, video::SColorf col2, f32 factor)
+ static video::SColorf m_mix_scolorf(video::SColorf col1, video::SColorf col2, f32 factor)
{
video::SColorf result =
video::SColorf(col1.r * (1 - factor) + col2.r * factor,
diff --git a/src/client/tile.cpp b/src/client/tile.cpp
index 7e3901247..96312ea27 100644
--- a/src/client/tile.cpp
+++ b/src/client/tile.cpp
@@ -34,15 +34,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "guiscalingfilter.h"
#include "renderingengine.h"
-
-#if ENABLE_GLES
-#ifdef _IRR_COMPILE_WITH_OGLES1_
-#include <GLES/gl.h>
-#else
-#include <GLES2/gl2.h>
-#endif
-#endif
-
/*
A cache from texture name to texture path
*/
@@ -427,6 +418,7 @@ private:
std::unordered_map<std::string, Palette> m_palettes;
// Cached settings needed for making textures from meshes
+ bool m_setting_mipmap;
bool m_setting_trilinear_filter;
bool m_setting_bilinear_filter;
};
@@ -447,6 +439,7 @@ TextureSource::TextureSource()
// Cache some settings
// Note: Since this is only done once, the game must be restarted
// for these settings to take effect
+ m_setting_mipmap = g_settings->getBool("mip_map");
m_setting_trilinear_filter = g_settings->getBool("trilinear_filter");
m_setting_bilinear_filter = g_settings->getBool("bilinear_filter");
}
@@ -667,7 +660,7 @@ video::ITexture* TextureSource::getTexture(const std::string &name, u32 *id)
video::ITexture* TextureSource::getTextureForMesh(const std::string &name, u32 *id)
{
static thread_local bool filter_needed =
- g_settings->getBool("texture_clean_transparent") ||
+ g_settings->getBool("texture_clean_transparent") || m_setting_mipmap ||
((m_setting_trilinear_filter || m_setting_bilinear_filter) &&
g_settings->getS32("texture_min_size") > 1);
// Avoid duplicating texture if it won't actually change
@@ -1011,42 +1004,19 @@ video::IImage* TextureSource::generateImage(const std::string &name)
#if ENABLE_GLES
-
-static inline u16 get_GL_major_version()
-{
- const GLubyte *gl_version = glGetString(GL_VERSION);
- return (u16) (gl_version[0] - '0');
-}
-
-/**
- * Check if hardware requires npot2 aligned textures
- * @return true if alignment NOT(!) requires, false otherwise
- */
-
-bool hasNPotSupport()
-{
- // Only GLES2 is trusted to correctly report npot support
- // Note: we cache the boolean result, the GL context will never change.
- static const bool supported = get_GL_major_version() > 1 &&
- glGetString(GL_EXTENSIONS) &&
- strstr((char *)glGetString(GL_EXTENSIONS), "GL_OES_texture_npot");
- return supported;
-}
-
/**
* Check and align image to npot2 if required by hardware
* @param image image to check for npot2 alignment
* @param driver driver to use for image operations
* @return image or copy of image aligned to npot2
*/
-
-video::IImage * Align2Npot2(video::IImage * image,
- video::IVideoDriver* driver)
+video::IImage *Align2Npot2(video::IImage *image,
+ video::IVideoDriver *driver)
{
if (image == NULL)
return image;
- if (hasNPotSupport())
+ if (driver->queryFeature(video::EVDF_TEXTURE_NPOT))
return image;
core::dimension2d<u32> dim = image->getDimension();
@@ -1636,8 +1606,8 @@ bool TextureSource::generateImagePart(std::string part_of_name,
return false;
}
- // Apply the "clean transparent" filter, if configured.
- if (g_settings->getBool("texture_clean_transparent"))
+ // Apply the "clean transparent" filter, if needed
+ if (m_setting_mipmap || g_settings->getBool("texture_clean_transparent"))
imageCleanTransparent(baseimg, 127);
/* Upscale textures to user's requested minimum size. This is a trick to make
diff --git a/src/client/tile.h b/src/client/tile.h
index 49c46f749..fcdc46460 100644
--- a/src/client/tile.h
+++ b/src/client/tile.h
@@ -134,8 +134,7 @@ public:
IWritableTextureSource *createTextureSource();
#if ENABLE_GLES
-bool hasNPotSupport();
-video::IImage * Align2Npot2(video::IImage * image, irr::video::IVideoDriver* driver);
+video::IImage *Align2Npot2(video::IImage *image, video::IVideoDriver *driver);
#endif
enum MaterialType{
diff --git a/src/client/wieldmesh.cpp b/src/client/wieldmesh.cpp
index 387eb17c3..08fd49fc0 100644
--- a/src/client/wieldmesh.cpp
+++ b/src/client/wieldmesh.cpp
@@ -294,9 +294,7 @@ void WieldMeshSceneNode::setExtruded(const std::string &imagename,
}
material.setFlag(video::EMF_ANISOTROPIC_FILTER, m_anisotropic_filter);
// mipmaps cause "thin black line" artifacts
-#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR >= 8) || IRRLICHT_VERSION_MAJOR >= 2
material.setFlag(video::EMF_USE_MIP_MAPS, false);
-#endif
if (m_enable_shaders) {
material.setTexture(2, tsrc->getShaderFlagsTexture(false));
}
@@ -309,18 +307,21 @@ static scene::SMesh *createSpecialNodeMesh(Client *client, MapNode n,
MeshMakeData mesh_make_data(client, false);
MeshCollector collector;
mesh_make_data.setSmoothLighting(false);
- MapblockMeshGenerator gen(&mesh_make_data, &collector);
+ MapblockMeshGenerator gen(&mesh_make_data, &collector,
+ client->getSceneManager()->getMeshManipulator());
if (n.getParam2()) {
// keep it
} else if (f.param_type_2 == CPT2_WALLMOUNTED ||
f.param_type_2 == CPT2_COLORED_WALLMOUNTED) {
- if (f.drawtype == NDT_TORCHLIKE)
- n.setParam2(1);
- else if (f.drawtype == NDT_SIGNLIKE ||
+ if (f.drawtype == NDT_TORCHLIKE ||
+ f.drawtype == NDT_SIGNLIKE ||
f.drawtype == NDT_NODEBOX ||
- f.drawtype == NDT_MESH)
+ f.drawtype == NDT_MESH) {
n.setParam2(4);
+ }
+ } else if (f.drawtype == NDT_SIGNLIKE || f.drawtype == NDT_TORCHLIKE) {
+ n.setParam2(1);
}
gen.renderSingle(n.getContent(), n.getParam2());
@@ -395,7 +396,6 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che
case NDT_TORCHLIKE:
case NDT_RAILLIKE:
case NDT_PLANTLIKE:
- case NDT_PLANTLIKE_ROOTED:
case NDT_FLOWINGLIQUID: {
v3f wscale = def.wield_scale;
if (f.drawtype == NDT_FLOWINGLIQUID)
@@ -411,6 +411,15 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che
m_colors.emplace_back(l1.has_color, l1.color);
break;
}
+ case NDT_PLANTLIKE_ROOTED: {
+ setExtruded(tsrc->getTextureName(f.special_tiles[0].layers[0].texture_id),
+ "", def.wield_scale, tsrc,
+ f.special_tiles[0].layers[0].animation_frame_count);
+ // Add color
+ const TileLayer &l0 = f.special_tiles[0].layers[0];
+ m_colors.emplace_back(l0.has_color, l0.color);
+ break;
+ }
case NDT_NORMAL:
case NDT_ALLFACES:
case NDT_LIQUID:
@@ -530,7 +539,7 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result)
content_t id = ndef->getId(def.name);
FATAL_ERROR_IF(!g_extrusion_mesh_cache, "Extrusion mesh cache is not yet initialized");
-
+
scene::SMesh *mesh = nullptr;
// Shading is on by default