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) };
}