mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-01-30 20:41:00 +00:00
Add Palette LUT tonemap mode
This commit is contained in:
parent
13a583faee
commit
25645d901e
10 changed files with 102 additions and 7 deletions
|
@ -55,6 +55,7 @@
|
||||||
#include "r_utility.h"
|
#include "r_utility.h"
|
||||||
#include "a_hexenglobal.h"
|
#include "a_hexenglobal.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
|
#include "colormatcher.h"
|
||||||
#include "gl/gl_functions.h"
|
#include "gl/gl_functions.h"
|
||||||
#include "gl/system/gl_interface.h"
|
#include "gl/system/gl_interface.h"
|
||||||
#include "gl/system/gl_framebuffer.h"
|
#include "gl/system/gl_framebuffer.h"
|
||||||
|
@ -89,7 +90,7 @@ CVAR(Float, gl_exposure, 0.0f, 0)
|
||||||
|
|
||||||
CUSTOM_CVAR(Int, gl_tonemap, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
CUSTOM_CVAR(Int, gl_tonemap, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
{
|
{
|
||||||
if (self < 0 || self > 4)
|
if (self < 0 || self > 5)
|
||||||
self = 0;
|
self = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,13 +223,61 @@ void FGLRenderer::TonemapScene()
|
||||||
mBuffers->BindCurrentTexture(0);
|
mBuffers->BindCurrentTexture(0);
|
||||||
mTonemapShader->Bind();
|
mTonemapShader->Bind();
|
||||||
mTonemapShader->SceneTexture.Set(0);
|
mTonemapShader->SceneTexture.Set(0);
|
||||||
|
|
||||||
|
if (mTonemapShader->IsPaletteMode())
|
||||||
|
{
|
||||||
|
mTonemapShader->PaletteLUT.Set(1);
|
||||||
|
BindTonemapPalette(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
mTonemapShader->Exposure.Set(mCameraExposure);
|
mTonemapShader->Exposure.Set(mCameraExposure);
|
||||||
|
}
|
||||||
|
|
||||||
RenderScreenQuad();
|
RenderScreenQuad();
|
||||||
mBuffers->NextTexture();
|
mBuffers->NextTexture();
|
||||||
|
|
||||||
FGLDebug::PopGroup();
|
FGLDebug::PopGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FGLRenderer::BindTonemapPalette(int texunit)
|
||||||
|
{
|
||||||
|
if (mTonemapPalette)
|
||||||
|
{
|
||||||
|
mTonemapPalette->Bind(texunit, 0, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TArray<unsigned char> lut;
|
||||||
|
lut.Resize(512 * 512 * 4);
|
||||||
|
for (int r = 0; r < 64; r++)
|
||||||
|
{
|
||||||
|
for (int g = 0; g < 64; g++)
|
||||||
|
{
|
||||||
|
for (int b = 0; b < 64; b++)
|
||||||
|
{
|
||||||
|
PalEntry color = GPalette.BaseColors[ColorMatcher.Pick((r << 2) | (r >> 1), (g << 2) | (g >> 1), (b << 2) | (b >> 1))];
|
||||||
|
int index = ((r * 64 + g) * 64 + b) * 4;
|
||||||
|
lut[index] = color.r;
|
||||||
|
lut[index + 1] = color.g;
|
||||||
|
lut[index + 2] = color.b;
|
||||||
|
lut[index + 3] = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mTonemapPalette = new FHardwareTexture(512, 512, true);
|
||||||
|
mTonemapPalette->CreateTexture(&lut[0], 512, 512, texunit, false, 0, "mTonemapPalette");
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0 + texunit);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Apply lens distortion and place the result in the HUD/2D texture
|
// Apply lens distortion and place the result in the HUD/2D texture
|
||||||
|
|
|
@ -62,8 +62,12 @@ FGLPostProcessState::FGLPostProcessState()
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
if (gl.flags & RFL_SAMPLER_OBJECTS)
|
if (gl.flags & RFL_SAMPLER_OBJECTS)
|
||||||
{
|
{
|
||||||
glGetIntegerv(GL_SAMPLER_BINDING, &samplerBinding);
|
glGetIntegerv(GL_SAMPLER_BINDING, &samplerBinding[0]);
|
||||||
glBindSampler(0, 0);
|
glBindSampler(0, 0);
|
||||||
|
glActiveTexture(GL_TEXTURE0 + 1);
|
||||||
|
glGetIntegerv(GL_SAMPLER_BINDING, &samplerBinding[1]);
|
||||||
|
glBindSampler(1, 0);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
}
|
}
|
||||||
|
|
||||||
glGetBooleanv(GL_BLEND, &blendEnabled);
|
glGetBooleanv(GL_BLEND, &blendEnabled);
|
||||||
|
@ -120,7 +124,10 @@ FGLPostProcessState::~FGLPostProcessState()
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
if (gl.flags & RFL_SAMPLER_OBJECTS)
|
if (gl.flags & RFL_SAMPLER_OBJECTS)
|
||||||
glBindSampler(0, samplerBinding);
|
{
|
||||||
|
glBindSampler(0, samplerBinding[0]);
|
||||||
|
glBindSampler(1, samplerBinding[1]);
|
||||||
|
}
|
||||||
glBindTexture(GL_TEXTURE_2D, textureBinding);
|
glBindTexture(GL_TEXTURE_2D, textureBinding);
|
||||||
glActiveTexture(activeTex);
|
glActiveTexture(activeTex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ private:
|
||||||
|
|
||||||
GLint activeTex;
|
GLint activeTex;
|
||||||
GLint textureBinding;
|
GLint textureBinding;
|
||||||
GLint samplerBinding;
|
GLint samplerBinding[2];
|
||||||
GLboolean blendEnabled;
|
GLboolean blendEnabled;
|
||||||
GLboolean scissorEnabled;
|
GLboolean scissorEnabled;
|
||||||
GLboolean depthEnabled;
|
GLboolean depthEnabled;
|
||||||
|
|
|
@ -123,6 +123,7 @@ void FGLRenderer::Initialize(int width, int height)
|
||||||
mBloomCombineShader = new FBloomCombineShader();
|
mBloomCombineShader = new FBloomCombineShader();
|
||||||
mBlurShader = new FBlurShader();
|
mBlurShader = new FBlurShader();
|
||||||
mTonemapShader = new FTonemapShader();
|
mTonemapShader = new FTonemapShader();
|
||||||
|
mTonemapPalette = nullptr;
|
||||||
mLensShader = new FLensShader();
|
mLensShader = new FLensShader();
|
||||||
mPresentShader = new FPresentShader();
|
mPresentShader = new FPresentShader();
|
||||||
m2DDrawer = new F2DDrawer;
|
m2DDrawer = new F2DDrawer;
|
||||||
|
@ -181,6 +182,7 @@ FGLRenderer::~FGLRenderer()
|
||||||
if (mBloomCombineShader) delete mBloomCombineShader;
|
if (mBloomCombineShader) delete mBloomCombineShader;
|
||||||
if (mBlurShader) delete mBlurShader;
|
if (mBlurShader) delete mBlurShader;
|
||||||
if (mTonemapShader) delete mTonemapShader;
|
if (mTonemapShader) delete mTonemapShader;
|
||||||
|
if (mTonemapPalette) delete mTonemapPalette;
|
||||||
if (mLensShader) delete mLensShader;
|
if (mLensShader) delete mLensShader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ class FTonemapShader;
|
||||||
class FLensShader;
|
class FLensShader;
|
||||||
class FPresentShader;
|
class FPresentShader;
|
||||||
class F2DDrawer;
|
class F2DDrawer;
|
||||||
|
class FHardwareTexture;
|
||||||
|
|
||||||
inline float DEG2RAD(float deg)
|
inline float DEG2RAD(float deg)
|
||||||
{
|
{
|
||||||
|
@ -92,6 +93,7 @@ public:
|
||||||
FBloomCombineShader *mBloomCombineShader;
|
FBloomCombineShader *mBloomCombineShader;
|
||||||
FBlurShader *mBlurShader;
|
FBlurShader *mBlurShader;
|
||||||
FTonemapShader *mTonemapShader;
|
FTonemapShader *mTonemapShader;
|
||||||
|
FHardwareTexture *mTonemapPalette;
|
||||||
FLensShader *mLensShader;
|
FLensShader *mLensShader;
|
||||||
FPresentShader *mPresentShader;
|
FPresentShader *mPresentShader;
|
||||||
|
|
||||||
|
@ -164,6 +166,7 @@ public:
|
||||||
void EndDrawScene(sector_t * viewsector);
|
void EndDrawScene(sector_t * viewsector);
|
||||||
void BloomScene();
|
void BloomScene();
|
||||||
void TonemapScene();
|
void TonemapScene();
|
||||||
|
void BindTonemapPalette(int texunit);
|
||||||
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() { CopyToBackbuffer(nullptr, true); }
|
||||||
|
|
|
@ -61,10 +61,16 @@ void FTonemapShader::Bind()
|
||||||
shader.SetAttribLocation(0, "PositionInProjection");
|
shader.SetAttribLocation(0, "PositionInProjection");
|
||||||
SceneTexture.Init(shader, "InputTexture");
|
SceneTexture.Init(shader, "InputTexture");
|
||||||
Exposure.Init(shader, "ExposureAdjustment");
|
Exposure.Init(shader, "ExposureAdjustment");
|
||||||
|
PaletteLUT.Init(shader, "PaletteLUT");
|
||||||
}
|
}
|
||||||
shader.Bind();
|
shader.Bind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FTonemapShader::IsPaletteMode()
|
||||||
|
{
|
||||||
|
return gl_tonemap == Palette;
|
||||||
|
}
|
||||||
|
|
||||||
const char *FTonemapShader::GetDefines(int mode)
|
const char *FTonemapShader::GetDefines(int mode)
|
||||||
{
|
{
|
||||||
switch (mode)
|
switch (mode)
|
||||||
|
@ -74,5 +80,6 @@ const char *FTonemapShader::GetDefines(int mode)
|
||||||
case Reinhard: return "#define REINHARD\n";
|
case Reinhard: return "#define REINHARD\n";
|
||||||
case HejlDawson: return "#define HEJLDAWSON\n";
|
case HejlDawson: return "#define HEJLDAWSON\n";
|
||||||
case Uncharted2: return "#define UNCHARTED2\n";
|
case Uncharted2: return "#define UNCHARTED2\n";
|
||||||
|
case Palette: return "#define PALETTE\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,9 @@ public:
|
||||||
|
|
||||||
FBufferedUniform1i SceneTexture;
|
FBufferedUniform1i SceneTexture;
|
||||||
FBufferedUniform1f Exposure;
|
FBufferedUniform1f Exposure;
|
||||||
|
FBufferedUniform1i PaletteLUT;
|
||||||
|
|
||||||
|
static bool IsPaletteMode();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum TonemapMode
|
enum TonemapMode
|
||||||
|
@ -19,6 +22,7 @@ private:
|
||||||
HejlDawson,
|
HejlDawson,
|
||||||
Reinhard,
|
Reinhard,
|
||||||
Linear,
|
Linear,
|
||||||
|
Palette,
|
||||||
NumTonemapModes
|
NumTonemapModes
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2700,3 +2700,4 @@ OPTVAL_QUADBUFFERED = "Quad-buffered";
|
||||||
OPTVAL_UNCHARTED2 = "Uncharted 2";
|
OPTVAL_UNCHARTED2 = "Uncharted 2";
|
||||||
OPTVAL_HEJLDAWSON = "Hejl Dawson";
|
OPTVAL_HEJLDAWSON = "Hejl Dawson";
|
||||||
OPTVAL_REINHARD = "Reinhard";
|
OPTVAL_REINHARD = "Reinhard";
|
||||||
|
OPTVAL_PALETTE = "Palette";
|
|
@ -39,6 +39,7 @@ OptionValue "TonemapModes"
|
||||||
2, "$OPTVAL_HEJLDAWSON"
|
2, "$OPTVAL_HEJLDAWSON"
|
||||||
3, "$OPTVAL_REINHARD"
|
3, "$OPTVAL_REINHARD"
|
||||||
4, "$OPTVAL_LINEAR"
|
4, "$OPTVAL_LINEAR"
|
||||||
|
5, "$OPTVAL_PALETTE"
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionValue "TextureFormats"
|
OptionValue "TextureFormats"
|
||||||
|
|
|
@ -42,7 +42,7 @@ vec3 Tonemap(vec3 color)
|
||||||
return (x * (6.2 * x + 0.5)) / (x * (6.2 * x + 1.7) + 0.06); // no sRGB needed
|
return (x * (6.2 * x + 0.5)) / (x * (6.2 * x + 1.7) + 0.06); // no sRGB needed
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#elif defined(UNCHARTED2)
|
||||||
|
|
||||||
vec3 Uncharted2Tonemap(vec3 x)
|
vec3 Uncharted2Tonemap(vec3 x)
|
||||||
{
|
{
|
||||||
|
@ -63,12 +63,33 @@ vec3 Tonemap(vec3 color)
|
||||||
return sRGB(curr * whiteScale);
|
return sRGB(curr * whiteScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif defined(PALETTE)
|
||||||
|
|
||||||
|
uniform sampler2D PaletteLUT;
|
||||||
|
|
||||||
|
vec3 Tonemap(vec3 color)
|
||||||
|
{
|
||||||
|
ivec3 c = ivec3(clamp(color.rgb, vec3(0.0), vec3(1.0)) * 255.0 + 0.5);
|
||||||
|
int index = ((c.r >> 2) * 64 + (c.g >> 2)) * 64 + (c.b >> 2);
|
||||||
|
int tx = index % 512;
|
||||||
|
int ty = index / 512;
|
||||||
|
#if __VERSION__ < 130
|
||||||
|
return texture2D(PaletteLUT, vec2(float(tx) / 512.0, float(ty) / 512.0))).rgb;
|
||||||
|
#else
|
||||||
|
return texelFetch(PaletteLUT, ivec2(tx, ty), 0).rgb;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "Tonemap mode define is missing"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec3 color = texture(InputTexture, TexCoord).rgb;
|
vec3 color = texture(InputTexture, TexCoord).rgb;
|
||||||
|
#ifndef PALETTE
|
||||||
color = color * ExposureAdjustment;
|
color = color * ExposureAdjustment;
|
||||||
color = Linear(color); // needed because gzdoom's scene texture is not linear at the moment
|
color = Linear(color); // needed because gzdoom's scene texture is not linear at the moment
|
||||||
|
#endif
|
||||||
FragColor = vec4(Tonemap(color), 1.0);
|
FragColor = vec4(Tonemap(color), 1.0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue