Classic-like visibility/fog for OpenGL modes, r_usenewshading 2 (new default).

Implemented using GL_LINEAR fog. The only source of difference (besides the
obvious indexed vs. true color) should now be the distance constant, which
still had to be determined experimentally.  Polymer implements this mode in
its fog fragment program part.

Parallaxed skies are always drawn with full visibility, I'm not sure if there
are any maps that expect otherwise.

Also, accidentally committed: factor out initialization code from
polymost_printext256() into gen_font_glyph_tex(), small game.c changes.

git-svn-id: https://svn.eduke32.com/eduke32@3301 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2012-12-16 19:18:10 +00:00
parent bb46b57d89
commit 922aa3ca8b
5 changed files with 169 additions and 92 deletions

View file

@ -28,6 +28,8 @@
# include "polymost.h"
# include "pragmas.h"
#define PR_LINEAR_FOG
// CVARS
extern int32_t pr_lighting;
extern int32_t pr_normalmapping;
@ -149,6 +151,10 @@ typedef struct s_prrograminfo {
GLint uniform_specMaterial;
// PR_BIT_MIRROR_MAP
GLint uniform_mirrorMap;
#ifdef PR_LINEAR_FOG
// PR_BIT_FOG
GLint uniform_linearFog;
#endif
// PR_BIT_GLOW_MAP
GLint uniform_glowMap;
// PR_BIT_PROJECTION_MAP

View file

@ -120,36 +120,63 @@ extern int32_t drawingskybox;
extern double gyxscale, gxyaspect, ghalfx, grhalfxdown10;
// For GL_EXP2 fog:
#define FOGSCALE 0.0000768
// For GL_LINEAR fog:
#define FOGDISTCONST 150
#define FULLVIS_BEGIN 2.9e38
#define FULLVIS_END 3.0e38
extern char nofog; // in windows/SDL layers
extern float fogresult, fogcol[4], fogtable[4*MAXPALOOKUPS];
extern float fogresult, fogresult2, fogcol[4], fogtable[4*MAXPALOOKUPS];
extern int32_t g_visibility;
static inline void fogcalc(int32_t shade, int32_t vis, int32_t pal)
{
float f;
Bmemcpy(fogcol, &fogtable[pal<<2], sizeof(fogcol));
if (r_usenewshading)
if (r_usenewshading==2)
{
f = 0.9f * shade;
f = (vis > 239) ? (float)(gvisibility*((vis-240+f))) :
(float)(gvisibility*(vis+16+f));
float combvis = (float)(g_visibility * (uint8_t)(vis+16));
bglFogi(GL_FOG_MODE, GL_LINEAR);
if (combvis == 0)
{
fogresult = FULLVIS_BEGIN;
fogresult2 = FULLVIS_END;
return;
}
fogresult = -(FOGDISTCONST * shade)/combvis;
fogresult2 = (FOGDISTCONST * (numshades-1-shade))/combvis;
}
else
{
f = (shade < 0) ? shade * 3.5f : shade * .66f;
f = (vis > 239) ? (float)(gvisibility*((vis-240+f)/(klabs(vis-256)))) :
(float)(gvisibility*(vis+16+f));
float f;
bglFogi(GL_FOG_MODE, GL_EXP2);
if (r_usenewshading==1)
{
f = 0.9f * shade;
f = (vis > 239) ? (float)(gvisibility*((vis-240+f))) :
(float)(gvisibility*(vis+16+f));
}
else
{
f = (shade < 0) ? shade * 3.5f : shade * .66f;
f = (vis > 239) ? (float)(gvisibility*((vis-240+f)/(klabs(vis-256)))) :
(float)(gvisibility*(vis+16+f));
}
if (f < 0.001f)
f = 0.001f;
else if (f > 100.0f)
f = 100.0f;
fogresult = f;
}
if (f < 0.001f)
f = 0.001f;
else if (f > 100.0f)
f = 100.0f;
fogresult = f;
Bmemcpy(fogcol, &fogtable[pal<<2], sizeof(fogcol));
}
static inline void calc_and_apply_fog(int32_t shade, int32_t vis, int32_t pal)
@ -157,8 +184,17 @@ static inline void calc_and_apply_fog(int32_t shade, int32_t vis, int32_t pal)
if (!nofog)
{
fogcalc(shade, vis, pal);
bglFogf(GL_FOG_DENSITY, fogresult);
bglFogfv(GL_FOG_COLOR, fogcol);
if (r_usenewshading==2)
{
bglFogf(GL_FOG_START, fogresult);
bglFogf(GL_FOG_END, fogresult2);
}
else
{
bglFogf(GL_FOG_DENSITY, fogresult);
}
}
}
@ -167,8 +203,17 @@ static inline void calc_and_apply_fog_factor(int32_t shade, int32_t vis, int32_t
if (!nofog)
{
fogcalc(shade, vis, pal);
bglFogf(GL_FOG_DENSITY, fogresult*factor);
bglFogfv(GL_FOG_COLOR, fogcol);
if (r_usenewshading==2)
{
bglFogf(GL_FOG_START, FULLVIS_BEGIN);
bglFogf(GL_FOG_END, FULLVIS_END);
}
else
{
bglFogf(GL_FOG_DENSITY, fogresult*factor);
}
}
}
#endif

