From 39046749d2b8f8bfc3601c8e51635b32e7b72a93 Mon Sep 17 00:00:00 2001 From: funto66 Date: Mon, 9 Dec 2013 00:09:35 +0000 Subject: [PATCH] Add a debug menu + option to reload shaders (memory leak, yeah, but it's just for debugging) git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14674 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- sources.cmake | 2 + src/graphics/irr_driver.hpp | 4 +- src/graphics/shaders.cpp | 38 ++++++++--- src/graphics/shaders.hpp | 3 +- src/guiengine/event_handler.cpp | 4 ++ src/utils/debug.cpp | 108 ++++++++++++++++++++++++++++++++ src/utils/debug.hpp | 32 ++++++++++ 7 files changed, 179 insertions(+), 12 deletions(-) create mode 100644 src/utils/debug.cpp create mode 100644 src/utils/debug.hpp diff --git a/sources.cmake b/sources.cmake index cc0000438..6ed2afbdd 100644 --- a/sources.cmake +++ b/sources.cmake @@ -305,6 +305,7 @@ src/tracks/track_object_presentation.cpp src/tracks/track_sector.cpp src/utils/constants.cpp src/utils/crash_reporting.cpp +src/utils/debug.cpp src/utils/helpers.cpp src/utils/leak_check.cpp src/utils/log.cpp @@ -635,6 +636,7 @@ src/tracks/track_object_presentation.hpp src/tracks/track_sector.hpp src/utils/aligned_array.hpp src/utils/constants.hpp +src/utils/debug.hpp src/utils/helpers.hpp src/utils/interpolation_array.hpp src/utils/crash_reporting.hpp diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index 2d149ef9d..e1c87b1f5 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -360,8 +360,10 @@ public: inline PostProcessing* getPostProcessing() {return m_post_processing;} // ------------------------------------------------------------------------ inline core::vector3df getWind() {return m_wind->getWind();} - // ------------------------------------------------------------------------ + // ----------------------------------------------------------------------- inline video::E_MATERIAL_TYPE getShader(const ShaderType num) {return m_shaders->getShader(num);} + // ----------------------------------------------------------------------- + inline void updateShaders() {m_shaders->loadShaders();} // ------------------------------------------------------------------------ inline video::IShaderConstantSetCallBack* getCallback(const ShaderType num) { diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index c62800249..6656a376d 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -29,14 +29,6 @@ using namespace video; Shaders::Shaders() { - const std::string &dir = file_manager->getShaderDir(); - - IGPUProgrammingServices * const gpu = irr_driver->getVideoDriver()->getGPUProgrammingServices(); - - #define glsl(a, b, c) gpu->addHighLevelShaderMaterialFromFiles((a).c_str(), (b).c_str(), (IShaderConstantSetCallBack*) c) - #define glslmat(a, b, c, d) gpu->addHighLevelShaderMaterialFromFiles((a).c_str(), (b).c_str(), (IShaderConstantSetCallBack*) c, d) - #define glsl_noinput(a, b) gpu->addHighLevelShaderMaterialFromFiles((a).c_str(), (b).c_str(), (IShaderConstantSetCallBack*) 0) - // Callbacks memset(m_callbacks, 0, sizeof(m_callbacks)); @@ -75,6 +67,26 @@ Shaders::Shaders() m_callbacks[ES_PPDISPLACE] = new PPDisplaceProvider(); m_callbacks[ES_FOG] = new FogProvider(); + for(s32 i=0 ; i < ES_COUNT ; i++) + m_shaders[i] = -1; + + loadShaders(); +} + +void Shaders::loadShaders() +{ + const std::string &dir = file_manager->getShaderDir(); + + IGPUProgrammingServices * const gpu = irr_driver->getVideoDriver()->getGPUProgrammingServices(); + + #define glsl(a, b, c) gpu->addHighLevelShaderMaterialFromFiles((a).c_str(), (b).c_str(), (IShaderConstantSetCallBack*) c) + #define glslmat(a, b, c, d) gpu->addHighLevelShaderMaterialFromFiles((a).c_str(), (b).c_str(), (IShaderConstantSetCallBack*) c, d) + #define glsl_noinput(a, b) gpu->addHighLevelShaderMaterialFromFiles((a).c_str(), (b).c_str(), (IShaderConstantSetCallBack*) 0) + + // Save previous shaders (used in case some shaders don't compile) + int saved_shaders[ES_COUNT]; + memcpy(saved_shaders, m_shaders, sizeof(m_shaders)); + // Ok, go m_shaders[ES_NORMAL_MAP] = glslmat(dir + "normalmap.vert", dir + "normalmap.frag", m_callbacks[ES_NORMAL_MAP], EMT_SOLID_2_LAYER); @@ -221,8 +233,7 @@ Shaders::Shaders() m_callbacks[ES_FOG], EMT_ONETEXTURE_BLEND); // Check that all successfully loaded - u32 i; - for (i = 0; i < ES_COUNT; i++) { + for (s32 i = 0; i < ES_COUNT; i++) { // Old Intel Windows drivers fail here. // It's an artist option, so not necessary to play. @@ -235,6 +246,13 @@ Shaders::Shaders() #undef glsl #undef glslmat #undef glsl_noinput + + // In case we're reloading and a shader didn't compile: keep the previous, working one + for(s32 i=0 ; i < ES_COUNT ; i++) + { + if(m_shaders[i] == -1) + m_shaders[i] = saved_shaders[i]; + } } Shaders::~Shaders() diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 2f9127a2b..3a713d0c4 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -105,9 +105,10 @@ public: video::IShaderConstantSetCallBack * m_callbacks[ES_COUNT]; + void loadShaders(); private: void check(const int num) const; - + int m_shaders[ES_COUNT]; }; diff --git a/src/guiengine/event_handler.cpp b/src/guiengine/event_handler.cpp index 6720113cf..27a82609a 100644 --- a/src/guiengine/event_handler.cpp +++ b/src/guiengine/event_handler.cpp @@ -34,6 +34,7 @@ #include "modes/demo_world.hpp" #include "modes/world.hpp" #include "states_screens/state_manager.hpp" +#include "utils/debug.hpp" #include "utils/profiler.hpp" using GUIEngine::EventHandler; @@ -59,6 +60,9 @@ EventHandler::~EventHandler() bool EventHandler::OnEvent (const SEvent &event) { if (!m_accept_events && event.EventType != EET_LOG_TEXT_EVENT) return true; + + if(!Debug::onEvent(event)) + return false; // TO DEBUG HATS (when you don't actually have a hat) /* diff --git a/src/utils/debug.cpp b/src/utils/debug.cpp new file mode 100644 index 000000000..32de90c17 --- /dev/null +++ b/src/utils/debug.cpp @@ -0,0 +1,108 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 Lionel Fuentes +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "debug.hpp" +#include "graphics/irr_driver.hpp" +#include "config/user_config.hpp" +#include "utils/log.hpp" +#include +#include +using namespace irr; +using namespace gui; + +namespace Debug { + +/** This is to let mouse input events go through when the debug menu is visible, otherwise + GUI events would be blocked while in a race... */ +static bool g_debug_menu_visible = false; + +static bool g_was_pointer_shown = false; + +// ----------------------------------------------------------------------------- +// Commands for the debug menu +enum DebugMenuCommand +{ + //! graphics commands + DEBUG_GRAPHICS_RELOAD_SHADERS, +}; + +// ----------------------------------------------------------------------------- +// Debug menu handling +bool onEvent(const SEvent &event) +{ + // Only activated in artist debug mode + if(!UserConfigParams::m_artist_debug_mode) + return true; // keep handling the events + + if(event.EventType == EET_MOUSE_INPUT_EVENT) + { + // Create the menu (only one menu at a time) + if(event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN && !g_debug_menu_visible) + { + // root menu + gui::IGUIEnvironment* guienv = irr_driver->getGUI(); + IGUIContextMenu* mnu = guienv->addContextMenu( + core::rect(event.MouseInput.X, event.MouseInput.Y, event.MouseInput.Y+100, event.MouseInput.Y+100),NULL); + mnu->addItem(L"Graphics >",-1,true,true); + + // graphics menu + IGUIContextMenu* sub = mnu->getSubMenu(0); + + sub->addItem(L"Reload shaders", DEBUG_GRAPHICS_RELOAD_SHADERS ); + g_debug_menu_visible = true; + + g_was_pointer_shown = irr_driver->isPointerShown(); + irr_driver->showPointer(); + } + + // Let Irrlicht handle the event while the menu is visible - otherwise in a race the GUI events won't be generated + if(g_debug_menu_visible) + return false; + } + + if (event.EventType == EET_GUI_EVENT) + { + if (event.GUIEvent.Caller != NULL) + { + if(event.GUIEvent.Caller->getType() == EGUIET_CONTEXT_MENU) + { + IGUIContextMenu *menu = (IGUIContextMenu*)event.GUIEvent.Caller; + s32 cmdID = menu->getItemCommandId(menu->getSelectedItem()); + + if(event.GUIEvent.EventType == EGET_ELEMENT_CLOSED) + { + g_debug_menu_visible = false; + if(g_was_pointer_shown) + irr_driver->showPointer(); + else + irr_driver->hidePointer(); + } + + if(cmdID == DEBUG_GRAPHICS_RELOAD_SHADERS) + { + Log::info("Debug", "Reloading shaders...\n"); + irr_driver->updateShaders(); + } + return false; // event has been treated + } + } + } + return true; // continue event handling +} + +} diff --git a/src/utils/debug.hpp b/src/utils/debug.hpp new file mode 100644 index 000000000..2a9ad179d --- /dev/null +++ b/src/utils/debug.hpp @@ -0,0 +1,32 @@ +// SuperTuxKart - a fun racing game with go-kart +// +// Copyright (C) 2013 Lionel Fuentes +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef HEADER_DEBUG_HPP +#define HEADER_DEBUG_HPP + +namespace irr { + struct SEvent; +} + +namespace Debug +{ + bool onEvent(const irr::SEvent &event); +} + + +#endif // HEADER_DEBUG_HPP