From 922aa3ca8b6c409117523791b7c8e22b124eb60d Mon Sep 17 00:00:00 2001 From: helixhorned Date: Sun, 16 Dec 2012 19:18:10 +0000 Subject: [PATCH] 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 --- polymer/eduke32/build/include/polymer.h | 6 ++ polymer/eduke32/build/include/polymost.h | 85 +++++++++++---- polymer/eduke32/build/src/polymer.c | 32 +++++- polymer/eduke32/build/src/polymost.c | 131 ++++++++++++----------- polymer/eduke32/source/game.c | 7 +- 5 files changed, 169 insertions(+), 92 deletions(-) diff --git a/polymer/eduke32/build/include/polymer.h b/polymer/eduke32/build/include/polymer.h index 460ba7f23..39d9ffb96 100644 --- a/polymer/eduke32/build/include/polymer.h +++ b/polymer/eduke32/build/include/polymer.h @@ -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 diff --git a/polymer/eduke32/build/include/polymost.h b/polymer/eduke32/build/include/polymost.h index cd4376bf6..23b76961c 100644 --- a/polymer/eduke32/build/include/polymost.h +++ b/polymer/eduke32/build/include/polymost.h @@ -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 diff --git a/polymer/eduke32/build/src/polymer.c b/polymer/eduke32/build/src/polymer.c index 6cac0b171..95d706bee 100644 --- a/polymer/eduke32/build/src/polymer.c +++ b/polymer/eduke32/build/src/polymer.c @@ -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) { diff --git a/polymer/eduke32/build/src/polymost.c b/polymer/eduke32/build/src/polymost.c index 1250a36bc..b11d0c5b3 100644 --- a/polymer/eduke32/build/src/polymost.c +++ b/polymer/eduke32/build/src/polymost.c @@ -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 }, diff --git a/polymer/eduke32/source/game.c b/polymer/eduke32/source/game.c index c1152cb45..68e1d2528 100644 --- a/polymer/eduke32/source/game.c +++ b/polymer/eduke32/source/game.c @@ -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]);