mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-27 14:12:28 +00:00
Implement wide side-by-side mode, using adjusted aspect ratio in projection matrix.
Use optimal framebuffer size for side-by-side modes.
This commit is contained in:
parent
9a257ac158
commit
1f79e23d5b
8 changed files with 87 additions and 24 deletions
|
@ -57,6 +57,7 @@
|
||||||
#include "gl/shaders/gl_colormapshader.h"
|
#include "gl/shaders/gl_colormapshader.h"
|
||||||
#include "gl/shaders/gl_lensshader.h"
|
#include "gl/shaders/gl_lensshader.h"
|
||||||
#include "gl/shaders/gl_presentshader.h"
|
#include "gl/shaders/gl_presentshader.h"
|
||||||
|
#include "gl/stereo3d/gl_stereo3d.h"
|
||||||
#include "gl/textures/gl_texture.h"
|
#include "gl/textures/gl_texture.h"
|
||||||
#include "gl/textures/gl_translate.h"
|
#include "gl/textures/gl_translate.h"
|
||||||
#include "gl/textures/gl_material.h"
|
#include "gl/textures/gl_material.h"
|
||||||
|
@ -273,6 +274,8 @@ void FGLRenderer::SetOutputViewport(GL_IRECT *bounds)
|
||||||
mSceneViewport.top += mOutputLetterbox.top;
|
mSceneViewport.top += mOutputLetterbox.top;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s3d::Stereo3DMode::getCurrentMode().AdjustViewports();
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
|
@ -801,7 +801,6 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo
|
||||||
{
|
{
|
||||||
const s3d::EyePose * eye = stereo3dMode.getEyePose(eye_ix);
|
const s3d::EyePose * eye = stereo3dMode.getEyePose(eye_ix);
|
||||||
eye->SetUp();
|
eye->SetUp();
|
||||||
// TODO: stereo specific viewport - needed when implementing side-by-side modes etc.
|
|
||||||
SetOutputViewport(bounds);
|
SetOutputViewport(bounds);
|
||||||
Set3DViewport(mainview);
|
Set3DViewport(mainview);
|
||||||
mDrawingScene2D = true;
|
mDrawingScene2D = true;
|
||||||
|
|
|
@ -39,6 +39,36 @@
|
||||||
|
|
||||||
namespace s3d {
|
namespace s3d {
|
||||||
|
|
||||||
|
void SideBySideBase::Present() const
|
||||||
|
{
|
||||||
|
GLRenderer->mBuffers->BindOutputFB();
|
||||||
|
GLRenderer->ClearBorders();
|
||||||
|
|
||||||
|
// Compute screen regions to use for left and right eye views
|
||||||
|
int leftWidth = GLRenderer->mOutputLetterbox.width / 2;
|
||||||
|
int rightWidth = GLRenderer->mOutputLetterbox.width - leftWidth;
|
||||||
|
GL_IRECT leftHalfScreen = GLRenderer->mOutputLetterbox;
|
||||||
|
leftHalfScreen.width = leftWidth;
|
||||||
|
GL_IRECT rightHalfScreen = GLRenderer->mOutputLetterbox;
|
||||||
|
rightHalfScreen.width = rightWidth;
|
||||||
|
rightHalfScreen.left += leftWidth;
|
||||||
|
|
||||||
|
GLRenderer->mBuffers->BindEyeTexture(0, 0);
|
||||||
|
GLRenderer->DrawPresentTexture(leftHalfScreen, true);
|
||||||
|
|
||||||
|
GLRenderer->mBuffers->BindEyeTexture(1, 0);
|
||||||
|
GLRenderer->DrawPresentTexture(rightHalfScreen, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// AdjustViewports() is called from within FLGRenderer::SetOutputViewport(...)
|
||||||
|
void SideBySideBase::AdjustViewports() const
|
||||||
|
{
|
||||||
|
// Change size of renderbuffer, and align to screen
|
||||||
|
GLRenderer->mSceneViewport.width /= 2;
|
||||||
|
GLRenderer->mSceneViewport.left /= 2;
|
||||||
|
GLRenderer->mScreenViewport.width /= 2;
|
||||||
|
GLRenderer->mScreenViewport.left /= 2;
|
||||||
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
const SideBySideSquished& SideBySideSquished::getInstance(float ipd)
|
const SideBySideSquished& SideBySideSquished::getInstance(float ipd)
|
||||||
|
@ -54,26 +84,18 @@ SideBySideSquished::SideBySideSquished(double ipdMeters)
|
||||||
eye_ptrs.Push(&rightEye);
|
eye_ptrs.Push(&rightEye);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SideBySideSquished::Present() const
|
/* static */
|
||||||
|
const SideBySideFull& SideBySideFull::getInstance(float ipd)
|
||||||
{
|
{
|
||||||
GLRenderer->mBuffers->BindOutputFB();
|
static SideBySideFull instance(ipd);
|
||||||
GLRenderer->ClearBorders();
|
return instance;
|
||||||
|
|
||||||
// Compute screen regions to use for left and right eye views
|
|
||||||
int leftWidth = GLRenderer->mOutputLetterbox.width/2;
|
|
||||||
int rightWidth = GLRenderer->mOutputLetterbox.width - leftWidth;
|
|
||||||
GL_IRECT leftHalfScreen = GLRenderer->mOutputLetterbox;
|
|
||||||
leftHalfScreen.width = leftWidth;
|
|
||||||
GL_IRECT rightHalfScreen = GLRenderer->mOutputLetterbox;
|
|
||||||
rightHalfScreen.width = rightWidth;
|
|
||||||
rightHalfScreen.left += leftWidth;
|
|
||||||
|
|
||||||
GLRenderer->mBuffers->BindEyeTexture(0, 0);
|
|
||||||
GLRenderer->DrawPresentTexture(leftHalfScreen, true);
|
|
||||||
|
|
||||||
GLRenderer->mBuffers->BindEyeTexture(1, 0);
|
|
||||||
GLRenderer->DrawPresentTexture(rightHalfScreen, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SideBySideFull::SideBySideFull(double ipdMeters)
|
||||||
|
: leftEye(ipdMeters), rightEye(ipdMeters)
|
||||||
|
{
|
||||||
|
eye_ptrs.Push(&leftEye);
|
||||||
|
eye_ptrs.Push(&rightEye);
|
||||||
|
}
|
||||||
|
|
||||||
} /* namespace s3d */
|
} /* namespace s3d */
|
||||||
|
|
|
@ -44,18 +44,49 @@
|
||||||
|
|
||||||
namespace s3d {
|
namespace s3d {
|
||||||
|
|
||||||
class SideBySideSquished : public Stereo3DMode
|
class SideBySideBase : public Stereo3DMode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void Present() const override;
|
||||||
|
virtual void AdjustViewports() const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SideBySideSquished : public SideBySideBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static const SideBySideSquished& getInstance(float ipd);
|
static const SideBySideSquished& getInstance(float ipd);
|
||||||
|
|
||||||
SideBySideSquished(double ipdMeters);
|
SideBySideSquished(double ipdMeters);
|
||||||
void Present() const override;
|
|
||||||
private:
|
private:
|
||||||
LeftEyePose leftEye;
|
LeftEyePose leftEye;
|
||||||
RightEyePose rightEye;
|
RightEyePose rightEye;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SBSFLeftEyePose : public LeftEyePose {
|
||||||
|
public:
|
||||||
|
SBSFLeftEyePose(double ipdMeters) : LeftEyePose(ipdMeters) {}
|
||||||
|
virtual VSMatrix GetProjection(float fov, float aspectRatio, float fovRatio) const override {
|
||||||
|
return LeftEyePose::GetProjection(fov, 0.5f * aspectRatio, fovRatio);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SBSFRightEyePose : public RightEyePose {
|
||||||
|
public:
|
||||||
|
SBSFRightEyePose(double ipdMeters) : RightEyePose(ipdMeters) {}
|
||||||
|
virtual VSMatrix GetProjection(float fov, float aspectRatio, float fovRatio) const override {
|
||||||
|
return RightEyePose::GetProjection(fov, 0.5f * aspectRatio, fovRatio);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SideBySideFull : public SideBySideBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const SideBySideFull& getInstance(float ipd);
|
||||||
|
SideBySideFull(double ipdMeters);
|
||||||
|
private:
|
||||||
|
SBSFLeftEyePose leftEye;
|
||||||
|
SBSFRightEyePose rightEye;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
} /* namespace s3d */
|
} /* namespace s3d */
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <cstring> // needed for memcpy on linux, which is needed by VSMatrix copy ctor
|
#include <cstring> // needed for memcpy on linux, which is needed by VSMatrix copy ctor
|
||||||
#include "tarray.h"
|
#include "tarray.h"
|
||||||
#include "gl/data/gl_matrix.h"
|
#include "gl/data/gl_matrix.h"
|
||||||
|
#include "gl/renderer/gl_renderer.h"
|
||||||
|
|
||||||
|
|
||||||
/* stereoscopic 3D API */
|
/* stereoscopic 3D API */
|
||||||
|
@ -78,6 +79,7 @@ public:
|
||||||
virtual void TearDown() const {};
|
virtual void TearDown() const {};
|
||||||
|
|
||||||
virtual bool IsMono() const { return false; }
|
virtual bool IsMono() const { return false; }
|
||||||
|
virtual void AdjustViewports() const {};
|
||||||
virtual void Present() const = 0;
|
virtual void Present() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -72,7 +72,9 @@ const Stereo3DMode& Stereo3DMode::getCurrentMode()
|
||||||
case 2:
|
case 2:
|
||||||
setCurrentMode(RedCyan::getInstance(vr_ipd));
|
setCurrentMode(RedCyan::getInstance(vr_ipd));
|
||||||
break;
|
break;
|
||||||
// TODO: missing index 3 for not-yet-implemented side-by-side mode, to match values from GZ3Doom
|
case 3:
|
||||||
|
setCurrentMode(SideBySideFull::getInstance(vr_ipd));
|
||||||
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
setCurrentMode(SideBySideSquished::getInstance(vr_ipd));
|
setCurrentMode(SideBySideSquished::getInstance(vr_ipd));
|
||||||
break;
|
break;
|
||||||
|
@ -93,7 +95,9 @@ const Stereo3DMode& Stereo3DMode::getCurrentMode()
|
||||||
// TODO: 8: Oculus Rift
|
// TODO: 8: Oculus Rift
|
||||||
case 9:
|
case 9:
|
||||||
setCurrentMode(AmberBlue::getInstance(vr_ipd));
|
setCurrentMode(AmberBlue::getInstance(vr_ipd));
|
||||||
break; case 0:
|
break;
|
||||||
|
// TODO: 10: HTC Vive/OpenVR
|
||||||
|
case 0:
|
||||||
default:
|
default:
|
||||||
setCurrentMode(MonoView::getInstance());
|
setCurrentMode(MonoView::getInstance());
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -2701,6 +2701,7 @@ OPTVAL_REDCYAN = "Red/Cyan";
|
||||||
OPTVAL_AMBERBLUE = "Amber/Blue";
|
OPTVAL_AMBERBLUE = "Amber/Blue";
|
||||||
OPTVAL_LEFTEYE = "Left Eye";
|
OPTVAL_LEFTEYE = "Left Eye";
|
||||||
OPTVAL_RIGHTEYE = "Right Eye";
|
OPTVAL_RIGHTEYE = "Right Eye";
|
||||||
|
OPTVAL_SBSFULL = "Side-by-side Full";
|
||||||
OPTVAL_SBSNARROW = "Side-by-side Narrow";
|
OPTVAL_SBSNARROW = "Side-by-side Narrow";
|
||||||
OPTVAL_QUADBUFFERED = "Quad-buffered";
|
OPTVAL_QUADBUFFERED = "Quad-buffered";
|
||||||
OPTVAL_UNCHARTED2 = "Uncharted 2";
|
OPTVAL_UNCHARTED2 = "Uncharted 2";
|
||||||
|
|
|
@ -167,6 +167,7 @@ OptionValue VRMode
|
||||||
1, "$OPTVAL_GREENMAGENTA"
|
1, "$OPTVAL_GREENMAGENTA"
|
||||||
2, "$OPTVAL_REDCYAN"
|
2, "$OPTVAL_REDCYAN"
|
||||||
9, "$OPTVAL_AMBERBLUE"
|
9, "$OPTVAL_AMBERBLUE"
|
||||||
|
3, "$OPTVAL_SBSFULL"
|
||||||
4, "$OPTVAL_SBSNARROW"
|
4, "$OPTVAL_SBSNARROW"
|
||||||
5, "$OPTVAL_LEFTEYE"
|
5, "$OPTVAL_LEFTEYE"
|
||||||
6, "$OPTVAL_RIGHTEYE"
|
6, "$OPTVAL_RIGHTEYE"
|
||||||
|
|
Loading…
Reference in a new issue