From f923b2ede46196ef2243a4a257763d94fbfaa010 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sun, 18 Sep 2016 20:32:23 -0700 Subject: [PATCH] first cut at improved HMD preview --- .../display-plugins/hmd/HmdDisplayPlugin.cpp | 144 +++++++++++++++++- .../display-plugins/hmd/HmdDisplayPlugin.h | 2 + 2 files changed, 141 insertions(+), 5 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp index 28b19ee9e0..f06fb622b7 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp @@ -137,6 +137,16 @@ ivec4 HmdDisplayPlugin::getViewportForSourceSize(const uvec2& size) const { float windowAspect = aspect(windowSize); float sceneAspect = aspect(size); float aspectRatio = sceneAspect / windowAspect; + + qDebug() << "size:" << size; + + /* + qDebug() << "windowSize:" << windowSize; + qDebug() << "windowAspect:" << windowAspect; + qDebug() << "sceneAspect:" << sceneAspect; + qDebug() << "aspectRatio:" << aspectRatio; + */ + uvec2 targetViewportSize = windowSize; if (aspectRatio < 1.0f) { targetViewportSize.x *= aspectRatio; @@ -152,6 +162,41 @@ ivec4 HmdDisplayPlugin::getViewportForSourceSize(const uvec2& size) const { return ivec4(targetViewportPosition, targetViewportSize); } +ivec4 HmdDisplayPlugin::getViewportForClippedSource(const uvec2& sourceSize, const uvec2& clippedRatio) const { + // screen preview mirroring + auto window = _container->getPrimaryWidget(); + auto devicePixelRatio = window->devicePixelRatio(); + auto windowSize = toGlm(window->size()); + windowSize *= devicePixelRatio; + float windowAspect = aspect(windowSize); + float sceneAspect = aspect(sourceSize); + float clippedAspect = aspect(clippedRatio); + + float aspectRatio = sceneAspect / windowAspect; // old way + //float aspectRatio = clippedAspect / windowAspect; + + qDebug() << "size:" << sourceSize; + qDebug() << "windowSize:" << windowSize; + qDebug() << "windowAspect:" << windowAspect; + qDebug() << "sceneAspect:" << sceneAspect; + qDebug() << "aspectRatio:" << aspectRatio; + + uvec2 targetViewportSize = windowSize; + if (aspectRatio < 1.0f) { + targetViewportSize.x *= aspectRatio; + } else { + targetViewportSize.y /= aspectRatio; + } + uvec2 targetViewportPosition; + if (targetViewportSize.x < windowSize.x) { + targetViewportPosition.x = (windowSize.x - targetViewportSize.x) / 2; + } else if (targetViewportSize.y < windowSize.y) { + targetViewportPosition.y = (windowSize.y - targetViewportSize.y) / 2; + } + return ivec4(targetViewportPosition, targetViewportSize); +} + + void HmdDisplayPlugin::internalPresent() { PROFILE_RANGE_EX(__FUNCTION__, 0xff00ff00, (uint64_t)presentCount()) @@ -164,16 +209,105 @@ void HmdDisplayPlugin::internalPresent() { if (_monoPreview) { sourceSize.x >>= 1; } - auto viewport = getViewportForSourceSize(sourceSize); + + /**** + eye image size: (1512, 1680) + desired aspect ratio: 16:9 + desired clipped image: 1512x850 + + original clipping: 0,415 + + + examples: + window size: 1512x850 + + viewport: 0, -415, + 1512, 1680 + + scissor: 0,0, 1512, 850 + ****/ + + // viewport is ivec4(targetViewportPosition, targetViewportSize); + + //qDebug() << "sourceSize:" << sourceSize.x << "," << sourceSize.y; + + const unsigned int RATIO_Y = 9; + const unsigned int RATIO_X = 16; + glm::uvec2 originalClippedSize { sourceSize.x, sourceSize.x * RATIO_Y / RATIO_X }; + + glm::ivec4 viewport = getViewportForSourceSize(sourceSize); + glm::ivec4 scissor = viewport; + + /* + qDebug() << "viewport.pos:" << viewport.x << "," << viewport.y + << "viewport.size:" << viewport.z << "," << viewport.w; + */ + render([&](gpu::Batch& batch) { + + if (_monoPreview) { + /* + glm::mat4 eyeProjection; + eyeProjection[0] = vec4 { 0.759056330, 0.000000000, 0.000000000, 0.000000000 }; + eyeProjection[1] = vec4 { 0.000000000, 0.682773232, 0.000000000, 0.000000000 }; + eyeProjection[2] = vec4 { -0.0580431037, -0.00619550655, -1.00000489, -1.00000000 }; + eyeProjection[3] = vec4 { 0.000000000, 0.000000000, -0.0800003856, 0.000000000 }; + glm::mat4 inverseEyeProjection = glm::inverse(eyeProjection); + vec2 eyeRenderTargetSize = viewport;// sourceSize; // { 3024 / 2, 1680 }; + + vec4 left = vec4(-1, 0, -1, 1); + vec4 right = vec4(1, 0, -1, 1); + vec4 right2 = inverseEyeProjection * right; + vec4 left2 = inverseEyeProjection * left; + left2 /= left2.w; + right2 /= right2.w; + float width = -left2.x + right2.x; + float leftBias = -left2.x / width; + float leftCenterPixel = eyeRenderTargetSize.x * leftBias; + */ + + auto window = _container->getPrimaryWidget(); + float devicePixelRatio = window->devicePixelRatio(); + glm::vec2 windowSize = toGlm(window->size()); + windowSize *= devicePixelRatio; + + float windowAspect = aspect(windowSize); // example: 1920 x 1080 = 1.78 + float sourceAspect = aspect(sourceSize); // usually: 1512 x 1680 (per eye) = 0.9 + float sceneAspect = aspect(originalClippedSize); // usually: 1512 x 850 = 1.78 + float sourceAspectRatio = sourceAspect / windowAspect; // typical: 0.505 + float clippedAspectRatio = sceneAspect / windowAspect; // typically: 1 + + bool scaleToWidth = windowAspect < sceneAspect; + + if (scaleToWidth) { + float ratio = (float)windowSize.x / (float)sourceSize.x; + int viewportSizeX = sourceSize.x * ratio; + int viewportSizeY = sourceSize.y * ratio; + int scissorSizeX = originalClippedSize.x * ratio; + int scissorSizeY = originalClippedSize.y * ratio; + int viewportOffset = ((int)windowSize.y - viewportSizeY) / 2; + int scissorOffset = ((int)windowSize.y - scissorSizeY) / 2; + scissor = ivec4(0, scissorOffset, scissorSizeX, scissorSizeY); + viewport = ivec4(0, viewportOffset, viewportSizeX, viewportSizeY); + } else { + float ratio = (float)windowSize.y / (float)originalClippedSize.y; + int viewportSizeX = sourceSize.x * ratio; + int viewportSizeY = sourceSize.y * ratio; + int scissorSizeX = originalClippedSize.x * ratio; + int scissorSizeY = originalClippedSize.y * ratio; + int viewportOffset = ((int)windowSize.y - viewportSizeY) / 2; + int scissorOffset = ((int)windowSize.x - scissorSizeX) / 2; + scissor = ivec4(scissorOffset, 0, scissorSizeX, scissorSizeY); + viewport = ivec4(scissorOffset, viewportOffset, viewportSizeX, viewportSizeY); + } + viewport.z *= 2; + } + batch.enableStereo(false); batch.resetViewTransform(); batch.setFramebuffer(gpu::FramebufferPointer()); batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, vec4(0)); - batch.setStateScissorRect(viewport); - if (_monoPreview) { - viewport.z *= 2; - } + batch.setStateScissorRect(scissor); // was viewport batch.setViewportTransform(viewport); batch.setResourceTexture(0, _compositeFramebuffer->getRenderBuffer(0)); batch.setPipeline(_presentPipeline); diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h index a5710b6077..f76c11b8d3 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h @@ -102,6 +102,8 @@ protected: bool _disablePreview{ true }; private: ivec4 getViewportForSourceSize(const uvec2& size) const; + ivec4 getViewportForClippedSource(const uvec2& sourceSize, const uvec2& clippedRatio) const; + bool _disablePreviewItemAdded { false }; bool _monoPreview { true };