From 6d8a16f19ee8a8d526f71489cfe76e554e066342 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 17 Jul 2016 02:33:45 +0200 Subject: [PATCH] Rendering ImGui, ScreenLog, and Information as a post-processing step to make it work in fisheye rendering (closing #119) Disable SGCT ESC terminate handling and implement a method that optionally waits before closing the application (closing #120) - ESC key is now bound to a call to "openspace.toggleShutdown()" that will initiate a shutdown in 3 seconds unless ESC is pressed again - The countdown timer is set in the openspace.cfg --- apps/OpenSpace/main.cpp | 3 ++ ext/ghoul | 2 +- .../openspace/engine/configurationmanager.h | 3 ++ include/openspace/engine/openspaceengine.h | 20 ++++++- .../engine/wrapper/sgctwindowwrapper.h | 1 + .../openspace/engine/wrapper/windowwrapper.h | 6 +++ include/openspace/rendering/renderengine.h | 6 ++- openspace.cfg | 1 + scripts/common.lua | 2 + src/engine/configurationmanager.cpp | 1 + src/engine/openspaceengine.cpp | 54 +++++++++++++++++-- src/engine/wrapper/sgctwindowwrapper.cpp | 4 ++ src/engine/wrapper/windowwrapper.cpp | 2 + src/rendering/renderengine.cpp | 44 +++++++++++---- 14 files changed, 133 insertions(+), 16 deletions(-) diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index d43be6508b..094f376248 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -130,6 +130,9 @@ int main(int argc, char** argv) { _sgctEngine->setExternalControlCallback(mainExternalControlCallback); _sgctEngine->setCharCallbackFunction(mainCharCallback); + // Disable the immediate exit of the application when the ESC key is pressed + _sgctEngine->setExitKey(SGCT_KEY_UNKNOWN); + sgct::MessageHandler::instance()->setNotifyLevel(sgct::MessageHandler::NOTIFY_ALL); // set encode and decode functions diff --git a/ext/ghoul b/ext/ghoul index 3c60705400..60e65350db 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 3c6070540080700b84f4e7e3986e2497a2b85b56 +Subproject commit 60e65350db67a5a364dfa5e201f1e888395f4f06 diff --git a/include/openspace/engine/configurationmanager.h b/include/openspace/engine/configurationmanager.h index 4af3c63afa..3f1b548a69 100644 --- a/include/openspace/engine/configurationmanager.h +++ b/include/openspace/engine/configurationmanager.h @@ -92,6 +92,9 @@ public: /// The key that stores the verbosity (None, Minimal, Default, Full) of the system /// capabilities components static const std::string KeyCapabilitiesVerbosity; + /// The key that stores the time (in seconds) that the application will wait before + /// shutting down after the shutdown call is made + static const std::string KeyShutdownCountdown; /// The key that stores whether the master node should perform rendering just function /// as a pure manager static const std::string KeyDisableMasterRendering; diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 2261ba879a..30817172d3 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -28,6 +28,8 @@ #include #include +#include + #include #include @@ -55,7 +57,7 @@ class SettingsEngine; namespace interaction { class InteractionHandler; } namespace gui { class GUI; } -namespace scripting { class ScriptEngine; } +//namespace scripting { class ScriptEngine; } namespace network { class ParallelConnection; } namespace properties { class PropertyOwner; } @@ -110,8 +112,16 @@ public: void enableBarrier(); void disableBarrier(); + void toggleShutdownMode(); + void runPostInitializationScripts(const std::string& sceneDescription); + /** + * Returns the Lua library that contains all Lua functions available to affect the + * application. + */ + static scripting::ScriptEngine::LuaLibrary luaLibrary(); + private: OpenSpaceEngine(std::string programName, std::unique_ptr windowWrapper); ~OpenSpaceEngine(); @@ -149,6 +159,14 @@ private: bool _isMaster; double _runTime; + // Whether the application is currently in shutdown mode (i.e. counting down the timer + // and closing it at '0' + bool _isInShutdownMode; + // The total amount of time the application will wait before actually shutting down + float _shutdownWait; + // The current state of the countdown; if it reaches '0', the application will close + float _shutdownCountdown; + static OpenSpaceEngine* _engine; }; diff --git a/include/openspace/engine/wrapper/sgctwindowwrapper.h b/include/openspace/engine/wrapper/sgctwindowwrapper.h index 62e9c728a3..5f3a59a9bf 100644 --- a/include/openspace/engine/wrapper/sgctwindowwrapper.h +++ b/include/openspace/engine/wrapper/sgctwindowwrapper.h @@ -36,6 +36,7 @@ namespace openspace { */ class SGCTWindowWrapper : public WindowWrapper { public: + void terminate() override; void setBarrier(bool enabled) override; void clearAllWindows(const glm::vec4& clearColor) override; bool windowHasResized() const override; diff --git a/include/openspace/engine/wrapper/windowwrapper.h b/include/openspace/engine/wrapper/windowwrapper.h index f9b778e5a5..cd91bc1732 100644 --- a/include/openspace/engine/wrapper/windowwrapper.h +++ b/include/openspace/engine/wrapper/windowwrapper.h @@ -42,6 +42,12 @@ namespace openspace { */ class WindowWrapper { public: + /** + * This method closes the application by calling the necessary terminate function of + * the window management system + */ + virtual void terminate(); + /** * This method enables or disables a framelock barrier. If the specific windowing * framework does not provide a framelock, this method defaults to a no-op. diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index e94f7a320b..832671c52b 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -89,7 +89,10 @@ public: bool initializeGL(); void postSynchronizationPreDraw(); void preSynchronization(); - void render(const glm::mat4& projectionMatrix, const glm::mat4& viewMatrix, bool showGui); + void render(const glm::mat4& projectionMatrix, const glm::mat4& viewMatrix); + + void renderScreenLog(); + void renderShutdownInformation(float timer, float fullTime); void postDraw(); void takeScreenshot(); @@ -183,7 +186,6 @@ private: RendererImplementation rendererFromString(const std::string& method); void renderInformation(); - void renderScreenLog(); Camera* _mainCamera; Scene* _sceneGraph; diff --git a/openspace.cfg b/openspace.cfg index 5f0ac5e37d..1c62525b33 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -55,6 +55,7 @@ return { Type = "text", File = "${BASE_PATH}/ScriptLog.txt" }, + ShutdownCountdown = 3, DownloadRequestURL = "http://openspace.itn.liu.se/request.cgi", RenderingMethod = "Framebuffer" --RenderingMethod = "ABuffer" -- alternative: "Framebuffer" diff --git a/scripts/common.lua b/scripts/common.lua index 7861bbf263..b8dcf5a401 100644 --- a/scripts/common.lua +++ b/scripts/common.lua @@ -11,6 +11,8 @@ helper.setCommonKeys = function() openspace.bindKey("F2", "openspace.setPerformanceMeasurement(true)") openspace.bindKey("F3", "openspace.setPerformanceMeasurement(false)") + openspace.bindKey("ESC", "openspace.toggleShutdown()") + openspace.bindKey("PRINT_SCREEN", "openspace.takeScreenshot()") openspace.bindKey("SPACE", "openspace.time.togglePause()") diff --git a/src/engine/configurationmanager.cpp b/src/engine/configurationmanager.cpp index 2e6cabe62c..67bc3f47c1 100644 --- a/src/engine/configurationmanager.cpp +++ b/src/engine/configurationmanager.cpp @@ -61,6 +61,7 @@ const string ConfigurationManager::KeyLogImmediateFlush = "Logging.ImmediateFlus const string ConfigurationManager::KeyLogs = "Logging.Logs"; const string ConfigurationManager::KeyCapabilitiesVerbosity = "Logging.CapabilitiesVerbosity"; +const string ConfigurationManager::KeyShutdownCountdown = "ShutdownCountdown"; const string ConfigurationManager::KeyDisableMasterRendering = "DisableRenderingOnMaster"; const string ConfigurationManager::KeyDownloadRequestURL = "DownloadRequestURL"; diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 7c492175c6..09d861d2fb 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -84,6 +84,8 @@ #include #endif +#include "openspaceengine_lua.inl" + using namespace openspace::scripting; using namespace ghoul::filesystem; using namespace ghoul::logging; @@ -140,6 +142,9 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName, , _isMaster(false) , _runTime(0.0) , _syncBuffer(new SyncBuffer(4096)) + , _isInShutdownMode(false) + , _shutdownCountdown(0.f) + , _shutdownWait(0.f) { _interactionHandler->setPropertyOwner(_globalPropertyNamespace.get()); _globalPropertyNamespace->addPropertySubOwner(_interactionHandler.get()); @@ -376,6 +381,7 @@ bool OpenSpaceEngine::initialize() { // Register Lua script functions LDEBUG("Registering Lua libraries"); + _scriptEngine->addLibrary(OpenSpaceEngine::luaLibrary()); _scriptEngine->addLibrary(RenderEngine::luaLibrary()); _scriptEngine->addLibrary(Scene::luaLibrary()); _scriptEngine->addLibrary(Time::luaLibrary()); @@ -410,6 +416,9 @@ bool OpenSpaceEngine::initialize() { ConfigurationManager::KeyDisableMasterRendering, disableMasterRendering); _renderEngine->setDisableRenderingOnMaster(disableMasterRendering); + configurationManager().getValue( + ConfigurationManager::KeyShutdownCountdown, _shutdownWait + ); // Load scenegraph Scene* sceneGraph = new Scene; @@ -768,6 +777,13 @@ void OpenSpaceEngine::preSynchronization() { } void OpenSpaceEngine::postSynchronizationPreDraw() { + if (_isInShutdownMode) { + if (_shutdownCountdown <= 0.f) { + _windowWrapper->terminate(); + } + _shutdownCountdown -= _windowWrapper->averageDeltaTime(); + } + Time::ref().postSynchronizationPreDraw(); _scriptEngine->postSynchronizationPreDraw(); @@ -815,9 +831,7 @@ void OpenSpaceEngine::postSynchronizationPreDraw() { } void OpenSpaceEngine::render(const glm::mat4& projectionMatrix, const glm::mat4& viewMatrix) { - bool showGui = _windowWrapper->hasGuiWindow() ? _windowWrapper->isGuiWindow() : true; - - _renderEngine->render(projectionMatrix, viewMatrix, showGui); + _renderEngine->render(projectionMatrix, viewMatrix); } void OpenSpaceEngine::postDraw() { @@ -825,6 +839,8 @@ void OpenSpaceEngine::postDraw() { bool showGui = _windowWrapper->hasGuiWindow() ? _windowWrapper->isGuiWindow() : true; if (showGui) { + _renderEngine->renderScreenLog(); + if (_console->isVisible()) _console->render(); #ifdef OPENSPACE_MODULE_ONSCREENGUI_ENABLED @@ -832,6 +848,9 @@ void OpenSpaceEngine::postDraw() { _gui->endFrame(); } #endif + + if (_isInShutdownMode) + _renderEngine->renderShutdownInformation(_shutdownCountdown, _shutdownWait); } void OpenSpaceEngine::keyboardCallback(Key key, KeyModifier mod, KeyAction action) { @@ -934,6 +953,35 @@ void OpenSpaceEngine::externalControlCallback(const char* receivedChars, int siz _networkEngine->handleMessage(std::string(receivedChars, size)); } +void OpenSpaceEngine::toggleShutdownMode() { + if (_isInShutdownMode) { + // If we are already in shutdown mode, we want to disable it instead + LINFO("Disabled shutdown mode"); + _isInShutdownMode = false; + } + else { + // Else, we hav eto enable it + LINFO("Shutting down OpenSpace"); + _shutdownCountdown = _shutdownWait; + _isInShutdownMode = true; + } +} + +scripting::ScriptEngine::LuaLibrary OpenSpaceEngine::luaLibrary() { + return { + "", + { + { + "toggleShutdown", + &luascriptfunctions::toggleShutdown, + "", + "Toggles the shutdown mode that will close the application after the count" + "down timer is reached" + } + } + }; +} + void OpenSpaceEngine::enableBarrier() { _windowWrapper->setBarrier(true); } diff --git a/src/engine/wrapper/sgctwindowwrapper.cpp b/src/engine/wrapper/sgctwindowwrapper.cpp index 1b0908db63..7abbdcda5c 100644 --- a/src/engine/wrapper/sgctwindowwrapper.cpp +++ b/src/engine/wrapper/sgctwindowwrapper.cpp @@ -36,6 +36,10 @@ namespace { namespace openspace { +void SGCTWindowWrapper::terminate() { + sgct::Engine::instance()->terminate(); +} + void SGCTWindowWrapper::setBarrier(bool enabled) { sgct::SGCTWindow::setBarrier(enabled); } diff --git a/src/engine/wrapper/windowwrapper.cpp b/src/engine/wrapper/windowwrapper.cpp index 0e45b73a0e..aa4c2ce284 100644 --- a/src/engine/wrapper/windowwrapper.cpp +++ b/src/engine/wrapper/windowwrapper.cpp @@ -31,6 +31,8 @@ namespace openspace { WindowWrapper::WindowWrapperException::WindowWrapperException(const std::string& msg) : ghoul::RuntimeError(msg, "WindowWrapper") {} + +void WindowWrapper::terminate() {} void WindowWrapper::setBarrier(bool) {} diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 8a90d3fa17..4b98620289 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -383,12 +383,10 @@ void RenderEngine::postSynchronizationPreDraw() { } -void RenderEngine::render(const glm::mat4& projectionMatrix, const glm::mat4& viewMatrix, bool showGui) { +void RenderEngine::render(const glm::mat4& projectionMatrix, const glm::mat4& viewMatrix){ _mainCamera->sgctInternal.setViewMatrix(viewMatrix); _mainCamera->sgctInternal.setProjectionMatrix(projectionMatrix); - - if (!(OsEng.isMaster() && _disableMasterRendering) && !OsEng.windowWrapper().isGuiWindow()) { _renderer->render(_globalBlackOutFactor, _performanceManager != nullptr); } @@ -398,9 +396,6 @@ void RenderEngine::render(const glm::mat4& projectionMatrix, const glm::mat4& vi if (_showInfo) { renderInformation(); } - if (_showLog && showGui) { - renderScreenLog(); - } } for (auto screenSpaceRenderable : _screenSpaceRenderables) { @@ -409,16 +404,44 @@ void RenderEngine::render(const glm::mat4& projectionMatrix, const glm::mat4& vi } } +void RenderEngine::renderShutdownInformation(float timer, float fullTime) { + timer = timer < 0.f ? 0.f : timer; + + auto size = ghoul::fontrendering::FontRenderer::defaultRenderer().boundingBox( + *_fontDate, + "Shutdown in: %.2fs/%.2fs", + timer, + fullTime + ); + + glm::vec2 penPosition = glm::vec2( + OsEng.windowWrapper().viewportPixelCoordinates().y - size.boundingBox.x, + OsEng.windowWrapper().viewportPixelCoordinates().w - size.boundingBox.y + ); + penPosition.y -= _fontDate->height(); + + RenderFontCr( + *_fontDate, + penPosition, + "Shutdown in: %.2fs/%.2fs", + timer, + fullTime + ); +} + void RenderEngine::postDraw() { - if (Time::ref().timeJumped()) + if (Time::ref().timeJumped()) { Time::ref().setTimeJumped(false); + } + if (_takeScreenshot) { OsEng.windowWrapper().takeScreenshot(); _takeScreenshot = false; } - if (_performanceManager) + if (_performanceManager) { _performanceManager->storeScenePerformanceMeasurements(scene()->allSceneGraphNodes()); + } } void RenderEngine::takeScreenshot() { @@ -1201,7 +1224,7 @@ void RenderEngine::renderInformation() { glm::vec2 penPosition = glm::vec2( 10.f, OsEng.windowWrapper().viewportPixelCoordinates().w - ); + ); penPosition.y -= _fontDate->height(); RenderFontCr(*_fontDate, @@ -1412,6 +1435,9 @@ void RenderEngine::renderInformation() { } void RenderEngine::renderScreenLog() { + if (!_showLog) + return; + _log->removeExpiredEntries(); const int max = 10;