Merge pull request #10643 from howard-stearns/monitor-display-of-texture

Monitor display of texture
This commit is contained in:
Howard Stearns 2017-06-08 16:09:11 -07:00 committed by GitHub
commit fee8001a40
8 changed files with 95 additions and 37 deletions

View file

@ -242,7 +242,7 @@ Rectangle {
labelTextOn: "Camera View"; labelTextOn: "Camera View";
labelGlyphOnText: hifi.glyphs.alert; labelGlyphOnText: hifi.glyphs.alert;
onCheckedChanged: { onCheckedChanged: {
sendToScript({method: (checked ? 'showCameraViewOnMonitor' : 'showHmdPreviewOnMonitor')}); sendToScript({method: 'setMonitorShowsCameraView', params: checked});
} }
} }

View file

@ -284,6 +284,11 @@ void WindowScriptingInterface::copyToClipboard(const QString& text) {
QApplication::clipboard()->setText(text); QApplication::clipboard()->setText(text);
} }
bool WindowScriptingInterface::setDisplayTexture(const QString& name) {
return qApp->getActiveDisplayPlugin()->setDisplayTexture(name); // Plugins that don't know how, answer false.
}
void WindowScriptingInterface::takeSnapshot(bool notify, bool includeAnimated, float aspectRatio) { void WindowScriptingInterface::takeSnapshot(bool notify, bool includeAnimated, float aspectRatio) {
qApp->takeSnapshot(notify, includeAnimated, aspectRatio); qApp->takeSnapshot(notify, includeAnimated, aspectRatio);
} }

View file

@ -62,6 +62,7 @@ public slots:
void displayAnnouncement(const QString& message); void displayAnnouncement(const QString& message);
void shareSnapshot(const QString& path, const QUrl& href = QUrl("")); void shareSnapshot(const QString& path, const QUrl& href = QUrl(""));
bool isPhysicsEnabled(); bool isPhysicsEnabled();
bool setDisplayTexture(const QString& name);
int openMessageBox(QString title, QString text, int buttons, int defaultButton); int openMessageBox(QString title, QString text, int buttons, int defaultButton);
void updateMessageBox(int id, QString title, QString text, int buttons, int defaultButton); void updateMessageBox(int id, QString title, QString text, int buttons, int defaultButton);

View file

