mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 23:12:24 +00:00
Present function for left, right and quad-buffered stereo3d
This commit is contained in:
parent
8b7267cf87
commit
63dc394913
6 changed files with 54 additions and 41 deletions
|
@ -34,6 +34,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "gl_quadstereo.h"
|
#include "gl_quadstereo.h"
|
||||||
|
#include "gl/renderer/gl_renderer.h"
|
||||||
|
#include "gl/renderer/gl_renderbuffers.h"
|
||||||
|
|
||||||
namespace s3d {
|
namespace s3d {
|
||||||
|
|
||||||
|
@ -46,7 +48,7 @@ QuadStereo::QuadStereo(double ipdMeters)
|
||||||
GLboolean supportsStereo, supportsBuffered;
|
GLboolean supportsStereo, supportsBuffered;
|
||||||
glGetBooleanv(GL_STEREO, &supportsStereo);
|
glGetBooleanv(GL_STEREO, &supportsStereo);
|
||||||
glGetBooleanv(GL_DOUBLEBUFFER, &supportsBuffered);
|
glGetBooleanv(GL_DOUBLEBUFFER, &supportsBuffered);
|
||||||
bool bQuadStereoSupported = supportsStereo && supportsBuffered;
|
bQuadStereoSupported = supportsStereo && supportsBuffered;
|
||||||
leftEye.bQuadStereoSupported = bQuadStereoSupported;
|
leftEye.bQuadStereoSupported = bQuadStereoSupported;
|
||||||
rightEye.bQuadStereoSupported = bQuadStereoSupported;
|
rightEye.bQuadStereoSupported = bQuadStereoSupported;
|
||||||
|
|
||||||
|
@ -57,6 +59,33 @@ QuadStereo::QuadStereo(double ipdMeters)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QuadStereo::Present() const
|
||||||
|
{
|
||||||
|
if (bQuadStereoSupported)
|
||||||
|
{
|
||||||
|
GLRenderer->mBuffers->BindOutputFB();
|
||||||
|
|
||||||
|
glDrawBuffer(GL_BACK_LEFT);
|
||||||
|
GLRenderer->ClearBorders();
|
||||||
|
GLRenderer->mBuffers->BindEyeTexture(0, 0);
|
||||||
|
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
|
||||||
|
|
||||||
|
glDrawBuffer(GL_BACK_RIGHT);
|
||||||
|
GLRenderer->ClearBorders();
|
||||||
|
GLRenderer->mBuffers->BindEyeTexture(1, 0);
|
||||||
|
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
|
||||||
|
|
||||||
|
glDrawBuffer(GL_BACK);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GLRenderer->mBuffers->BindOutputFB();
|
||||||
|
GLRenderer->ClearBorders();
|
||||||
|
GLRenderer->mBuffers->BindEyeTexture(1, 0);
|
||||||
|
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
const QuadStereo& QuadStereo::getInstance(float ipd)
|
const QuadStereo& QuadStereo::getInstance(float ipd)
|
||||||
{
|
{
|
||||||
|
|
|
@ -47,14 +47,6 @@ class QuadStereoLeftPose : public LeftEyePose
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QuadStereoLeftPose(float ipd) : LeftEyePose(ipd), bQuadStereoSupported(false) {}
|
QuadStereoLeftPose(float ipd) : LeftEyePose(ipd), bQuadStereoSupported(false) {}
|
||||||
virtual void SetUp() const {
|
|
||||||
if (bQuadStereoSupported)
|
|
||||||
glDrawBuffer(GL_BACK_LEFT);
|
|
||||||
}
|
|
||||||
virtual void TearDown() const {
|
|
||||||
if (bQuadStereoSupported)
|
|
||||||
glDrawBuffer(GL_BACK);
|
|
||||||
}
|
|
||||||
bool bQuadStereoSupported;
|
bool bQuadStereoSupported;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -62,14 +54,6 @@ class QuadStereoRightPose : public RightEyePose
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QuadStereoRightPose(float ipd) : RightEyePose(ipd), bQuadStereoSupported(false){}
|
QuadStereoRightPose(float ipd) : RightEyePose(ipd), bQuadStereoSupported(false){}
|
||||||
virtual void SetUp() const {
|
|
||||||
if (bQuadStereoSupported)
|
|
||||||
glDrawBuffer(GL_BACK_RIGHT);
|
|
||||||
}
|
|
||||||
virtual void TearDown() const {
|
|
||||||
if (bQuadStereoSupported)
|
|
||||||
glDrawBuffer(GL_BACK);
|
|
||||||
}
|
|
||||||
bool bQuadStereoSupported;
|
bool bQuadStereoSupported;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -84,10 +68,12 @@ class QuadStereo : public Stereo3DMode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QuadStereo(double ipdMeters);
|
QuadStereo(double ipdMeters);
|
||||||
|
void Present() const override;
|
||||||
static const QuadStereo& getInstance(float ipd);
|
static const QuadStereo& getInstance(float ipd);
|
||||||
private:
|
private:
|
||||||
QuadStereoLeftPose leftEye;
|
QuadStereoLeftPose leftEye;
|
||||||
QuadStereoRightPose rightEye;
|
QuadStereoRightPose rightEye;
|
||||||
|
bool bQuadStereoSupported;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@
|
||||||
#include "gl/system/gl_system.h"
|
#include "gl/system/gl_system.h"
|
||||||
#include "gl/stereo3d/gl_stereo3d.h"
|
#include "gl/stereo3d/gl_stereo3d.h"
|
||||||
#include "gl/renderer/gl_renderer.h"
|
#include "gl/renderer/gl_renderer.h"
|
||||||
#include "gl/renderer/gl_renderbuffers.h"
|
|
||||||
#include "vectors.h" // RAD2DEG
|
#include "vectors.h" // RAD2DEG
|
||||||
#include "doomtype.h" // M_PI
|
#include "doomtype.h" // M_PI
|
||||||
|
|
||||||
|
@ -80,28 +79,6 @@ Stereo3DMode::~Stereo3DMode()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stereo3DMode::Present() const
|
|
||||||
{
|
|
||||||
// Example copying eye textures to the back buffer:
|
|
||||||
|
|
||||||
// The letterbox for the output destination.
|
|
||||||
// If stereo modes needs different dimensions then that needs to be added to FGLRenderer::SetOutputViewport.
|
|
||||||
const auto &box = GLRenderer->mOutputLetterbox;
|
|
||||||
|
|
||||||
GLRenderer->mBuffers->BindOutputFB();
|
|
||||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
for (int eye_ix = 0; eye_ix < eye_count(); ++eye_ix)
|
|
||||||
{
|
|
||||||
GLRenderer->mBuffers->BindEyeFB(eye_ix, true);
|
|
||||||
int width = GLRenderer->mBuffers->GetWidth();
|
|
||||||
int height = GLRenderer->mBuffers->GetHeight();
|
|
||||||
glBlitFramebuffer(0, 0, width, height, box.left + eye_ix * box.width / eye_count(), box.top, box.left + (eye_ix + 1) * box.width / eye_count(), box.height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
|
||||||
}
|
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Avoid static initialization order fiasco by declaring first Mode type (Mono) here in the
|
// Avoid static initialization order fiasco by declaring first Mode type (Mono) here in the
|
||||||
// same source file as Stereo3DMode::getCurrentMode()
|
// same source file as Stereo3DMode::getCurrentMode()
|
||||||
// https://isocpp.org/wiki/faq/ctors#static-init-order
|
// https://isocpp.org/wiki/faq/ctors#static-init-order
|
||||||
|
|
|
@ -86,7 +86,7 @@ public:
|
||||||
virtual void TearDown() const {};
|
virtual void TearDown() const {};
|
||||||
|
|
||||||
virtual bool IsMono() const { return false; }
|
virtual bool IsMono() const { return false; }
|
||||||
virtual void Present() const;
|
virtual void Present() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TArray<const EyePose *> eye_ptrs;
|
TArray<const EyePose *> eye_ptrs;
|
||||||
|
@ -106,6 +106,7 @@ public:
|
||||||
static const MonoView& getInstance();
|
static const MonoView& getInstance();
|
||||||
|
|
||||||
bool IsMono() const override { return true; }
|
bool IsMono() const override { return true; }
|
||||||
|
void Present() const override { }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MonoView() { eye_ptrs.Push(¢ralEye); }
|
MonoView() { eye_ptrs.Push(¢ralEye); }
|
||||||
|
|
|
@ -37,7 +37,10 @@
|
||||||
#include "vectors.h" // RAD2DEG
|
#include "vectors.h" // RAD2DEG
|
||||||
#include "doomtype.h" // M_PI
|
#include "doomtype.h" // M_PI
|
||||||
#include "gl/system/gl_cvars.h"
|
#include "gl/system/gl_cvars.h"
|
||||||
|
#include "gl/system/gl_system.h"
|
||||||
|
#include "gl/renderer/gl_renderstate.h"
|
||||||
#include "gl/renderer/gl_renderer.h"
|
#include "gl/renderer/gl_renderer.h"
|
||||||
|
#include "gl/renderer/gl_renderbuffers.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
EXTERN_CVAR(Float, vr_screendist)
|
EXTERN_CVAR(Float, vr_screendist)
|
||||||
|
@ -89,6 +92,13 @@ const LeftEyeView& LeftEyeView::getInstance(float ipd)
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LeftEyeView::Present() const
|
||||||
|
{
|
||||||
|
GLRenderer->mBuffers->BindOutputFB();
|
||||||
|
GLRenderer->ClearBorders();
|
||||||
|
GLRenderer->mBuffers->BindEyeTexture(0, 0);
|
||||||
|
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
|
||||||
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
const RightEyeView& RightEyeView::getInstance(float ipd)
|
const RightEyeView& RightEyeView::getInstance(float ipd)
|
||||||
|
@ -98,5 +108,13 @@ const RightEyeView& RightEyeView::getInstance(float ipd)
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RightEyeView::Present() const
|
||||||
|
{
|
||||||
|
GLRenderer->mBuffers->BindOutputFB();
|
||||||
|
GLRenderer->ClearBorders();
|
||||||
|
GLRenderer->mBuffers->BindEyeTexture(0, 0);
|
||||||
|
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} /* namespace s3d */
|
} /* namespace s3d */
|
||||||
|
|
|
@ -83,6 +83,7 @@ public:
|
||||||
LeftEyeView(float ipd) : eye(ipd) { eye_ptrs.Push(&eye); }
|
LeftEyeView(float ipd) : eye(ipd) { eye_ptrs.Push(&eye); }
|
||||||
float getIpd() const { return eye.getIpd(); }
|
float getIpd() const { return eye.getIpd(); }
|
||||||
void setIpd(float ipd) { eye.setIpd(ipd); }
|
void setIpd(float ipd) { eye.setIpd(ipd); }
|
||||||
|
void Present() const override;
|
||||||
protected:
|
protected:
|
||||||
LeftEyePose eye;
|
LeftEyePose eye;
|
||||||
};
|
};
|
||||||
|
@ -96,6 +97,7 @@ public:
|
||||||
RightEyeView(float ipd) : eye(ipd) { eye_ptrs.Push(&eye); }
|
RightEyeView(float ipd) : eye(ipd) { eye_ptrs.Push(&eye); }
|
||||||
float getIpd() const { return eye.getIpd(); }
|
float getIpd() const { return eye.getIpd(); }
|
||||||
void setIpd(float ipd) { eye.setIpd(ipd); }
|
void setIpd(float ipd) { eye.setIpd(ipd); }
|
||||||
|
void Present() const override;
|
||||||
protected:
|
protected:
|
||||||
RightEyePose eye;
|
RightEyePose eye;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue