From 24480ea0c188ca03522eacd011002cfa8cefb79e Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Mon, 29 Sep 2014 19:12:37 -0400 Subject: [PATCH 01/73] First attempt at caching tangents meshes --- src/graphics/mesh_tools.cpp | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/graphics/mesh_tools.cpp b/src/graphics/mesh_tools.cpp index a0c05242e..a5fc3db63 100644 --- a/src/graphics/mesh_tools.cpp +++ b/src/graphics/mesh_tools.cpp @@ -22,6 +22,8 @@ #include #include "utils/log.hpp" #include "graphics/irr_driver.hpp" +#include "modes/world.hpp" +#include "tracks/track.hpp" void MeshTools::minMax3D(scene::IMesh* mesh, Vec3 *min, Vec3 *max) { @@ -325,7 +327,8 @@ bool MeshTools::isNormalMap(scene::IMeshBuffer* mb) { if (!irr_driver->isGLSL()) return false; - return (mb->getMaterial().MaterialType == irr_driver->getShader(ES_NORMAL_MAP)); + return (mb->getMaterial().MaterialType == irr_driver->getShader(ES_NORMAL_MAP) && + mb->getVertexType() != video::EVT_TANGENTS); } // Copied from irrlicht @@ -435,8 +438,29 @@ scene::IMesh* MeshTools::createMeshWithTangents(scene::IMesh* mesh, bool(*predic if (calculateTangents) recalculateTangents(clone, recalculateNormals, smooth, angleWeighted); + int mbcount = clone->getMeshBufferCount(); + for (int i = 0; i < mbcount; i++) + { + scene::IMeshBuffer* mb = clone->getMeshBuffer(i); + + for (int t = 0; t < video::MATERIAL_MAX_TEXTURES; t++) + { + video::ITexture* texture = mb->getMaterial().TextureLayer[t].Texture; + if (texture != NULL) + texture->grab(); + } + } + + scene::IMeshCache* meshCache = irr_driver->getSceneManager()->getMeshCache(); + io::SNamedPath path = meshCache->getMeshName(mesh); irr_driver->removeMeshFromCache(mesh); + scene::SAnimatedMesh* amesh = new scene::SAnimatedMesh(clone); + meshCache->addMesh(path, amesh); + amesh->drop(); + + World::getWorld()->getTrack()->addCachedMesh(amesh); + return clone; } From f0429ce95e8439abcd6d012c867893222d5ee1ae Mon Sep 17 00:00:00 2001 From: Marc Coll Carrillo Date: Sat, 11 Oct 2014 10:50:06 +0200 Subject: [PATCH 02/73] Use length limit for dynamic ribbon labels in the GP editor --- src/states_screens/edit_track_screen.cpp | 4 ++++ src/states_screens/grand_prix_editor_screen.cpp | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/src/states_screens/edit_track_screen.cpp b/src/states_screens/edit_track_screen.cpp index b492ea595..c7dcd0d2a 100644 --- a/src/states_screens/edit_track_screen.cpp +++ b/src/states_screens/edit_track_screen.cpp @@ -85,7 +85,11 @@ bool EditTrackScreen::getResult() const // ----------------------------------------------------------------------------- void EditTrackScreen::loadedFromFile() { + static const int MAX_LABEL_LENGTH = 35; + DynamicRibbonWidget* tracks_widget = getWidget("tracks"); + assert(tracks_widget != NULL); + tracks_widget->setMaxLabelLength(MAX_LABEL_LENGTH); } // ----------------------------------------------------------------------------- diff --git a/src/states_screens/grand_prix_editor_screen.cpp b/src/states_screens/grand_prix_editor_screen.cpp index 372984d0d..06405e217 100644 --- a/src/states_screens/grand_prix_editor_screen.cpp +++ b/src/states_screens/grand_prix_editor_screen.cpp @@ -62,7 +62,15 @@ void GrandPrixEditorScreen::beforeAddingWidget() // ----------------------------------------------------------------------------- void GrandPrixEditorScreen::loadedFromFile() { + static const int MAX_LABEL_LENGTH = 35; + DynamicRibbonWidget* gplist_widget = getWidget("gplist"); + assert (gplist_widget != NULL); + gplist_widget->setMaxLabelLength(MAX_LABEL_LENGTH); + + DynamicRibbonWidget* tracks_widget = getWidget("tracks"); + assert(tracks_widget != NULL); + tracks_widget->setMaxLabelLength(MAX_LABEL_LENGTH); } // ----------------------------------------------------------------------------- From 6dd9feff3662234fc03ba4e2850a02dc808f1a85 Mon Sep 17 00:00:00 2001 From: quizywiz Date: Sun, 12 Oct 2014 15:57:18 +0530 Subject: [PATCH 03/73] escape or back on friends profile takes you to your profile Also, fixed bug where user info dialog was accessing m_enter_profile after it was deleted --- src/states_screens/dialogs/user_info_dialog.cpp | 3 ++- src/states_screens/online_profile_base.cpp | 16 ++++++++++++++++ src/states_screens/online_profile_base.hpp | 2 ++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/states_screens/dialogs/user_info_dialog.cpp b/src/states_screens/dialogs/user_info_dialog.cpp index 8c457f518..698e396ce 100644 --- a/src/states_screens/dialogs/user_info_dialog.cpp +++ b/src/states_screens/dialogs/user_info_dialog.cpp @@ -479,8 +479,9 @@ void UserInfoDialog::onUpdate(float dt) // It's unsafe to delete from inside the event handler so we do it here if (m_self_destroy) { + bool enter_profile = m_enter_profile; ModalDialog::dismiss(); - if (m_enter_profile) + if (enter_profile) StateManager::get()->replaceTopMostScreen(OnlineProfileAchievements::getInstance()); return; } diff --git a/src/states_screens/online_profile_base.cpp b/src/states_screens/online_profile_base.cpp index c7b938a5c..0d90bdd0d 100644 --- a/src/states_screens/online_profile_base.cpp +++ b/src/states_screens/online_profile_base.cpp @@ -17,6 +17,7 @@ #include "states_screens/online_profile_base.hpp" +#include "config/player_manager.hpp" #include "guiengine/engine.hpp" #include "guiengine/scalable_font.hpp" #include "guiengine/screen.hpp" @@ -71,6 +72,8 @@ void OnlineProfileBase::beforeAddingWidget() m_visiting_profile = ProfileManager::get()->getVisitingProfile(); if (!m_visiting_profile || !m_visiting_profile->isCurrentUser()) m_settings_tab->setVisible(false); + else + m_settings_tab->setVisible(true); // If not logged in, don't show profile or friends if (!m_visiting_profile) @@ -103,6 +106,19 @@ void OnlineProfileBase::init() } // init +// ----------------------------------------------------------------------------- +bool OnlineProfileBase::onEscapePressed() +{ + //return to main menu if it's your profile + if (!m_visiting_profile || m_visiting_profile->isCurrentUser()) + return true; + + //return to your profile if it's another profile + ProfileManager::get()->setVisiting(PlayerManager::getCurrentOnlineId()); + StateManager::get()->replaceTopMostScreen(OnlineProfileAchievements::getInstance()); + return false; +} // onEscapePressed + // ----------------------------------------------------------------------------- /** Called when an event occurs (i.e. user clicks on something). */ diff --git a/src/states_screens/online_profile_base.hpp b/src/states_screens/online_profile_base.hpp index 956b43d9b..247de6e95 100644 --- a/src/states_screens/online_profile_base.hpp +++ b/src/states_screens/online_profile_base.hpp @@ -62,6 +62,8 @@ public: /** \brief implement callback from parent class GUIEngine::Screen */ virtual void init() OVERRIDE; + virtual bool onEscapePressed() OVERRIDE; + virtual void beforeAddingWidget() OVERRIDE; }; From 607e94ea84863ecb1483197f47129a0565e9a3c5 Mon Sep 17 00:00:00 2001 From: hiker Date: Wed, 15 Oct 2014 08:20:06 +1100 Subject: [PATCH 04/73] Fixed #1622 (missing password field in login screen). --- src/states_screens/user_screen.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/states_screens/user_screen.cpp b/src/states_screens/user_screen.cpp index 148848885..048e55e90 100644 --- a/src/states_screens/user_screen.cpp +++ b/src/states_screens/user_screen.cpp @@ -212,11 +212,15 @@ void BaseUserScreen::makeEntryFieldsVisible() getWidget("label_remember")->setVisible(online); getWidget("remember-user")->setVisible(online); PlayerProfile *player = getSelectedPlayer(); + // Don't show the password fields if the player wants to be online - // and either is the current player (no need to enter a password then) - // or has a saved session. + // and either is the current player and logged in (no need to enter a + // password then) or has a saved session. if(player && online && - (player->hasSavedSession() || player==PlayerManager::getCurrentPlayer())) + (player->hasSavedSession() || + (player==PlayerManager::getCurrentPlayer() && player->isLoggedIn() ) + ) + ) { // If we show the online login fields, but the player has a // saved session, don't show the password field. @@ -451,6 +455,7 @@ void BaseUserScreen::onUpdate(float dt) { player->clearSession(); makeEntryFieldsVisible(); + m_username_tb->setText(player->getLastOnlineName()); } } } // onUpdate From 514d0c4dfee8302470cd42c72be9554733f3f417 Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Tue, 14 Oct 2014 19:59:42 -0400 Subject: [PATCH 05/73] Work around #1626 --- src/guiengine/widgets/dynamic_ribbon_widget.cpp | 2 +- src/states_screens/options_screen_video.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/guiengine/widgets/dynamic_ribbon_widget.cpp b/src/guiengine/widgets/dynamic_ribbon_widget.cpp index ce6428911..57e110276 100644 --- a/src/guiengine/widgets/dynamic_ribbon_widget.cpp +++ b/src/guiengine/widgets/dynamic_ribbon_widget.cpp @@ -1085,7 +1085,7 @@ bool DynamicRibbonWidget::setSelection(int item_id, const int playerID, if (iterations > 50) { - Log::fatal("DynamicRibbonWidget::setSelection", "Cannot find item %d (%s)", item_id, name.c_str()); + Log::error("DynamicRibbonWidget::setSelection", "Cannot find item %d (%s)", item_id, name.c_str()); return false; } diff --git a/src/states_screens/options_screen_video.cpp b/src/states_screens/options_screen_video.cpp index c6c3a121c..ff4042496 100644 --- a/src/states_screens/options_screen_video.cpp +++ b/src/states_screens/options_screen_video.cpp @@ -310,6 +310,7 @@ void OptionsScreenVideo::init() } // end if not inited + res->setActivated(); res->updateItemDisplay(); // ---- select current resolution every time From 3fe2870c396200b7a129016f81f6db95124c90f2 Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Tue, 14 Oct 2014 20:03:50 -0400 Subject: [PATCH 06/73] Cleaner fix for #1626, closes #1626 --- src/guiengine/widgets/dynamic_ribbon_widget.cpp | 6 +++--- src/guiengine/widgets/dynamic_ribbon_widget.hpp | 2 +- src/states_screens/options_screen_video.cpp | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/guiengine/widgets/dynamic_ribbon_widget.cpp b/src/guiengine/widgets/dynamic_ribbon_widget.cpp index 57e110276..cd3d16c05 100644 --- a/src/guiengine/widgets/dynamic_ribbon_widget.cpp +++ b/src/guiengine/widgets/dynamic_ribbon_widget.cpp @@ -757,9 +757,9 @@ void DynamicRibbonWidget::onRibbonWidgetFocus(RibbonWidget* emitter, const int p #pragma mark Setters / Actions #endif -void DynamicRibbonWidget::scroll(const int x_delta) +void DynamicRibbonWidget::scroll(int x_delta, bool evenIfDeactivated) { - if (m_deactivated) return; + if (m_deactivated && !evenIfDeactivated) return; // Refuse to scroll when everything is visible if ((int)m_items.size() <= m_row_amount*m_col_amount) return; @@ -1081,7 +1081,7 @@ bool DynamicRibbonWidget::setSelection(int item_id, const int playerID, while (!findItemInRows(name.c_str(), &row, &id)) { // if we get here it means the item is scrolled out. Try to find it. - scroll(1); + scroll(1, evenIfDeactivated); if (iterations > 50) { diff --git a/src/guiengine/widgets/dynamic_ribbon_widget.hpp b/src/guiengine/widgets/dynamic_ribbon_widget.hpp index a46a28202..d2e842cf8 100644 --- a/src/guiengine/widgets/dynamic_ribbon_widget.hpp +++ b/src/guiengine/widgets/dynamic_ribbon_widget.hpp @@ -159,7 +159,7 @@ namespace GUIEngine void buildInternalStructure(); /** Call this to scroll within a scrollable ribbon */ - void scroll(const int x_delta); + void scroll(int x_delta, bool evenIfDeactivated = false); /** Used for combo ribbons, to contain the ID of the currently selected item for each player */ int m_selected_item[MAX_PLAYER_COUNT]; diff --git a/src/states_screens/options_screen_video.cpp b/src/states_screens/options_screen_video.cpp index ff4042496..c6c3a121c 100644 --- a/src/states_screens/options_screen_video.cpp +++ b/src/states_screens/options_screen_video.cpp @@ -310,7 +310,6 @@ void OptionsScreenVideo::init() } // end if not inited - res->setActivated(); res->updateItemDisplay(); // ---- select current resolution every time From 7e4e857b4190ff6d516f84dcf5e5c84653238d1b Mon Sep 17 00:00:00 2001 From: hiker Date: Wed, 15 Oct 2014 23:38:13 +1100 Subject: [PATCH 07/73] Improve situation of #1624 - it should only happen now if you pause the game in the first one or two seconds after start (still wip). --- src/audio/sfx_openal.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index 5494222c9..dd1fdb086 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -223,6 +223,7 @@ void SFXOpenAL::stop() { SFXManager::get()->queue(SFXManager::SFX_STOP, this); } // stop + //----------------------------------------------------------------------------- /** The sfx manager thread executes a stop for this sfx. */ @@ -252,7 +253,11 @@ void SFXOpenAL::pause() */ void SFXOpenAL::reallyPauseNow() { - if(m_status==SFX_UNKNOWN) return; + // This updates the status, i.e. potentially switches from + // playing to stopped. + getStatus(); + if(m_status!=SFX_PLAYING) return; + m_status = SFX_PAUSED; alSourcePause(m_sound_source); SFXManager::checkError("pausing"); @@ -271,15 +276,8 @@ void SFXOpenAL::resume() */ void SFXOpenAL::reallyResumeNow() { - if (m_status==SFX_UNKNOWN) - { - // lazily create OpenAL source when needed - init(); - - // creation of OpenAL source failed, giving up - if (m_status==SFX_UNKNOWN) return; - } - + // Will init the sfx (lazy) if necessary. + getStatus(); if(m_status==SFX_PAUSED) { alSourcePlay(m_sound_source); From bba7156affbdc37638cb8324f6b3130a6a4cb99a Mon Sep 17 00:00:00 2001 From: hiker Date: Wed, 15 Oct 2014 23:42:59 +1100 Subject: [PATCH 08/73] Handle the setting of the listener position in the sfx thread. --- src/audio/sfx_manager.cpp | 76 +++++++++++++++++++--------- src/audio/sfx_manager.hpp | 24 ++++++--- src/graphics/camera.cpp | 7 ++- src/modes/cutscene_world.cpp | 3 +- src/states_screens/state_manager.cpp | 2 +- 5 files changed, 76 insertions(+), 36 deletions(-) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 288e80c85..079c59714 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -74,7 +74,10 @@ SFXManager::SFXManager() m_initialized = music_manager->initialized(); m_master_gain = UserConfigParams::m_sfx_volume; // Init position, since it can be used before positionListener is called. - m_position = Vec3(0,0,0); + // No need to use lock here, since the thread will be created later. + m_listener_position.getData() = Vec3(0, 0, 0); + m_listener_front = Vec3(0, 0, 1); + m_listener_up = Vec3(0, 1, 0); loadSfx(); @@ -261,21 +264,21 @@ void* SFXManager::mainLoop(void *obj) me->m_sfx_commands.unlock(); switch(current->m_command) { - case SFX_PLAY: current->m_sfx->reallyPlayNow(); break; - case SFX_STOP: current->m_sfx->reallyStopNow(); break; - case SFX_PAUSE: current->m_sfx->reallyPauseNow(); break; - case SFX_RESUME: current->m_sfx->reallyResumeNow(); break; - case SFX_SPEED: current->m_sfx->reallySetSpeed( + case SFX_PLAY: current->m_sfx->reallyPlayNow(); break; + case SFX_STOP: current->m_sfx->reallyStopNow(); break; + case SFX_PAUSE: current->m_sfx->reallyPauseNow(); break; + case SFX_RESUME: current->m_sfx->reallyResumeNow(); break; + case SFX_SPEED: current->m_sfx->reallySetSpeed( current->m_parameter.getX()); break; case SFX_POSITION: current->m_sfx->reallySetPosition( current->m_parameter); break; - case SFX_VOLUME: current->m_sfx->reallySetVolume( + case SFX_VOLUME: current->m_sfx->reallySetVolume( current->m_parameter.getX()); break; - case SFX_DELETE: { - current->m_sfx->reallyStopNow(); - me->deleteSFX(current->m_sfx); - break; - } + case SFX_DELETE: { + current->m_sfx->reallyStopNow(); + me->deleteSFX(current->m_sfx); break; + } + case SFX_LISTENER: me->reallyPositionListenerNow(); break; default: assert("Not yet supported."); } delete current; @@ -702,28 +705,51 @@ const std::string SFXManager::getErrorString(int err) /** Sets the position and orientation of the listener. * \param position Position of the listener. * \param front Which way the listener is facing. + * \param up The up direction of the listener. */ -void SFXManager::positionListener(const Vec3 &position, const Vec3 &front) +void SFXManager::positionListener(const Vec3 &position, const Vec3 &front, + const Vec3 &up) +{ + m_listener_position.lock(); + m_listener_position.getData() = position; + m_listener_front = front; + m_listener_up = up; + m_listener_position.unlock(); + queue(SFX_LISTENER, NULL); +} // positionListener + +//----------------------------------------------------------------------------- +/** Sets the position and orientation of the listener. + * \param position Position of the listener. + * \param front Which way the listener is facing. + */ +void SFXManager::reallyPositionListenerNow() { #if HAVE_OGGVORBIS if (!UserConfigParams::m_sfx || !m_initialized) return; - m_position = position; + m_listener_position.lock(); + { - //forward vector - m_listenerVec[0] = front.getX(); - m_listenerVec[1] = front.getY(); - m_listenerVec[2] = front.getZ(); + //forward vector + float orientation[6]; + orientation[0] = m_listener_front.getX(); + orientation[1] = m_listener_front.getY(); + orientation[2] = m_listener_front.getZ(); - //up vector - m_listenerVec[3] = 0; - m_listenerVec[4] = 0; - m_listenerVec[5] = 1; + //up vector + orientation[3] = m_listener_up.getX(); + orientation[4] = m_listener_up.getY(); + orientation[5] = m_listener_up.getZ(); + + const Vec3 &pos = m_listener_position.getData(); + alListener3f(AL_POSITION, pos.getX(), pos.getY(), pos.getZ()); + alListenerfv(AL_ORIENTATION, orientation); + } + m_listener_position.unlock(); - alListener3f(AL_POSITION, position.getX(), position.getY(), position.getZ()); - alListenerfv(AL_ORIENTATION, m_listenerVec); #endif -} +} // reallyPositionListenerNow //----------------------------------------------------------------------------- /** Positional sound is cool, but creating a new object just to play a simple diff --git a/src/audio/sfx_manager.hpp b/src/audio/sfx_manager.hpp index 8f9edc25b..6d5d2e542 100644 --- a/src/audio/sfx_manager.hpp +++ b/src/audio/sfx_manager.hpp @@ -70,6 +70,7 @@ public: SFX_SPEED, SFX_POSITION, SFX_VOLUME, + SFX_LISTENER, SFX_EXIT, }; // SFXCommands @@ -129,8 +130,17 @@ private: } // SFXCommand(Vec3) }; // SFXCommand // ======================================================================== - /** Listener position */ - Vec3 m_position; + + /** The position of the listener. Its lock will be used to + * access m_listener_{position,front, up}. */ + Synchronised m_listener_position; + + /** The direction the listener is facing. */ + Vec3 m_listener_front; + + /** Up vector of the listener. */ + Vec3 m_listener_up; + /** The buffers and info for all sound effects. These are shared among all * instances of SFXOpenal. */ @@ -145,9 +155,6 @@ private: /** To play non-positional sounds without having to create a new object for each */ std::map m_quick_sounds; - /** listener vector (position vector + up vector) */ - float m_listenerVec[6]; - /** If the sfx manager has been initialised. */ bool m_initialized; @@ -167,6 +174,8 @@ private: static void* mainLoop(void *obj); void deleteSFX(SFXBase *sfx); void queueCommand(SFXCommand *command); + void reallyPositionListenerNow(); + public: static void create(); static void destroy(); @@ -211,7 +220,8 @@ public: static bool checkError(const std::string &context); static const std::string getErrorString(int err); - void positionListener(const Vec3 &position, const Vec3 &front); + void positionListener(const Vec3 &position, + const Vec3 &front, const Vec3 &up); SFXBase* quickSound(const std::string &soundName); /** Called when sound was muted/unmuted */ @@ -224,7 +234,7 @@ public: // ------------------------------------------------------------------------ /** Returns the current position of the listener. */ - Vec3 getListenerPos() const { return m_position; } + Vec3 getListenerPos() const { return m_listener_position.getData(); } }; diff --git a/src/graphics/camera.cpp b/src/graphics/camera.cpp index 446f308c1..5195773dd 100644 --- a/src/graphics/camera.cpp +++ b/src/graphics/camera.cpp @@ -372,7 +372,9 @@ void Camera::smoothMoveCamera(float dt) if (race_manager->getNumLocalPlayers() < 2) { - SFXManager::get()->positionListener(current_position, current_target - current_position); + SFXManager::get()->positionListener(current_position, + current_target - current_position, + Vec3(0,1,0)); } } // smoothMoveCamera @@ -578,7 +580,8 @@ void Camera::positionCamera(float dt, float above_kart, float cam_angle, if (race_manager->getNumLocalPlayers() < 2) { SFXManager::get()->positionListener(m_camera->getPosition(), - wanted_target - m_camera->getPosition()); + wanted_target - m_camera->getPosition(), + Vec3(0, 1, 0)); } } diff --git a/src/modes/cutscene_world.cpp b/src/modes/cutscene_world.cpp index 5134c4850..1713e3d0b 100644 --- a/src/modes/cutscene_world.cpp +++ b/src/modes/cutscene_world.cpp @@ -309,7 +309,8 @@ void CutsceneWorld::update(float dt) SFXManager::get()->positionListener(m_camera->getAbsolutePosition(), m_camera->getTarget() - - m_camera->getAbsolutePosition()); + m_camera->getAbsolutePosition(), + Vec3(0,1,0)); break; } diff --git a/src/states_screens/state_manager.cpp b/src/states_screens/state_manager.cpp index 366520c24..a1356e7d2 100644 --- a/src/states_screens/state_manager.cpp +++ b/src/states_screens/state_manager.cpp @@ -201,7 +201,7 @@ void StateManager::onGameStateChange(GameState new_state) { irr_driver->showPointer(); input_manager->setMode(InputManager::MENU); - SFXManager::get()->positionListener( Vec3(0,0,0), Vec3(0,1,0) ); + SFXManager::get()->positionListener( Vec3(0,0,0), Vec3(0,1,0), Vec3(0, 1, 0) ); if (new_state == MENU) { From aae834ba4b217985b9fd9adbb3b422ae8bc76892 Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 16 Oct 2014 08:13:55 +1100 Subject: [PATCH 09/73] Run the music manager from the sfx thread. --- src/audio/sfx_manager.cpp | 16 ++++++++++++++-- src/audio/sfx_manager.hpp | 2 ++ src/main_loop.cpp | 4 ++-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 079c59714..b836d25ea 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -214,9 +214,19 @@ void SFXManager::queueCommand(SFXCommand *command) m_sfx_commands.getData().push_back(command); m_sfx_commands.unlock(); // Wake up the sfx thread - pthread_cond_signal(&m_cond_request); } // queueCommand +//---------------------------------------------------------------------------- +/** Make sures that the sfx thread is started at least one per frame. It also + * adds an update command for the music manager. + * \param dt Time step size. + */ +void SFXManager::update(float dt) +{ + queue(SFX_UPDATE_MUSIC, NULL, dt); + pthread_cond_signal(&m_cond_request); +} // update + //---------------------------------------------------------------------------- /** Puts a NULL request into the queue, which will trigger the thread to * exit. @@ -279,6 +289,8 @@ void* SFXManager::mainLoop(void *obj) me->deleteSFX(current->m_sfx); break; } case SFX_LISTENER: me->reallyPositionListenerNow(); break; + case SFX_UPDATE_MUSIC: music_manager->update( + current->m_parameter.getX()); break; default: assert("Not yet supported."); } delete current; @@ -326,7 +338,7 @@ void SFXManager::soundToggled(const bool on) { pauseAll(); } -} +} // soundToggled //---------------------------------------------------------------------------- /** Returns if sfx can be played. This means sfx are enabled and diff --git a/src/audio/sfx_manager.hpp b/src/audio/sfx_manager.hpp index 6d5d2e542..eb41f701c 100644 --- a/src/audio/sfx_manager.hpp +++ b/src/audio/sfx_manager.hpp @@ -71,6 +71,7 @@ public: SFX_POSITION, SFX_VOLUME, SFX_LISTENER, + SFX_UPDATE_MUSIC, SFX_EXIT, }; // SFXCommands @@ -213,6 +214,7 @@ public: void deleteSFXMapping(const std::string &name); void pauseAll(); void resumeAll(); + void update(float dt); bool soundExist(const std::string &name); void setMasterSFXVolume(float gain); float getMasterSFXVolume() const { return m_master_gain; } diff --git a/src/main_loop.cpp b/src/main_loop.cpp index 216bdcbc6..4e7bccff0 100644 --- a/src/main_loop.cpp +++ b/src/main_loop.cpp @@ -21,7 +21,7 @@ #include -#include "audio/music_manager.hpp" +#include "audio/sfx_manager.hpp" #include "config/user_config.hpp" #include "graphics/irr_driver.hpp" #include "graphics/material_manager.hpp" @@ -138,7 +138,7 @@ void MainLoop::run() if (!m_abort && !ProfileWorld::isNoGraphics()) { PROFILER_PUSH_CPU_MARKER("Music/input/GUI", 0x7F, 0x00, 0x00); - music_manager->update(dt); + SFXManager::get()->update(dt); input_manager->update(dt); #ifdef ENABLE_WIIUSE From 140ea5ed84cb9356b928ee41e422b6e07d8818e3 Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 16 Oct 2014 08:21:26 +1100 Subject: [PATCH 10/73] Update comments. --- src/audio/sfx_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index b836d25ea..6374c401d 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -213,7 +213,6 @@ void SFXManager::queueCommand(SFXCommand *command) m_sfx_commands.lock(); m_sfx_commands.getData().push_back(command); m_sfx_commands.unlock(); - // Wake up the sfx thread } // queueCommand //---------------------------------------------------------------------------- @@ -224,6 +223,7 @@ void SFXManager::queueCommand(SFXCommand *command) void SFXManager::update(float dt) { queue(SFX_UPDATE_MUSIC, NULL, dt); + // Wake up the sfx thread to handle all queued up audio commands. pthread_cond_signal(&m_cond_request); } // update From 0cccb5f1d598666699fe2df395c4359e35a83ca6 Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 16 Oct 2014 09:11:56 +1100 Subject: [PATCH 11/73] Fixed typo. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85c5e0c76..960ff5cd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ * Added Tutorial * Added new Supertux difficulty * New bubblegum shield weapon -* New Speeodmeter and nitro meter +* New Speedometer and nitro meter * Add ability to filter addons * Updated nitro models * Add ability to save and resume Grand Prix From c61b7d632df0938afb6a9b920a4b7c3cb5bbd373 Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 16 Oct 2014 12:48:48 +1100 Subject: [PATCH 12/73] Fix stk hanging on exit. --- src/audio/sfx_manager.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 6374c401d..40eadb184 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -234,6 +234,8 @@ void SFXManager::update(float dt) void SFXManager::stopThread() { queue(SFX_EXIT, NULL); + // Make sure the thread wakes up. + pthread_cond_signal(&m_cond_request); } // stopThread //---------------------------------------------------------------------------- From 4edcf6169b544fe99f93ae03ace881c38264745f Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 16 Oct 2014 12:55:59 +1100 Subject: [PATCH 13/73] Removed debug code. --- src/audio/sfx_manager.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 40eadb184..863025b8a 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -524,8 +524,6 @@ SFXBase* SFXManager::createSoundSource(SFXBuffer* buffer, m_all_sfx.getData().push_back(sfx); m_all_sfx.unlock(); } - else - printf(""); return sfx; } // createSoundSource From a18766e3e649f26ec5cd0332fe6c08c63d09cd0f Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 16 Oct 2014 16:57:12 +1100 Subject: [PATCH 14/73] Handle looping in sfx thread. --- src/audio/dummy_sfx.hpp | 1 + src/audio/sfx_base.hpp | 1 + src/audio/sfx_manager.cpp | 2 ++ src/audio/sfx_manager.hpp | 1 + src/audio/sfx_openal.cpp | 10 +++++++++- src/audio/sfx_openal.hpp | 1 + 6 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/audio/dummy_sfx.hpp b/src/audio/dummy_sfx.hpp index 8f5572431..6f0997f71 100644 --- a/src/audio/dummy_sfx.hpp +++ b/src/audio/dummy_sfx.hpp @@ -37,6 +37,7 @@ public: virtual bool init() { return true; } virtual void setLoop(bool status) {} + virtual void reallySetLoop(bool status) {} virtual void setPosition(const Vec3 &p) {} virtual void reallySetPosition(const Vec3 &p) {} virtual void play() {} diff --git a/src/audio/sfx_base.hpp b/src/audio/sfx_base.hpp index a23ef0dbb..ea0e33a14 100644 --- a/src/audio/sfx_base.hpp +++ b/src/audio/sfx_base.hpp @@ -56,6 +56,7 @@ public: virtual void setPosition(const Vec3 &p) = 0; virtual void reallySetPosition(const Vec3 &p) = 0; virtual void setLoop(bool status) = 0; + virtual void reallySetLoop(bool status) = 0; virtual bool isPlaying() = 0; virtual void play() = 0; virtual void reallyPlayNow() = 0; diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 40eadb184..5efd57c90 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -286,6 +286,8 @@ void* SFXManager::mainLoop(void *obj) current->m_parameter); break; case SFX_VOLUME: current->m_sfx->reallySetVolume( current->m_parameter.getX()); break; + case SFX_LOOP: current->m_sfx->reallySetLoop( + current->m_parameter.getX()!=0); break; case SFX_DELETE: { current->m_sfx->reallyStopNow(); me->deleteSFX(current->m_sfx); break; diff --git a/src/audio/sfx_manager.hpp b/src/audio/sfx_manager.hpp index eb41f701c..0f5db39f2 100644 --- a/src/audio/sfx_manager.hpp +++ b/src/audio/sfx_manager.hpp @@ -70,6 +70,7 @@ public: SFX_SPEED, SFX_POSITION, SFX_VOLUME, + SFX_LOOP, SFX_LISTENER, SFX_UPDATE_MUSIC, SFX_EXIT, diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index dd1fdb086..63d0e973c 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -207,6 +207,14 @@ void SFXOpenAL::setMasterVolume(float gain) /** Loops this sound effect. */ void SFXOpenAL::setLoop(bool status) +{ + SFXManager::get()->queue(SFXManager::SFX_LOOP, this, status ? 1.0f : 0.0f); +} // setLoop + +//----------------------------------------------------------------------------- +/** Loops this sound effect. + */ +void SFXOpenAL::reallySetLoop(bool status) { m_loop = status; @@ -214,7 +222,7 @@ void SFXOpenAL::setLoop(bool status) alSourcei(m_sound_source, AL_LOOPING, status ? AL_TRUE : AL_FALSE); SFXManager::checkError("looping"); -} // loop +} // reallySetLoop //----------------------------------------------------------------------------- /** Queues a stop for this effect to the sound manager. diff --git a/src/audio/sfx_openal.hpp b/src/audio/sfx_openal.hpp index a4b59b587..64d134cf7 100644 --- a/src/audio/sfx_openal.hpp +++ b/src/audio/sfx_openal.hpp @@ -85,6 +85,7 @@ public: virtual void play(); virtual void reallyPlayNow(); virtual void setLoop(bool status); + virtual void reallySetLoop(bool status); virtual bool isPlaying(); virtual void stop(); virtual void reallyStopNow(); From e4e0724cb9afe7a01df6f582a4fecfbf865b6a02 Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 16 Oct 2014 17:03:13 +1100 Subject: [PATCH 15/73] Removed unnecessary stop of music (music will stop anyway once the buffer is finished, but if music is completely threaded it might just keep on playing). --- src/modes/world_status.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/modes/world_status.cpp b/src/modes/world_status.cpp index a969e7efd..d6bdb73f5 100644 --- a/src/modes/world_status.cpp +++ b/src/modes/world_status.cpp @@ -39,8 +39,6 @@ WorldStatus::WorldStatus() m_start_sound = SFXManager::get()->createSoundSource("start_race"); m_track_intro_sound = SFXManager::get()->createSoundSource("track_intro"); - music_manager->stopMusic(); - m_play_racestart_sounds = true; IrrlichtDevice *device = irr_driver->getDevice(); From 4bb1091f3e181b07aea336d9a5685ed96f2b8ee2 Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 16 Oct 2014 17:11:15 +1100 Subject: [PATCH 16/73] Moved sfx thread update to happen after graphics code is finished. This improves performance since threads in graphics code do not compete with threads in sfx handling anymore. --- src/main_loop.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main_loop.cpp b/src/main_loop.cpp index 4e7bccff0..730b663a6 100644 --- a/src/main_loop.cpp +++ b/src/main_loop.cpp @@ -138,7 +138,6 @@ void MainLoop::run() if (!m_abort && !ProfileWorld::isNoGraphics()) { PROFILER_PUSH_CPU_MARKER("Music/input/GUI", 0x7F, 0x00, 0x00); - SFXManager::get()->update(dt); input_manager->update(dt); #ifdef ENABLE_WIIUSE @@ -152,6 +151,13 @@ void MainLoop::run() irr_driver->update(dt); PROFILER_POP_CPU_MARKER(); + // Update sfx and music after graphics, so that graphics code + // can use as many threads as possible without interfering + // with audia + PROFILER_PUSH_CPU_MARKER("Music/input/GUI", 0x7F, 0x00, 0x00); + SFXManager::get()->update(dt); + PROFILER_POP_CPU_MARKER(); + PROFILER_PUSH_CPU_MARKER("Protocol manager update", 0x7F, 0x00, 0x7F); ProtocolManager::getInstance()->update(); PROFILER_POP_CPU_MARKER(); From 014bc7394055c5cdc9e03b72eb6711702e726b83 Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 16 Oct 2014 21:46:31 +1100 Subject: [PATCH 17/73] Don't create a sound effect for AIs if its volume is set to 0. --- src/karts/kart.cpp | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index d017ba85d..e361b4508 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -1436,21 +1436,14 @@ void Kart::handleMaterialSFX(const Material *material) m_previous_terrain_sound->setLoop(false); const std::string &s = material->getSFXName(); - if (s != "") + + // In multiplayer mode sounds are NOT positional, because we have + // multiple listeners. This would make the sounds of all AIs be + // audible at all times. So silence AI karts. + if (s.size()!=0 && (race_manager->getNumPlayers()==1 || + m_controller->isPlayerController() ) ) { m_terrain_sound = SFXManager::get()->createSoundSource(s); - - // In multiplayer mode sounds are NOT positional, because we have - // multiple listeners. This would make the sounds of all AIs be - // audible at all times. So silence AI karts. - if (race_manager->getNumLocalPlayers() > 1) - { - if (!m_controller->isPlayerController()) - { - m_terrain_sound->setVolume( 0.0f ); - } - } - m_terrain_sound->play(); m_terrain_sound->setLoop(true); } From 3d15f13c741aeb64e485fc2be05bab0221f14c47 Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 16 Oct 2014 23:45:09 +1100 Subject: [PATCH 18/73] iFixed #1624 (though it is a bit of a hack). --- src/audio/sfx_openal.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index 63d0e973c..c95f6497c 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -338,7 +338,18 @@ void SFXOpenAL::reallyPlayNow() // At non-race time the end time is not important if(World::getWorld()) - m_end_time = World::getWorld()->getTime()+m_sound_buffer->getDuration(); + { + float t= World::getWorld()->getTime(); + // A special case: the track intro music starts at world clock = 0, + // and has a duration of 3.7 seconds. So if the game is paused in the + // first 3.7 seconds, the sfx wil be considered to be not finished + // (since the world clock stays at 0 before the race start), and + // therefore resumed if the game is resumed, which means it is + // played again. To avoid this, any sound starting at t=0 is set + // to have an end time of 0 - which means the track intro music is + // not resumed in this case. + m_end_time = t>0 ? t+m_sound_buffer->getDuration() : 0; + } else m_end_time = 1.0f; } // reallyPlayNow From 3499975b03c142b3fff07b5c4a1756c226edcda7 Mon Sep 17 00:00:00 2001 From: Deve Date: Thu, 16 Oct 2014 19:33:54 +0200 Subject: [PATCH 19/73] Move track name to center. It allows a bit longer track names and looks better. --- data/gui/select_challenge.stkgui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/gui/select_challenge.stkgui b/data/gui/select_challenge.stkgui index e45870601..931b51db8 100644 --- a/data/gui/select_challenge.stkgui +++ b/data/gui/select_challenge.stkgui @@ -2,7 +2,7 @@
-
+
From a40d6d8a00810abcb172df09d1f7725fb9b1e358 Mon Sep 17 00:00:00 2001 From: hiker Date: Fri, 17 Oct 2014 08:27:40 +1100 Subject: [PATCH 20/73] Removed isPlaying function, and use getStatus instead. --- src/audio/dummy_sfx.hpp | 1 - src/audio/sfx_base.hpp | 1 - src/audio/sfx_manager.cpp | 2 -- src/audio/sfx_manager.hpp | 2 +- src/audio/sfx_openal.cpp | 61 ++++++++++++++++++--------------------- src/audio/sfx_openal.hpp | 9 +++--- src/karts/kart.cpp | 4 +-- 7 files changed, 35 insertions(+), 45 deletions(-) diff --git a/src/audio/dummy_sfx.hpp b/src/audio/dummy_sfx.hpp index 6f0997f71..72f2ac17e 100644 --- a/src/audio/dummy_sfx.hpp +++ b/src/audio/dummy_sfx.hpp @@ -56,7 +56,6 @@ public: virtual SFXStatus getStatus() { return SFX_STOPPED; } virtual void onSoundEnabledBack() {} virtual void setRolloff(float rolloff) {} - virtual bool isPlaying() { return false; } virtual const SFXBuffer* getBuffer() const { return NULL; } }; // DummySFX diff --git a/src/audio/sfx_base.hpp b/src/audio/sfx_base.hpp index ea0e33a14..e0663ec0d 100644 --- a/src/audio/sfx_base.hpp +++ b/src/audio/sfx_base.hpp @@ -57,7 +57,6 @@ public: virtual void reallySetPosition(const Vec3 &p) = 0; virtual void setLoop(bool status) = 0; virtual void reallySetLoop(bool status) = 0; - virtual bool isPlaying() = 0; virtual void play() = 0; virtual void reallyPlayNow() = 0; virtual void stop() = 0; diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 5efd57c90..2fcff4e5c 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -526,8 +526,6 @@ SFXBase* SFXManager::createSoundSource(SFXBuffer* buffer, m_all_sfx.getData().push_back(sfx); m_all_sfx.unlock(); } - else - printf(""); return sfx; } // createSoundSource diff --git a/src/audio/sfx_manager.hpp b/src/audio/sfx_manager.hpp index 0f5db39f2..aa9d918ff 100644 --- a/src/audio/sfx_manager.hpp +++ b/src/audio/sfx_manager.hpp @@ -207,7 +207,7 @@ public: const bool load = true); SFXBase* createSoundSource(SFXBuffer* info, - const bool addToSFXList=true, + const bool add_to_SFX_list=true, const bool owns_buffer=false); SFXBase* createSoundSource(const std::string &name, const bool addToSFXList=true); diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index c95f6497c..53e5e5b8e 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -1,7 +1,8 @@ // // SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2006-2013 Patrick Ammann -// Copyright (C) 2009-2013 Marianne Gagnon +// Copyright (C) 2014 Joerg Henrichs +// Copyright (C) 2006-2014 Patrick Ammann +// Copyright (C) 2009-2014 Marianne Gagnon // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -37,14 +38,15 @@ #include #include -SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float gain, bool owns_buffer) : SFXBase() +SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float gain, + bool owns_buffer) + : SFXBase() { m_sound_buffer = buffer; m_sound_source = 0; m_status = SFX_UNKNOWN; - m_is_playing = false; m_positional = positional; - m_defaultGain = gain; + m_default_gain = gain; m_loop = false; m_gain = -1.0f; m_master_gain = 1.0f; @@ -78,7 +80,8 @@ SFXOpenAL::~SFXOpenAL() } // ~SFXOpenAL //----------------------------------------------------------------------------- - +/** Initialises the sfx. + */ bool SFXOpenAL::init() { alGenSources(1, &m_sound_source ); @@ -101,7 +104,7 @@ bool SFXOpenAL::init() if (m_gain < 0.0f) { - alSourcef (m_sound_source, AL_GAIN, m_defaultGain * m_master_gain); + alSourcef (m_sound_source, AL_GAIN, m_default_gain * m_master_gain); } else { @@ -113,10 +116,11 @@ bool SFXOpenAL::init() alSourcei(m_sound_source, AL_LOOPING, m_loop ? AL_TRUE : AL_FALSE); - if(SFXManager::checkError("setting up the source")) - m_status = SFX_INITIAL; + if(!SFXManager::checkError("setting up the source")) + return false; - return m_status==SFX_INITIAL; + m_status = SFX_STOPPED; + return true; } // init // ------------------------------------------------------------------------ @@ -152,7 +156,6 @@ void SFXOpenAL::setSpeed(float factor) */ void SFXOpenAL::reallySetSpeed(float factor) { - if(m_status==SFX_UNKNOWN) return; //OpenAL only accepts pitches in the range of 0.5 to 2.0 if(factor > 2.0f) { @@ -182,8 +185,7 @@ void SFXOpenAL::setVolume(float gain) */ void SFXOpenAL::reallySetVolume(float gain) { - if(m_status==SFX_UNKNOWN) return; - m_gain = m_defaultGain * gain; + m_gain = m_default_gain * gain; if(m_status==SFX_UNKNOWN) return; @@ -199,7 +201,7 @@ void SFXOpenAL::setMasterVolume(float gain) if(m_status==SFX_UNKNOWN) return; alSourcef(m_sound_source, AL_GAIN, - (m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain); + (m_gain < 0.0f ? m_default_gain : m_gain) * m_master_gain); SFXManager::checkError("setting volume"); } //setMasterVolume @@ -239,7 +241,6 @@ void SFXOpenAL::reallyStopNow() { if(m_status==SFX_UNKNOWN) return; - m_is_playing = false; m_status = SFX_STOPPED; m_loop = false; alSourcei(m_sound_source, AL_LOOPING, AL_FALSE); @@ -313,7 +314,7 @@ void SFXOpenAL::play() // Technically the sfx is only playing after the sfx thread starts it, // but for STK this is correct since we don't want to start the same // sfx twice. - m_is_playing = true; + m_status = SFX_PLAYING; SFXManager::get()->queue(SFXManager::SFX_PLAY, this); } // play @@ -333,7 +334,6 @@ void SFXOpenAL::reallyPlayNow() } alSourcePlay(m_sound_source); - m_status = SFX_PLAYING; SFXManager::checkError("playing"); // At non-race time the end time is not important @@ -354,14 +354,6 @@ void SFXOpenAL::reallyPlayNow() m_end_time = 1.0f; } // reallyPlayNow -//----------------------------------------------------------------------------- -/** Returns true if the sound effect is currently playing. - */ -bool SFXOpenAL::isPlaying() -{ - return m_is_playing; -} // isPlaying - //----------------------------------------------------------------------------- /** Sets the position where this sound effects is played. * \param position Position of the sound effect. @@ -389,9 +381,9 @@ void SFXOpenAL::reallySetPosition(const Vec3 &position) } if (!m_positional) { - // in multiplayer, all sounds are positional, so in this case don't bug users with - // an error message if (race_manager->getNumLocalPlayers() > 1) - // (note that 0 players is also possible, in cutscenes) + // in multiplayer, all sounds are positional, so in this case don't + // bug users with an error message if (note that 0 players is also + // possible, in cutscenes) if (race_manager->getNumLocalPlayers() < 2) { Log::warn("SFX", "Position called on non-positional SFX"); @@ -399,16 +391,18 @@ void SFXOpenAL::reallySetPosition(const Vec3 &position) return; } - alSource3f(m_sound_source, AL_POSITION, - (float)position.getX(), (float)position.getY(), (float)position.getZ()); + alSource3f(m_sound_source, AL_POSITION, (float)position.getX(), + (float)position.getY(), (float)position.getZ()); - if (SFXManager::get()->getListenerPos().distance(position) > m_sound_buffer->getMaxDist()) + if (SFXManager::get()->getListenerPos().distance(position) + > m_sound_buffer->getMaxDist()) { alSourcef(m_sound_source, AL_GAIN, 0); } else { - alSourcef(m_sound_source, AL_GAIN, (m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain); + alSourcef(m_sound_source, AL_GAIN, + (m_gain < 0.0f ? m_default_gain : m_gain) * m_master_gain); } SFXManager::checkError("positioning"); @@ -426,7 +420,8 @@ void SFXOpenAL::onSoundEnabledBack() alSourcef(m_sound_source, AL_GAIN, 0); play(); pause(); - alSourcef(m_sound_source, AL_GAIN, (m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain); + alSourcef(m_sound_source, AL_GAIN, + (m_gain < 0.0f ? m_default_gain : m_gain) * m_master_gain); } } } // onSoundEnabledBack diff --git a/src/audio/sfx_openal.hpp b/src/audio/sfx_openal.hpp index 64d134cf7..7ba7ca456 100644 --- a/src/audio/sfx_openal.hpp +++ b/src/audio/sfx_openal.hpp @@ -48,8 +48,11 @@ private: /** The status of this SFX. */ SFXStatus m_status; + /** If the sfx is positional. */ bool m_positional; - float m_defaultGain; + + /** Default gain value. */ + float m_default_gain; /** The OpenAL source contains this info, but if audio is disabled initially then the sound source won't be created and we'll be left with no clue when enabling @@ -62,9 +65,6 @@ private: the sound source won't be created and we'll be left with no clue when enabling sounds later. */ float m_gain; - - /** True when the sfx is currently playing. */ - bool m_is_playing; /** The master gain set in user preferences */ float m_master_gain; @@ -86,7 +86,6 @@ public: virtual void reallyPlayNow(); virtual void setLoop(bool status); virtual void reallySetLoop(bool status); - virtual bool isPlaying(); virtual void stop(); virtual void reallyStopNow(); virtual void pause(); diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index e361b4508..42f6c8577 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -2010,10 +2010,10 @@ void Kart::updatePhysics(float dt) m_skidding->getSkidState() == Skidding::SKID_ACCUMULATE_RIGHT ) && m_skidding->getGraphicalJumpOffset()==0) { - if(!m_skid_sound->isPlaying() && !isWheeless()) + if(m_skid_sound->getStatus()!=SFXBase::SFX_PLAYING && !isWheeless()) m_skid_sound->play(); } - else if(m_skid_sound->isPlaying()) + else if(m_skid_sound->getStatus()==SFXBase::SFX_PLAYING) { m_skid_sound->stop(); } From 1bd9fc0423499597220f92301e544d5c1ef32664 Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Thu, 16 Oct 2014 18:40:49 -0400 Subject: [PATCH 21/73] Fix mesh tangents caching --- src/graphics/mesh_tools.cpp | 41 ++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src/graphics/mesh_tools.cpp b/src/graphics/mesh_tools.cpp index a5fc3db63..2993dfd6c 100644 --- a/src/graphics/mesh_tools.cpp +++ b/src/graphics/mesh_tools.cpp @@ -388,28 +388,28 @@ scene::IMesh* MeshTools::createMeshWithTangents(scene::IMesh* mesh, bool(*predic { switch (vType) { - case video::EVT_STANDARD: - { - const video::S3DVertex* v = - (const video::S3DVertex*)original->getVertices(); - vNew = video::S3DVertexTangents( - v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords); - } + case video::EVT_STANDARD: + { + const video::S3DVertex* v = + (const video::S3DVertex*)original->getVertices(); + vNew = video::S3DVertexTangents( + v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords); + } break; - case video::EVT_2TCOORDS: - { - const video::S3DVertex2TCoords* v = - (const video::S3DVertex2TCoords*)original->getVertices(); - vNew = video::S3DVertexTangents( - v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords); - } + case video::EVT_2TCOORDS: + { + const video::S3DVertex2TCoords* v = + (const video::S3DVertex2TCoords*)original->getVertices(); + vNew = video::S3DVertexTangents( + v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords); + } break; - case video::EVT_TANGENTS: - { - const video::S3DVertexTangents* v = - (const video::S3DVertexTangents*)original->getVertices(); - vNew = v[idx[i]]; - } + case video::EVT_TANGENTS: + { + const video::S3DVertexTangents* v = + (const video::S3DVertexTangents*)original->getVertices(); + vNew = v[idx[i]]; + } break; } core::map::Node* n = vertMap.find(vNew); @@ -457,7 +457,6 @@ scene::IMesh* MeshTools::createMeshWithTangents(scene::IMesh* mesh, bool(*predic scene::SAnimatedMesh* amesh = new scene::SAnimatedMesh(clone); meshCache->addMesh(path, amesh); - amesh->drop(); World::getWorld()->getTrack()->addCachedMesh(amesh); From 813edc7ddf1f5432175aff187d302692eb6a13e4 Mon Sep 17 00:00:00 2001 From: hiker Date: Fri, 17 Oct 2014 12:00:00 +1100 Subject: [PATCH 22/73] Remove SFX_INITIAL state. --- src/audio/sfx_base.hpp | 3 +-- src/audio/sfx_openal.cpp | 6 ++++-- src/graphics/hit_sfx.cpp | 1 - 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/audio/sfx_base.hpp b/src/audio/sfx_base.hpp index e0663ec0d..50fc0aee9 100644 --- a/src/audio/sfx_base.hpp +++ b/src/audio/sfx_base.hpp @@ -45,8 +45,7 @@ public: /** Status of a sound effect. */ enum SFXStatus { - SFX_UNKNOWN = -1, SFX_STOPPED = 0, SFX_PAUSED = 1, SFX_PLAYING = 2, - SFX_INITIAL = 3 + SFX_UNKNOWN = -1, SFX_STOPPED = 0, SFX_PAUSED = 1, SFX_PLAYING = 2 }; virtual ~SFXBase() {} diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index 53e5e5b8e..20d6a0d59 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -312,8 +312,10 @@ void SFXOpenAL::deleteSFX() void SFXOpenAL::play() { // Technically the sfx is only playing after the sfx thread starts it, - // but for STK this is correct since we don't want to start the same - // sfx twice. + // but this is important to set this here since stk might decide the + // delete a sfx if it has finished playing (i.e. is in stopped state) + // - which can happen if the sfx thread had no time to actually start + // it yet. m_status = SFX_PLAYING; SFXManager::get()->queue(SFXManager::SFX_PLAY, this); } // play diff --git a/src/graphics/hit_sfx.cpp b/src/graphics/hit_sfx.cpp index e9018a474..1a1f45c58 100644 --- a/src/graphics/hit_sfx.cpp +++ b/src/graphics/hit_sfx.cpp @@ -65,6 +65,5 @@ void HitSFX::setPlayerKartHit() bool HitSFX::updateAndDelete(float dt) { SFXBase::SFXStatus status = m_sfx->getStatus(); - if(status==SFXBase::SFX_INITIAL) return false; return status!= SFXBase::SFX_PLAYING; } // updateAndDelete From c7f37297b1cbd7515d1f0f873151ed92ca4181e7 Mon Sep 17 00:00:00 2001 From: hiker Date: Fri, 17 Oct 2014 12:02:23 +1100 Subject: [PATCH 23/73] Fixed potential deadlock (if a sfx is not found in the queue, which shouldn't happen); stop sounds which are deleted only once, slightly reduce size of locked region. --- src/audio/sfx_manager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 2fcff4e5c..81370c94b 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -289,7 +289,6 @@ void* SFXManager::mainLoop(void *obj) case SFX_LOOP: current->m_sfx->reallySetLoop( current->m_parameter.getX()!=0); break; case SFX_DELETE: { - current->m_sfx->reallyStopNow(); me->deleteSFX(current->m_sfx); break; } case SFX_LISTENER: me->reallyPositionListenerNow(); break; @@ -598,13 +597,14 @@ void SFXManager::deleteSFX(SFXBase *sfx) Log::warn("SFXManager", "SFXManager::deleteSFX : Warning: sfx '%s' %lx not found in list.", sfx->getBuffer()->getFileName().c_str(), sfx); + m_all_sfx.unlock(); return; } m_all_sfx.getData().erase(i); - delete sfx; - m_all_sfx.unlock(); + + delete sfx; } // deleteSFX //---------------------------------------------------------------------------- From 403702d6bbdf8d2acb96b2e15bd77ab5ff3363c6 Mon Sep 17 00:00:00 2001 From: hiker Date: Fri, 17 Oct 2014 16:26:15 +1100 Subject: [PATCH 24/73] Handle pauseAll and resumeAll completely in thread now. Avoids a crash (caused by pauseAll trying to pause a sfx that is still in the list of all sfx, but has a delete command already queued up). --- src/audio/sfx_manager.cpp | 35 +++++++++++++++++++++++++++-------- src/audio/sfx_manager.hpp | 6 +++++- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 81370c94b..3cf632c17 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -233,7 +233,7 @@ void SFXManager::update(float dt) */ void SFXManager::stopThread() { - queue(SFX_EXIT, NULL); + queue(SFX_EXIT); // Make sure the thread wakes up. pthread_cond_signal(&m_cond_request); } // stopThread @@ -291,7 +291,9 @@ void* SFXManager::mainLoop(void *obj) case SFX_DELETE: { me->deleteSFX(current->m_sfx); break; } - case SFX_LISTENER: me->reallyPositionListenerNow(); break; + case SFX_PAUSE_ALL: me->reallyPauseAllNow(); break; + case SFX_RESUME_ALL: me->reallyResumeAllNow(); break; + case SFX_LISTENER: me->reallyPositionListenerNow(); break; case SFX_UPDATE_MUSIC: music_manager->update( current->m_parameter.getX()); break; default: assert("Not yet supported."); @@ -610,24 +612,41 @@ void SFXManager::deleteSFX(SFXBase *sfx) //---------------------------------------------------------------------------- /** Pauses all looping SFXs. Non-looping SFX will be finished, since it's * otherwise not possible to determine which SFX must be resumed (i.e. were - * actually playing at the time pause was called. + * actually playing at the time pause was called). */ void SFXManager::pauseAll() +{ + queue(SFX_PAUSE_ALL); +} // pauseAll + +//---------------------------------------------------------------------------- +/** Pauses all looping SFXs. Non-looping SFX will be finished, since it's + * otherwise not possible to determine which SFX must be resumed (i.e. were + * actually playing at the time pause was called. + */ +void SFXManager::reallyPauseAllNow() { m_all_sfx.lock(); for (std::vector::iterator i= m_all_sfx.getData().begin(); i!=m_all_sfx.getData().end(); i++) { - (*i)->pause(); + (*i)->reallyPauseNow(); } // for i in m_all_sfx m_all_sfx.unlock(); } // pauseAll //---------------------------------------------------------------------------- -/** - * Resumes all paused SFXs. If sound is disabled, does nothing. +/** Resumes all paused SFXs. If sound is disabled, does nothing. */ void SFXManager::resumeAll() +{ + queue(SFX_RESUME_ALL); +} // resumeAll + +//---------------------------------------------------------------------------- +/** Resumes all paused SFXs. If sound is disabled, does nothing. + */ +void SFXManager::reallyResumeAllNow() { // ignore unpausing if sound is disabled if (!sfxAllowed()) return; @@ -636,7 +655,7 @@ void SFXManager::resumeAll() for (std::vector::iterator i =m_all_sfx.getData().begin(); i!=m_all_sfx.getData().end(); i++) { - (*i)->resume(); + (*i)->reallyResumeNow(); } // for i in m_all_sfx m_all_sfx.unlock(); } // resumeAll @@ -729,7 +748,7 @@ void SFXManager::positionListener(const Vec3 &position, const Vec3 &front, m_listener_front = front; m_listener_up = up; m_listener_position.unlock(); - queue(SFX_LISTENER, NULL); + queue(SFX_LISTENER); } // positionListener //----------------------------------------------------------------------------- diff --git a/src/audio/sfx_manager.hpp b/src/audio/sfx_manager.hpp index aa9d918ff..09ba8ba42 100644 --- a/src/audio/sfx_manager.hpp +++ b/src/audio/sfx_manager.hpp @@ -65,7 +65,9 @@ public: SFX_PLAY = 1, SFX_STOP, SFX_PAUSE, + SFX_PAUSE_ALL, SFX_RESUME, + SFX_RESUME_ALL, SFX_DELETE, SFX_SPEED, SFX_POSITION, @@ -181,7 +183,7 @@ private: public: static void create(); static void destroy(); - void queue(SFXCommands command, SFXBase *sfx); + void queue(SFXCommands command, SFXBase *sfx=NULL); void queue(SFXCommands command, SFXBase *sfx, float f); void queue(SFXCommands command, SFXBase *sfx, const Vec3 &p); // ------------------------------------------------------------------------ @@ -214,7 +216,9 @@ public: void deleteSFXMapping(const std::string &name); void pauseAll(); + void reallyPauseAllNow(); void resumeAll(); + void reallyResumeAllNow(); void update(float dt); bool soundExist(const std::string &name); void setMasterSFXVolume(float gain); From 0a39842b04270a3157c41ec57663130974cad0d3 Mon Sep 17 00:00:00 2001 From: hiker Date: Fri, 17 Oct 2014 16:49:14 +1100 Subject: [PATCH 25/73] Throttle sfx command if the queue should get too long (might need some tuning). Non-essential sfx (positioning, speed, looping, and play) are discarded. --- src/audio/sfx_manager.cpp | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 3cf632c17..f255f1e82 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -101,7 +101,7 @@ SFXManager::SFXManager() delete m_thread_id.getData(); m_thread_id.unlock(); m_thread_id.setAtomic(0); - Log::error("HTTP Manager", "Could not create thread, error=%d.", + Log::error("SFXManager", "Could not create thread, error=%d.", errno); } pthread_attr_destroy(&attr); @@ -211,6 +211,23 @@ void SFXManager::queue(SFXCommands command, SFXBase *sfx, const Vec3 &p) void SFXManager::queueCommand(SFXCommand *command) { m_sfx_commands.lock(); + if(m_sfx_commands.getData().size() > 20*race_manager->getNumberOfKarts()+20) + { + if(command->m_command==SFX_POSITION || command->m_command==SFX_LOOP || + command->m_command==SFX_PLAY || command->m_command==SFX_SPEED ) + { + delete command; + static int count_messages = 0; + if(count_messages < 5) + { + Log::warn("SFXManager", "Throttling sfx - queue size %d", + m_sfx_commands.getData().size()); + count_messages++; + } + m_sfx_commands.unlock(); + return; + } // if throttling + } m_sfx_commands.getData().push_back(command); m_sfx_commands.unlock(); } // queueCommand @@ -266,13 +283,12 @@ void* SFXManager::mainLoop(void *obj) pthread_cond_wait(&me->m_cond_request, me->m_sfx_commands.getMutex()); empty = me->m_sfx_commands.getData().empty(); } - SFXCommand *current = me->m_sfx_commands.getData().front(); me->m_sfx_commands.getData().erase(me->m_sfx_commands.getData().begin()); if (current->m_command == SFX_EXIT) break; - + Log::verbose("sfx", "%d", me->m_sfx_commands.getData().size()); me->m_sfx_commands.unlock(); switch(current->m_command) { @@ -443,7 +459,7 @@ SFXBuffer* SFXManager::addSingleSfx(const std::string &sfx_name, } if (UserConfigParams::logMisc()) - Log::debug("SFXManager", "Loading SFX %s\n", sfx_file.c_str()); + Log::debug("SFXManager", "Loading SFX %s", sfx_file.c_str()); if (load && buffer->load()) return buffer; @@ -463,7 +479,7 @@ SFXBuffer* SFXManager::loadSingleSfx(const XMLNode* node, if (node->get("filename", &filename) == 0) { Log::error("SFXManager", - "/!\\ The 'filename' attribute is mandatory in the SFX XML file!\n"); + "The 'filename' attribute is mandatory in the SFX XML file!"); return NULL; } @@ -472,7 +488,7 @@ SFXBuffer* SFXManager::loadSingleSfx(const XMLNode* node, if(m_all_sfx_types.find(sfx_name)!=m_all_sfx_types.end()) { Log::error("SFXManager", - "There is already a sfx named '%s' installed - new one is ignored.\n", + "There is already a sfx named '%s' installed - new one is ignored.", sfx_name.c_str()); return NULL; } @@ -540,7 +556,7 @@ SFXBase* SFXManager::createSoundSource(const std::string &name, { Log::error("SFXManager", "SFXManager::createSoundSource could not find the " - "requested sound effect : '%s'\n", name.c_str()); + "requested sound effect : '%s'.", name.c_str()); return NULL; } From 7103ea8e88410f65036c40211de3f2f7a4f88420 Mon Sep 17 00:00:00 2001 From: hiker Date: Fri, 17 Oct 2014 16:49:14 +1100 Subject: [PATCH 26/73] Throttle sfx command if the queue should get too long (might need some tuning). Non-essential sfx (positioning, speed, looping, and play) are discarded. --- src/audio/sfx_manager.cpp | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 3cf632c17..fb4251931 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -101,7 +101,7 @@ SFXManager::SFXManager() delete m_thread_id.getData(); m_thread_id.unlock(); m_thread_id.setAtomic(0); - Log::error("HTTP Manager", "Could not create thread, error=%d.", + Log::error("SFXManager", "Could not create thread, error=%d.", errno); } pthread_attr_destroy(&attr); @@ -211,6 +211,23 @@ void SFXManager::queue(SFXCommands command, SFXBase *sfx, const Vec3 &p) void SFXManager::queueCommand(SFXCommand *command) { m_sfx_commands.lock(); + if(m_sfx_commands.getData().size() > 20*race_manager->getNumberOfKarts()+20) + { + if(command->m_command==SFX_POSITION || command->m_command==SFX_LOOP || + command->m_command==SFX_PLAY || command->m_command==SFX_SPEED ) + { + delete command; + static int count_messages = 0; + if(count_messages < 5) + { + Log::warn("SFXManager", "Throttling sfx - queue size %d", + m_sfx_commands.getData().size()); + count_messages++; + } + m_sfx_commands.unlock(); + return; + } // if throttling + } m_sfx_commands.getData().push_back(command); m_sfx_commands.unlock(); } // queueCommand @@ -266,13 +283,11 @@ void* SFXManager::mainLoop(void *obj) pthread_cond_wait(&me->m_cond_request, me->m_sfx_commands.getMutex()); empty = me->m_sfx_commands.getData().empty(); } - SFXCommand *current = me->m_sfx_commands.getData().front(); me->m_sfx_commands.getData().erase(me->m_sfx_commands.getData().begin()); if (current->m_command == SFX_EXIT) break; - me->m_sfx_commands.unlock(); switch(current->m_command) { @@ -443,7 +458,7 @@ SFXBuffer* SFXManager::addSingleSfx(const std::string &sfx_name, } if (UserConfigParams::logMisc()) - Log::debug("SFXManager", "Loading SFX %s\n", sfx_file.c_str()); + Log::debug("SFXManager", "Loading SFX %s", sfx_file.c_str()); if (load && buffer->load()) return buffer; @@ -463,7 +478,7 @@ SFXBuffer* SFXManager::loadSingleSfx(const XMLNode* node, if (node->get("filename", &filename) == 0) { Log::error("SFXManager", - "/!\\ The 'filename' attribute is mandatory in the SFX XML file!\n"); + "The 'filename' attribute is mandatory in the SFX XML file!"); return NULL; } @@ -472,7 +487,7 @@ SFXBuffer* SFXManager::loadSingleSfx(const XMLNode* node, if(m_all_sfx_types.find(sfx_name)!=m_all_sfx_types.end()) { Log::error("SFXManager", - "There is already a sfx named '%s' installed - new one is ignored.\n", + "There is already a sfx named '%s' installed - new one is ignored.", sfx_name.c_str()); return NULL; } @@ -540,7 +555,7 @@ SFXBase* SFXManager::createSoundSource(const std::string &name, { Log::error("SFXManager", "SFXManager::createSoundSource could not find the " - "requested sound effect : '%s'\n", name.c_str()); + "requested sound effect : '%s'.", name.c_str()); return NULL; } From f67f207d4b6fcda59bc0396625778213ce4391e0 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 17 Oct 2014 18:19:23 +0200 Subject: [PATCH 27/73] Start fixing speedmeter --- src/graphics/glwrap.cpp | 33 +++++++++++++++++ src/graphics/glwrap.hpp | 66 +++++++++++++++++++++++++++++++++ src/states_screens/race_gui.cpp | 6 +-- 3 files changed, 102 insertions(+), 3 deletions(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 86a84c5a5..d6d0ef9bf 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -655,6 +655,39 @@ void draw2DImage(const video::ITexture* texture, const core::rect& destRect glGetError(); } +void draw2DVertexPrimitiveList(const void* vertices, + u32 vertexCount, const void* indexList, u32 primitiveCount, + video::E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, video::E_INDEX_TYPE iType) +{ + if (!irr_driver->isGLSL()) + { + irr_driver->getVideoDriver()->draw2DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType); + return; + } + GLuint tmpvao, tmpvbo, tmpibo; + glGenVertexArrays(1, &tmpvao); + glBindVertexArray(tmpvao); + glGenBuffers(1, &tmpvbo); + glBindBuffer(GL_ARRAY_BUFFER, tmpvbo); + glBufferData(GL_ARRAY_BUFFER, vertexCount * getVertexPitchFromType(vType), vertices, GL_STREAM_DRAW); + glGenBuffers(1, &tmpibo); + glBindBuffer(GL_ARRAY_BUFFER, tmpibo); + glBufferData(GL_ARRAY_BUFFER, primitiveCount * sizeof(u16), indexList, GL_STREAM_DRAW); + + glUseProgram(MeshShader::TransparentShader::getInstance()->Program); + MeshShader::TransparentShader::getInstance()->setUniforms(core::IdentityMatrix, core::IdentityMatrix); + const video::SOverrideMaterial &m = irr_driver->getVideoDriver()->getOverrideMaterial(); + video::ITexture* tex = getUnicolorTexture(video::SColor(255, 255, 255, 255)); + compressTexture(tex, false); + MeshShader::TransparentShader::getInstance()->SetTextureUnits({ getTextureGLuint(tex) }); + glDrawElements(GL_TRIANGLE_FAN, primitiveCount, GL_UNSIGNED_SHORT, 0); + + glDeleteVertexArrays(1, &tmpvao); + glDeleteBuffers(1, &tmpvbo); + glDeleteBuffers(1, &tmpibo); + +} + void GL32_draw2DRectangle(video::SColor color, const core::rect& position, const core::rect* clip) { diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index 3477b649b..dabf530f8 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -132,6 +132,68 @@ public: void BlitToDefault(size_t, size_t, size_t, size_t); }; +class VertexUtils +{ +public: + static void bindVertexArrayAttrib(enum video::E_VERTEX_TYPE tp) + { + switch (tp) + { + case video::EVT_STANDARD: + // Position + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), 0); + // Normal + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), (GLvoid*)12); + // Color + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitchFromType(tp), (GLvoid*)24); + // Texcoord + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), (GLvoid*)28); + break; + case video::EVT_2TCOORDS: + // Position + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), 0); + // Normal + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), (GLvoid*)12); + // Color + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitchFromType(tp), (GLvoid*)24); + // Texcoord + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), (GLvoid*)28); + // SecondTexcoord + glEnableVertexAttribArray(4); + glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), (GLvoid*)36); + break; + case video::EVT_TANGENTS: + // Position + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), 0); + // Normal + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), (GLvoid*)12); + // Color + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitchFromType(tp), (GLvoid*)24); + // Texcoord + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), (GLvoid*)28); + // Tangent + glEnableVertexAttribArray(5); + glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), (GLvoid*)36); + // Bitangent + glEnableVertexAttribArray(6); + glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), (GLvoid*)48); + break; + } + } +}; + // core::rect needs these includes #include #include "utils/vec3.hpp" @@ -153,6 +215,10 @@ void draw2DImage(const irr::video::ITexture* texture, const irr::core::rect const irr::core::rect& sourceRect, const irr::core::rect* clipRect, const irr::video::SColor* const colors, bool useAlphaChannelOfTexture); +void draw2DVertexPrimitiveList(const void* vertices, + u32 vertexCount, const void* indexList, u32 primitiveCount, + video::E_VERTEX_TYPE vType = video::EVT_STANDARD, scene::E_PRIMITIVE_TYPE pType = scene::EPT_TRIANGLES, video::E_INDEX_TYPE iType = video::EIT_16BIT); + void GL32_draw2DRectangle(irr::video::SColor color, const irr::core::rect& position, const irr::core::rect* clip = 0); diff --git a/src/states_screens/race_gui.cpp b/src/states_screens/race_gui.cpp index 5accb0fd0..55b1327a5 100644 --- a/src/states_screens/race_gui.cpp +++ b/src/states_screens/race_gui.cpp @@ -506,7 +506,7 @@ void RaceGUI::drawEnergyMeter(int x, int y, const AbstractKart *kart, m.setTexture(0, m_gauge_goal); m.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; irr_driver->getVideoDriver()->setMaterial(m); - irr_driver->getVideoDriver()->draw2DVertexPrimitiveList(vertices, count, + draw2DVertexPrimitiveList(vertices, count, index, count-2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN); } @@ -594,7 +594,7 @@ void RaceGUI::drawEnergyMeter(int x, int y, const AbstractKart *kart, m.setTexture(0, m_gauge_full); m.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; irr_driver->getVideoDriver()->setMaterial(m); - irr_driver->getVideoDriver()->draw2DVertexPrimitiveList(vertices, count, + draw2DVertexPrimitiveList(vertices, count, index, count-2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN); } @@ -800,7 +800,7 @@ void RaceGUI::drawSpeedEnergyRank(const AbstractKart* kart, m.setTexture(0, m_speed_bar_icon->getTexture()); m.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; irr_driver->getVideoDriver()->setMaterial(m); - irr_driver->getVideoDriver()->draw2DVertexPrimitiveList(vertices, count, + draw2DVertexPrimitiveList(vertices, count, index, count-2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN); } // drawSpeedEnergyRank From ce7f017adf0ced5f8d7de4780e5676333c97fbe2 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 17 Oct 2014 18:43:39 +0200 Subject: [PATCH 28/73] Some fixes --- data/shaders/primitive2dlist.vert | 27 +++++++++++++++++++++++++++ src/graphics/glwrap.cpp | 13 ++++++++----- src/graphics/shaders.cpp | 10 ++++++++++ src/graphics/shaders.hpp | 7 +++++++ 4 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 data/shaders/primitive2dlist.vert diff --git a/data/shaders/primitive2dlist.vert b/data/shaders/primitive2dlist.vert new file mode 100644 index 000000000..d0b43a6c5 --- /dev/null +++ b/data/shaders/primitive2dlist.vert @@ -0,0 +1,27 @@ +#if __VERSION__ >= 330 +layout(location = 0) in vec3 Position; +layout(location = 1) in vec3 Normal; +layout(location = 2) in vec4 Color; +layout(location = 3) in vec2 Texcoord; +layout(location = 4) in vec2 SecondTexcoord; +layout(location = 5) in vec3 Tangent; +layout(location = 6) in vec3 Bitangent; +#else +in vec3 Position; +in vec3 Normal; +in vec4 Color; +in vec2 Texcoord; +in vec2 SecondTexcoord; +in vec3 Tangent; +in vec3 Bitangent; +#endif + +out vec2 uv; +out vec4 color; + +void main(void) +{ + color = Color.zyxw; + gl_Position = vec4(Position, 1.) / vec4(screen, 1., 1.); + uv = Texcoord; +} diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index d6d0ef9bf..cb3c19f88 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -665,21 +665,24 @@ void draw2DVertexPrimitiveList(const void* vertices, return; } GLuint tmpvao, tmpvbo, tmpibo; + primitiveCount += 2; glGenVertexArrays(1, &tmpvao); glBindVertexArray(tmpvao); glGenBuffers(1, &tmpvbo); glBindBuffer(GL_ARRAY_BUFFER, tmpvbo); glBufferData(GL_ARRAY_BUFFER, vertexCount * getVertexPitchFromType(vType), vertices, GL_STREAM_DRAW); glGenBuffers(1, &tmpibo); - glBindBuffer(GL_ARRAY_BUFFER, tmpibo); - glBufferData(GL_ARRAY_BUFFER, primitiveCount * sizeof(u16), indexList, GL_STREAM_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tmpibo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, primitiveCount * sizeof(u16), indexList, GL_STREAM_DRAW); - glUseProgram(MeshShader::TransparentShader::getInstance()->Program); - MeshShader::TransparentShader::getInstance()->setUniforms(core::IdentityMatrix, core::IdentityMatrix); + VertexUtils::bindVertexArrayAttrib(vType); + + glUseProgram(UIShader::Primitive2DList::getInstance()->Program); + UIShader::Primitive2DList::getInstance()->setUniforms(); const video::SOverrideMaterial &m = irr_driver->getVideoDriver()->getOverrideMaterial(); video::ITexture* tex = getUnicolorTexture(video::SColor(255, 255, 255, 255)); compressTexture(tex, false); - MeshShader::TransparentShader::getInstance()->SetTextureUnits({ getTextureGLuint(tex) }); + UIShader::Primitive2DList::getInstance()->SetTextureUnits({ getTextureGLuint(tex) }); glDrawElements(GL_TRIANGLE_FAN, primitiveCount, GL_UNSIGNED_SHORT, 0); glDeleteVertexArrays(1, &tmpvao); diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 1a5945c04..97e6b6020 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -1749,6 +1749,16 @@ namespace FullScreenShader namespace UIShader { + + Primitive2DList::Primitive2DList() + { + Program = LoadProgram(OBJECT, + GL_VERTEX_SHADER, file_manager->getAsset("shaders/primitive2dlist.vert").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/transparent.frag").c_str()); + AssignUniforms(); + AssignSamplerNames(Program, 0, "tex"); + } + TextureRectShader::TextureRectShader() { Program = LoadProgram(OBJECT, diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 1d498c930..edd5a58d4 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -580,6 +580,13 @@ public: namespace UIShader { + +class Primitive2DList : public ShaderHelperSingleton, public TextureRead < Bilinear_Filtered > +{ +public: + Primitive2DList(); +}; + class TextureRectShader : public ShaderHelperSingleton, public TextureRead { public: From 2f45266c6f57e0b1a4923c2e5be5996d3bebad2b Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 17 Oct 2014 18:51:41 +0200 Subject: [PATCH 29/73] Fix position of speedmeter Only need to get the texture --- data/shaders/primitive2dlist.vert | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/data/shaders/primitive2dlist.vert b/data/shaders/primitive2dlist.vert index d0b43a6c5..ceb835a89 100644 --- a/data/shaders/primitive2dlist.vert +++ b/data/shaders/primitive2dlist.vert @@ -22,6 +22,9 @@ out vec4 color; void main(void) { color = Color.zyxw; - gl_Position = vec4(Position, 1.) / vec4(screen, 1., 1.); + vec3 P = Position / vec3(screen, 1.); + P = 2. * P - 1.; + P.y *= -1; + gl_Position = vec4(P, 1.); uv = Texcoord; } From c95e90b925b6246d43daa96fbedc5b90648b059b Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Fri, 17 Oct 2014 19:24:21 -0400 Subject: [PATCH 30/73] Tweak checkbox position on login screen --- data/gui/user_screen.stkgui | 8 +++++--- data/gui/user_screen_tab.stkgui | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/data/gui/user_screen.stkgui b/data/gui/user_screen.stkgui index 63496bfe3..e636e3f73 100644 --- a/data/gui/user_screen.stkgui +++ b/data/gui/user_screen.stkgui @@ -15,13 +15,15 @@
-
-
Display the saved data m_online_cb->setState(true); makeEntryFieldsVisible(); - m_username_tb->setText(profile->getLastOnlineName()); getWidget("remember-user")->setState( profile->rememberPassword()); if(profile->getLastOnlineName().size()>0) @@ -231,14 +233,6 @@ void BaseUserScreen::makeEntryFieldsVisible() { getWidget("label_password")->setVisible(online); m_password_tb->setVisible(online); - if(player && player->hasSavedSession()) - { - // Even though this field is invisible we need to set - // the name, otherwise in update a change of user name - // will be detected, causing a clearing of this player - // (which then removes the associated online user name). - m_username_tb->setText(player->getLastOnlineName()); - } } } // makeEntryFieldsVisible @@ -446,18 +440,6 @@ void BaseUserScreen::onUpdate(float dt) m_info_widget->setText(StringUtils::loadingDots(message.c_str()), false ); } - PlayerProfile *player = getSelectedPlayer(); - if(player) - { - // If the player changes the online name, clear the saved session - // flag, and make the password field visible again. - if (m_username_tb->getText()!=player->getLastOnlineName()) - { - player->clearSession(); - makeEntryFieldsVisible(); - m_username_tb->setText(player->getLastOnlineName()); - } - } } // onUpdate // ---------------------------------------------------------------------------- From 5efea6fd1a3ef6e5aa5ab7e6add775e6091f9082 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 18 Oct 2014 17:59:30 +0200 Subject: [PATCH 37/73] Factorise attribute binding function --- src/graphics/vaomanager.cpp | 72 +++++++++---------------------------- src/graphics/vaomanager.hpp | 1 + 2 files changed, 18 insertions(+), 55 deletions(-) diff --git a/src/graphics/vaomanager.cpp b/src/graphics/vaomanager.cpp index 9cc094934..adaa080ea 100644 --- a/src/graphics/vaomanager.cpp +++ b/src/graphics/vaomanager.cpp @@ -1,6 +1,7 @@ #include "vaomanager.hpp" #include "irr_driver.hpp" #include "stkmesh.hpp" +#include "glwrap.hpp" VAOManager::VAOManager() { @@ -121,61 +122,8 @@ void VAOManager::regenerateVAO(enum VTXTYPE tp) glGenVertexArrays(1, &vao[tp]); glBindVertexArray(vao[tp]); glBindBuffer(GL_ARRAY_BUFFER, vbo[tp]); - switch (tp) - { - case VTXTYPE_COUNT: break; // avoid compiler warning - case VTXTYPE_STANDARD: - // Position - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), 0); - // Normal - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)12); - // Color - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitch(tp), (GLvoid*)24); - // Texcoord - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)28); - break; - case VTXTYPE_TCOORD: - // Position - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), 0); - // Normal - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)12); - // Color - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitch(tp), (GLvoid*)24); - // Texcoord - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)28); - // SecondTexcoord - glEnableVertexAttribArray(4); - glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)36); - break; - case VTXTYPE_TANGENT: - // Position - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), 0); - // Normal - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)12); - // Color - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitch(tp), (GLvoid*)24); - // Texcoord - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)28); - // Tangent - glEnableVertexAttribArray(5); - glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)36); - // Bitangent - glEnableVertexAttribArray(6); - glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)48); - break; - } + + VertexUtils::bindVertexArrayAttrib(getVertexType(tp)); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[tp]); glBindVertexArray(0); @@ -319,6 +267,20 @@ VAOManager::VTXTYPE VAOManager::getVTXTYPE(video::E_VERTEX_TYPE type) } }; +irr::video::E_VERTEX_TYPE VAOManager::getVertexType(enum VTXTYPE tp) +{ + switch (tp) + { + default: + case VTXTYPE_STANDARD: + return video::EVT_STANDARD; + case VTXTYPE_TCOORD: + return video::EVT_2TCOORDS; + case VTXTYPE_TANGENT: + return video::EVT_TANGENTS; + } +} + void VAOManager::append(scene::IMeshBuffer *mb, VTXTYPE tp) { size_t old_vtx_cnt = last_vertex[tp]; diff --git a/src/graphics/vaomanager.hpp b/src/graphics/vaomanager.hpp index 8a555b7b8..af86bcc6e 100644 --- a/src/graphics/vaomanager.hpp +++ b/src/graphics/vaomanager.hpp @@ -154,6 +154,7 @@ class VAOManager : public Singleton void regenerateInstancedVAO(); size_t getVertexPitch(enum VTXTYPE) const; VTXTYPE getVTXTYPE(irr::video::E_VERTEX_TYPE type); + irr::video::E_VERTEX_TYPE getVertexType(enum VTXTYPE tp); void append(irr::scene::IMeshBuffer *, VTXTYPE tp); public: VAOManager(); From 95cf6c5f4a00d4d713ad9bbca940846e0dc7a9cb Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 18 Oct 2014 18:16:50 +0200 Subject: [PATCH 38/73] Put 2d function in their own header --- src/graphics/2dutils.cpp | 338 ++++++++++++++++++++++ src/graphics/2dutils.hpp | 33 +++ src/graphics/glwrap.cpp | 336 --------------------- src/graphics/glwrap.hpp | 20 -- src/graphics/irr_driver.cpp | 1 + src/guiengine/CGUISpriteBank.cpp | 2 +- src/guiengine/engine.cpp | 2 +- src/guiengine/scalable_font.cpp | 2 +- src/guiengine/skin.cpp | 2 +- src/guiengine/widgets/CGUIEditBox.cpp | 3 +- src/states_screens/cutscene_gui.cpp | 3 +- src/states_screens/race_gui.cpp | 2 +- src/states_screens/race_gui_base.cpp | 2 +- src/states_screens/race_gui_overworld.cpp | 2 +- src/states_screens/race_result_gui.cpp | 2 +- src/utils/profiler.cpp | 2 +- 16 files changed, 383 insertions(+), 369 deletions(-) create mode 100644 src/graphics/2dutils.cpp create mode 100644 src/graphics/2dutils.hpp diff --git a/src/graphics/2dutils.cpp b/src/graphics/2dutils.cpp new file mode 100644 index 000000000..0136d003e --- /dev/null +++ b/src/graphics/2dutils.cpp @@ -0,0 +1,338 @@ +#include "2dutils.hpp" +#include "glwrap.hpp" +#include "utils/cpp2011.hpp" + +#include "../../lib/irrlicht/source/Irrlicht/COpenGLTexture.h" + +static void drawTexColoredQuad(const video::ITexture *texture, const video::SColor *col, float width, float height, + float center_pos_x, float center_pos_y, float tex_center_pos_x, float tex_center_pos_y, + float tex_width, float tex_height) +{ + unsigned colors[] = { + col[0].getRed(), col[0].getGreen(), col[0].getBlue(), col[0].getAlpha(), + col[1].getRed(), col[1].getGreen(), col[1].getBlue(), col[1].getAlpha(), + col[2].getRed(), col[2].getGreen(), col[2].getBlue(), col[2].getAlpha(), + col[3].getRed(), col[3].getGreen(), col[3].getBlue(), col[3].getAlpha(), + }; + + glBindBuffer(GL_ARRAY_BUFFER, UIShader::ColoredTextureRectShader::getInstance()->colorvbo); + glBufferSubData(GL_ARRAY_BUFFER, 0, 16 * sizeof(unsigned), colors); + + glUseProgram(UIShader::ColoredTextureRectShader::getInstance()->Program); + glBindVertexArray(UIShader::ColoredTextureRectShader::getInstance()->vao); + + UIShader::ColoredTextureRectShader::getInstance()->SetTextureUnits(createVector(static_cast(texture)->getOpenGLTextureName())); + UIShader::ColoredTextureRectShader::getInstance()->setUniforms( + core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), + core::vector2df(tex_center_pos_x, tex_center_pos_y), core::vector2df(tex_width, tex_height)); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glGetError(); +} + +static +void drawTexQuad(GLuint texture, float width, float height, +float center_pos_x, float center_pos_y, float tex_center_pos_x, float tex_center_pos_y, +float tex_width, float tex_height) +{ + glUseProgram(UIShader::TextureRectShader::getInstance()->Program); + glBindVertexArray(SharedObject::UIVAO); + + UIShader::TextureRectShader::getInstance()->SetTextureUnits(createVector(texture)); + UIShader::TextureRectShader::getInstance()->setUniforms( + core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), + core::vector2df(tex_center_pos_x, tex_center_pos_y), + core::vector2df(tex_width, tex_height)); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glGetError(); +} + +static void +getSize(unsigned texture_width, unsigned texture_height, bool textureisRTT, +const core::rect& destRect, +const core::rect& sourceRect, +float &width, float &height, +float ¢er_pos_x, float ¢er_pos_y, +float &tex_width, float &tex_height, +float &tex_center_pos_x, float &tex_center_pos_y +) +{ + core::dimension2d frame_size = + irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); + const int screen_w = frame_size.Width; + const int screen_h = frame_size.Height; + center_pos_x = float(destRect.UpperLeftCorner.X + destRect.LowerRightCorner.X); + center_pos_x /= screen_w; + center_pos_x -= 1.; + center_pos_y = float(destRect.UpperLeftCorner.Y + destRect.LowerRightCorner.Y); + center_pos_y /= screen_h; + center_pos_y = float(1.f - center_pos_y); + width = float(destRect.LowerRightCorner.X - destRect.UpperLeftCorner.X); + width /= screen_w; + height = float(destRect.LowerRightCorner.Y - destRect.UpperLeftCorner.Y); + height /= screen_h; + + tex_center_pos_x = float(sourceRect.UpperLeftCorner.X + sourceRect.LowerRightCorner.X); + tex_center_pos_x /= texture_width * 2.f; + tex_center_pos_y = float(sourceRect.UpperLeftCorner.Y + sourceRect.LowerRightCorner.Y); + tex_center_pos_y /= texture_height * 2.f; + tex_width = float(sourceRect.LowerRightCorner.X - sourceRect.UpperLeftCorner.X); + tex_width /= texture_width * 2.f; + tex_height = float(sourceRect.LowerRightCorner.Y - sourceRect.UpperLeftCorner.Y); + tex_height /= texture_height * 2.f; + + if (textureisRTT) + tex_height = -tex_height; + + const f32 invW = 1.f / static_cast(texture_width); + const f32 invH = 1.f / static_cast(texture_height); + const core::rect tcoords( + sourceRect.UpperLeftCorner.X * invW, + sourceRect.UpperLeftCorner.Y * invH, + sourceRect.LowerRightCorner.X * invW, + sourceRect.LowerRightCorner.Y *invH); +} + +void draw2DImage(const video::ITexture* texture, const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect, + const video::SColor &colors, bool useAlphaChannelOfTexture) +{ + if (!irr_driver->isGLSL()) { + video::SColor duplicatedArray[4] = { + colors, colors, colors, colors + }; + draw2DImage(texture, destRect, sourceRect, clipRect, duplicatedArray, useAlphaChannelOfTexture); + return; + } + + float width, height, + center_pos_x, center_pos_y, + tex_width, tex_height, + tex_center_pos_x, tex_center_pos_y; + + getSize(texture->getOriginalSize().Width, texture->getOriginalSize().Height, texture->isRenderTarget(), + destRect, sourceRect, width, height, center_pos_x, center_pos_y, + tex_width, tex_height, tex_center_pos_x, tex_center_pos_y); + + if (useAlphaChannelOfTexture) + { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + else + { + glDisable(GL_BLEND); + } + if (clipRect) + { + if (!clipRect->isValid()) + return; + + glEnable(GL_SCISSOR_TEST); + const core::dimension2d& renderTargetSize = irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); + glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height - clipRect->LowerRightCorner.Y, + clipRect->getWidth(), clipRect->getHeight()); + } + + glUseProgram(UIShader::UniformColoredTextureRectShader::getInstance()->Program); + glBindVertexArray(SharedObject::UIVAO); + + UIShader::UniformColoredTextureRectShader::getInstance()->SetTextureUnits(createVector(static_cast(texture)->getOpenGLTextureName())); + UIShader::UniformColoredTextureRectShader::getInstance()->setUniforms( + core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), core::vector2df(tex_center_pos_x, tex_center_pos_y), core::vector2df(tex_width, tex_height), colors); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + if (clipRect) + glDisable(GL_SCISSOR_TEST); + glUseProgram(0); + + glGetError(); +} + +void draw2DImageFromRTT(GLuint texture, size_t texture_w, size_t texture_h, + const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect, + const video::SColor &colors, bool useAlphaChannelOfTexture) +{ + if (useAlphaChannelOfTexture) + { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + float width, height, + center_pos_x, center_pos_y, + tex_width, tex_height, + tex_center_pos_x, tex_center_pos_y; + + getSize((int)texture_w, (int)texture_h, true, + destRect, sourceRect, width, height, center_pos_x, center_pos_y, + tex_width, tex_height, tex_center_pos_x, tex_center_pos_y); + + glUseProgram(UIShader::UniformColoredTextureRectShader::getInstance()->Program); + glBindVertexArray(SharedObject::UIVAO); + + UIShader::UniformColoredTextureRectShader::getInstance()->SetTextureUnits(createVector(texture)); + UIShader::UniformColoredTextureRectShader::getInstance()->setUniforms( + core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), + core::vector2df(tex_center_pos_x, tex_center_pos_y), core::vector2df(tex_width, tex_height), + colors); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +void draw2DImage(const video::ITexture* texture, const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect, + const video::SColor* const colors, bool useAlphaChannelOfTexture) +{ + if (!irr_driver->isGLSL()) + { + irr_driver->getVideoDriver()->draw2DImage(texture, destRect, sourceRect, clipRect, colors, useAlphaChannelOfTexture); + return; + } + + float width, height, + center_pos_x, center_pos_y, + tex_width, tex_height, + tex_center_pos_x, tex_center_pos_y; + + getSize(texture->getOriginalSize().Width, texture->getOriginalSize().Height, texture->isRenderTarget(), + destRect, sourceRect, width, height, center_pos_x, center_pos_y, + tex_width, tex_height, tex_center_pos_x, tex_center_pos_y); + + if (useAlphaChannelOfTexture) + { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + else + { + glDisable(GL_BLEND); + } + if (clipRect) + { + if (!clipRect->isValid()) + return; + + glEnable(GL_SCISSOR_TEST); + const core::dimension2d& renderTargetSize = irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); + glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height - clipRect->LowerRightCorner.Y, + clipRect->getWidth(), clipRect->getHeight()); + } + if (colors) + drawTexColoredQuad(texture, colors, width, height, center_pos_x, center_pos_y, + tex_center_pos_x, tex_center_pos_y, tex_width, tex_height); + else + drawTexQuad(static_cast(texture)->getOpenGLTextureName(), width, height, center_pos_x, center_pos_y, + tex_center_pos_x, tex_center_pos_y, tex_width, tex_height); + if (clipRect) + glDisable(GL_SCISSOR_TEST); + glUseProgram(0); + + glGetError(); +} + +void draw2DVertexPrimitiveList(video::ITexture *tex, const void* vertices, + u32 vertexCount, const void* indexList, u32 primitiveCount, + video::E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, video::E_INDEX_TYPE iType) +{ + if (!irr_driver->isGLSL()) + { + irr_driver->getVideoDriver()->draw2DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType); + return; + } + GLuint tmpvao, tmpvbo, tmpibo; + primitiveCount += 2; + glGenVertexArrays(1, &tmpvao); + glBindVertexArray(tmpvao); + glGenBuffers(1, &tmpvbo); + glBindBuffer(GL_ARRAY_BUFFER, tmpvbo); + glBufferData(GL_ARRAY_BUFFER, vertexCount * getVertexPitchFromType(vType), vertices, GL_STREAM_DRAW); + glGenBuffers(1, &tmpibo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tmpibo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, primitiveCount * sizeof(u16), indexList, GL_STREAM_DRAW); + + VertexUtils::bindVertexArrayAttrib(vType); + + glUseProgram(UIShader::Primitive2DList::getInstance()->Program); + UIShader::Primitive2DList::getInstance()->setUniforms(); + const video::SOverrideMaterial &m = irr_driver->getVideoDriver()->getOverrideMaterial(); + compressTexture(tex, false); + UIShader::Primitive2DList::getInstance()->SetTextureUnits({ getTextureGLuint(tex) }); + glDrawElements(GL_TRIANGLE_FAN, primitiveCount, GL_UNSIGNED_SHORT, 0); + + glDeleteVertexArrays(1, &tmpvao); + glDeleteBuffers(1, &tmpvbo); + glDeleteBuffers(1, &tmpibo); + +} + +void GL32_draw2DRectangle(video::SColor color, const core::rect& position, + const core::rect* clip) +{ + + if (!irr_driver->isGLSL()) + { + irr_driver->getVideoDriver()->draw2DRectangle(color, position, clip); + return; + } + + core::dimension2d frame_size = + irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); + const int screen_w = frame_size.Width; + const int screen_h = frame_size.Height; + float center_pos_x = float(position.UpperLeftCorner.X + position.LowerRightCorner.X); + center_pos_x /= screen_w; + center_pos_x -= 1; + float center_pos_y = float(position.UpperLeftCorner.Y + position.LowerRightCorner.Y); + center_pos_y /= screen_h; + center_pos_y = 1 - center_pos_y; + float width = float(position.LowerRightCorner.X - position.UpperLeftCorner.X); + width /= screen_w; + float height = float(position.LowerRightCorner.Y - position.UpperLeftCorner.Y); + height /= screen_h; + + if (color.getAlpha() < 255) + { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + else + { + glDisable(GL_BLEND); + } + + if (clip) + { + if (!clip->isValid()) + return; + + glEnable(GL_SCISSOR_TEST); + const core::dimension2d& renderTargetSize = irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); + glScissor(clip->UpperLeftCorner.X, renderTargetSize.Height - clip->LowerRightCorner.Y, + clip->getWidth(), clip->getHeight()); + } + + glUseProgram(UIShader::ColoredRectShader::getInstance()->Program); + glBindVertexArray(SharedObject::UIVAO); + UIShader::ColoredRectShader::getInstance()->setUniforms(core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), color); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + if (clip) + glDisable(GL_SCISSOR_TEST); + glUseProgram(0); + + glGetError(); +} diff --git a/src/graphics/2dutils.hpp b/src/graphics/2dutils.hpp new file mode 100644 index 000000000..47b0b1ef5 --- /dev/null +++ b/src/graphics/2dutils.hpp @@ -0,0 +1,33 @@ +#ifndef UTILS2D_HPP +#define UTILS2D_HPP + +#include "gl_headers.hpp" +#include +#include +#include +#include +#include +#include +#include + +void draw2DImageFromRTT(GLuint texture, size_t texture_w, size_t texture_h, + const irr::core::rect& destRect, + const irr::core::rect& sourceRect, const irr::core::rect* clipRect, + const irr::video::SColor &colors, bool useAlphaChannelOfTexture); + +void draw2DImage(const irr::video::ITexture* texture, const irr::core::rect& destRect, + const irr::core::rect& sourceRect, const irr::core::rect* clipRect, + const irr::video::SColor &color, bool useAlphaChannelOfTexture); + +void draw2DImage(const irr::video::ITexture* texture, const irr::core::rect& destRect, + const irr::core::rect& sourceRect, const irr::core::rect* clipRect, + const irr::video::SColor* const colors, bool useAlphaChannelOfTexture); + +void draw2DVertexPrimitiveList(irr::video::ITexture *t, const void* vertices, + irr::u32 vertexCount, const void* indexList, irr::u32 primitiveCount, + irr::video::E_VERTEX_TYPE vType = irr::video::EVT_STANDARD, irr::scene::E_PRIMITIVE_TYPE pType = irr::scene::EPT_TRIANGLES, irr::video::E_INDEX_TYPE iType = irr::video::EIT_16BIT); + +void GL32_draw2DRectangle(irr::video::SColor color, const irr::core::rect& position, + const irr::core::rect* clip = 0); + +#endif \ No newline at end of file diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 7d276e441..50911c6c3 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -6,9 +6,6 @@ #include "utils/profiler.hpp" #include "utils/cpp2011.hpp" - -#include "../../lib/irrlicht/source/Irrlicht/COpenGLTexture.h" - #include #include #include @@ -417,339 +414,6 @@ void draw3DLine(const core::vector3df& start, glGetError(); } -static void drawTexColoredQuad(const video::ITexture *texture, const video::SColor *col, float width, float height, - float center_pos_x, float center_pos_y, float tex_center_pos_x, float tex_center_pos_y, - float tex_width, float tex_height) -{ - unsigned colors[] = { - col[0].getRed(), col[0].getGreen(), col[0].getBlue(), col[0].getAlpha(), - col[1].getRed(), col[1].getGreen(), col[1].getBlue(), col[1].getAlpha(), - col[2].getRed(), col[2].getGreen(), col[2].getBlue(), col[2].getAlpha(), - col[3].getRed(), col[3].getGreen(), col[3].getBlue(), col[3].getAlpha(), - }; - - glBindBuffer(GL_ARRAY_BUFFER, UIShader::ColoredTextureRectShader::getInstance()->colorvbo); - glBufferSubData(GL_ARRAY_BUFFER, 0, 16 * sizeof(unsigned), colors); - - glUseProgram(UIShader::ColoredTextureRectShader::getInstance()->Program); - glBindVertexArray(UIShader::ColoredTextureRectShader::getInstance()->vao); - - UIShader::ColoredTextureRectShader::getInstance()->SetTextureUnits(createVector(static_cast(texture)->getOpenGLTextureName())); - UIShader::ColoredTextureRectShader::getInstance()->setUniforms( - core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), - core::vector2df(tex_center_pos_x, tex_center_pos_y), core::vector2df(tex_width, tex_height)); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - glGetError(); -} - -static -void drawTexQuad(GLuint texture, float width, float height, - float center_pos_x, float center_pos_y, float tex_center_pos_x, float tex_center_pos_y, - float tex_width, float tex_height) -{ - glUseProgram(UIShader::TextureRectShader::getInstance()->Program); - glBindVertexArray(SharedObject::UIVAO); - - UIShader::TextureRectShader::getInstance()->SetTextureUnits(createVector(texture)); - UIShader::TextureRectShader::getInstance()->setUniforms( - core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), - core::vector2df(tex_center_pos_x, tex_center_pos_y), - core::vector2df(tex_width, tex_height)); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - glGetError(); -} - -static void -getSize(unsigned texture_width, unsigned texture_height, bool textureisRTT, - const core::rect& destRect, - const core::rect& sourceRect, - float &width, float &height, - float ¢er_pos_x, float ¢er_pos_y, - float &tex_width, float &tex_height, - float &tex_center_pos_x, float &tex_center_pos_y - ) -{ - core::dimension2d frame_size = - irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); - const int screen_w = frame_size.Width; - const int screen_h = frame_size.Height; - center_pos_x = float(destRect.UpperLeftCorner.X + destRect.LowerRightCorner.X); - center_pos_x /= screen_w; - center_pos_x -= 1.; - center_pos_y = float(destRect.UpperLeftCorner.Y + destRect.LowerRightCorner.Y); - center_pos_y /= screen_h; - center_pos_y = float(1.f - center_pos_y); - width = float(destRect.LowerRightCorner.X - destRect.UpperLeftCorner.X); - width /= screen_w; - height = float(destRect.LowerRightCorner.Y - destRect.UpperLeftCorner.Y); - height /= screen_h; - - tex_center_pos_x = float(sourceRect.UpperLeftCorner.X + sourceRect.LowerRightCorner.X); - tex_center_pos_x /= texture_width * 2.f; - tex_center_pos_y = float(sourceRect.UpperLeftCorner.Y + sourceRect.LowerRightCorner.Y); - tex_center_pos_y /= texture_height * 2.f; - tex_width = float(sourceRect.LowerRightCorner.X - sourceRect.UpperLeftCorner.X); - tex_width /= texture_width * 2.f; - tex_height = float(sourceRect.LowerRightCorner.Y - sourceRect.UpperLeftCorner.Y); - tex_height /= texture_height * 2.f; - - if (textureisRTT) - tex_height = -tex_height; - - const f32 invW = 1.f / static_cast(texture_width); - const f32 invH = 1.f / static_cast(texture_height); - const core::rect tcoords( - sourceRect.UpperLeftCorner.X * invW, - sourceRect.UpperLeftCorner.Y * invH, - sourceRect.LowerRightCorner.X * invW, - sourceRect.LowerRightCorner.Y *invH); -} - -void draw2DImage(const video::ITexture* texture, const core::rect& destRect, - const core::rect& sourceRect, const core::rect* clipRect, - const video::SColor &colors, bool useAlphaChannelOfTexture) -{ - if (!irr_driver->isGLSL()) { - video::SColor duplicatedArray[4] = { - colors, colors, colors, colors - }; - draw2DImage(texture, destRect, sourceRect, clipRect, duplicatedArray, useAlphaChannelOfTexture); - return; - } - - float width, height, - center_pos_x, center_pos_y, - tex_width, tex_height, - tex_center_pos_x, tex_center_pos_y; - - getSize(texture->getOriginalSize().Width, texture->getOriginalSize().Height, texture->isRenderTarget(), - destRect, sourceRect, width, height, center_pos_x, center_pos_y, - tex_width, tex_height, tex_center_pos_x, tex_center_pos_y); - - if (useAlphaChannelOfTexture) - { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - else - { - glDisable(GL_BLEND); - } - if (clipRect) - { - if (!clipRect->isValid()) - return; - - glEnable(GL_SCISSOR_TEST); - const core::dimension2d& renderTargetSize = irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); - glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height - clipRect->LowerRightCorner.Y, - clipRect->getWidth(), clipRect->getHeight()); - } - - glUseProgram(UIShader::UniformColoredTextureRectShader::getInstance()->Program); - glBindVertexArray(SharedObject::UIVAO); - - UIShader::UniformColoredTextureRectShader::getInstance()->SetTextureUnits(createVector(static_cast(texture)->getOpenGLTextureName())); - UIShader::UniformColoredTextureRectShader::getInstance()->setUniforms( - core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), core::vector2df(tex_center_pos_x, tex_center_pos_y), core::vector2df(tex_width, tex_height), colors); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - if (clipRect) - glDisable(GL_SCISSOR_TEST); - glUseProgram(0); - - glGetError(); -} - -void draw2DImageFromRTT(GLuint texture, size_t texture_w, size_t texture_h, - const core::rect& destRect, - const core::rect& sourceRect, const core::rect* clipRect, - const video::SColor &colors, bool useAlphaChannelOfTexture) -{ - if (useAlphaChannelOfTexture) - { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - float width, height, - center_pos_x, center_pos_y, - tex_width, tex_height, - tex_center_pos_x, tex_center_pos_y; - - getSize((int)texture_w, (int)texture_h, true, - destRect, sourceRect, width, height, center_pos_x, center_pos_y, - tex_width, tex_height, tex_center_pos_x, tex_center_pos_y); - - glUseProgram(UIShader::UniformColoredTextureRectShader::getInstance()->Program); - glBindVertexArray(SharedObject::UIVAO); - - UIShader::UniformColoredTextureRectShader::getInstance()->SetTextureUnits(createVector(texture)); - UIShader::UniformColoredTextureRectShader::getInstance()->setUniforms( - core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), - core::vector2df(tex_center_pos_x, tex_center_pos_y), core::vector2df(tex_width, tex_height), - colors); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); -} - -void draw2DImage(const video::ITexture* texture, const core::rect& destRect, - const core::rect& sourceRect, const core::rect* clipRect, - const video::SColor* const colors, bool useAlphaChannelOfTexture) -{ - if (!irr_driver->isGLSL()) - { - irr_driver->getVideoDriver()->draw2DImage(texture, destRect, sourceRect, clipRect, colors, useAlphaChannelOfTexture); - return; - } - - float width, height, - center_pos_x, center_pos_y, - tex_width, tex_height, - tex_center_pos_x, tex_center_pos_y; - - getSize(texture->getOriginalSize().Width, texture->getOriginalSize().Height, texture->isRenderTarget(), - destRect, sourceRect, width, height, center_pos_x, center_pos_y, - tex_width, tex_height, tex_center_pos_x, tex_center_pos_y); - - if (useAlphaChannelOfTexture) - { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - else - { - glDisable(GL_BLEND); - } - if (clipRect) - { - if (!clipRect->isValid()) - return; - - glEnable(GL_SCISSOR_TEST); - const core::dimension2d& renderTargetSize = irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); - glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height - clipRect->LowerRightCorner.Y, - clipRect->getWidth(), clipRect->getHeight()); - } - if (colors) - drawTexColoredQuad(texture, colors, width, height, center_pos_x, center_pos_y, - tex_center_pos_x, tex_center_pos_y, tex_width, tex_height); - else - drawTexQuad(static_cast(texture)->getOpenGLTextureName(), width, height, center_pos_x, center_pos_y, - tex_center_pos_x, tex_center_pos_y, tex_width, tex_height); - if (clipRect) - glDisable(GL_SCISSOR_TEST); - glUseProgram(0); - - glGetError(); -} - -void draw2DVertexPrimitiveList(video::ITexture *tex, const void* vertices, - u32 vertexCount, const void* indexList, u32 primitiveCount, - video::E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, video::E_INDEX_TYPE iType) -{ - if (!irr_driver->isGLSL()) - { - irr_driver->getVideoDriver()->draw2DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType); - return; - } - GLuint tmpvao, tmpvbo, tmpibo; - primitiveCount += 2; - glGenVertexArrays(1, &tmpvao); - glBindVertexArray(tmpvao); - glGenBuffers(1, &tmpvbo); - glBindBuffer(GL_ARRAY_BUFFER, tmpvbo); - glBufferData(GL_ARRAY_BUFFER, vertexCount * getVertexPitchFromType(vType), vertices, GL_STREAM_DRAW); - glGenBuffers(1, &tmpibo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tmpibo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, primitiveCount * sizeof(u16), indexList, GL_STREAM_DRAW); - - VertexUtils::bindVertexArrayAttrib(vType); - - glUseProgram(UIShader::Primitive2DList::getInstance()->Program); - UIShader::Primitive2DList::getInstance()->setUniforms(); - const video::SOverrideMaterial &m = irr_driver->getVideoDriver()->getOverrideMaterial(); - compressTexture(tex, false); - UIShader::Primitive2DList::getInstance()->SetTextureUnits({ getTextureGLuint(tex) }); - glDrawElements(GL_TRIANGLE_FAN, primitiveCount, GL_UNSIGNED_SHORT, 0); - - glDeleteVertexArrays(1, &tmpvao); - glDeleteBuffers(1, &tmpvbo); - glDeleteBuffers(1, &tmpibo); - -} - -void GL32_draw2DRectangle(video::SColor color, const core::rect& position, - const core::rect* clip) -{ - - if (!irr_driver->isGLSL()) - { - irr_driver->getVideoDriver()->draw2DRectangle(color, position, clip); - return; - } - - core::dimension2d frame_size = - irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); - const int screen_w = frame_size.Width; - const int screen_h = frame_size.Height; - float center_pos_x = float(position.UpperLeftCorner.X + position.LowerRightCorner.X); - center_pos_x /= screen_w; - center_pos_x -= 1; - float center_pos_y = float(position.UpperLeftCorner.Y + position.LowerRightCorner.Y); - center_pos_y /= screen_h; - center_pos_y = 1 - center_pos_y; - float width = float(position.LowerRightCorner.X - position.UpperLeftCorner.X); - width /= screen_w; - float height = float(position.LowerRightCorner.Y - position.UpperLeftCorner.Y); - height /= screen_h; - - if (color.getAlpha() < 255) - { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - else - { - glDisable(GL_BLEND); - } - - if (clip) - { - if (!clip->isValid()) - return; - - glEnable(GL_SCISSOR_TEST); - const core::dimension2d& renderTargetSize = irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); - glScissor(clip->UpperLeftCorner.X, renderTargetSize.Height - clip->LowerRightCorner.Y, - clip->getWidth(), clip->getHeight()); - } - - glUseProgram(UIShader::ColoredRectShader::getInstance()->Program); - glBindVertexArray(SharedObject::UIVAO); - UIShader::ColoredRectShader::getInstance()->setUniforms(core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), color); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(0); - if (clip) - glDisable(GL_SCISSOR_TEST); - glUseProgram(0); - - glGetError(); -} - bool hasGLExtension(const char* extension) { if (glGetStringi != NULL) diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index f1c17d53e..f63d59bc3 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -202,26 +202,6 @@ public: void draw3DLine(const core::vector3df& start, const core::vector3df& end, irr::video::SColor color); -void draw2DImageFromRTT(GLuint texture, size_t texture_w, size_t texture_h, - const core::rect& destRect, - const core::rect& sourceRect, const core::rect* clipRect, - const video::SColor &colors, bool useAlphaChannelOfTexture); - -void draw2DImage(const irr::video::ITexture* texture, const irr::core::rect& destRect, - const irr::core::rect& sourceRect, const irr::core::rect* clipRect, - const irr::video::SColor &color, bool useAlphaChannelOfTexture); - -void draw2DImage(const irr::video::ITexture* texture, const irr::core::rect& destRect, - const irr::core::rect& sourceRect, const irr::core::rect* clipRect, - const irr::video::SColor* const colors, bool useAlphaChannelOfTexture); - -void draw2DVertexPrimitiveList(video::ITexture *t, const void* vertices, - u32 vertexCount, const void* indexList, u32 primitiveCount, - video::E_VERTEX_TYPE vType = video::EVT_STANDARD, scene::E_PRIMITIVE_TYPE pType = scene::EPT_TRIANGLES, video::E_INDEX_TYPE iType = video::EIT_16BIT); - -void GL32_draw2DRectangle(irr::video::SColor color, const irr::core::rect& position, - const irr::core::rect* clip = 0); - bool hasGLExtension(const char* extension); const std::string getGLExtensions(); void getGLLimits(HardwareStats::Json *json); diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 8238b8c3a..594b899bb 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -22,6 +22,7 @@ #include "graphics/callbacks.hpp" #include "graphics/camera.hpp" #include "graphics/glwrap.hpp" +#include "graphics/2dutils.hpp" #include "graphics/hardware_skinning.hpp" #include "graphics/lens_flare.hpp" #include "graphics/light.hpp" diff --git a/src/guiengine/CGUISpriteBank.cpp b/src/guiengine/CGUISpriteBank.cpp index 6b0970fa6..925a2e1c9 100644 --- a/src/guiengine/CGUISpriteBank.cpp +++ b/src/guiengine/CGUISpriteBank.cpp @@ -9,7 +9,7 @@ #include "IVideoDriver.h" #include "ITexture.h" #include -#include "graphics/glwrap.hpp" +#include "graphics/2dutils.hpp" namespace irr { diff --git a/src/guiengine/engine.cpp b/src/guiengine/engine.cpp index c31366b03..5ea597e62 100644 --- a/src/guiengine/engine.cpp +++ b/src/guiengine/engine.cpp @@ -657,7 +657,7 @@ namespace GUIEngine #include "guiengine/engine.hpp" #include "config/user_config.hpp" -#include "graphics/irr_driver.hpp" +#include "graphics/2dutils.hpp" #include "input/input_manager.hpp" #include "io/file_manager.hpp" #include "guiengine/event_handler.hpp" diff --git a/src/guiengine/scalable_font.cpp b/src/guiengine/scalable_font.cpp index 41484cd62..c9ad661e7 100644 --- a/src/guiengine/scalable_font.cpp +++ b/src/guiengine/scalable_font.cpp @@ -13,7 +13,7 @@ #include "guiengine/engine.hpp" #include "io/file_manager.hpp" #include "utils/translation.hpp" -#include "graphics/glwrap.hpp" +#include "graphics/2dutils.hpp" namespace irr { diff --git a/src/guiengine/skin.cpp b/src/guiengine/skin.cpp index 278817772..40e056c39 100644 --- a/src/guiengine/skin.cpp +++ b/src/guiengine/skin.cpp @@ -23,7 +23,7 @@ #include #include "config/user_config.hpp" -#include "graphics/irr_driver.hpp" +#include "graphics/2dutils.hpp" #include "guiengine/engine.hpp" #include "guiengine/modaldialog.hpp" #include "guiengine/scalable_font.hpp" diff --git a/src/guiengine/widgets/CGUIEditBox.cpp b/src/guiengine/widgets/CGUIEditBox.cpp index f2688b3c2..114c63854 100644 --- a/src/guiengine/widgets/CGUIEditBox.cpp +++ b/src/guiengine/widgets/CGUIEditBox.cpp @@ -12,8 +12,7 @@ //#include "os.h" #include "Keycodes.h" -#include "graphics/glwrap.hpp" -#include "graphics/irr_driver.hpp" +#include "graphics/2dutils.hpp" #include "utils/translation.hpp" #include "utils/time.hpp" diff --git a/src/states_screens/cutscene_gui.cpp b/src/states_screens/cutscene_gui.cpp index ac9c7b681..4d4399e5e 100644 --- a/src/states_screens/cutscene_gui.cpp +++ b/src/states_screens/cutscene_gui.cpp @@ -19,8 +19,7 @@ #include "config/user_config.hpp" #include "guiengine/engine.hpp" #include "guiengine/scalable_font.hpp" -#include "graphics/irr_driver.hpp" -#include "graphics/glwrap.hpp" +#include "graphics/2dutils.hpp" #include "states_screens/cutscene_gui.hpp" // ----------------------------------------------------------------------------- diff --git a/src/states_screens/race_gui.cpp b/src/states_screens/race_gui.cpp index 5f903fb77..de3cb84d7 100644 --- a/src/states_screens/race_gui.cpp +++ b/src/states_screens/race_gui.cpp @@ -26,8 +26,8 @@ using namespace irr; #include "challenges/unlock_manager.hpp" #include "config/user_config.hpp" #include "graphics/camera.hpp" +#include "graphics/2dutils.hpp" #include "graphics/glwrap.hpp" -#include "graphics/irr_driver.hpp" #include "graphics/material_manager.hpp" #include "guiengine/engine.hpp" #include "guiengine/modaldialog.hpp" diff --git a/src/states_screens/race_gui_base.cpp b/src/states_screens/race_gui_base.cpp index 185c6ed5e..f68114dad 100644 --- a/src/states_screens/race_gui_base.cpp +++ b/src/states_screens/race_gui_base.cpp @@ -23,7 +23,7 @@ #include "audio/music_manager.hpp" #include "config/user_config.hpp" #include "graphics/camera.hpp" -#include "graphics/glwrap.hpp" +#include "graphics/2dutils.hpp" #include "graphics/irr_driver.hpp" #include "graphics/material.hpp" #include "graphics/material_manager.hpp" diff --git a/src/states_screens/race_gui_overworld.cpp b/src/states_screens/race_gui_overworld.cpp index 57aa620c0..78ccbd861 100644 --- a/src/states_screens/race_gui_overworld.cpp +++ b/src/states_screens/race_gui_overworld.cpp @@ -24,8 +24,8 @@ #include "config/player_manager.hpp" #include "config/user_config.hpp" #include "graphics/camera.hpp" +#include "graphics/2dutils.hpp" #include "graphics/glwrap.hpp" -#include "graphics/irr_driver.hpp" #include "graphics/material_manager.hpp" #include "guiengine/engine.hpp" #include "guiengine/modaldialog.hpp" diff --git a/src/states_screens/race_result_gui.cpp b/src/states_screens/race_result_gui.cpp index 86a25afd3..c618274c3 100644 --- a/src/states_screens/race_result_gui.cpp +++ b/src/states_screens/race_result_gui.cpp @@ -24,7 +24,7 @@ #include "challenges/unlock_manager.hpp" #include "config/player_manager.hpp" #include "config/user_config.hpp" -#include "graphics/glwrap.hpp" +#include "graphics/2dutils.hpp" #include "graphics/material.hpp" #include "guiengine/engine.hpp" #include "guiengine/modaldialog.hpp" diff --git a/src/utils/profiler.cpp b/src/utils/profiler.cpp index 48f91e2c7..4578d97ea 100644 --- a/src/utils/profiler.cpp +++ b/src/utils/profiler.cpp @@ -16,8 +16,8 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "profiler.hpp" -#include "graphics/irr_driver.hpp" #include "graphics/glwrap.hpp" +#include "graphics/2dutils.hpp" #include "guiengine/event_handler.hpp" #include "guiengine/engine.hpp" #include "guiengine/scalable_font.hpp" From 80c7c5e49bf6cf8902d9288564e5cd045142dd97 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 18 Oct 2014 18:29:37 +0200 Subject: [PATCH 39/73] Remove unused functions --- src/graphics/glwrap.cpp | 16 ---------------- src/graphics/glwrap.hpp | 3 --- 2 files changed, 19 deletions(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 50911c6c3..f4a9a0505 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -256,22 +256,6 @@ GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsi return Program; } -void setTexture(unsigned TextureUnit, GLuint TextureId, GLenum MagFilter, GLenum MinFilter, bool allowAF) -{ - glActiveTexture(GL_TEXTURE0 + TextureUnit); - glBindTexture(GL_TEXTURE_2D, TextureId); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, MagFilter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, MinFilter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - - int aniso = UserConfigParams::m_anisotropic; - if (aniso == 0) aniso = 1; - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, allowAF ? (float)aniso : 1.0f); - - glGetError(); -} - ScopedGPUTimer::ScopedGPUTimer(GPUTimer &t) : timer(t) { if (!UserConfigParams::m_profiler_enabled) return; diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index f63d59bc3..bc6d4adc3 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -17,7 +17,6 @@ namespace HardwareStats void initGL(); GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount); video::ITexture* getUnicolorTexture(const video::SColor &c); -void setTexture(unsigned TextureUnit, GLuint TextureId, GLenum MagFilter, GLenum MinFilter, bool allowAF = false); GLuint LoadShader(const char * file, unsigned type); template @@ -194,8 +193,6 @@ public: } }; -// core::rect needs these includes -#include #include "utils/vec3.hpp" #include "texturemanager.hpp" From e23aba65f4020f0715cf86b58f728bd0e284b099 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 18 Oct 2014 23:53:16 +0200 Subject: [PATCH 40/73] Move shader load code to shader.cpp instead of glwrap.hpp --- src/graphics/glwrap.cpp | 137 --------------------------------- src/graphics/glwrap.hpp | 70 ----------------- src/graphics/shaders.cpp | 139 ++++++++++++++++++++++++++++++++++ src/graphics/shaders_util.hpp | 71 +++++++++++++++++ 4 files changed, 210 insertions(+), 207 deletions(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index f4a9a0505..e13454bef 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -119,143 +119,6 @@ void initGL() #endif } -static std::string LoadHeader() -{ - std::string result; - std::ifstream Stream(file_manager->getAsset("shaders/header.txt").c_str(), std::ios::in); - - if (Stream.is_open()) - { - std::string Line = ""; - while (getline(Stream, Line)) - result += "\n" + Line; - Stream.close(); - } - - return result; -} - -// Mostly from shader tutorial -GLuint LoadShader(const char * file, unsigned type) -{ - GLuint Id = glCreateShader(type); - char versionString[20]; - sprintf(versionString, "#version %d\n", irr_driver->getGLSLVersion()); - std::string Code = versionString; - if (irr_driver->hasVSLayerExtension()) - Code += "#extension GL_AMD_vertex_shader_layer : enable\n"; - if (UserConfigParams::m_azdo) - Code += "#extension GL_ARB_bindless_texture : enable\n"; - else - { - Code += "#extension GL_ARB_bindless_texture : disable\n"; - Code += "#undef GL_ARB_bindless_texture\n"; - } - std::ifstream Stream(file, std::ios::in); - Code += "//" + std::string(file) + "\n"; - if (irr_driver->needUBOWorkaround()) - Code += "#define UBO_DISABLED\n"; - if (irr_driver->hasVSLayerExtension()) - Code += "#define VSLayer\n"; - if (irr_driver->needsRGBBindlessWorkaround()) - Code += "#define SRGBBindlessFix\n"; - Code += LoadHeader(); - if (Stream.is_open()) - { - std::string Line = ""; - while (getline(Stream, Line)) - Code += "\n" + Line; - Stream.close(); - } - GLint Result = GL_FALSE; - int InfoLogLength; - Log::info("GLWrap", "Compiling shader : %s", file); - char const * SourcePointer = Code.c_str(); - int length = (int)strlen(SourcePointer); - glShaderSource(Id, 1, &SourcePointer, &length); - glCompileShader(Id); - - glGetShaderiv(Id, GL_COMPILE_STATUS, &Result); - if (Result == GL_FALSE) - { - Log::error("GLWrap", "Error in shader %s", file); - glGetShaderiv(Id, GL_INFO_LOG_LENGTH, &InfoLogLength); - if(InfoLogLength<0) - InfoLogLength = 1024; - char *ErrorMessage = new char[InfoLogLength]; - ErrorMessage[0]=0; - glGetShaderInfoLog(Id, InfoLogLength, NULL, ErrorMessage); - Log::error("GLWrap", ErrorMessage); - delete[] ErrorMessage; - } - - glGetError(); - - return Id; -} - -void setAttribute(AttributeType Tp, GLuint ProgramID) -{ - switch (Tp) - { - case OBJECT: - glBindAttribLocation(ProgramID, 0, "Position"); - glBindAttribLocation(ProgramID, 1, "Normal"); - glBindAttribLocation(ProgramID, 2, "Color"); - glBindAttribLocation(ProgramID, 3, "Texcoord"); - glBindAttribLocation(ProgramID, 4, "SecondTexcoord"); - glBindAttribLocation(ProgramID, 5, "Tangent"); - glBindAttribLocation(ProgramID, 6, "Bitangent"); - glBindAttribLocation(ProgramID, 7, "Origin"); - glBindAttribLocation(ProgramID, 8, "Orientation"); - glBindAttribLocation(ProgramID, 9, "Scale"); - break; - case PARTICLES_SIM: - glBindAttribLocation(ProgramID, 0, "particle_position"); - glBindAttribLocation(ProgramID, 1, "lifetime"); - glBindAttribLocation(ProgramID, 2, "particle_velocity"); - glBindAttribLocation(ProgramID, 3, "size"); - glBindAttribLocation(ProgramID, 4, "particle_position_initial"); - glBindAttribLocation(ProgramID, 5, "lifetime_initial"); - glBindAttribLocation(ProgramID, 6, "particle_velocity_initial"); - glBindAttribLocation(ProgramID, 7, "size_initial"); - break; - case PARTICLES_RENDERING: - glBindAttribLocation(ProgramID, 1, "lifetime"); - glBindAttribLocation(ProgramID, 2, "size"); - glBindAttribLocation(ProgramID, 4, "quadcorner"); - glBindAttribLocation(ProgramID, 5, "rotationvec"); - glBindAttribLocation(ProgramID, 6, "anglespeed"); - break; - } -} - -GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount) -{ - GLuint Program = glCreateProgram(); - loadAndAttach(Program, GL_VERTEX_SHADER, vertex_file_path); - if (irr_driver->getGLSLVersion() < 330) - setAttribute(PARTICLES_SIM, Program); - glTransformFeedbackVaryings(Program, varyingscount, varyings, GL_INTERLEAVED_ATTRIBS); - glLinkProgram(Program); - - GLint Result = GL_FALSE; - int InfoLogLength; - glGetProgramiv(Program, GL_LINK_STATUS, &Result); - if (Result == GL_FALSE) - { - glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &InfoLogLength); - char *ErrorMessage = new char[InfoLogLength]; - glGetProgramInfoLog(Program, InfoLogLength, NULL, ErrorMessage); - Log::error("GLWrap", ErrorMessage); - delete[] ErrorMessage; - } - - glGetError(); - - return Program; -} - ScopedGPUTimer::ScopedGPUTimer(GPUTimer &t) : timer(t) { if (!UserConfigParams::m_profiler_enabled) return; diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index bc6d4adc3..631fc4cf2 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -15,77 +15,7 @@ namespace HardwareStats } void initGL(); -GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount); video::ITexture* getUnicolorTexture(const video::SColor &c); -GLuint LoadShader(const char * file, unsigned type); - -template -void loadAndAttach(GLint ProgramID) -{ - return; -} - -template -void loadAndAttach(GLint ProgramID, GLint ShaderType, const char *filepath, Types ... args) -{ - GLint ShaderID = LoadShader(filepath, ShaderType); - glAttachShader(ProgramID, ShaderID); - glDeleteShader(ShaderID); - loadAndAttach(ProgramID, args...); -} - -template -void printFileList() -{ - return; -} - -template -void printFileList(GLint ShaderType, const char *filepath, Types ... args) -{ - Log::error("GLWrapp", filepath); - printFileList(args...); -} - -enum AttributeType -{ - OBJECT, - PARTICLES_SIM, - PARTICLES_RENDERING, -}; - -void setAttribute(AttributeType Tp, GLuint ProgramID); - -template -GLint LoadProgram(AttributeType Tp, Types ... args) -{ - GLint ProgramID = glCreateProgram(); - loadAndAttach(ProgramID, args...); - if (irr_driver->getGLSLVersion() < 330) - setAttribute(Tp, ProgramID); - glLinkProgram(ProgramID); - - GLint Result = GL_FALSE; - int InfoLogLength; - glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); - if (Result == GL_FALSE) { - Log::error("GLWrapp", "Error when linking these shaders :"); - printFileList(args...); - glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); - char *ErrorMessage = new char[InfoLogLength]; - glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, ErrorMessage); - Log::error("GLWrapp", ErrorMessage); - delete[] ErrorMessage; - } - - GLenum glErr = glGetError(); - if (glErr != GL_NO_ERROR) - { - Log::warn("IrrDriver", "GLWrap : OpenGL error %i\n", glErr); - } - - return ProgramID; -} class GPUTimer; diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 97e6b6020..6566c25ae 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -123,6 +123,145 @@ Shaders::Shaders() loadShaders(); } +// Shader loading related hook + +static std::string LoadHeader() +{ + std::string result; + std::ifstream Stream(file_manager->getAsset("shaders/header.txt").c_str(), std::ios::in); + + if (Stream.is_open()) + { + std::string Line = ""; + while (getline(Stream, Line)) + result += "\n" + Line; + Stream.close(); + } + + return result; +} + +// Mostly from shader tutorial +GLuint LoadShader(const char * file, unsigned type) +{ + GLuint Id = glCreateShader(type); + char versionString[20]; + sprintf(versionString, "#version %d\n", irr_driver->getGLSLVersion()); + std::string Code = versionString; + if (irr_driver->hasVSLayerExtension()) + Code += "#extension GL_AMD_vertex_shader_layer : enable\n"; + if (UserConfigParams::m_azdo) + Code += "#extension GL_ARB_bindless_texture : enable\n"; + else + { + Code += "#extension GL_ARB_bindless_texture : disable\n"; + Code += "#undef GL_ARB_bindless_texture\n"; + } + std::ifstream Stream(file, std::ios::in); + Code += "//" + std::string(file) + "\n"; + if (irr_driver->needUBOWorkaround()) + Code += "#define UBO_DISABLED\n"; + if (irr_driver->hasVSLayerExtension()) + Code += "#define VSLayer\n"; + if (irr_driver->needsRGBBindlessWorkaround()) + Code += "#define SRGBBindlessFix\n"; + Code += LoadHeader(); + if (Stream.is_open()) + { + std::string Line = ""; + while (getline(Stream, Line)) + Code += "\n" + Line; + Stream.close(); + } + GLint Result = GL_FALSE; + int InfoLogLength; + Log::info("GLWrap", "Compiling shader : %s", file); + char const * SourcePointer = Code.c_str(); + int length = (int)strlen(SourcePointer); + glShaderSource(Id, 1, &SourcePointer, &length); + glCompileShader(Id); + + glGetShaderiv(Id, GL_COMPILE_STATUS, &Result); + if (Result == GL_FALSE) + { + Log::error("GLWrap", "Error in shader %s", file); + glGetShaderiv(Id, GL_INFO_LOG_LENGTH, &InfoLogLength); + if (InfoLogLength<0) + InfoLogLength = 1024; + char *ErrorMessage = new char[InfoLogLength]; + ErrorMessage[0] = 0; + glGetShaderInfoLog(Id, InfoLogLength, NULL, ErrorMessage); + Log::error("GLWrap", ErrorMessage); + delete[] ErrorMessage; + } + + glGetError(); + + return Id; +} + +void setAttribute(AttributeType Tp, GLuint ProgramID) +{ + switch (Tp) + { + case OBJECT: + glBindAttribLocation(ProgramID, 0, "Position"); + glBindAttribLocation(ProgramID, 1, "Normal"); + glBindAttribLocation(ProgramID, 2, "Color"); + glBindAttribLocation(ProgramID, 3, "Texcoord"); + glBindAttribLocation(ProgramID, 4, "SecondTexcoord"); + glBindAttribLocation(ProgramID, 5, "Tangent"); + glBindAttribLocation(ProgramID, 6, "Bitangent"); + glBindAttribLocation(ProgramID, 7, "Origin"); + glBindAttribLocation(ProgramID, 8, "Orientation"); + glBindAttribLocation(ProgramID, 9, "Scale"); + break; + case PARTICLES_SIM: + glBindAttribLocation(ProgramID, 0, "particle_position"); + glBindAttribLocation(ProgramID, 1, "lifetime"); + glBindAttribLocation(ProgramID, 2, "particle_velocity"); + glBindAttribLocation(ProgramID, 3, "size"); + glBindAttribLocation(ProgramID, 4, "particle_position_initial"); + glBindAttribLocation(ProgramID, 5, "lifetime_initial"); + glBindAttribLocation(ProgramID, 6, "particle_velocity_initial"); + glBindAttribLocation(ProgramID, 7, "size_initial"); + break; + case PARTICLES_RENDERING: + glBindAttribLocation(ProgramID, 1, "lifetime"); + glBindAttribLocation(ProgramID, 2, "size"); + glBindAttribLocation(ProgramID, 4, "quadcorner"); + glBindAttribLocation(ProgramID, 5, "rotationvec"); + glBindAttribLocation(ProgramID, 6, "anglespeed"); + break; + } +} + +GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount) +{ + GLuint Program = glCreateProgram(); + loadAndAttach(Program, GL_VERTEX_SHADER, vertex_file_path); + if (irr_driver->getGLSLVersion() < 330) + setAttribute(PARTICLES_SIM, Program); + glTransformFeedbackVaryings(Program, varyingscount, varyings, GL_INTERLEAVED_ATTRIBS); + glLinkProgram(Program); + + GLint Result = GL_FALSE; + int InfoLogLength; + glGetProgramiv(Program, GL_LINK_STATUS, &Result); + if (Result == GL_FALSE) + { + glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &InfoLogLength); + char *ErrorMessage = new char[InfoLogLength]; + glGetProgramInfoLog(Program, InfoLogLength, NULL, ErrorMessage); + Log::error("GLWrap", ErrorMessage); + delete[] ErrorMessage; + } + + glGetError(); + + return Program; +} + GLuint quad_vbo, tri_vbo; GLuint SharedObject::FullScreenQuadVAO = 0; diff --git a/src/graphics/shaders_util.hpp b/src/graphics/shaders_util.hpp index 6b1563bed..9631a2cd2 100644 --- a/src/graphics/shaders_util.hpp +++ b/src/graphics/shaders_util.hpp @@ -12,6 +12,77 @@ bool needsUBO(); unsigned getGLSLVersion(); +GLuint LoadShader(const char * file, unsigned type); +GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount); + +template +void loadAndAttach(GLint ProgramID) +{ + return; +} + +template +void loadAndAttach(GLint ProgramID, GLint ShaderType, const char *filepath, Types ... args) +{ + GLint ShaderID = LoadShader(filepath, ShaderType); + glAttachShader(ProgramID, ShaderID); + glDeleteShader(ShaderID); + loadAndAttach(ProgramID, args...); +} + +template +void printFileList() +{ + return; +} + +template +void printFileList(GLint ShaderType, const char *filepath, Types ... args) +{ + Log::error("GLWrapp", filepath); + printFileList(args...); +} + +enum AttributeType +{ + OBJECT, + PARTICLES_SIM, + PARTICLES_RENDERING, +}; + +void setAttribute(AttributeType Tp, GLuint ProgramID); + +template +GLint LoadProgram(AttributeType Tp, Types ... args) +{ + GLint ProgramID = glCreateProgram(); + loadAndAttach(ProgramID, args...); + if (irr_driver->getGLSLVersion() < 330) + setAttribute(Tp, ProgramID); + glLinkProgram(ProgramID); + + GLint Result = GL_FALSE; + int InfoLogLength; + glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); + if (Result == GL_FALSE) { + Log::error("GLWrapp", "Error when linking these shaders :"); + printFileList(args...); + glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); + char *ErrorMessage = new char[InfoLogLength]; + glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, ErrorMessage); + Log::error("GLWrapp", ErrorMessage); + delete[] ErrorMessage; + } + + GLenum glErr = glGetError(); + if (glErr != GL_NO_ERROR) + { + Log::warn("IrrDriver", "GLWrap : OpenGL error %i\n", glErr); + } + + return ProgramID; +} + struct UniformHelper { template From 9b46cdc981b04c7ac39622fc1e031c73106ea3fd Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Sat, 18 Oct 2014 19:11:24 -0400 Subject: [PATCH 41/73] Refactor library nodes to be proper TrackObjects, allows animating them with curves --- src/tracks/model_definition_loader.cpp | 14 ++++ src/tracks/model_definition_loader.hpp | 22 ++++++- src/tracks/track.cpp | 83 ++---------------------- src/tracks/track.hpp | 6 +- src/tracks/track_object.cpp | 4 ++ src/tracks/track_object_presentation.cpp | 71 ++++++++++++++++++++ src/tracks/track_object_presentation.hpp | 12 ++++ 7 files changed, 128 insertions(+), 84 deletions(-) diff --git a/src/tracks/model_definition_loader.cpp b/src/tracks/model_definition_loader.cpp index e8444e98a..b4984448e 100644 --- a/src/tracks/model_definition_loader.cpp +++ b/src/tracks/model_definition_loader.cpp @@ -122,3 +122,17 @@ scene::IMesh* ModelDefinitionLoader::getFirstMeshFor(const std::string& name) { return irr_driver->getMesh(m_lod_groups[name][0].m_model_file); } + +// ---------------------------------------------------------------------------- + +void ModelDefinitionLoader::cleanLibraryNodesAfterLoad() +{ + for (std::map::iterator it = m_library_nodes.begin(); + it != m_library_nodes.end(); it++) + { + delete it->second; + + file_manager->popTextureSearchPath(); + file_manager->popModelSearchPath(); + } +} \ No newline at end of file diff --git a/src/tracks/model_definition_loader.hpp b/src/tracks/model_definition_loader.hpp index b3bf75694..5cfb3a7aa 100644 --- a/src/tracks/model_definition_loader.hpp +++ b/src/tracks/model_definition_loader.hpp @@ -68,12 +68,13 @@ struct ModelDefinition } }; -/** Utility class to load level-of-detail nodes and instaincing nodes +/** Utility class to load level-of-detail nodes and library nodes * \ingroup tracks */ class ModelDefinitionLoader { private: + std::map m_library_nodes; std::map< std::string, std::vector< ModelDefinition > > m_lod_groups; std::map< std::string, STKInstancedSceneNode* > m_instancing_nodes; Track* m_track; @@ -86,8 +87,25 @@ public: void clear(); - scene::IMesh* getFirstMeshFor(const std::string& name); + + std::map& getLibraryNodes() + { + return m_library_nodes; + } + + void cleanLibraryNodesAfterLoad(); + + bool containsLibraryNode(const std::string& name) const + { + return m_library_nodes.find(name) != m_library_nodes.end(); + } + + void addToLibrary(const std::string& name, XMLNode* xml) + { + assert(xml != NULL); + m_library_nodes[name] = xml; + } }; // ModelDefinitionLoader #endif // HEADER_LOD_NODE_LOADER_HPP diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 1319d4084..fe41c4c46 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -1738,18 +1738,9 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) } } - std::map library_nodes; - loadObjects(root, path, model_def_loader, true, NULL, library_nodes); + loadObjects(root, path, model_def_loader, true, NULL); - // Cleanup library nodes - for (std::map::iterator it = library_nodes.begin(); - it != library_nodes.end(); it++) - { - delete it->second; - - file_manager->popTextureSearchPath(); - file_manager->popModelSearchPath(); - } + model_def_loader.cleanLibraryNodesAfterLoad(); // Init all track objects m_track_object_manager->init(); @@ -1914,8 +1905,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) //----------------------------------------------------------------------------- void Track::loadObjects(const XMLNode* root, const std::string& path, ModelDefinitionLoader& model_def_loader, - bool create_lod_definitions, scene::ISceneNode* parent, - std::map& library_nodes) + bool create_lod_definitions, scene::ISceneNode* parent) { unsigned int start_position_counter = 0; @@ -1927,75 +1917,10 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, ModelDefin // The track object was already converted before the loop, and the // default start was already used, too - so ignore those. if (name == "track" || name == "default-start") continue; - if (name == "object") + if (name == "object" || name == "library") { m_track_object_manager->add(*node, parent, model_def_loader); } - else if (name == "library") - { - std::string name; - node->get("name", &name); - - core::vector3df xyz; - node->get("xyz", &xyz); - - core::vector3df hpr; - node->get("hpr", &hpr); - - core::vector3df scale; - node->get("scale", &scale); - - XMLNode* libroot; - std::string lib_path = - file_manager->getAsset(FileManager::LIBRARY, name)+"/"; - bool create_lod_definitions = true; - - if (library_nodes.find(name) == library_nodes.end()) - { - std::string lib_node_path = lib_path+"node.xml"; - libroot = file_manager->createXMLTree(lib_node_path); - if (libroot == NULL) - { - Log::error("Track", "Cannot find library '%s'", lib_node_path.c_str()); - continue; - } - - file_manager->pushTextureSearchPath(lib_path + "/"); - file_manager->pushModelSearchPath (lib_path); - material_manager->pushTempMaterial(lib_path + "/materials.xml"); - library_nodes[name] = libroot; - - // Load LOD groups - const XMLNode *lod_xml_node = libroot->getNode("lod"); - if (lod_xml_node != NULL) - { - for (unsigned int i = 0; i < lod_xml_node->getNumNodes(); i++) - { - const XMLNode* lod_group_xml = lod_xml_node->getNode(i); - for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++) - { - model_def_loader.addModelDefinition(lod_group_xml->getNode(j)); - } - } - } - } - else - { - libroot = library_nodes[name]; - create_lod_definitions = false; // LOD definitions are already created, don't create them again - } - - scene::ISceneNode* parent = irr_driver->getSceneManager()->addEmptySceneNode(); -#ifdef DEBUG - parent->setName(("libnode_" + name).c_str()); -#endif - parent->setPosition(xyz); - parent->setRotation(hpr); - parent->setScale(scale); - parent->updateAbsolutePosition(); - loadObjects(libroot, lib_path, model_def_loader, create_lod_definitions, parent, library_nodes); - //m_all_nodes.push_back(parent); - } else if (name == "water") { createWater(*node); diff --git a/src/tracks/track.hpp b/src/tracks/track.hpp index d5eadd80b..10f2ff18e 100644 --- a/src/tracks/track.hpp +++ b/src/tracks/track.hpp @@ -412,9 +412,6 @@ private: std::vector& m_music ); void loadCurves(const XMLNode &node); void handleSky(const XMLNode &root, const std::string &filename); - void loadObjects(const XMLNode* root, const std::string& path, ModelDefinitionLoader& lod_loader, - bool create_lod_definitions, scene::ISceneNode* parent, - std::map& library_nodes); public: @@ -472,6 +469,9 @@ public: /** Returns true if this track has easter eggs. */ bool hasEasterEggs() const { return m_has_easter_eggs; } // ------------------------------------------------------------------------ + void loadObjects(const XMLNode* root, const std::string& path, ModelDefinitionLoader& lod_loader, + bool create_lod_definitions, scene::ISceneNode* parent); + // ------------------------------------------------------------------------ bool isSoccer () const { return m_is_soccer; } // ------------------------------------------------------------------------ void loadTrackModel (World* parent, diff --git a/src/tracks/track_object.cpp b/src/tracks/track_object.cpp index 12ecc3679..369628bee 100644 --- a/src/tracks/track_object.cpp +++ b/src/tracks/track_object.cpp @@ -132,6 +132,10 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent, m_type = "light"; m_presentation = new TrackObjectPresentationLight(xml_node, parent); } + else if (xml_node.getName() == "library") + { + m_presentation = new TrackObjectPresentationLibraryNode(xml_node, model_def_loader); + } else if (type == "sfx-emitter") { // FIXME: at this time sound emitters are just disabled in multiplayer diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index f8367f233..083ab3621 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -148,6 +148,77 @@ TrackObjectPresentationEmpty::~TrackObjectPresentationEmpty() // ---------------------------------------------------------------------------- +TrackObjectPresentationLibraryNode::TrackObjectPresentationLibraryNode( + const XMLNode& xml_node, + ModelDefinitionLoader& model_def_loader) : +TrackObjectPresentationSceneNode(xml_node) +{ + std::string name; + xml_node.get("name", &name); + + m_node = irr_driver->getSceneManager()->addEmptySceneNode(); +#ifdef DEBUG + m_node->setName(("libnode_" + name).c_str()); +#endif + + XMLNode* libroot; + std::string lib_path = + file_manager->getAsset(FileManager::LIBRARY, name) + "/"; + bool create_lod_definitions = true; + + if (!model_def_loader.containsLibraryNode(name)) + { + std::string lib_node_path = lib_path + "node.xml"; + libroot = file_manager->createXMLTree(lib_node_path); + if (libroot == NULL) + { + Log::error("TrackObjectPresentationLibraryNode", "Cannot find library '%s'", lib_node_path.c_str()); + return; + } + + file_manager->pushTextureSearchPath(lib_path + "/"); + file_manager->pushModelSearchPath(lib_path); + material_manager->pushTempMaterial(lib_path + "/materials.xml"); + model_def_loader.addToLibrary(name, libroot); + + // Load LOD groups + const XMLNode *lod_xml_node = libroot->getNode("lod"); + if (lod_xml_node != NULL) + { + for (unsigned int i = 0; i < lod_xml_node->getNumNodes(); i++) + { + const XMLNode* lod_group_xml = lod_xml_node->getNode(i); + for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++) + { + model_def_loader.addModelDefinition(lod_group_xml->getNode(j)); + } + } + } + } + else + { + libroot = model_def_loader.getLibraryNodes()[name]; + assert(libroot != NULL); + create_lod_definitions = false; // LOD definitions are already created, don't create them again + } + + m_node->setPosition(m_init_xyz); + m_node->setRotation(m_init_hpr); + m_node->setScale(m_init_scale); + m_node->updateAbsolutePosition(); + + assert(libroot != NULL); + World::getWorld()->getTrack()->loadObjects(libroot, lib_path, model_def_loader, + create_lod_definitions, m_node); +} + +TrackObjectPresentationLibraryNode::~TrackObjectPresentationLibraryNode() +{ + irr_driver->removeNode(m_node); +} + +// ---------------------------------------------------------------------------- + TrackObjectPresentationLOD::TrackObjectPresentationLOD(const XMLNode& xml_node, scene::ISceneNode* parent, ModelDefinitionLoader& model_def_loader) : TrackObjectPresentationSceneNode(xml_node) diff --git a/src/tracks/track_object_presentation.hpp b/src/tracks/track_object_presentation.hpp index 219c98c5e..c951fcfe4 100644 --- a/src/tracks/track_object_presentation.hpp +++ b/src/tracks/track_object_presentation.hpp @@ -152,6 +152,18 @@ public: virtual ~TrackObjectPresentationEmpty(); }; +/** +* \ingroup tracks +* A track object representation that is a library node +*/ +class TrackObjectPresentationLibraryNode : public TrackObjectPresentationSceneNode +{ +public: + + TrackObjectPresentationLibraryNode(const XMLNode& xml_node, + ModelDefinitionLoader& model_def_loader); + virtual ~TrackObjectPresentationLibraryNode(); +}; /** * \ingroup tracks From 11dbb6f06253a701682bdebf5ef8b12d523d1514 Mon Sep 17 00:00:00 2001 From: hiker Date: Mon, 20 Oct 2014 00:05:48 +1100 Subject: [PATCH 42/73] Fixed some warnings printed when sfx are disabled. --- src/audio/sfx_openal.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index 97f33b6a4..0cb3fb062 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -244,11 +244,14 @@ void SFXOpenAL::stop() */ void SFXOpenAL::reallyStopNow() { - m_status = SFX_STOPPED; - m_loop = false; - alSourcei(m_sound_source, AL_LOOPING, AL_FALSE); - alSourceStop(m_sound_source); - SFXManager::checkError("stoping"); + if(m_status==SFX_PLAYING || m_status==SFX_PAUSED) + { + m_status = SFX_STOPPED; + m_loop = false; + alSourcei(m_sound_source, AL_LOOPING, AL_FALSE); + alSourceStop(m_sound_source); + SFXManager::checkError("stoping"); + } } // reallyStopNow //----------------------------------------------------------------------------- From 3ea954cc73eceb58d558c1e62ecb70267e8491eb Mon Sep 17 00:00:00 2001 From: hiker Date: Mon, 20 Oct 2014 00:48:15 +1100 Subject: [PATCH 43/73] Try to fix travis build. --- src/graphics/shaders_util.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/graphics/shaders_util.hpp b/src/graphics/shaders_util.hpp index 9631a2cd2..92d2bd1e0 100644 --- a/src/graphics/shaders_util.hpp +++ b/src/graphics/shaders_util.hpp @@ -1,6 +1,7 @@ #ifndef SHADERS_UTIL_HPP #define SHADERS_UTIL_HPP +#include "graphics/irr_driver.hpp" #include "utils/singleton.hpp" #include #include From b13e6931cecdc2f4344342afe5b4fe714347a5c9 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 19 Oct 2014 16:39:39 +0200 Subject: [PATCH 44/73] Revert "Try to fix travis build." This reverts commit 3ea954cc73eceb58d558c1e62ecb70267e8491eb. --- src/graphics/shaders_util.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/graphics/shaders_util.hpp b/src/graphics/shaders_util.hpp index 92d2bd1e0..9631a2cd2 100644 --- a/src/graphics/shaders_util.hpp +++ b/src/graphics/shaders_util.hpp @@ -1,7 +1,6 @@ #ifndef SHADERS_UTIL_HPP #define SHADERS_UTIL_HPP -#include "graphics/irr_driver.hpp" #include "utils/singleton.hpp" #include #include From 4ee0e24ff7581aba2c13953d05a577c24355e0a0 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 19 Oct 2014 16:40:27 +0200 Subject: [PATCH 45/73] Try to fix travis build. --- src/graphics/shaders_util.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/shaders_util.hpp b/src/graphics/shaders_util.hpp index 9631a2cd2..497491d55 100644 --- a/src/graphics/shaders_util.hpp +++ b/src/graphics/shaders_util.hpp @@ -57,7 +57,7 @@ GLint LoadProgram(AttributeType Tp, Types ... args) { GLint ProgramID = glCreateProgram(); loadAndAttach(ProgramID, args...); - if (irr_driver->getGLSLVersion() < 330) + if (getGLSLVersion() < 330) setAttribute(Tp, ProgramID); glLinkProgram(ProgramID); From f3dd0093766fc29b1abbaa4c746d87f502a16250 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 19 Oct 2014 18:44:08 +0200 Subject: [PATCH 46/73] Try to fix model loader hpp --- src/tracks/model_definition_loader.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tracks/model_definition_loader.hpp b/src/tracks/model_definition_loader.hpp index 5cfb3a7aa..f7c669362 100644 --- a/src/tracks/model_definition_loader.hpp +++ b/src/tracks/model_definition_loader.hpp @@ -23,6 +23,7 @@ class LODNode; class Track; class STKInstancedSceneNode; +#include #include #include #include From 36ea7f30bf3b48a90bc12893e982c538071b9a7b Mon Sep 17 00:00:00 2001 From: hiker Date: Mon, 20 Oct 2014 09:43:05 +1100 Subject: [PATCH 47/73] Only restart sfx if they were really paused. --- src/audio/sfx_openal.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index 0cb3fb062..a84c0fd7f 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -259,7 +259,6 @@ void SFXOpenAL::reallyStopNow() */ void SFXOpenAL::pause() { - if (m_status != SFX_PLAYING || !SFXManager::get()->sfxAllowed()) return; SFXManager::get()->queue(SFXManager::SFX_PAUSE, this); } // pause @@ -269,6 +268,9 @@ void SFXOpenAL::pause() */ void SFXOpenAL::reallyPauseNow() { + // Need to be tested again here, since this function can be called + // from pauseAll, and we have to make sure to only pause playing sfx. + if (m_status != SFX_PLAYING || !SFXManager::get()->sfxAllowed()) return; m_status = SFX_PAUSED; alSourcePause(m_sound_source); SFXManager::checkError("pausing"); From 8b7bf28e0f0fc148b53abd21cbe3804e9dd85d67 Mon Sep 17 00:00:00 2001 From: hiker Date: Mon, 20 Oct 2014 22:37:19 +1100 Subject: [PATCH 48/73] Fixed #1147 - sounds should stopped when they are disabled in option screen. Fixed by explicitely stopping all non-looped sfx. --- src/audio/dummy_sfx.hpp | 6 ++-- src/audio/sfx_base.hpp | 4 ++- src/audio/sfx_manager.cpp | 13 ++++++-- src/audio/sfx_openal.cpp | 63 ++++++++++++++++++++++++++++----------- src/audio/sfx_openal.hpp | 7 ++++- 5 files changed, 70 insertions(+), 23 deletions(-) diff --git a/src/audio/dummy_sfx.hpp b/src/audio/dummy_sfx.hpp index b7448d49d..765912902 100644 --- a/src/audio/dummy_sfx.hpp +++ b/src/audio/dummy_sfx.hpp @@ -30,11 +30,13 @@ class DummySFX : public SFXBase { public: - DummySFX(SFXBuffer* buffer, bool positional, float gain) {} + DummySFX(SFXBuffer* buffer, bool positional, + float gain) {} virtual ~DummySFX() {} /** Late creation, if SFX was initially disabled */ - virtual bool init() { return true; } + virtual bool init() { return true; } + virtual bool isLooped() { return false; } virtual void updatePlayingSFX(float dt) {} virtual void setLoop(bool status) {} virtual void reallySetLoop(bool status) {} diff --git a/src/audio/sfx_base.hpp b/src/audio/sfx_base.hpp index d8e7785ec..4e647b87c 100644 --- a/src/audio/sfx_base.hpp +++ b/src/audio/sfx_base.hpp @@ -45,13 +45,15 @@ public: /** Status of a sound effect. */ enum SFXStatus { - SFX_UNKNOWN = -1, SFX_STOPPED = 0, SFX_PAUSED = 1, SFX_PLAYING = 2 + SFX_UNKNOWN = -1, SFX_STOPPED = 0, SFX_PAUSED = 1, SFX_PLAYING = 2, + SFX_NOT_INITIALISED = 3 }; virtual ~SFXBase() {} /** Late creation, if SFX was initially disabled */ virtual bool init() = 0; + virtual bool isLooped() = 0; virtual void updatePlayingSFX(float dt) = 0; virtual void setPosition(const Vec3 &p) = 0; virtual void reallySetPosition(const Vec3 &p) = 0; diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 0eb286bee..1b45a8a5c 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -106,8 +106,6 @@ SFXManager::SFXManager() } pthread_attr_destroy(&attr); - if (!sfxAllowed()) return; - setMasterSFXVolume( UserConfigParams::m_sfx_volume ); m_sfx_commands.lock(); m_sfx_commands.getData().clear(); @@ -343,6 +341,17 @@ void SFXManager::soundToggled(const bool on) } else { + // First stop all sfx that are not looped + const int sfx_amount = (int)m_all_sfx.getData().size(); + m_all_sfx.lock(); + for (int i=0; iisLooped()) + { + m_all_sfx.getData()[i]->reallyStopNow(); + } + } + m_all_sfx.unlock(); pauseAll(); } } // soundToggled diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index a84c0fd7f..dafd3ce1f 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -44,7 +44,7 @@ SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float gain, { m_sound_buffer = buffer; m_sound_source = 0; - m_status = SFX_UNKNOWN; + m_status = SFX_NOT_INITIALISED; m_positional = positional; m_default_gain = gain; m_loop = false; @@ -84,8 +84,11 @@ SFXOpenAL::~SFXOpenAL() */ bool SFXOpenAL::init() { + m_status = SFX_UNKNOWN; + alGenSources(1, &m_sound_source ); - if (!SFXManager::checkError("generating a source")) return false; + if (!SFXManager::checkError("generating a source")) + return false; assert( alIsBuffer(m_sound_buffer->getBufferID()) ); assert( alIsSource(m_sound_source) ); @@ -137,13 +140,6 @@ void SFXOpenAL::updatePlayingSFX(float dt) m_status = SFX_STOPPED; } // updatePlayingSFX -// ------------------------------------------------------------------------ -/** Returns the status of this sfx. */ -SFXBase::SFXStatus SFXOpenAL::getStatus() -{ - return m_status; -} // getStatus; - //----------------------------------------------------------------------------- /** Queues up a change of the pitch of a sound effect to the sfx manager. * \param factor Speedup/slowdown between 0.5 and 2.0 @@ -161,6 +157,13 @@ void SFXOpenAL::setSpeed(float factor) */ void SFXOpenAL::reallySetSpeed(float factor) { + if(m_status==SFX_NOT_INITIALISED) + { + init(); + if(m_status==SFX_UNKNOWN) + return; + } + //OpenAL only accepts pitches in the range of 0.5 to 2.0 if(factor > 2.0f) { @@ -194,6 +197,13 @@ void SFXOpenAL::reallySetVolume(float gain) if(m_status==SFX_UNKNOWN) return; + if(m_status==SFX_NOT_INITIALISED) + { + init(); + if(m_status==SFX_UNKNOWN) + return; + } + alSourcef(m_sound_source, AL_GAIN, m_gain * m_master_gain); } // reallySetVolume @@ -204,6 +214,13 @@ void SFXOpenAL::setMasterVolume(float gain) m_master_gain = gain; if(m_status==SFX_UNKNOWN) return; + if(m_status==SFX_NOT_INITIALISED) + { + init(); + if(m_status==SFX_UNKNOWN) + return; + } + alSourcef(m_sound_source, AL_GAIN, (m_gain < 0.0f ? m_default_gain : m_gain) * m_master_gain); @@ -224,6 +241,12 @@ void SFXOpenAL::setLoop(bool status) */ void SFXOpenAL::reallySetLoop(bool status) { + if(m_status==SFX_NOT_INITIALISED) + { + init(); + if(m_status==SFX_UNKNOWN) + return; + } m_loop = status; alSourcei(m_sound_source, AL_LOOPING, status ? AL_TRUE : AL_FALSE); @@ -290,6 +313,13 @@ void SFXOpenAL::resume() */ void SFXOpenAL::reallyResumeNow() { + if(m_status==SFX_NOT_INITIALISED) + { + init(); + if(m_status==SFX_UNKNOWN) + return; + } + if(m_status==SFX_PAUSED) { alSourcePlay(m_sound_source); @@ -324,7 +354,7 @@ void SFXOpenAL::play() void SFXOpenAL::reallyPlayNow() { if (!SFXManager::get()->sfxAllowed()) return; - if (m_status==SFX_UNKNOWN) + if (m_status==SFX_NOT_INITIALISED) { // lazily create OpenAL source when needed init(); @@ -354,14 +384,13 @@ void SFXOpenAL::setPosition(const Vec3 &position) */ void SFXOpenAL::reallySetPosition(const Vec3 &position) { - if(!UserConfigParams::m_sfx) - return; - if (m_status==SFX_UNKNOWN) + if(m_status==SFX_NOT_INITIALISED) { - Log::warn("SFX", "Position called on non-ok SFX <%s>", - m_sound_buffer->getFileName().c_str()); - return; + init(); + if(m_status==SFX_UNKNOWN) + return; } + if (!m_positional) { // in multiplayer, all sounds are positional, so in this case don't @@ -407,7 +436,7 @@ void SFXOpenAL::onSoundEnabledBack() { if (m_loop) { - if (m_status==SFX_UNKNOWN) init(); + if (m_status==SFX_NOT_INITIALISED) init(); if (m_status!=SFX_UNKNOWN) { alSourcef(m_sound_source, AL_GAIN, 0); diff --git a/src/audio/sfx_openal.hpp b/src/audio/sfx_openal.hpp index 23321f3e9..f417fedbb 100644 --- a/src/audio/sfx_openal.hpp +++ b/src/audio/sfx_openal.hpp @@ -102,7 +102,12 @@ public: virtual void setMasterVolume(float gain); virtual void onSoundEnabledBack(); virtual void setRolloff(float rolloff); - virtual SFXStatus getStatus(); + // ------------------------------------------------------------------------ + /** Returns if this sfx is looped or not. */ + virtual bool isLooped() { return m_loop; } + // ------------------------------------------------------------------------ + /** Returns the status of this sfx. */ + virtual SFXStatus getStatus() { return m_status; } // ------------------------------------------------------------------------ /** Returns the buffer associated with this sfx. */ From 9dff5a79907141c5cb1639fbf07976ee6db928c3 Mon Sep 17 00:00:00 2001 From: hiker Date: Mon, 20 Oct 2014 23:01:31 +1100 Subject: [PATCH 49/73] Fix potential memory overwrite in soccer mode when using one player only (artist debug mode). --- src/modes/soccer_world.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/modes/soccer_world.cpp b/src/modes/soccer_world.cpp index 022ffc9f0..4e4fc754c 100644 --- a/src/modes/soccer_world.cpp +++ b/src/modes/soccer_world.cpp @@ -436,6 +436,11 @@ void SoccerWorld::initKartList() for(unsigned int n=0; ngetLocalKartInfo(n).getSoccerTeam(); +#ifdef DEBUG + // In debug mode it's possible to play soccer with a single player + // (in artist debug mode). Avoid overwriting memory in this case. + if(team==SOCCER_TEAM_NONE) team=SOCCER_TEAM_RED; +#endif m_karts[n]->setPosition(team_cur_position[team]); team_cur_position[team]++; } // next kart From a09c1346b7460ad1280dc5d649f1571fd07562ae Mon Sep 17 00:00:00 2001 From: hiker Date: Tue, 21 Oct 2014 08:21:58 +1100 Subject: [PATCH 50/73] Fixed sound objects. --- src/tracks/track_object_presentation.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index 083ab3621..7f0bd7cf3 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -482,7 +482,8 @@ TrackObjectPresentationSound::TrackObjectPresentationSound(const XMLNode& xml_no xml_node.get("max_dist", &max_dist ); // first try track dir, then global dir - std::string soundfile = file_manager->getAsset(FileManager::MODEL,sound); + std::string soundfile = World::getWorld()->getTrack()->getTrackFile(sound); + //std::string soundfile = file_manager->getAsset(FileManager::MODEL,sound); if (!file_manager->fileExists(soundfile)) { soundfile = file_manager->getAsset(FileManager::SFX, sound); From c7d7e17ff97fada49e9477b049b87bd366d7ee28 Mon Sep 17 00:00:00 2001 From: hiker Date: Tue, 21 Oct 2014 08:28:41 +1100 Subject: [PATCH 51/73] Handle setMasterVolume in sfx thread. --- src/audio/dummy_sfx.hpp | 2 ++ src/audio/sfx_base.hpp | 51 ++++++++++++++++++++------------------- src/audio/sfx_manager.cpp | 3 +++ src/audio/sfx_manager.hpp | 1 + src/audio/sfx_openal.cpp | 27 +++++++++++++-------- src/audio/sfx_openal.hpp | 1 + 6 files changed, 50 insertions(+), 35 deletions(-) diff --git a/src/audio/dummy_sfx.hpp b/src/audio/dummy_sfx.hpp index 765912902..578eded7b 100644 --- a/src/audio/dummy_sfx.hpp +++ b/src/audio/dummy_sfx.hpp @@ -55,6 +55,8 @@ public: virtual void reallySetSpeed(float factor) {} virtual void setVolume(float gain) {} virtual void reallySetVolume(float gain) {} + virtual void setMasterVolume(float gain) {} + virtual void reallySetMasterVolumeNow(float gain) {} virtual SFXStatus getStatus() { return SFX_STOPPED; } virtual void onSoundEnabledBack() {} virtual void setRolloff(float rolloff) {} diff --git a/src/audio/sfx_base.hpp b/src/audio/sfx_base.hpp index 4e647b87c..eedc85b59 100644 --- a/src/audio/sfx_base.hpp +++ b/src/audio/sfx_base.hpp @@ -52,31 +52,32 @@ public: virtual ~SFXBase() {} /** Late creation, if SFX was initially disabled */ - virtual bool init() = 0; - virtual bool isLooped() = 0; - virtual void updatePlayingSFX(float dt) = 0; - virtual void setPosition(const Vec3 &p) = 0; - virtual void reallySetPosition(const Vec3 &p) = 0; - virtual void setLoop(bool status) = 0; - virtual void reallySetLoop(bool status) = 0; - virtual void play() = 0; - virtual void reallyPlayNow() = 0; - virtual void stop() = 0; - virtual void reallyStopNow() = 0; - virtual void pause() = 0; - virtual void reallyPauseNow() = 0; - virtual void resume() = 0; - virtual void reallyResumeNow() = 0; - virtual void deleteSFX() = 0; - virtual void setSpeed(float factor) = 0; - virtual void reallySetSpeed(float factor) = 0; - virtual void setVolume(float gain) = 0; - virtual void reallySetVolume(float gain) = 0; - virtual void setMasterVolume(float gain) = 0; - virtual void onSoundEnabledBack() = 0; - virtual void setRolloff(float rolloff) = 0; - virtual const SFXBuffer* getBuffer() const = 0; - virtual SFXStatus getStatus() = 0; + virtual bool init() = 0; + virtual bool isLooped() = 0; + virtual void updatePlayingSFX(float dt) = 0; + virtual void setPosition(const Vec3 &p) = 0; + virtual void reallySetPosition(const Vec3 &p) = 0; + virtual void setLoop(bool status) = 0; + virtual void reallySetLoop(bool status) = 0; + virtual void play() = 0; + virtual void reallyPlayNow() = 0; + virtual void stop() = 0; + virtual void reallyStopNow() = 0; + virtual void pause() = 0; + virtual void reallyPauseNow() = 0; + virtual void resume() = 0; + virtual void reallyResumeNow() = 0; + virtual void deleteSFX() = 0; + virtual void setSpeed(float factor) = 0; + virtual void reallySetSpeed(float factor) = 0; + virtual void setVolume(float gain) = 0; + virtual void reallySetVolume(float gain) = 0; + virtual void setMasterVolume(float gain) = 0; + virtual void reallySetMasterVolumeNow(float gain) = 0; + virtual void onSoundEnabledBack() = 0; + virtual void setRolloff(float rolloff) = 0; + virtual const SFXBuffer* getBuffer() const = 0; + virtual SFXStatus getStatus() = 0; }; // SFXBase diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 1b45a8a5c..f629dcce0 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -287,6 +287,9 @@ void* SFXManager::mainLoop(void *obj) current->m_parameter); break; case SFX_VOLUME: current->m_sfx->reallySetVolume( current->m_parameter.getX()); break; + case SFX_MASTER_VOLUME: + current->m_sfx->reallySetMasterVolumeNow( + current->m_parameter.getX()); break; case SFX_LOOP: current->m_sfx->reallySetLoop( current->m_parameter.getX()!=0); break; case SFX_DELETE: { diff --git a/src/audio/sfx_manager.hpp b/src/audio/sfx_manager.hpp index 47e4cbb74..7bcf9efce 100644 --- a/src/audio/sfx_manager.hpp +++ b/src/audio/sfx_manager.hpp @@ -72,6 +72,7 @@ public: SFX_SPEED, SFX_POSITION, SFX_VOLUME, + SFX_MASTER_VOLUME, SFX_LOOP, SFX_LISTENER, SFX_UPDATE, diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index dafd3ce1f..ef8046ee0 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -208,24 +208,31 @@ void SFXOpenAL::reallySetVolume(float gain) } // reallySetVolume //----------------------------------------------------------------------------- - +/** Schedules setting of the master volume. + * \param gain Gain value. + */ void SFXOpenAL::setMasterVolume(float gain) +{ + // This needs to be called even if sfx are disabled atm, so only exit + // in case that the sfx could not be loaded in the first place. + if(m_status==SFX_UNKNOWN) return; + SFXManager::get()->queue(SFXManager::SFX_MASTER_VOLUME, this, gain); +} // setMasterVolume + +//----------------------------------------------------------------------------- +/** Sets the master volume. + * \param gain Master volume. + */ +void SFXOpenAL::reallySetMasterVolumeNow(float gain) { m_master_gain = gain; - if(m_status==SFX_UNKNOWN) return; - if(m_status==SFX_NOT_INITIALISED) - { - init(); - if(m_status==SFX_UNKNOWN) - return; - } - + if(m_status==SFX_UNKNOWN || m_status == SFX_NOT_INITIALISED) return; alSourcef(m_sound_source, AL_GAIN, (m_gain < 0.0f ? m_default_gain : m_gain) * m_master_gain); SFXManager::checkError("setting volume"); -} //setMasterVolume +} // reallySetMasterVolumeNow //----------------------------------------------------------------------------- /** Loops this sound effect. diff --git a/src/audio/sfx_openal.hpp b/src/audio/sfx_openal.hpp index f417fedbb..87a3c7d3b 100644 --- a/src/audio/sfx_openal.hpp +++ b/src/audio/sfx_openal.hpp @@ -100,6 +100,7 @@ public: virtual void setVolume(float gain); virtual void reallySetVolume(float gain); virtual void setMasterVolume(float gain); + virtual void reallySetMasterVolumeNow(float gain); virtual void onSoundEnabledBack(); virtual void setRolloff(float rolloff); // ------------------------------------------------------------------------ From 65b7589849ff375e7d40033b6d61aa4acbab4329 Mon Sep 17 00:00:00 2001 From: hiker Date: Tue, 21 Oct 2014 08:31:10 +1100 Subject: [PATCH 52/73] Make sure the sfx are resumed before calling onSOundEnbaledBack(). --- src/audio/sfx_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index f629dcce0..41017e290 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -333,7 +333,7 @@ void SFXManager::soundToggled(const bool on) buffer->load(); } - resumeAll(); + reallyResumeAllNow(); m_all_sfx.lock(); const int sfx_amount = (int)m_all_sfx.getData().size(); for (int n=0; n Date: Fri, 17 Oct 2014 23:49:19 +0200 Subject: [PATCH 53/73] only one saved GP per GP-ident Conflicts: src/graphics/glwrap.cpp --- src/config/saved_grand_prix.cpp | 10 +- src/config/saved_grand_prix.hpp | 20 ++-- src/race/race_manager.cpp | 103 ++++++++---------- src/race/race_manager.hpp | 8 +- src/states_screens/dialogs/gp_info_dialog.cpp | 2 - src/states_screens/gp_info_screen.cpp | 24 ++-- 6 files changed, 74 insertions(+), 93 deletions(-) diff --git a/src/config/saved_grand_prix.cpp b/src/config/saved_grand_prix.cpp index 8f01643a6..e80714edd 100644 --- a/src/config/saved_grand_prix.cpp +++ b/src/config/saved_grand_prix.cpp @@ -143,29 +143,27 @@ void SavedGrandPrix::setKarts(const std::vector &kart_l //------------------------------------------------------------------------------ void SavedGrandPrix::loadKarts(std::vector & kart_list) { - //Fix aikarts int aikarts = 0; for(unsigned int i = 0; i < m_karts.size(); i++) { const KartProperties *kp = kart_properties_manager->getKart(m_karts[i].m_ident); - if(m_karts[i].m_local_player_id == -1) + if(m_karts[i].m_local_player_id == -1) // AI kart { - //AI kart found if(kp) kart_list[aikarts].m_ident = m_karts[i].m_ident; - kart_list[aikarts].m_score = m_karts[i].m_score; + kart_list[aikarts].m_score = m_karts[i].m_score; kart_list[aikarts].m_overall_time = m_karts[i].m_overall_time; aikarts++; } else { - //Get correct player + // Get correct player for(unsigned int x = kart_list.size()-m_player_karts; x < kart_list.size(); x++) { if(kart_list[x].m_local_player_id == m_karts[i].m_local_player_id) { - kart_list[x].m_score = m_karts[i].m_score; + kart_list[x].m_score = m_karts[i].m_score; kart_list[x].m_overall_time = m_karts[i].m_overall_time; } // if kart_list[x].m_local_player_id == m_karts[i].,_local } // for x diff --git a/src/config/saved_grand_prix.hpp b/src/config/saved_grand_prix.hpp index 840da10c7..f06f0ff0c 100644 --- a/src/config/saved_grand_prix.hpp +++ b/src/config/saved_grand_prix.hpp @@ -135,25 +135,19 @@ public: // ------------------------------------------------------------------------ /** Finds the right SavedGrandPrix given the specified data, or - * NULL if no matching GP was found. - */ + * NULL if no matching GP was found. */ static SavedGrandPrix* getSavedGP(unsigned int player, - const std::string &gpid, - int difficulty, int total_karts, - int player_karts) + const std::string &gpid, + const unsigned int number_of_players) { for (unsigned int n=0; ngetGPID() == gpid) && - (gp->getPlayerID() == player) && - (gp->getDifficulty() == difficulty) && - (gp->getTotalKarts() == total_karts) && - (gp->getPlayerKarts() == player_karts)){ + if (gp->getGPID() == gpid && + gp->getPlayerID() == player && + gp->getPlayerKarts() == (int)number_of_players) return gp; - } // if - } // for n + } return NULL; } // getSavedGP // ------------------------------------------------------------------------ diff --git a/src/race/race_manager.cpp b/src/race/race_manager.cpp index 539466de3..11bdfe29b 100644 --- a/src/race/race_manager.cpp +++ b/src/race/race_manager.cpp @@ -279,15 +279,38 @@ void RaceManager::computeRandomKartList() void RaceManager::startNew(bool from_overworld) { m_started_from_overworld = from_overworld; + m_saved_gp = NULL; // There will be checks for this being NULL done later - if(m_major_mode==MAJOR_MODE_GRAND_PRIX) + if (m_major_mode==MAJOR_MODE_GRAND_PRIX) { // GP: get tracks, laps and reverse info from grand prix m_tracks = m_grand_prix.getTrackNames(); m_num_laps = m_grand_prix.getLaps(); m_reverse_track = m_grand_prix.getReverse(); + + // Saved GP only in offline mode + if (m_continue_saved_gp && !NetworkWorld::getInstance()->isRunning()) + { + // We look if Player 1 has a saved version of this GP. + m_saved_gp = SavedGrandPrix::getSavedGP( + StateManager::get() + ->getActivePlayerProfile(0) + ->getUniqueID(), + m_grand_prix.getId(), + m_player_karts.size()); + + if (m_saved_gp == NULL) + { + Log::error("Race Manager", "Can not continue Grand Prix '%s'" + "because it could not exist", + m_grand_prix.getId().c_str()); + m_continue_saved_gp = false; // simple and working + } else { + setNumKarts(m_saved_gp->getTotalKarts()); + setupPlayerKartInfo(); + } + } } - //assert(m_player_karts.size() > 0); // command line parameters: negative numbers=all karts if(m_num_karts < 0 ) m_num_karts = stk_config->m_max_karts; @@ -308,8 +331,8 @@ void RaceManager::startNew(bool from_overworld) race_manager->getMinorMode()==RaceManager::MINOR_MODE_FOLLOW_LEADER ? -1 : 0; - const unsigned int ai_kart_count = (unsigned int) m_ai_kart_list.size(); - for(unsigned int i=0; i()->isRunning()) // offline mode only + if (MAJOR_MODE_GRAND_PRIX) { - //We look if Player 1 has a saved version of this GP. - // ================================================= - SavedGrandPrix* gp = SavedGrandPrix::getSavedGP( StateManager::get() - ->getActivePlayerProfile(0) - ->getUniqueID(), - m_grand_prix.getId(), - m_difficulty, - m_num_karts, - (int)m_player_karts.size()); - - // Start the race with the appropriate track - // ========================================= - if(gp != NULL) + if (m_continue_saved_gp) { - if (m_continue_saved_gp) - { - m_track_number = gp->getNextTrack(); - gp->loadKarts(m_kart_status); - } - else - { - gp->remove(); - } + m_track_number = m_saved_gp->getNextTrack(); + m_saved_gp->loadKarts(m_kart_status); + } + else + { + m_track_number = 0; + m_saved_gp->remove(); } } + startNextRace(); } // startNew @@ -493,25 +501,16 @@ void RaceManager::next() { if(m_major_mode==MAJOR_MODE_GRAND_PRIX && !NetworkWorld::getInstance()->isRunning()) { - //Saving GP state - //We look if Player 1 has already saved this GP. - SavedGrandPrix* gp = - SavedGrandPrix::getSavedGP(StateManager::get() - ->getActivePlayerProfile(0) - ->getUniqueID(), - m_grand_prix.getId(), - m_difficulty, - m_num_karts, - (int)m_player_karts.size()); - if(gp != NULL) + // Saving GP state + // If Player 1 has already saved a GP, we adapt it + if(m_saved_gp != NULL) { - //if so addept it - gp->setKarts(m_kart_status); - gp->setNextTrack(m_track_number); + m_saved_gp->setKarts(m_kart_status); + m_saved_gp->setNextTrack(m_track_number); } else { - //create a new entry + // Otherwise we create a new entry UserConfigParams::m_saved_grand_prix_list.push_back( new SavedGrandPrix( StateManager::get()->getActivePlayerProfile(0) @@ -630,16 +629,8 @@ void RaceManager::exitRace(bool delete_world) PlayerManager::getCurrentPlayer()->grandPrixFinished(); if(m_major_mode==MAJOR_MODE_GRAND_PRIX&& !NetworkWorld::getInstance()->isRunning()) { - //Delete saved GP - SavedGrandPrix* gp = - SavedGrandPrix::getSavedGP(StateManager::get() - ->getActivePlayerProfile(0) - ->getUniqueID(), - m_grand_prix.getId(), - m_difficulty, - m_num_karts, - (int)m_player_karts.size()); - if(gp != NULL) gp->remove(); + if(m_saved_gp != NULL) + m_saved_gp->remove(); } StateManager::get()->resetAndGoToScreen( MainMenuScreen::getInstance() ); @@ -717,6 +708,7 @@ void RaceManager::exitRace(bool delete_world) if (delete_world) World::deleteWorld(); + m_saved_gp = NULL; m_track_number = 0; } // exitRace @@ -766,7 +758,6 @@ void RaceManager::startGP(const GrandPrixData &gp, bool from_overworld, { StateManager::get()->enterGameState(); setGrandPrix(gp); - setCoinTarget( 0 ); // Might still be set from a previous challenge race_manager->setupPlayerKartInfo(); m_continue_saved_gp = continue_saved_gp; diff --git a/src/race/race_manager.hpp b/src/race/race_manager.hpp index 2d47aef98..5e7d9feca 100644 --- a/src/race/race_manager.hpp +++ b/src/race/race_manager.hpp @@ -36,6 +36,7 @@ #include "utils/vec3.hpp" class AbstractKart; +class SavedGrandPrix; class Track; static const std::string IDENT_STD ("STANDARD" ); @@ -326,6 +327,7 @@ private: std::vector m_ai_kart_list; int m_track_number; GrandPrixData m_grand_prix; + SavedGrandPrix* m_saved_gp; int m_num_karts; unsigned int m_num_finished_karts; unsigned int m_num_finished_players; @@ -410,11 +412,13 @@ public: */ void setDifficulty(Difficulty diff); + // ------------------------------------------------------------------------ + void setCoinTarget(int num) { m_coin_target = num; } // ------------------------------------------------------------------------ void setGrandPrix(const GrandPrixData &gp) { m_grand_prix = gp; - m_coin_target = 0; + setCoinTarget(0); } // ------------------------------------------------------------------------ void setAIKartOverride(const std::string& kart) @@ -453,8 +457,6 @@ public: m_ai_superpower = SUPERPOWER_NONE; } // ------------------------------------------------------------------------ - void setCoinTarget(int num) { m_coin_target = num; } - // ------------------------------------------------------------------------ void setTimeTarget(float num) { m_has_time_target = true; m_time_target = num; } /** \} */ diff --git a/src/states_screens/dialogs/gp_info_dialog.cpp b/src/states_screens/dialogs/gp_info_dialog.cpp index a283cae3c..464e9af30 100644 --- a/src/states_screens/dialogs/gp_info_dialog.cpp +++ b/src/states_screens/dialogs/gp_info_dialog.cpp @@ -203,8 +203,6 @@ void GPInfoDialog::addButtons() ->getActivePlayerProfile(0) ->getUniqueID(), m_gp.getId(), - race_manager->getDifficulty(), - race_manager->getNumberOfKarts(), race_manager->getNumLocalPlayers()); okBtn->m_properties[PROP_ID] = "start"; diff --git a/src/states_screens/gp_info_screen.cpp b/src/states_screens/gp_info_screen.cpp index d36133c92..8fc0c7422 100644 --- a/src/states_screens/gp_info_screen.cpp +++ b/src/states_screens/gp_info_screen.cpp @@ -81,7 +81,7 @@ void GPInfoScreen::loadedFromFile() // Only init the number of tracks here, this way the previously selected // number of tracks will be the default. m_num_tracks_spinner->setValue(1); - + m_ai_kart_spinner = getWidget("ai-spinner"); } // loadedFromFile @@ -97,14 +97,14 @@ void GPInfoScreen::setGP(const std::string &gp_ident) { // Doesn't matter what kind of GP we create, it just gets the // right id ("random"). - m_gp.createRandomGP(1, "standard", + m_gp.createRandomGP(1, "standard", m_reverse_spinner ? getReverse() : GrandPrixData::GP_NO_REVERSE); } } // setGP // ---------------------------------------------------------------------------- -/** Converts the currently selected reverse status into a value of type +/** Converts the currently selected reverse status into a value of type * GPReverseType . */ GrandPrixData::GPReverseType GPInfoScreen::getReverse() const @@ -130,8 +130,6 @@ void GPInfoScreen::beforeAddingWidget() SavedGrandPrix* saved_gp = SavedGrandPrix::getSavedGP( StateManager::get()->getActivePlayerProfile(0)->getUniqueID(), m_gp.getId(), - race_manager->getDifficulty(), - race_manager->getNumberOfKarts(), race_manager->getNumLocalPlayers()); RibbonWidget* ribbonButtons = getWidget("buttons"); @@ -194,10 +192,10 @@ void GPInfoScreen::init() else m_group_name = stringc(m_group_spinner->getStringValue().c_str()).c_str(); - // If there are more tracks selected atm as in the group (which can + // If there are more tracks selected atm as in the group (which can // happen if the group has been changed since last time this screen // was shown), adjust it: - int max_num_tracks = m_group_name=="all" + int max_num_tracks = m_group_name=="all" ? track_manager->getNumberOfRaceTracks() : (int)track_manager->getTracksInGroup(m_group_name).size(); m_num_tracks_spinner->setMax(max_num_tracks); @@ -207,7 +205,7 @@ void GPInfoScreen::init() } // Now create the random GP: - m_gp.createRandomGP(m_num_tracks_spinner->getValue(), + m_gp.createRandomGP(m_num_tracks_spinner->getValue(), m_group_name, getReverse(), true); } else @@ -215,7 +213,7 @@ void GPInfoScreen::init() getWidget("name")->setText(m_gp.getName(), false); m_gp.checkConsistency(); } - + // Number of AIs // ------------- const bool has_AI = race_manager->hasAI(); @@ -288,7 +286,7 @@ void GPInfoScreen::addScreenshot() m_screenshot_widget->m_h = screenshot_div->m_h; - // Temporary icon, will replace it just after + // Temporary icon, will replace it just after // (but it will be shown if the given icon is not found) m_screenshot_widget->m_properties[PROP_ICON] = "gui/main_help.png"; m_screenshot_widget->add(); @@ -336,7 +334,7 @@ void GPInfoScreen::eventCallback(Widget *, const std::string &name, // the current track. The current value in the Number-of-tracks-spinner // has to be updated, since otherwise the displayed (and used) value // can be bigger than the maximum. (Might be a TODO to fix this) - int max_num_tracks = m_group_name=="all" + int max_num_tracks = m_group_name=="all" ? track_manager->getNumberOfRaceTracks() : (int)track_manager->getTracksInGroup(m_group_name).size(); m_num_tracks_spinner->setMax(max_num_tracks); @@ -344,7 +342,7 @@ void GPInfoScreen::eventCallback(Widget *, const std::string &name, m_num_tracks_spinner->setValue(max_num_tracks); // Create a new (i.e. with new tracks) random gp, since the old // tracks might not all belong to the newly selected group. - + m_gp.createRandomGP(m_num_tracks_spinner->getValue(), m_group_name, getReverse(), /*new_tracks*/true); addTracks(); @@ -359,7 +357,7 @@ void GPInfoScreen::eventCallback(Widget *, const std::string &name, const int num_ai = m_ai_kart_spinner->getValue(); race_manager->setNumKarts( race_manager->getNumLocalPlayers() + num_ai ); UserConfigParams::m_num_karts = race_manager->getNumLocalPlayers() + num_ai; - + //Redraw scene because available buttons depend on current settings getWidget("buttons")->setSelection(0, PLAYER_ID_GAME_MASTER); reshowCurrentScreen(); From 035fc599ee1485be90eb429ead581142138112eb Mon Sep 17 00:00:00 2001 From: konstin Date: Sat, 18 Oct 2014 00:49:22 +0200 Subject: [PATCH 54/73] fix ordering of the karts and maybe some more --- src/config/saved_grand_prix.cpp | 8 ++++++++ src/config/saved_grand_prix.hpp | 5 +++-- src/race/race_manager.cpp | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/config/saved_grand_prix.cpp b/src/config/saved_grand_prix.cpp index e80714edd..9059ba5cf 100644 --- a/src/config/saved_grand_prix.cpp +++ b/src/config/saved_grand_prix.cpp @@ -140,9 +140,15 @@ void SavedGrandPrix::setKarts(const std::vector &kart_l } } // setKarts +/* compares two KartStatus-objects for std::sort in the next function */ +bool cmp__l(RaceManager::KartStatus first, RaceManager::KartStatus second) +{ + return (first.m_score > second.m_score); +} //------------------------------------------------------------------------------ void SavedGrandPrix::loadKarts(std::vector & kart_list) { + int aikarts = 0; for(unsigned int i = 0; i < m_karts.size(); i++) { @@ -169,4 +175,6 @@ void SavedGrandPrix::loadKarts(std::vector & kart_list) } // for x } // if m_local_player_id == -1 } // for i + + std::sort(kart_list.begin(), kart_list.end(), cmp__l); } // loadKarts diff --git a/src/config/saved_grand_prix.hpp b/src/config/saved_grand_prix.hpp index f06f0ff0c..746132fa2 100644 --- a/src/config/saved_grand_prix.hpp +++ b/src/config/saved_grand_prix.hpp @@ -19,11 +19,13 @@ #ifndef HEADER_SAVED_GRAND_PRIX_HPP #define HEADER_SAVED_GRAND_PRIX_HPP -#include #include "config/user_config.hpp" #include "race/race_manager.hpp" #include "utils/ptr_vector.hpp" +#include +#include + class RaceManager; // ============================================================================ @@ -151,7 +153,6 @@ public: return NULL; } // getSavedGP // ------------------------------------------------------------------------ - }; // class SavedGrandPrix #endif diff --git a/src/race/race_manager.cpp b/src/race/race_manager.cpp index 11bdfe29b..ee8e3d2ed 100644 --- a/src/race/race_manager.cpp +++ b/src/race/race_manager.cpp @@ -362,7 +362,7 @@ void RaceManager::startNew(bool from_overworld) init_gp_rank ++; } - if (MAJOR_MODE_GRAND_PRIX) + if (m_major_mode == MAJOR_MODE_GRAND_PRIX) { if (m_continue_saved_gp) { From f65ad8f84f8d699c77f946534a9d5a1af97674df Mon Sep 17 00:00:00 2001 From: konstin Date: Sat, 18 Oct 2014 20:54:25 +0200 Subject: [PATCH 55/73] Save GP reverse Type; close #1137 --- src/config/saved_grand_prix.cpp | 22 +++++++++++++--------- src/config/saved_grand_prix.hpp | 8 ++++++++ src/race/grand_prix_data.cpp | 2 ++ src/race/grand_prix_data.hpp | 18 ++++++++++++------ src/race/race_manager.cpp | 3 +++ 5 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/config/saved_grand_prix.cpp b/src/config/saved_grand_prix.cpp index 9059ba5cf..0f808e642 100644 --- a/src/config/saved_grand_prix.cpp +++ b/src/config/saved_grand_prix.cpp @@ -68,6 +68,7 @@ SavedGrandPrix::SavedGrandPrix(unsigned int player_id, RaceManager::Difficulty difficulty, int player_karts, int last_track, + int reverse_type, const std::vector &kart_list) : m_savedgp_group("SavedGP", "Represents the saved state of a GP"), @@ -75,7 +76,8 @@ SavedGrandPrix::SavedGrandPrix(unsigned int player_id, m_gp_id(gp_id.c_str(), "gp_id", &m_savedgp_group), m_difficulty((int)difficulty,"difficulty", &m_savedgp_group), m_player_karts(player_karts,"player_karts", &m_savedgp_group), - m_next_track(last_track,"last_track", &m_savedgp_group) + m_next_track(last_track,"last_track", &m_savedgp_group), + m_reverse_type(reverse_type,"reverse_type", &m_savedgp_group) { for(unsigned int i =0; i < kart_list.size(); i++) { @@ -94,18 +96,20 @@ SavedGrandPrix::SavedGrandPrix(unsigned int player_id, SavedGrandPrix::SavedGrandPrix(const XMLNode* node) : m_savedgp_group("SavedGP", "Represents the saved state of a GP"), - m_player_id(0, "player_id", &m_savedgp_group), - m_gp_id("-", "gp_id", &m_savedgp_group), - m_difficulty(0,"difficulty", &m_savedgp_group), + m_player_id (0, "player_id", &m_savedgp_group), + m_gp_id ("-", "gp_id", &m_savedgp_group), + m_difficulty (0,"difficulty", &m_savedgp_group), m_player_karts(0,"player_karts", &m_savedgp_group), - m_next_track(0,"last_track", &m_savedgp_group) + m_next_track (0,"last_track", &m_savedgp_group), + m_reverse_type(0,"reverse_type", &m_savedgp_group) { //m_player_group.findYourDataInAChildOf(node); - m_player_id.findYourDataInAnAttributeOf(node); - m_gp_id.findYourDataInAnAttributeOf(node); - m_difficulty.findYourDataInAnAttributeOf(node); + m_player_id. findYourDataInAnAttributeOf(node); + m_gp_id. findYourDataInAnAttributeOf(node); + m_difficulty. findYourDataInAnAttributeOf(node); m_player_karts.findYourDataInAnAttributeOf(node); - m_next_track.findYourDataInAnAttributeOf(node); + m_next_track. findYourDataInAnAttributeOf(node); + m_reverse_type.findYourDataInAnAttributeOf(node); std::vector karts; node->getNodes("Kart", karts); diff --git a/src/config/saved_grand_prix.hpp b/src/config/saved_grand_prix.hpp index 746132fa2..84b494067 100644 --- a/src/config/saved_grand_prix.hpp +++ b/src/config/saved_grand_prix.hpp @@ -76,6 +76,9 @@ protected: /** Index of the next to run track. */ IntUserConfigParam m_next_track; + /** GPReverseType of the GP as int */ + IntUserConfigParam m_reverse_type; + PtrVector m_karts; public: @@ -88,6 +91,7 @@ public: RaceManager::Difficulty difficulty, int player_karts, int last_track, + int reverse_type, const std::vector &kart_list); /** @@ -122,6 +126,10 @@ public: /** Returns the index of the last track finished when this GP was saved. */ int getNextTrack() const { return m_next_track; } + // ------------------------------------------------------------------------ + /** Returns the reverse Type. */ + int getReverseType() const { return m_reverse_type; } + // ------------------------------------------------------------------------ /** Sets the index of the last track finished. */ void setNextTrack(int next_track) { m_next_track = next_track; } diff --git a/src/race/grand_prix_data.cpp b/src/race/grand_prix_data.cpp index f7fac4613..e1c7d8f25 100644 --- a/src/race/grand_prix_data.cpp +++ b/src/race/grand_prix_data.cpp @@ -70,6 +70,7 @@ void GrandPrixData::createRandomGP(const unsigned int number_of_tracks, m_name = "Random Grand Prix"; m_editable = false; m_group = GP_NONE; + m_reverse_type = use_reverse; if(new_tracks) { @@ -155,6 +156,7 @@ void GrandPrixData::changeTrackNumber(const unsigned int number_of_tracks, */ void GrandPrixData::changeReverse(const GrandPrixData::GPReverseType use_reverse) { + m_reverse_type = use_reverse; for (unsigned int i = 0; i < m_tracks.size(); i++) { if (use_reverse == GP_NO_REVERSE) diff --git a/src/race/grand_prix_data.hpp b/src/race/grand_prix_data.hpp index 81f9d7726..0a2c617ad 100644 --- a/src/race/grand_prix_data.hpp +++ b/src/race/grand_prix_data.hpp @@ -94,6 +94,9 @@ public: GP_DEFAULT_REVERSE = 3 }; // GPReverseType +private: + GPReverseType m_reverse_type; + public: #if (defined(WIN32) || defined(_WIN32)) && !defined(__MINGW32__) # pragma warning(disable:4290) @@ -145,22 +148,25 @@ public: // ------------------------------------------------------------------------ /** @return the (potentially translated) user-visible name of the Grand * Prix (apply fribidi as needed) */ - irr::core::stringw getName() const { return _LTR(m_name.c_str()); } + irr::core::stringw getName() const { return _LTR(m_name.c_str()); } // ------------------------------------------------------------------------ /** @return the internal indentifier of the Grand Prix (not translated) */ - const std::string& getId() const { return m_id; } + const std::string& getId() const { return m_id; } // ------------------------------------------------------------------------ /** Returns true if this GP is a random GP. */ - bool isRandomGP() const { return m_id=="random"; } + bool isRandomGP() const { return m_id=="random"; } // ------------------------------------------------------------------------ /** Returns the filename of the grand prix xml file. */ - const std::string& getFilename() const { return m_filename; } + const std::string& getFilename() const { return m_filename; } // ------------------------------------------------------------------------ - /** Returns the group. */ - enum GPGroupType getGroup() const { return m_group; } + enum GPGroupType getGroup() const { return m_group; } + + // ------------------------------------------------------------------------ + enum GPReverseType getReverseType() + const { return m_reverse_type; } }; // GrandPrixData #endif diff --git a/src/race/race_manager.cpp b/src/race/race_manager.cpp index ee8e3d2ed..173ce1f4a 100644 --- a/src/race/race_manager.cpp +++ b/src/race/race_manager.cpp @@ -308,6 +308,8 @@ void RaceManager::startNew(bool from_overworld) } else { setNumKarts(m_saved_gp->getTotalKarts()); setupPlayerKartInfo(); + m_grand_prix.changeReverse((GrandPrixData::GPReverseType)m_saved_gp->getReverseType()); + m_reverse_track = m_grand_prix.getReverse(); } } } @@ -519,6 +521,7 @@ void RaceManager::next() m_difficulty, (int)m_player_karts.size(), m_track_number, + m_grand_prix.getReverseType(), m_kart_status ) ); From 4647a50acb970fb051637876523f569d14026600 Mon Sep 17 00:00:00 2001 From: konstin Date: Sat, 18 Oct 2014 21:07:54 +0200 Subject: [PATCH 56/73] Save GP on abort --- src/race/race_manager.cpp | 35 +++++++++++++++----------- src/race/race_manager.hpp | 7 ++++-- src/states_screens/race_result_gui.cpp | 1 + 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/race/race_manager.cpp b/src/race/race_manager.cpp index 173ce1f4a..30bb79908 100644 --- a/src/race/race_manager.cpp +++ b/src/race/race_manager.cpp @@ -492,7 +492,6 @@ void RaceManager::startNextRace() } // startNextRace //----------------------------------------------------------------------------- - void RaceManager::next() { World::deleteWorld(); @@ -509,24 +508,12 @@ void RaceManager::next() { m_saved_gp->setKarts(m_kart_status); m_saved_gp->setNextTrack(m_track_number); + user_config->saveConfig(); } else { - // Otherwise we create a new entry - UserConfigParams::m_saved_grand_prix_list.push_back( - new SavedGrandPrix( - StateManager::get()->getActivePlayerProfile(0) - ->getUniqueID(), - m_grand_prix.getId(), - m_difficulty, - (int)m_player_karts.size(), - m_track_number, - m_grand_prix.getReverseType(), - m_kart_status - ) - ); + saveGP(); } - user_config->saveConfig(); } startNextRace(); } @@ -536,6 +523,24 @@ void RaceManager::next() } } // next +//----------------------------------------------------------------------------- +void RaceManager::saveGP() +{ + UserConfigParams::m_saved_grand_prix_list.push_back( + new SavedGrandPrix( + StateManager::get()->getActivePlayerProfile(0) + ->getUniqueID(), + m_grand_prix.getId(), + m_difficulty, + (int)m_player_karts.size(), + m_track_number, + m_grand_prix.getReverseType(), + m_kart_status + ) + ); + user_config->saveConfig(); +} + //----------------------------------------------------------------------------- /** This class is only used in computeGPRanks, but the C++ standard diff --git a/src/race/race_manager.hpp b/src/race/race_manager.hpp index 5e7d9feca..e53956fc9 100644 --- a/src/race/race_manager.hpp +++ b/src/race/race_manager.hpp @@ -685,8 +685,11 @@ public: * \brief Higher-level method to start a GP without having to care about * the exact startup sequence */ - void startGP(const GrandPrixData &gp, bool from_overworld, - bool continue_saved_gp); + void startGP(const GrandPrixData &gp, bool from_overworld, + bool continue_saved_gp); + + /** Saves the current GP to the config */ + void saveGP(); /** * \brief Higher-level method to start a GP without having to care about diff --git a/src/states_screens/race_result_gui.cpp b/src/states_screens/race_result_gui.cpp index c618274c3..e9153d64f 100644 --- a/src/states_screens/race_result_gui.cpp +++ b/src/states_screens/race_result_gui.cpp @@ -393,6 +393,7 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget, void RaceResultGUI::onConfirm() { + race_manager->saveGP(); // Save the aborted GP GUIEngine::ModalDialog::dismiss(); cleanupGPProgress(); StateManager::get()->popMenu(); From 321f0e7078223ebe1de8ce0195ee3169319e0d50 Mon Sep 17 00:00:00 2001 From: Deve Date: Mon, 20 Oct 2014 23:19:20 +0200 Subject: [PATCH 57/73] Remove saved GP when we start new race. Avoid a crash. Saved GP was deleted, but was not NULL. And in other place we have if(m_saved_gp != NULL) check, which was true for deleted object. --- src/race/race_manager.cpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/race/race_manager.cpp b/src/race/race_manager.cpp index 30bb79908..19e14a812 100644 --- a/src/race/race_manager.cpp +++ b/src/race/race_manager.cpp @@ -288,24 +288,26 @@ void RaceManager::startNew(bool from_overworld) m_num_laps = m_grand_prix.getLaps(); m_reverse_track = m_grand_prix.getReverse(); + // We look if Player 1 has a saved version of this GP. + m_saved_gp = SavedGrandPrix::getSavedGP( + StateManager::get() + ->getActivePlayerProfile(0) + ->getUniqueID(), + m_grand_prix.getId(), + m_player_karts.size()); + // Saved GP only in offline mode if (m_continue_saved_gp && !NetworkWorld::getInstance()->isRunning()) { - // We look if Player 1 has a saved version of this GP. - m_saved_gp = SavedGrandPrix::getSavedGP( - StateManager::get() - ->getActivePlayerProfile(0) - ->getUniqueID(), - m_grand_prix.getId(), - m_player_karts.size()); - if (m_saved_gp == NULL) { Log::error("Race Manager", "Can not continue Grand Prix '%s'" "because it could not exist", m_grand_prix.getId().c_str()); m_continue_saved_gp = false; // simple and working - } else { + } + else + { setNumKarts(m_saved_gp->getTotalKarts()); setupPlayerKartInfo(); m_grand_prix.changeReverse((GrandPrixData::GPReverseType)m_saved_gp->getReverseType()); @@ -364,6 +366,7 @@ void RaceManager::startNew(bool from_overworld) init_gp_rank ++; } + m_track_number = 0; if (m_major_mode == MAJOR_MODE_GRAND_PRIX) { if (m_continue_saved_gp) @@ -371,10 +374,10 @@ void RaceManager::startNew(bool from_overworld) m_track_number = m_saved_gp->getNextTrack(); m_saved_gp->loadKarts(m_kart_status); } - else + else if (m_saved_gp != NULL) { - m_track_number = 0; m_saved_gp->remove(); + m_saved_gp = NULL; } } From 04933af4b05e87c4469aa6f14185f409fa50f099 Mon Sep 17 00:00:00 2001 From: Deve Date: Mon, 20 Oct 2014 23:45:06 +0200 Subject: [PATCH 58/73] Redrawing GP info screen is not needed now. --- src/states_screens/gp_info_screen.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/states_screens/gp_info_screen.cpp b/src/states_screens/gp_info_screen.cpp index 8fc0c7422..db587f75c 100644 --- a/src/states_screens/gp_info_screen.cpp +++ b/src/states_screens/gp_info_screen.cpp @@ -357,11 +357,6 @@ void GPInfoScreen::eventCallback(Widget *, const std::string &name, const int num_ai = m_ai_kart_spinner->getValue(); race_manager->setNumKarts( race_manager->getNumLocalPlayers() + num_ai ); UserConfigParams::m_num_karts = race_manager->getNumLocalPlayers() + num_ai; - - //Redraw scene because available buttons depend on current settings - getWidget("buttons")->setSelection(0, PLAYER_ID_GAME_MASTER); - reshowCurrentScreen(); - m_ai_kart_spinner->setFocusForPlayer(PLAYER_ID_GAME_MASTER); } else if(name=="back") { From 8d9f1aa002d5012e0c0f24831469e8b0dda0c608 Mon Sep 17 00:00:00 2001 From: hiker Date: Tue, 21 Oct 2014 08:48:21 +1100 Subject: [PATCH 59/73] Renamed SoundToggled to toggleSound. --- src/audio/sfx_manager.cpp | 4 ++-- src/audio/sfx_manager.hpp | 2 +- src/states_screens/options_screen_audio.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 41017e290..1a8ad86fc 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -321,7 +321,7 @@ void* SFXManager::mainLoop(void *obj) * resumes all sound effects. * \param on If sound is switched on or off. */ -void SFXManager::soundToggled(const bool on) +void SFXManager::toggleSound(const bool on) { // When activating SFX, load all buffers if (on) @@ -357,7 +357,7 @@ void SFXManager::soundToggled(const bool on) m_all_sfx.unlock(); pauseAll(); } -} // soundToggled +} // toggleSound //---------------------------------------------------------------------------- /** Returns if sfx can be played. This means sfx are enabled and diff --git a/src/audio/sfx_manager.hpp b/src/audio/sfx_manager.hpp index 7bcf9efce..01cbf0038 100644 --- a/src/audio/sfx_manager.hpp +++ b/src/audio/sfx_manager.hpp @@ -234,7 +234,7 @@ public: SFXBase* quickSound(const std::string &soundName); /** Called when sound was muted/unmuted */ - void soundToggled(const bool newValue); + void toggleSound(const bool newValue); // ------------------------------------------------------------------------ /** Prints the list of currently loaded sounds to stdout. Useful to diff --git a/src/states_screens/options_screen_audio.cpp b/src/states_screens/options_screen_audio.cpp index c3cfc751b..819a38a0d 100644 --- a/src/states_screens/options_screen_audio.cpp +++ b/src/states_screens/options_screen_audio.cpp @@ -163,7 +163,7 @@ void OptionsScreenAudio::eventCallback(Widget* widget, const std::string& name, CheckBoxWidget* w = dynamic_cast(widget); UserConfigParams::m_sfx = w->getState(); - SFXManager::get()->soundToggled(UserConfigParams::m_sfx); + SFXManager::get()->toggleSound(UserConfigParams::m_sfx); if (UserConfigParams::m_sfx) { From 2e27d8724ae0147591a7de19b2da4a1fcaec8a3a Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Tue, 21 Oct 2014 00:35:25 +0200 Subject: [PATCH 60/73] Add a script that computes IBL factors --- tools/ibl.py | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 tools/ibl.py diff --git a/tools/ibl.py b/tools/ibl.py new file mode 100644 index 000000000..f90383b81 --- /dev/null +++ b/tools/ibl.py @@ -0,0 +1,51 @@ +import Image as img +import numpy as np +import pylab as pl + +n = 4 + +# constant factor of Ylm +c00 = 0.282095 +c1minus1 = 0.488603 +c10 = 0.488603 +c11 = 0.488603 +c2minus2 = 1.092548 +c2minus1 = 1.092548 +c21 = 1.092548 +c20 = 0.315392 +c22 = 0.546274 + +def computeYmlOnGrid(Xgrid, Ygrid, Zgrid): + "compute Yml from Y00 to Y22 on Xgrid/Ygrid/Zgrid" + "Xgrid/Ygrid/Zgrid must be normalised" + Y00 = c00 + Y1minus1 = c1minus1 * Ygrid + Y10 = c10 * Zgrid + Y11 = c11 * Xgrid + Y2minus2 = c2minus2 * Xgrid * Ygrid + Y2minus1 = c2minus1 * Ygrid * Zgrid + Y21= c21 * Xgrid * Zgrid + Y20 = c20 * (3 * Zgrid * Zgrid - 1) + Y22 = c22 * (Xgrid * Xgrid - Ygrid * Ygrid) + return (Y00, Y1minus1, Y10, Y11, Y2minus2, Y2minus1, Y20, Y21, Y22) + + +Grid0, Grid1 = np.meshgrid(np.linspace(-1, 1, n), np.linspace(-1, 1, n)) + +FaceGrid = [(np.ones((n,n)), Grid0, Grid1), #GL_TEXTURE_CUBE_MAP_POSITIVE_X + (-1 * np.ones((n,n)), Grid0, Grid1), #GL_TEXTURE_CUBE_MAP_NEGATIVE_X + (Grid0, np.ones((n,n)), Grid1), #GL_TEXTURE_CUBE_MAP_POSITIVE_Y + (Grid0, -1 * np.ones((n,n)), Grid1), #GL_TEXTURE_CUBE_MAP_NEGATIVE_Y + (Grid0, Grid1, np.ones((n,n))), #GL_TEXTURE_CUBE_MAP_POSITIVE_Z + (Grid0, Grid1, -1 * np.ones((n,n)))] #GL_TEXTURE_CUBE_MAP_NEGATIVE_Z + +res = [] +for (Xd, Yd, Zd) in FaceGrid: + res.append(computeYmlOnGrid(Xd, Yd, Zd)) + +print(res) + +I = img.open("C:/Users/vljn_000/Documents/GitHub/stk-assets/textures/ants.png") +m = np.array(I) +print(type(m)) +pl.imshow(m) From 0025f908db7fd236d775b0dfa905cc1624ffb88c Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Mon, 20 Oct 2014 20:38:37 -0400 Subject: [PATCH 61/73] Add cleanup post-minimap-RTT. Appears to fix #1470 . Hard to know for sure since this bug is random :( --- src/tracks/quad_graph.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/tracks/quad_graph.cpp b/src/tracks/quad_graph.cpp index a8198cdd1..638608adc 100644 --- a/src/tracks/quad_graph.cpp +++ b/src/tracks/quad_graph.cpp @@ -1104,6 +1104,13 @@ void QuadGraph::makeMiniMap(const core::dimension2du &dimension, *newRttMinimap = frame_buffer; World::getWorld()->setClearbackBufferColor(oldClearColor); World::getWorld()->forceFogDisabled(false); + + irr_driver->getSceneManager()->clear(); + VAOManager::kill(); + irr_driver->clearGlowingNodes(); + irr_driver->clearLights(); + irr_driver->clearForcedBloom(); + irr_driver->clearBackgroundNodes(); } // makeMiniMap //----------------------------------------------------------------------------- From 690ad4ce95024b44878ec391e4d1b756a210521a Mon Sep 17 00:00:00 2001 From: hiker Date: Tue, 21 Oct 2014 22:07:22 +1100 Subject: [PATCH 62/73] Fixed sfx direction. --- src/audio/sfx_manager.cpp | 6 +++--- src/audio/sfx_openal.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 1a8ad86fc..03261862c 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -814,15 +814,15 @@ void SFXManager::reallyPositionListenerNow() float orientation[6]; orientation[0] = m_listener_front.getX(); orientation[1] = m_listener_front.getY(); - orientation[2] = m_listener_front.getZ(); + orientation[2] = -m_listener_front.getZ(); //up vector orientation[3] = m_listener_up.getX(); orientation[4] = m_listener_up.getY(); - orientation[5] = m_listener_up.getZ(); + orientation[5] = -m_listener_up.getZ(); const Vec3 &pos = m_listener_position.getData(); - alListener3f(AL_POSITION, pos.getX(), pos.getY(), pos.getZ()); + alListener3f(AL_POSITION, pos.getX(), pos.getY(), -pos.getZ()); alListenerfv(AL_ORIENTATION, orientation); } m_listener_position.unlock(); diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index ef8046ee0..1d676410a 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -410,8 +410,8 @@ void SFXOpenAL::reallySetPosition(const Vec3 &position) return; } - alSource3f(m_sound_source, AL_POSITION, (float)position.getX(), - (float)position.getY(), (float)position.getZ()); + alSource3f(m_sound_source, AL_POSITION, position.getX(), + position.getY(), -position.getZ()); if (SFXManager::get()->getListenerPos().distance(position) > m_sound_buffer->getMaxDist()) From c012e98f9b17b7f88333851182d0332371bc739e Mon Sep 17 00:00:00 2001 From: hiker Date: Wed, 22 Oct 2014 08:20:26 +1100 Subject: [PATCH 63/73] Allow disabling of hw stats collection. --- data/gui/options_ui.stkgui | 11 +++++-- src/config/hardware_stats.cpp | 3 ++ src/config/user_config.hpp | 6 ++++ src/main.cpp | 9 ++++-- src/states_screens/options_screen_ui.cpp | 39 ++++++++++++++++++++++++ 5 files changed, 63 insertions(+), 5 deletions(-) diff --git a/data/gui/options_ui.stkgui b/data/gui/options_ui.stkgui index 5e411fba1..266ace0f6 100644 --- a/data/gui/options_ui.stkgui +++ b/data/gui/options_ui.stkgui @@ -33,6 +33,12 @@
+
+ + +
+
@@ -40,9 +46,10 @@
- + -
diff --git a/src/config/hardware_stats.cpp b/src/config/hardware_stats.cpp index 275cb71a0..6ca8d27d8 100644 --- a/src/config/hardware_stats.cpp +++ b/src/config/hardware_stats.cpp @@ -257,6 +257,9 @@ const std::string& getOSVersion() */ void reportHardwareStats() { + if(!UserConfigParams::m_hw_report_enable) + return; + // Version of the hw report, which is stored in the DB. If new fields // are added, increase this version. Each STK installation will report // its configuration only once (per version number). So if the version diff --git a/src/config/user_config.hpp b/src/config/user_config.hpp index 3de0c45e0..fedf7a5ac 100644 --- a/src/config/user_config.hpp +++ b/src/config/user_config.hpp @@ -698,6 +698,12 @@ namespace UserConfigParams &m_hw_report_group, "The server used for reporting statistics to.")); + PARAM_PREFIX BoolUserConfigParam m_hw_report_enable + PARAM_DEFAULT( BoolUserConfigParam( true, + "hw-report-enabled", + &m_hw_report_group, + "If HW reports are enabled.")); + // ---- User management PARAM_PREFIX BoolUserConfigParam m_always_show_login_screen diff --git a/src/main.cpp b/src/main.cpp index 54bd8b79e..58a860cff 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1150,11 +1150,12 @@ void askForInternetPermission() }; // ConfirmServer new MessageDialog(_("SuperTuxKart may connect to a server " - "to download add-ons and notify you of updates. Would you " - "like this feature to be enabled? (To change this setting " + "to download add-ons and notify you of updates. We also collect " + "anonymous hardware statistics to help with the development of STK. " + "Would you like this feature to be enabled? (To change this setting " "at a later time, go to options, select tab " "'User Interface', and edit \"Allow STK to connect to the " - "Internet\")."), + "Internet\" and \"Allow STK to send anonymous HW statistics\")."), MessageDialog::MESSAGE_DIALOG_CONFIRM, new ConfirmServer(), true); } @@ -1302,6 +1303,8 @@ int main(int argc, char *argv[] ) } } + // Note that on the very first run of STK internet status is set to + // "not asked", so the report will only be sent in the next run. if(UserConfigParams::m_internet_status==Online::RequestManager::IPERM_ALLOWED) { HardwareStats::reportHardwareStats(); diff --git a/src/states_screens/options_screen_ui.cpp b/src/states_screens/options_screen_ui.cpp index 3e796e33f..435344297 100644 --- a/src/states_screens/options_screen_ui.cpp +++ b/src/states_screens/options_screen_ui.cpp @@ -21,12 +21,14 @@ #include "audio/music_manager.hpp" #include "audio/sfx_manager.hpp" #include "audio/sfx_base.hpp" +#include "config/hardware_stats.hpp" #include "config/user_config.hpp" #include "guiengine/scalable_font.hpp" #include "guiengine/screen.hpp" #include "guiengine/widgets/button_widget.hpp" #include "guiengine/widgets/check_box_widget.hpp" #include "guiengine/widgets/dynamic_ribbon_widget.hpp" +#include "guiengine/widgets/label_widget.hpp" #include "guiengine/widgets/list_widget.hpp" #include "guiengine/widgets/spinner_widget.hpp" #include "guiengine/widget.hpp" @@ -130,6 +132,23 @@ void OptionsScreenUI::init() assert( news != NULL ); news->setState( UserConfigParams::m_internet_status ==RequestManager::IPERM_ALLOWED ); + CheckBoxWidget* stats = getWidget("enable-hw-report"); + assert( stats != NULL ); + LabelWidget *stats_label = getWidget("label-hw-report"); + assert( stats_label ); + stats->setState(UserConfigParams::m_hw_report_enable); + + if(news->getState()) + { + stats_label->setVisible(true); + stats->setVisible(true); + stats->setState(UserConfigParams::m_hw_report_enable); + } + else + { + stats_label->setVisible(false); + stats->setVisible(false); + } CheckBoxWidget* show_login = getWidget("show-login"); assert( show_login!= NULL ); @@ -251,8 +270,28 @@ void OptionsScreenUI::eventCallback(Widget* widget, const std::string& name, con // If internet gets enabled, re-initialise the addon manager (which // happens in a separate thread) so that news.xml etc can be // downloaded if necessary. + CheckBoxWidget *stats = getWidget("enable-hw-report"); + LabelWidget *stats_label = getWidget("label-hw-report"); if(internet->getState()) + { NewsManager::get()->init(false); + stats->setVisible(true); + stats_label->setVisible(true); + stats->setState(UserConfigParams::m_hw_report_enable); + } + else + { + stats->setVisible(false); + stats_label->setVisible(false); + } + + } + else if (name=="enable-hw-report") + { + CheckBoxWidget* stats = getWidget("enable-hw-report"); + UserConfigParams::m_hw_report_enable = stats->getState(); + if(stats->getState()) + HardwareStats::reportHardwareStats(); } else if (name=="show-login") { From d9ea756b157709de54cf4f4a3096e356f4154b4b Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Tue, 21 Oct 2014 23:28:01 +0200 Subject: [PATCH 64/73] Add function for solid angle --- tools/ibl.py | 44 +++++++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/tools/ibl.py b/tools/ibl.py index f90383b81..25e426061 100644 --- a/tools/ibl.py +++ b/tools/ibl.py @@ -2,7 +2,7 @@ import Image as img import numpy as np import pylab as pl -n = 4 +n = 3 # constant factor of Ylm c00 = 0.282095 @@ -30,22 +30,40 @@ def computeYmlOnGrid(Xgrid, Ygrid, Zgrid): return (Y00, Y1minus1, Y10, Y11, Y2minus2, Y2minus1, Y20, Y21, Y22) -Grid0, Grid1 = np.meshgrid(np.linspace(-1, 1, n), np.linspace(-1, 1, n)) +GridI, GridJ = np.meshgrid(np.linspace(-1, 1, n), np.linspace(-1, 1, n)) -FaceGrid = [(np.ones((n,n)), Grid0, Grid1), #GL_TEXTURE_CUBE_MAP_POSITIVE_X - (-1 * np.ones((n,n)), Grid0, Grid1), #GL_TEXTURE_CUBE_MAP_NEGATIVE_X - (Grid0, np.ones((n,n)), Grid1), #GL_TEXTURE_CUBE_MAP_POSITIVE_Y - (Grid0, -1 * np.ones((n,n)), Grid1), #GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - (Grid0, Grid1, np.ones((n,n))), #GL_TEXTURE_CUBE_MAP_POSITIVE_Z - (Grid0, Grid1, -1 * np.ones((n,n)))] #GL_TEXTURE_CUBE_MAP_NEGATIVE_Z +FaceGrid = [(np.ones((n,n)), -GridI, -GridJ), #GL_TEXTURE_CUBE_MAP_POSITIVE_X + (-1 * np.ones((n,n)), -GridI, GridJ), #GL_TEXTURE_CUBE_MAP_NEGATIVE_X + (GridJ, np.ones((n,n)), GridI), #GL_TEXTURE_CUBE_MAP_POSITIVE_Y + (GridJ, -1 * np.ones((n,n)), -GridI), #GL_TEXTURE_CUBE_MAP_NEGATIVE_Y + (GridJ, GridI, np.ones((n,n))), #GL_TEXTURE_CUBE_MAP_POSITIVE_Z + (GridJ, -GridI, -1 * np.ones((n,n)))] #GL_TEXTURE_CUBE_MAP_NEGATIVE_Z res = [] for (Xd, Yd, Zd) in FaceGrid: res.append(computeYmlOnGrid(Xd, Yd, Zd)) -print(res) + +# From http://www.rorydriscoll.com/2012/01/15/cubemap-texel-solid-angle/ +def areaToPoint(x, y): + return np.arctan2(x * y, np.sqrt(x * x + y * y + 1)) +def getSolidAngleGrid(Xgrid, Ygrid): + "Compute solid angles using Xgrid/Ygrid/Zgrid texel position" + result = np.zeros((n,n)) + for i in range(n): + for j in range(n): + x = Xgrid[i,j] + y = Ygrid[i,j] + x0 = x - (1. / n) + x1 = x + (1. / n) + y0 = y - (1. / n) + y1 = y + (1. / n) + result[i,j] = areaToPoint(x0,y0) - areaToPoint(x1, y0) - areaToPoint(x0, y1) + areaToPoint(x1, y1) + return result + +print(getSolidAngleGrid(GridI, GridJ)) -I = img.open("C:/Users/vljn_000/Documents/GitHub/stk-assets/textures/ants.png") -m = np.array(I) -print(type(m)) -pl.imshow(m) +#I = img.open("C:/Users/vljn_000/Documents/GitHub/stk-assets/textures/ants.png") +#m = np.array(I) +#print(type(m)) +#pl.imshow(m) From 82610cc048e4a2064fb32700e4927cb088c4e1ed Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Tue, 21 Oct 2014 23:32:45 +0200 Subject: [PATCH 65/73] Normalize terms in computeYmlOnGrid --- tools/ibl.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/tools/ibl.py b/tools/ibl.py index 25e426061..9bac306d4 100644 --- a/tools/ibl.py +++ b/tools/ibl.py @@ -17,16 +17,19 @@ c22 = 0.546274 def computeYmlOnGrid(Xgrid, Ygrid, Zgrid): "compute Yml from Y00 to Y22 on Xgrid/Ygrid/Zgrid" - "Xgrid/Ygrid/Zgrid must be normalised" + norm = np.sqrt(Xgrid * Xgrid + Ygrid * Ygrid + Zgrid * Zgrid) + Xg = Xgrid / norm + Yg = Ygrid / norm + Zg = Zgrid / norm Y00 = c00 - Y1minus1 = c1minus1 * Ygrid - Y10 = c10 * Zgrid - Y11 = c11 * Xgrid - Y2minus2 = c2minus2 * Xgrid * Ygrid - Y2minus1 = c2minus1 * Ygrid * Zgrid - Y21= c21 * Xgrid * Zgrid - Y20 = c20 * (3 * Zgrid * Zgrid - 1) - Y22 = c22 * (Xgrid * Xgrid - Ygrid * Ygrid) + Y1minus1 = c1minus1 * Yg + Y10 = c10 * Zg + Y11 = c11 * Xg + Y2minus2 = c2minus2 * Xg * Yg + Y2minus1 = c2minus1 * Yg * Zg + Y21= c21 * Xg * Zg + Y20 = c20 * (3 * Zg * Zg - 1) + Y22 = c22 * (Xg * Xg - Yg * Yg) return (Y00, Y1minus1, Y10, Y11, Y2minus2, Y2minus1, Y20, Y21, Y22) From 7d22a5961dd0cfb1ac4518252f4d71f006969a53 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Tue, 21 Oct 2014 23:37:48 +0200 Subject: [PATCH 66/73] Vectorize solid angles a little more --- tools/ibl.py | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/tools/ibl.py b/tools/ibl.py index 9bac306d4..fad960754 100644 --- a/tools/ibl.py +++ b/tools/ibl.py @@ -50,19 +50,16 @@ for (Xd, Yd, Zd) in FaceGrid: # From http://www.rorydriscoll.com/2012/01/15/cubemap-texel-solid-angle/ def areaToPoint(x, y): return np.arctan2(x * y, np.sqrt(x * x + y * y + 1)) + def getSolidAngleGrid(Xgrid, Ygrid): "Compute solid angles using Xgrid/Ygrid/Zgrid texel position" - result = np.zeros((n,n)) - for i in range(n): - for j in range(n): - x = Xgrid[i,j] - y = Ygrid[i,j] - x0 = x - (1. / n) - x1 = x + (1. / n) - y0 = y - (1. / n) - y1 = y + (1. / n) - result[i,j] = areaToPoint(x0,y0) - areaToPoint(x1, y0) - areaToPoint(x0, y1) + areaToPoint(x1, y1) - return result + (step, _) = np.shape(Xgrid) + x0 = Xgrid - (1. / step) + x1 = Xgrid + (1. / step) + y0 = Ygrid - (1. / step) + y1 = Ygrid + (1. / step) + return areaToPoint(x0,y0) - areaToPoint(x1, y0) - areaToPoint(x0, y1) + areaToPoint(x1, y1) + print(getSolidAngleGrid(GridI, GridJ)) From 69c155063a3eb4a83a6d63a76a23b8c49f245536 Mon Sep 17 00:00:00 2001 From: hiker Date: Wed, 22 Oct 2014 09:15:42 +1100 Subject: [PATCH 67/73] Added Yes/No dialog box, and used it for the 'allow STK to connect to internet' question. --- src/main.cpp | 2 +- src/states_screens/dialogs/message_dialog.cpp | 8 ++++++++ src/states_screens/dialogs/message_dialog.hpp | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 58a860cff..ffa2277a3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1156,7 +1156,7 @@ void askForInternetPermission() "at a later time, go to options, select tab " "'User Interface', and edit \"Allow STK to connect to the " "Internet\" and \"Allow STK to send anonymous HW statistics\")."), - MessageDialog::MESSAGE_DIALOG_CONFIRM, + MessageDialog::MESSAGE_DIALOG_YESNO, new ConfirmServer(), true); } diff --git a/src/states_screens/dialogs/message_dialog.cpp b/src/states_screens/dialogs/message_dialog.cpp index c012dcd86..b9a571b46 100644 --- a/src/states_screens/dialogs/message_dialog.cpp +++ b/src/states_screens/dialogs/message_dialog.cpp @@ -95,6 +95,14 @@ void MessageDialog::doInit(MessageDialogType type, cancelbtn->setText(_("OK")); cancelbtn->setFocusForPlayer(PLAYER_ID_GAME_MASTER); } + else if (type == MessageDialog::MESSAGE_DIALOG_YESNO) + { + ButtonWidget* yesbtn = getWidget("confirm"); + + ButtonWidget* cancelbtn = getWidget("cancel"); + cancelbtn->setText(_("No")); + + } else if (type == MessageDialog::MESSAGE_DIALOG_OK_CANCEL) { // In case of a OK_CANCEL dialog, change the text from 'Yes' to 'Ok' diff --git a/src/states_screens/dialogs/message_dialog.hpp b/src/states_screens/dialogs/message_dialog.hpp index c325b52f4..05dfda475 100644 --- a/src/states_screens/dialogs/message_dialog.hpp +++ b/src/states_screens/dialogs/message_dialog.hpp @@ -62,7 +62,7 @@ public: }; enum MessageDialogType { MESSAGE_DIALOG_OK, MESSAGE_DIALOG_CONFIRM, - MESSAGE_DIALOG_OK_CANCEL }; + MESSAGE_DIALOG_OK_CANCEL, MESSAGE_DIALOG_YESNO }; private: From de09937f88d23a7e27d9492a8dcd4042758eb92a Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Wed, 22 Oct 2014 00:17:32 +0200 Subject: [PATCH 68/73] Algorithm for diffuse coeff implemented in py --- tools/ibl.py | 57 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/tools/ibl.py b/tools/ibl.py index fad960754..fd3472322 100644 --- a/tools/ibl.py +++ b/tools/ibl.py @@ -3,6 +3,8 @@ import numpy as np import pylab as pl n = 3 +GridI, GridJ = np.meshgrid(np.linspace(-1, 1, n), np.linspace(-1, 1, n)) +img = np.ones((n,n)) # constant factor of Ylm c00 = 0.282095 @@ -32,21 +34,6 @@ def computeYmlOnGrid(Xgrid, Ygrid, Zgrid): Y22 = c22 * (Xg * Xg - Yg * Yg) return (Y00, Y1minus1, Y10, Y11, Y2minus2, Y2minus1, Y20, Y21, Y22) - -GridI, GridJ = np.meshgrid(np.linspace(-1, 1, n), np.linspace(-1, 1, n)) - -FaceGrid = [(np.ones((n,n)), -GridI, -GridJ), #GL_TEXTURE_CUBE_MAP_POSITIVE_X - (-1 * np.ones((n,n)), -GridI, GridJ), #GL_TEXTURE_CUBE_MAP_NEGATIVE_X - (GridJ, np.ones((n,n)), GridI), #GL_TEXTURE_CUBE_MAP_POSITIVE_Y - (GridJ, -1 * np.ones((n,n)), -GridI), #GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - (GridJ, GridI, np.ones((n,n))), #GL_TEXTURE_CUBE_MAP_POSITIVE_Z - (GridJ, -GridI, -1 * np.ones((n,n)))] #GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - -res = [] -for (Xd, Yd, Zd) in FaceGrid: - res.append(computeYmlOnGrid(Xd, Yd, Zd)) - - # From http://www.rorydriscoll.com/2012/01/15/cubemap-texel-solid-angle/ def areaToPoint(x, y): return np.arctan2(x * y, np.sqrt(x * x + y * y + 1)) @@ -60,8 +47,44 @@ def getSolidAngleGrid(Xgrid, Ygrid): y1 = Ygrid + (1. / step) return areaToPoint(x0,y0) - areaToPoint(x1, y0) - areaToPoint(x0, y1) + areaToPoint(x1, y1) - -print(getSolidAngleGrid(GridI, GridJ)) + +def computeCoefficients(): + "Compute coefficient SH00 to SH22 for monochromatic img" + FaceGrid = [(np.ones((n,n)), -GridI, -GridJ), #GL_TEXTURE_CUBE_MAP_POSITIVE_X + (-1 * np.ones((n,n)), -GridI, GridJ), #GL_TEXTURE_CUBE_MAP_NEGATIVE_X + (GridJ, np.ones((n,n)), GridI), #GL_TEXTURE_CUBE_MAP_POSITIVE_Y + (GridJ, -1 * np.ones((n,n)), -GridI), #GL_TEXTURE_CUBE_MAP_NEGATIVE_Y + (GridJ, GridI, np.ones((n,n))), #GL_TEXTURE_CUBE_MAP_POSITIVE_Z + (GridJ, -GridI, -1 * np.ones((n,n)))] #GL_TEXTURE_CUBE_MAP_NEGATIVE_Z + incomingIrradiance = getSolidAngleGrid(GridI, GridJ) + SH00 = 0 + SH1minus1 = 0 + SH10 = 0 + SH11 = 0 + SH2minus2 = 0 + SH2minus1 = 0 + SH20 = 0 + SH21 = 0 + SH22 = 0 + for (Xgrid, Ygrid, Zgrid) in FaceGrid: + (Y00, Y1minus1, Y10, Y11, Y2minus2, Y2minus1, Y20, Y21, Y22) = computeYmlOnGrid(Xgrid, Ygrid, Zgrid) + SH00 += np.sum(np.sum(Y00 * incomingIrradiance * img)) + SH1minus1 += np.sum(np.sum(Y1minus1 * incomingIrradiance * img)) + SH10 += np.sum(np.sum(Y10 * incomingIrradiance * img)) + SH11 += np.sum(np.sum(Y11 * incomingIrradiance * img)) + SH2minus2 += np.sum(np.sum(Y2minus2 * incomingIrradiance * img)) + SH2minus1 += np.sum(np.sum(Y2minus1 * incomingIrradiance * img)) + SH20 += np.sum(np.sum(Y20 * incomingIrradiance * img)) + SH21 += np.sum(np.sum(Y21 * incomingIrradiance * img)) + SH22 += np.sum(np.sum(Y22 * incomingIrradiance * img)) + return (SH00, SH1minus1, SH10, SH2minus2, SH2minus1, SH20, SH21, SH22) + +print(computeCoefficients()) + +#res = [] +#for (Xd, Yd, Zd) in FaceGrid: +# res.append(computeYmlOnGrid(Xd, Yd, Zd)) + #I = img.open("C:/Users/vljn_000/Documents/GitHub/stk-assets/textures/ants.png") #m = np.array(I) From bdb98d6380e311227f11926bed1b1f508c92898e Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Wed, 22 Oct 2014 00:40:58 +0200 Subject: [PATCH 69/73] remove nested np.sum --- tools/ibl.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tools/ibl.py b/tools/ibl.py index fd3472322..5e15383c7 100644 --- a/tools/ibl.py +++ b/tools/ibl.py @@ -68,15 +68,15 @@ def computeCoefficients(): SH22 = 0 for (Xgrid, Ygrid, Zgrid) in FaceGrid: (Y00, Y1minus1, Y10, Y11, Y2minus2, Y2minus1, Y20, Y21, Y22) = computeYmlOnGrid(Xgrid, Ygrid, Zgrid) - SH00 += np.sum(np.sum(Y00 * incomingIrradiance * img)) - SH1minus1 += np.sum(np.sum(Y1minus1 * incomingIrradiance * img)) - SH10 += np.sum(np.sum(Y10 * incomingIrradiance * img)) - SH11 += np.sum(np.sum(Y11 * incomingIrradiance * img)) - SH2minus2 += np.sum(np.sum(Y2minus2 * incomingIrradiance * img)) - SH2minus1 += np.sum(np.sum(Y2minus1 * incomingIrradiance * img)) - SH20 += np.sum(np.sum(Y20 * incomingIrradiance * img)) - SH21 += np.sum(np.sum(Y21 * incomingIrradiance * img)) - SH22 += np.sum(np.sum(Y22 * incomingIrradiance * img)) + SH00 += np.sum(Y00 * incomingIrradiance * img) + SH1minus1 += np.sum(Y1minus1 * incomingIrradiance * img) + SH10 += np.sum(Y10 * incomingIrradiance * img) + SH11 += np.sum(Y11 * incomingIrradiance * img) + SH2minus2 += np.sum(Y2minus2 * incomingIrradiance * img) + SH2minus1 += np.sum(Y2minus1 * incomingIrradiance * img) + SH20 += np.sum(Y20 * incomingIrradiance * img) + SH21 += np.sum(Y21 * incomingIrradiance * img) + SH22 += np.sum(Y22 * incomingIrradiance * img) return (SH00, SH1minus1, SH10, SH2minus2, SH2minus1, SH20, SH21, SH22) print(computeCoefficients()) From 86b80369263bff2d8588377a8c819a034ab48e8b Mon Sep 17 00:00:00 2001 From: hiker Date: Wed, 22 Oct 2014 17:16:39 +1100 Subject: [PATCH 70/73] Fix #1631 (SFX can not be enabled in in-race game menu). --- src/audio/sfx_openal.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index 1d676410a..572f296d7 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -239,6 +239,9 @@ void SFXOpenAL::reallySetMasterVolumeNow(float gain) */ void SFXOpenAL::setLoop(bool status) { + // Set the flag (even if sfx are disabled), so that the right settings + // are available on restart. + m_loop = status; if (m_status == SFX_UNKNOWN || !SFXManager::get()->sfxAllowed()) return; SFXManager::get()->queue(SFXManager::SFX_LOOP, this, status ? 1.0f : 0.0f); } // setLoop @@ -254,7 +257,6 @@ void SFXOpenAL::reallySetLoop(bool status) if(m_status==SFX_UNKNOWN) return; } - m_loop = status; alSourcei(m_sound_source, AL_LOOPING, status ? AL_TRUE : AL_FALSE); SFXManager::checkError("looping"); From 9ca4d7e3e694b73162678062ffe3c6536420dd19 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Wed, 22 Oct 2014 14:49:06 +0200 Subject: [PATCH 71/73] Improve ibl specular reflexion using mipmap chain --- data/shaders/diffuseenvmap.frag | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/data/shaders/diffuseenvmap.frag b/data/shaders/diffuseenvmap.frag index 2ded6b2b0..4a5087f18 100644 --- a/data/shaders/diffuseenvmap.frag +++ b/data/shaders/diffuseenvmap.frag @@ -50,7 +50,9 @@ void main(void) sampleDirection = (InverseViewMatrix * vec4(sampleDirection, 0.)).xyz; float specval = texture(ntex, uv).z; - float lodval = 16 * (1. - ((log2(specval) - 1.) / 10.)); + // From http://graphics.cs.williams.edu/papers/EnvMipReport2013/ + int texSize = textureSize(tex, 0).x; + float lodval = log2(texSize * sqrt(3)) - .5 * log2(specval + 1); vec4 specular = textureLod(tex, sampleDirection, lodval); Spec = max(specular, vec4(0.)); } From d0b996ab4af37eed95b7c5fca27ef1585715cd76 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 19 Oct 2014 00:25:56 +0200 Subject: [PATCH 72/73] Use template defined SetTexture argument sets instead of vector --- src/graphics/2dutils.cpp | 10 +- src/graphics/gpuparticles.cpp | 4 +- src/graphics/post_processing.cpp | 58 ++-- src/graphics/render_geometry.cpp | 469 ++++++++++++++++++------------ src/graphics/render_lighting.cpp | 6 +- src/graphics/render_skybox.cpp | 2 +- src/graphics/shaders_util.hpp | 119 +++++--- src/graphics/stkbillboard.cpp | 2 +- src/graphics/stkmeshscenenode.cpp | 22 +- src/utils/tuple.hpp | 2 +- 10 files changed, 417 insertions(+), 277 deletions(-) diff --git a/src/graphics/2dutils.cpp b/src/graphics/2dutils.cpp index 0136d003e..b13bc00e3 100644 --- a/src/graphics/2dutils.cpp +++ b/src/graphics/2dutils.cpp @@ -21,7 +21,7 @@ static void drawTexColoredQuad(const video::ITexture *texture, const video::SCol glUseProgram(UIShader::ColoredTextureRectShader::getInstance()->Program); glBindVertexArray(UIShader::ColoredTextureRectShader::getInstance()->vao); - UIShader::ColoredTextureRectShader::getInstance()->SetTextureUnits(createVector(static_cast(texture)->getOpenGLTextureName())); + UIShader::ColoredTextureRectShader::getInstance()->SetTextureUnits(static_cast(texture)->getOpenGLTextureName()); UIShader::ColoredTextureRectShader::getInstance()->setUniforms( core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), core::vector2df(tex_center_pos_x, tex_center_pos_y), core::vector2df(tex_width, tex_height)); @@ -41,7 +41,7 @@ float tex_width, float tex_height) glUseProgram(UIShader::TextureRectShader::getInstance()->Program); glBindVertexArray(SharedObject::UIVAO); - UIShader::TextureRectShader::getInstance()->SetTextureUnits(createVector(texture)); + UIShader::TextureRectShader::getInstance()->SetTextureUnits(texture); UIShader::TextureRectShader::getInstance()->setUniforms( core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), core::vector2df(tex_center_pos_x, tex_center_pos_y), @@ -144,7 +144,7 @@ void draw2DImage(const video::ITexture* texture, const core::rect& destRect glUseProgram(UIShader::UniformColoredTextureRectShader::getInstance()->Program); glBindVertexArray(SharedObject::UIVAO); - UIShader::UniformColoredTextureRectShader::getInstance()->SetTextureUnits(createVector(static_cast(texture)->getOpenGLTextureName())); + UIShader::UniformColoredTextureRectShader::getInstance()->SetTextureUnits(static_cast(texture)->getOpenGLTextureName()); UIShader::UniformColoredTextureRectShader::getInstance()->setUniforms( core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), core::vector2df(tex_center_pos_x, tex_center_pos_y), core::vector2df(tex_width, tex_height), colors); @@ -180,7 +180,7 @@ void draw2DImageFromRTT(GLuint texture, size_t texture_w, size_t texture_h, glUseProgram(UIShader::UniformColoredTextureRectShader::getInstance()->Program); glBindVertexArray(SharedObject::UIVAO); - UIShader::UniformColoredTextureRectShader::getInstance()->SetTextureUnits(createVector(texture)); + UIShader::UniformColoredTextureRectShader::getInstance()->SetTextureUnits(texture); UIShader::UniformColoredTextureRectShader::getInstance()->setUniforms( core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), core::vector2df(tex_center_pos_x, tex_center_pos_y), core::vector2df(tex_width, tex_height), @@ -268,7 +268,7 @@ void draw2DVertexPrimitiveList(video::ITexture *tex, const void* vertices, UIShader::Primitive2DList::getInstance()->setUniforms(); const video::SOverrideMaterial &m = irr_driver->getVideoDriver()->getOverrideMaterial(); compressTexture(tex, false); - UIShader::Primitive2DList::getInstance()->SetTextureUnits({ getTextureGLuint(tex) }); + UIShader::Primitive2DList::getInstance()->SetTextureUnits(getTextureGLuint(tex)); glDrawElements(GL_TRIANGLE_FAN, primitiveCount, GL_UNSIGNED_SHORT, 0); glDeleteVertexArrays(1, &tmpvao); diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 89ccfdc72..0120e4f6b 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -350,7 +350,7 @@ void ParticleSystemProxy::drawFlip() glBlendFunc(GL_ONE, GL_ONE); glUseProgram(ParticleShader::FlipParticleRender::getInstance()->Program); - ParticleShader::FlipParticleRender::getInstance()->SetTextureUnits(std::vector{ texture, irr_driver->getDepthStencilTexture() }); + ParticleShader::FlipParticleRender::getInstance()->SetTextureUnits(texture, irr_driver->getDepthStencilTexture()); ParticleShader::FlipParticleRender::getInstance()->setUniforms(); glBindVertexArray(current_rendering_vao); @@ -365,7 +365,7 @@ void ParticleSystemProxy::drawNotFlip() glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glUseProgram(ParticleShader::SimpleParticleRender::getInstance()->Program); - ParticleShader::SimpleParticleRender::getInstance()->SetTextureUnits(std::vector{ texture, irr_driver->getDepthStencilTexture() }); + ParticleShader::SimpleParticleRender::getInstance()->SetTextureUnits(texture, irr_driver->getDepthStencilTexture()); video::SColorf ColorFrom = video::SColorf(getColorFrom()[0], getColorFrom()[1], getColorFrom()[2]); video::SColorf ColorTo = video::SColorf(getColorTo()[0], getColorTo()[1], getColorTo()[2]); diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 3ac843d14..7a586b6ce 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -217,7 +217,7 @@ static void DrawFullScreenEffect(Args...args) static void renderBloom(GLuint in) { - FullScreenShader::BloomShader::getInstance()->SetTextureUnits(createVector(in)); + FullScreenShader::BloomShader::getInstance()->SetTextureUnits(in); DrawFullScreenEffect(); } @@ -231,7 +231,7 @@ void PostProcessing::renderEnvMap(const float *bSHCoeff, const float *gSHCoeff, glUseProgram(FullScreenShader::EnvMapShader::getInstance()->Program); glBindVertexArray(SharedObject::FullScreenQuadVAO); - FullScreenShader::EnvMapShader::getInstance()->SetTextureUnits(createVector(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), irr_driver->getDepthStencilTexture(), skybox)); + FullScreenShader::EnvMapShader::getInstance()->SetTextureUnits(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), irr_driver->getDepthStencilTexture(), skybox); core::matrix4 TVM = irr_driver->getViewMatrix().getTransposed(); FullScreenShader::EnvMapShader::getInstance()->setUniforms(TVM, std::vector(bSHCoeff, bSHCoeff + 9), std::vector(gSHCoeff, gSHCoeff + 9), std::vector(rSHCoeff, rSHCoeff + 9)); @@ -264,8 +264,8 @@ void PostProcessing::renderGI(const core::matrix4 &RHMatrix, const core::vector3 core::matrix4 InvRHMatrix; RHMatrix.getInverse(InvRHMatrix); glDisable(GL_DEPTH_TEST); - FullScreenShader::GlobalIlluminationReconstructionShader::getInstance()->SetTextureUnits(createVector( - irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), irr_driver->getDepthStencilTexture(), shr, shg, shb)); + FullScreenShader::GlobalIlluminationReconstructionShader::getInstance()->SetTextureUnits( + irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), irr_driver->getDepthStencilTexture(), shr, shg, shb); DrawFullScreenEffect(RHMatrix, InvRHMatrix, rh_extend); } @@ -278,7 +278,7 @@ void PostProcessing::renderSunlight() glBlendFunc(GL_ONE, GL_ONE); glBlendEquation(GL_FUNC_ADD); - FullScreenShader::SunLightShader::getInstance()->SetTextureUnits(createVector(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), irr_driver->getDepthStencilTexture())); + FullScreenShader::SunLightShader::getInstance()->SetTextureUnits(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), irr_driver->getDepthStencilTexture()); DrawFullScreenEffect(cb->getPosition(), video::SColorf(cb->getRed(), cb->getGreen(), cb->getBlue())); } @@ -291,7 +291,7 @@ void PostProcessing::renderShadowedSunlight(const std::vector &su glBlendFunc(GL_ONE, GL_ONE); glBlendEquation(GL_FUNC_ADD); - FullScreenShader::ShadowedSunLightShader::getInstance()->SetTextureUnits(createVector( irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), irr_driver->getDepthStencilTexture(), depthtex )); + FullScreenShader::ShadowedSunLightShader::getInstance()->SetTextureUnits(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), irr_driver->getDepthStencilTexture(), depthtex); DrawFullScreenEffect(cb->getPosition(), video::SColorf(cb->getRed(), cb->getGreen(), cb->getBlue())); } @@ -303,13 +303,13 @@ void PostProcessing::renderGaussian3Blur(FrameBuffer &in_fbo, FrameBuffer &auxil { auxiliary.Bind(); - FullScreenShader::Gaussian3VBlurShader::getInstance()->SetTextureUnits(createVector(in_fbo.getRTT()[0])); + FullScreenShader::Gaussian3VBlurShader::getInstance()->SetTextureUnits(in_fbo.getRTT()[0]); DrawFullScreenEffect(core::vector2df(inv_width, inv_height)); } { in_fbo.Bind(); - FullScreenShader::Gaussian3HBlurShader::getInstance()->SetTextureUnits(createVector(auxiliary.getRTT()[0])); + FullScreenShader::Gaussian3HBlurShader::getInstance()->SetTextureUnits(auxiliary.getRTT()[0]); DrawFullScreenEffect(core::vector2df(inv_width, inv_height)); } } @@ -321,13 +321,13 @@ void PostProcessing::renderGaussian6Blur(FrameBuffer &in_fbo, FrameBuffer &auxil { auxiliary.Bind(); - FullScreenShader::Gaussian6VBlurShader::getInstance()->SetTextureUnits(createVector(in_fbo.getRTT()[0])); + FullScreenShader::Gaussian6VBlurShader::getInstance()->SetTextureUnits(in_fbo.getRTT()[0]); DrawFullScreenEffect(core::vector2df(inv_width, inv_height)); } { in_fbo.Bind(); - FullScreenShader::Gaussian6HBlurShader::getInstance()->SetTextureUnits(createVector(auxiliary.getRTT()[0])); + FullScreenShader::Gaussian6HBlurShader::getInstance()->SetTextureUnits(auxiliary.getRTT()[0]); DrawFullScreenEffect(core::vector2df(inv_width, inv_height)); } } @@ -342,14 +342,14 @@ void PostProcessing::renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &a if (!irr_driver->hasARBComputeShaders()) { auxiliary.Bind(); - FullScreenShader::Gaussian17TapHShader::getInstance()->SetTextureUnits(createVector(in_fbo.getRTT()[0], irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0])); + FullScreenShader::Gaussian17TapHShader::getInstance()->SetTextureUnits(in_fbo.getRTT()[0], irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0]); DrawFullScreenEffect(core::vector2df(inv_width, inv_height)); } else { glUseProgram(FullScreenShader::ComputeGaussian17TapHShader::getInstance()->Program); glBindSampler(FullScreenShader::ComputeGaussian17TapHShader::getInstance()->TU_dest, 0); - FullScreenShader::ComputeGaussian17TapHShader::getInstance()->SetTextureUnits({ in_fbo.getRTT()[0], irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0] }); + FullScreenShader::ComputeGaussian17TapHShader::getInstance()->SetTextureUnits(in_fbo.getRTT()[0], irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0]); glBindImageTexture(FullScreenShader::ComputeGaussian17TapHShader::getInstance()->TU_dest, auxiliary.getRTT()[0], 0, false, 0, GL_WRITE_ONLY, GL_R16F); FullScreenShader::ComputeGaussian17TapHShader::getInstance()->setUniforms(core::vector2df(inv_width, inv_height)); glDispatchCompute((int)in_fbo.getWidth() / 8 + 1, (int)in_fbo.getHeight() / 8 + 1, 1); @@ -362,14 +362,14 @@ void PostProcessing::renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &a { in_fbo.Bind(); - FullScreenShader::Gaussian17TapVShader::getInstance()->SetTextureUnits(createVector(auxiliary.getRTT()[0], irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0])); + FullScreenShader::Gaussian17TapVShader::getInstance()->SetTextureUnits(auxiliary.getRTT()[0], irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0]); DrawFullScreenEffect(core::vector2df(inv_width, inv_height)); } else { glUseProgram(FullScreenShader::ComputeGaussian17TapVShader::getInstance()->Program); glBindSampler(FullScreenShader::ComputeGaussian17TapVShader::getInstance()->TU_dest, 0); - FullScreenShader::ComputeGaussian17TapVShader::getInstance()->SetTextureUnits({ auxiliary.getRTT()[0], irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0] }); + FullScreenShader::ComputeGaussian17TapVShader::getInstance()->SetTextureUnits(auxiliary.getRTT()[0], irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0]); glBindImageTexture(FullScreenShader::ComputeGaussian17TapVShader::getInstance()->TU_dest, in_fbo.getRTT()[0], 0, false, 0, GL_WRITE_ONLY, GL_R16F); FullScreenShader::ComputeGaussian17TapVShader::getInstance()->setUniforms(core::vector2df(inv_width, inv_height)); glDispatchCompute((int)in_fbo.getWidth() / 8 + 1, (int)in_fbo.getHeight() / 8 + 1, 1); @@ -384,7 +384,7 @@ void PostProcessing::renderPassThrough(GLuint tex) glUseProgram(FullScreenShader::PassThroughShader::getInstance()->Program); glBindVertexArray(FullScreenShader::PassThroughShader::getInstance()->vao); - FullScreenShader::PassThroughShader::getInstance()->SetTextureUnits(createVector(tex)); + FullScreenShader::PassThroughShader::getInstance()->SetTextureUnits(tex); FullScreenShader::PassThroughShader::getInstance()->setUniforms(); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); @@ -409,7 +409,7 @@ void PostProcessing::renderGlow(unsigned tex) glUseProgram(FullScreenShader::GlowShader::getInstance()->Program); glBindVertexArray(FullScreenShader::GlowShader::getInstance()->vao); - FullScreenShader::GlowShader::getInstance()->SetTextureUnits(createVector(tex)); + FullScreenShader::GlowShader::getInstance()->SetTextureUnits(tex); FullScreenShader::GlowShader::getInstance()->setUniforms(); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); @@ -422,11 +422,11 @@ void PostProcessing::renderSSAO() // Generate linear depth buffer irr_driver->getFBO(FBO_LINEAR_DEPTH).Bind(); - FullScreenShader::LinearizeDepthShader::getInstance()->SetTextureUnits(createVector(irr_driver->getDepthStencilTexture())); + FullScreenShader::LinearizeDepthShader::getInstance()->SetTextureUnits(irr_driver->getDepthStencilTexture()); DrawFullScreenEffect(irr_driver->getSceneManager()->getActiveCamera()->getNearValue(), irr_driver->getSceneManager()->getActiveCamera()->getFarValue()); irr_driver->getFBO(FBO_SSAO).Bind(); - FullScreenShader::SSAOShader::getInstance()->SetTextureUnits(createVector(irr_driver->getRenderTargetTexture(RTT_LINEAR_DEPTH))); + FullScreenShader::SSAOShader::getInstance()->SetTextureUnits(irr_driver->getRenderTargetTexture(RTT_LINEAR_DEPTH)); glGenerateMipmap(GL_TEXTURE_2D); DrawFullScreenEffect(irr_driver->getSSAORadius(), irr_driver->getSSAOK(), irr_driver->getSSAOSigma()); @@ -454,7 +454,7 @@ void PostProcessing::renderFog() glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - FullScreenShader::FogShader::getInstance()->SetTextureUnits(createVector(irr_driver->getDepthStencilTexture())); + FullScreenShader::FogShader::getInstance()->SetTextureUnits(irr_driver->getDepthStencilTexture()); DrawFullScreenEffect(fogmax, startH, endH, start, end, col); glEnable(GL_DEPTH_TEST); @@ -487,7 +487,7 @@ void PostProcessing::renderMotionBlur(unsigned cam, FrameBuffer &in_fbo, FrameBu out_fbo.Bind(); glClear(GL_COLOR_BUFFER_BIT); - FullScreenShader::MotionBlurShader::getInstance()->SetTextureUnits(createVector(in_fbo.getRTT()[0], irr_driver->getDepthStencilTexture())); + FullScreenShader::MotionBlurShader::getInstance()->SetTextureUnits(in_fbo.getRTT()[0], irr_driver->getDepthStencilTexture()); DrawFullScreenEffect( // Todo : use a previousPVMatrix per cam, not global irr_driver->getPreviousPVMatrix(), @@ -500,7 +500,7 @@ static void renderGodFade(GLuint tex, const SColor &col) { glUseProgram(FullScreenShader::GodFadeShader::getInstance()->Program); glBindVertexArray(FullScreenShader::GodFadeShader::getInstance()->vao); - FullScreenShader::GodFadeShader::getInstance()->SetTextureUnits(createVector(tex)); + FullScreenShader::GodFadeShader::getInstance()->SetTextureUnits(tex); FullScreenShader::GodFadeShader::getInstance()->setUniforms(col); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); @@ -510,7 +510,7 @@ static void renderGodRay(GLuint tex, const core::vector2df &sunpos) { glUseProgram(FullScreenShader::GodRayShader::getInstance()->Program); glBindVertexArray(FullScreenShader::GodRayShader::getInstance()->vao); - FullScreenShader::GodRayShader::getInstance()->SetTextureUnits(createVector(tex)); + FullScreenShader::GodRayShader::getInstance()->SetTextureUnits(tex); FullScreenShader::GodRayShader::getInstance()->setUniforms(sunpos); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); @@ -519,14 +519,14 @@ static void renderGodRay(GLuint tex, const core::vector2df &sunpos) static void toneMap(FrameBuffer &fbo, GLuint rtt) { fbo.Bind(); - FullScreenShader::ToneMapShader::getInstance()->SetTextureUnits(createVector(rtt)); + FullScreenShader::ToneMapShader::getInstance()->SetTextureUnits(rtt); DrawFullScreenEffect(); } static void renderDoF(FrameBuffer &fbo, GLuint rtt) { fbo.Bind(); - FullScreenShader::DepthOfFieldShader::getInstance()->SetTextureUnits(createVector(rtt, irr_driver->getDepthStencilTexture())); + FullScreenShader::DepthOfFieldShader::getInstance()->SetTextureUnits(rtt, irr_driver->getDepthStencilTexture()); DrawFullScreenEffect(); } @@ -543,7 +543,7 @@ void PostProcessing::applyMLAA() // Pass 1: color edge detection glUseProgram(FullScreenShader::MLAAColorEdgeDetectionSHader::getInstance()->Program); - FullScreenShader::MLAAColorEdgeDetectionSHader::getInstance()->SetTextureUnits(createVector(irr_driver->getRenderTargetTexture(RTT_MLAA_COLORS))); + FullScreenShader::MLAAColorEdgeDetectionSHader::getInstance()->SetTextureUnits(irr_driver->getRenderTargetTexture(RTT_MLAA_COLORS)); FullScreenShader::MLAAColorEdgeDetectionSHader::getInstance()->setUniforms(PIXEL_SIZE); glBindVertexArray(FullScreenShader::MLAAColorEdgeDetectionSHader::getInstance()->vao); @@ -557,7 +557,7 @@ void PostProcessing::applyMLAA() glClear(GL_COLOR_BUFFER_BIT); glUseProgram(FullScreenShader::MLAABlendWeightSHader::getInstance()->Program); - FullScreenShader::MLAABlendWeightSHader::getInstance()->SetTextureUnits(createVector(irr_driver->getRenderTargetTexture(RTT_MLAA_TMP), getTextureGLuint(m_areamap))); + FullScreenShader::MLAABlendWeightSHader::getInstance()->SetTextureUnits(irr_driver->getRenderTargetTexture(RTT_MLAA_TMP), getTextureGLuint(m_areamap)); FullScreenShader::MLAABlendWeightSHader::getInstance()->setUniforms(PIXEL_SIZE); glBindVertexArray(FullScreenShader::MLAABlendWeightSHader::getInstance()->vao); @@ -570,7 +570,7 @@ void PostProcessing::applyMLAA() irr_driver->getFBO(FBO_MLAA_COLORS).Bind(); glUseProgram(FullScreenShader::MLAAGatherSHader::getInstance()->Program); - FullScreenShader::MLAAGatherSHader::getInstance()->SetTextureUnits(createVector(irr_driver->getRenderTargetTexture(RTT_MLAA_BLEND), irr_driver->getRenderTargetTexture(RTT_MLAA_TMP))); + FullScreenShader::MLAAGatherSHader::getInstance()->SetTextureUnits(irr_driver->getRenderTargetTexture(RTT_MLAA_BLEND), irr_driver->getRenderTargetTexture(RTT_MLAA_TMP)); FullScreenShader::MLAAGatherSHader::getInstance()->setUniforms(PIXEL_SIZE); glBindVertexArray(FullScreenShader::MLAAGatherSHader::getInstance()->vao); @@ -704,8 +704,8 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); glBlendEquation(GL_FUNC_ADD); - FullScreenShader::BloomBlendShader::getInstance()->SetTextureUnits(createVector( - irr_driver->getRenderTargetTexture(RTT_BLOOM_128), irr_driver->getRenderTargetTexture(RTT_BLOOM_256), irr_driver->getRenderTargetTexture(RTT_BLOOM_512) )); + FullScreenShader::BloomBlendShader::getInstance()->SetTextureUnits( + irr_driver->getRenderTargetTexture(RTT_BLOOM_128), irr_driver->getRenderTargetTexture(RTT_BLOOM_256), irr_driver->getRenderTargetTexture(RTT_BLOOM_512)); DrawFullScreenEffect(); glDisable(GL_BLEND); diff --git a/src/graphics/render_geometry.cpp b/src/graphics/render_geometry.cpp index 224c0936b..803b24428 100644 --- a/src/graphics/render_geometry.cpp +++ b/src/graphics/render_geometry.cpp @@ -63,140 +63,202 @@ struct DefaultMaterial { typedef MeshShader::InstancedObjectPass1Shader InstancedFirstPassShader; typedef MeshShader::InstancedObjectPass2Shader InstancedSecondPassShader; + typedef MeshShader::InstancedShadowShader InstancedShadowPassShader; + typedef MeshShader::InstancedRSMShader InstancedRSMShader; typedef ListInstancedMatDefault InstancedList; typedef MeshShader::ObjectPass1Shader FirstPassShader; typedef MeshShader::ObjectPass2Shader SecondPassShader; + typedef MeshShader::ShadowShader ShadowPassShader; + typedef MeshShader::RSMShader RSMShader; typedef ListMatDefault List; static const enum video::E_VERTEX_TYPE VertexType = video::EVT_STANDARD; static const enum Material::ShaderType MaterialType = Material::SHADERTYPE_SOLID; static const enum InstanceType Instance = InstanceTypeDualTex; - static const std::vector FirstPassTextures; - static const std::vector SecondPassTextures; + static const STK::Tuple FirstPassTextures; + static const STK::Tuple SecondPassTextures; + static const STK::Tuple<> ShadowTextures; + static const STK::Tuple RSMTextures; }; -const std::vector DefaultMaterial::FirstPassTextures = { 1 }; -const std::vector DefaultMaterial::SecondPassTextures = { 0, 1 }; +const STK::Tuple DefaultMaterial::FirstPassTextures = STK::Tuple(1); +const STK::Tuple DefaultMaterial::SecondPassTextures = STK::Tuple(0, 1); +const STK::Tuple<> DefaultMaterial::ShadowTextures; +const STK::Tuple DefaultMaterial::RSMTextures = STK::Tuple(0); struct AlphaRef { typedef MeshShader::InstancedObjectRefPass1Shader InstancedFirstPassShader; typedef MeshShader::InstancedObjectRefPass2Shader InstancedSecondPassShader; + typedef MeshShader::InstancedRefShadowShader InstancedShadowPassShader; + typedef MeshShader::InstancedRSMShader InstancedRSMShader; typedef ListInstancedMatAlphaRef InstancedList; typedef MeshShader::ObjectRefPass1Shader FirstPassShader; typedef MeshShader::ObjectRefPass2Shader SecondPassShader; + typedef MeshShader::RefShadowShader ShadowPassShader; + typedef MeshShader::RSMShader RSMShader; typedef ListMatAlphaRef List; static const enum video::E_VERTEX_TYPE VertexType = video::EVT_STANDARD; static const enum Material::ShaderType MaterialType = Material::SHADERTYPE_ALPHA_TEST; static const enum InstanceType Instance = InstanceTypeDualTex; - static const std::vector FirstPassTextures; - static const std::vector SecondPassTextures; + static const STK::Tuple FirstPassTextures; + static const STK::Tuple SecondPassTextures; + static const STK::Tuple ShadowTextures; + static const STK::Tuple RSMTextures; }; -const std::vector AlphaRef::FirstPassTextures = { 0, 1 }; -const std::vector AlphaRef::SecondPassTextures = { 0, 1 }; +const STK::Tuple AlphaRef::FirstPassTextures = STK::Tuple(0, 1); +const STK::Tuple AlphaRef::SecondPassTextures = STK::Tuple(0, 1); +const STK::Tuple AlphaRef::ShadowTextures = STK::Tuple(0); +const STK::Tuple AlphaRef::RSMTextures = STK::Tuple(0); struct SphereMap { typedef MeshShader::InstancedObjectPass1Shader InstancedFirstPassShader; typedef MeshShader::InstancedSphereMapShader InstancedSecondPassShader; + typedef MeshShader::InstancedShadowShader InstancedShadowPassShader; + typedef MeshShader::InstancedRSMShader InstancedRSMShader; typedef ListInstancedMatSphereMap InstancedList; typedef MeshShader::ObjectPass1Shader FirstPassShader; typedef MeshShader::SphereMapShader SecondPassShader; + typedef MeshShader::ShadowShader ShadowPassShader; + typedef MeshShader::RSMShader RSMShader; typedef ListMatSphereMap List; static const enum video::E_VERTEX_TYPE VertexType = video::EVT_STANDARD; static const enum Material::ShaderType MaterialType = Material::SHADERTYPE_SPHERE_MAP; static const enum InstanceType Instance = InstanceTypeDualTex; - static const std::vector FirstPassTextures; - static const std::vector SecondPassTextures; + static const STK::Tuple FirstPassTextures; + static const STK::Tuple SecondPassTextures; + static const STK::Tuple<> ShadowTextures; + static const STK::Tuple RSMTextures; }; -const std::vector SphereMap::FirstPassTextures = { 1 }; -const std::vector SphereMap::SecondPassTextures = { 0 }; +const STK::Tuple SphereMap::FirstPassTextures = STK::Tuple(1); +const STK::Tuple SphereMap::SecondPassTextures = STK::Tuple(0); +const STK::Tuple<> SphereMap::ShadowTextures; +const STK::Tuple SphereMap::RSMTextures = STK::Tuple(0); struct UnlitMat { typedef MeshShader::InstancedObjectRefPass1Shader InstancedFirstPassShader; typedef MeshShader::InstancedObjectUnlitShader InstancedSecondPassShader; + typedef MeshShader::InstancedRefShadowShader InstancedShadowPassShader; + typedef MeshShader::InstancedRSMShader InstancedRSMShader; typedef ListInstancedMatUnlit InstancedList; typedef MeshShader::ObjectRefPass1Shader FirstPassShader; typedef MeshShader::ObjectUnlitShader SecondPassShader; + typedef MeshShader::RefShadowShader ShadowPassShader; + typedef MeshShader::RSMShader RSMShader; typedef ListMatUnlit List; static const enum video::E_VERTEX_TYPE VertexType = video::EVT_STANDARD; static const enum Material::ShaderType MaterialType = Material::SHADERTYPE_SOLID_UNLIT; static const enum InstanceType Instance = InstanceTypeDualTex; - static const std::vector FirstPassTextures; - static const std::vector SecondPassTextures; + static const STK::Tuple FirstPassTextures; + static const STK::Tuple SecondPassTextures; + static const STK::Tuple ShadowTextures; + static const STK::Tuple RSMTextures; }; -const std::vector UnlitMat::FirstPassTextures = { 0, 1 }; -const std::vector UnlitMat::SecondPassTextures = { 0 }; +const STK::Tuple UnlitMat::FirstPassTextures = STK::Tuple(0, 1); +const STK::Tuple UnlitMat::SecondPassTextures = STK::Tuple(0); +const STK::Tuple UnlitMat::ShadowTextures = STK::Tuple(0); +const STK::Tuple UnlitMat::RSMTextures = STK::Tuple(0); struct GrassMat { typedef MeshShader::InstancedGrassPass1Shader InstancedFirstPassShader; typedef MeshShader::InstancedGrassPass2Shader InstancedSecondPassShader; + typedef MeshShader::InstancedGrassShadowShader InstancedShadowPassShader; + typedef MeshShader::InstancedRSMShader InstancedRSMShader; typedef ListInstancedMatGrass InstancedList; typedef MeshShader::GrassPass1Shader FirstPassShader; typedef MeshShader::GrassPass2Shader SecondPassShader; + typedef MeshShader::GrassShadowShader ShadowPassShader; + typedef MeshShader::RSMShader RSMShader; typedef ListMatGrass List; static const enum video::E_VERTEX_TYPE VertexType = video::EVT_STANDARD; static const enum Material::ShaderType MaterialType = Material::SHADERTYPE_VEGETATION; static const enum InstanceType Instance = InstanceTypeDualTex; - static const std::vector FirstPassTextures; - static const std::vector SecondPassTextures; + static const STK::Tuple FirstPassTextures; + static const STK::Tuple SecondPassTextures; + static const STK::Tuple ShadowTextures; + static const STK::Tuple RSMTextures; }; -const std::vector GrassMat::FirstPassTextures = { 0, 1 }; -const std::vector GrassMat::SecondPassTextures = { 0, 1 }; +const STK::Tuple GrassMat::FirstPassTextures = STK::Tuple(0, 1); +const STK::Tuple GrassMat::SecondPassTextures = STK::Tuple(0, 1); +const STK::Tuple GrassMat::ShadowTextures = STK::Tuple(0); +const STK::Tuple GrassMat::RSMTextures = STK::Tuple(0); struct NormalMat { typedef MeshShader::InstancedNormalMapShader InstancedFirstPassShader; typedef MeshShader::InstancedObjectPass2Shader InstancedSecondPassShader; + typedef MeshShader::InstancedShadowShader InstancedShadowPassShader; + typedef MeshShader::InstancedRSMShader InstancedRSMShader; typedef ListInstancedMatNormalMap InstancedList; typedef MeshShader::NormalMapShader FirstPassShader; typedef MeshShader::ObjectPass2Shader SecondPassShader; + typedef MeshShader::ShadowShader ShadowPassShader; + typedef MeshShader::RSMShader RSMShader; typedef ListMatNormalMap List; static const enum video::E_VERTEX_TYPE VertexType = video::EVT_TANGENTS; static const enum Material::ShaderType MaterialType = Material::SHADERTYPE_NORMAL_MAP; static const enum InstanceType Instance = InstanceTypeThreeTex; - static const std::vector FirstPassTextures; - static const std::vector SecondPassTextures; + static const STK::Tuple FirstPassTextures; + static const STK::Tuple SecondPassTextures; + static const STK::Tuple<> ShadowTextures; + static const STK::Tuple RSMTextures; }; -const std::vector NormalMat::FirstPassTextures = { 2, 1 }; -const std::vector NormalMat::SecondPassTextures = { 0, 1 }; +const STK::Tuple NormalMat::FirstPassTextures = STK::Tuple(2, 1); +const STK::Tuple NormalMat::SecondPassTextures = STK::Tuple(0, 1); +const STK::Tuple<> NormalMat::ShadowTextures; +const STK::Tuple NormalMat::RSMTextures = STK::Tuple(0); struct DetailMat { typedef MeshShader::InstancedObjectPass1Shader InstancedFirstPassShader; typedef MeshShader::InstancedDetailledObjectPass2Shader InstancedSecondPassShader; + typedef MeshShader::InstancedShadowShader InstancedShadowPassShader; + typedef MeshShader::InstancedRSMShader InstancedRSMShader; typedef ListInstancedMatDetails InstancedList; typedef MeshShader::ObjectPass1Shader FirstPassShader; typedef MeshShader::DetailledObjectPass2Shader SecondPassShader; + typedef MeshShader::ShadowShader ShadowPassShader; + typedef MeshShader::RSMShader RSMShader; typedef ListMatDetails List; static const enum video::E_VERTEX_TYPE VertexType = video::EVT_2TCOORDS; static const enum Material::ShaderType MaterialType = Material::SHADERTYPE_DETAIL_MAP; static const enum InstanceType Instance = InstanceTypeThreeTex; - static const std::vector FirstPassTextures; - static const std::vector SecondPassTextures; + static const STK::Tuple FirstPassTextures; + static const STK::Tuple SecondPassTextures; + static const STK::Tuple<> ShadowTextures; + static const STK::Tuple RSMTextures; }; -const std::vector DetailMat::FirstPassTextures = { 1 }; -const std::vector DetailMat::SecondPassTextures = { 0, 2, 1 }; +const STK::Tuple DetailMat::FirstPassTextures = STK::Tuple(1); +const STK::Tuple DetailMat::SecondPassTextures = STK::Tuple(0, 2, 1); +const STK::Tuple<> DetailMat::ShadowTextures; +const STK::Tuple DetailMat::RSMTextures = STK::Tuple(0); struct SplattingMat { typedef MeshShader::ObjectPass1Shader FirstPassShader; typedef MeshShader::SplattingShader SecondPassShader; + typedef MeshShader::ShadowShader ShadowPassShader; + typedef MeshShader::SplattingRSMShader RSMShader; typedef ListMatSplatting List; static const enum video::E_VERTEX_TYPE VertexType = video::EVT_2TCOORDS; - static const std::vector FirstPassTextures; - static const std::vector SecondPassTextures; + static const STK::Tuple FirstPassTextures; + static const STK::Tuple SecondPassTextures; + static const STK::Tuple<> ShadowTextures; + static const STK::Tuple RSMTextures; }; -const std::vector SplattingMat::FirstPassTextures = { 6 }; -const std::vector SplattingMat::SecondPassTextures = { 1, 2, 3, 4, 5 }; +const STK::Tuple SplattingMat::FirstPassTextures = STK::Tuple(6); +const STK::Tuple SplattingMat::SecondPassTextures = STK::Tuple(1, 2, 3, 4, 5); +const STK::Tuple<> SplattingMat::ShadowTextures; +const STK::Tuple SplattingMat::RSMTextures = STK::Tuple(1, 2, 3, 4, 5); namespace RenderGeometry { @@ -280,11 +342,72 @@ struct custom_unroll_args } }; +template +struct TexExpander_impl +{ + template + static void ExpandTex(GLMesh &mesh, const STK::Tuple &TexSwizzle, Args... args) + { + size_t idx = STK::tuple_get(TexSwizzle); + TexExpander_impl::template ExpandTex(mesh, TexSwizzle, args..., getTextureGLuint(mesh.textures[idx])); + } +}; + +template +struct TexExpander_impl +{ + template + static void ExpandTex(GLMesh &mesh, const STK::Tuple &TexSwizzle, Args... args) + { + T::getInstance()->SetTextureUnits(args...); + } +}; + +template +struct TexExpander +{ + template + static void ExpandTex(GLMesh &mesh, const STK::Tuple &TexSwizzle, Args... args) + { + TexExpander_impl::ExpandTex(mesh, TexSwizzle, args...); + } +}; + + +template +struct HandleExpander_impl +{ + template + static void Expand(uint64_t *TextureHandles, const STK::Tuple &TexSwizzle, Args... args) + { + size_t idx = STK::tuple_get(TexSwizzle); + HandleExpander_impl::template Expand(TextureHandles, TexSwizzle, args..., TextureHandles[idx]); + } +}; + +template +struct HandleExpander_impl +{ + template + static void Expand(uint64_t *TextureHandles, const STK::Tuple &TexSwizzle, Args... args) + { + T::getInstance()->SetTextureHandles(args...); + } +}; + +template +struct HandleExpander +{ + template + static void Expand(uint64_t *TextureHandles, const STK::Tuple &TexSwizzle, Args... args) + { + HandleExpander_impl::Expand(TextureHandles, TexSwizzle, args...); + } +}; template void renderMeshes1stPass() { - const std::vector &TexUnits = T::FirstPassTextures; auto &meshes = T::List::getInstance()->SolidPass; glUseProgram(T::FirstPassShader::getInstance()->Program); if (irr_driver->hasARB_base_instance()) @@ -296,13 +419,6 @@ void renderMeshes1stPass() GLMesh &mesh = *(STK::tuple_get<0>(meshes.at(i))); if (!irr_driver->hasARB_base_instance()) glBindVertexArray(mesh.vao); - for (unsigned j = 0; j < TexUnits.size(); j++) - { - if (UserConfigParams::m_azdo) - Handles.push_back(mesh.TextureHandles[TexUnits[j]]); - else - Textures.push_back(getTextureGLuint(mesh.textures[TexUnits[j]])); - } if (mesh.VAOType != T::VertexType) { #ifdef DEBUG @@ -312,9 +428,9 @@ void renderMeshes1stPass() } if (UserConfigParams::m_azdo) - T::FirstPassShader::getInstance()->SetTextureHandles(Handles); + HandleExpander::template Expand(mesh.TextureHandles, T::FirstPassTextures); else - T::FirstPassShader::getInstance()->SetTextureUnits(Textures); + TexExpander::template ExpandTex(mesh, T::FirstPassTextures); custom_unroll_args::template exec(T::FirstPassShader::getInstance(), meshes.at(i)); } } @@ -322,7 +438,6 @@ void renderMeshes1stPass() template void renderInstancedMeshes1stPass(Args...args) { - const std::vector &TexUnits = T::FirstPassTextures; std::vector &meshes = T::InstancedList::getInstance()->SolidPass; glUseProgram(T::InstancedFirstPassShader::getInstance()->Program); glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType, T::Instance)); @@ -335,9 +450,7 @@ void renderInstancedMeshes1stPass(Args...args) Log::error("RenderGeometry", "Wrong instanced vertex format (hint : %s)", mesh->textures[0]->getName().getPath().c_str()); #endif - for (unsigned j = 0; j < TexUnits.size(); j++) - Textures.push_back(getTextureGLuint(mesh->textures[TexUnits[j]])); - T::InstancedFirstPassShader::getInstance()->SetTextureUnits(Textures); + TexExpander::template ExpandTex(*mesh, T::FirstPassTextures); T::InstancedFirstPassShader::getInstance()->setUniforms(args...); glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)((SolidPassCmd::getInstance()->Offset[T::MaterialType] + i) * sizeof(DrawElementsIndirectCommand))); @@ -412,25 +525,15 @@ template void renderMeshes2ndPass( const std::vector &Prefilled_Handle, const std::vector &Prefilled_Tex) { - const std::vector &TexUnits = T::SecondPassTextures; auto &meshes = T::List::getInstance()->SolidPass; glUseProgram(T::SecondPassShader::getInstance()->Program); if (irr_driver->hasARB_base_instance()) glBindVertexArray(VAOManager::getInstance()->getVAO(T::VertexType)); for (unsigned i = 0; i < meshes.size(); i++) { - std::vector Handles(Prefilled_Handle); - std::vector Textures(Prefilled_Tex); GLMesh &mesh = *(STK::tuple_get<0>(meshes.at(i))); if (!irr_driver->hasARB_base_instance()) glBindVertexArray(mesh.vao); - for (unsigned j = 0; j < TexUnits.size(); j++) - { - if (UserConfigParams::m_azdo) - Handles.push_back(mesh.TextureHandles[TexUnits[j]]); - else - Textures.push_back(getTextureGLuint(mesh.textures[TexUnits[j]])); - } if (mesh.VAOType != T::VertexType) { @@ -441,9 +544,9 @@ void renderMeshes2ndPass( const std::vector &Prefilled_Handle, } if (UserConfigParams::m_azdo) - T::SecondPassShader::getInstance()->SetTextureHandles(Handles); + HandleExpander::template Expand(mesh.TextureHandles, T::SecondPassTextures, Prefilled_Handle[0], Prefilled_Handle[1], Prefilled_Handle[2]); else - T::SecondPassShader::getInstance()->SetTextureUnits(Textures); + TexExpander::template ExpandTex(mesh, T::SecondPassTextures, Prefilled_Tex[0], Prefilled_Tex[1], Prefilled_Tex[2]); custom_unroll_args::template exec(T::SecondPassShader::getInstance(), meshes.at(i)); } } @@ -452,29 +555,27 @@ template void renderInstancedMeshes2ndPass(const std::vector &Prefilled_tex, Args...args) { std::vector &meshes = T::InstancedList::getInstance()->SolidPass; - const std::vector &TexUnits = T::SecondPassTextures; glUseProgram(T::InstancedSecondPassShader::getInstance()->Program); glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType, T::Instance)); for (unsigned i = 0; i < meshes.size(); i++) { GLMesh *mesh = meshes[i]; - std::vector Textures(Prefilled_tex); - for (unsigned j = 0; j < TexUnits.size(); j++) - Textures.push_back(getTextureGLuint(mesh->textures[TexUnits[j]])); - T::InstancedSecondPassShader::getInstance()->SetTextureUnits(Textures); + TexExpander::template ExpandTex(*mesh, T::SecondPassTextures, Prefilled_tex[0], Prefilled_tex[1], Prefilled_tex[2]); T::InstancedSecondPassShader::getInstance()->setUniforms(args...); glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)((SolidPassCmd::getInstance()->Offset[T::MaterialType] + i) * sizeof(DrawElementsIndirectCommand))); } } + template void multidraw2ndPass(const std::vector &Handles, Args... args) { glUseProgram(T::InstancedSecondPassShader::getInstance()->Program); glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType, T::Instance)); + uint64_t nulltex[10] = {}; if (SolidPassCmd::getInstance()->Size[T::MaterialType]) { - T::InstancedSecondPassShader::getInstance()->SetTextureHandles(Handles); + HandleExpander::template Expand(nulltex, T::SecondPassTextures, Handles[0], Handles[1], Handles[2]); T::InstancedSecondPassShader::getInstance()->setUniforms(args...); glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)(SolidPassCmd::getInstance()->Offset[T::MaterialType] * sizeof(DrawElementsIndirectCommand)), @@ -535,11 +636,25 @@ void IrrDriver::renderSolidSecondPass() multidraw2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0, 0)); multidraw2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0)); multidraw2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0)); - SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT); - multidraw2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle, DepthHandle, 0, 0), windDir, cb->getPosition()); - multidraw2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0, 0)); multidraw2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0, 0, 0)); + + // template does not work with template due to extra depth texture + { + SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT); + glUseProgram(GrassMat::InstancedSecondPassShader::getInstance()->Program); + glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(GrassMat::VertexType, GrassMat::Instance)); + uint64_t nulltex[10] = {}; + if (SolidPassCmd::getInstance()->Size[GrassMat::MaterialType]) + { + HandleExpander::Expand(nulltex, GrassMat::SecondPassTextures, DiffuseHandle, SpecularHandle, SSAOHandle, DepthHandle); + GrassMat::InstancedSecondPassShader::getInstance()->setUniforms(windDir, cb->getPosition()); + glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, + (const void*)(SolidPassCmd::getInstance()->Offset[GrassMat::MaterialType] * sizeof(DrawElementsIndirectCommand)), + (int)SolidPassCmd::getInstance()->Size[GrassMat::MaterialType], + (int)sizeof(DrawElementsIndirectCommand)); + } + } } else if (irr_driver->hasARB_draw_indirect()) { @@ -547,12 +662,23 @@ void IrrDriver::renderSolidSecondPass() renderInstancedMeshes2ndPass(DiffSpecSSAOTex); renderInstancedMeshes2ndPass(DiffSpecSSAOTex); renderInstancedMeshes2ndPass(DiffSpecSSAOTex); - SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT); - DiffSpecSSAOTex.push_back(irr_driver->getDepthStencilTexture()); - renderInstancedMeshes2ndPass(DiffSpecSSAOTex, windDir, cb->getPosition()); - DiffSpecSSAOTex.pop_back(); renderInstancedMeshes2ndPass(DiffSpecSSAOTex); renderInstancedMeshes2ndPass(DiffSpecSSAOTex); + + // template does not work with template due to extra depth texture + { + SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT); + std::vector &meshes = GrassMat::InstancedList::getInstance()->SolidPass; + glUseProgram(GrassMat::InstancedSecondPassShader::getInstance()->Program); + glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(GrassMat::VertexType, GrassMat::Instance)); + for (unsigned i = 0; i < meshes.size(); i++) + { + GLMesh *mesh = meshes[i]; + TexExpander::ExpandTex(*mesh, GrassMat::SecondPassTextures, DiffSpecSSAOTex[0], DiffSpecSSAOTex[1], DiffSpecSSAOTex[2], irr_driver->getDepthStencilTexture()); + GrassMat::InstancedSecondPassShader::getInstance()->setUniforms(windDir, cb->getPosition()); + glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)((SolidPassCmd::getInstance()->Offset[GrassMat::MaterialType] + i) * sizeof(DrawElementsIndirectCommand))); + } + } } } } @@ -598,7 +724,6 @@ void renderTransparenPass(const std::vector &TexUnits, std::vectorsize(); i++) { std::vector Handles; - std::vector Textures; GLMesh &mesh = *(STK::tuple_get<0>(meshes->at(i))); if (!irr_driver->hasARB_base_instance()) glBindVertexArray(mesh.vao); @@ -615,8 +740,6 @@ void renderTransparenPass(const std::vector &TexUnits, std::vector &TexUnits, std::vectorSetTextureHandles(Handles); + Shader::getInstance()->SetTextureHandles(Handles[0]); else - Shader::getInstance()->SetTextureUnits(Textures); + Shader::getInstance()->SetTextureUnits(getTextureGLuint(mesh.textures[0])); custom_unroll_args::template exec(Shader::getInstance(), meshes->at(i)); } } @@ -741,10 +864,10 @@ void IrrDriver::renderTransparent() size_t count = mesh.IndexCount; // Render the effect MeshShader::DisplaceShader::getInstance()->SetTextureUnits( - createVector(getTextureGLuint(displaceTex), - irr_driver->getRenderTargetTexture(RTT_COLOR), - irr_driver->getRenderTargetTexture(RTT_TMP1), - getTextureGLuint(mesh.textures[0]))); + getTextureGLuint(displaceTex), + irr_driver->getRenderTargetTexture(RTT_COLOR), + irr_driver->getRenderTargetTexture(RTT_TMP1), + getTextureGLuint(mesh.textures[0])); glUseProgram(MeshShader::DisplaceShader::getInstance()->Program); MeshShader::DisplaceShader::getInstance()->setUniforms(AbsoluteTransformation, core::vector2df(cb->getDirX(), cb->getDirY()), @@ -795,67 +918,55 @@ struct shadow_custom_unroll_args } }; -template -void renderShadow(const std::vector TextureUnits, unsigned cascade, const std::vector > &t) +template +void renderShadow(unsigned cascade) { - glUseProgram(T::getInstance()->Program); + auto &t = T::List::getInstance()->Shadows[cascade]; + glUseProgram(T::ShadowPassShader::getInstance()->Program); if (irr_driver->hasARB_base_instance()) - glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType)); + glBindVertexArray(VAOManager::getInstance()->getVAO(T::VertexType)); for (unsigned i = 0; i < t.size(); i++) { - std::vector Handles; - std::vector Textures; GLMesh *mesh = STK::tuple_get<0>(t.at(i)); if (!irr_driver->hasARB_base_instance()) glBindVertexArray(mesh->vao); - for (unsigned j = 0; j < TextureUnits.size(); j++) - { - compressTexture(mesh->textures[TextureUnits[j]], true); - if (UserConfigParams::m_azdo) - Handles.push_back(mesh->TextureHandles[TextureUnits[j]]); - else - Textures.push_back(getTextureGLuint(mesh->textures[TextureUnits[j]])); - } if (UserConfigParams::m_azdo) - T::getInstance()->SetTextureHandles(Handles); + HandleExpander::template Expand(mesh->TextureHandles, T::ShadowTextures); else - T::getInstance()->SetTextureUnits(Textures); - shadow_custom_unroll_args::template exec(T::getInstance(), cascade, t.at(i)); + TexExpander::template ExpandTex(*mesh, T::ShadowTextures); + shadow_custom_unroll_args::template exec(T::ShadowPassShader::getInstance(), cascade, t.at(i)); } } -template -void renderInstancedShadow(const std::vector TextureUnits, unsigned cascade, const std::vector &t, Args ...args) +template +void renderInstancedShadow(unsigned cascade, Args ...args) { - glUseProgram(Shader::getInstance()->Program); - glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(VT, InstanceTypeShadow)); + glUseProgram(T::InstancedShadowPassShader::getInstance()->Program); + glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType, InstanceTypeShadow)); + std::vector &t = T::InstancedList::getInstance()->Shadows[cascade]; for (unsigned i = 0; i < t.size(); i++) { - std::vector Handles; - std::vector Textures; GLMesh *mesh = t[i]; - for (unsigned j = 0; j < TextureUnits.size(); j++) - Textures.push_back(getTextureGLuint(mesh->textures[TextureUnits[j]])); - - Shader::getInstance()->SetTextureUnits(Textures); - Shader::getInstance()->setUniforms(cascade, args...); - size_t tmp = ShadowPassCmd::getInstance()->Offset[cascade][Mat] + i; + TexExpander::template ExpandTex(*mesh, T::ShadowTextures); + T::InstancedShadowPassShader::getInstance()->setUniforms(cascade, args...); + size_t tmp = ShadowPassCmd::getInstance()->Offset[cascade][T::MaterialType] + i; glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)((tmp) * sizeof(DrawElementsIndirectCommand))); } + } -template +template static void multidrawShadow(unsigned i, Args ...args) { - glUseProgram(Shader::getInstance()->Program); - glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(VT, InstanceTypeShadow)); - if (ShadowPassCmd::getInstance()->Size[i][Mat]) + glUseProgram(T::InstancedShadowPassShader::getInstance()->Program); + glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType, InstanceTypeShadow)); + if (ShadowPassCmd::getInstance()->Size[i][T::MaterialType]) { - Shader::getInstance()->setUniforms(i, args...); + T::InstancedShadowPassShader::getInstance()->setUniforms(i, args...); glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, - (const void*)(ShadowPassCmd::getInstance()->Offset[i][Mat] * sizeof(DrawElementsIndirectCommand)), - (int)ShadowPassCmd::getInstance()->Size[i][Mat], sizeof(DrawElementsIndirectCommand)); + (const void*)(ShadowPassCmd::getInstance()->Offset[i][T::MaterialType] * sizeof(DrawElementsIndirectCommand)), + (int)ShadowPassCmd::getInstance()->Size[i][T::MaterialType], sizeof(DrawElementsIndirectCommand)); } } @@ -875,37 +986,36 @@ void IrrDriver::renderShadows() for (unsigned cascade = 0; cascade < 4; cascade++) { ScopedGPUTimer Timer(getGPUTimer(Q_SHADOWS_CASCADE0 + cascade)); - std::vector noTexUnits; - renderShadow(noTexUnits, cascade, ListMatDefault::getInstance()->Shadows[cascade]); - renderShadow(noTexUnits, cascade, ListMatSphereMap::getInstance()->Shadows[cascade]); - renderShadow(noTexUnits, cascade, ListMatDetails::getInstance()->Shadows[cascade]); - renderShadow(noTexUnits, cascade, ListMatSplatting::getInstance()->Shadows[cascade]); - renderShadow(noTexUnits, cascade, ListMatNormalMap::getInstance()->Shadows[cascade]); - renderShadow(std::vector{ 0 }, cascade, ListMatAlphaRef::getInstance()->Shadows[cascade]); - renderShadow(std::vector{ 0 }, cascade, ListMatUnlit::getInstance()->Shadows[cascade]); - renderShadow(std::vector{ 0 }, cascade, ListMatGrass::getInstance()->Shadows[cascade]); + renderShadow(cascade); + renderShadow(cascade); + renderShadow(cascade); + renderShadow(cascade); + renderShadow(cascade); + renderShadow(cascade); + renderShadow(cascade); + renderShadow(cascade); if (irr_driver->hasARB_draw_indirect()) glBindBuffer(GL_DRAW_INDIRECT_BUFFER, ShadowPassCmd::getInstance()->drawindirectcmd); if (UserConfigParams::m_azdo) { - multidrawShadow(cascade); - multidrawShadow(cascade); - multidrawShadow(cascade); - multidrawShadow(cascade); - multidrawShadow(cascade); - multidrawShadow(cascade, windDir); + multidrawShadow(cascade); + multidrawShadow(cascade); + multidrawShadow(cascade); + multidrawShadow(cascade); + multidrawShadow(cascade); + multidrawShadow(cascade, windDir); } else if (irr_driver->hasARB_draw_indirect()) { - renderInstancedShadow(noTexUnits, cascade, ListInstancedMatDefault::getInstance()->Shadows[cascade]); - renderInstancedShadow(noTexUnits, cascade, ListInstancedMatDetails::getInstance()->Shadows[cascade]); - renderInstancedShadow(std::vector < GLuint > { 0 }, cascade, ListInstancedMatAlphaRef::getInstance()->Shadows[cascade]); - renderInstancedShadow(std::vector < GLuint > { 0 }, cascade, ListInstancedMatUnlit::getInstance()->Shadows[cascade]); - renderInstancedShadow(std::vector < GLuint > { 0 }, cascade, ListInstancedMatGrass::getInstance()->Shadows[cascade], windDir); - renderInstancedShadow(noTexUnits, cascade, ListInstancedMatNormalMap::getInstance()->Shadows[cascade]); + renderInstancedShadow(cascade); + renderInstancedShadow(cascade); + renderInstancedShadow(cascade); + renderInstancedShadow(cascade); + renderInstancedShadow(cascade, windDir); + renderInstancedShadow(cascade); } } @@ -937,56 +1047,55 @@ struct rsm_custom_unroll_args } }; -template -void drawRSM(const core::matrix4 & rsm_matrix, const std::vector &TextureUnits, const std::vector > &t) +template +void drawRSM(const core::matrix4 & rsm_matrix) { - glUseProgram(T::getInstance()->Program); + glUseProgram(T::RSMShader::getInstance()->Program); if (irr_driver->hasARB_base_instance()) - glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType)); + glBindVertexArray(VAOManager::getInstance()->getVAO(T::VertexType)); + auto t = T::List::getInstance()->RSM; for (unsigned i = 0; i < t.size(); i++) { std::vector Textures; GLMesh *mesh = STK::tuple_get<0>(t.at(i)); if (!irr_driver->hasARB_base_instance()) glBindVertexArray(mesh->vao); - for (unsigned j = 0; j < TextureUnits.size(); j++) - Textures.push_back(getTextureGLuint(mesh->textures[TextureUnits[j]])); - T::getInstance()->SetTextureUnits(Textures); - rsm_custom_unroll_args::template exec(rsm_matrix, t.at(i)); + if (UserConfigParams::m_azdo) + HandleExpander::template Expand(mesh->TextureHandles, T::RSMTextures); + else + TexExpander::template ExpandTex(*mesh, T::RSMTextures); + rsm_custom_unroll_args::template exec(rsm_matrix, t.at(i)); } } -template -void renderRSMShadow(const std::vector TextureUnits, const std::vector &t, Args ...args) +template +void renderRSMShadow(Args ...args) { - glUseProgram(Shader::getInstance()->Program); - glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(VT, InstanceTypeRSM)); + glUseProgram(T::InstancedRSMShader::getInstance()->Program); + glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType, InstanceTypeRSM)); + auto t = T::InstancedList::getInstance()->RSM; for (unsigned i = 0; i < t.size(); i++) { - std::vector Handles; std::vector Textures; GLMesh *mesh = t[i]; - for (unsigned j = 0; j < TextureUnits.size(); j++) - Textures.push_back(getTextureGLuint(mesh->textures[TextureUnits[j]])); - - Shader::getInstance()->SetTextureUnits(Textures); - Shader::getInstance()->setUniforms(args...); - glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)((RSMPassCmd::getInstance()->Offset[Mat] + i)* sizeof(DrawElementsIndirectCommand))); + TexExpander::template ExpandTex(*mesh, T::RSMTextures); + T::InstancedRSMShader::getInstance()->setUniforms(args...); + glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)((RSMPassCmd::getInstance()->Offset[T::MaterialType] + i)* sizeof(DrawElementsIndirectCommand))); } } -template +template void multidrawRSM(Args...args) { - glUseProgram(Shader::getInstance()->Program); - glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(VertexType, InstanceTypeRSM)); - if (RSMPassCmd::getInstance()->Size[Mat]) + glUseProgram(T::InstancedRSMShader::getInstance()->Program); + glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType, InstanceTypeRSM)); + if (RSMPassCmd::getInstance()->Size[T::MaterialType]) { - Shader::getInstance()->setUniforms(args...); - glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, - (const void*)(RSMPassCmd::getInstance()->Offset[Mat] * sizeof(DrawElementsIndirectCommand)), - (int)RSMPassCmd::getInstance()->Size[Mat], sizeof(DrawElementsIndirectCommand)); + T::InstancedRSMShader::getInstance()->setUniforms(args...); + glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, + (const void*)(RSMPassCmd::getInstance()->Offset[T::MaterialType] * sizeof(DrawElementsIndirectCommand)), + (int)RSMPassCmd::getInstance()->Size[T::MaterialType], sizeof(DrawElementsIndirectCommand)); } } @@ -996,30 +1105,30 @@ void IrrDriver::renderRSM() m_rtts->getRSM().Bind(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - drawRSM(rsm_matrix, std::vector{ 0 }, ListMatDefault::getInstance()->RSM); - drawRSM(rsm_matrix, std::vector{ 0 }, ListMatAlphaRef::getInstance()->RSM); - drawRSM(rsm_matrix, std::vector{ 0 }, ListMatNormalMap::getInstance()->RSM); - drawRSM(rsm_matrix, std::vector{ 0 }, ListMatUnlit::getInstance()->RSM); - drawRSM(rsm_matrix, std::vector{ 0 }, ListMatDetails::getInstance()->RSM); - drawRSM(rsm_matrix, createVector(1, 2, 3, 4, 5), ListMatSplatting::getInstance()->RSM); + drawRSM(rsm_matrix); + drawRSM(rsm_matrix); + drawRSM(rsm_matrix); + drawRSM(rsm_matrix); + drawRSM(rsm_matrix); + drawRSM(rsm_matrix); if (irr_driver->hasARB_draw_indirect()) glBindBuffer(GL_DRAW_INDIRECT_BUFFER, RSMPassCmd::getInstance()->drawindirectcmd); if (UserConfigParams::m_azdo) { - multidrawRSM(rsm_matrix); - multidrawRSM(rsm_matrix); - multidrawRSM(rsm_matrix); - multidrawRSM(rsm_matrix); - multidrawRSM(rsm_matrix); + multidrawRSM(rsm_matrix); + multidrawRSM(rsm_matrix); + multidrawRSM(rsm_matrix); + multidrawRSM(rsm_matrix); + multidrawRSM(rsm_matrix); } else if (irr_driver->hasARB_draw_indirect()) { - renderRSMShadow(std::vector < GLuint > { 0 }, ListInstancedMatDefault::getInstance()->RSM, rsm_matrix); - renderRSMShadow(std::vector < GLuint > { 0 }, ListInstancedMatAlphaRef::getInstance()->RSM, rsm_matrix); - renderRSMShadow(std::vector < GLuint > { 0 }, ListInstancedMatUnlit::getInstance()->RSM, rsm_matrix); - renderRSMShadow(std::vector < GLuint > { 0 }, ListInstancedMatNormalMap::getInstance()->RSM, rsm_matrix); - renderRSMShadow(std::vector < GLuint > { 0 }, ListInstancedMatDetails::getInstance()->RSM, rsm_matrix); + renderRSMShadow(rsm_matrix); + renderRSMShadow(rsm_matrix); + renderRSMShadow(rsm_matrix); + renderRSMShadow(rsm_matrix); + renderRSMShadow(rsm_matrix); } } diff --git a/src/graphics/render_lighting.cpp b/src/graphics/render_lighting.cpp index aa49be335..24712f6b0 100644 --- a/src/graphics/render_lighting.cpp +++ b/src/graphics/render_lighting.cpp @@ -29,7 +29,7 @@ static void renderPointLights(unsigned count) glBindBuffer(GL_ARRAY_BUFFER, LightShader::PointLightShader::getInstance()->vbo); glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(LightShader::PointLightInfo), PointLightsInfo); - LightShader::PointLightShader::getInstance()->SetTextureUnits(createVector(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), irr_driver->getDepthStencilTexture())); + LightShader::PointLightShader::getInstance()->SetTextureUnits(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), irr_driver->getDepthStencilTexture()); LightShader::PointLightShader::getInstance()->setUniforms(); glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count); @@ -120,7 +120,7 @@ void IrrDriver::renderLights(unsigned pointlightcount, bool hasShadow) { glUseProgram(FullScreenShader::NVWorkaroundRadianceHintsConstructionShader::getInstance()->Program); FullScreenShader::NVWorkaroundRadianceHintsConstructionShader::getInstance()->SetTextureUnits( - createVector(m_rtts->getRSM().getRTT()[0], m_rtts->getRSM().getRTT()[1], m_rtts->getRSM().getDepthTexture())); + m_rtts->getRSM().getRTT()[0], m_rtts->getRSM().getRTT()[1], m_rtts->getRSM().getDepthTexture()); for (unsigned i = 0; i < 32; i++) { FullScreenShader::NVWorkaroundRadianceHintsConstructionShader::getInstance()->setUniforms(rsm_matrix, rh_matrix, rh_extend, i, video::SColorf(cb->getRed(), cb->getGreen(), cb->getBlue())); @@ -131,11 +131,9 @@ void IrrDriver::renderLights(unsigned pointlightcount, bool hasShadow) { glUseProgram(FullScreenShader::RadianceHintsConstructionShader::getInstance()->Program); FullScreenShader::RadianceHintsConstructionShader::getInstance()->SetTextureUnits( - createVector( m_rtts->getRSM().getRTT()[0], m_rtts->getRSM().getRTT()[1], m_rtts->getRSM().getDepthTexture() - ) ); FullScreenShader::RadianceHintsConstructionShader::getInstance()->setUniforms(rsm_matrix, rh_matrix, rh_extend, video::SColorf(cb->getRed(), cb->getGreen(), cb->getBlue())); glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 32); diff --git a/src/graphics/render_skybox.cpp b/src/graphics/render_skybox.cpp index 24bffde0c..0016016f2 100644 --- a/src/graphics/render_skybox.cpp +++ b/src/graphics/render_skybox.cpp @@ -541,7 +541,7 @@ void IrrDriver::renderSkybox(const scene::ICameraSceneNode *camera) glUseProgram(MeshShader::SkyboxShader::getInstance()->Program); MeshShader::SkyboxShader::getInstance()->setUniforms(transform); - MeshShader::SkyboxShader::getInstance()->SetTextureUnits(createVector(SkyboxCubeMap)); + MeshShader::SkyboxShader::getInstance()->SetTextureUnits(SkyboxCubeMap); glDrawElements(GL_TRIANGLES, 6 * 6, GL_UNSIGNED_INT, 0); glBindVertexArray(0); diff --git a/src/graphics/shaders_util.hpp b/src/graphics/shaders_util.hpp index 497491d55..e917125fc 100644 --- a/src/graphics/shaders_util.hpp +++ b/src/graphics/shaders_util.hpp @@ -238,7 +238,8 @@ struct CreateSamplers<> template<> struct BindTexture<> { - static void exec(const std::vector &TU, const std::vector &TexId, unsigned N) + template + static void exec(const std::vector &TU) {} }; @@ -260,10 +261,11 @@ void BindTextureNearest(unsigned TU, unsigned tid); template struct BindTexture { - static void exec(const std::vector &TU, const std::vector &TexId, unsigned N) + template + static void exec(const std::vector &TU, GLuint TexId, Args... args) { - BindTextureNearest(TU[N], TexId[N]); - BindTexture::exec(TU, TexId, N + 1); + BindTextureNearest(TU[N], TexId); + BindTexture::template exec(TU, args...); } }; @@ -289,16 +291,17 @@ struct CreateSamplers template struct BindTexture { - static void exec(const std::vector &TU, const std::vector &TexId, unsigned N) + template + static void exec(const std::vector &TU, GLuint TexId, Args... args) { glActiveTexture(GL_TEXTURE0 + TU[N]); - glBindTexture(GL_TEXTURE_2D, TexId[N]); + glBindTexture(GL_TEXTURE_2D, TexId); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.); - BindTexture::exec(TU, TexId, N + 1); + BindTexture::template exec(TU, args...); } }; @@ -320,10 +323,11 @@ void BindTextureBilinear(unsigned TU, unsigned tex); template struct BindTexture { - static void exec(const std::vector &TU, const std::vector &TexId, unsigned N) + template + static void exec(const std::vector &TU, GLuint TexId, Args... args) { - BindTextureBilinear(TU[N], TexId[N]); - BindTexture::exec(TU, TexId, N + 1); + BindTextureBilinear(TU[N], TexId); + BindTexture::template exec(TU, args...); } }; @@ -345,10 +349,11 @@ void BindTextureBilinearClamped(unsigned TU, unsigned tex); template struct BindTexture { - static void exec(const std::vector &TU, const std::vector &TexId, unsigned N) + template + static void exec(const std::vector &TU, GLuint TexId, Args... args) { - BindTextureBilinearClamped(TU[N], TexId[N]); - BindTexture::exec(TU, TexId, N + 1); + BindTextureBilinearClamped(TU[N], TexId); + BindTexture::template exec(TU, args...); } }; @@ -370,10 +375,11 @@ void BindTextureSemiTrilinear(unsigned TU, unsigned tex); template struct BindTexture { - static void exec(const std::vector &TU, const std::vector &TexId, unsigned N) + template + static void exec(const std::vector &TU, GLuint TexId, Args... args) { - BindTextureSemiTrilinear(TU[N], TexId[N]); - BindTexture::exec(TU, TexId, N + 1); + BindTextureSemiTrilinear(TU[N], TexId); + BindTexture::template exec(TU, args...); } }; @@ -408,20 +414,22 @@ void BindCubemapTrilinear(unsigned TU, unsigned tex); template struct BindTexture { - static void exec(const std::vector &TU, const std::vector &TexId, unsigned N) + template + static void exec(const std::vector &TU, GLuint TexId, Args... args) { - BindCubemapTrilinear(TU[N], TexId[N]); - BindTexture::exec(TU, TexId, N + 1); + BindCubemapTrilinear(TU[N], TexId); + BindTexture::template exec(TU, args...); } }; template struct BindTexture { - static void exec(const std::vector &TU, const std::vector &TexId, unsigned N) + template + static void exec(const std::vector &TU, GLuint TexId, Args... args) { - BindTextureTrilinearAnisotropic(TU[N], TexId[N]); - BindTexture::exec(TU, TexId, N + 1); + BindTextureTrilinearAnisotropic(TU[N], TexId); + BindTexture::template exec(TU, args...); } }; @@ -441,10 +449,11 @@ void BindTextureVolume(unsigned TU, unsigned tex); template struct BindTexture { - static void exec(const std::vector &TU, const std::vector &TexId, unsigned N) + template + static void exec(const std::vector &TU, GLuint TexId, Args... args) { - BindTextureVolume(TU[N], TexId[N]); - BindTexture::exec(TU, TexId, N + 1); + BindTextureVolume(TU[N], TexId); + BindTexture::template exec(TU, args...); } }; @@ -466,10 +475,11 @@ void BindTextureShadow(unsigned TU, unsigned tex); template struct BindTexture { - static void exec(const std::vector &TU, const std::vector &TexId, unsigned N) + template + static void exec(const std::vector &TU, GLuint TexId, Args... args) { - BindTextureShadow(TU[N], TexId[N]); - BindTexture::exec(TU, TexId, N + 1); + BindTextureShadow(TU[N], TexId); + BindTexture::template exec(TU, args...); } }; @@ -507,21 +517,44 @@ protected: glUseProgram(0); } + template + void SetTextureUnits_impl() + { + static_assert(N == sizeof...(tp), "Not enough texture set"); + } + + template + void SetTextureUnits_impl(GLuint texid, TexIds... args) + { + setTextureSampler(TextureType[N], TextureUnits[N], texid, SamplersId[N]); + SetTextureUnits_impl(args...); + } + + + template + void SetTextureHandles_impl() + { + static_assert(N == sizeof...(tp), "Not enough handle set"); + } + + template + void SetTextureHandles_impl(uint64_t handle, HandlesId... args) + { + if (handle) + glUniformHandleui64ARB(TextureLocation[N], handle); + SetTextureHandles_impl(args...); + } + public: std::vector SamplersId; - void SetTextureUnits(const std::vector &args) + + template + void SetTextureUnits(TexIds... args) { - if (args.size() != sizeof...(tp)) - abort(); if (getGLSLVersion() >= 330) - { - for (unsigned i = 0; i < args.size(); i++) - { - setTextureSampler(TextureType[i], TextureUnits[i], args[i], SamplersId[i]); - } - } + SetTextureUnits_impl<0>(args...); else - BindTexture::exec(TextureUnits, args, 0); + BindTexture::template exec<0>(TextureUnits, args...); } ~TextureRead() @@ -530,14 +563,10 @@ public: glDeleteSamplers(1, &SamplersId[i]); } - void SetTextureHandles(const std::vector &args) + template + void SetTextureHandles(HandlesId... ids) { - assert(args.size() == TextureLocation.size() && "Wrong Handle count"); - for (unsigned i = 0; i < args.size(); i++) - { - if (args[i]) - glUniformHandleui64ARB(TextureLocation[i], args[i]); - } + SetTextureHandles_impl<0>(ids...); } }; #endif \ No newline at end of file diff --git a/src/graphics/stkbillboard.cpp b/src/graphics/stkbillboard.cpp index 913727ec1..1753acd94 100644 --- a/src/graphics/stkbillboard.cpp +++ b/src/graphics/stkbillboard.cpp @@ -52,7 +52,7 @@ void STKBillboard::render() compressTexture(tex, true, true); GLuint texid = getTextureGLuint(tex); glUseProgram(MeshShader::BillboardShader::getInstance()->Program); - MeshShader::BillboardShader::getInstance()->SetTextureUnits(createVector(texid)); + MeshShader::BillboardShader::getInstance()->SetTextureUnits(texid); MeshShader::BillboardShader::getInstance()->setUniforms(irr_driver->getViewMatrix(), irr_driver->getProjMatrix(), pos, Size); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindVertexArray(0); diff --git a/src/graphics/stkmeshscenenode.cpp b/src/graphics/stkmeshscenenode.cpp index c5cb8dfc5..470adc051 100644 --- a/src/graphics/stkmeshscenenode.cpp +++ b/src/graphics/stkmeshscenenode.cpp @@ -268,10 +268,10 @@ void STKMeshSceneNode::render() mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]); if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0])) glMakeTextureHandleResidentARB(mesh.TextureHandles[0]); - MeshShader::ObjectPass1Shader::getInstance()->SetTextureHandles(createVector(mesh.TextureHandles[0])); + MeshShader::ObjectPass1Shader::getInstance()->SetTextureHandles(mesh.TextureHandles[0]); } else - MeshShader::ObjectPass1Shader::getInstance()->SetTextureUnits(std::vector < GLuint > { getTextureGLuint(mesh.textures[0]) }); + MeshShader::ObjectPass1Shader::getInstance()->SetTextureUnits(getTextureGLuint(mesh.textures[0])); MeshShader::ObjectPass1Shader::getInstance()->setUniforms(AbsoluteTransformation, invmodel); assert(mesh.vao); glBindVertexArray(mesh.vao); @@ -318,15 +318,19 @@ void STKMeshSceneNode::render() mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]); if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0])) glMakeTextureHandleResidentARB(mesh.TextureHandles[0]); - MeshShader::ObjectPass2Shader::getInstance()->SetTextureHandles(createVector(DiffuseHandle, SpecularHandle, SSAOHandle, mesh.TextureHandles[0])); + if (!mesh.TextureHandles[1]) + mesh.TextureHandles[1] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[1]), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]); + if (!glIsTextureHandleResidentARB(mesh.TextureHandles[1])) + glMakeTextureHandleResidentARB(mesh.TextureHandles[1]); + MeshShader::ObjectPass2Shader::getInstance()->SetTextureHandles(DiffuseHandle, SpecularHandle, SSAOHandle, mesh.TextureHandles[0], mesh.TextureHandles[1]); } else - MeshShader::ObjectPass2Shader::getInstance()->SetTextureUnits(createVector( + MeshShader::ObjectPass2Shader::getInstance()->SetTextureUnits( irr_driver->getRenderTargetTexture(RTT_DIFFUSE), irr_driver->getRenderTargetTexture(RTT_SPECULAR), irr_driver->getRenderTargetTexture(RTT_HALF1_R), getTextureGLuint(mesh.textures[0]), - getTextureGLuint(mesh.textures[1]))); + getTextureGLuint(mesh.textures[1])); MeshShader::ObjectPass2Shader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix); assert(mesh.vao); glBindVertexArray(mesh.vao); @@ -395,10 +399,10 @@ void STKMeshSceneNode::render() mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]); if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0])) glMakeTextureHandleResidentARB(mesh.TextureHandles[0]); - MeshShader::TransparentFogShader::getInstance()->SetTextureHandles(createVector(mesh.TextureHandles[0])); + MeshShader::TransparentFogShader::getInstance()->SetTextureHandles(mesh.TextureHandles[0]); } else - MeshShader::TransparentFogShader::getInstance()->SetTextureUnits(std::vector{ getTextureGLuint(mesh.textures[0]) }); + MeshShader::TransparentFogShader::getInstance()->SetTextureUnits(getTextureGLuint(mesh.textures[0])); MeshShader::TransparentFogShader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix, fogmax, startH, endH, start, end, col); assert(mesh.vao); @@ -425,10 +429,10 @@ void STKMeshSceneNode::render() mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentShader::getInstance()->SamplersId[0]); if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0])) glMakeTextureHandleResidentARB(mesh.TextureHandles[0]); - MeshShader::TransparentShader::getInstance()->SetTextureHandles(createVector(mesh.TextureHandles[0])); + MeshShader::TransparentShader::getInstance()->SetTextureHandles(mesh.TextureHandles[0]); } else - MeshShader::TransparentShader::getInstance()->SetTextureUnits(std::vector{ getTextureGLuint(mesh.textures[0]) }); + MeshShader::TransparentShader::getInstance()->SetTextureUnits(getTextureGLuint(mesh.textures[0])); MeshShader::TransparentShader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix); assert(mesh.vao); diff --git a/src/utils/tuple.hpp b/src/utils/tuple.hpp index 007bebbee..533e95fde 100644 --- a/src/utils/tuple.hpp +++ b/src/utils/tuple.hpp @@ -81,7 +81,7 @@ namespace STK { template struct TupleSize { - int value; + const int value; TupleSize() { value = sizeof...(T); From 7d602225fbcff7350ff44664eb1642ffcf0702f7 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Wed, 22 Oct 2014 22:05:09 +0200 Subject: [PATCH 73/73] Use InitTexture for transparents too --- src/graphics/render_geometry.cpp | 18 +----------------- src/graphics/stkanimatedmesh.cpp | 2 ++ src/graphics/stkmesh.cpp | 17 +++++++++++++++++ src/graphics/stkmesh.hpp | 1 + src/graphics/stkmeshscenenode.cpp | 2 ++ 5 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/graphics/render_geometry.cpp b/src/graphics/render_geometry.cpp index 803b24428..eb366b07d 100644 --- a/src/graphics/render_geometry.cpp +++ b/src/graphics/render_geometry.cpp @@ -723,25 +723,9 @@ void renderTransparenPass(const std::vector &TexUnits, std::vectorgetVAO(VertexType)); for (unsigned i = 0; i < meshes->size(); i++) { - std::vector Handles; GLMesh &mesh = *(STK::tuple_get<0>(meshes->at(i))); if (!irr_driver->hasARB_base_instance()) glBindVertexArray(mesh.vao); - for (unsigned j = 0; j < TexUnits.size(); j++) - { - if (!mesh.textures[TexUnits[j].m_id]) - mesh.textures[TexUnits[j].m_id] = getUnicolorTexture(video::SColor(255, 255, 255, 255)); - compressTexture(mesh.textures[TexUnits[j].m_id], TexUnits[j].m_premul_alpha); - if (UserConfigParams::m_azdo) - { - if (!mesh.TextureHandles[TexUnits[j].m_id]) - mesh.TextureHandles[TexUnits[j].m_id] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[TexUnits[j].m_id]), Shader::getInstance()->SamplersId[Handles.size()]); - if (!glIsTextureHandleResidentARB(mesh.TextureHandles[TexUnits[j].m_id])) - glMakeTextureHandleResidentARB(mesh.TextureHandles[TexUnits[j].m_id]); - Handles.push_back(mesh.TextureHandles[TexUnits[j].m_id]); - } - } - if (mesh.VAOType != VertexType) { #ifdef DEBUG @@ -751,7 +735,7 @@ void renderTransparenPass(const std::vector &TexUnits, std::vectorSetTextureHandles(Handles[0]); + Shader::getInstance()->SetTextureHandles(mesh.TextureHandles[0]); else Shader::getInstance()->SetTextureUnits(getTextureGLuint(mesh.textures[0])); custom_unroll_args::template exec(Shader::getInstance(), meshes->at(i)); diff --git a/src/graphics/stkanimatedmesh.cpp b/src/graphics/stkanimatedmesh.cpp index 7f168c2db..d12d71dbd 100644 --- a/src/graphics/stkanimatedmesh.cpp +++ b/src/graphics/stkanimatedmesh.cpp @@ -149,6 +149,8 @@ void STKAnimatedMesh::updateGL() Material::ShaderType MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType(), material, material2); InitTextures(mesh, MatType); } + else + InitTexturesTransparent(mesh); if (irr_driver->hasARB_base_instance()) { diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 6dd3c3114..380bddf92 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -349,4 +349,21 @@ void InitTextures(GLMesh &mesh, Material::ShaderType Mat) SetTexture(mesh, 6, false, getShaderTypeName(Mat)); break; } +} + +void InitTexturesTransparent(GLMesh &mesh) +{ + if (!mesh.textures[0]) + { + Log::fatal("STKMesh", "Missing texture for material transparent"); + return; + } + compressTexture(mesh.textures[0], true); + if (UserConfigParams::m_azdo) + { + if (!mesh.TextureHandles[0]) + mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::ObjectPass1Shader::getInstance()->SamplersId[0]); + if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0])) + glMakeTextureHandleResidentARB(mesh.TextureHandles[0]); + } } \ No newline at end of file diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp index df533c031..8e9c3ea7b 100644 --- a/src/graphics/stkmesh.hpp +++ b/src/graphics/stkmesh.hpp @@ -179,5 +179,6 @@ Material::ShaderType MaterialTypeToMeshMaterial(video::E_MATERIAL_TYPE MaterialT TransparentMaterial MaterialTypeToTransparentMaterial(video::E_MATERIAL_TYPE, f32 MaterialTypeParam, Material* material); void InitTextures(GLMesh &mesh, Material::ShaderType); +void InitTexturesTransparent(GLMesh &mesh); #endif // STKMESH_H diff --git a/src/graphics/stkmeshscenenode.cpp b/src/graphics/stkmeshscenenode.cpp index 470adc051..6f9818300 100644 --- a/src/graphics/stkmeshscenenode.cpp +++ b/src/graphics/stkmeshscenenode.cpp @@ -189,6 +189,8 @@ void STKMeshSceneNode::updateGL() if (!immediate_draw) InitTextures(mesh, MatType); } + else if (!immediate_draw) + InitTexturesTransparent(mesh); if (!immediate_draw && irr_driver->hasARB_base_instance()) {