mirror of
https://github.com/Shpoike/Quakespasm.git
synced 2025-02-15 00:20:46 +00:00
palette filter, WIP
This commit is contained in:
parent
087ecdfce6
commit
6830935563
1 changed files with 134 additions and 4 deletions
|
@ -124,10 +124,13 @@ static GLuint r_gamma_texture;
|
||||||
static GLuint r_gamma_program;
|
static GLuint r_gamma_program;
|
||||||
static int r_gamma_texture_width, r_gamma_texture_height;
|
static int r_gamma_texture_width, r_gamma_texture_height;
|
||||||
|
|
||||||
|
static GLuint r_lut_texture;
|
||||||
|
|
||||||
// uniforms used in gamma shader
|
// uniforms used in gamma shader
|
||||||
static GLuint gammaLoc;
|
static GLuint gammaLoc;
|
||||||
static GLuint contrastLoc;
|
static GLuint contrastLoc;
|
||||||
static GLuint textureLoc;
|
static GLuint textureLoc;
|
||||||
|
static GLuint lutTextureLoc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=============
|
=============
|
||||||
|
@ -160,13 +163,26 @@ static void GLSLGamma_CreateShaders (void)
|
||||||
"#version 110\n"
|
"#version 110\n"
|
||||||
"\n"
|
"\n"
|
||||||
"uniform sampler2D GammaTexture;\n"
|
"uniform sampler2D GammaTexture;\n"
|
||||||
|
"uniform sampler2D LutTexture;\n"
|
||||||
"uniform float GammaValue;\n"
|
"uniform float GammaValue;\n"
|
||||||
"uniform float ContrastValue;\n"
|
"uniform float ContrastValue;\n"
|
||||||
"\n"
|
"\n"
|
||||||
"void main(void) {\n"
|
"void main(void) {\n"
|
||||||
" vec4 frag = texture2D(GammaTexture, gl_TexCoord[0].xy);\n"
|
" vec4 frag = texture2D(GammaTexture, gl_TexCoord[0].xy);\n"
|
||||||
|
" // apply palette lut\n"
|
||||||
|
" int r = int(clamp(frag.r, 0.0, 1.0) * 31.0);\n"
|
||||||
|
" int g = int(clamp(frag.g, 0.0, 1.0) * 63.0);\n"
|
||||||
|
" int b = int(clamp(frag.b, 0.0, 1.0) * 31.0);\n"
|
||||||
|
// " int r = 31; int g = 0; int b = 0;\n" // r in [0,31] g in [0, 63], b in [0,31]
|
||||||
|
" int idx = b + (g * 32) + (r * 32 * 64);\n"
|
||||||
|
" vec2 lutTexCoord = vec2(mod(float(idx), 256.0)/256.0 + (0.5/256.0), float(idx / 256)/256.0 + (0.5/256.0));\n"
|
||||||
|
" vec4 lutValue = texture2D(LutTexture, lutTexCoord);\n"
|
||||||
|
" frag.rgb = (0.06 * frag.rgb) + 0.94 * lutValue.rgb;\n"
|
||||||
|
// " frag = 0.1 * frag + 0.9 * vec4(1.0, 0.0, 0.0, 1.0);\n"
|
||||||
|
" // apply contrast and gamma\n"
|
||||||
" frag.rgb = frag.rgb * ContrastValue;\n"
|
" frag.rgb = frag.rgb * ContrastValue;\n"
|
||||||
" gl_FragColor = vec4(pow(frag.rgb, vec3(GammaValue)), 1.0);\n"
|
" gl_FragColor = vec4(pow(frag.rgb, vec3(GammaValue)), 1.0);\n"
|
||||||
|
//" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
if (!gl_glsl_gamma_able)
|
if (!gl_glsl_gamma_able)
|
||||||
|
@ -178,8 +194,45 @@ static void GLSLGamma_CreateShaders (void)
|
||||||
gammaLoc = GL_GetUniformLocation (&r_gamma_program, "GammaValue");
|
gammaLoc = GL_GetUniformLocation (&r_gamma_program, "GammaValue");
|
||||||
contrastLoc = GL_GetUniformLocation (&r_gamma_program, "ContrastValue");
|
contrastLoc = GL_GetUniformLocation (&r_gamma_program, "ContrastValue");
|
||||||
textureLoc = GL_GetUniformLocation (&r_gamma_program, "GammaTexture");
|
textureLoc = GL_GetUniformLocation (&r_gamma_program, "GammaTexture");
|
||||||
|
lutTextureLoc = GL_GetUniformLocation(&r_gamma_program, "LutTexture");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SQR(a) ((a)*(a))
|
||||||
|
|
||||||
|
static int colordist2(int r1, int g1, int b1, int r2, int g2, int b2)
|
||||||
|
{
|
||||||
|
return SQR(r2 - r1) + SQR(g2 - g1) + SQR(b2 - b1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int closestPaletteIndex(int r8, int g8, int b8)
|
||||||
|
{
|
||||||
|
int i, besti;
|
||||||
|
int dist, bestdist;
|
||||||
|
const byte *pal = (const byte *)d_8to24table;
|
||||||
|
|
||||||
|
bestdist = (255 * 255 * 255) + 1;
|
||||||
|
besti = INT_MAX;
|
||||||
|
|
||||||
|
for (i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
int r, g, b;
|
||||||
|
r = pal[i*4];
|
||||||
|
g = pal[i*4+1];
|
||||||
|
b = pal[i*4+2];
|
||||||
|
|
||||||
|
dist = colordist2(r,g,b,r8,g8,b8);
|
||||||
|
if (dist < bestdist) {
|
||||||
|
bestdist = dist;
|
||||||
|
besti = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return besti;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Hack
|
||||||
|
void TexMgr_LoadPalette (void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=============
|
=============
|
||||||
GLSLGamma_GammaCorrect
|
GLSLGamma_GammaCorrect
|
||||||
|
@ -188,12 +241,13 @@ GLSLGamma_GammaCorrect
|
||||||
void GLSLGamma_GammaCorrect (void)
|
void GLSLGamma_GammaCorrect (void)
|
||||||
{
|
{
|
||||||
float smax, tmax;
|
float smax, tmax;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (!gl_glsl_gamma_able)
|
if (!gl_glsl_gamma_able)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (vid_gamma.value == 1 && vid_contrast.value == 1)
|
// if (vid_gamma.value == 1 && vid_contrast.value == 1)
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
// create render-to-texture texture if needed
|
// create render-to-texture texture if needed
|
||||||
if (!r_gamma_texture)
|
if (!r_gamma_texture)
|
||||||
|
@ -214,6 +268,72 @@ void GLSLGamma_GammaCorrect (void)
|
||||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!r_lut_texture)
|
||||||
|
{
|
||||||
|
// FIXME: Hack
|
||||||
|
TexMgr_LoadPalette();
|
||||||
|
|
||||||
|
int i,r,g,b;
|
||||||
|
unsigned char *texdata;
|
||||||
|
|
||||||
|
texdata = (unsigned char *) calloc(256 * 256 * 4, 1);
|
||||||
|
|
||||||
|
glGenTextures (1, &r_lut_texture);
|
||||||
|
glBindTexture (GL_TEXTURE_2D, r_lut_texture);
|
||||||
|
|
||||||
|
// make an RGB 565 to quake palette lookup table
|
||||||
|
// This fits exactly in a 256x256 texture.
|
||||||
|
|
||||||
|
// for each color in the 16-bit colorspace...
|
||||||
|
i=0;
|
||||||
|
for (r = 0; r < 32; r++)
|
||||||
|
{
|
||||||
|
for (g = 0; g < 64; g++)
|
||||||
|
{
|
||||||
|
for (b = 0; b < 32; b++)
|
||||||
|
{
|
||||||
|
int idx = b + (g * 32) + (r * 32 * 64);
|
||||||
|
int lut_x = idx / 256;
|
||||||
|
int lut_y = idx % 256;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// convert rgb 565 to 888
|
||||||
|
int r8 = r << 3;
|
||||||
|
int g8 = g << 2;
|
||||||
|
int b8 = b << 3;
|
||||||
|
|
||||||
|
int bestPalIndex = closestPaletteIndex(r8, g8, b8);
|
||||||
|
|
||||||
|
|
||||||
|
const byte *pal = (const byte *)d_8to24table;
|
||||||
|
int newr = pal[4*bestPalIndex];
|
||||||
|
int newg = pal[4*bestPalIndex+1];
|
||||||
|
int newb = pal[4*bestPalIndex+2];
|
||||||
|
//
|
||||||
|
|
||||||
|
// int newr = r8;
|
||||||
|
// int newg = g8;
|
||||||
|
// int newb = b8;
|
||||||
|
|
||||||
|
// insert the r,g,b values of bestPalIndex into the LUT
|
||||||
|
texdata[4*i] = newr;
|
||||||
|
texdata[4*i+1] = newg;
|
||||||
|
texdata[4*i+2] = newb;
|
||||||
|
texdata[4*i+3] = 255;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, texdata);
|
||||||
|
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
|
free(texdata);
|
||||||
|
}
|
||||||
|
|
||||||
// create shader if needed
|
// create shader if needed
|
||||||
if (!r_gamma_program)
|
if (!r_gamma_program)
|
||||||
|
@ -229,13 +349,20 @@ void GLSLGamma_GammaCorrect (void)
|
||||||
GL_DisableMultitexture();
|
GL_DisableMultitexture();
|
||||||
glBindTexture (GL_TEXTURE_2D, r_gamma_texture);
|
glBindTexture (GL_TEXTURE_2D, r_gamma_texture);
|
||||||
glCopyTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, glx, gly, glwidth, glheight);
|
glCopyTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, glx, gly, glwidth, glheight);
|
||||||
|
|
||||||
|
// bind textures
|
||||||
|
GL_SelectTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture (GL_TEXTURE_2D, r_gamma_texture);
|
||||||
|
GL_SelectTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture (GL_TEXTURE_2D, r_lut_texture);
|
||||||
|
|
||||||
// draw the texture back to the framebuffer with a fragment shader
|
// draw the texture back to the framebuffer with a fragment shader
|
||||||
GL_UseProgramFunc (r_gamma_program);
|
GL_UseProgramFunc (r_gamma_program);
|
||||||
GL_Uniform1fFunc (gammaLoc, vid_gamma.value);
|
GL_Uniform1fFunc (gammaLoc, vid_gamma.value);
|
||||||
GL_Uniform1fFunc (contrastLoc, q_min(2.0, q_max(1.0, vid_contrast.value)));
|
GL_Uniform1fFunc (contrastLoc, q_min(2.0, q_max(1.0, vid_contrast.value)));
|
||||||
GL_Uniform1iFunc (textureLoc, 0); // use texture unit 0
|
GL_Uniform1iFunc (textureLoc, 0); // use texture unit 0
|
||||||
|
GL_Uniform1iFunc (lutTextureLoc, 1); // use texture unit 1
|
||||||
|
|
||||||
glDisable (GL_ALPHA_TEST);
|
glDisable (GL_ALPHA_TEST);
|
||||||
glDisable (GL_DEPTH_TEST);
|
glDisable (GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
@ -244,6 +371,8 @@ void GLSLGamma_GammaCorrect (void)
|
||||||
smax = glwidth/(float)r_gamma_texture_width;
|
smax = glwidth/(float)r_gamma_texture_width;
|
||||||
tmax = glheight/(float)r_gamma_texture_height;
|
tmax = glheight/(float)r_gamma_texture_height;
|
||||||
|
|
||||||
|
//R_Clear();
|
||||||
|
|
||||||
glBegin (GL_QUADS);
|
glBegin (GL_QUADS);
|
||||||
glTexCoord2f (0, 0);
|
glTexCoord2f (0, 0);
|
||||||
glVertex2f (-1, -1);
|
glVertex2f (-1, -1);
|
||||||
|
@ -259,6 +388,7 @@ void GLSLGamma_GammaCorrect (void)
|
||||||
|
|
||||||
// clear cached binding
|
// clear cached binding
|
||||||
GL_ClearBindings ();
|
GL_ClearBindings ();
|
||||||
|
GL_SelectTexture(GL_TEXTURE0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue