Added bloom and tonemap to menus

Added gl_renderbuffers CVAR that disables render buffers
Added patch shader support to FShaderProgram
Added OpenGL 2 fallback support to render buffers
This commit is contained in:
Magnus Norddahl 2016-07-29 21:31:20 +02:00
commit 5849c83028
27 changed files with 401 additions and 193 deletions

View file

@ -53,6 +53,8 @@
#include "i_system.h"
#include "doomerrors.h"
CVAR(Bool, gl_renderbuffers, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
//==========================================================================
//
// Initialize render buffers and textures used in rendering passes
@ -80,37 +82,45 @@ void FGLRenderBuffers::Clear()
for (int i = 0; i < NumBloomLevels; i++)
{
auto &level = BloomLevels[i];
if (level.HFramebuffer != 0)
glDeleteFramebuffers(1, &level.HFramebuffer);
if (level.VFramebuffer != 0)
glDeleteFramebuffers(1, &level.VFramebuffer);
if (level.HTexture != 0)
glDeleteTextures(1, &level.HTexture);
if (level.VTexture != 0)
glDeleteTextures(1, &level.VTexture);
DeleteFrameBuffer(level.HFramebuffer);
DeleteFrameBuffer(level.VFramebuffer);
DeleteTexture(level.HTexture);
DeleteTexture(level.VTexture);
level = FGLBloomTextureLevel();
}
if (mSceneFB != 0)
glDeleteFramebuffers(1, &mSceneFB);
if (mSceneTexture != 0)
glDeleteTextures(1, &mSceneTexture);
if (mSceneDepthStencil != 0)
glDeleteRenderbuffers(1, &mSceneDepthStencil);
if (mHudFB != 0)
glDeleteFramebuffers(1, &mHudFB);
if (mHudTexture != 0)
glDeleteTextures(1, &mHudTexture);
mSceneFB = 0;
mSceneTexture = 0;
mSceneDepthStencil = 0;
mHudFB = 0;
mHudTexture = 0;
DeleteFrameBuffer(mSceneFB);
DeleteTexture(mSceneTexture);
DeleteRenderBuffer(mSceneDepthStencil);
DeleteRenderBuffer(mSceneDepth);
DeleteRenderBuffer(mSceneStencil);
DeleteFrameBuffer(mHudFB);
DeleteTexture(mHudTexture);
mWidth = 0;
mHeight = 0;
}
void FGLRenderBuffers::DeleteTexture(GLuint &handle)
{
if (handle != 0)
glDeleteTextures(1, &handle);
handle = 0;
}
void FGLRenderBuffers::DeleteRenderBuffer(GLuint &handle)
{
if (handle != 0)
glDeleteRenderbuffers(1, &handle);
handle = 0;
}
void FGLRenderBuffers::DeleteFrameBuffer(GLuint &handle)
{
if (handle != 0)
glDeleteFramebuffers(1, &handle);
handle = 0;
}
//==========================================================================
//
// Makes sure all render buffers have sizes suitable for rending at the
@ -125,37 +135,23 @@ void FGLRenderBuffers::Setup(int width, int height)
Clear();
glActiveTexture(GL_TEXTURE0);
GLuint hdrFormat = ((gl.flags & RFL_NO_RGBA16F) != 0) ? GL_RGBA8 : GL_RGBA16F;
glGenFramebuffers(1, &mSceneFB);
glGenFramebuffers(1, &mHudFB);
glGenTextures(1, &mSceneTexture);
glGenTextures(1, &mHudTexture);
glGenRenderbuffers(1, &mSceneDepthStencil);
mSceneTexture = Create2DTexture(hdrFormat, width, height);
if ((gl.flags & RFL_NO_DEPTHSTENCIL) != 0)
{
mSceneDepth = CreateRenderBuffer(GL_DEPTH_COMPONENT24, width, height);
mSceneStencil = CreateRenderBuffer(GL_STENCIL_INDEX8, width, height);
mSceneFB = CreateFrameBuffer(mSceneTexture, mSceneDepth, mSceneStencil);
}
else
{
mSceneDepthStencil = CreateRenderBuffer(GL_DEPTH24_STENCIL8, width, height);
mSceneFB = CreateFrameBuffer(mSceneTexture, mSceneDepthStencil);
}
glBindTexture(GL_TEXTURE_2D, mSceneTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindRenderbuffer(GL_RENDERBUFFER, mSceneDepthStencil);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
glBindFramebuffer(GL_FRAMEBUFFER, mSceneFB);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mSceneTexture, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mSceneDepthStencil);
glBindTexture(GL_TEXTURE_2D, mHudTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindFramebuffer(GL_FRAMEBUFFER, mHudFB);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mHudTexture, 0);
mHudTexture = Create2DTexture(hdrFormat, width, height);
mHudFB = CreateFrameBuffer(mHudTexture);
int bloomWidth = MAX(width / 2, 1);
int bloomHeight = MAX(height / 2, 1);
@ -165,31 +161,16 @@ void FGLRenderBuffers::Setup(int width, int height)
level.Width = MAX(bloomWidth / 2, 1);
level.Height = MAX(bloomHeight / 2, 1);
glGenTextures(1, &level.VTexture);
glGenTextures(1, &level.HTexture);
glGenFramebuffers(1, &level.VFramebuffer);
glGenFramebuffers(1, &level.HFramebuffer);
glBindTexture(GL_TEXTURE_2D, level.VTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, level.Width, level.Height, 0, GL_RGBA, GL_FLOAT, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, level.HTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, level.Width, level.Height, 0, GL_RGBA, GL_FLOAT, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindFramebuffer(GL_FRAMEBUFFER, level.VFramebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, level.VTexture, 0);
glBindFramebuffer(GL_FRAMEBUFFER, level.HFramebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, level.HTexture, 0);
level.VTexture = Create2DTexture(hdrFormat, level.Width, level.Height);
level.HTexture = Create2DTexture(hdrFormat, level.Width, level.Height);
level.VFramebuffer = CreateFrameBuffer(level.VTexture);
level.HFramebuffer = CreateFrameBuffer(level.HTexture);
bloomWidth = level.Width;
bloomHeight = level.Height;
}
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, mOutputFB);
@ -198,6 +179,78 @@ void FGLRenderBuffers::Setup(int width, int height)
mHeight = height;
}
//==========================================================================
//
// Creates a 2D texture defaulting to linear filtering and clamp to edge
//
//==========================================================================
GLuint FGLRenderBuffers::Create2DTexture(GLuint format, int width, int height)
{
GLuint type = (format == GL_RGBA16F) ? GL_FLOAT : GL_UNSIGNED_BYTE;
GLuint handle = 0;
glGenTextures(1, &handle);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, handle);
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, GL_RGBA, type, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
return handle;
}
//==========================================================================
//
// Creates a render buffer
//
//==========================================================================
GLuint FGLRenderBuffers::CreateRenderBuffer(GLuint format, int width, int height)
{
GLuint handle = 0;
glGenRenderbuffers(1, &handle);
glBindRenderbuffer(GL_RENDERBUFFER, handle);
glRenderbufferStorage(GL_RENDERBUFFER, format, width, height);
return handle;
}
//==========================================================================
//
// Creates a frame buffer
//
//==========================================================================
GLuint FGLRenderBuffers::CreateFrameBuffer(GLuint colorbuffer)
{
GLuint handle = 0;
glGenFramebuffers(1, &handle);
glBindFramebuffer(GL_FRAMEBUFFER, handle);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0);
return handle;
}
GLuint FGLRenderBuffers::CreateFrameBuffer(GLuint colorbuffer, GLuint depthstencil)
{
GLuint handle = 0;
glGenFramebuffers(1, &handle);
glBindFramebuffer(GL_FRAMEBUFFER, handle);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthstencil);
return handle;
}
GLuint FGLRenderBuffers::CreateFrameBuffer(GLuint colorbuffer, GLuint depth, GLuint stencil)
{
GLuint handle = 0;
glGenFramebuffers(1, &handle);
glBindFramebuffer(GL_FRAMEBUFFER, handle);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencil);
return handle;
}
//==========================================================================
//
// Makes the scene frame buffer active
@ -217,7 +270,10 @@ void FGLRenderBuffers::BindSceneFB()
void FGLRenderBuffers::BindHudFB()
{
glBindFramebuffer(GL_FRAMEBUFFER, mHudFB);
if (gl_tonemap != 0)
glBindFramebuffer(GL_FRAMEBUFFER, mHudFB);
else
glBindFramebuffer(GL_FRAMEBUFFER, mSceneFB);
}
//==========================================================================
@ -252,5 +308,19 @@ void FGLRenderBuffers::BindSceneTexture(int index)
void FGLRenderBuffers::BindHudTexture(int index)
{
glActiveTexture(GL_TEXTURE0 + index);
glBindTexture(GL_TEXTURE_2D, mHudTexture);
if (gl_tonemap != 0)
glBindTexture(GL_TEXTURE_2D, mHudTexture);
else
glBindTexture(GL_TEXTURE_2D, mSceneTexture);
}
//==========================================================================
//
// Returns true if render buffers are supported and should be used
//
//==========================================================================
bool FGLRenderBuffers::IsEnabled()
{
return gl_renderbuffers && gl.glslversion != 0;
}