Hook up eye textures in renderer

This commit is contained in:
Magnus Norddahl 2016-09-07 21:52:43 +02:00 committed by Christoph Oelckers
parent 4bdd872f09
commit aaa3581ee6
7 changed files with 71 additions and 8 deletions

View file

@ -75,6 +75,7 @@
#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/renderer/gl_2ddrawer.h" #include "gl/renderer/gl_2ddrawer.h"
#include "gl/stereo3d/gl_stereo3d.h"
//========================================================================== //==========================================================================
// //
@ -375,6 +376,38 @@ void FGLRenderer::LensDistortScene()
FGLDebug::PopGroup(); FGLDebug::PopGroup();
} }
//-----------------------------------------------------------------------------
//
// Copies the rendered screen to its final destination
//
//-----------------------------------------------------------------------------
void FGLRenderer::Flush()
{
const s3d::Stereo3DMode& stereo3dMode = s3d::Stereo3DMode::getCurrentMode();
if (stereo3dMode.IsMono() || !FGLRenderBuffers::IsEnabled())
{
CopyToBackbuffer(nullptr, true);
}
else
{
// Render 2D to eye textures
for (int eye_ix = 0; eye_ix < stereo3dMode.eye_count(); ++eye_ix)
{
FGLDebug::PushGroup("Eye2D");
mBuffers->BindEyeFB(eye_ix);
m2DDrawer->Flush(); // Draw the 2D
FGLDebug::PopGroup();
}
FGLPostProcessState savedState;
FGLDebug::PushGroup("PresentEyes");
stereo3dMode.Present();
FGLDebug::PopGroup();
}
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// //
// Gamma correct while copying to frame buffer // Gamma correct while copying to frame buffer

View file

@ -122,12 +122,12 @@ void FGLRenderBuffers::ClearBloom()
void FGLRenderBuffers::ClearEyeBuffers() void FGLRenderBuffers::ClearEyeBuffers()
{ {
for (auto handle : mEyeTextures)
DeleteTexture(handle);
for (auto handle : mEyeFBs) for (auto handle : mEyeFBs)
DeleteFrameBuffer(handle); DeleteFrameBuffer(handle);
for (auto handle : mEyeTextures)
DeleteTexture(handle);
mEyeTextures.Clear(); mEyeTextures.Clear();
mEyeFBs.Clear(); mEyeFBs.Clear();
} }
@ -311,7 +311,7 @@ void FGLRenderBuffers::CreateEyeBuffers(int eye)
glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding); glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &frameBufferBinding); glGetIntegerv(GL_FRAMEBUFFER_BINDING, &frameBufferBinding);
while (mEyeFBs.Size() < eye) while (mEyeFBs.Size() <= eye)
{ {
GLuint texture = Create2DTexture("EyeTexture", GL_RGBA16F, mWidth, mHeight); GLuint texture = Create2DTexture("EyeTexture", GL_RGBA16F, mWidth, mHeight);
mEyeTextures.Push(texture); mEyeTextures.Push(texture);
@ -546,10 +546,10 @@ void FGLRenderBuffers::BindEyeTexture(int eye, int texunit)
glBindTexture(GL_TEXTURE_2D, mEyeTextures[eye]); glBindTexture(GL_TEXTURE_2D, mEyeTextures[eye]);
} }
void FGLRenderBuffers::BindEyeFB(int eye) void FGLRenderBuffers::BindEyeFB(int eye, bool readBuffer)
{ {
CreateEyeBuffers(eye); CreateEyeBuffers(eye);
glBindFramebuffer(GL_FRAMEBUFFER, mEyeFBs[eye]); glBindFramebuffer(readBuffer ? GL_READ_FRAMEBUFFER : GL_FRAMEBUFFER, mEyeFBs[eye]);
} }
//========================================================================== //==========================================================================

View file

@ -34,7 +34,7 @@ public:
void BlitToEyeTexture(int eye); void BlitToEyeTexture(int eye);
void BindEyeTexture(int eye, int texunit); void BindEyeTexture(int eye, int texunit);
void BindEyeFB(int eye); void BindEyeFB(int eye, bool readBuffer = false);
enum { NumBloomLevels = 4 }; enum { NumBloomLevels = 4 };
FGLBloomTextureLevel BloomLevels[NumBloomLevels]; FGLBloomTextureLevel BloomLevels[NumBloomLevels];

View file

@ -173,7 +173,7 @@ public:
void ClearTonemapPalette(); void ClearTonemapPalette();
void LensDistortScene(); void LensDistortScene();
void CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma); void CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma);
void Flush() { CopyToBackbuffer(nullptr, true); } void Flush();
void SetProjection(float fov, float ratio, float fovratio); void SetProjection(float fov, float ratio, float fovratio);
void SetProjection(VSMatrix matrix); // raw matrix input from stereo 3d modes void SetProjection(VSMatrix matrix); // raw matrix input from stereo 3d modes

View file

@ -863,6 +863,8 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo
DrawBlend(lviewsector); DrawBlend(lviewsector);
} }
mDrawingScene2D = false; mDrawingScene2D = false;
if (!stereo3dMode.IsMono())
mBuffers->BlitToEyeTexture(eye_ix);
eye->TearDown(); eye->TearDown();
} }
stereo3dMode.TearDown(); stereo3dMode.TearDown();

View file

@ -36,6 +36,7 @@
#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
@ -79,6 +80,28 @@ 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

@ -85,6 +85,9 @@ public:
virtual void SetUp() const {}; virtual void SetUp() const {};
virtual void TearDown() const {}; virtual void TearDown() const {};
virtual bool IsMono() const { return false; }
virtual void Present() const;
protected: protected:
TArray<const EyePose *> eye_ptrs; TArray<const EyePose *> eye_ptrs;
@ -102,6 +105,8 @@ class MonoView : public Stereo3DMode
public: public:
static const MonoView& getInstance(); static const MonoView& getInstance();
bool IsMono() const override { return true; }
protected: protected:
MonoView() { eye_ptrs.Push(&centralEye); } MonoView() { eye_ptrs.Push(&centralEye); }
EyePose centralEye; EyePose centralEye;