@ -496,6 +496,17 @@ void OpenGLDisplayPlugin::submitFrame(const gpu::FramePointer& newFrame) {
_newFrameQueue.push(newFrame); _newFrameQueue.push(newFrame);
}); });
} }
void OpenGLDisplayPlugin::renderFromTexture(gpu::Batch& batch, const gpu::TexturePointer texture, glm::ivec4 viewport, const glm::ivec4 scissor) {
batch.enableStereo(false);
batch.resetViewTransform();
batch.setFramebuffer(gpu::FramebufferPointer());
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, vec4(0));
batch.setStateScissorRect(scissor);
batch.setViewportTransform(viewport);
batch.setResourceTexture(0, texture);
batch.setPipeline(_presentPipeline);
batch.draw(gpu::TRIANGLE_STRIP, 4);
}
void OpenGLDisplayPlugin::updateFrameData() { void OpenGLDisplayPlugin::updateFrameData() {
PROFILE_RANGE(render, __FUNCTION__) PROFILE_RANGE(render, __FUNCTION__)
@ -605,13 +616,10 @@ void OpenGLDisplayPlugin::compositeLayers() {
void OpenGLDisplayPlugin::internalPresent() { void OpenGLDisplayPlugin::internalPresent() {
render([&](gpu::Batch& batch) { render([&](gpu::Batch& batch) {
batch.enableStereo(false); // Note: _displayTexture must currently be the same size as the display.
batch.resetViewTransform(); uvec2 dims = _displayTexture ? uvec2(_displayTexture->getDimensions()) : getSurfacePixels();
batch.setFramebuffer(gpu::FramebufferPointer()); auto viewport = ivec4(uvec2(0), dims);
batch.setViewportTransform(ivec4(uvec2(0), getSurfacePixels())); renderFromTexture(batch, _displayTexture ? _displayTexture : _compositeFramebuffer->getRenderBuffer(0), viewport, viewport);
batch.setResourceTexture(0, _compositeFramebuffer->getRenderBuffer(0));
batch.setPipeline(_presentPipeline);
batch.draw(gpu::TRIANGLE_STRIP, 4);
}); });
swapBuffers(); swapBuffers();
_presentRate.increment(); _presentRate.increment();
@ -694,6 +702,21 @@ void OpenGLDisplayPlugin::withMainThreadContext(std::function<void()> f) const {
_container->makeRenderingContextCurrent(); _container->makeRenderingContextCurrent();
} }
bool OpenGLDisplayPlugin::setDisplayTexture(const QString& name) {
// Note: it is the caller's responsibility to keep the network texture in cache.
if (name.isEmpty()) {
_displayTexture.reset();
return true;
}
auto textureCache = DependencyManager::get<TextureCache>();
auto displayNetworkTexture = textureCache->getTexture(name);
if (!displayNetworkTexture) {
return false;
}
_displayTexture = displayNetworkTexture->getGPUTexture();
return !!_displayTexture;
}
QImage OpenGLDisplayPlugin::getScreenshot(float aspectRatio) const { QImage OpenGLDisplayPlugin::getScreenshot(float aspectRatio) const {
auto size = _compositeFramebuffer->getSize(); auto size = _compositeFramebuffer->getSize();
if (isHmd()) { if (isHmd()) {

View file

@ -57,6 +57,7 @@ public:
return getSurfaceSize(); return getSurfaceSize();
} }
virtual bool setDisplayTexture(const QString& name) override;
QImage getScreenshot(float aspectRatio = 0.0f) const override; QImage getScreenshot(float aspectRatio = 0.0f) const override;
float presentRate() const override; float presentRate() const override;
@ -109,6 +110,7 @@ protected:
// Plugin specific functionality to send the composed scene to the output window or device // Plugin specific functionality to send the composed scene to the output window or device
virtual void internalPresent(); virtual void internalPresent();
void renderFromTexture(gpu::Batch& batch, const gpu::TexturePointer texture, glm::ivec4 viewport, const glm::ivec4 scissor);
virtual void updateFrameData(); virtual void updateFrameData();
void withMainThreadContext(std::function<void()> f) const; void withMainThreadContext(std::function<void()> f) const;
@ -134,6 +136,7 @@ protected:
gpu::PipelinePointer _simplePipeline; gpu::PipelinePointer _simplePipeline;
gpu::PipelinePointer _presentPipeline; gpu::PipelinePointer _presentPipeline;
gpu::PipelinePointer _cursorPipeline; gpu::PipelinePointer _cursorPipeline;
gpu::TexturePointer _displayTexture{};
float _compositeOverlayAlpha { 1.0f }; float _compositeOverlayAlpha { 1.0f };
struct CursorData { struct CursorData {

View file

@ -27,6 +27,7 @@
#include <gpu/StandardShaderLib.h> #include <gpu/StandardShaderLib.h>
#include <gpu/gl/GLBackend.h> #include <gpu/gl/GLBackend.h>
#include <TextureCache.h>
#include <PathUtils.h> #include <PathUtils.h>
#include "../Logging.h" #include "../Logging.h"
@ -211,7 +212,15 @@ void HmdDisplayPlugin::internalPresent() {
// Composite together the scene, overlay and mouse cursor // Composite together the scene, overlay and mouse cursor
hmdPresent(); hmdPresent();
if (!_disablePreview) { if (_displayTexture) {
// Note: _displayTexture must currently be the same size as the display.
uvec2 dims = uvec2(_displayTexture->getDimensions());
auto viewport = ivec4(uvec2(0), dims);
render([&](gpu::Batch& batch) {
renderFromTexture(batch, _displayTexture, viewport, viewport);
});
swapBuffers();
} else if (!_disablePreview) {
// screen preview mirroring // screen preview mirroring
auto sourceSize = _renderTargetSize; auto sourceSize = _renderTargetSize;
if (_monoPreview) { if (_monoPreview) {
@ -272,16 +281,7 @@ void HmdDisplayPlugin::internalPresent() {
viewport.z *= 2; viewport.z *= 2;
} }
renderFromTexture(batch, _compositeFramebuffer->getRenderBuffer(0), viewport, scissor);
batch.enableStereo(false);
batch.resetViewTransform();
batch.setFramebuffer(gpu::FramebufferPointer());
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, vec4(0));
batch.setStateScissorRect(scissor); // was viewport
batch.setViewportTransform(viewport);
batch.setResourceTexture(0, _compositeFramebuffer->getRenderBuffer(0));
batch.setPipeline(_presentPipeline);
batch.draw(gpu::TRIANGLE_STRIP, 4);
}); });
swapBuffers(); swapBuffers();
} else if (_clearPreviewFlag) { } else if (_clearPreviewFlag) {
@ -310,15 +310,7 @@ void HmdDisplayPlugin::internalPresent() {
auto viewport = getViewportForSourceSize(uvec2(_previewTexture->getDimensions())); auto viewport = getViewportForSourceSize(uvec2(_previewTexture->getDimensions()));
render([&](gpu::Batch& batch) { render([&](gpu::Batch& batch) {
batch.enableStereo(false); renderFromTexture(batch, _previewTexture, viewport, viewport);
batch.resetViewTransform();
batch.setFramebuffer(gpu::FramebufferPointer());
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, vec4(0));
batch.setStateScissorRect(viewport);
batch.setViewportTransform(viewport);
batch.setResourceTexture(0, _previewTexture);
batch.setPipeline(_presentPipeline);
batch.draw(gpu::TRIANGLE_STRIP, 4);
}); });
_clearPreviewFlag = false; _clearPreviewFlag = false;
swapBuffers(); swapBuffers();

View file

@ -184,6 +184,9 @@ public:
// will query the underlying hmd api to compute the most recent head pose // will query the underlying hmd api to compute the most recent head pose
virtual bool beginFrameRender(uint32_t frameIndex) { return true; } virtual bool beginFrameRender(uint32_t frameIndex) { return true; }
// Set the texture to display on the monitor and return true, if allowed. Empty string resets.
virtual bool setDisplayTexture(const QString& name) { return false; }
virtual float devicePixelRatio() { return 1.0f; } virtual float devicePixelRatio() { return 1.0f; }
// Rate at which we render frames // Rate at which we render frames
virtual float renderRate() const { return -1.0f; } virtual float renderRate() const { return -1.0f; }

View file

@ -117,6 +117,7 @@
orientation: flip(cameraRotation), orientation: flip(cameraRotation),
scale: -0.35, scale: -0.35,
}); });
setDisplay(monitorShowsCameraView);
} }
// //
@ -147,6 +148,12 @@
} }
camera = false; camera = false;
viewFinderOverlay = false; viewFinderOverlay = false;
setDisplay(monitorShowsCameraView);
}
function onHMDChanged(isHMDMode) {
// Will also eventually enable disable app, camera, etc.
setDisplay(monitorShowsCameraView);
} }
// //
@ -174,6 +181,8 @@
button.clicked.connect(onTabletButtonClicked); button.clicked.connect(onTabletButtonClicked);
tablet.screenChanged.connect(onTabletScreenChanged); tablet.screenChanged.connect(onTabletScreenChanged);
Window.domainChanged.connect(spectatorCameraOff); Window.domainChanged.connect(spectatorCameraOff);
Controller.keyPressEvent.connect(keyPressEvent);
HMD.displayModeChanged.connect(onHMDChanged);
viewFinderOverlay = false; viewFinderOverlay = false;
camera = false; camera = false;
} }
@ -205,6 +214,31 @@
} }
} }
function setDisplay(showCameraView) {
// It would be fancy if (showCameraView && !isUpdateRenderWired) would show instructions, but that's out of scope for now.
var url = (showCameraView && isUpdateRenderWired) ? "http://selfieFrame" : "";
Window.setDisplayTexture(url);
}
const MONITOR_SHOWS_CAMERA_VIEW_DEFAULT = false;
var monitorShowsCameraView = !!Settings.getValue('spectatorCamera/monitorShowsCameraView', MONITOR_SHOWS_CAMERA_VIEW_DEFAULT);
function setMonitorShowsCameraView(showCameraView) {
if (showCameraView === monitorShowsCameraView) {
return;
}
monitorShowsCameraView = showCameraView;
setDisplay(showCameraView);
Settings.setValue('spectatorCamera/monitorShowsCameraView', showCameraView);
}
function setMonitorShowsCameraViewAndSendToQml(showCameraView) {
setMonitorShowsCameraView(showCameraView);
sendToQml({ method: 'updateMonitorShowsSwitch', params: showCameraView });
}
function keyPressEvent(event) {
if ((event.text === "0") && !event.isAutoRepeat && !event.isShifted && !event.isMeta && event.isControl && !event.isAlt) {
setMonitorShowsCameraViewAndSendToQml(!monitorShowsCameraView);
}
}
// //
// Function Name: onTabletButtonClicked() // Function Name: onTabletButtonClicked()
// //
@ -230,7 +264,7 @@
tablet.loadQMLSource("../SpectatorCamera.qml"); tablet.loadQMLSource("../SpectatorCamera.qml");
onSpectatorCameraScreen = true; onSpectatorCameraScreen = true;
sendToQml({ method: 'updateSpectatorCameraCheckbox', params: !!camera }); sendToQml({ method: 'updateSpectatorCameraCheckbox', params: !!camera });
sendToQml({ method: 'updateMonitorShowsSwitch', params: !!Settings.getValue('spectatorCamera/monitorShowsCameraView', false) }); setMonitorShowsCameraViewAndSendToQml(monitorShowsCameraView);
} }
} }
@ -293,13 +327,8 @@
case 'spectatorCameraOff': case 'spectatorCameraOff':
spectatorCameraOff(); spectatorCameraOff();
break; break;
case 'showHmdPreviewOnMonitor': case 'setMonitorShowsCameraView':
print('FIXME: showHmdPreviewOnMonitor'); setMonitorShowsCameraView(message.params);
Settings.setValue('spectatorCamera/monitorShowsCameraView', false);
break;
case 'showCameraViewOnMonitor':
print('FIXME: showCameraViewOnMonitor');
Settings.setValue('spectatorCamera/monitorShowsCameraView', true);
break; break;
case 'changeSwitchViewFromControllerPreference': case 'changeSwitchViewFromControllerPreference':
print('FIXME: Preference is now: ' + message.params); print('FIXME: Preference is now: ' + message.params);
@ -327,6 +356,8 @@
tablet.removeButton(button); tablet.removeButton(button);
button.clicked.disconnect(onTabletButtonClicked); button.clicked.disconnect(onTabletButtonClicked);
tablet.screenChanged.disconnect(onTabletScreenChanged); tablet.screenChanged.disconnect(onTabletScreenChanged);
HMD.displayModeChanged.disconnect(onHMDChanged);
Controller.keyPressEvent.disconnect(keyPressEvent);
} }
// //