diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 63df7fdda9..e5de6fce8a 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -497,16 +497,26 @@ void OpenGLDisplayPlugin::submitFrame(const gpu::FramePointer& newFrame) { _newFrameQueue.push(newFrame); }); } + void OpenGLDisplayPlugin::renderFromTexture(gpu::Batch& batch, const gpu::TexturePointer texture, glm::ivec4 viewport, const glm::ivec4 scissor) { + renderFromTexture(batch, texture, viewport, scissor, gpu::FramebufferPointer()); +} + +void OpenGLDisplayPlugin::renderFromTexture(gpu::Batch& batch, const gpu::TexturePointer texture, glm::ivec4 viewport, const glm::ivec4 scissor, gpu::FramebufferPointer copyFbo /*=gpu::FramebufferPointer()*/) { + auto fbo = gpu::FramebufferPointer(); batch.enableStereo(false); batch.resetViewTransform(); - batch.setFramebuffer(gpu::FramebufferPointer()); + batch.setFramebuffer(fbo); 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); + if (copyFbo) { + gpu::Vec4i rect {0, 0, scissor.z, scissor.w}; + batch.blit(fbo, rect, copyFbo, rect); + } } void OpenGLDisplayPlugin::updateFrameData() { diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index 237864ded6..2f93fa630d 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -113,6 +113,7 @@ protected: // Plugin specific functionality to send the composed scene to the output window or device virtual void internalPresent(); + void renderFromTexture(gpu::Batch& batch, const gpu::TexturePointer texture, glm::ivec4 viewport, const glm::ivec4 scissor, gpu::FramebufferPointer fbo); void renderFromTexture(gpu::Batch& batch, const gpu::TexturePointer texture, glm::ivec4 viewport, const glm::ivec4 scissor); virtual void updateFrameData(); diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp index aed99da920..656d3013ab 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp @@ -242,7 +242,6 @@ void HmdDisplayPlugin::internalPresent() { glm::ivec4 viewport = getViewportForSourceSize(sourceSize); glm::ivec4 scissor = viewport; - render([&](gpu::Batch& batch) { if (_monoPreview) { @@ -287,10 +286,11 @@ void HmdDisplayPlugin::internalPresent() { viewport.z *= 2; } - DependencyManager::get()->setHmdPreviewTexture(_compositeFramebuffer->getRenderBuffer(0)); - renderFromTexture(batch, _compositeFramebuffer->getRenderBuffer(0), viewport, scissor); + auto fbo = DependencyManager::get()->getHmdPreviewFramebuffer(); + renderFromTexture(batch, _compositeFramebuffer->getRenderBuffer(0), viewport, scissor, fbo); }); swapBuffers(); + } else if (_clearPreviewFlag) { QImage image; if (_vsyncEnabled) { diff --git a/libraries/model-networking/src/model-networking/TextureCache.cpp b/libraries/model-networking/src/model-networking/TextureCache.cpp index a01979730f..c511db28ac 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.cpp +++ b/libraries/model-networking/src/model-networking/TextureCache.cpp @@ -970,13 +970,6 @@ void ImageReader::read() { Q_ARG(int, texture->getHeight())); } -void TextureCache::setHmdPreviewTexture(gpu::TexturePointer texturePointer) { - if (!_hmdPreviewNetworkTexture) { - _hmdPreviewNetworkTexture.reset(new NetworkTexture(HMD_PREVIEW_FRAME_URL)); - } - _hmdPreviewNetworkTexture->setImage(texturePointer, texturePointer->getWidth(), texturePointer->getHeight()); -} - NetworkTexturePointer TextureCache::getResourceTexture(QUrl resourceTextureUrl) { gpu::TexturePointer texture; if (resourceTextureUrl == SPECTATOR_CAMERA_FRAME_URL) { @@ -991,15 +984,30 @@ NetworkTexturePointer TextureCache::getResourceTexture(QUrl resourceTextureUrl) } } } + // FIXME: Generalize this, DRY up this code if (resourceTextureUrl == HMD_PREVIEW_FRAME_URL) { - if (_hmdPreviewNetworkTexture) { - return _hmdPreviewNetworkTexture; + if (!_hmdPreviewNetworkTexture) { + _hmdPreviewNetworkTexture.reset(new NetworkTexture(resourceTextureUrl)); + } + if (_hmdPreviewFramebuffer) { + texture = _hmdPreviewFramebuffer->getRenderBuffer(0); + if (texture) { + _hmdPreviewNetworkTexture->setImage(texture, texture->getWidth(), texture->getHeight()); + return _hmdPreviewNetworkTexture; + } } } return NetworkTexturePointer(); } +const gpu::FramebufferPointer& TextureCache::getHmdPreviewFramebuffer() { + if (!_hmdPreviewFramebuffer) { + _hmdPreviewFramebuffer.reset(gpu::Framebuffer::create("hmdPreview",gpu::Element::COLOR_SRGBA_32, 2040, 1024)); + } + return _hmdPreviewFramebuffer; +} + const gpu::FramebufferPointer& TextureCache::getSpectatorCameraFramebuffer() { if (!_spectatorCameraFramebuffer) { resetSpectatorCameraFramebuffer(2048, 1024); diff --git a/libraries/model-networking/src/model-networking/TextureCache.h b/libraries/model-networking/src/model-networking/TextureCache.h index 7e3d421ad0..8b7607d04d 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.h +++ b/libraries/model-networking/src/model-networking/TextureCache.h @@ -170,7 +170,7 @@ public: NetworkTexturePointer getResourceTexture(QUrl resourceTextureUrl); const gpu::FramebufferPointer& getSpectatorCameraFramebuffer(); void resetSpectatorCameraFramebuffer(int width, int height); - void setHmdPreviewTexture(gpu::TexturePointer texturePointer); + const gpu::FramebufferPointer& getHmdPreviewFramebuffer(); protected: // Overload ResourceCache::prefetch to allow specifying texture type for loads @@ -205,6 +205,7 @@ private: gpu::FramebufferPointer _spectatorCameraFramebuffer; NetworkTexturePointer _hmdPreviewNetworkTexture; + gpu::FramebufferPointer _hmdPreviewFramebuffer; }; #endif // hifi_TextureCache_h