Add eye textures and FBOs to FGLRenderBuffers

This commit is contained in:
Magnus Norddahl 2016-09-07 20:31:42 +02:00 committed by Christoph Oelckers
parent b9ca3c85f8
commit 4bdd872f09
2 changed files with 91 additions and 0 deletions

View file

@ -85,6 +85,7 @@ FGLRenderBuffers::~FGLRenderBuffers()
{ {
ClearScene(); ClearScene();
ClearPipeline(); ClearPipeline();
ClearEyeBuffers();
ClearBloom(); ClearBloom();
} }
@ -119,6 +120,18 @@ void FGLRenderBuffers::ClearBloom()
} }
} }
void FGLRenderBuffers::ClearEyeBuffers()
{
for (auto handle : mEyeTextures)
DeleteTexture(handle);
for (auto handle : mEyeFBs)
DeleteFrameBuffer(handle);
mEyeTextures.Clear();
mEyeFBs.Clear();
}
void FGLRenderBuffers::DeleteTexture(GLuint &handle) void FGLRenderBuffers::DeleteTexture(GLuint &handle)
{ {
if (handle != 0) if (handle != 0)
@ -202,6 +215,7 @@ bool FGLRenderBuffers::Setup(int width, int height, int sceneWidth, int sceneHei
{ {
ClearScene(); ClearScene();
ClearPipeline(); ClearPipeline();
ClearEyeBuffers();
ClearBloom(); ClearBloom();
mWidth = 0; mWidth = 0;
mHeight = 0; mHeight = 0;
@ -239,6 +253,7 @@ void FGLRenderBuffers::CreateScene(int width, int height, int samples)
void FGLRenderBuffers::CreatePipeline(int width, int height) void FGLRenderBuffers::CreatePipeline(int width, int height)
{ {
ClearPipeline(); ClearPipeline();
ClearEyeBuffers();
for (int i = 0; i < NumPipelineTextures; i++) for (int i = 0; i < NumPipelineTextures; i++)
{ {
@ -279,6 +294,35 @@ void FGLRenderBuffers::CreateBloom(int width, int height)
} }
} }
//==========================================================================
//
// Creates eye buffers if needed
//
//==========================================================================
void FGLRenderBuffers::CreateEyeBuffers(int eye)
{
if (mEyeFBs.Size() > eye)
return;
GLint activeTex, textureBinding, frameBufferBinding;
glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex);
glActiveTexture(GL_TEXTURE0);
glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &frameBufferBinding);
while (mEyeFBs.Size() < eye)
{
GLuint texture = Create2DTexture("EyeTexture", GL_RGBA16F, mWidth, mHeight);
mEyeTextures.Push(texture);
mEyeFBs.Push(CreateFrameBuffer("EyeFB", texture));
}
glBindTexture(GL_TEXTURE_2D, textureBinding);
glActiveTexture(activeTex);
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferBinding);
}
//========================================================================== //==========================================================================
// //
// Creates a 2D texture defaulting to linear filtering and clamp to edge // Creates a 2D texture defaulting to linear filtering and clamp to edge
@ -471,6 +515,43 @@ void FGLRenderBuffers::BlitSceneToTexture()
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
} }
//==========================================================================
//
// Eye textures and their frame buffers
//
//==========================================================================
void FGLRenderBuffers::BlitToEyeTexture(int eye)
{
CreateEyeBuffers(eye);
glBindFramebuffer(GL_READ_FRAMEBUFFER, mPipelineFB[mCurrentPipelineTexture]);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mEyeFBs[eye]);
glBlitFramebuffer(0, 0, mWidth, mHeight, 0, 0, mWidth, mHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
if ((gl.flags & RFL_INVALIDATE_BUFFER) != 0)
{
GLenum attachments[2] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_STENCIL_ATTACHMENT };
glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 2, attachments);
}
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}
void FGLRenderBuffers::BindEyeTexture(int eye, int texunit)
{
CreateEyeBuffers(eye);
glActiveTexture(GL_TEXTURE0 + texunit);
glBindTexture(GL_TEXTURE_2D, mEyeTextures[eye]);
}
void FGLRenderBuffers::BindEyeFB(int eye)
{
CreateEyeBuffers(eye);
glBindFramebuffer(GL_FRAMEBUFFER, mEyeFBs[eye]);
}
//========================================================================== //==========================================================================
// //
// Makes the scene frame buffer active (multisample, depth, stecil, etc.) // Makes the scene frame buffer active (multisample, depth, stecil, etc.)

View file

@ -32,6 +32,10 @@ public:
void BindOutputFB(); void BindOutputFB();
void BlitToEyeTexture(int eye);
void BindEyeTexture(int eye, int texunit);
void BindEyeFB(int eye);
enum { NumBloomLevels = 4 }; enum { NumBloomLevels = 4 };
FGLBloomTextureLevel BloomLevels[NumBloomLevels]; FGLBloomTextureLevel BloomLevels[NumBloomLevels];
@ -43,10 +47,12 @@ public:
private: private:
void ClearScene(); void ClearScene();
void ClearPipeline(); void ClearPipeline();
void ClearEyeBuffers();
void ClearBloom(); void ClearBloom();
void CreateScene(int width, int height, int samples); void CreateScene(int width, int height, int samples);
void CreatePipeline(int width, int height); void CreatePipeline(int width, int height);
void CreateBloom(int width, int height); void CreateBloom(int width, int height);
void CreateEyeBuffers(int eye);
GLuint Create2DTexture(const FString &name, GLuint format, int width, int height); GLuint Create2DTexture(const FString &name, GLuint format, int width, int height);
GLuint CreateRenderBuffer(const FString &name, GLuint format, int width, int height); GLuint CreateRenderBuffer(const FString &name, GLuint format, int width, int height);
GLuint CreateRenderBuffer(const FString &name, GLuint format, int samples, int width, int height); GLuint CreateRenderBuffer(const FString &name, GLuint format, int samples, int width, int height);
@ -83,6 +89,10 @@ private:
// Back buffer frame buffer // Back buffer frame buffer
GLuint mOutputFB = 0; GLuint mOutputFB = 0;
// Eye buffers
TArray<GLuint> mEyeTextures;
TArray<GLuint> mEyeFBs;
static bool FailedCreate; static bool FailedCreate;
static bool BuffersActive; static bool BuffersActive;
}; };