diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index 8f119dd707..0d4a5c7c86 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -890,6 +890,11 @@ void setSgctDelegateFunctions() { }; sgctDelegate.currentSubwindowSize = []() { auto window = sgct::Engine::instance()->getCurrentWindowPtr(); + if (sgct::Engine::instance()->getCurrentWindowPtr()->getNumberOfViewports() > 1) { + sgct_core::Viewport* viewport = + sgct::Engine::instance()->getCurrentWindowPtr()->getViewport(0); + return glm::ivec2(window->getXResolution()*viewport->getXSize(), window->getYResolution()*viewport->getYSize()); + } switch (window->getStereoMode()) { case sgct::SGCTWindow::Side_By_Side_Stereo: case sgct::SGCTWindow::Side_By_Side_Inverted_Stereo: @@ -915,6 +920,12 @@ void setSgctDelegateFunctions() { int res = viewport->getNonLinearProjectionPtr()->getCubemapResolution(); return glm::ivec2(res, res); } + else if (sgct::Engine::instance()->getCurrentWindowPtr()->getNumberOfViewports() > 1) { + int x, y; + auto window = sgct::Engine::instance()->getCurrentWindowPtr(); + window->getFinalFBODimensions(x, y); + return glm::ivec2(x*viewport->getXSize(), y*viewport->getYSize()); + } else { int x, y; auto window = sgct::Engine::instance()->getCurrentWindowPtr(); @@ -944,16 +955,6 @@ void setSgctDelegateFunctions() { sgctDelegate.currentNumberOfAaSamples = []() { return sgct::Engine::instance()->getCurrentWindowPtr()->getNumberOfAASamples(); }; - sgctDelegate.isRegularRendering = []() { - sgct::SGCTWindow* w = sgct::Engine::instance()->getCurrentWindowPtr(); - ghoul_assert( - w->getNumberOfViewports() > 0, - "At least one viewport must exist at this time" - ); - sgct_core::Viewport* vp = w->getViewport(0); - sgct_core::NonLinearProjection* nlp = vp->getNonLinearProjectionPtr(); - return nlp == nullptr; - }; sgctDelegate.hasGuiWindow = []() { auto engine = sgct::Engine::instance(); for (size_t i = 0; i < engine->getNumberOfWindows(); ++i) { diff --git a/config/single_sbs_stereo.xml b/config/single_sbs_stereo.xml new file mode 100644 index 0000000000..87ee3a33ec --- /dev/null +++ b/config/single_sbs_stereo.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/include/openspace/engine/windowdelegate.h b/include/openspace/engine/windowdelegate.h index 70f6f21d3d..677bed9a3d 100644 --- a/include/openspace/engine/windowdelegate.h +++ b/include/openspace/engine/windowdelegate.h @@ -74,8 +74,6 @@ struct WindowDelegate { int (*currentNumberOfAaSamples)() = []() { return 1; }; - bool (*isRegularRendering)() = []() { return true; }; - bool (*hasGuiWindow)() = []() { return false; }; bool (*isGuiWindow)() = []() { return false; }; diff --git a/modules/base/rendering/screenspacedashboard.cpp b/modules/base/rendering/screenspacedashboard.cpp index c0530f8491..e252807e1f 100644 --- a/modules/base/rendering/screenspacedashboard.cpp +++ b/modules/base/rendering/screenspacedashboard.cpp @@ -201,7 +201,7 @@ bool ScreenSpaceDashboard::isReady() const { void ScreenSpaceDashboard::update() { if (global::windowDelegate.windowHasResized()) { - const glm::ivec2 size = global::windowDelegate.currentWindowResolution(); + const glm::ivec2 size = global::windowDelegate.currentDrawBufferResolution(); _size = { 0.f, 0.f, size.x, size.y }; createFramebuffer(); } diff --git a/modules/base/rendering/screenspaceframebuffer.cpp b/modules/base/rendering/screenspaceframebuffer.cpp index 5a94669b99..035e38b618 100644 --- a/modules/base/rendering/screenspaceframebuffer.cpp +++ b/modules/base/rendering/screenspaceframebuffer.cpp @@ -77,7 +77,7 @@ ScreenSpaceFramebuffer::ScreenSpaceFramebuffer(const ghoul::Dictionary& dictiona setGuiName("ScreenSpaceFramebuffer " + std::to_string(iIdentifier)); } - glm::vec2 resolution = global::windowDelegate.currentWindowResolution(); + glm::vec2 resolution = global::windowDelegate.currentDrawBufferResolution(); addProperty(_size); _size.set(glm::vec4(0, 0, resolution.x,resolution.y)); } @@ -103,13 +103,15 @@ bool ScreenSpaceFramebuffer::deinitializeGL() { } void ScreenSpaceFramebuffer::render() { - const glm::vec2& resolution = global::windowDelegate.currentWindowResolution(); + const glm::vec2& resolution = global::windowDelegate.currentDrawBufferResolution(); const glm::vec4& size = _size.value(); const float xratio = resolution.x / (size.z - size.x); const float yratio = resolution.y / (size.w - size.y);; if (!_renderFunctions.empty()) { + GLint viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); glViewport( static_cast(-size.x * xratio), static_cast(-size.y * yratio), @@ -127,12 +129,7 @@ void ScreenSpaceFramebuffer::render() { _framebuffer->deactivate(); glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); - glViewport( - 0, - 0, - static_cast(resolution.x), - static_cast(resolution.y) - ); + glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); const glm::mat4 globalRotation = globalRotationMatrix(); const glm::mat4 translation = translationMatrix(); @@ -170,7 +167,7 @@ void ScreenSpaceFramebuffer::removeAllRenderFunctions() { } void ScreenSpaceFramebuffer::createFramebuffer() { - glm::vec2 resolution = global::windowDelegate.currentWindowResolution(); + glm::vec2 resolution = global::windowDelegate.currentDrawBufferResolution(); _framebuffer = std::make_unique(); _framebuffer->activate(); diff --git a/modules/cefwebgui/cefwebguimodule.cpp b/modules/cefwebgui/cefwebguimodule.cpp index e0a1de88e7..8a6951f8de 100644 --- a/modules/cefwebgui/cefwebguimodule.cpp +++ b/modules/cefwebgui/cefwebguimodule.cpp @@ -103,6 +103,10 @@ void CefWebGuiModule::startOrStopGui() { new GUIKeyboardHandler ); _instance->initialize(); + _instance->reshape(static_cast( + static_cast(global::windowDelegate.currentSubwindowSize()) * + global::windowDelegate.dpiScaling() + )); if (!_url.value().empty()) { _instance->loadUrl(_url); } @@ -200,11 +204,12 @@ void CefWebGuiModule::internalInitialize(const ghoul::Dictionary& configuration) const bool isMaster = global::windowDelegate.isMaster(); if (isGuiWindow && isMaster && _instance) { - if (global::windowDelegate.windowHasResized()) { + if (global::windowDelegate.windowHasResized() || _instance->_shouldReshape) { _instance->reshape(static_cast( - static_cast(global::windowDelegate.currentWindowSize()) * + static_cast(global::windowDelegate.currentSubwindowSize()) * global::windowDelegate.dpiScaling() )); + _instance->_shouldReshape = false; } if (_visible) { _instance->draw(); diff --git a/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp b/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp index c5a6032e25..9ef2a3a9a9 100644 --- a/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp +++ b/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp @@ -1731,7 +1731,7 @@ void RenderableBillboardsCloud::renderToTexture(GLuint textureToRenderTo, glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, textureToRenderTo, 0); - glViewport(0, 0, textureWidth, textureHeight); + glViewport(viewport[0], viewport[1], textureWidth, textureHeight); loadPolygonGeometryForRendering(); renderPolygonGeometry(_polygonVao); diff --git a/modules/imgui/imguimodule.cpp b/modules/imgui/imguimodule.cpp index a8ee5aacff..7ee1293e2d 100644 --- a/modules/imgui/imguimodule.cpp +++ b/modules/imgui/imguimodule.cpp @@ -151,8 +151,8 @@ ImGUIModule::ImGUIModule() : OpenSpaceModule(Name) { WindowDelegate& delegate = global::windowDelegate; const bool showGui = delegate.hasGuiWindow() ? delegate.isGuiWindow() : true; if (delegate.isMaster() && showGui) { - const glm::ivec2 windowSize = delegate.currentWindowSize(); - const glm::ivec2 resolution = delegate.currentWindowResolution(); + const glm::ivec2 windowSize = delegate.currentSubwindowSize(); + const glm::ivec2 resolution = delegate.currentDrawBufferResolution(); if (windowSize.x <= 0 || windowSize.y <= 0) { return; diff --git a/modules/webbrowser/include/browserinstance.h b/modules/webbrowser/include/browserinstance.h index 5aa1cc71de..688949963d 100644 --- a/modules/webbrowser/include/browserinstance.h +++ b/modules/webbrowser/include/browserinstance.h @@ -119,6 +119,8 @@ public: bool hasContent(int x, int y); + bool _shouldReshape = false; + private: CefRefPtr _renderHandler; CefRefPtr _keyboardHandler; diff --git a/modules/webbrowser/src/browserinstance.cpp b/modules/webbrowser/src/browserinstance.cpp index 3622a4583e..61f14ad7ad 100644 --- a/modules/webbrowser/src/browserinstance.cpp +++ b/modules/webbrowser/src/browserinstance.cpp @@ -74,10 +74,11 @@ BrowserInstance::~BrowserInstance() { void BrowserInstance::initialize() { reshape(static_cast( - static_cast(global::windowDelegate.currentWindowSize()) * + static_cast(global::windowDelegate.currentSubwindowSize()) * global::windowDelegate.dpiScaling() )); _isInitialized = true; + _shouldReshape = true; } void BrowserInstance::loadUrl(std::string url) { diff --git a/openspace.cfg b/openspace.cfg index 9cdc1e6149..571958c466 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -32,6 +32,9 @@ SGCTConfig = sgct.config.single{} -- Streaming OpenSpace via Spout to OBS -- SGCTConfig = sgct.config.single{2560, 1440, shared=true, name="WV_OBS_SPOUT1"} +-- A side-by-side test of mutiple viewport (also with different eyes) +-- SGCTConfig = "${CONFIG}/single_sbs_stereo.xml" + -- Spout exit -- SGCTConfig = "${CONFIG}/spout_output.xml" @@ -97,6 +100,7 @@ ModuleConfigurations = { SynchronizationRoot = "${SYNC}", HttpSynchronizationRepositories = { "http://data.openspaceproject.com/request" + -- "http://openspace.sci.utah.edu/request" } }, Server = { diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 0a6dd0ab57..579319a6cb 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -1137,8 +1137,6 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO); } - glViewport(0, 0, _resolution.x, _resolution.y); - // Apply the selected TMO on the results and resolve the result for the default FBO applyTMO(blackoutFactor); @@ -1155,6 +1153,8 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector glBindFramebuffer(GL_FRAMEBUFFER, _exitFramebuffer); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + GLint viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); ghoul::opengl::ProgramObject* exitProgram = _exitPrograms[raycaster].get(); if (exitProgram) { @@ -1166,7 +1166,7 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector if (raycaster->downscaleRender() < 1.f) { float scaleDown = raycaster->downscaleRender(); glBindFramebuffer(GL_FRAMEBUFFER, _downscaleVolumeRendering.framebuffer); - glViewport(0, 0, _resolution.x * scaleDown, _resolution.y * scaleDown); + glViewport(viewport[0], viewport[1], viewport[2] * scaleDown, viewport[3] * scaleDown); if (_downscaleVolumeRendering.currentDownscaleFactor != scaleDown) { _downscaleVolumeRendering.currentDownscaleFactor = scaleDown; updateDownscaleTextures(); @@ -1259,7 +1259,7 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector } if (raycaster->downscaleRender() < 1.f) { - glViewport(0, 0, _resolution.x, _resolution.y); + glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _gBuffers.framebuffer); writeDownscaledVolume(); } diff --git a/src/rendering/loadingscreen.cpp b/src/rendering/loadingscreen.cpp index 7a876ef8ab..6ef24cdb46 100644 --- a/src/rendering/loadingscreen.cpp +++ b/src/rendering/loadingscreen.cpp @@ -159,7 +159,7 @@ void LoadingScreen::render() { const glm::vec2 dpiScaling = global::windowDelegate.dpiScaling(); const glm::ivec2 res = - glm::vec2(global::windowDelegate.currentDrawBufferResolution()) / dpiScaling; + glm::vec2(global::windowDelegate.currentSubwindowSize()) / dpiScaling; float screenAspectRatio = static_cast(res.x) / static_cast(res.y); @@ -178,7 +178,7 @@ void LoadingScreen::render() { // glClearColor(0.f, 0.f, 0.f, 1.f); glClear(ClearBufferMask::GL_COLOR_BUFFER_BIT); - + glViewport(0, 0, res.x, res.y); glDisable(GL_CULL_FACE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); diff --git a/src/rendering/luaconsole.cpp b/src/rendering/luaconsole.cpp index d4c02f3a16..d32a1ace4c 100644 --- a/src/rendering/luaconsole.cpp +++ b/src/rendering/luaconsole.cpp @@ -615,7 +615,7 @@ void LuaConsole::update() { // Update the current height. // The current height is the offset that is used to slide // the console in from the top. - const glm::ivec2 res = global::windowDelegate.currentWindowResolution(); + const glm::ivec2 res = global::windowDelegate.currentSubwindowSize(); const glm::vec2 dpiScaling = global::windowDelegate.dpiScaling(); const double dHeight = (_targetHeight - _currentHeight) * std::pow(0.98, 1.0 / (ConsoleOpenSpeed / dpiScaling.y * frametime)); @@ -636,7 +636,7 @@ void LuaConsole::render() { const glm::vec2 dpiScaling = global::windowDelegate.dpiScaling(); const glm::ivec2 res = - glm::vec2(global::windowDelegate.currentWindowResolution()) / dpiScaling; + glm::vec2(global::windowDelegate.currentSubwindowSize()) / dpiScaling; // Render background diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index d8dcbd7b65..5fde95806a 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -555,12 +555,7 @@ void RenderEngine::updateScreenSpaceRenderables() { } glm::ivec2 RenderEngine::renderingResolution() const { - if (global::windowDelegate.isRegularRendering()) { - return global::windowDelegate.currentWindowResolution(); - } - else { - return global::windowDelegate.currentDrawBufferResolution(); - } + return global::windowDelegate.currentDrawBufferResolution(); } glm::ivec2 RenderEngine::fontResolution() const { @@ -569,7 +564,7 @@ glm::ivec2 RenderEngine::fontResolution() const { return global::windowDelegate.currentViewportSize(); } else { - return global::windowDelegate.currentWindowSize(); + return global::windowDelegate.currentSubwindowSize(); } } @@ -771,6 +766,11 @@ void RenderEngine::renderEndscreen() { glm::vec4(0.f, 0.f, 0.f, 0.5f) ); + const glm::vec2 dpiScaling = global::windowDelegate.dpiScaling(); + const glm::ivec2 res = + glm::vec2(global::windowDelegate.currentSubwindowSize()) / dpiScaling; + glViewport(0, 0, res.x, res.y); + using FR = ghoul::fontrendering::FontRenderer; using BBox = FR::BoundingBoxInformation; BBox size = FR::defaultRenderer().boundingBox( diff --git a/src/rendering/screenspacerenderable.cpp b/src/rendering/screenspacerenderable.cpp index 6fe7813bc8..ce8ea4511c 100644 --- a/src/rendering/screenspacerenderable.cpp +++ b/src/rendering/screenspacerenderable.cpp @@ -515,7 +515,7 @@ float ScreenSpaceRenderable::depth() { void ScreenSpaceRenderable::createShaders() { ghoul::Dictionary dict = ghoul::Dictionary(); - auto res = global::windowDelegate.currentWindowResolution(); + auto res = global::windowDelegate.currentDrawBufferResolution(); ghoul::Dictionary rendererData = { { "fragmentRendererPath", "${SHADERS}/framebuffer/renderframebuffer.frag" }, { "windowWidth" , res.x }, @@ -537,7 +537,7 @@ void ScreenSpaceRenderable::createShaders() { } glm::mat4 ScreenSpaceRenderable::scaleMatrix() { - glm::vec2 resolution = global::windowDelegate.currentWindowResolution(); + glm::vec2 resolution = global::windowDelegate.currentDrawBufferResolution(); //to scale the plane float textureRatio = diff --git a/src/scene/scenegraphnode.cpp b/src/scene/scenegraphnode.cpp index fd9e731817..f56d29b136 100644 --- a/src/scene/scenegraphnode.cpp +++ b/src/scene/scenegraphnode.cpp @@ -684,7 +684,7 @@ void SceneGraphNode::computeScreenSpaceData(RenderData& newData) { return; } - glm::ivec2 res = global::windowDelegate.currentWindowSize(); + glm::ivec2 res = global::windowDelegate.currentSubwindowSize(); // Get the radius of node double nodeRadius = static_cast(this->boundingSphere()); diff --git a/src/util/touch.cpp b/src/util/touch.cpp index ab16c23ed4..995e871850 100644 --- a/src/util/touch.cpp +++ b/src/util/touch.cpp @@ -44,7 +44,7 @@ glm::vec2 TouchInput::screenCoordinates(glm::vec2 resolution) const { } glm::vec2 TouchInput::currentWindowCoordinates() const { - glm::vec2 res = global::windowDelegate.currentWindowSize(); + glm::vec2 res = global::windowDelegate.currentSubwindowSize(); return { std::floor(x * res.x + 0.5f), std::floor(y * res.y + 0.5f) }; }