diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 88aa56cccf..0993daaa8b 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -418,6 +418,19 @@ void OpenGLDisplayPlugin::customizeContext() { _hudPipeline = gpu::Pipeline::create(program, state); } + { + auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS(); + auto ps = gpu::StandardShaderLib::getDrawTextureMirroredXPS(); + gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); + gpu::Shader::makeProgram(*program); + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + state->setDepthTest(gpu::State::DepthTest(false)); + state->setBlendFunction(true, + gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, + gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + _mirrorHUDPipeline = gpu::Pipeline::create(program, state); + } + { auto vs = gpu::StandardShaderLib::getDrawTransformUnitQuadVS(); auto ps = gpu::StandardShaderLib::getDrawTexturePS(); @@ -438,6 +451,7 @@ void OpenGLDisplayPlugin::uncustomizeContext() { _presentPipeline.reset(); _cursorPipeline.reset(); _hudPipeline.reset(); + _mirrorHUDPipeline.reset(); _compositeFramebuffer.reset(); withPresentThreadLock([&] { _currentFrame.reset(); @@ -562,11 +576,11 @@ void OpenGLDisplayPlugin::updateFrameData() { }); } -std::function OpenGLDisplayPlugin::getHUDOperator() { - return [this](gpu::Batch& batch, const gpu::TexturePointer& hudTexture) { +std::function OpenGLDisplayPlugin::getHUDOperator() { + return [this](gpu::Batch& batch, const gpu::TexturePointer& hudTexture, bool mirror) { if (_hudPipeline) { batch.enableStereo(false); - batch.setPipeline(_hudPipeline); + batch.setPipeline(mirror ? _mirrorHUDPipeline : _hudPipeline); batch.setResourceTexture(0, hudTexture); if (isStereo()) { for_each_eye([&](Eye eye) { diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index ec775aed4c..d67c0b8663 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -95,7 +95,7 @@ protected: virtual QThread::Priority getPresentPriority() { return QThread::HighPriority; } virtual void compositeLayers(); virtual void compositeScene(); - virtual std::function getHUDOperator(); + virtual std::function getHUDOperator(); virtual void compositePointer(); virtual void compositeExtra() {}; @@ -140,6 +140,8 @@ protected: gpu::Frame* _lastFrame { nullptr }; gpu::FramebufferPointer _compositeFramebuffer; gpu::PipelinePointer _hudPipeline; + gpu::PipelinePointer _mirrorHUDPipeline; + gpu::ShaderPointer _mirrorHUDPS; gpu::PipelinePointer _simplePipeline; gpu::PipelinePointer _presentPipeline; gpu::PipelinePointer _cursorPipeline; diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp index 0785226836..1d7fee38eb 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp @@ -419,9 +419,9 @@ void HmdDisplayPlugin::HUDRenderer::updatePipeline() { } } -std::function HmdDisplayPlugin::HUDRenderer::render(HmdDisplayPlugin& plugin) { +std::function HmdDisplayPlugin::HUDRenderer::render(HmdDisplayPlugin& plugin) { updatePipeline(); - return [this](gpu::Batch& batch, const gpu::TexturePointer& hudTexture) { + return [this](gpu::Batch& batch, const gpu::TexturePointer& hudTexture, bool mirror) { if (pipeline) { batch.setPipeline(pipeline); @@ -436,7 +436,11 @@ std::function HmdDisplayPlugin::H batch.setUniformBuffer(uniformsLocation, uniformsBuffer); auto compositorHelper = DependencyManager::get(); - batch.setModelTransform(compositorHelper->getUiTransform()); + glm::mat4 modelTransform = compositorHelper->getUiTransform(); + if (mirror) { + modelTransform = glm::scale(modelTransform, glm::vec3(-1, 1, 1)); + } + batch.setModelTransform(modelTransform); batch.setResourceTexture(0, hudTexture); batch.drawIndexed(gpu::TRIANGLES, indexCount); @@ -468,7 +472,7 @@ void HmdDisplayPlugin::compositePointer() { }); } -std::function HmdDisplayPlugin::getHUDOperator() { +std::function HmdDisplayPlugin::getHUDOperator() { return _hudRenderer.render(*this); } diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h index a7a6d2938d..d2d30df093 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h @@ -53,7 +53,7 @@ protected: bool internalActivate() override; void internalDeactivate() override; - std::function getHUDOperator() override; + std::function getHUDOperator() override; void compositePointer() override; void internalPresent() override; void customizeContext() override; @@ -116,6 +116,6 @@ private: void build(); void updatePipeline(); - std::function render(HmdDisplayPlugin& plugin); + std::function render(HmdDisplayPlugin& plugin); } _hudRenderer; }; diff --git a/libraries/gpu/src/gpu/DrawTextureMirroredX.slf b/libraries/gpu/src/gpu/DrawTextureMirroredX.slf new file mode 100644 index 0000000000..aef4033496 --- /dev/null +++ b/libraries/gpu/src/gpu/DrawTextureMirroredX.slf @@ -0,0 +1,22 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// Draw texture 0 fetched at (1.0 - texcoord.x, texcoord.y) +// +// Created by Sam Gondelman on 10/24/2017 +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + + +uniform sampler2D colorMap; + +in vec2 varTexCoord0; +out vec4 outFragColor; + +void main(void) { + outFragColor = texture(colorMap, vec2(1.0 - varTexCoord0.x, varTexCoord0.y)); +} diff --git a/libraries/gpu/src/gpu/StandardShaderLib.cpp b/libraries/gpu/src/gpu/StandardShaderLib.cpp index 756070ff68..7143242618 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.cpp +++ b/libraries/gpu/src/gpu/StandardShaderLib.cpp @@ -23,6 +23,7 @@ const char DrawNada_frag[] = "void main(void) {}"; // DrawNada is really simple. #include "DrawWhite_frag.h" #include "DrawTexture_frag.h" +#include "DrawTextureMirroredX_frag.h" #include "DrawTextureOpaque_frag.h" #include "DrawColoredTexture_frag.h" @@ -37,6 +38,7 @@ ShaderPointer StandardShaderLib::_drawTransformVertexPositionVS; ShaderPointer StandardShaderLib::_drawNadaPS; ShaderPointer StandardShaderLib::_drawWhitePS; ShaderPointer StandardShaderLib::_drawTexturePS; +ShaderPointer StandardShaderLib::_drawTextureMirroredXPS; ShaderPointer StandardShaderLib::_drawTextureOpaquePS; ShaderPointer StandardShaderLib::_drawColoredTexturePS; StandardShaderLib::ProgramMap StandardShaderLib::_programs; @@ -130,6 +132,13 @@ ShaderPointer StandardShaderLib::getDrawTexturePS() { return _drawTexturePS; } +ShaderPointer StandardShaderLib::getDrawTextureMirroredXPS() { + if (!_drawTextureMirroredXPS) { + _drawTextureMirroredXPS = gpu::Shader::createPixel(std::string(DrawTextureMirroredX_frag)); + } + return _drawTextureMirroredXPS; +} + ShaderPointer StandardShaderLib::getDrawTextureOpaquePS() { if (!_drawTextureOpaquePS) { _drawTextureOpaquePS = gpu::Shader::createPixel(std::string(DrawTextureOpaque_frag)); diff --git a/libraries/gpu/src/gpu/StandardShaderLib.h b/libraries/gpu/src/gpu/StandardShaderLib.h index a21d4dea9a..94885b8ca0 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.h +++ b/libraries/gpu/src/gpu/StandardShaderLib.h @@ -47,6 +47,7 @@ public: static ShaderPointer getDrawWhitePS(); static ShaderPointer getDrawTexturePS(); + static ShaderPointer getDrawTextureMirroredXPS(); static ShaderPointer getDrawTextureOpaquePS(); static ShaderPointer getDrawColoredTexturePS(); @@ -67,6 +68,7 @@ protected: static ShaderPointer _drawNadaPS; static ShaderPointer _drawWhitePS; static ShaderPointer _drawTexturePS; + static ShaderPointer _drawTextureMirroredXPS; static ShaderPointer _drawTextureOpaquePS; static ShaderPointer _drawColoredTexturePS; diff --git a/libraries/plugins/src/plugins/DisplayPlugin.cpp b/libraries/plugins/src/plugins/DisplayPlugin.cpp index e43d5e76f3..2a8a72f594 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.cpp +++ b/libraries/plugins/src/plugins/DisplayPlugin.cpp @@ -35,8 +35,8 @@ void DisplayPlugin::waitForPresent() { } } -std::function DisplayPlugin::getHUDOperator() { - std::function hudOperator; +std::function DisplayPlugin::getHUDOperator() { + std::function hudOperator; { QMutexLocker locker(&_presentMutex); hudOperator = _hudOperator; diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index 11ca6f754a..efce158864 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -204,7 +204,7 @@ public: void waitForPresent(); - std::function getHUDOperator(); + std::function getHUDOperator(); static const QString& MENU_PATH(); @@ -218,7 +218,7 @@ protected: gpu::ContextPointer _gpuContext; - std::function _hudOperator { std::function() }; + std::function _hudOperator { std::function() }; private: QMutex _presentMutex; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index ac4e717d60..6a3b560167 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -441,7 +441,7 @@ void CompositeHUD::run(const RenderContextPointer& renderContext) { // Grab the HUD texture gpu::doInBatch(renderContext->args->_context, [&](gpu::Batch& batch) { if (renderContext->args->_hudOperator) { - renderContext->args->_hudOperator(batch, renderContext->args->_hudTexture); + renderContext->args->_hudOperator(batch, renderContext->args->_hudTexture, renderContext->args->_renderMode == RenderArgs::RenderMode::MIRROR_RENDER_MODE); } }); } diff --git a/libraries/render/src/render/Args.h b/libraries/render/src/render/Args.h index a76b60ffe6..627d4f17b2 100644 --- a/libraries/render/src/render/Args.h +++ b/libraries/render/src/render/Args.h @@ -122,7 +122,7 @@ namespace render { render::ScenePointer _scene; int8_t _cameraMode { -1 }; - std::function _hudOperator; + std::function _hudOperator; gpu::TexturePointer _hudTexture; };