Present function for left, right and quad-buffered stereo3d

This commit is contained in:
Magnus Norddahl 2016-09-08 21:15:00 +02:00 committed by Christoph Oelckers
parent 8b7267cf87
commit 63dc394913
6 changed files with 54 additions and 41 deletions

View file

@ -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)
{ {

View file

@ -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;
}; };

View file

@ -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

View file

@ -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(&centralEye); } MonoView() { eye_ptrs.Push(&centralEye); }

View file

@ -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 */

View file

@ -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;
}; };