mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-16 22:30:42 +02:00
first cut at improved HMD preview
This commit is contained in:
parent
41bbfcd578
commit
f923b2ede4
2 changed files with 141 additions and 5 deletions
|
@ -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);
|
||||
|
|
|
@ -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 };
|
||||
|
|
Loading…
Reference in a new issue