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:
parent
0efee85bd8
commit
5849c83028
27 changed files with 401 additions and 193 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue