mirror of
https://github.com/overte-org/overte.git
synced 2025-04-25 08:17:11 +02:00
Merge pull request #10643 from howard-stearns/monitor-display-of-texture
Monitor display of texture
This commit is contained in:
commit
fee8001a40
8 changed files with 95 additions and 37 deletions
|
@ -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});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,14 +616,11 @@ 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()) {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in a new issue