View file

@ -395,14 +395,28 @@ _prprogrambit prprogrambits[PR_BIT_COUNT] = {
// vert_prog
"",
// frag_def
#ifdef PR_LINEAR_FOG
"uniform bool linearFog;\n"
#endif
"",
// frag_prog
" float fragDepth;\n"
" float fogFactor;\n"
"\n"
" fragDepth = gl_FragCoord.z / gl_FragCoord.w / 35.0;\n"
" fragDepth *= fragDepth;\n"
" fogFactor = exp2(-gl_Fog.density * gl_Fog.density * fragDepth * 1.442695);\n"
#ifdef PR_LINEAR_FOG
" if (!linearFog) {\n"
#endif
" fragDepth *= fragDepth;\n"
" fogFactor = exp2(-gl_Fog.density * gl_Fog.density * fragDepth * 1.442695);\n"
#ifdef PR_LINEAR_FOG
/* 0.65127==150/230, another constant found out by experiment. :/
* (150 is Polymost's FOGDISTCONST.) */
" } else {\n"
" fogFactor = gl_Fog.scale * (gl_Fog.end - fragDepth*0.65217);\n"
" fogFactor = clamp(fogFactor, 0.0, 1.0);"
" }\n"
#endif
" result.rgb = mix(gl_Fog.color.rgb, result.rgb, fogFactor);\n"
"\n",
},
@ -4810,7 +4824,12 @@ static int32_t polymer_bindmaterial(_prmaterial material, int16_t* lights,
texunit++;
}
#ifdef PR_LINEAR_FOG
if (programbits & prprogrambits[PR_BIT_FOG].bit)
{
bglUniform1iARB(prprograms[programbits].uniform_linearFog, r_usenewshading==2);
}
#endif
// PR_BIT_GLOW_MAP
if (programbits & prprogrambits[PR_BIT_GLOW_MAP].bit)
{
@ -5103,7 +5122,12 @@ static void polymer_compileprogram(int32_t programbits)
{
prprograms[programbits].uniform_mirrorMap = bglGetUniformLocationARB(program, "mirrorMap");
}
#ifdef PR_LINEAR_FOG
if (programbits & prprogrambits[PR_BIT_FOG].bit)
{
prprograms[programbits].uniform_linearFog = bglGetUniformLocationARB(program, "linearFog");
}
#endif
// PR_BIT_GLOW_MAP
if (programbits & prprogrambits[PR_BIT_GLOW_MAP].bit)
{

View file

@ -113,7 +113,7 @@ static double dxb1[MAXWALLSB], dxb2[MAXWALLSB];
float shadescale = 1.3f;
int32_t shadescale_unbounded = 0;
int32_t r_usenewshading = 1;
int32_t r_usenewshading = 2;
static double gviewxrange, ghoriz;
double gyxscale, gxyaspect, ghalfx, grhalfxdown10, grhalfxdown10x;
@ -197,7 +197,7 @@ int32_t r_downsize = 1;
int32_t r_downsizevar = -1;
// used for fogcalc
float fogresult, fogcol[4], fogtable[4*MAXPALOOKUPS];
float fogresult, fogresult2, fogcol[4], fogtable[4*MAXPALOOKUPS];
#endif
static char ptempbuf[MAXWALLSB<<1];
@ -711,26 +711,16 @@ static void clear_cache_internal(void)
// one-time initialization of OpenGL for polymost
void polymost_glinit()
{
GLfloat col[4];
int32_t i;
if (!Bstrcmp(glinfo.vendor, "NVIDIA Corporation"))
{
bglHint(GL_FOG_HINT,GL_NICEST);
}
bglHint(GL_FOG_HINT, GL_NICEST);
else
{
bglHint(GL_FOG_HINT,GL_DONT_CARE);
}
bglHint(GL_FOG_HINT, GL_DONT_CARE);
bglFogi(GL_FOG_MODE, GL_EXP2);
bglFogf(GL_FOG_DENSITY,1.0); //must be > 0, default is 1
/* bglFogf(GL_FOG_START,0.0); //default is 0
bglFogf(GL_FOG_END,1.0); //default is 1 */
col[0] = 0; col[1] = 0; col[2] = 0; col[3] = 0; //range:0 to 1
bglFogfv(GL_FOG_COLOR,col); //default is 0,0,0,0
bglBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
bglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
bglPixelStorei(GL_PACK_ALIGNMENT, 1);
@ -5996,6 +5986,61 @@ int32_t polymost_drawtilescreen(int32_t tilex, int32_t tiley, int32_t wallnum, i
#endif
}
static int32_t gen_font_glyph_tex(void)
{
// construct a 256x128 8-bit alpha-only texture for the font glyph matrix
char *tbuf, *cptr, *tptr;
int32_t h,i,j;
bglGenTextures(1,&polymosttext);
if (!polymosttext) return -1;
tbuf = (char *)Bmalloc(256*128);
if (!tbuf)
{
bglDeleteTextures(1,&polymosttext);
polymosttext = 0;
return -1;
}
Bmemset(tbuf, 0, 256*128);
cptr = (char *)textfont;
for (h=0; h<256; h++)
{
tptr = tbuf + (h%32)*8 + (h/32)*256*8;
for (i=0; i<8; i++)
{
for (j=0; j<8; j++)
{
if (cptr[h*8+i] & pow2char[7-j]) tptr[j] = 255;
}
tptr += 256;
}
}
cptr = (char *)smalltextfont;
for (h=0; h<256; h++)
{
tptr = tbuf + 256*64 + (h%32)*8 + (h/32)*256*8;
for (i=1; i<7; i++)
{
for (j=2; j<6; j++)
{
if (cptr[h*8+i] & pow2char[7-j]) tptr[j-2] = 255;
}
tptr += 256;
}
}
bglBindTexture(GL_TEXTURE_2D, polymosttext);
bglTexImage2D(GL_TEXTURE_2D,0,GL_ALPHA,256,128,0,GL_ALPHA,GL_UNSIGNED_BYTE,(GLvoid *)tbuf);
bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
Bfree(tbuf);
return 0;
}
int32_t polymost_printext256(int32_t xpos, int32_t ypos, int16_t col, int16_t backcol, const char *name, char fontsize)
{
#ifndef USE_OPENGL
@ -6017,57 +6062,13 @@ int32_t polymost_printext256(int32_t xpos, int32_t ypos, int16_t col, int16_t ba
if (!polymosttext)
{
// construct a 256x128 8-bit alpha-only texture for the font glyph matrix
char *tbuf, *cptr, *tptr;
int32_t h,i,j;
bglGenTextures(1,&polymosttext);
if (!polymosttext) return -1;
tbuf = (char *)Bmalloc(256*128);
if (!tbuf)
{
bglDeleteTextures(1,&polymosttext);
polymosttext = 0;
if (gen_font_glyph_tex() < 0)
return -1;
}
Bmemset(tbuf, 0, 256*128);
cptr = (char *)textfont;
for (h=0; h<256; h++)
{
tptr = tbuf + (h%32)*8 + (h/32)*256*8;
for (i=0; i<8; i++)
{
for (j=0; j<8; j++)
{
if (cptr[h*8+i] & pow2char[7-j]) tptr[j] = 255;
}
tptr += 256;
}
}
cptr = (char *)smalltextfont;
for (h=0; h<256; h++)
{
tptr = tbuf + 256*64 + (h%32)*8 + (h/32)*256*8;
for (i=1; i<7; i++)
{
for (j=2; j<6; j++)
{
if (cptr[h*8+i] & pow2char[7-j]) tptr[j-2] = 255;
}
tptr += 256;
}
}
bglBindTexture(GL_TEXTURE_2D, polymosttext);
bglTexImage2D(GL_TEXTURE_2D,0,GL_ALPHA,256,128,0,GL_ALPHA,GL_UNSIGNED_BYTE,(GLvoid *)tbuf);
bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
Bfree(tbuf);
}
else bglBindTexture(GL_TEXTURE_2D, polymosttext);
else
{
bglBindTexture(GL_TEXTURE_2D, polymosttext);
}
setpolymost2dview(); // disables blending, texturing, and depth testing
bglDisable(GL_ALPHA_TEST);
@ -6283,7 +6284,7 @@ void polymost_initosdfuncs(void)
{ "r_texturemaxsize","r_texturemaxsize: changes the maximum OpenGL texture size limit",(void *) &gltexmaxsize, CVAR_INT | CVAR_NOSAVE, 0, 4096 },
{ "r_texturemiplevel","r_texturemiplevel: changes the highest OpenGL mipmap level used",(void *) &gltexmiplevel, CVAR_INT, 0, 6 },
{ "r_texturemode", "r_texturemode: changes the texture filtering settings", (void *) &gltexfiltermode, CVAR_INT|CVAR_FUNCPTR, 0, 5 },
{ "r_usenewshading", "r_usenewshading: enable/disable new shading/visibility code", (void *) &r_usenewshading, CVAR_BOOL, 0, 1 },
{ "r_usenewshading", "r_usenewshading: visibility code: 0: Polymost, 2: Classic", (void *) &r_usenewshading, CVAR_INT, 0, 2 },
{ "r_vbocount","r_vbocount: sets the number of Vertex Buffer Objects to use when drawing models",(void *) &r_vbocount, CVAR_INT, 1, 256 },
{ "r_vbos","r_vbos: enable/disable using Vertex Buffer Objects when drawing models",(void *) &r_vbos, CVAR_BOOL, 0, 1 },
{ "r_vertexarrays","r_vertexarrays: enable/disable using vertex arrays when drawing models",(void *) &r_vertexarrays, CVAR_BOOL, 0, 1 },

View file

@ -3044,7 +3044,7 @@ void G_DisplayRest(int32_t smoothratio)
}
}
static void G_DoThirdPerson(DukePlayer_t *pp, vec3_t *vect,int16_t *vsectnum, int32_t ang, int32_t horiz)
static void G_DoThirdPerson(const DukePlayer_t *pp, vec3_t *vect, int16_t *vsectnum, int32_t ang, int32_t horiz)
{
spritetype *sp = &sprite[pp->i];
int32_t i, hx, hy;
@ -7868,10 +7868,11 @@ FAKE_F2:
return;
}
M_ChangeMenu(350);
g_screenCapture = 1;
G_DrawRooms(myconnectindex,65536);
//savetemp("duke3d.tmp",waloff[TILE_SAVESHOT],160*100);
g_screenCapture = 0;
FX_StopAllSounds();
S_ClearSoundLocks();
@ -7938,8 +7939,8 @@ FAKE_F3:
}
g_screenCapture = 1;
G_DrawRooms(myconnectindex,65536);
//savetemp("duke3d.tmp",waloff[TILE_SAVESHOT],160*100);
g_screenCapture = 0;
if (g_lastSaveSlot >= 0)
{
/* inputloc = Bstrlen(&ud.savegame[g_lastSaveSlot][0]);