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