From f6670a63746fcec41e9227b819a7519b4a2db16f Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Thu, 18 Aug 2016 16:29:42 -0700 Subject: [PATCH 1/2] new optional aspect-ratio argument to snapshot chain (javascript through c++ display plugin). When non-zero, it pulls out the largest piece from the center that maintains that ratio. Snapshot button uses 1.91. --- interface/src/Application.cpp | 4 ++-- interface/src/Application.h | 2 +- .../src/scripting/WindowScriptingInterface.cpp | 6 +++--- .../src/scripting/WindowScriptingInterface.h | 2 +- .../src/display-plugins/NullDisplayPlugin.cpp | 2 +- .../src/display-plugins/NullDisplayPlugin.h | 2 +- .../src/display-plugins/OpenGLDisplayPlugin.cpp | 17 ++++++++++++++--- .../src/display-plugins/OpenGLDisplayPlugin.h | 2 +- libraries/plugins/src/plugins/DisplayPlugin.h | 2 +- scripts/system/snapshot.js | 2 +- 10 files changed, 26 insertions(+), 15 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 340597f18a..59ec1c0641 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5130,13 +5130,13 @@ void Application::toggleLogDialog() { } } -void Application::takeSnapshot(bool notify) { +void Application::takeSnapshot(bool notify, float aspectRatio) { QMediaPlayer* player = new QMediaPlayer(); QFileInfo inf = QFileInfo(PathUtils::resourcesPath() + "sounds/snap.wav"); player->setMedia(QUrl::fromLocalFile(inf.absoluteFilePath())); player->play(); - QString path = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot()); + QString path = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot(aspectRatio)); emit DependencyManager::get()->snapshotTaken(path, notify); } diff --git a/interface/src/Application.h b/interface/src/Application.h index 9fcce66f55..667969abf1 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -250,7 +250,7 @@ public: float getAvatarSimrate() const { return _avatarSimCounter.rate(); } float getAverageSimsPerSecond() const { return _simCounter.rate(); } - void takeSnapshot(bool notify); + void takeSnapshot(bool notify, float aspectRatio = 0.0f); void shareSnapshot(const QString& filename); model::SkyboxPointer getDefaultSkybox() const { return _defaultSkybox; } diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp index f843673c07..f68f6d212a 100644 --- a/interface/src/scripting/WindowScriptingInterface.cpp +++ b/interface/src/scripting/WindowScriptingInterface.cpp @@ -204,10 +204,10 @@ void WindowScriptingInterface::copyToClipboard(const QString& text) { QApplication::clipboard()->setText(text); } -void WindowScriptingInterface::takeSnapshot(bool notify) { +void WindowScriptingInterface::takeSnapshot(bool notify, float aspectRatio) { // only evil-doers call takeSnapshot from a random thread - qApp->postLambdaEvent([notify] { - qApp->takeSnapshot(notify); + qApp->postLambdaEvent([notify, aspectRatio] { + qApp->takeSnapshot(notify, aspectRatio); }); } diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h index 15dc1a8004..ca82753598 100644 --- a/interface/src/scripting/WindowScriptingInterface.h +++ b/interface/src/scripting/WindowScriptingInterface.h @@ -55,7 +55,7 @@ public slots: QScriptValue save(const QString& title = "", const QString& directory = "", const QString& nameFilter = ""); void showAssetServer(const QString& upload = ""); void copyToClipboard(const QString& text); - void takeSnapshot(bool notify); + void takeSnapshot(bool notify = true, float aspectRatio = 0.0f); void shareSnapshot(const QString& path); signals: diff --git a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp index 5ee05fa2e3..a4777b087b 100644 --- a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp @@ -31,6 +31,6 @@ void NullDisplayPlugin::submitFrame(const gpu::FramePointer& frame) { } } -QImage NullDisplayPlugin::getScreenshot() const { +QImage NullDisplayPlugin::getScreenshot(float aspectRatio) const { return QImage(); } diff --git a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h index 198c89ae78..1852ed53ee 100644 --- a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h @@ -18,7 +18,7 @@ public: glm::uvec2 getRecommendedRenderSize() const override; bool hasFocus() const override; void submitFrame(const gpu::FramePointer& newFrame) override; - QImage getScreenshot() const override; + QImage getScreenshot(float aspectRatio = 0.0f) const override; private: static const QString NAME; }; diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 905042cb79..7334191b75 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -659,15 +659,26 @@ void OpenGLDisplayPlugin::withMainThreadContext(std::function f) const { _container->makeRenderingContextCurrent(); } -QImage OpenGLDisplayPlugin::getScreenshot() const { +QImage OpenGLDisplayPlugin::getScreenshot(float aspectRatio) const { auto size = _compositeFramebuffer->getSize(); if (isHmd()) { size.x /= 2; } + auto bestSize = size; + uvec2 corner(0); + if (aspectRatio != 0.0f) { // Pick out the largest piece of the center that produces the requested width/height aspectRatio + if (((size.y * aspectRatio) + 0.5f) < size.x) { + bestSize.x = round(size.y * aspectRatio); + } else { + bestSize.y = round(size.x / aspectRatio); + } + corner.x = round((size.x - bestSize.x) / 2.0f); + corner.y = round((size.y - bestSize.y) / 2.0f); + } auto glBackend = const_cast(*this).getGLBackend(); - QImage screenshot(size.x, size.y, QImage::Format_ARGB32); + QImage screenshot(bestSize.x, bestSize.y, QImage::Format_ARGB32); withMainThreadContext([&] { - glBackend->downloadFramebuffer(_compositeFramebuffer, ivec4(uvec2(0), size), screenshot); + glBackend->downloadFramebuffer(_compositeFramebuffer, ivec4(corner, bestSize), screenshot); }); return screenshot.mirrored(false, true); } diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index 48f9a78eda..51b33c9bcd 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -54,7 +54,7 @@ public: return getSurfaceSize(); } - QImage getScreenshot() const override; + QImage getScreenshot(float aspectRatio = 0.0f) const override; float presentRate() const override; diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index 49c341cdcb..288cee3223 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -172,7 +172,7 @@ public: } // Fetch the most recently displayed image as a QImage - virtual QImage getScreenshot() const = 0; + virtual QImage getScreenshot(float aspectRatio = 0.0f) const = 0; // will query the underlying hmd api to compute the most recent head pose virtual bool beginFrameRender(uint32_t frameIndex) { return true; } diff --git a/scripts/system/snapshot.js b/scripts/system/snapshot.js index 92b16d31bc..5c893fad4a 100644 --- a/scripts/system/snapshot.js +++ b/scripts/system/snapshot.js @@ -116,7 +116,7 @@ function onClicked() { // take snapshot (with no notification) Script.setTimeout(function () { - Window.takeSnapshot(false); + Window.takeSnapshot(false, 1.91); }, SNAPSHOT_DELAY); } From 4d7d483c0eac43fca4232c6b4d44ff1601d9c372 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Fri, 19 Aug 2016 09:51:58 -0700 Subject: [PATCH 2/2] use ceil --- .../display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 7334191b75..b304b3802e 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -667,7 +667,7 @@ QImage OpenGLDisplayPlugin::getScreenshot(float aspectRatio) const { auto bestSize = size; uvec2 corner(0); if (aspectRatio != 0.0f) { // Pick out the largest piece of the center that produces the requested width/height aspectRatio - if (((size.y * aspectRatio) + 0.5f) < size.x) { + if (ceil(size.y * aspectRatio) < size.x) { bestSize.x = round(size.y * aspectRatio); } else { bestSize.y = round(size.x / aspectRatio);