From 8f924f76965cb1be85621180fc70de043959efc9 Mon Sep 17 00:00:00 2001 From: Joakim Kilby Date: Tue, 17 Feb 2015 11:58:03 +0100 Subject: [PATCH 1/7] added serialize, deserialize, post sync and pre sync functions for script engine --- include/openspace/scripting/scriptengine.h | 17 +++++++++ src/scripting/scriptengine.cpp | 40 ++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/include/openspace/scripting/scriptengine.h b/include/openspace/scripting/scriptengine.h index f81e033750..63a6dfd30c 100644 --- a/include/openspace/scripting/scriptengine.h +++ b/include/openspace/scripting/scriptengine.h @@ -34,6 +34,8 @@ */ namespace openspace { + class SyncBuffer; + namespace scripting { class ScriptEngine { @@ -67,6 +69,16 @@ public: bool writeDocumentation(const std::string& filename, const std::string& type) const; + void serialize(SyncBuffer* syncBuffer); + + void deserialize(SyncBuffer* syncBuffer); + + void postSynchronizationPreDraw(); + + void preSynchronization(); + + void queueScript(const std::string &script); + std::vector allLuaFunctions() const; private: @@ -80,6 +92,11 @@ private: lua_State* _state; std::set _registeredLibraries; + + //sync variables + std::mutex _mutex; + std::vector _queuedScripts; + std::string _currentSyncedScript; }; } // namespace scripting diff --git a/src/scripting/scriptengine.cpp b/src/scripting/scriptengine.cpp index 2dfb37ce9c..ac6603181c 100644 --- a/src/scripting/scriptengine.cpp +++ b/src/scripting/scriptengine.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -605,6 +606,45 @@ bool ScriptEngine::writeDocumentation(const std::string& filename, const std::st } } +void ScriptEngine::serialize(SyncBuffer* syncBuffer){ + syncBuffer->encode(_currentSyncedScript); +} + +void ScriptEngine::deserialize(SyncBuffer* syncBuffer){ + syncBuffer->decode(_currentSyncedScript); +} + +void ScriptEngine::postSynchronizationPreDraw(){ + +} + +void ScriptEngine::preSynchronization(){ + if (!_currentSyncedScript.empty()){ + runScript(_currentSyncedScript); + _currentSyncedScript.clear(); + } + + _mutex.lock(); + + if (!_queuedScripts.empty()){ + _currentSyncedScript = _queuedScripts.back(); + _queuedScripts.pop_back(); + } + + _mutex.unlock(); +} + +void ScriptEngine::queueScript(const std::string &script){ + if (script.empty()) + return; + + _mutex.lock(); + + _queuedScripts.insert(_queuedScripts.begin(), script); + + _mutex.unlock(); +} + } // namespace scripting } // namespace openspace From aa66bdeaa4f084099d5c724ea8c8ed097c3f51b0 Mon Sep 17 00:00:00 2001 From: Joakim Kilby Date: Tue, 17 Feb 2015 11:58:57 +0100 Subject: [PATCH 2/7] added synced versions of shared variables and modified set/get methods to adress the right versions of variables --- include/openspace/util/camera.h | 5 +++++ include/openspace/util/time.h | 5 +++++ src/util/camera.cpp | 19 +++++++++++++------ src/util/time.cpp | 25 ++++++++++++++++--------- 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/include/openspace/util/camera.h b/include/openspace/util/camera.h index 79e96090e2..601a0fbf21 100644 --- a/include/openspace/util/camera.h +++ b/include/openspace/util/camera.h @@ -169,6 +169,11 @@ private: glm::vec2 _sharedScaling; psc _sharedPosition; glm::mat4 _sharedViewRotationMatrix; + + //synced copies of local variables + glm::vec2 _syncedScaling; + psc _syncedPosition; + glm::mat4 _syncedViewRotationMatrix; }; diff --git a/include/openspace/util/time.h b/include/openspace/util/time.h index 708cd660bc..b9934bc864 100644 --- a/include/openspace/util/time.h +++ b/include/openspace/util/time.h @@ -197,6 +197,11 @@ private: double _sharedTime; double _sharedDt; bool _sharedTimeJumped; + + //synced copies + double _syncedTime; + double _syncedDt; + bool _syncedTimeJumped; std::mutex _syncMutex; diff --git a/src/util/camera.cpp b/src/util/camera.cpp index 8b11f2e459..d384de1b77 100644 --- a/src/util/camera.cpp +++ b/src/util/camera.cpp @@ -51,6 +51,9 @@ Camera::Camera() , _sharedPosition() , _sharedScaling(1.f, 0.f) , _sharedViewRotationMatrix(1.f) + , _syncedPosition() + , _syncedScaling(1.f, 0.f) + , _syncedViewRotationMatrix(1.f) , _focusPosition() { } @@ -66,7 +69,8 @@ void Camera::setPosition(psc pos) const psc& Camera::position() const { - return _localPosition; + //return _localPosition; + return _syncedPosition; } void Camera::setModelMatrix(glm::mat4 modelMatrix){ @@ -119,7 +123,8 @@ void Camera::setViewRotationMatrix(glm::mat4 m) { const glm::mat4& Camera::viewRotationMatrix() const { - return _localViewRotationMatrix; + //return _localViewRotationMatrix; + return _syncedViewRotationMatrix; } void Camera::compileViewRotationMatrix() @@ -129,6 +134,7 @@ void Camera::compileViewRotationMatrix() // the camera matrix needs to be rotated inverse to the world // _viewDirection = glm::rotate(glm::inverse(_viewRotation), _cameraDirection); + //_viewDirection = (glm::inverse(_localViewRotationMatrix) * glm::vec4(_cameraDirection, 0.f)).xyz; _viewDirection = (glm::inverse(_localViewRotationMatrix) * glm::vec4(_cameraDirection, 0.f)).xyz; _viewDirection = glm::normalize(_viewDirection); } @@ -194,7 +200,8 @@ void Camera::setScaling(glm::vec2 scaling) const glm::vec2& Camera::scaling() const { - return _localScaling; + //return _localScaling; + return _syncedScaling; } void Camera::setLookUpVector(glm::vec3 lookUp) @@ -230,9 +237,9 @@ void Camera::deserialize(SyncBuffer* syncBuffer){ void Camera::postSynchronizationPreDraw(){ _syncMutex.lock(); - _localViewRotationMatrix = _sharedViewRotationMatrix; - _localPosition = _sharedPosition; - _localScaling = _sharedScaling; + _syncedViewRotationMatrix = _sharedViewRotationMatrix; + _syncedPosition = _sharedPosition; + _syncedScaling = _sharedScaling; _syncMutex.unlock(); } diff --git a/src/util/time.cpp b/src/util/time.cpp index a90dec7091..3b418696a6 100644 --- a/src/util/time.cpp +++ b/src/util/time.cpp @@ -148,10 +148,13 @@ Time* Time::_instance = nullptr; Time::Time() : _time(-1.0) , _dt(1.0) + , _timeJumped(false) + , _syncedTime(-1.0) + , _syncedDt(1.0) + , _syncedTimeJumped(false) + , _deltaTimePerSecond(1.0) , _sharedTime(-1.0) , _sharedDt(1.0) - , _deltaTimePerSecond(1.0) - , _timeJumped(false) , _sharedTimeJumped(false) { } @@ -184,7 +187,8 @@ void Time::setTime(double value) { double Time::currentTime() const { assert(_instance); - return _time; + //return _time; + return _syncedTime; } double Time::advanceTime(double tickTime) { @@ -200,7 +204,8 @@ void Time::setDeltaTime(double deltaT) { } double Time::deltaTime() const { - return _dt; + //return _dt; + return _syncedDt; } void Time::setTime(std::string time) { @@ -212,7 +217,8 @@ void Time::setTime(std::string time) { std::string Time::currentTimeUTC() const { std::string date; - SpiceManager::ref().getDateFromET(_time, date); + //SpiceManager::ref().getDateFromET(_time, date); + SpiceManager::ref().getDateFromET(_syncedTime, date); return date; } @@ -239,9 +245,9 @@ void Time::deserialize(SyncBuffer* syncBuffer){ void Time::postSynchronizationPreDraw(){ _syncMutex.lock(); - _time = _sharedTime; - _dt = _sharedDt; - _timeJumped = _sharedTimeJumped; + _syncedTime = _sharedTime; + _syncedDt = _sharedDt; + _syncedTimeJumped = _sharedTimeJumped; _syncMutex.unlock(); } @@ -257,7 +263,8 @@ void Time::preSynchronization(){ } bool Time::timeJumped(){ - return _timeJumped; + //return _timeJumped; + return _syncedTimeJumped; } void Time::setTimeJumped(bool jumped){ From 0f9476519c76a477d468674b90617ceb9439f13c Mon Sep 17 00:00:00 2001 From: Joakim Kilby Date: Tue, 17 Feb 2015 11:59:52 +0100 Subject: [PATCH 3/7] changed into average delta time instaed of delta time, added calls to pre/pro sync and serialize/deserialize of scriptengine and time --- src/engine/openspaceengine.cpp | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 07246f784a..83834e3f60 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -493,18 +493,23 @@ bool OpenSpaceEngine::initializeGL() { void OpenSpaceEngine::preSynchronization() { FileSys.triggerFilesystemEvents(); if (sgct::Engine::instance()->isMaster()) { - const double dt = sgct::Engine::instance()->getDt(); - - _interactionHandler.update(dt); - //_interactionHandler.lockControls(); + //const double dt = sgct::Engine::instance()->getDt(); + const double dt = sgct::Engine::instance()->getAvgDt(); Time::ref().advanceTime(dt); + Time::ref().preSynchronization(); + + _interactionHandler.update(dt); + //_interactionHandler.lockControls(); + _scriptEngine.preSynchronization(); _renderEngine.preSynchronization(); } } void OpenSpaceEngine::postSynchronizationPreDraw() { + Time::ref().postSynchronizationPreDraw(); + _scriptEngine.postSynchronizationPreDraw(); _renderEngine.postSynchronizationPreDraw(); if (sgct::Engine::instance()->isMaster() && _gui.isEnabled()) { @@ -611,7 +616,10 @@ void OpenSpaceEngine::mouseScrollWheelCallback(int pos) { void OpenSpaceEngine::encode() { if (_syncBuffer) { + _scriptEngine.serialize(_syncBuffer); + Time::ref().serialize(_syncBuffer); _renderEngine.serialize(_syncBuffer); + _syncBuffer->write(); } } @@ -619,7 +627,11 @@ void OpenSpaceEngine::encode() { void OpenSpaceEngine::decode() { if (_syncBuffer) { _syncBuffer->read(); + + _scriptEngine.deserialize(_syncBuffer); + Time::ref().deserialize(_syncBuffer); _renderEngine.deserialize(_syncBuffer); + } } @@ -636,7 +648,8 @@ void OpenSpaceEngine::externalControlCallback(const char* receivedChars, { std::string script = std::string(receivedChars + 1); LINFO("Received Lua Script: '" << script << "'"); - _scriptEngine.runScript(script); + //_scriptEngine.runScript(script); + _scriptEngine.queueScript(script); } } } From 525b8a4de3bb17b11b7d62df1beef8e12e37ddf5 Mon Sep 17 00:00:00 2001 From: Joakim Kilby Date: Tue, 17 Feb 2015 12:00:19 +0100 Subject: [PATCH 4/7] LUA consola now queues scripts instead of runnings them --- src/interaction/luaconsole.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/interaction/luaconsole.cpp b/src/interaction/luaconsole.cpp index 9fb510221c..f6912f7d92 100644 --- a/src/interaction/luaconsole.cpp +++ b/src/interaction/luaconsole.cpp @@ -217,7 +217,8 @@ void LuaConsole::keyboardCallback(int key, int action) { // ENTER == run lua script else { if (_commands.at(_activeCommand) != "") { - OsEng.scriptEngine().runScript(_commands.at(_activeCommand)); + //OsEng.scriptEngine().runScript(_commands.at(_activeCommand)); + OsEng.scriptEngine().queueScript(_commands.at(_activeCommand)); if (!_commandsHistory.empty() && _commands.at(_activeCommand) != _commandsHistory.at(_commandsHistory.size() - 1)) _commandsHistory.push_back(_commands.at(_activeCommand)); From eafa4e2fe65d83e424c14d4102931a44d07a4bc6 Mon Sep 17 00:00:00 2001 From: Joakim Kilby Date: Tue, 17 Feb 2015 12:00:58 +0100 Subject: [PATCH 5/7] changed camera update (for object following) is now done in orbit function of interactionhandler --- src/interaction/interactionhandler.cpp | 28 +++++++++++++++++--------- src/interaction/mousecontroller.cpp | 4 ++-- src/rendering/renderengine.cpp | 7 ++++--- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index ba00fda1ee..5b552e75fd 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -552,26 +552,35 @@ void InteractionHandler::orbit(const float &dx, const float &dy, const float &dz transform = glm::rotate(dy * 10, cameraRight) * transform; transform = glm::rotate(dz * 10, _camera->viewDirection()) * transform; - // should be changed to something more dynamic =) + + //get "old" focus position + psc focus = _camera->focusPosition(); + + // get camera position + psc relative = _camera->position(); + //get relative vector + psc relative_focus_coordinate = relative - focus; + //rotate relative vector + relative_focus_coordinate = glm::inverse(transform) * relative_focus_coordinate.vec4(); + + //get new new position of focus node psc origin; if (_focusNode) { origin = _focusNode->worldPosition(); } - _camera->setFocusPosition(origin); - // the camera position - psc relative = _camera->position(); - psc relative_origin_coordinate = relative - origin; - relative_origin_coordinate = glm::inverse(transform) * relative_origin_coordinate.vec4(); - relative = origin + relative_origin_coordinate; //relative_origin_coordinate + origin; + //new camera position + relative = origin + relative_focus_coordinate; float bounds = 2.f * (_focusNode ? _focusNode->boundingSphere().lengthf() : 0.f); - psc target = relative + relative_origin_coordinate * dist;// *fmaxf(bounds, (1.f - d)); + psc target = relative + relative_focus_coordinate * dist; //don't fly into objects if ((target - origin).length() < bounds){ target = relative; } + + _camera->setFocusPosition(origin); _camera->setPosition(target); _camera->rotate(glm::quat_cast(transform)); @@ -866,7 +875,8 @@ void InteractionHandler::keyboardCallback(int key, int action) { _validKeyLua = true; auto ret = _keyLua.equal_range(key); for (auto it = ret.first; it != ret.second; ++it) { - OsEng.scriptEngine().runScript(it->second); + //OsEng.scriptEngine().runScript(it->second); + OsEng.scriptEngine().queueScript(it->second); if (!_validKeyLua) { break; } diff --git a/src/interaction/mousecontroller.cpp b/src/interaction/mousecontroller.cpp index ff45f21f75..e4c61e8d36 100644 --- a/src/interaction/mousecontroller.cpp +++ b/src/interaction/mousecontroller.cpp @@ -223,13 +223,13 @@ void OrbitalMouseController::scrollWheel(int pos) { void OrbitalMouseController::update(const double& dt){ - if (_leftMouseButtonDown || _rightMouseButtonDown || _middleMouseButtonDown){ + //if (_leftMouseButtonDown || _rightMouseButtonDown || _middleMouseButtonDown){ _handler->orbit( static_cast(_leftMouseButtonDown) * static_cast(dt) * _currentCursorDiff[MouseButtons::ButtonLeft].x * _rotationSpeed, static_cast(_leftMouseButtonDown) * static_cast(dt) * _currentCursorDiff[MouseButtons::ButtonLeft].y * _rotationSpeed, static_cast(_middleMouseButtonDown) * static_cast(dt) * _currentCursorDiff[MouseButtons::ButtonMiddle].x * _rotationSpeed, static_cast(_rightMouseButtonDown) * static_cast(dt) * _currentCursorDiff[MouseButtons::ButtonRight].y * _navigationSpeed); - } + //} // if (_leftMouseButtonDown){ // _handler->orbit(static_cast(dt)* _currentCursorDiff[MouseButtons::ButtonLeft].x * _rotationSpeed, static_cast(dt)* _currentCursorDiff[MouseButtons::ButtonLeft].y * _rotationSpeed, 0.f); diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 0aeef5e88a..8b72ce2410 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -306,7 +306,7 @@ void RenderEngine::postSynchronizationPreDraw() if (_mainCamera){ _mainCamera->postSynchronizationPreDraw(); } - + sgct_core::SGCTNode * thisNode = sgct_core::ClusterManager::instance()->getThisNodePtr(); bool updateAbuffer = false; for (unsigned int i = 0; i < thisNode->getNumberOfWindows(); i++) { @@ -330,6 +330,7 @@ void RenderEngine::postSynchronizationPreDraw() Time::ref().deltaTime(), _doPerformanceMeasurements }); + _sceneGraph->evaluate(_mainCamera); // clear the abuffer before rendering the scene @@ -337,9 +338,9 @@ void RenderEngine::postSynchronizationPreDraw() //Allow focus node to update camera (enables camera-following) //FIX LATER: THIS CAUSES MASTER NODE TO BE ONE FRAME AHEAD OF SLAVES - if (const SceneGraphNode* node = OsEng.ref().interactionHandler().focusNode()){ + /*if (const SceneGraphNode* node = OsEng.ref().interactionHandler().focusNode()){ node->updateCamera(_mainCamera); - } + }*/ } From 5b3742961ed5b2276468762d22e0151a006f6291 Mon Sep 17 00:00:00 2001 From: Joakim Kilby Date: Tue, 17 Feb 2015 13:29:45 +0100 Subject: [PATCH 6/7] added function for getting un-synchronized position of the camera (only meant to be used on master for calculation of camera matrix and position) --- include/openspace/util/camera.h | 2 ++ src/util/camera.cpp | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/include/openspace/util/camera.h b/include/openspace/util/camera.h index 601a0fbf21..fbef5e62d3 100644 --- a/include/openspace/util/camera.h +++ b/include/openspace/util/camera.h @@ -99,6 +99,8 @@ public: void setPosition(psc pos); const psc& position() const; + + const psc& unsynchedPosition() const; void setModelMatrix(glm::mat4 modelMatrix); const glm::mat4& modelMatrix() const; diff --git a/src/util/camera.cpp b/src/util/camera.cpp index d384de1b77..32d168604c 100644 --- a/src/util/camera.cpp +++ b/src/util/camera.cpp @@ -73,6 +73,10 @@ const psc& Camera::position() const return _syncedPosition; } +const psc& Camera::unsynchedPosition() const{ + return _localPosition; +} + void Camera::setModelMatrix(glm::mat4 modelMatrix){ _modelMatrix = std::move(modelMatrix); } From 7764553a3557ca91c26553a51d5019daafba12f8 Mon Sep 17 00:00:00 2001 From: Joakim Kilby Date: Tue, 17 Feb 2015 13:30:45 +0100 Subject: [PATCH 7/7] fixing bugs caused by merge --- src/engine/openspaceengine.cpp | 25 +- src/interaction/interactionhandler.cpp | 13 +- src/interaction/luaconsole.cpp | 5 +- src/rendering/renderengine.cpp | 1132 ++++++++++++------------ 4 files changed, 586 insertions(+), 589 deletions(-) diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 501bf5bf20..63de5e0ccd 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -520,23 +520,21 @@ void OpenSpaceEngine::preSynchronization() { //const double dt = sgct::Engine::instance()->getDt(); const double dt = sgct::Engine::instance()->getAvgDt(); - _interactionHandler->update(dt); Time::ref().advanceTime(dt); Time::ref().preSynchronization(); - _interactionHandler.update(dt); + _interactionHandler->update(dt); //_interactionHandler.lockControls(); - _scriptEngine.preSynchronization(); + _scriptEngine->preSynchronization(); _renderEngine->preSynchronization(); } } void OpenSpaceEngine::postSynchronizationPreDraw() { - _renderEngine->postSynchronizationPreDraw(); Time::ref().postSynchronizationPreDraw(); - _scriptEngine.postSynchronizationPreDraw(); - _renderEngine.postSynchronizationPreDraw(); + _scriptEngine->postSynchronizationPreDraw(); + _renderEngine->postSynchronizationPreDraw(); if (sgct::Engine::instance()->isMaster() && _gui->isEnabled()) { double posX, posY; @@ -642,10 +640,9 @@ void OpenSpaceEngine::mouseScrollWheelCallback(int pos) { void OpenSpaceEngine::encode() { if (_syncBuffer) { - _renderEngine->serialize(_syncBuffer); - _scriptEngine.serialize(_syncBuffer); Time::ref().serialize(_syncBuffer); - _renderEngine.serialize(_syncBuffer); + _scriptEngine->serialize(_syncBuffer); + _renderEngine->serialize(_syncBuffer); _syncBuffer->write(); } @@ -654,11 +651,10 @@ void OpenSpaceEngine::encode() { void OpenSpaceEngine::decode() { if (_syncBuffer) { _syncBuffer->read(); - _renderEngine->deserialize(_syncBuffer); - _scriptEngine.deserialize(_syncBuffer); Time::ref().deserialize(_syncBuffer); - _renderEngine.deserialize(_syncBuffer); + _scriptEngine->deserialize(_syncBuffer); + _renderEngine->deserialize(_syncBuffer); } } @@ -676,9 +672,8 @@ void OpenSpaceEngine::externalControlCallback(const char* receivedChars, { std::string script = std::string(receivedChars + 1); LINFO("Received Lua Script: '" << script << "'"); - _scriptEngine->runScript(script); - //_scriptEngine.runScript(script); - _scriptEngine.queueScript(script); + //_scriptEngine->runScript(script); + _scriptEngine->queueScript(script); } } } diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index b5ace527cf..68e3860d75 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -536,8 +536,12 @@ void InteractionHandler::orbit(const float &dx, const float &dy, const float &dz //get "old" focus position psc focus = _camera->focusPosition(); - // get camera position - psc relative = _camera->position(); + //// get camera position + //psc relative = _camera->position(); + + // get camera position (UNSYNCHRONIZED) + psc relative = _camera->unsynchedPosition(); + //get relative vector psc relative_focus_coordinate = relative - focus; //rotate relative vector @@ -855,9 +859,8 @@ void InteractionHandler::keyboardCallback(int key, int action) { _validKeyLua = true; auto ret = _keyLua.equal_range(key); for (auto it = ret.first; it != ret.second; ++it) { - OsEng.scriptEngine()->runScript(it->second); - //OsEng.scriptEngine().runScript(it->second); - OsEng.scriptEngine().queueScript(it->second); + //OsEng.scriptEngine()->runScript(it->second); + OsEng.scriptEngine()->queueScript(it->second); if (!_validKeyLua) { break; } diff --git a/src/interaction/luaconsole.cpp b/src/interaction/luaconsole.cpp index 9cfa7ac987..fcb15901a9 100644 --- a/src/interaction/luaconsole.cpp +++ b/src/interaction/luaconsole.cpp @@ -217,9 +217,8 @@ void LuaConsole::keyboardCallback(int key, int action) { // ENTER == run lua script else { if (_commands.at(_activeCommand) != "") { - OsEng.scriptEngine()->runScript(_commands.at(_activeCommand)); - //OsEng.scriptEngine().runScript(_commands.at(_activeCommand)); - OsEng.scriptEngine().queueScript(_commands.at(_activeCommand)); + //OsEng.scriptEngine()->runScript(_commands.at(_activeCommand)); + OsEng.scriptEngine()->queueScript(_commands.at(_activeCommand)); if (!_commandsHistory.empty() && _commands.at(_activeCommand) != _commandsHistory.at(_commandsHistory.size() - 1)) _commandsHistory.push_back(_commands.at(_activeCommand)); diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index f68c9672a7..0d85952dc9 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -74,660 +74,660 @@ namespace { namespace openspace { -const std::string RenderEngine::PerformanceMeasurementSharedData = - "OpenSpacePerformanceMeasurementSharedData"; + const std::string RenderEngine::PerformanceMeasurementSharedData = + "OpenSpacePerformanceMeasurementSharedData"; -namespace luascriptfunctions { + namespace luascriptfunctions { -/** - * \ingroup LuaScripts - * takeScreenshot(): - * Save the rendering to an image file - */ -int takeScreenshot(lua_State* L) { - int nArguments = lua_gettop(L); - if (nArguments != 0) - return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments); - OsEng.renderEngine()->takeScreenshot(); - return 0; -} + /** + * \ingroup LuaScripts + * takeScreenshot(): + * Save the rendering to an image file + */ + int takeScreenshot(lua_State* L) { + int nArguments = lua_gettop(L); + if (nArguments != 0) + return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments); + OsEng.renderEngine()->takeScreenshot(); + return 0; + } -/** -* \ingroup LuaScripts -* visualizeABuffer(bool): -* Toggle the visualization of the ABuffer -*/ -int visualizeABuffer(lua_State* L) { - int nArguments = lua_gettop(L); - if (nArguments != 1) - return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); + /** + * \ingroup LuaScripts + * visualizeABuffer(bool): + * Toggle the visualization of the ABuffer + */ + int visualizeABuffer(lua_State* L) { + int nArguments = lua_gettop(L); + if (nArguments != 1) + return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); - const int type = lua_type(L, -1); - bool b = lua_toboolean(L, -1) != 0; - OsEng.renderEngine()->toggleVisualizeABuffer(b); - return 0; -} + const int type = lua_type(L, -1); + bool b = lua_toboolean(L, -1) != 0; + OsEng.renderEngine()->toggleVisualizeABuffer(b); + return 0; + } -/** -* \ingroup LuaScripts -* visualizeABuffer(bool): -* Toggle the visualization of the ABuffer -*/ -int showRenderInformation(lua_State* L) { - int nArguments = lua_gettop(L); - if (nArguments != 1) - return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); + /** + * \ingroup LuaScripts + * visualizeABuffer(bool): + * Toggle the visualization of the ABuffer + */ + int showRenderInformation(lua_State* L) { + int nArguments = lua_gettop(L); + if (nArguments != 1) + return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); - const int type = lua_type(L, -1); - bool b = lua_toboolean(L, -1) != 0; - OsEng.renderEngine()->toggleInfoText(b); - return 0; -} + const int type = lua_type(L, -1); + bool b = lua_toboolean(L, -1) != 0; + OsEng.renderEngine()->toggleInfoText(b); + return 0; + } -/** -* \ingroup LuaScripts -* visualizeABuffer(bool): -* Toggle the visualization of the ABuffer -*/ -int setPerformanceMeasurement(lua_State* L) { - int nArguments = lua_gettop(L); - if (nArguments != 1) - return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); + /** + * \ingroup LuaScripts + * visualizeABuffer(bool): + * Toggle the visualization of the ABuffer + */ + int setPerformanceMeasurement(lua_State* L) { + int nArguments = lua_gettop(L); + if (nArguments != 1) + return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); - bool b = lua_toboolean(L, -1) != 0; - OsEng.renderEngine()->setPerformanceMeasurements(b); - return 0; -} + bool b = lua_toboolean(L, -1) != 0; + OsEng.renderEngine()->setPerformanceMeasurements(b); + return 0; + } -} // namespace luascriptfunctions + } // namespace luascriptfunctions -RenderEngine::RenderEngine() - : _mainCamera(nullptr) - , _sceneGraph(nullptr) - , _abuffer(nullptr) - , _log(nullptr) - , _showInfo(true) - , _showScreenLog(true) - , _takeScreenshot(false) - , _doPerformanceMeasurements(false) - , _performanceMemory(nullptr) - , _visualizeABuffer(false) - , _visualizer(nullptr) -{ -} + RenderEngine::RenderEngine() + : _mainCamera(nullptr) + , _sceneGraph(nullptr) + , _abuffer(nullptr) + , _log(nullptr) + , _showInfo(true) + , _showScreenLog(true) + , _takeScreenshot(false) + , _doPerformanceMeasurements(false) + , _performanceMemory(nullptr) + , _visualizeABuffer(false) + , _visualizer(nullptr) + { + } -RenderEngine::~RenderEngine() -{ - if(_abuffer) - delete _abuffer; - _abuffer = nullptr; + RenderEngine::~RenderEngine() + { + if (_abuffer) + delete _abuffer; + _abuffer = nullptr; - if(_sceneGraph) - delete _sceneGraph; - _sceneGraph = nullptr; + if (_sceneGraph) + delete _sceneGraph; + _sceneGraph = nullptr; - delete _mainCamera; - if (_visualizer) - delete _visualizer; + delete _mainCamera; + if (_visualizer) + delete _visualizer; - delete _performanceMemory; - if (ghoul::SharedMemory::exists(PerformanceMeasurementSharedData)) - ghoul::SharedMemory::remove(PerformanceMeasurementSharedData); -} + delete _performanceMemory; + if (ghoul::SharedMemory::exists(PerformanceMeasurementSharedData)) + ghoul::SharedMemory::remove(PerformanceMeasurementSharedData); + } -bool RenderEngine::initialize() -{ - generateGlslConfig(); + bool RenderEngine::initialize() + { + generateGlslConfig(); - // init camera and set temporary position and scaling - _mainCamera = new Camera(); - _mainCamera->setScaling(glm::vec2(1.0, -8.0)); - _mainCamera->setPosition(psc(0.f, 0.f, 1.499823f, 11.f)); - OsEng.interactionHandler()->setCamera(_mainCamera); + // init camera and set temporary position and scaling + _mainCamera = new Camera(); + _mainCamera->setScaling(glm::vec2(1.0, -8.0)); + _mainCamera->setPosition(psc(0.f, 0.f, 1.499823f, 11.f)); + OsEng.interactionHandler()->setCamera(_mainCamera); #ifdef GHOUL_USE_DEVIL - ghoul::io::TextureReader::ref().addReader(new ghoul::io::impl::TextureReaderDevIL); + ghoul::io::TextureReader::ref().addReader(new ghoul::io::impl::TextureReaderDevIL); #endif // GHOUL_USE_DEVIL #ifdef GHOUL_USE_FREEIMAGE - ghoul::io::TextureReader::ref().addReader(new ghoul::io::impl::TextureReaderFreeImage); + ghoul::io::TextureReader::ref().addReader(new ghoul::io::impl::TextureReaderFreeImage); #endif // GHOUL_USE_FREEIMAGE - ghoul::io::TextureReader::ref().addReader(new ghoul::io::impl::TextureReaderCMAP); - + ghoul::io::TextureReader::ref().addReader(new ghoul::io::impl::TextureReaderCMAP); + #if ABUFFER_IMPLEMENTATION == ABUFFER_FRAMEBUFFER - _abuffer = new ABufferFramebuffer(); + _abuffer = new ABufferFramebuffer(); #elif ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED - _abuffer = new ABufferSingleLinked(); + _abuffer = new ABufferSingleLinked(); #elif ABUFFER_IMPLEMENTATION == ABUFFER_FIXED - _abuffer = new ABufferFixed(); + _abuffer = new ABufferFixed(); #elif ABUFFER_IMPLEMENTATION == ABUFFER_DYNAMIC - _abuffer = new ABufferDynamic(); + _abuffer = new ABufferDynamic(); #endif - return true; -} + return true; + } -bool RenderEngine::initializeGL() -{ - // LDEBUG("RenderEngine::initializeGL()"); - sgct::SGCTWindow* wPtr = sgct::Engine::instance()->getActiveWindowPtr(); + bool RenderEngine::initializeGL() + { + // LDEBUG("RenderEngine::initializeGL()"); + sgct::SGCTWindow* wPtr = sgct::Engine::instance()->getActiveWindowPtr(); - // TODO: Fix the power scaled coordinates in such a way that these - // values can be set to more realistic values + // TODO: Fix the power scaled coordinates in such a way that these + // values can be set to more realistic values - // set the close clip plane and the far clip plane to extreme values while in - // development - sgct::Engine::instance()->setNearAndFarClippingPlanes(0.01f,10000.0f); - // sgct::Engine::instance()->setNearAndFarClippingPlanes(0.1f, 30.0f); + // set the close clip plane and the far clip plane to extreme values while in + // development + sgct::Engine::instance()->setNearAndFarClippingPlanes(0.01f, 10000.0f); + // sgct::Engine::instance()->setNearAndFarClippingPlanes(0.1f, 30.0f); - // calculating the maximum field of view for the camera, used to - // determine visibility of objects in the scene graph - if (wPtr->isUsingFisheyeRendering()) { - // fisheye mode, looking upwards to the "dome" - glm::vec4 upDirection(0, 1, 0, 0); + // calculating the maximum field of view for the camera, used to + // determine visibility of objects in the scene graph + if (wPtr->isUsingFisheyeRendering()) { + // fisheye mode, looking upwards to the "dome" + glm::vec4 upDirection(0, 1, 0, 0); - // get the tilt and rotate the view - const float tilt = wPtr->getFisheyeTilt(); - glm::mat4 tiltMatrix - = glm::rotate(glm::mat4(1.0f), tilt, glm::vec3(1.0f, 0.0f, 0.0f)); - const glm::vec4 viewdir = tiltMatrix * upDirection; + // get the tilt and rotate the view + const float tilt = wPtr->getFisheyeTilt(); + glm::mat4 tiltMatrix + = glm::rotate(glm::mat4(1.0f), tilt, glm::vec3(1.0f, 0.0f, 0.0f)); + const glm::vec4 viewdir = tiltMatrix * upDirection; - // set the tilted view and the FOV - _mainCamera->setCameraDirection(glm::vec3(viewdir[0], viewdir[1], viewdir[2])); - _mainCamera->setMaxFov(wPtr->getFisheyeFOV()); - _mainCamera->setLookUpVector(glm::vec3(0.0, 1.0, 0.0)); - } else { - // get corner positions, calculating the forth to easily calculate center - glm::vec3 corners[4]; - corners[0] = wPtr->getCurrentViewport()->getViewPlaneCoords( - sgct_core::Viewport::LowerLeft); - corners[1] = wPtr->getCurrentViewport()->getViewPlaneCoords( - sgct_core::Viewport::UpperLeft); - corners[2] = wPtr->getCurrentViewport()->getViewPlaneCoords( - sgct_core::Viewport::UpperRight); - corners[3] = glm::vec3(corners[2][0], corners[0][1], corners[2][2]); - const glm::vec3 center = (corners[0] + corners[1] + corners[2] + corners[3]) - / 4.0f; + // set the tilted view and the FOV + _mainCamera->setCameraDirection(glm::vec3(viewdir[0], viewdir[1], viewdir[2])); + _mainCamera->setMaxFov(wPtr->getFisheyeFOV()); + _mainCamera->setLookUpVector(glm::vec3(0.0, 1.0, 0.0)); + } + else { + // get corner positions, calculating the forth to easily calculate center + glm::vec3 corners[4]; + corners[0] = wPtr->getCurrentViewport()->getViewPlaneCoords( + sgct_core::Viewport::LowerLeft); + corners[1] = wPtr->getCurrentViewport()->getViewPlaneCoords( + sgct_core::Viewport::UpperLeft); + corners[2] = wPtr->getCurrentViewport()->getViewPlaneCoords( + sgct_core::Viewport::UpperRight); + corners[3] = glm::vec3(corners[2][0], corners[0][1], corners[2][2]); + const glm::vec3 center = (corners[0] + corners[1] + corners[2] + corners[3]) + / 4.0f; #if 0 -// @TODO Remove the ifdef when the next SGCT version is released that requests the -// getUserPtr to get a name parameter ---abock + // @TODO Remove the ifdef when the next SGCT version is released that requests the + // getUserPtr to get a name parameter ---abock - // set the eye position, useful during rendering - const glm::vec3 eyePosition - = sgct_core::ClusterManager::instance()->getUserPtr("")->getPos(); + // set the eye position, useful during rendering + const glm::vec3 eyePosition + = sgct_core::ClusterManager::instance()->getUserPtr("")->getPos(); #else - const glm::vec3 eyePosition - = sgct_core::ClusterManager::instance()->getUserPtr()->getPos(); + const glm::vec3 eyePosition + = sgct_core::ClusterManager::instance()->getUserPtr()->getPos(); #endif - // get viewdirection, stores the direction in the camera, used for culling - const glm::vec3 viewdir = glm::normalize(eyePosition - center); - _mainCamera->setCameraDirection(-viewdir); - _mainCamera->setLookUpVector(glm::vec3(0.0, 1.0, 0.0)); + // get viewdirection, stores the direction in the camera, used for culling + const glm::vec3 viewdir = glm::normalize(eyePosition - center); + _mainCamera->setCameraDirection(-viewdir); + _mainCamera->setLookUpVector(glm::vec3(0.0, 1.0, 0.0)); - // set the initial fov to be 0.0 which means everything will be culled - float maxFov = 0.0f; + // set the initial fov to be 0.0 which means everything will be culled + float maxFov = 0.0f; - // for each corner - for (int i = 0; i < 4; ++i) { - // calculate radians to corner - glm::vec3 dir = glm::normalize(eyePosition - corners[i]); - float radsbetween = acos(glm::dot(viewdir, dir)) - / (glm::length(viewdir) * glm::length(dir)); + // for each corner + for (int i = 0; i < 4; ++i) { + // calculate radians to corner + glm::vec3 dir = glm::normalize(eyePosition - corners[i]); + float radsbetween = acos(glm::dot(viewdir, dir)) + / (glm::length(viewdir) * glm::length(dir)); - // the angle to a corner is larger than the current maxima - if (radsbetween > maxFov) { - maxFov = radsbetween; - } - } - _mainCamera->setMaxFov(maxFov); - } - - _abuffer->initialize(); - - _log = new ScreenLog(); - ghoul::logging::LogManager::ref().addLog(_log); + // the angle to a corner is larger than the current maxima + if (radsbetween > maxFov) { + maxFov = radsbetween; + } + } + _mainCamera->setMaxFov(maxFov); + } - _visualizer = new ABufferVisualizer(); + _abuffer->initialize(); - // successful init - return true; -} + _log = new ScreenLog(); + ghoul::logging::LogManager::ref().addLog(_log); -void RenderEngine::preSynchronization(){ - if (_mainCamera){ - _mainCamera->preSynchronization(); + _visualizer = new ABufferVisualizer(); + + // successful init + return true; } -} -void RenderEngine::postSynchronizationPreDraw() -{ - if (_mainCamera){ - _mainCamera->postSynchronizationPreDraw(); - } - - sgct_core::SGCTNode * thisNode = sgct_core::ClusterManager::instance()->getThisNodePtr(); - bool updateAbuffer = false; - for (unsigned int i = 0; i < thisNode->getNumberOfWindows(); i++) { - if (sgct::Engine::instance()->getWindowPtr(i)->isWindowResized()) { - updateAbuffer = true; - break; + void RenderEngine::preSynchronization(){ + if (_mainCamera){ + _mainCamera->preSynchronization(); } } - if (updateAbuffer) { - generateGlslConfig(); - _abuffer->reinitialize(); - } - - // converts the quaternion used to rotation matrices - _mainCamera->compileViewRotationMatrix(); - UpdateData a = { Time::ref().currentTime(), Time::ref().deltaTime() }; - // update and evaluate the scene starting from the root node - _sceneGraph->update({ - Time::ref().currentTime(), - Time::ref().deltaTime(), - _doPerformanceMeasurements - }); + void RenderEngine::postSynchronizationPreDraw() + { + if (_mainCamera){ + _mainCamera->postSynchronizationPreDraw(); + } - _sceneGraph->evaluate(_mainCamera); + sgct_core::SGCTNode * thisNode = sgct_core::ClusterManager::instance()->getThisNodePtr(); + bool updateAbuffer = false; + for (unsigned int i = 0; i < thisNode->getNumberOfWindows(); i++) { + if (sgct::Engine::instance()->getWindowPtr(i)->isWindowResized()) { + updateAbuffer = true; + break; + } + } + if (updateAbuffer) { + generateGlslConfig(); + _abuffer->reinitialize(); + } - // clear the abuffer before rendering the scene - _abuffer->clear(); - - //Allow focus node to update camera (enables camera-following) - //FIX LATER: THIS CAUSES MASTER NODE TO BE ONE FRAME AHEAD OF SLAVES - if (const SceneGraphNode* node = OsEng.ref().interactionHandler()->focusNode()){ - /*if (const SceneGraphNode* node = OsEng.ref().interactionHandler().focusNode()){ - node->updateCamera(_mainCamera); - }*/ - -} + // converts the quaternion used to rotation matrices + _mainCamera->compileViewRotationMatrix(); + UpdateData a = { Time::ref().currentTime(), Time::ref().deltaTime() }; -void RenderEngine::render() -{ - // We need the window pointer - sgct::SGCTWindow* w = sgct::Engine::instance()->getActiveWindowPtr(); - if (w->isUsingFisheyeRendering()) - _abuffer->clear(); - - // SGCT resets certain settings -#ifndef __APPLE__ - glDisable(GL_DEPTH_TEST); - glDisable(GL_CULL_FACE); - glDisable(GL_BLEND); -#else - glEnable(GL_DEPTH_TEST); - glDisable(GL_CULL_FACE); - glDisable(GL_BLEND); -#endif - // setup the camera for the current frame - -#if 0 -// @TODO: Use this as soon as the new SGCT version is available ---abock - const glm::vec3 eyePosition - = sgct_core::ClusterManager::instance()->getUserPtr("")->getPos(); -#else - const glm::vec3 eyePosition - = sgct_core::ClusterManager::instance()->getUserPtr()->getPos(); -#endif - //@CHECK does the dome disparity disappear if this line disappears? ---abock - const glm::mat4 view - = glm::translate(glm::mat4(1.0), - eyePosition); // make sure the eye is in the center - _mainCamera->setViewProjectionMatrix( - sgct::Engine::instance()->getActiveModelViewProjectionMatrix() * view); - - _mainCamera->setModelMatrix( - sgct::Engine::instance()->getModelMatrix()); - - _mainCamera->setViewMatrix( - sgct::Engine::instance()->getActiveViewMatrix()* view); - - _mainCamera->setProjectionMatrix( - sgct::Engine::instance()->getActiveProjectionMatrix()); - - - // render the scene starting from the root node - if (!_visualizeABuffer) { - _abuffer->preRender(); - _sceneGraph->render({ - *_mainCamera, - psc(), + // update and evaluate the scene starting from the root node + _sceneGraph->update({ + Time::ref().currentTime(), + Time::ref().deltaTime(), _doPerformanceMeasurements }); - _abuffer->postRender(); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - _abuffer->resolve(); - glDisable(GL_BLEND); + _sceneGraph->evaluate(_mainCamera); + + // clear the abuffer before rendering the scene + _abuffer->clear(); + + //Allow focus node to update camera (enables camera-following) + //FIX LATER: THIS CAUSES MASTER NODE TO BE ONE FRAME AHEAD OF SLAVES + //if (const SceneGraphNode* node = OsEng.ref().interactionHandler().focusNode()){ + //node->updateCamera(_mainCamera); + //} + } - else { - _visualizer->render(); - } - + + void RenderEngine::render() + { + // We need the window pointer + sgct::SGCTWindow* w = sgct::Engine::instance()->getActiveWindowPtr(); + if (w->isUsingFisheyeRendering()) + _abuffer->clear(); + + // SGCT resets certain settings +#ifndef __APPLE__ + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + glDisable(GL_BLEND); +#else + glEnable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + glDisable(GL_BLEND); +#endif + // setup the camera for the current frame + +#if 0 + // @TODO: Use this as soon as the new SGCT version is available ---abock + const glm::vec3 eyePosition + = sgct_core::ClusterManager::instance()->getUserPtr("")->getPos(); +#else + const glm::vec3 eyePosition + = sgct_core::ClusterManager::instance()->getUserPtr()->getPos(); +#endif + //@CHECK does the dome disparity disappear if this line disappears? ---abock + const glm::mat4 view + = glm::translate(glm::mat4(1.0), + eyePosition); // make sure the eye is in the center + _mainCamera->setViewProjectionMatrix( + sgct::Engine::instance()->getActiveModelViewProjectionMatrix() * view); + + _mainCamera->setModelMatrix( + sgct::Engine::instance()->getModelMatrix()); + + _mainCamera->setViewMatrix( + sgct::Engine::instance()->getActiveViewMatrix()* view); + + _mainCamera->setProjectionMatrix( + sgct::Engine::instance()->getActiveProjectionMatrix()); + + + // render the scene starting from the root node + if (!_visualizeABuffer) { + _abuffer->preRender(); + _sceneGraph->render({ + *_mainCamera, + psc(), + _doPerformanceMeasurements + }); + _abuffer->postRender(); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + _abuffer->resolve(); + glDisable(GL_BLEND); + } + else { + _visualizer->render(); + } + #if 1 - - // Print some useful information on the master viewport - if (sgct::Engine::instance()->isMaster() && ! w->isUsingFisheyeRendering()) { - // TODO: Adjust font_size properly when using retina screen - const int font_size_mono = 10; - const int font_size_light = 8; - const int font_with_light = static_cast(font_size_light*0.7); - const sgct_text::Font* fontLight = sgct_text::FontManager::instance()->getFont(constants::fonts::keyLight, font_size_light); - const sgct_text::Font* fontMono = sgct_text::FontManager::instance()->getFont(constants::fonts::keyMono, font_size_mono); - - if (_showInfo) { - const sgct_text::Font* font = fontMono; - int x1, xSize, y1, ySize; - sgct::Engine::instance()->getActiveWindowPtr()->getCurrentViewportPixelCoords(x1, y1, xSize, ySize); - int startY = ySize - 2 * font_size_mono; - const glm::vec2 scaling = _mainCamera->scaling(); - const glm::vec3 viewdirection = _mainCamera->viewDirection(); - const psc position = _mainCamera->position(); - const psc origin = OsEng.interactionHandler()->focusNode()->worldPosition(); - const PowerScaledScalar pssl = (position - origin).length(); + // Print some useful information on the master viewport + if (sgct::Engine::instance()->isMaster() && !w->isUsingFisheyeRendering()) { - // GUI PRINT -// Using a macro to shorten line length and increase readability + // TODO: Adjust font_size properly when using retina screen + const int font_size_mono = 10; + const int font_size_light = 8; + const int font_with_light = static_cast(font_size_light*0.7); + const sgct_text::Font* fontLight = sgct_text::FontManager::instance()->getFont(constants::fonts::keyLight, font_size_light); + const sgct_text::Font* fontMono = sgct_text::FontManager::instance()->getFont(constants::fonts::keyMono, font_size_mono); + + if (_showInfo) { + const sgct_text::Font* font = fontMono; + int x1, xSize, y1, ySize; + sgct::Engine::instance()->getActiveWindowPtr()->getCurrentViewportPixelCoords(x1, y1, xSize, ySize); + int startY = ySize - 2 * font_size_mono; + const glm::vec2 scaling = _mainCamera->scaling(); + const glm::vec3 viewdirection = _mainCamera->viewDirection(); + const psc position = _mainCamera->position(); + const psc origin = OsEng.interactionHandler()->focusNode()->worldPosition(); + const PowerScaledScalar pssl = (position - origin).length(); + + // GUI PRINT + // Using a macro to shorten line length and increase readability #define PrintText(i, format, ...) Freetype::print(font, 10.f, static_cast(startY - font_size_mono * i * 2), format, __VA_ARGS__); - int i = 0; - PrintText(i++, "Date: %s", Time::ref().currentTimeUTC().c_str()); - PrintText(i++, "Avg. Frametime: %.5f", sgct::Engine::instance()->getAvgDt()); - PrintText(i++, "Drawtime: %.5f", sgct::Engine::instance()->getDrawTime()); - PrintText(i++, "Frametime: %.5f", sgct::Engine::instance()->getDt()); - PrintText(i++, "Origin: (% .5f, % .5f, % .5f, % .5f)", origin[0], origin[1], origin[2], origin[3]); - PrintText(i++, "Cam pos: (% .5f, % .5f, % .5f, % .5f)", position[0], position[1], position[2], position[3]); - PrintText(i++, "View dir: (% .5f, % .5f, % .5f)", viewdirection[0], viewdirection[1], viewdirection[2]); - PrintText(i++, "Cam->origin: (% .15f, % .4f)", pssl[0], pssl[1]); - PrintText(i++, "Scaling: (% .5f, % .5f)", scaling[0], scaling[1]); + int i = 0; + PrintText(i++, "Date: %s", Time::ref().currentTimeUTC().c_str()); + PrintText(i++, "Avg. Frametime: %.5f", sgct::Engine::instance()->getAvgDt()); + PrintText(i++, "Drawtime: %.5f", sgct::Engine::instance()->getDrawTime()); + PrintText(i++, "Frametime: %.5f", sgct::Engine::instance()->getDt()); + PrintText(i++, "Origin: (% .5f, % .5f, % .5f, % .5f)", origin[0], origin[1], origin[2], origin[3]); + PrintText(i++, "Cam pos: (% .5f, % .5f, % .5f, % .5f)", position[0], position[1], position[2], position[3]); + PrintText(i++, "View dir: (% .5f, % .5f, % .5f)", viewdirection[0], viewdirection[1], viewdirection[2]); + PrintText(i++, "Cam->origin: (% .15f, % .4f)", pssl[0], pssl[1]); + PrintText(i++, "Scaling: (% .5f, % .5f)", scaling[0], scaling[1]); #undef PrintText - } - - if (_showScreenLog) - { - const sgct_text::Font* font = fontLight; - const int max = 10; - const int category_length = 20; - const int msg_length = 140; - const float ttl = 15.f; - const float fade = 5.f; - auto entries = _log->last(max); - - const glm::vec4 white(0.9, 0.9, 0.9, 1); - const glm::vec4 red(1, 0, 0, 1); - const glm::vec4 yellow(1, 1, 0, 1); - const glm::vec4 green(0, 1, 0, 1); - const glm::vec4 blue(0, 0, 1, 1); - - size_t nr = 1; - for (auto& it = entries.first; it != entries.second; ++it) { - const ScreenLog::LogEntry* e = &(*it); - - const double t = sgct::Engine::instance()->getTime(); - float diff = static_cast(t - e->timeStamp); - - // Since all log entries are ordered, once one is exceeding TTL, all have - if (diff > ttl) - break; - - float alpha = 1; - float ttf = ttl - fade; - if (diff > ttf) { - diff = diff - ttf; - float p = 0.8f - diff / fade; - alpha = (p <= 0.f) ? 0.f : pow(p, 0.3f); } - // Since all log entries are ordered, once one exceeds alpha, all have - if (alpha <= 0.0) - break; + if (_showScreenLog) + { + const sgct_text::Font* font = fontLight; + const int max = 10; + const int category_length = 20; + const int msg_length = 140; + const float ttl = 15.f; + const float fade = 5.f; + auto entries = _log->last(max); - const std::string lvl = "(" + ghoul::logging::LogManager::stringFromLevel(e->level) + ")"; - const std::string& message = e->message.substr(0, msg_length); - nr += std::count(message.begin(), message.end(), '\n'); + const glm::vec4 white(0.9, 0.9, 0.9, 1); + const glm::vec4 red(1, 0, 0, 1); + const glm::vec4 yellow(1, 1, 0, 1); + const glm::vec4 green(0, 1, 0, 1); + const glm::vec4 blue(0, 0, 1, 1); - Freetype::print(font, 10.f, static_cast(font_size_light * nr * 2), white*alpha, - "%-14s %s%s", // Format - e->timeString.c_str(), // Time string - e->category.substr(0, category_length).c_str(), // Category string (up to category_length) - e->category.length() > 20 ? "..." : ""); // Pad category with "..." if exceeds category_length + size_t nr = 1; + for (auto& it = entries.first; it != entries.second; ++it) { + const ScreenLog::LogEntry* e = &(*it); - glm::vec4 color = white; - if (e->level == ghoul::logging::LogManager::LogLevel::Debug) - color = green; - if (e->level == ghoul::logging::LogManager::LogLevel::Warning) - color = yellow; - if (e->level == ghoul::logging::LogManager::LogLevel::Error) - color = red; - if (e->level == ghoul::logging::LogManager::LogLevel::Fatal) - color = blue; + const double t = sgct::Engine::instance()->getTime(); + float diff = static_cast(t - e->timeStamp); - Freetype::print(font, static_cast(10 + 39 * font_with_light), static_cast(font_size_light * nr * 2), color*alpha, "%s", lvl.c_str()); + // Since all log entries are ordered, once one is exceeding TTL, all have + if (diff > ttl) + break; - - Freetype::print(font, static_cast(10 + 53 * font_with_light), static_cast(font_size_light * nr * 2), white*alpha, "%s", message.c_str()); - ++nr; + float alpha = 1; + float ttf = ttl - fade; + if (diff > ttf) { + diff = diff - ttf; + float p = 0.8f - diff / fade; + alpha = (p <= 0.f) ? 0.f : pow(p, 0.3f); + } + + // Since all log entries are ordered, once one exceeds alpha, all have + if (alpha <= 0.0) + break; + + const std::string lvl = "(" + ghoul::logging::LogManager::stringFromLevel(e->level) + ")"; + const std::string& message = e->message.substr(0, msg_length); + nr += std::count(message.begin(), message.end(), '\n'); + + Freetype::print(font, 10.f, static_cast(font_size_light * nr * 2), white*alpha, + "%-14s %s%s", // Format + e->timeString.c_str(), // Time string + e->category.substr(0, category_length).c_str(), // Category string (up to category_length) + e->category.length() > 20 ? "..." : ""); // Pad category with "..." if exceeds category_length + + glm::vec4 color = white; + if (e->level == ghoul::logging::LogManager::LogLevel::Debug) + color = green; + if (e->level == ghoul::logging::LogManager::LogLevel::Warning) + color = yellow; + if (e->level == ghoul::logging::LogManager::LogLevel::Error) + color = red; + if (e->level == ghoul::logging::LogManager::LogLevel::Fatal) + color = blue; + + Freetype::print(font, static_cast(10 + 39 * font_with_light), static_cast(font_size_light * nr * 2), color*alpha, "%s", lvl.c_str()); + + + Freetype::print(font, static_cast(10 + 53 * font_with_light), static_cast(font_size_light * nr * 2), white*alpha, "%s", message.c_str()); + ++nr; + } + } + } +#endif + } + + void RenderEngine::postDraw() { + if (_takeScreenshot) { + sgct::Engine::instance()->takeScreenshot(); + _takeScreenshot = false; + } + + if (_doPerformanceMeasurements) + storePerformanceMeasurements(); + } + + void RenderEngine::takeScreenshot() { + _takeScreenshot = true; + } + + void RenderEngine::toggleVisualizeABuffer(bool b) { + _visualizeABuffer = b; + if (!_visualizeABuffer) + return; + + std::vector _d = _abuffer->pixelData(); + _visualizer->updateData(_d); + } + + + void RenderEngine::toggleInfoText(bool b) { + _showInfo = b; + } + + SceneGraph* RenderEngine::sceneGraph() + { + // TODO custom assert (ticket #5) + assert(_sceneGraph); + return _sceneGraph; + } + + void RenderEngine::setSceneGraph(SceneGraph* sceneGraph) + { + _sceneGraph = sceneGraph; + } + + void RenderEngine::serialize(SyncBuffer* syncBuffer) { + if (_mainCamera){ + _mainCamera->serialize(syncBuffer); } } - } -#endif -} -void RenderEngine::postDraw() { - if (_takeScreenshot) { - sgct::Engine::instance()->takeScreenshot(); - _takeScreenshot = false; - } + void RenderEngine::deserialize(SyncBuffer* syncBuffer) { + if (_mainCamera){ + _mainCamera->deserialize(syncBuffer); + } + } - if (_doPerformanceMeasurements) - storePerformanceMeasurements(); -} + Camera* RenderEngine::camera() const { + return _mainCamera; + } -void RenderEngine::takeScreenshot() { - _takeScreenshot = true; -} + ABuffer* RenderEngine::abuffer() const { + return _abuffer; + } -void RenderEngine::toggleVisualizeABuffer(bool b) { - _visualizeABuffer = b; - if (!_visualizeABuffer) - return; + void RenderEngine::generateGlslConfig() { + LDEBUG("Generating GLSLS config, expect shader recompilation"); + int xSize = sgct::Engine::instance()->getActiveWindowPtr()->getXFramebufferResolution();; + int ySize = sgct::Engine::instance()->getActiveWindowPtr()->getYFramebufferResolution();; - std::vector _d = _abuffer->pixelData(); - _visualizer->updateData(_d); -} - - -void RenderEngine::toggleInfoText(bool b) { - _showInfo = b; -} - -SceneGraph* RenderEngine::sceneGraph() -{ - // TODO custom assert (ticket #5) - assert(_sceneGraph); - return _sceneGraph; -} - -void RenderEngine::setSceneGraph(SceneGraph* sceneGraph) -{ - _sceneGraph = sceneGraph; -} - -void RenderEngine::serialize(SyncBuffer* syncBuffer) { - if (_mainCamera){ - _mainCamera->serialize(syncBuffer); - } -} - -void RenderEngine::deserialize(SyncBuffer* syncBuffer) { - if (_mainCamera){ - _mainCamera->deserialize(syncBuffer); - } -} - -Camera* RenderEngine::camera() const { - return _mainCamera; -} - -ABuffer* RenderEngine::abuffer() const { - return _abuffer; -} - -void RenderEngine::generateGlslConfig() { - LDEBUG("Generating GLSLS config, expect shader recompilation"); - int xSize = sgct::Engine::instance()->getActiveWindowPtr()->getXFramebufferResolution();; - int ySize = sgct::Engine::instance()->getActiveWindowPtr()->getYFramebufferResolution();; - - // TODO: Make this file creation dynamic and better in every way - // TODO: If the screen size changes it is enough if this file is regenerated to - // recompile all necessary files - std::ofstream os(absPath("${SHADERS_GENERATED}/constants.hglsl")); - os << "#ifndef CONSTANTS_HGLSL\n" - << "#define CONSTANTS_HGLSL\n" - << "#define SCREEN_WIDTH " << xSize << "\n" - << "#define SCREEN_HEIGHT " << ySize << "\n" - << "#define MAX_LAYERS " << ABuffer::MAX_LAYERS << "\n" - << "#define ABUFFER_FRAMEBUFFER " << ABUFFER_FRAMEBUFFER << "\n" - << "#define ABUFFER_SINGLE_LINKED " << ABUFFER_SINGLE_LINKED << "\n" - << "#define ABUFFER_FIXED " << ABUFFER_FIXED << "\n" - << "#define ABUFFER_DYNAMIC " << ABUFFER_DYNAMIC << "\n" - << "#define ABUFFER_IMPLEMENTATION " << ABUFFER_IMPLEMENTATION << "\n"; -// System specific + // TODO: Make this file creation dynamic and better in every way + // TODO: If the screen size changes it is enough if this file is regenerated to + // recompile all necessary files + std::ofstream os(absPath("${SHADERS_GENERATED}/constants.hglsl")); + os << "#ifndef CONSTANTS_HGLSL\n" + << "#define CONSTANTS_HGLSL\n" + << "#define SCREEN_WIDTH " << xSize << "\n" + << "#define SCREEN_HEIGHT " << ySize << "\n" + << "#define MAX_LAYERS " << ABuffer::MAX_LAYERS << "\n" + << "#define ABUFFER_FRAMEBUFFER " << ABUFFER_FRAMEBUFFER << "\n" + << "#define ABUFFER_SINGLE_LINKED " << ABUFFER_SINGLE_LINKED << "\n" + << "#define ABUFFER_FIXED " << ABUFFER_FIXED << "\n" + << "#define ABUFFER_DYNAMIC " << ABUFFER_DYNAMIC << "\n" + << "#define ABUFFER_IMPLEMENTATION " << ABUFFER_IMPLEMENTATION << "\n"; + // System specific #ifdef WIN32 - os << "#define WIN32\n"; + os << "#define WIN32\n"; #endif #ifdef __APPLE__ - os << "#define APPLE\n"; + os << "#define APPLE\n"; #endif #ifdef __linux__ - os << "#define linux\n"; + os << "#define linux\n"; #endif - os << "#endif\n"; + os << "#endif\n"; - os.close(); -} - -scripting::ScriptEngine::LuaLibrary RenderEngine::luaLibrary() { - return { - "", - { - { - "takeScreenshot", - &luascriptfunctions::takeScreenshot, - "", - "Renders the current image to a file on disk" - }, - { - "visualizeABuffer", - &luascriptfunctions::visualizeABuffer, - "bool", - "Toggles the visualization of the ABuffer" - }, - { - "showRenderInformation", - &luascriptfunctions::showRenderInformation, - "bool", - "Toggles the showing of render information on-screen text" - }, - { - "setPerformanceMeasurement", - &luascriptfunctions::setPerformanceMeasurement, - "bool", - "Sets the performance measurements" - } - }, - }; -} - -void RenderEngine::setPerformanceMeasurements(bool performanceMeasurements) { - _doPerformanceMeasurements = performanceMeasurements; -} - -bool RenderEngine::doesPerformanceMeasurements() const { - return _doPerformanceMeasurements; -} - -void RenderEngine::storePerformanceMeasurements() { - const int8_t Version = 0; - const int nValues = 250; - const int lengthName = 256; - const int maxValues = 50; - - struct PerformanceLayout { - int8_t version; - int32_t nValuesPerEntry; - int32_t nEntries; - int32_t maxNameLength; - int32_t maxEntries; - - struct PerformanceLayoutEntry { - char name[lengthName]; - float renderTime[nValues]; - float updateRenderable[nValues]; - float updateEphemeris[nValues]; - - int32_t currentRenderTime; - int32_t currentUpdateRenderable; - int32_t currentUpdateEphemeris; - }; - - PerformanceLayoutEntry entries[maxValues]; - }; - - const int nNodes = static_cast(sceneGraph()->allSceneGraphNodes().size()); - if (!_performanceMemory) { - - // Compute the total size - const int totalSize = sizeof(int8_t) + 4 * sizeof(int32_t) + - maxValues * sizeof(PerformanceLayout::PerformanceLayoutEntry); - LINFO("Create shared memory of " << totalSize << " bytes"); - - ghoul::SharedMemory::create(PerformanceMeasurementSharedData, totalSize); - _performanceMemory = new ghoul::SharedMemory(PerformanceMeasurementSharedData); - - PerformanceLayout* layout = reinterpret_cast(_performanceMemory->pointer()); - layout->version = Version; - layout->nValuesPerEntry = nValues; - layout->nEntries = nNodes; - layout->maxNameLength = lengthName; - layout->maxEntries = maxValues; - - memset(layout->entries, 0, maxValues * sizeof(PerformanceLayout::PerformanceLayoutEntry)); - - for (int i = 0; i < nNodes; ++i) { - SceneGraphNode* node = sceneGraph()->allSceneGraphNodes()[i]; - - memset(layout->entries[i].name, 0, lengthName); - strcpy(layout->entries[i].name, node->name().c_str()); - - layout->entries[i].currentRenderTime = 0; - layout->entries[i].currentUpdateRenderable = 0; - layout->entries[i].currentUpdateEphemeris = 0; + os.close(); } - } - PerformanceLayout* layout = reinterpret_cast(_performanceMemory->pointer()); - _performanceMemory->acquireLock(); - for (int i = 0; i < nNodes; ++i) { - SceneGraphNode* node = sceneGraph()->allSceneGraphNodes()[i]; - SceneGraphNode::PerformanceRecord r = node->performanceRecord(); - PerformanceLayout::PerformanceLayoutEntry& entry = layout->entries[i]; + scripting::ScriptEngine::LuaLibrary RenderEngine::luaLibrary() { + return{ + "", + { + { + "takeScreenshot", + &luascriptfunctions::takeScreenshot, + "", + "Renders the current image to a file on disk" + }, + { + "visualizeABuffer", + &luascriptfunctions::visualizeABuffer, + "bool", + "Toggles the visualization of the ABuffer" + }, + { + "showRenderInformation", + &luascriptfunctions::showRenderInformation, + "bool", + "Toggles the showing of render information on-screen text" + }, + { + "setPerformanceMeasurement", + &luascriptfunctions::setPerformanceMeasurement, + "bool", + "Sets the performance measurements" + } + }, + }; + } - entry.renderTime[entry.currentRenderTime] = r.renderTime / 1000.f; - entry.updateEphemeris[entry.currentUpdateEphemeris] = r.updateTimeEphemeris / 1000.f; - entry.updateRenderable[entry.currentUpdateRenderable] = r.updateTimeRenderable / 1000.f; + void RenderEngine::setPerformanceMeasurements(bool performanceMeasurements) { + _doPerformanceMeasurements = performanceMeasurements; + } - entry.currentRenderTime = (entry.currentRenderTime + 1) % nValues; - entry.currentUpdateEphemeris = (entry.currentUpdateEphemeris + 1) % nValues; - entry.currentUpdateRenderable = (entry.currentUpdateRenderable + 1) % nValues; - } - _performanceMemory->releaseLock(); -} + bool RenderEngine::doesPerformanceMeasurements() const { + return _doPerformanceMeasurements; + } -} // namespace openspace + void RenderEngine::storePerformanceMeasurements() { + const int8_t Version = 0; + const int nValues = 250; + const int lengthName = 256; + const int maxValues = 50; + + struct PerformanceLayout { + int8_t version; + int32_t nValuesPerEntry; + int32_t nEntries; + int32_t maxNameLength; + int32_t maxEntries; + + struct PerformanceLayoutEntry { + char name[lengthName]; + float renderTime[nValues]; + float updateRenderable[nValues]; + float updateEphemeris[nValues]; + + int32_t currentRenderTime; + int32_t currentUpdateRenderable; + int32_t currentUpdateEphemeris; + }; + + PerformanceLayoutEntry entries[maxValues]; + }; + + const int nNodes = static_cast(sceneGraph()->allSceneGraphNodes().size()); + if (!_performanceMemory) { + + // Compute the total size + const int totalSize = sizeof(int8_t) + 4 * sizeof(int32_t) + + maxValues * sizeof(PerformanceLayout::PerformanceLayoutEntry); + LINFO("Create shared memory of " << totalSize << " bytes"); + + ghoul::SharedMemory::create(PerformanceMeasurementSharedData, totalSize); + _performanceMemory = new ghoul::SharedMemory(PerformanceMeasurementSharedData); + + PerformanceLayout* layout = reinterpret_cast(_performanceMemory->pointer()); + layout->version = Version; + layout->nValuesPerEntry = nValues; + layout->nEntries = nNodes; + layout->maxNameLength = lengthName; + layout->maxEntries = maxValues; + + memset(layout->entries, 0, maxValues * sizeof(PerformanceLayout::PerformanceLayoutEntry)); + + for (int i = 0; i < nNodes; ++i) { + SceneGraphNode* node = sceneGraph()->allSceneGraphNodes()[i]; + + memset(layout->entries[i].name, 0, lengthName); + strcpy(layout->entries[i].name, node->name().c_str()); + + layout->entries[i].currentRenderTime = 0; + layout->entries[i].currentUpdateRenderable = 0; + layout->entries[i].currentUpdateEphemeris = 0; + } + } + + PerformanceLayout* layout = reinterpret_cast(_performanceMemory->pointer()); + _performanceMemory->acquireLock(); + for (int i = 0; i < nNodes; ++i) { + SceneGraphNode* node = sceneGraph()->allSceneGraphNodes()[i]; + SceneGraphNode::PerformanceRecord r = node->performanceRecord(); + PerformanceLayout::PerformanceLayoutEntry& entry = layout->entries[i]; + + entry.renderTime[entry.currentRenderTime] = r.renderTime / 1000.f; + entry.updateEphemeris[entry.currentUpdateEphemeris] = r.updateTimeEphemeris / 1000.f; + entry.updateRenderable[entry.currentUpdateRenderable] = r.updateTimeRenderable / 1000.f; + + entry.currentRenderTime = (entry.currentRenderTime + 1) % nValues; + entry.currentUpdateEphemeris = (entry.currentUpdateEphemeris + 1) % nValues; + entry.currentUpdateRenderable = (entry.currentUpdateRenderable + 1) % nValues; + } + _performanceMemory->releaseLock(); + } + +}// namespace openspace