Skip to content

Commit

Permalink
Add cvars for various aspects of r_softemu (#74)
Browse files Browse the repository at this point in the history
- r_softemu_dither: global dithering multiplier (default: 1.0)
- r_softemu_dither_screen: multiplier for screen-space dithering (default: 1.0)
- r_softemu_dither_texture: multiplier for texture-space dithering (default: 1.0)
- r_softemu_lightmap_banding: whether or not to limit lightmap precision to 6 bits
       0 = disabled (8-bit lightmaps)
       1 = enabled (6-bit lightmaps)
      -1 (default) = auto (enabled for r_softemu 3, disabled otherwise)
- r_softemu_mdl_warp: whether or not to use software-style MDL UV mapping
       0 = disabled (use perspective correction)
       1 = enabled (no perspective correction, half-texel offset)
      -1 (default) = auto (enabled for r_softemu 3, disabled otherwise)
- scr_menubgstyle: menu background style
       0 = glquake
       1 = winquake (fine)
       2 = winquake (coarse)
       3 = dos quake
      -1 (default) = auto (chosen based on the value of r_softemu)
  • Loading branch information
andrei-drexler committed Aug 24, 2024
1 parent e53ecee commit b0971a3
Show file tree
Hide file tree
Showing 10 changed files with 138 additions and 30 deletions.
35 changes: 29 additions & 6 deletions Quake/gl_draw.c
Original file line number Diff line number Diff line change
Expand Up @@ -951,13 +951,31 @@ Draw_FadeScreen -- johnfitz -- revised
void Draw_FadeScreen (void)
{
guivertex_t *verts;
int type;
float smax = 0.f, tmax = 0.f, s;

if (scr_menubgalpha.value <= 0.f)
return;

if (scr_menubgstyle.value < 0.f)
{
if (softemu >= SOFTEMU_BANDED)
type = MENUBG_DOSQUAKE;
else if (softemu == SOFTEMU_COARSE)
type = MENUBG_WINQUAKE_SCALED;
else if (softemu == SOFTEMU_FINE)
type = MENUBG_WINQUAKE;
else
type = MENUBG_GLQUAKE;
}
else
{
type = (int)scr_menubgstyle.value;
type = CLAMP (0, type, MENUBG_NUMTYPES - 1);
}

GL_SetCanvas (CANVAS_DEFAULT);
if (softemu >= SOFTEMU_BANDED)
if (type == MENUBG_DOSQUAKE)
{
float clr[3];
Draw_SetTexture (whitetexture);
Expand All @@ -979,11 +997,16 @@ void Draw_FadeScreen (void)
s = (sqrt (s) + s) * 0.5f; // ~0.6 with scr_menubgalpha 0.5
GL_SetCanvasColor (0.095f, 0.08f, 0.045f, s);
}
else if (softemu == SOFTEMU_COARSE)
else if (type == MENUBG_WINQUAKE || type == MENUBG_WINQUAKE_SCALED)
{
s = q_min ((float)vid.guiwidth / 320.0f, (float)vid.guiheight / 200.0f);
s = CLAMP (1.0f, scr_menuscale.value, s);
s = floor (s);
if (type == MENUBG_WINQUAKE_SCALED)
{
s = q_min ((float)vid.guiwidth / 320.0f, (float)vid.guiheight / 200.0f);
s = CLAMP (1.0f, scr_menuscale.value, s);
s = floor (s);
}
else
s = 1.f;
smax = glwidth / (winquakemenubg->width * s);
tmax = glheight / (winquakemenubg->height * s);
Draw_SetTexture (winquakemenubg);
Expand All @@ -1000,7 +1023,7 @@ void Draw_FadeScreen (void)
GL_SetCanvasColor (0.f, 0.f, 0.f, s);
}
}
else
else // MENUBG_GLQUAKE
{
Draw_SetTexture (whitetexture);
Draw_SetBlending (GLS_BLEND_ALPHA);
Expand Down
19 changes: 18 additions & 1 deletion Quake/gl_rmain.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ cvar_t r_noshadow_list = {"r_noshadow_list", "progs/flame2.mdl,progs/flame.mdl,p
extern cvar_t r_vfog;
extern cvar_t vid_fsaa;
//johnfitz
extern cvar_t r_softemu_dither;
extern cvar_t r_softemu_dither_screen;
extern cvar_t r_softemu_dither_texture;

cvar_t gl_zfix = {"gl_zfix", "1", CVAR_ARCHIVE}; // QuakeSpasm z-fighting fix

Expand Down Expand Up @@ -311,6 +314,8 @@ void GL_DeleteFrameBuffers (void)
//
//==============================================================================

static const float NOISESCALE = 9.f / 255.f;

extern GLuint gl_palette_lut;
extern GLuint gl_palette_buffer[2];

Expand All @@ -322,12 +327,14 @@ GL_PostProcess
void GL_PostProcess (void)
{
int palidx, variant;
float dither;
if (!GL_NeedsPostprocess ())
return;

GL_BeginGroup ("Postprocess");

palidx = GLPalette_Postprocess ();
dither = (softemu == SOFTEMU_FINE) ? NOISESCALE * r_softemu_dither.value * r_softemu_dither_screen.value : 0.f;

GL_BindFramebufferFunc (GL_FRAMEBUFFER, 0);
glViewport (glx, gly, glwidth, glheight);
Expand All @@ -339,7 +346,7 @@ void GL_PostProcess (void)
GL_BindNative (GL_TEXTURE1, GL_TEXTURE_3D, gl_palette_lut);
GL_BindBufferRange (GL_SHADER_STORAGE_BUFFER, 0, gl_palette_buffer[palidx], 0, 256 * sizeof (GLuint));
if (variant != 2) // some AMD drivers optimize out the uniform in variant #2
GL_Uniform3fFunc (0, vid_gamma.value, q_min(2.0f, q_max(1.0f, vid_contrast.value)), 1.f/r_refdef.scale);
GL_Uniform4fFunc (0, vid_gamma.value, q_min(2.0f, q_max(1.0f, vid_contrast.value)), 1.f/r_refdef.scale, dither);

glDrawArrays (GL_TRIANGLES, 0, 3);

Expand Down Expand Up @@ -923,6 +930,16 @@ void R_SetupView (void)
r_framedata.eyepos[1] = r_refdef.vieworg[1];
r_framedata.eyepos[2] = r_refdef.vieworg[2];
r_framedata.time = cl.time;
if (softemu == SOFTEMU_FINE || softemu == SOFTEMU_COARSE)
{
r_framedata.screendither = NOISESCALE * r_softemu_dither.value * r_softemu_dither_screen.value;
r_framedata.texturedither = NOISESCALE * r_softemu_dither.value * r_softemu_dither_texture.value;
}
else
{
r_framedata.screendither = 0.f;
r_framedata.texturedither = 0.f;
}

Fog_SetupFrame (); //johnfitz
Sky_SetupFrame ();
Expand Down
2 changes: 2 additions & 0 deletions Quake/gl_screen.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ float scr_conlines; // lines of console to display
//johnfitz -- new cvars
cvar_t scr_menuscale = {"scr_menuscale", "1", CVAR_ARCHIVE};
cvar_t scr_menubgalpha = {"scr_menubgalpha", "0.7", CVAR_ARCHIVE};
cvar_t scr_menubgstyle = {"scr_menubgstyle", "-1", CVAR_ARCHIVE};
cvar_t scr_sbarscale = {"scr_sbarscale", "1", CVAR_ARCHIVE};
cvar_t scr_sbaralpha = {"scr_sbaralpha", "0.75", CVAR_ARCHIVE};
cvar_t scr_conwidth = {"scr_conwidth", "0", CVAR_ARCHIVE};
Expand Down Expand Up @@ -541,6 +542,7 @@ void SCR_Init (void)
//johnfitz -- new cvars
Cvar_RegisterVariable (&scr_menuscale);
Cvar_RegisterVariable (&scr_menubgalpha);
Cvar_RegisterVariable (&scr_menubgstyle);
Cvar_RegisterVariable (&scr_sbarscale);
Cvar_SetCallback (&scr_sbaralpha, SCR_Callback_refdef);
Cvar_RegisterVariable (&scr_sbaralpha);
Expand Down
28 changes: 16 additions & 12 deletions Quake/gl_shaders.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,6 @@ SOFTWARE.*/\
"#define DITHER_NOISE(uv) tri(bayer01(ivec2(uv)))\n"\
"#define SCREEN_SPACE_NOISE() DITHER_NOISE(floor(gl_FragCoord.xy)+0.5)\n"\
"#define SUPPRESS_BANDING() (bayer(ivec2(gl_FragCoord.xy)) * (1./255.))\n"\
"#define PAL_NOISESCALE (9./255.)\n"\

////////////////////////////////////////////////////////////////

Expand All @@ -245,7 +244,7 @@ static const char postprocess_fragment_shader[] =
PALETTE_BUFFER
NOISE_FUNCTIONS
"\n"
"layout(location=0) uniform vec3 Params;\n"
"layout(location=0) uniform vec4 Params;\n"
"\n"
"layout(location=0) out vec4 out_fragcolor;\n"
"\n"
Expand All @@ -254,11 +253,12 @@ NOISE_FUNCTIONS
" float gamma = Params.x;\n"
" float contrast = Params.y;\n"
" float scale = Params.z;\n"
" float dither = Params.w;\n"
" out_fragcolor = texelFetch(GammaTexture, ivec2(gl_FragCoord), 0);\n"
"#if PALETTIZE == 1\n"
" vec2 noiseuv = floor(gl_FragCoord.xy * scale) + 0.5;\n"
" out_fragcolor.rgb = sqrt(out_fragcolor.rgb);\n"
" out_fragcolor.rgb += DITHER_NOISE(noiseuv) * PAL_NOISESCALE;\n"
" out_fragcolor.rgb += DITHER_NOISE(noiseuv) * dither;\n"
" out_fragcolor.rgb *= out_fragcolor.rgb;\n"
"#endif // PALETTIZE == 1\n"
"#if PALETTIZE\n"
Expand All @@ -285,6 +285,8 @@ NOISE_FUNCTIONS
" vec4 SkyFog;\n"\
" vec3 WindDir;\n"\
" float WindPhase;\n"\
" float ScreenDither;\n"\
" float TextureDither;\n"\
" vec3 EyePos;\n"\
" float Time;\n"\
" float ZLogScale;\n"\
Expand Down Expand Up @@ -720,9 +722,9 @@ OIT_OUTPUT (out_fragcolor)
" farblend *= farblend;\n"
" out_fragcolor.rgb = sqrt(out_fragcolor.rgb);\n"
" float luma = dot(out_fragcolor.rgb, vec3(.25, .625, .125));\n"
" float nearnoise = tri(whitenoise01(lmuv * lmsize)) * luma;\n"
" float farnoise = Fog.w > 0. ? SCREEN_SPACE_NOISE() : 0.;\n"
" out_fragcolor.rgb += mix(nearnoise, farnoise, farblend) * PAL_NOISESCALE;\n"
" float nearnoise = tri(whitenoise01(lmuv * lmsize)) * luma * TextureDither;\n"
" float farnoise = Fog.w > 0. ? SCREEN_SPACE_NOISE() * ScreenDither : 0.;\n"
" out_fragcolor.rgb += mix(nearnoise, farnoise, farblend);\n"
" out_fragcolor.rgb *= out_fragcolor.rgb;\n"
"#endif // DITHER == 1\n"
"#if DITHER >= 2\n"
Expand Down Expand Up @@ -803,7 +805,7 @@ OIT_OUTPUT (out_fragcolor)
" if (Fog.w > 0.)\n"
" {\n"
" out_fragcolor.rgb = sqrt(out_fragcolor.rgb);\n"
" out_fragcolor.rgb += SCREEN_SPACE_NOISE() * PAL_NOISESCALE;\n"
" out_fragcolor.rgb += SCREEN_SPACE_NOISE() * ScreenDither;\n"
" out_fragcolor.rgb *= out_fragcolor.rgb;\n"
" }\n"
"#else\n"
Expand Down Expand Up @@ -961,7 +963,7 @@ NOISE_FUNCTIONS
" out_fragcolor.rgb = mix(out_fragcolor.rgb, SkyFog.rgb, SkyFog.a);\n"
"#if DITHER\n"
" out_fragcolor.rgb = sqrt(out_fragcolor.rgb);\n"
" out_fragcolor.rgb += SCREEN_SPACE_NOISE() * PAL_NOISESCALE;\n"
" out_fragcolor.rgb += SCREEN_SPACE_NOISE() * ScreenDither;\n"
" out_fragcolor.rgb *= out_fragcolor.rgb;\n"
"#else\n"
" out_fragcolor.rgb += SUPPRESS_BANDING();\n"
Expand Down Expand Up @@ -1000,6 +1002,7 @@ static const char sky_boxside_fragment_shader[] =
NOISE_FUNCTIONS
"\n"
"layout(location=2) uniform vec4 Fog;\n"
"layout(location=3) uniform float ScreenDither;\n"
"\n"
"layout(location=0) in vec3 in_dir;\n"
"layout(location=1) in vec2 in_uv;\n"
Expand All @@ -1012,7 +1015,7 @@ NOISE_FUNCTIONS
" out_fragcolor.rgb = mix(out_fragcolor.rgb, Fog.rgb, Fog.w);\n"
"#if DITHER\n"
" out_fragcolor.rgb = sqrt(out_fragcolor.rgb);\n"
" out_fragcolor.rgb += SCREEN_SPACE_NOISE() * PAL_NOISESCALE;\n"
" out_fragcolor.rgb += SCREEN_SPACE_NOISE() * ScreenDither;\n"
" out_fragcolor.rgb *= out_fragcolor.rgb;\n"
"#else\n"
" out_fragcolor.rgb += SUPPRESS_BANDING();\n"
Expand Down Expand Up @@ -1041,6 +1044,7 @@ NOISE_FUNCTIONS
" mat4 ViewProj;\n"\
" vec3 EyePos;\n"\
" vec4 Fog;\n"\
" float ScreenDither;\n"\
" InstanceData instances[];\n"\
"};\n"\

Expand Down Expand Up @@ -1185,7 +1189,7 @@ OIT_OUTPUT (out_fragcolor)
" if (abs(Fog.w) > 0.)\n"
" {\n"
" out_fragcolor.rgb = sqrt(out_fragcolor.rgb);\n"
" out_fragcolor.rgb += SCREEN_SPACE_NOISE() * PAL_NOISESCALE;\n"
" out_fragcolor.rgb += SCREEN_SPACE_NOISE() * ScreenDither;\n"
" out_fragcolor.rgb *= out_fragcolor.rgb;\n"
" }\n"
"#else\n"
Expand Down Expand Up @@ -1239,7 +1243,7 @@ NOISE_FUNCTIONS
" if (Fog.w > 0.)\n"
" {\n"
" out_fragcolor.rgb = sqrt(out_fragcolor.rgb);\n"
" out_fragcolor.rgb += SCREEN_SPACE_NOISE() * PAL_NOISESCALE;\n"
" out_fragcolor.rgb += SCREEN_SPACE_NOISE() * ScreenDither;\n"
" out_fragcolor.rgb *= out_fragcolor.rgb;\n"
" }\n"
"#else\n"
Expand Down Expand Up @@ -1313,7 +1317,7 @@ OIT_OUTPUT (out_fragcolor)
" if (Fog.w > 0.)\n"
" {\n"
" out_fragcolor.rgb = sqrt(out_fragcolor.rgb);\n"
" out_fragcolor.rgb += SCREEN_SPACE_NOISE() * PAL_NOISESCALE;\n"
" out_fragcolor.rgb += SCREEN_SPACE_NOISE() * ScreenDither;\n"
" out_fragcolor.rgb *= out_fragcolor.rgb;\n"
" }\n"
"#else\n"
Expand Down
1 change: 1 addition & 0 deletions Quake/gl_sky.c
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,7 @@ void Sky_DrawSkyBox (void)
GL_UniformMatrix4fvFunc (0, 1, GL_FALSE, r_matviewproj);
GL_Uniform3fvFunc (1, 1, r_refdef.vieworg);
GL_Uniform4fvFunc (2, 1, fog);
GL_Uniform1fFunc (3, r_framedata.screendither);

for (i = 0; i < 6; i++)
{
Expand Down
16 changes: 14 additions & 2 deletions Quake/gl_texmgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ static const struct {

cvar_t r_softemu = {"r_softemu", "0", CVAR_ARCHIVE};
cvar_t r_softemu_metric = {"r_softemu_metric", "-1", CVAR_ARCHIVE};
cvar_t r_softemu_lightmap_banding = {"r_softemu_lightmap_banding", "-1", CVAR_ARCHIVE};
cvar_t r_softemu_mdl_warp = {"r_softemu_mdl_warp", "-1", CVAR_ARCHIVE};
cvar_t r_softemu_dither = {"r_softemu_dither", "1.0", CVAR_ARCHIVE};
cvar_t r_softemu_dither_screen = {"r_softemu_dither_screen", "1.0", CVAR_ARCHIVE};
cvar_t r_softemu_dither_texture = {"r_softemu_dither_texture", "1.0", CVAR_ARCHIVE};

static cvar_t gl_max_size = {"gl_max_size", "0", CVAR_NONE};
static cvar_t gl_picmip = {"gl_picmip", "0", CVAR_NONE};
cvar_t gl_lodbias = {"gl_lodbias", "auto", CVAR_ARCHIVE };
Expand Down Expand Up @@ -333,8 +339,8 @@ void TexMgr_ApplySettings (void)
gl_texfilter.anisotropy = CLAMP (1.f, gl_texture_anisotropy.value, gl_max_anisotropy);
gl_texfilter.lodbias = lodbias;

// softemu 2 & 3 override filtering mode, unless it's GL_NEAREST
if (softemu >= SOFTEMU_COARSE && gl_texfilter.mode != 0)
// if softemu is either 2 & 3 or r_softemu_lightmap_banding is > 0 we override the filtering mode, unless it's GL_NEAREST
if (gl_texfilter.mode != 0 && (softemu >= SOFTEMU_COARSE || r_softemu_lightmap_banding.value > 0.f))
{
const float SOFTEMU_ANISOTROPY = 8.f;
gl_texfilter.mode = 2; // nearest with linear mips
Expand Down Expand Up @@ -867,6 +873,12 @@ void TexMgr_Init (void)
Cvar_SetCallback (&gl_lodbias, TexMgr_LodBias_f);
Cvar_RegisterVariable (&r_softemu);
Cvar_SetCallback (&r_softemu, TexMgr_SoftEmu_f);
Cvar_RegisterVariable (&r_softemu_lightmap_banding);
Cvar_SetCallback (&r_softemu_lightmap_banding, TexMgr_SoftEmu_f);
Cvar_RegisterVariable (&r_softemu_mdl_warp);
Cvar_RegisterVariable (&r_softemu_dither);
Cvar_RegisterVariable (&r_softemu_dither_screen);
Cvar_RegisterVariable (&r_softemu_dither_texture);
Cmd_AddCommand ("gl_describetexturemodes", &TexMgr_DescribeTextureModes_f);
cmd = Cmd_AddCommand ("imagelist", &TexMgr_Imagelist_f);
if (cmd)
Expand Down
7 changes: 5 additions & 2 deletions Quake/glquake.h
Original file line number Diff line number Diff line change
Expand Up @@ -403,12 +403,15 @@ typedef struct gpuframedata_s {
float skyfogdata[4];
vec3_t winddir;
float windphase;
float screendither;
float texturedither;
float _padding1[2];
vec3_t eyepos;
float time;
float zlogscale;
float zlogbias;
int numlights;
int padding;
int _padding2;
} gpuframedata_t;

extern gpulightbuffer_t r_lightbuffer;
Expand Down Expand Up @@ -500,7 +503,7 @@ typedef struct glprogs_s {
GLuint oit_resolve[2]; // [msaa]

/* 3d */
GLuint world[2][3][3]; // [OIT][dither][mode:solid/alpha test/water]
GLuint world[2][3][3]; // [OIT][standard/dithered/banded][solid/alpha test/water]
GLuint water[2][2]; // [OIT][dither]
GLuint skystencil;
GLuint skylayers[2]; // [dither]
Expand Down
14 changes: 9 additions & 5 deletions Quake/r_alias.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ struct ibuf_s {
vec3_t eyepos;
float _pad;
vec4_t fog;
float dither;
float _padding[3];
} global;
aliasinstance_t inst[MAX_ALIAS_INSTANCES];
} ibuf;
Expand Down Expand Up @@ -292,10 +294,11 @@ R_FlushAliasInstances
*/
void R_FlushAliasInstances (void)
{
extern cvar_t r_softemu_mdl_warp;
qmodel_t *model;
aliashdr_t *paliashdr;
qboolean alphatest, translucent, oit, md5;
GLuint program;
int mode;
unsigned state;
GLuint buf;
GLbyte *ofs;
Expand All @@ -320,16 +323,16 @@ void R_FlushAliasInstances (void)
switch (softemu)
{
case SOFTEMU_BANDED:
program = glprogs.alias[oit][ALIASSHADER_NOPERSP][alphatest][md5];
mode = r_softemu_mdl_warp.value != 0.f ? ALIASSHADER_NOPERSP : ALIASSHADER_STANDARD;
break;
case SOFTEMU_COARSE:
program = glprogs.alias[oit][ALIASSHADER_DITHER][alphatest][md5];
mode = r_softemu_mdl_warp.value > 0.f ? ALIASSHADER_NOPERSP : ALIASSHADER_DITHER;
break;
default:
program = glprogs.alias[oit][ALIASSHADER_STANDARD][alphatest][md5];
mode = r_softemu_mdl_warp.value > 0.f ? ALIASSHADER_NOPERSP : ALIASSHADER_STANDARD;
break;
}
GL_UseProgram (program);
GL_UseProgram (glprogs.alias[oit][mode][alphatest][md5]);

if (md5)
state = GLS_CULL_BACK | GLS_ATTRIBS(5);
Expand All @@ -351,6 +354,7 @@ void R_FlushAliasInstances (void)
-fabs (r_framedata.fogdata[3]) :
fabs (r_framedata.fogdata[3])
;
ibuf.global.dither = r_framedata.screendither;

ibuf_size = sizeof(ibuf.global) + sizeof(ibuf.inst[0]) * ibuf.count;
GL_Upload (GL_SHADER_STORAGE_BUFFER, &ibuf.global, ibuf_size, &buf, &ofs);
Expand Down
Loading

0 comments on commit b0971a3

Please sign in to comment.