From f3a962c391db3e0dcddaea1d9f483c7e089250c5 Mon Sep 17 00:00:00 2001 From: Geoffrey Mon Date: Wed, 2 Aug 2017 12:49:14 -0400 Subject: [PATCH 01/19] Save and use usernames in replay files Fixes #2754. * Store usernames of each racer in recorded replay files * Display those usernames in a column of the replay selection UI and in race result dialogs * RaceResultGUI::getKartDisplayName functionality moved into Controller::getName --- src/karts/controller/controller.hpp | 10 ++++--- src/karts/controller/ghost_controller.cpp | 3 ++- src/karts/controller/ghost_controller.hpp | 6 ++++- src/replay/replay_base.hpp | 2 +- src/replay/replay_play.cpp | 18 +++++++++---- src/replay/replay_play.hpp | 24 ++++++++++------- src/replay/replay_recorder.cpp | 10 ++++--- src/states_screens/ghost_replay_selection.cpp | 6 +++++ src/states_screens/race_result_gui.cpp | 27 ++----------------- src/states_screens/race_result_gui.hpp | 1 - 10 files changed, 57 insertions(+), 50 deletions(-) diff --git a/src/karts/controller/controller.hpp b/src/karts/controller/controller.hpp index 747f9cc0c..98403badf 100644 --- a/src/karts/controller/controller.hpp +++ b/src/karts/controller/controller.hpp @@ -28,9 +28,9 @@ using namespace irr; */ #include "input/input.hpp" +#include "karts/abstract_kart.hpp" #include "states_screens/state_manager.hpp" -class AbstractKart; class Item; class KartControl; class Material; @@ -100,17 +100,19 @@ public: /** Only local players can get achievements. */ virtual bool canGetAchievements () const { return false; } // ------------------------------------------------------------------------ - /** This should only be called for End- and LocalPlayer-Controller. */ + /** Display name of the controller. + * Defaults to kart name; overriden by controller classes + * (such as player controllers) to display username. */ virtual core::stringw getName() const { - assert(false); - return core::stringw(""); + return translations->fribidize(m_kart->getName()); } // getName // ------------------------------------------------------------------------ /** Returns the kart controlled by this controller. */ AbstractKart *getKart() const { return m_kart; } }; // Controller +extern Translations* translations; #endif /* EOF */ diff --git a/src/karts/controller/ghost_controller.cpp b/src/karts/controller/ghost_controller.cpp index ce9fa8d96..99a4c8475 100644 --- a/src/karts/controller/ghost_controller.cpp +++ b/src/karts/controller/ghost_controller.cpp @@ -21,9 +21,10 @@ #include "karts/controller/kart_control.hpp" #include "modes/world.hpp" -GhostController::GhostController(AbstractKart *kart) +GhostController::GhostController(AbstractKart *kart, core::stringw display_name) : Controller(kart) { + m_display_name = display_name; } // GhostController //----------------------------------------------------------------------------- diff --git a/src/karts/controller/ghost_controller.hpp b/src/karts/controller/ghost_controller.hpp index c0eb462f9..c78b4b454 100644 --- a/src/karts/controller/ghost_controller.hpp +++ b/src/karts/controller/ghost_controller.hpp @@ -37,11 +37,14 @@ private: /** The current world time. */ float m_current_time; + /** Player name of the ghost kart. */ + core::stringw m_display_name; + /** The list of the times at which the events of kart were reached. */ std::vector m_all_times; public: - GhostController(AbstractKart *kart); + GhostController(AbstractKart *kart, core::stringw display_name); virtual ~GhostController() {}; virtual void reset() OVERRIDE; virtual void update (float dt) OVERRIDE; @@ -73,6 +76,7 @@ public: unsigned int getCurrentReplayIndex() const { return m_current_index; } // ------------------------------------------------------------------------ + core::stringw getName() const OVERRIDE { return m_display_name; } }; // GhostController #endif diff --git a/src/replay/replay_base.hpp b/src/replay/replay_base.hpp index 2d7f8b408..0655d2daf 100644 --- a/src/replay/replay_base.hpp +++ b/src/replay/replay_base.hpp @@ -81,7 +81,7 @@ protected: /** Returns the version number of the replay file. This is used to check * that a loaded replay file can still be understood by this * executable. */ - unsigned int getReplayVersion() const { return 3; } + unsigned int getReplayVersion() const { return 4; } public: ReplayBase(); diff --git a/src/replay/replay_play.cpp b/src/replay/replay_play.cpp index cc998ae74..942f07175 100644 --- a/src/replay/replay_play.cpp +++ b/src/replay/replay_play.cpp @@ -135,13 +135,20 @@ bool ReplayPlay::addReplayFile(const std::string& fn, bool custom_replay) is_end.trim(); if (is_end == "kart_list_end") break; char s1[1024]; + char display_name_encoded[1024]; - if (sscanf(s,"kart: %s", s1) != 1) + if (sscanf(s,"kart: %s %[^\n]", s1, display_name_encoded) != 2) { Log::warn("Replay", "Could not read ghost karts info!"); break; } rd.m_kart_list.push_back(std::string(s1)); + rd.m_name_list.push_back(StringUtils::xmlDecode(std::string(display_name_encoded))); + + if (rd.m_name_list.size() == 1) { + // First user is the game master and the "owner" of this replay file + rd.m_user_name = rd.m_name_list[0]; + } } int reverse = 0; @@ -249,11 +256,12 @@ void ReplayPlay::readKartData(FILE *fd, char *next_line) { char s[1024]; const unsigned int kart_num = m_ghost_karts.size(); - m_ghost_karts.push_back(new GhostKart(m_replay_file_list - [m_current_replay_file].m_kart_list.at(kart_num), - kart_num, kart_num + 1)); + ReplayData &rd = m_replay_file_list[m_current_replay_file]; + m_ghost_karts.push_back(new GhostKart(rd.m_kart_list.at(kart_num), + kart_num, kart_num + 1)); m_ghost_karts[kart_num].init(RaceManager::KT_GHOST); - Controller* controller = new GhostController(getGhostKart(kart_num)); + Controller* controller = new GhostController(getGhostKart(kart_num), + rd.m_name_list[kart_num]); getGhostKart(kart_num)->setController(controller); unsigned int size; diff --git a/src/replay/replay_play.hpp b/src/replay/replay_play.hpp index c589c7fc2..04b6ed7b4 100644 --- a/src/replay/replay_play.hpp +++ b/src/replay/replay_play.hpp @@ -45,20 +45,23 @@ public: SO_KART_NUM, SO_DIFF, SO_LAPS, - SO_TIME + SO_TIME, + SO_USER }; class ReplayData { public: - std::string m_filename; - std::string m_track_name; - std::vector m_kart_list; - bool m_reverse; - bool m_custom_replay_file; - unsigned int m_difficulty; - unsigned int m_laps; - float m_min_time; + std::string m_filename; + std::string m_track_name; + core::stringw m_user_name; + std::vector m_kart_list; + std::vector m_name_list; + bool m_reverse; + bool m_custom_replay_file; + unsigned int m_difficulty; + unsigned int m_laps; + float m_min_time; bool operator < (const ReplayData& r) const { @@ -82,6 +85,9 @@ public: case SO_TIME: return m_min_time < r.m_min_time; break; + case SO_USER: + return m_user_name < r.m_user_name; + break; } // switch return true; } // operator < diff --git a/src/replay/replay_recorder.cpp b/src/replay/replay_recorder.cpp index 4a1c986e2..e94a111e4 100644 --- a/src/replay/replay_recorder.cpp +++ b/src/replay/replay_recorder.cpp @@ -31,6 +31,7 @@ #include #include #include +#include ReplayRecorder *ReplayRecorder::m_replay_recorder = NULL; @@ -222,9 +223,12 @@ void ReplayRecorder::save() fprintf(fd, "version: %d\n", getReplayVersion()); for (unsigned int real_karts = 0; real_karts < num_karts; real_karts++) { - if (world->getKart(real_karts)->isGhostKart()) continue; - fprintf(fd, "kart: %s\n", - world->getKart(real_karts)->getIdent().c_str()); + const AbstractKart *kart = world->getKart(real_karts); + if (kart->isGhostKart()) continue; + + // XML encode the username to handle Unicode + fprintf(fd, "kart: %s %s\n", kart->getIdent().c_str(), + StringUtils::xmlEncode(kart->getController()->getName()).c_str()); } fprintf(fd, "kart_list_end\n"); diff --git a/src/states_screens/ghost_replay_selection.cpp b/src/states_screens/ghost_replay_selection.cpp index 7828efc4a..92fe70882 100644 --- a/src/states_screens/ghost_replay_selection.cpp +++ b/src/states_screens/ghost_replay_selection.cpp @@ -80,6 +80,7 @@ void GhostReplaySelection::beforeAddingWidget() m_replay_list_widget->addColumn( _("Difficulty"), 1); m_replay_list_widget->addColumn( _("Laps"), 1); m_replay_list_widget->addColumn( _("Finish Time"), 1); + m_replay_list_widget->addColumn( _("User"), 1); } // beforeAddingWidget // ---------------------------------------------------------------------------- @@ -122,6 +123,8 @@ void GhostReplaySelection::loadList() (StringUtils::toWString(rd.m_laps), -1, 1, true)); row.push_back(GUIEngine::ListWidget::ListCell (StringUtils::toWString(rd.m_min_time) + L"s", -1, 1, true)); + row.push_back(GUIEngine::ListWidget::ListCell + (rd.m_user_name, -1, 1, true)); m_replay_list_widget->addItem(StringUtils::toString(i), row); } } // loadList @@ -213,6 +216,9 @@ void GhostReplaySelection::onColumnClicked(int column_id) case 5: ReplayPlay::setSortOrder(ReplayPlay::SO_TIME); break; + case 6: + ReplayPlay::setSortOrder(ReplayPlay::SO_USER); + break; default: assert(0); break; diff --git a/src/states_screens/race_result_gui.cpp b/src/states_screens/race_result_gui.cpp index 7aee51f4f..0a1b65ec6 100644 --- a/src/states_screens/race_result_gui.cpp +++ b/src/states_screens/race_result_gui.cpp @@ -486,7 +486,7 @@ void RaceResultGUI::backToLobby() // Save a pointer to the current row_info entry RowInfo *ri = &(m_all_row_infos[position - first_position]); ri->m_is_player_kart = kart->getController()->isLocalPlayerController(); - ri->m_kart_name = getKartDisplayName(kart); + ri->m_kart_name = kart->getController()->getName(); video::ITexture *icon = kart->getKartProperties()->getIconMaterial()->getTexture(); @@ -855,7 +855,7 @@ void RaceResultGUI::backToLobby() ri->m_kart_icon = kart->getKartProperties()->getIconMaterial()->getTexture(); ri->m_is_player_kart = kart->getController()->isLocalPlayerController(); - ri->m_kart_name = getKartDisplayName(kart); + ri->m_kart_name = kart->getController()->getName(); // In FTL karts do have a time, which is shown even when the kart // is eliminated @@ -907,29 +907,6 @@ void RaceResultGUI::backToLobby() #endif } // determineGPLayout - //----------------------------------------------------------------------------- - /** Returns a string to display next to a kart. For a player that's the name - * of the player, for an AI kart it's the name of the driver. - */ - core::stringw RaceResultGUI::getKartDisplayName(const AbstractKart *kart) const - { - const EndController *ec = - dynamic_cast(kart->getController()); - // If the race was given up, there is no end controller for the - // players, so this case needs to be handled separately - if(ec && ec->isLocalPlayerController()) - return ec->getName(); - else - { - // No end controller, check explicitely for a player controller - const PlayerController *pc = - dynamic_cast(kart->getController()); - // Check if the kart is a player controller to get the real name - if(pc) return pc->getName(); - } - return translations->fribidize(kart->getName()); - } // getKartDisplayName - //----------------------------------------------------------------------------- /** Displays the race results for a single kart. * \param n Index of the kart to be displayed. diff --git a/src/states_screens/race_result_gui.hpp b/src/states_screens/race_result_gui.hpp index 75c663901..0c1960ca0 100644 --- a/src/states_screens/race_result_gui.hpp +++ b/src/states_screens/race_result_gui.hpp @@ -194,7 +194,6 @@ private: void displayPostRaceInfo(); void displaySoccerResults(); void displayScreenShots(); - irr::core::stringw getKartDisplayName(const AbstractKart *kart) const; int getFontHeight () const; From ca5258a46cfeac04704ccf7dfe50849fcc361d6b Mon Sep 17 00:00:00 2001 From: Geoffrey Mon Date: Wed, 2 Aug 2017 13:46:48 -0400 Subject: [PATCH 02/19] Move Controller::getName definition to avoid unnecessary #include --- src/karts/controller/controller.cpp | 4 ++++ src/karts/controller/controller.hpp | 7 ++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/karts/controller/controller.cpp b/src/karts/controller/controller.cpp index fe3450464..6460b0341 100644 --- a/src/karts/controller/controller.cpp +++ b/src/karts/controller/controller.cpp @@ -34,3 +34,7 @@ Controller::Controller(AbstractKart *kart) m_kart = kart; setControllerName("Controller"); } // Controller + +core::stringw Controller::getName() const { + return translations->fribidize(m_kart->getName()); +} diff --git a/src/karts/controller/controller.hpp b/src/karts/controller/controller.hpp index 98403badf..1e101d137 100644 --- a/src/karts/controller/controller.hpp +++ b/src/karts/controller/controller.hpp @@ -28,9 +28,9 @@ using namespace irr; */ #include "input/input.hpp" -#include "karts/abstract_kart.hpp" #include "states_screens/state_manager.hpp" +class AbstractKart; class Item; class KartControl; class Material; @@ -103,10 +103,7 @@ public: /** Display name of the controller. * Defaults to kart name; overriden by controller classes * (such as player controllers) to display username. */ - virtual core::stringw getName() const - { - return translations->fribidize(m_kart->getName()); - } // getName + virtual core::stringw getName() const; // ------------------------------------------------------------------------ /** Returns the kart controlled by this controller. */ AbstractKart *getKart() const { return m_kart; } From 9ec2ff5c4a0b8223a59f7b649581962a2026f81f Mon Sep 17 00:00:00 2001 From: Geoffrey Mon Date: Wed, 2 Aug 2017 14:13:26 -0400 Subject: [PATCH 03/19] Backwards compatibility: use kart name if username is not in replay --- src/karts/controller/ghost_controller.hpp | 5 ++++- src/replay/replay_base.hpp | 2 +- src/replay/replay_play.cpp | 23 ++++++++++++++++------- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/karts/controller/ghost_controller.hpp b/src/karts/controller/ghost_controller.hpp index c78b4b454..746d95544 100644 --- a/src/karts/controller/ghost_controller.hpp +++ b/src/karts/controller/ghost_controller.hpp @@ -76,7 +76,10 @@ public: unsigned int getCurrentReplayIndex() const { return m_current_index; } // ------------------------------------------------------------------------ - core::stringw getName() const OVERRIDE { return m_display_name; } + /** Return the display name; if not set, use default display name (kart name) */ + core::stringw getName() const OVERRIDE { return m_display_name.empty() ? + Controller::getName() : + m_display_name; } }; // GhostController #endif diff --git a/src/replay/replay_base.hpp b/src/replay/replay_base.hpp index 0655d2daf..2d7f8b408 100644 --- a/src/replay/replay_base.hpp +++ b/src/replay/replay_base.hpp @@ -81,7 +81,7 @@ protected: /** Returns the version number of the replay file. This is used to check * that a loaded replay file can still be understood by this * executable. */ - unsigned int getReplayVersion() const { return 4; } + unsigned int getReplayVersion() const { return 3; } public: ReplayBase(); diff --git a/src/replay/replay_play.cpp b/src/replay/replay_play.cpp index 942f07175..130dbad0a 100644 --- a/src/replay/replay_play.cpp +++ b/src/replay/replay_play.cpp @@ -137,17 +137,26 @@ bool ReplayPlay::addReplayFile(const std::string& fn, bool custom_replay) char s1[1024]; char display_name_encoded[1024]; - if (sscanf(s,"kart: %s %[^\n]", s1, display_name_encoded) != 2) + int scanned = sscanf(s,"kart: %s %[^\n]", s1, display_name_encoded); + if (scanned < 1) { Log::warn("Replay", "Could not read ghost karts info!"); break; - } - rd.m_kart_list.push_back(std::string(s1)); - rd.m_name_list.push_back(StringUtils::xmlDecode(std::string(display_name_encoded))); + } else { + rd.m_kart_list.push_back(std::string(s1)); - if (rd.m_name_list.size() == 1) { - // First user is the game master and the "owner" of this replay file - rd.m_user_name = rd.m_name_list[0]; + if (scanned == 2) { + // If username of kart is present, use it + rd.m_name_list.push_back(StringUtils::xmlDecode(std::string(display_name_encoded))); + if (rd.m_name_list.size() == 1) { + // First user is the game master and the "owner" of this replay file + rd.m_user_name = rd.m_name_list[0]; + } + } else { // scanned == 1 + // If username is not present, kart display name will default to kart name + // (see GhostController::getName) + rd.m_name_list.push_back(""); + } } } From 802d70ca8d7f50adc0d39e28ef56984cd1b8e2c8 Mon Sep 17 00:00:00 2001 From: Geoffrey Mon Date: Wed, 2 Aug 2017 17:21:37 -0400 Subject: [PATCH 04/19] Fix code style issues --- src/karts/controller/controller.cpp | 3 ++- src/karts/controller/ghost_controller.hpp | 7 +++--- src/replay/replay_play.cpp | 28 ++++++++++++----------- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/karts/controller/controller.cpp b/src/karts/controller/controller.cpp index 6460b0341..26d8311d2 100644 --- a/src/karts/controller/controller.cpp +++ b/src/karts/controller/controller.cpp @@ -35,6 +35,7 @@ Controller::Controller(AbstractKart *kart) setControllerName("Controller"); } // Controller -core::stringw Controller::getName() const { +core::stringw Controller::getName() const +{ return translations->fribidize(m_kart->getName()); } diff --git a/src/karts/controller/ghost_controller.hpp b/src/karts/controller/ghost_controller.hpp index 746d95544..245abae74 100644 --- a/src/karts/controller/ghost_controller.hpp +++ b/src/karts/controller/ghost_controller.hpp @@ -77,9 +77,10 @@ public: { return m_current_index; } // ------------------------------------------------------------------------ /** Return the display name; if not set, use default display name (kart name) */ - core::stringw getName() const OVERRIDE { return m_display_name.empty() ? - Controller::getName() : - m_display_name; } + core::stringw getName() const OVERRIDE + { + return m_display_name.empty() ? Controller::getName() : m_display_name; + } }; // GhostController #endif diff --git a/src/replay/replay_play.cpp b/src/replay/replay_play.cpp index 130dbad0a..923374af9 100644 --- a/src/replay/replay_play.cpp +++ b/src/replay/replay_play.cpp @@ -142,21 +142,23 @@ bool ReplayPlay::addReplayFile(const std::string& fn, bool custom_replay) { Log::warn("Replay", "Could not read ghost karts info!"); break; - } else { - rd.m_kart_list.push_back(std::string(s1)); + } - if (scanned == 2) { - // If username of kart is present, use it - rd.m_name_list.push_back(StringUtils::xmlDecode(std::string(display_name_encoded))); - if (rd.m_name_list.size() == 1) { - // First user is the game master and the "owner" of this replay file - rd.m_user_name = rd.m_name_list[0]; - } - } else { // scanned == 1 - // If username is not present, kart display name will default to kart name - // (see GhostController::getName) - rd.m_name_list.push_back(""); + rd.m_kart_list.push_back(std::string(s1)); + if (scanned == 2) + { + // If username of kart is present, use it + rd.m_name_list.push_back(StringUtils::xmlDecode(std::string(display_name_encoded))); + if (rd.m_name_list.size() == 1) + { + // First user is the game master and the "owner" of this replay file + rd.m_user_name = rd.m_name_list[0]; } + } else + { // scanned == 1 + // If username is not present, kart display name will default to kart name + // (see GhostController::getName) + rd.m_name_list.push_back(""); } } From 0a715ac31a45a964366642f35f210708182e1e14 Mon Sep 17 00:00:00 2001 From: Deve Date: Mon, 7 Aug 2017 22:33:57 +0200 Subject: [PATCH 05/19] Fixed 32-bit mingw compilation --- cmake/Toolchain-mingw.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Toolchain-mingw.cmake b/cmake/Toolchain-mingw.cmake index 141465228..052c984c0 100644 --- a/cmake/Toolchain-mingw.cmake +++ b/cmake/Toolchain-mingw.cmake @@ -10,7 +10,7 @@ SET(CMAKE_CXX_COMPILER i686-w64-mingw32-g++-posix) SET(CMAKE_RC_COMPILER i686-w64-mingw32-windres) # figure out folder to look in -execute_process(COMMAND sh -c "ls /usr/lib/gcc/x86_64-w64-mingw32/ | grep posix | tr -d '\n'" OUTPUT_VARIABLE MINGW_DEPS_FOLDER) +execute_process(COMMAND sh -c "ls /usr/lib/gcc/i686-w64-mingw32/ | grep posix | tr -d '\n'" OUTPUT_VARIABLE MINGW_DEPS_FOLDER) # here is the target environment located SET(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32 /usr/lib/gcc/i686-w64-mingw32/${MINGW_DEPS_FOLDER}/ ${PROJECT_SOURCE_DIR}/dependencies) From f589bbea04732f1e2505db1df6646fef7a45070f Mon Sep 17 00:00:00 2001 From: "auria.mg" Date: Tue, 8 Aug 2017 20:23:22 -0400 Subject: [PATCH 06/19] Attempt to fix 2617 --- src/input/input_manager.cpp | 6 ++++-- src/input/input_manager.hpp | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/input/input_manager.cpp b/src/input/input_manager.cpp index f41aafab6..e604e6b82 100644 --- a/src/input/input_manager.cpp +++ b/src/input/input_manager.cpp @@ -488,11 +488,13 @@ void InputManager::inputSensing(Input::InputType type, int deviceID, // We have to save the direction in which the axis was moved. // This is done by storing it as a sign (and since button can // be zero, we add one before changing the sign). - int input_id = value>=0 ? 1+button : -(1+button); + int input_button_id = value>=0 ? 1+button : -(1+button); + std::tuple input_id(deviceID, input_button_id); + std::tuple input_id_inv(deviceID, -input_button_id); bool id_was_high = m_sensed_input_high_gamepad.find(input_id) != m_sensed_input_high_gamepad.end(); - bool inverse_id_was_high = m_sensed_input_high_gamepad.find(-input_id) + bool inverse_id_was_high = m_sensed_input_high_gamepad.find(input_id_inv) != m_sensed_input_high_gamepad.end(); bool id_was_zero = m_sensed_input_zero_gamepad.find(button) != m_sensed_input_zero_gamepad.end(); diff --git a/src/input/input_manager.hpp b/src/input/input_manager.hpp index 2ffff2ea4..8c2ed7ff0 100644 --- a/src/input/input_manager.hpp +++ b/src/input/input_manager.hpp @@ -53,7 +53,7 @@ public: private: DeviceManager *m_device_manager; - std::set m_sensed_input_high_gamepad; + std::set> m_sensed_input_high_gamepad; std::set m_sensed_input_high_kbd; std::set m_sensed_input_zero_gamepad; From 94bb657102cc7cb430916a35de67e60af54477ca Mon Sep 17 00:00:00 2001 From: "auria.mg" Date: Tue, 8 Aug 2017 20:44:31 -0400 Subject: [PATCH 07/19] Ignore input sensing coming from the wrong gamepad --- src/states_screens/options_screen_device.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/states_screens/options_screen_device.cpp b/src/states_screens/options_screen_device.cpp index caa3c43ea..8033226dc 100644 --- a/src/states_screens/options_screen_device.cpp +++ b/src/states_screens/options_screen_device.cpp @@ -434,6 +434,10 @@ void OptionsScreenDevice::gotSensedInput(const Input& sensed_input) // refresh display updateInputButtons(); } + else + { + return; + } } else if (sensed_input.m_type == Input::IT_NONE) { From ea97258b65e49f4bf7389944a1a0a1aa02bf02e8 Mon Sep 17 00:00:00 2001 From: Benau Date: Wed, 9 Aug 2017 12:23:37 +0800 Subject: [PATCH 08/19] Add scripting code for throwing banana monkeys --- lib/irrlicht/include/IAnimatedMeshSceneNode.h | 3 +- .../Irrlicht/CAnimatedMeshSceneNode.cpp | 55 ++++++++ .../source/Irrlicht/CAnimatedMeshSceneNode.h | 3 +- src/scriptengine/script_track.cpp | 73 +++++++++-- src/tracks/track_object.cpp | 37 +++++- src/tracks/track_object.hpp | 2 +- src/tracks/track_object_presentation.cpp | 120 ++++++++++-------- src/tracks/track_object_presentation.hpp | 26 ++-- 8 files changed, 241 insertions(+), 78 deletions(-) diff --git a/lib/irrlicht/include/IAnimatedMeshSceneNode.h b/lib/irrlicht/include/IAnimatedMeshSceneNode.h index 89c84d740..6929dd347 100644 --- a/lib/irrlicht/include/IAnimatedMeshSceneNode.h +++ b/lib/irrlicht/include/IAnimatedMeshSceneNode.h @@ -177,8 +177,9 @@ namespace scene \param newManager An optional new scene manager. \return The newly created clone of this node. */ virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0) = 0; - + virtual void setFrameLoopOnce(s32 begin, s32 end) = 0; virtual u32 getAnimationSetNum() = 0; + virtual s32 getAnimationSet() const = 0; virtual void addAnimationSet(u32 start, u32 end) = 0; virtual void useAnimationSet(u32 set_num) = 0; }; diff --git a/lib/irrlicht/source/Irrlicht/CAnimatedMeshSceneNode.cpp b/lib/irrlicht/source/Irrlicht/CAnimatedMeshSceneNode.cpp index 3d6b08aa5..030b107e2 100644 --- a/lib/irrlicht/source/Irrlicht/CAnimatedMeshSceneNode.cpp +++ b/lib/irrlicht/source/Irrlicht/CAnimatedMeshSceneNode.cpp @@ -1002,5 +1002,60 @@ void CAnimatedMeshSceneNode::useAnimationSet(u32 set_num) setFrameLoop(m_animation_set[set_num * 2], m_animation_set[set_num * 2 + 1]); } +void CAnimatedMeshSceneNode::setFrameLoopOnce(s32 begin, s32 end) +{ + if (LoopCallBack != NULL || !Looping) + { + return; + } + Looping = false; + class MiniLoopSetter : public IAnimationEndCallBack + { + private: + int m_old_start, m_old_end, m_new_start, m_new_end; + + bool m_run_cb; + public: + MiniLoopSetter(int old_start, int old_end, int new_start, int new_end) + : m_old_start(old_start), m_old_end(old_end), + m_new_start(new_start), m_new_end(new_end), m_run_cb(false) {} + virtual void OnAnimationEnd(IAnimatedMeshSceneNode* node) + { + if (!m_run_cb) + { + m_run_cb = true; + node->setFrameLoop(m_new_start, m_new_end); + return; + } + if (m_run_cb) + { + node->setFrameLoop(m_old_start, m_old_end); + node->setLoopMode(true); + node->setAnimationEndCallback(NULL); + return; + } + } + }; + MiniLoopSetter* mls = new MiniLoopSetter(StartFrame, EndFrame, + begin, end); + setAnimationEndCallback(mls); + mls->drop(); + +} + +s32 CAnimatedMeshSceneNode::getAnimationSet() const +{ + for (u32 i = 0; i < m_animation_set.size(); i += 2) + { + if (m_animation_set[i] == (u32)StartFrame && + m_animation_set[i + 1] == (u32)EndFrame) + { + return (s32)(i >> 1); + } + } + return -1; +} + + } // end namespace scene } // end namespace irr diff --git a/lib/irrlicht/source/Irrlicht/CAnimatedMeshSceneNode.h b/lib/irrlicht/source/Irrlicht/CAnimatedMeshSceneNode.h index 1ea8f5112..68dc93748 100644 --- a/lib/irrlicht/source/Irrlicht/CAnimatedMeshSceneNode.h +++ b/lib/irrlicht/source/Irrlicht/CAnimatedMeshSceneNode.h @@ -161,13 +161,14 @@ namespace scene virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0); virtual u32 getAnimationSetNum() { return m_animation_set.size() / 2; } + virtual s32 getAnimationSet() const; virtual void addAnimationSet(u32 start, u32 end) { m_animation_set.push_back(start); m_animation_set.push_back(end); } virtual void useAnimationSet(u32 set_num); - + virtual void setFrameLoopOnce(s32 begin, s32 end); protected: //! Get a static mesh for the current frame of this animated mesh diff --git a/src/scriptengine/script_track.cpp b/src/scriptengine/script_track.cpp index e4ad0e7cd..114657ba7 100644 --- a/src/scriptengine/script_track.cpp +++ b/src/scriptengine/script_track.cpp @@ -127,6 +127,23 @@ namespace Scripting #endif } + /** Function for re-enable a trigger after a specific timeout*/ + void setTriggerReenableTimeout(std::string* triggerID, std::string* lib_id, + float reenable_time) + { + ::TrackObject* tobj = ::Track::getCurrentTrack()->getTrackObjectManager() + ->getTrackObject(*lib_id, *triggerID); + if (tobj != NULL) + { + TrackObjectPresentationActionTrigger* topat = + tobj->getPresentation(); + if (topat != NULL) + { + topat->setReenableTimeout(reenable_time); + } + } + } + /** Exits the race to the main menu */ void exitRace() { @@ -231,22 +248,52 @@ namespace Scripting /** Sets a loop for a skeletal animation */ // TODO: can we use a type and avoid void* ? - void setLoop(int start, int end /** \cond DOXYGEN_IGNORE */, void *memory /** \endcond */) + void setFrameLoop(int start, int end /** \cond DOXYGEN_IGNORE */, void *memory /** \endcond */) { - ((TrackObjectPresentationMesh*)(memory))->setLoop(start, end); + if (memory) + { + ((scene::IAnimatedMeshSceneNode*)(memory))->setFrameLoop(start, end); + } + } + + /** Sets a loop once for a skeletal animation */ + void setFrameLoopOnce(int start, int end /** \cond DOXYGEN_IGNORE */, void *memory /** \endcond */) + { + if (memory) + { + ((scene::IAnimatedMeshSceneNode*)(memory))->setFrameLoopOnce(start, end); + } + } + + /** Get current frame in a skeletal animation */ + int getFrameNr(/** \cond DOXYGEN_IGNORE */void *memory /** \endcond */) + { + if (memory) + { + return ((scene::IAnimatedMeshSceneNode*)(memory))->getFrameNr(); + } + return -1; + } + + /** Gets the animation set for a skeletal animation */ + int getAnimationSet(/** \cond DOXYGEN_IGNORE */void *memory /** \endcond */) + { + if (memory) + { + return ((scene::IAnimatedMeshSceneNode*)(memory))->getAnimationSet(); + } + return -1; } /** Sets the current frame for a skeletal animation */ void setCurrentFrame(int frame /** \cond DOXYGEN_IGNORE */, void *memory /** \endcond */) { - ((TrackObjectPresentationMesh*)(memory))->setCurrentFrame(frame); + if (memory) + { + ((scene::IAnimatedMeshSceneNode*)(memory))->setCurrentFrame(frame); + } } - /** Get current frame in a skeletal animation */ - int getCurrentFrame(/** \cond DOXYGEN_IGNORE */void *memory /** \endcond */) - { - return ((TrackObjectPresentationMesh*)(memory))->getCurrentFrame(); - } /** @} */ } @@ -384,6 +431,8 @@ namespace Scripting asFUNCTION(createTrigger), asCALL_CDECL); assert(r >= 0); r = engine->RegisterGlobalFunction("void createTextBillboard(const string &in, const Vec3 &in)", asFUNCTION(createTextBillboard), asCALL_CDECL); assert(r >= 0); + r = engine->RegisterGlobalFunction("void setTriggerReenableTimeout(const string &in, const string &in, float reenable_time)", + asFUNCTION(setTriggerReenableTimeout), asCALL_CDECL); assert(r >= 0); r = engine->RegisterGlobalFunction("TrackObject@ getTrackObject(const string &in, const string &in)", asFUNCTION(getTrackObject), asCALL_CDECL); assert(r >= 0); r = engine->RegisterGlobalFunction("void exitRace()", asFUNCTION(exitRace), asCALL_CDECL); assert(r >= 0); r = engine->RegisterGlobalFunction("void pauseRace()", asFUNCTION(pauseRace), asCALL_CDECL); assert(r >= 0); @@ -410,9 +459,11 @@ namespace Scripting r = engine->RegisterObjectMethod("PhysicalObject", "void disable()", asMETHOD(PhysicalObject, disable), asCALL_THISCALL); assert(r >= 0); r = engine->RegisterObjectMethod("PhysicalObject", "void enable()", asMETHOD(PhysicalObject, enable), asCALL_THISCALL); assert(r >= 0); - // TrackObjectPresentationMesh (Mesh or Skeletal Animation) - r = engine->RegisterObjectMethod("Mesh", "void setLoop(int start, int end)", asFUNCTION(Mesh::setLoop), asCALL_CDECL_OBJLAST); assert(r >= 0); - r = engine->RegisterObjectMethod("Mesh", "int getCurrentFrame()", asFUNCTION(Mesh::getCurrentFrame), asCALL_CDECL_OBJLAST); assert(r >= 0); + // Animated Mesh + r = engine->RegisterObjectMethod("Mesh", "void setFrameLoop(int start, int end)", asFUNCTION(Mesh::setFrameLoop), asCALL_CDECL_OBJLAST); assert(r >= 0); + r = engine->RegisterObjectMethod("Mesh", "void setFrameLoopOnce(int start, int end)", asFUNCTION(Mesh::setFrameLoopOnce), asCALL_CDECL_OBJLAST); assert(r >= 0); + r = engine->RegisterObjectMethod("Mesh", "int getFrameNr()", asFUNCTION(Mesh::getFrameNr), asCALL_CDECL_OBJLAST); assert(r >= 0); + r = engine->RegisterObjectMethod("Mesh", "int getAnimationSet()", asFUNCTION(Mesh::getAnimationSet), asCALL_CDECL_OBJLAST); assert(r >= 0); r = engine->RegisterObjectMethod("Mesh", "void setCurrentFrame(int frame)", asFUNCTION(Mesh::setCurrentFrame), asCALL_CDECL_OBJLAST); assert(r >= 0); //r = engine->RegisterObjectMethod("Mesh", "void move(Vec3 &in)", asFUNCTION(movePresentation), asCALL_CDECL_OBJLAST); assert(r >= 0); diff --git a/src/tracks/track_object.cpp b/src/tracks/track_object.cpp index ada404ae6..f68dc3f0c 100644 --- a/src/tracks/track_object.cpp +++ b/src/tracks/track_object.cpp @@ -20,6 +20,7 @@ #include "animations/three_d_animation.hpp" #include "graphics/irr_driver.hpp" +#include "graphics/lod_node.hpp" #include "graphics/material.hpp" #include "graphics/material_manager.hpp" #include "graphics/render_info.hpp" @@ -32,6 +33,7 @@ #include "scriptengine/script_engine.hpp" #include "tracks/model_definition_loader.hpp" +#include #include /** A track object: any additional object on the track. This object implements @@ -156,6 +158,7 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent, } else if (xml_node.getName() == "library") { + xml_node.get("name", &m_name); m_presentation = new TrackObjectPresentationLibraryNode(this, xml_node, model_def_loader); } else if (type == "sfx-emitter") @@ -170,7 +173,7 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent, std::string action; xml_node.get("action", &action); m_name = action; //adds action as name so that it can be found by using getName() - m_presentation = new TrackObjectPresentationActionTrigger(xml_node); + m_presentation = new TrackObjectPresentationActionTrigger(xml_node, parent_library); } else if (type == "billboard") { @@ -661,3 +664,35 @@ void TrackObject::moveTo(const Scripting::SimpleVec3* pos, bool isAbsoluteCoord) isAbsoluteCoord); } } + +// ---------------------------------------------------------------------------- +scene::IAnimatedMeshSceneNode* TrackObject::getMesh() +{ + if (getPresentation()) + { + LODNode* ln = dynamic_cast + (getPresentation()->getNode()); + if (ln && !ln->getAllNodes().empty()) + { + scene::IAnimatedMeshSceneNode* an = + dynamic_cast + (ln->getFirstNode()); + if (an) + { + return an; + } + } + } + else if (getPresentation()) + { + scene::IAnimatedMeshSceneNode* an = + dynamic_cast + (getPresentation()->getNode()); + if (an) + { + return an; + } + } + Log::debug("TrackObject", "No animated mesh"); + return NULL; +} // getMesh diff --git a/src/tracks/track_object.hpp b/src/tracks/track_object.hpp index ceabc0c31..c8b7b5acc 100644 --- a/src/tracks/track_object.hpp +++ b/src/tracks/track_object.hpp @@ -190,7 +190,7 @@ public: /** Should only be used on mesh track objects. * On the script side, the returned object is of type : @ref Scripting_Mesh */ - TrackObjectPresentationMesh* getMesh() { return getPresentation(); } + scene::IAnimatedMeshSceneNode* getMesh(); /** Should only be used on particle emitter track objects. * On the script side, the returned object is of type : @ref Scripting_ParticleEmitter */ diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index 7a2914171..8f70e1ee6 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -358,11 +358,13 @@ void TrackObjectPresentationLOD::reset() dynamic_cast(node); if (a_node) { + a_node->setLoopMode(true); + a_node->setAnimationEndCallback(NULL); RandomGenerator rg; int animation_set = 0; if (a_node->getAnimationSetNum() > 0) animation_set = rg.get(a_node->getAnimationSetNum()); - a_node->useAnimationSet(animation_set); + a_node->useAnimationSet(animation_set); } } } @@ -642,6 +644,7 @@ void TrackObjectPresentationMesh::reset() a_node->setRotation(m_init_hpr); a_node->setScale(m_init_scale); a_node->setLoopMode(m_is_looped); + a_node->setAnimationEndCallback(NULL); a_node->setCurrentFrame((float)(a_node->getStartFrame())); // trick to reset the animation AND also the timer inside it @@ -658,49 +661,6 @@ void TrackObjectPresentationMesh::reset() } } // reset -// ---------------------------------------------------------------------------- -int TrackObjectPresentationMesh::getCurrentFrame() -{ - if (m_node->getType() == scene::ESNT_ANIMATED_MESH) - { - scene::IAnimatedMeshSceneNode *a_node = - (scene::IAnimatedMeshSceneNode*)m_node; - - return (int)a_node->getFrameNr(); - } - return -1; //Not a skeletal animation -} // getCurrentFrame - -// ---------------------------------------------------------------------------- -void TrackObjectPresentationMesh::setCurrentFrame(int frame) -{ - if (m_node->getType() == scene::ESNT_ANIMATED_MESH) - { - scene::IAnimatedMeshSceneNode *a_node = - (scene::IAnimatedMeshSceneNode*)m_node; - - a_node->setCurrentFrame((f32)frame); - } -} // setCurrentFrame - -// ---------------------------------------------------------------------------- -/** Set custom loops, as well as pause by scripts. - * \param start Start frame. - * \param end End frame. - */ -void TrackObjectPresentationMesh::setLoop(int start, int end) -{ - if (m_node->getType() == scene::ESNT_ANIMATED_MESH) - { - scene::IAnimatedMeshSceneNode *a_node = - (scene::IAnimatedMeshSceneNode*)m_node; - - // irrlicht's "setFrameLoop" is a misnomer, it just sets the first and - // last frame, even if looping is disabled - a_node->setFrameLoop(start, end); - } -} // setLoop - // ---------------------------------------------------------------------------- TrackObjectPresentationSound::TrackObjectPresentationSound( const XMLNode& xml_node, @@ -1094,7 +1054,8 @@ void TrackObjectPresentationLight::setEnergy(float energy) } // ---------------------------------------------------------------------------- TrackObjectPresentationActionTrigger::TrackObjectPresentationActionTrigger( - const XMLNode& xml_node) + const XMLNode& xml_node, + TrackObject* parent) : TrackObjectPresentation(xml_node) { float trigger_distance = 1.0f; @@ -1115,11 +1076,36 @@ TrackObjectPresentationActionTrigger::TrackObjectPresentationActionTrigger( { assert(false); } + m_xml_reenable_timeout = 999999.9f; + xml_node.get("reenable-timeout", &m_xml_reenable_timeout); + m_reenable_timeout = 0.0f; - m_action_active = true; - - if (m_action.size() == 0) + if (m_action.empty()) + { Log::warn("TrackObject", "Action-trigger has no action defined."); + return; + } + + if (parent != NULL) + { + core::vector3df parent_xyz = parent->getInitXYZ(); + core::vector3df parent_rot = parent->getInitRotation(); + core::vector3df parent_scale = parent->getInitScale(); + core::matrix4 lm, sm, rm; + lm.setTranslation(parent_xyz); + sm.setScale(parent_scale); + rm.setRotationDegrees(parent_rot); + core::matrix4 abs_trans = lm * rm * sm; + + m_library_id = parent->getID(); + m_library_name = parent->getName(); + xml_node.get("triggered-object", &m_triggered_object); + if (!m_library_id.empty() && !m_triggered_object.empty() && + !m_library_name.empty()) + { + abs_trans.transformVect(m_init_xyz); + } + } if (m_type == TRIGGER_TYPE_POINT) { @@ -1149,7 +1135,8 @@ TrackObjectPresentationActionTrigger::TrackObjectPresentationActionTrigger( m_init_scale = core::vector3df(1, 1, 1); float trigger_distance = distance; m_action = script_name; - m_action_active = true; + m_xml_reenable_timeout = 999999.9f; + m_reenable_timeout = 0.0f; m_type = TRIGGER_TYPE_POINT; ItemManager::get()->newItem(m_init_xyz, trigger_distance, this); } // TrackObjectPresentationActionTrigger @@ -1157,13 +1144,36 @@ TrackObjectPresentationActionTrigger::TrackObjectPresentationActionTrigger( // ---------------------------------------------------------------------------- void TrackObjectPresentationActionTrigger::onTriggerItemApproached() { - if (!m_action_active) return; + if (m_reenable_timeout > 0.0f) + { + return; + } + m_reenable_timeout = m_xml_reenable_timeout; - m_action_active = false; // TODO: allow auto re-activating? - int idKart = 0; + int kart_id = 0; Camera* camera = Camera::getActiveCamera(); if (camera != NULL && camera->getKart() != NULL) - idKart = camera->getKart()->getWorldKartId(); - Scripting::ScriptEngine::getInstance()->runFunction(true, "void " + m_action + "(int)", - [=](asIScriptContext* ctx) { ctx->SetArgDWord(0, idKart); }); + { + kart_id = camera->getKart()->getWorldKartId(); + } + if (!m_library_id.empty() && !m_triggered_object.empty() && + !m_library_name.empty()) + { + Scripting::ScriptEngine::getInstance()->runFunction(true, "void " + + m_library_name + "::" + m_action + + "(int, const string, const string)", [=](asIScriptContext* ctx) + { + ctx->SetArgDWord(0, kart_id); + ctx->SetArgObject(1, &m_library_id); + ctx->SetArgObject(2, &m_triggered_object); + }); + } + else + { + Scripting::ScriptEngine::getInstance()->runFunction(true, + "void " + m_action + "(int)", [=](asIScriptContext* ctx) + { + ctx->SetArgDWord(0, kart_id); + }); + } } // onTriggerItemApproached diff --git a/src/tracks/track_object_presentation.hpp b/src/tracks/track_object_presentation.hpp index 000ee5071..ed87ad248 100644 --- a/src/tracks/track_object_presentation.hpp +++ b/src/tracks/track_object_presentation.hpp @@ -251,9 +251,6 @@ public: const core::vector3df& hpr, const core::vector3df& scale); virtual ~TrackObjectPresentationMesh(); - void setLoop(int start, int end); - void setCurrentFrame(int frame); - int getCurrentFrame(); virtual void reset() OVERRIDE; // ------------------------------------------------------------------------ /** Returns the mode file name. */ @@ -382,14 +379,15 @@ class TrackObjectPresentationActionTrigger : public TrackObjectPresentation, { private: /** For action trigger objects */ - std::string m_action; + std::string m_action, m_library_id, m_triggered_object, m_library_name; - bool m_action_active; + float m_xml_reenable_timeout, m_reenable_timeout; ActionTriggerType m_type; public: - TrackObjectPresentationActionTrigger(const XMLNode& xml_node); + TrackObjectPresentationActionTrigger(const XMLNode& xml_node, + TrackObject* parent); TrackObjectPresentationActionTrigger(const core::vector3df& xyz, const std::string& scriptname, float distance); @@ -399,11 +397,23 @@ public: virtual void onTriggerItemApproached() OVERRIDE; // ------------------------------------------------------------------------ /** Reset the trigger (i.e. sets it to active again). */ - virtual void reset() OVERRIDE { m_action_active = true; } + virtual void reset() OVERRIDE { m_reenable_timeout = 0.0f; } + // ------------------------------------------------------------------------ + virtual void update(float dt) OVERRIDE + { + if (m_reenable_timeout < 900000.0f) + { + m_reenable_timeout -= dt; + } + } // ------------------------------------------------------------------------ /** Sets the trigger to be enabled or disabled. */ - virtual void setEnable(bool status) OVERRIDE{ m_action_active = status; } + virtual void setEnable(bool status) OVERRIDE + { m_reenable_timeout = status ? 0.0f : 999999.9f; } + // ------------------------------------------------------------------------ + void setReenableTimeout(float time) { m_reenable_timeout = time; } }; // class TrackObjectPresentationActionTrigger #endif // TRACKOBJECTPRESENTATION_HPP + From 79c6705bb14f1af96d47e1e2fdd73ea737190a66 Mon Sep 17 00:00:00 2001 From: Benau Date: Wed, 9 Aug 2017 13:00:09 +0800 Subject: [PATCH 09/19] Fix #2814 --- data/shaders/grass_pass.vert | 2 +- data/shaders/grass_pass2.frag | 21 +----------- data/shaders/instanced_grass.vert | 2 +- data/shaders/instanced_grass_pass2.frag | 25 ++------------ src/graphics/command_buffer.cpp | 20 ------------ src/graphics/command_buffer.hpp | 10 +----- src/graphics/draw_policies.cpp | 43 ------------------------- src/graphics/materials.cpp | 14 ++++---- src/graphics/materials.hpp | 4 +-- 9 files changed, 14 insertions(+), 127 deletions(-) diff --git a/data/shaders/grass_pass.vert b/data/shaders/grass_pass.vert index e6903c19e..c3c5d3721 100644 --- a/data/shaders/grass_pass.vert +++ b/data/shaders/grass_pass.vert @@ -20,7 +20,7 @@ out vec2 uv; void main() { - vec3 test = sin(windDir * (Position.y* 0.5)) * 0.5; + vec3 test = sin(windDir * (Position.y * 0.1)) * 1.; test += cos(windDir) * 0.7; mat4 new_model_matrix = ModelMatrix; diff --git a/data/shaders/grass_pass2.frag b/data/shaders/grass_pass2.frag index b5ebadbd9..c6d18a6c9 100644 --- a/data/shaders/grass_pass2.frag +++ b/data/shaders/grass_pass2.frag @@ -1,11 +1,9 @@ #ifdef Use_Bindless_Texture layout(bindless_sampler) uniform sampler2D Albedo; -layout(bindless_sampler) uniform sampler2D dtex; layout(bindless_sampler) uniform sampler2D SpecMap; layout(bindless_sampler) uniform sampler2D colorization_mask; #else uniform sampler2D Albedo; -uniform sampler2D dtex; uniform sampler2D SpecMap; uniform sampler2D colorization_mask; #endif @@ -36,25 +34,8 @@ void main(void) vec2 new_xy = mix(vec2(old_hsv.x, old_hsv.y), vec2(color_change.x, max(old_hsv.y, color_change.y)), vec2(mask_step, mask_step)); color.xyz = hsvToRgb(vec3(new_xy.x, new_xy.y, old_hsv.z)); } - - vec2 texc = gl_FragCoord.xy / screen; - float z = texture(dtex, texc).x; - - vec4 xpos = 2.0 * vec4(texc, z, 1.0) - 1.0f; - xpos = InverseProjectionMatrix * xpos; - xpos /= xpos.w; - vec3 eyedir = normalize(xpos.xyz); - - // Inspired from http://http.developer.nvidia.com/GPUGems3/gpugems3_ch16.html - vec3 L = normalize((transpose(InverseViewMatrix) * vec4(sun_direction, 0.)).xyz); - float fEdotL = clamp(dot(L, eyedir), 0., 1.); - float fPowEdotL = pow(fEdotL, 4.); - - float fLdotNBack = max(0., - dot(nor, L) * 0.6 + 0.4); - float scattering = mix(fPowEdotL, fLdotNBack, .5); - float specmap = texture(SpecMap, uv).g; float emitmap = texture(SpecMap, uv).b; - vec3 LightFactor = color.xyz * (scattering * 0.1) + getLightFactor(color.xyz, vec3(1.), specmap, emitmap); + vec3 LightFactor = getLightFactor(color.xyz, vec3(1.), specmap, emitmap); FragColor = vec4(LightFactor, 1.); } diff --git a/data/shaders/instanced_grass.vert b/data/shaders/instanced_grass.vert index 0127a8346..92cac1e4f 100644 --- a/data/shaders/instanced_grass.vert +++ b/data/shaders/instanced_grass.vert @@ -41,7 +41,7 @@ flat out sampler2D thirdhandle; void main() { - vec3 test = sin(windDir * (Position.y* 0.5)) * 0.5; + vec3 test = sin(windDir * (Position.y * 0.1)) * 1.; test += cos(windDir) * 0.7; mat4 ModelMatrix = getWorldMatrix(Origin + test * Color.r, Orientation, Scale); mat4 TransposeInverseModelView = transpose(getInverseWorldMatrix(Origin + test * Color.r, Orientation, Scale) * InverseViewMatrix); diff --git a/data/shaders/instanced_grass_pass2.frag b/data/shaders/instanced_grass_pass2.frag index 6ba698f7b..0577f3f75 100644 --- a/data/shaders/instanced_grass_pass2.frag +++ b/data/shaders/instanced_grass_pass2.frag @@ -1,9 +1,6 @@ -#ifdef Use_Bindless_Texture -layout(bindless_sampler) uniform sampler2D dtex; -#else +#ifndef Use_Bindless_Texture uniform sampler2D Albedo; uniform sampler2D SpecMap; -uniform sampler2D dtex; uniform sampler2D colorization_mask; #endif @@ -45,24 +42,6 @@ void main(void) vec2 new_xy = mix(vec2(old_hsv.x, old_hsv.y), vec2(color_change.x, max(old_hsv.y, color_change.y)), vec2(mask_step, mask_step)); color.xyz = hsvToRgb(vec3(new_xy.x, new_xy.y, old_hsv.z)); } - - vec2 texc = gl_FragCoord.xy / screen; - float z = texture(dtex, texc).x; - - vec4 xpos = 2.0 * vec4(texc, z, 1.0) - 1.0f; - xpos = InverseProjectionMatrix * xpos; - xpos /= xpos.w; - vec3 eyedir = normalize(xpos.xyz); - - // Inspired from http://http.developer.nvidia.com/GPUGems3/gpugems3_ch16.html - vec3 L = normalize((transpose(InverseViewMatrix) * vec4(sun_direction, 0.)).xyz); - float fEdotL = clamp(dot(L, eyedir), 0., 1.); - float fPowEdotL = pow(fEdotL, 4.); - - float fLdotNBack = max(0., - dot(nor, L) * 0.6 + 0.4); - float scattering = mix(fPowEdotL, fLdotNBack, .5); - - vec3 LightFactor = color.xyz * (scattering * 0.1) + getLightFactor(color.xyz, vec3(1.), specmap, emitmap); - + vec3 LightFactor = getLightFactor(color.xyz, vec3(1.), specmap, emitmap); FragColor = vec4(LightFactor, 1.); } diff --git a/src/graphics/command_buffer.cpp b/src/graphics/command_buffer.cpp index 24df0d6cb..761ae122b 100644 --- a/src/graphics/command_buffer.cpp +++ b/src/graphics/command_buffer.cpp @@ -80,26 +80,6 @@ void InstanceFiller::add(GLMesh* mesh, instance.Color = nd->getGlowColor().color; } -// ---------------------------------------------------------------------------- -template<> -void expandTexSecondPass(const GLMesh &mesh, - const std::vector &prefilled_tex) -{ - TexExpander:: - expandTex(mesh, GrassMat::SecondPassTextures, prefilled_tex[0], - prefilled_tex[1], prefilled_tex[2], prefilled_tex[3]); -} - -// ---------------------------------------------------------------------------- -template<> -void expandHandlesSecondPass(const std::vector &handles) -{ - uint64_t nulltex[10] = {}; - HandleExpander:: - expand(nulltex, GrassMat::SecondPassTextures, - handles[0], handles[1], handles[2], handles[3]); -} - #if !defined(USE_GLES2) // ---------------------------------------------------------------------------- template diff --git a/src/graphics/command_buffer.hpp b/src/graphics/command_buffer.hpp index 565b2c7b2..c1e7543bd 100644 --- a/src/graphics/command_buffer.hpp +++ b/src/graphics/command_buffer.hpp @@ -112,11 +112,7 @@ void expandTexSecondPass(const GLMesh &mesh, expandTex(mesh, T::SecondPassTextures, prefilled_tex[0], prefilled_tex[1], prefilled_tex[2]); } - -template<> -void expandTexSecondPass(const GLMesh &mesh, - const std::vector &prefilled_tex); - + // ---------------------------------------------------------------------------- /** Give acces textures for second rendering pass in shaders * without first binding them in order to reduce driver overhead. @@ -133,10 +129,6 @@ void expandHandlesSecondPass(const std::vector &handles) handles[0], handles[1], handles[2]); } -template<> -void expandHandlesSecondPass(const std::vector &handles); - - #if !defined(USE_GLES2) // ---------------------------------------------------------------------------- /** diff --git a/src/graphics/draw_policies.cpp b/src/graphics/draw_policies.cpp index 9414caa8c..b9e593f2e 100644 --- a/src/graphics/draw_policies.cpp +++ b/src/graphics/draw_policies.cpp @@ -89,49 +89,6 @@ void renderMeshes2ndPass( const std::vector &Prefilled_Handle, } } // renderMeshes2ndPass -// ---------------------------------------------------------------------------- -template<> -void renderMeshes2ndPass - (const std::vector &Prefilled_Handle, - const std::vector &Prefilled_Tex) -{ - auto &meshes = GrassMat::List::getInstance()->SolidPass; - GrassMat::SecondPassShader::getInstance()->use(); - if (CVS->isARBBaseInstanceUsable()) - glBindVertexArray(VAOManager::getInstance()->getVAO(GrassMat::VertexType)); - for (unsigned i = 0; i < meshes.size(); i++) - { - GLMesh &mesh = *(std::get<0>(meshes.at(i))); - if (!CVS->isARBBaseInstanceUsable()) - glBindVertexArray(mesh.vao); - - if (mesh.VAOType != GrassMat::VertexType) - { -#ifdef DEBUG - Log::error("Materials", "Wrong vertex Type associed to pass 2 " - "(hint texture : %s)", - mesh.textures[0]->getName().getPath().c_str()); -#endif - continue; - } - - if (CVS->isAZDOEnabled()) - { - HandleExpander:: - expand(mesh.TextureHandles, GrassMat::SecondPassTextures, - Prefilled_Handle[0], Prefilled_Handle[1], - Prefilled_Handle[2], Prefilled_Handle[3]); - } - else - { - TexExpander:: - expandTex(mesh, GrassMat::SecondPassTextures, Prefilled_Tex[0], - Prefilled_Tex[1], Prefilled_Tex[2], Prefilled_Tex[3]); - } - CustomUnrollArgs<4, 3, 1>::drawMesh(meshes.at(i)); - } -} // renderMeshes2ndPass - // ---------------------------------------------------------------------------- template void renderShadow(unsigned cascade) diff --git a/src/graphics/materials.cpp b/src/graphics/materials.cpp index e7b098071..681f43b76 100644 --- a/src/graphics/materials.cpp +++ b/src/graphics/materials.cpp @@ -432,10 +432,9 @@ GrassPass2Shader::GrassPass2Shader() assignSamplerNames(0, "DiffuseMap", ST_NEAREST_FILTERED, 1, "SpecularMap", ST_NEAREST_FILTERED, 2, "SSAO", ST_BILINEAR_FILTERED, - 3, "dtex", ST_NEAREST_FILTERED, - 4, "Albedo", ST_TRILINEAR_ANISOTROPIC_FILTERED, - 5, "SpecMap", ST_TRILINEAR_ANISOTROPIC_FILTERED, - 6, "colorization_mask", + 3, "Albedo", ST_TRILINEAR_ANISOTROPIC_FILTERED, + 4, "SpecMap", ST_TRILINEAR_ANISOTROPIC_FILTERED, + 5, "colorization_mask", ST_TRILINEAR_ANISOTROPIC_FILTERED); } // GrassPass2Shader @@ -448,10 +447,9 @@ InstancedGrassPass2Shader::InstancedGrassPass2Shader() assignSamplerNames(0, "DiffuseMap", ST_NEAREST_FILTERED, 1, "SpecularMap", ST_NEAREST_FILTERED, 2, "SSAO", ST_BILINEAR_FILTERED, - 3, "dtex", ST_NEAREST_FILTERED, - 4, "Albedo", ST_TRILINEAR_ANISOTROPIC_FILTERED, - 5, "SpecMap", ST_TRILINEAR_ANISOTROPIC_FILTERED, - 6, "colorization_mask", + 3, "Albedo", ST_TRILINEAR_ANISOTROPIC_FILTERED, + 4, "SpecMap", ST_TRILINEAR_ANISOTROPIC_FILTERED, + 5, "colorization_mask", ST_TRILINEAR_ANISOTROPIC_FILTERED); } // InstancedGrassPass2Shader diff --git a/src/graphics/materials.hpp b/src/graphics/materials.hpp index 4bc52bd82..8cce5a087 100644 --- a/src/graphics/materials.hpp +++ b/src/graphics/materials.hpp @@ -260,7 +260,7 @@ public: }; // InstancedGrassShadowShader // ============================================================================ -class GrassPass2Shader : public TextureShader { @@ -270,7 +270,7 @@ public: // ============================================================================ class InstancedGrassPass2Shader - : public TextureShader + : public TextureShader { public: InstancedGrassPass2Shader(); From cc8331f5cdf8a51b473fcb71b7d34f487478cb51 Mon Sep 17 00:00:00 2001 From: Benau Date: Wed, 9 Aug 2017 15:03:37 +0800 Subject: [PATCH 10/19] Fix #2897 --- data/shaders/billboard.frag | 2 ++ data/shaders/billboard.vert | 6 ++-- src/graphics/shader_based_renderer.cpp | 2 ++ src/graphics/stk_billboard.cpp | 49 ++++++++++++++++++-------- src/graphics/stk_billboard.hpp | 5 +++ 5 files changed, 48 insertions(+), 16 deletions(-) diff --git a/data/shaders/billboard.frag b/data/shaders/billboard.frag index 7b7af00a8..6f583946a 100644 --- a/data/shaders/billboard.frag +++ b/data/shaders/billboard.frag @@ -1,10 +1,12 @@ uniform sampler2D tex; in vec2 uv; +in vec4 vertex_color; out vec4 FragColor; void main(void) { vec4 color = texture(tex, uv); + color *= vertex_color; FragColor = vec4(color.a * color.rgb, color.a); } diff --git a/data/shaders/billboard.vert b/data/shaders/billboard.vert index 06882526d..c47b2f15a 100644 --- a/data/shaders/billboard.vert +++ b/data/shaders/billboard.vert @@ -1,4 +1,4 @@ -uniform mat4 ModelViewMatrix; +uniform mat4 color_matrix; uniform vec3 Position; uniform vec2 Size; @@ -11,10 +11,12 @@ in vec2 Texcoord; #endif out vec2 uv; +out vec4 vertex_color; void main(void) { uv = Texcoord; - vec4 Center = ModelViewMatrix * vec4(Position, 1.); + vec4 Center = ViewMatrix * vec4(Position, 1.); gl_Position = ProjectionMatrix * (Center + vec4(Size * Corner, 0., 0.)); + vertex_color = color_matrix[gl_VertexID]; } diff --git a/src/graphics/shader_based_renderer.cpp b/src/graphics/shader_based_renderer.cpp index 1d253cb58..8a86c2464 100644 --- a/src/graphics/shader_based_renderer.cpp +++ b/src/graphics/shader_based_renderer.cpp @@ -33,6 +33,7 @@ #include "graphics/rtts.hpp" #include "graphics/shaders.hpp" #include "graphics/skybox.hpp" +#include "graphics/stk_billboard.hpp" #include "graphics/stk_mesh_scene_node.hpp" #include "graphics/spherical_harmonics.hpp" #include "items/item_manager.hpp" @@ -659,6 +660,7 @@ ShaderBasedRenderer::~ShaderBasedRenderer() delete m_skybox; delete m_rtts; ShaderFilesManager::kill(); + STKBillboard::destroyBillboardVAO(); } // ---------------------------------------------------------------------------- diff --git a/src/graphics/stk_billboard.cpp b/src/graphics/stk_billboard.cpp index 2a3d99ca8..53c0cb39c 100644 --- a/src/graphics/stk_billboard.cpp +++ b/src/graphics/stk_billboard.cpp @@ -30,10 +30,10 @@ using namespace irr; -static GLuint billboardvao = 0; +GLuint STKBillboard::m_billboard_vao = 0; -class BillboardShader : public TextureShader { @@ -43,18 +43,16 @@ public: loadProgram(OBJECT, GL_VERTEX_SHADER, "billboard.vert", GL_FRAGMENT_SHADER, "billboard.frag"); - assignUniforms("ModelViewMatrix", "ProjectionMatrix", "Position", - "Size"); + assignUniforms("color_matrix", "Position", "Size"); assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED); } // BillboardShader }; // BillboardShader // ============================================================================ - -static void createBillboardVAO() +void STKBillboard::createBillboardVAO() { - glGenVertexArrays(1, &billboardvao); - glBindVertexArray(billboardvao); + glGenVertexArrays(1, &m_billboard_vao); + glBindVertexArray(m_billboard_vao); glBindBuffer(GL_ARRAY_BUFFER, SharedGPUObjects::getBillboardVBO()); glEnableVertexAttribArray(0); glEnableVertexAttribArray(3); @@ -64,6 +62,16 @@ static void createBillboardVAO() glBindVertexArray(0); } // createBillboardVAO +// ---------------------------------------------------------------------------- +void STKBillboard::destroyBillboardVAO() +{ + if (m_billboard_vao != 0) + { + glDeleteVertexArrays(1, &m_billboard_vao); + m_billboard_vao = 0; + } +} // destroyBillboardVAO + // ---------------------------------------------------------------------------- STKBillboard::STKBillboard(irr::scene::ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id, @@ -75,7 +83,7 @@ STKBillboard::STKBillboard(irr::scene::ISceneNode* parent, CBillboardSceneNode(parent, mgr, id, position, size, colorTop, colorBottom) { - if (!billboardvao) + if (!m_billboard_vao) createBillboardVAO(); } // STKBillboard @@ -97,9 +105,9 @@ void STKBillboard::render() return; core::vector3df pos = getAbsolutePosition(); - glBindVertexArray(billboardvao); + glBindVertexArray(m_billboard_vao); video::ITexture *tex = Material.getTexture(0); - if (!tex ) + if (!tex) return; ::Material* material = material_manager->getMaterialFor(tex, @@ -109,11 +117,24 @@ void STKBillboard::render() else glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + video::SColor col[2]; + getColor(col[0], col[1]); + const float colors[] = + { + col[1].getRed() / 255.f, col[1].getGreen() / 255.f, + col[1].getBlue() / 255.f, col[1].getAlpha() / 255.f, + col[0].getRed() / 255.f, col[0].getGreen() / 255.f, + col[0].getBlue() / 255.f, col[0].getAlpha() / 255.f, + col[1].getRed() / 255.f, col[1].getGreen() / 255.f, + col[1].getBlue() / 255.f, col[1].getAlpha() / 255.f, + col[0].getRed() / 255.f, col[0].getGreen() / 255.f, + col[0].getBlue() / 255.f, col[0].getAlpha() / 255.f, + }; + core::matrix4 color_matrix; + color_matrix.setM(colors); BillboardShader::getInstance()->use(); BillboardShader::getInstance()->setTextureUnits(tex->getOpenGLTextureName()); - BillboardShader::getInstance()->setUniforms(irr_driver->getViewMatrix(), - irr_driver->getProjMatrix(), - pos, Size); + BillboardShader::getInstance()->setUniforms(color_matrix, pos, Size); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindVertexArray(0); } // render diff --git a/src/graphics/stk_billboard.hpp b/src/graphics/stk_billboard.hpp index 63ef48d4d..b8a8be723 100644 --- a/src/graphics/stk_billboard.hpp +++ b/src/graphics/stk_billboard.hpp @@ -21,10 +21,14 @@ #include "../lib/irrlicht/source/Irrlicht/CBillboardSceneNode.h" #include #include +#include "graphics/gl_headers.hpp" #include "utils/cpp2011.hpp" class STKBillboard : public irr::scene::CBillboardSceneNode { +private: + static GLuint m_billboard_vao; + static void createBillboardVAO(); public: STKBillboard(irr::scene::ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id, const irr::core::vector3df& position, @@ -35,6 +39,7 @@ public: virtual void OnRegisterSceneNode() OVERRIDE; virtual void render() OVERRIDE; + static void destroyBillboardVAO(); }; // STKBillboard #endif From 861e7f7ebd885a1bb19d795c2dbe98ae1c2675fc Mon Sep 17 00:00:00 2001 From: Benau Date: Wed, 9 Aug 2017 15:36:26 +0800 Subject: [PATCH 11/19] Remove contradiction --- src/karts/kart_model.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/karts/kart_model.cpp b/src/karts/kart_model.cpp index ebd1fb17c..111eab374 100644 --- a/src/karts/kart_model.cpp +++ b/src/karts/kart_model.cpp @@ -273,7 +273,6 @@ KartModel::~KartModel() for (size_t i = 0; i < m_headlight_objects.size(); i++) { HeadlightObject& obj = m_headlight_objects[i]; - obj.setNode(NULL); if (obj.getNode()) { // Master KartModels should never have a headlight attached. From 936ef3c4c732aaa126a116d1ed853ec3f952cab4 Mon Sep 17 00:00:00 2001 From: "auria.mg" Date: Wed, 9 Aug 2017 19:37:49 -0400 Subject: [PATCH 12/19] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f12f5b50..ba326e73e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ * Hardware skinning * New smoother camera by Auria * New grand prix win scene +* Gamepad configuration bugfixes * Various improvements (wall driving fixes, parachutes, GP points, cannon fixes, colorization shader) ## SuperTuxKart 0.9.2 From 3923da30bcbaa33160297280cf825dafd8d53dd6 Mon Sep 17 00:00:00 2001 From: hiker Date: Fri, 11 Aug 2017 09:41:22 +1000 Subject: [PATCH 13/19] Use unique names for profiler events. --- src/main_loop.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main_loop.cpp b/src/main_loop.cpp index 6f97697f2..446320c0e 100644 --- a/src/main_loop.cpp +++ b/src/main_loop.cpp @@ -256,7 +256,7 @@ void MainLoop::run() // enabled. if (!m_abort && !ProfileWorld::isNoGraphics()) { - PROFILER_PUSH_CPU_MARKER("Music/input/GUI", 0x7F, 0x00, 0x00); + PROFILER_PUSH_CPU_MARKER("Input/GUI", 0x7F, 0x00, 0x00); input_manager->update(dt); #ifdef ENABLE_WIIUSE @@ -269,7 +269,7 @@ void MainLoop::run() // Update sfx and music after graphics, so that graphics code // can use as many threads as possible without interfering // with audio - PROFILER_PUSH_CPU_MARKER("Music/input/GUI", 0x7F, 0x00, 0x00); + PROFILER_PUSH_CPU_MARKER("Music", 0x7F, 0x00, 0x00); SFXManager::get()->update(); PROFILER_POP_CPU_MARKER(); From cf868df93f628e56301b0064dffd32c469fd3bb1 Mon Sep 17 00:00:00 2001 From: Deve Date: Sun, 13 Aug 2017 01:03:13 +0200 Subject: [PATCH 14/19] Fixed memory leaks in wayland device --- .../source/Irrlicht/CIrrDeviceWayland.cpp | 44 ++++++++++++++++--- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceWayland.cpp b/lib/irrlicht/source/Irrlicht/CIrrDeviceWayland.cpp index 8493ecf5a..6ceff83f3 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceWayland.cpp +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceWayland.cpp @@ -715,6 +715,9 @@ CIrrDeviceWayland::CIrrDeviceWayland(const SIrrlichtCreationParameters& params) CIrrDeviceWayland::~CIrrDeviceWayland() { delete m_egl_context; + + if (m_egl_window) + wl_egl_window_destroy(m_egl_window); if (m_keyboard) wl_keyboard_destroy(m_keyboard); @@ -730,15 +733,46 @@ CIrrDeviceWayland::~CIrrDeviceWayland() if (m_shell_surface) wl_shell_surface_destroy(m_shell_surface); + + if (m_surface) + wl_surface_destroy(m_surface); + + if (m_shell) + wl_shell_destroy(m_shell); + + if (m_shm) + wl_shm_destroy(m_shm); + + if (m_compositor) + wl_compositor_destroy(m_compositor); + + if (m_output) + wl_output_destroy(m_output); + + if (m_seat) + wl_seat_destroy(m_seat); + + if (m_registry) + wl_registry_destroy(m_registry); + + if (m_xkb_state) + xkb_state_unref(m_xkb_state); + + if (m_xkb_keymap) + xkb_keymap_unref(m_xkb_keymap); + + if (m_xkb_compose_state) + xkb_compose_state_unref(m_xkb_compose_state); + + if (m_xkb_compose_table) + xkb_compose_table_unref(m_xkb_compose_table); + + if (m_xkb_context) + xkb_context_unref(m_xkb_context); - wl_output_destroy(m_output); - wl_seat_destroy(m_seat); - wl_registry_destroy(m_registry); wl_display_flush(m_display); wl_display_disconnect(m_display); - xkb_context_unref(m_xkb_context); - closeJoysticks(); } From fd4ab9d88f94c794f349c454d3c0012bdd0bc9c3 Mon Sep 17 00:00:00 2001 From: Deve Date: Sun, 13 Aug 2017 01:04:19 +0200 Subject: [PATCH 15/19] Fixed possible uninitialized variable in gles renderer --- lib/irrlicht/source/Irrlicht/COGLES2MaterialRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/irrlicht/source/Irrlicht/COGLES2MaterialRenderer.cpp b/lib/irrlicht/source/Irrlicht/COGLES2MaterialRenderer.cpp index fea967bee..a068dbf3f 100644 --- a/lib/irrlicht/source/Irrlicht/COGLES2MaterialRenderer.cpp +++ b/lib/irrlicht/source/Irrlicht/COGLES2MaterialRenderer.cpp @@ -93,7 +93,7 @@ COGLES2MaterialRenderer::~COGLES2MaterialRenderer() if (Program) { GLuint shaders[8]; - GLint count; + GLint count = 0; glGetAttachedShaders(Program, 8, &count, shaders); count=core::min_(count,8); From ee5bdad9260d6eb65245f6fed0529334f0e61e95 Mon Sep 17 00:00:00 2001 From: Deve Date: Sun, 13 Aug 2017 01:12:00 +0200 Subject: [PATCH 16/19] Move output/seat listener to better place --- lib/irrlicht/source/Irrlicht/CIrrDeviceWayland.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceWayland.cpp b/lib/irrlicht/source/Irrlicht/CIrrDeviceWayland.cpp index 6ceff83f3..0c504d84f 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceWayland.cpp +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceWayland.cpp @@ -537,6 +537,7 @@ public: device->m_seat = static_cast(wl_registry_bind(registry, name, &wl_seat_interface, version < 4 ? version : 4)); + wl_seat_add_listener(device->m_seat, &seat_listener, device); } else if (interface_str == "wl_shm") { @@ -547,6 +548,7 @@ public: { device->m_output = static_cast(wl_registry_bind(registry, name, &wl_output_interface, 2)); + wl_output_add_listener(device->m_output, &output_listener, device); } } @@ -700,9 +702,6 @@ CIrrDeviceWayland::CIrrDeviceWayland(const SIrrlichtCreationParameters& params) return; } - wl_seat_add_listener(m_seat, &WaylandCallbacks::seat_listener, this); - wl_output_add_listener(m_output, &WaylandCallbacks::output_listener, this); - createDriver(); if (VideoDriver) From 1f4a9135b63e2c7fd258c0e91f23d2b02ed98998 Mon Sep 17 00:00:00 2001 From: Deve Date: Sun, 13 Aug 2017 01:20:22 +0200 Subject: [PATCH 17/19] Remove useless elif --- src/graphics/shader_based_renderer.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/graphics/shader_based_renderer.cpp b/src/graphics/shader_based_renderer.cpp index 8a86c2464..0a6aca980 100644 --- a/src/graphics/shader_based_renderer.cpp +++ b/src/graphics/shader_based_renderer.cpp @@ -59,12 +59,9 @@ void ShaderBasedRenderer::setRTT(RTT* rtts) rtts->getDepthStencilTexture()); m_geometry_passes->setFirstPassRenderTargets(prefilled_textures, rtts->getPrefilledHandles()); - m_rtts = rtts; - } - else if (rtts == NULL) - { - m_rtts = NULL; } + + m_rtts = rtts; } //setRTT // ---------------------------------------------------------------------------- From 0bf0ca0a35b31e5161a60cb09e8c700af1ffd57a Mon Sep 17 00:00:00 2001 From: Deve Date: Sun, 13 Aug 2017 01:34:43 +0200 Subject: [PATCH 18/19] Fixed memory leak --- src/input/device_manager.cpp | 6 ++++++ src/input/device_manager.hpp | 1 + 2 files changed, 7 insertions(+) diff --git a/src/input/device_manager.cpp b/src/input/device_manager.cpp index e5fc6f144..4ea2b0059 100644 --- a/src/input/device_manager.cpp +++ b/src/input/device_manager.cpp @@ -47,6 +47,12 @@ DeviceManager::DeviceManager() m_multitouch_device = NULL; } // DeviceManager +// ----------------------------------------------------------------------------- +DeviceManager::~DeviceManager() +{ + delete m_multitouch_device; +} // ~DeviceManager + // ----------------------------------------------------------------------------- bool DeviceManager::initialize() { diff --git a/src/input/device_manager.hpp b/src/input/device_manager.hpp index 341ebaf5f..e9e0388cc 100644 --- a/src/input/device_manager.hpp +++ b/src/input/device_manager.hpp @@ -103,6 +103,7 @@ public: DeviceManager(); + ~DeviceManager(); // ---- Assign mode ---- PlayerAssignMode getAssignMode() const { return m_assign_mode; } From 71bbafadbd35a98921208c3fa74a7fd99941df0c Mon Sep 17 00:00:00 2001 From: Deve Date: Sun, 13 Aug 2017 22:02:55 +0200 Subject: [PATCH 19/19] Fixed memory leaks in gles --- lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp | 3 +++ lib/irrlicht/source/Irrlicht/COGLES2Driver.cpp | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp index 85dd171f8..4f4ed1358 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp @@ -1218,6 +1218,9 @@ bool CIrrDeviceLinux::createInputContext() return false; } + // It's showed as memory leak, but we shouldn't delete it. From the xlib + // documentation: "The returned modifiers string is owned by Xlib and + // should not be modified or freed by the client." char* p = XSetLocaleModifiers(""); if (p == NULL) { diff --git a/lib/irrlicht/source/Irrlicht/COGLES2Driver.cpp b/lib/irrlicht/source/Irrlicht/COGLES2Driver.cpp index 77890ecf5..7b86362e7 100644 --- a/lib/irrlicht/source/Irrlicht/COGLES2Driver.cpp +++ b/lib/irrlicht/source/Irrlicht/COGLES2Driver.cpp @@ -432,6 +432,13 @@ namespace video addAndDropMaterialRenderer(new COGLES2ParallaxMapRenderer(PMVSData, PMFSData, EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA, this)); addAndDropMaterialRenderer(new COGLES2FixedPipelineRenderer(FPVSData, FPFSData, EMT_ONETEXTURE_BLEND, this)); + + delete[] FPVSData; + delete[] FPFSData; + delete[] NMVSData; + delete[] NMFSData; + delete[] PMVSData; + delete[] PMFSData; // Create 2D material renderer. @@ -476,6 +483,9 @@ namespace video R2DFSFile->drop(); MaterialRenderer2D = new COGLES2Renderer2D(R2DVSData, R2DFSData, this); + + delete[] R2DVSData; + delete[] R2DFSData; }