From ee67d350e3cf88dc893d724f394ad8e8847765f2 Mon Sep 17 00:00:00 2001 From: mittorn Date: Sat, 13 Apr 2019 20:50:27 +0700 Subject: [PATCH] ref_soft: Fix world unload. Improve lightmap sample detection --- r_context.c | 10 +++-- r_edge.c | 10 ++--- r_local.h | 7 ++++ r_main.c | 36 +++++++++++++++- r_surf.c | 119 ++++++++++++++++++++++++++++++++++++++++++---------- 5 files changed, 147 insertions(+), 35 deletions(-) diff --git a/r_context.c b/r_context.c index 101d093a..f13b8825 100644 --- a/r_context.c +++ b/r_context.c @@ -123,7 +123,7 @@ static void GAME_EXPORT CL_FillRGBABlend( float _x, float _y, float _w, float _h _TriColor4ub(r,g,b,a); Draw_Fill(_x,_y,_w,_h); } - +void Mod_UnloadTextures( model_t *mod ); qboolean GAME_EXPORT Mod_ProcessRenderData( model_t *mod, qboolean create, const byte *buf ) { @@ -155,8 +155,8 @@ qboolean GAME_EXPORT Mod_ProcessRenderData( model_t *mod, qboolean create, const if( loaded && gEngfuncs.drawFuncs->Mod_ProcessUserData ) gEngfuncs.drawFuncs->Mod_ProcessUserData( mod, create, buf ); - //if( !create ) - //Mod_UnloadTextures( mod ); + if( !create ) + Mod_UnloadTextures( mod ); return loaded; } @@ -281,6 +281,10 @@ void Mod_BrushUnloadTextures( model_t *mod ) { int i; + + gEngfuncs.Con_Printf("Unloading world\n"); + tr.map_unload = true; + for( i = 0; i < mod->numtextures; i++ ) { texture_t *tx = mod->textures[i]; diff --git a/r_edge.c b/r_edge.c index cf10f868..e48495ca 100644 --- a/r_edge.c +++ b/r_edge.c @@ -846,7 +846,6 @@ void D_CalcGradients (msurface_t *pface) tadjust = ((fixed16_t)(DotProduct (p_temp1, p_taxis) * 0x10000 + 0.5)) - ((pface->info->lightmapmins[1] << 16) >> miplevel) + pface->info->lmvecs[1][3]*t; -#if 1 // PGM - changing flow speed for non-warping textures. if (pface->flags & SURF_CONVEYOR) { @@ -855,13 +854,10 @@ void D_CalcGradients (msurface_t *pface) sadjust += 0x10000 * (-128 * ( (gpGlobals->time * 0.25) - (int)(gpGlobals->time * 0.25) )); else sadjust += 0x10000 * (-128 * ( (gpGlobals->time * 0.77) - (int)(gpGlobals->time * 0.77) )); + bbextents = ((pface->extents[0] << 16) >> miplevel) - 1; } - // PGM -#endif -// -// -1 (-epsilon) so we never wander off the edge of the texture -// - bbextents = ((pface->info->lightextents[0] << 16) >> miplevel) - 1; + else + bbextents = ((pface->info->lightextents[0] << 16) >> miplevel) - 1; bbextentt = ((pface->info->lightextents[1] << 16) >> miplevel) - 1; } diff --git a/r_local.h b/r_local.h index ad3bf50a..dc6e7acf 100644 --- a/r_local.h +++ b/r_local.h @@ -294,6 +294,9 @@ typedef struct qboolean fCustomSkybox; char mapname[MAX_STRING]; + int sample_size; + uint sample_bits; + qboolean map_unload; } gl_globals_t; typedef struct @@ -1285,6 +1288,10 @@ void R_SetUpWorldTransform (void); #define BLEND_ADD(src, screen) vid.addmap[ src& 0xff00|(screen>>8)] << 8 | (screen & 0xff) | ((src & 0xff) >> 0); #define BLEND_COLOR(src, color) vid.modmap[src & 0xff00|(color>>8)] << 8 | (src & color & 0xff) | ((src & 0xff) >> 3); +#define LM_SAMPLE_SIZE_AUTO(surf) (tr.sample_size == -1?gEngfuncs.Mod_SampleSizeForFace( surf ): tr.sample_size) + + + // // engine callbacks // diff --git a/r_main.c b/r_main.c index c50538be..f1103a4d 100644 --- a/r_main.c +++ b/r_main.c @@ -1594,6 +1594,12 @@ void GAME_EXPORT R_RenderScene( void ) // begin a new frame tr.framecount++; + if( tr.map_unload ) + { + D_FlushCaches(); + tr.map_unload = false; + } + R_SetupFrustum(); R_SetupFrame(); @@ -1824,6 +1830,7 @@ void GAME_EXPORT R_NewMap (void) { int i; r_viewcluster = -1; + model_t *world = WORLDMODEL; tr.draw_list->num_solid_entities = 0; tr.draw_list->num_trans_entities = 0; @@ -1871,8 +1878,33 @@ void GAME_EXPORT R_NewMap (void) } // clear out efrags in case the level hasn't been reloaded - for( i = 0; i < WORLDMODEL->numleafs; i++ ) - WORLDMODEL->leafs[i+1].efrags = NULL; + for( i = 0; i < world->numleafs; i++ ) + world->leafs[i+1].efrags = NULL; + + tr.sample_size = gEngfuncs.Mod_SampleSizeForFace( &world->surfaces[0] ); + + for( i = 1; i < world->numsurfaces; i++ ) + { + int sample_size = gEngfuncs.Mod_SampleSizeForFace( &world->surfaces[i] ); + if( sample_size != tr.sample_size ) + { + tr.sample_size = -1; + break; + } + } + tr.sample_bits = -1; + + if( tr.sample_size != -1 ) + { + uint sample_pot; + + tr.sample_bits = 0; + + for( sample_pot = 1; sample_pot < tr.sample_size; sample_pot <<= 1, tr.sample_bits++ ); + } + + gEngfuncs.Con_Printf("Map sample size is %d\n", tr.sample_size ); + } /* diff --git a/r_surf.c b/r_surf.c index ce6f2823..4a95293a 100644 --- a/r_surf.c +++ b/r_surf.c @@ -40,6 +40,7 @@ void R_DrawSurfaceBlock8_mip0 (void); void R_DrawSurfaceBlock8_mip1 (void); void R_DrawSurfaceBlock8_mip2 (void); void R_DrawSurfaceBlock8_mip3 (void); +void R_DrawSurfaceBlock8_Generic (void); static void (*surfmiptable[4])(void) = { R_DrawSurfaceBlock8_mip0, @@ -488,12 +489,21 @@ void R_DrawSurface (void) surfrowbytes = r_drawsurf.rowbytes; - sample_size = gEngfuncs.Mod_SampleSizeForFace( r_drawsurf.surf ); - sample_bits = 0; - for( sample_pot = 1; sample_pot < sample_size; sample_pot <<= 1, sample_bits++ ); - + sample_size = LM_SAMPLE_SIZE_AUTO(r_drawsurf.surf); + if( sample_size == 16 ) + sample_bits = 4, sample_pot = sample_size; + else + { + sample_bits = tr.sample_bits; - //printf("%d\n", sample_size ); + if( sample_bits == -1 ) + { + sample_bits = 0; + for( sample_pot = 1; sample_pot < sample_size; sample_pot <<= 1, sample_bits++ ); + } + else + sample_pot = 1 << sample_bits; + } mt = r_drawsurf.image; @@ -508,15 +518,21 @@ void R_DrawSurface (void) blockdivshift = sample_bits - r_drawsurf.surfmip; blockdivmask = (1 << blockdivshift) - 1; - r_lightwidth = ( r_drawsurf.surf->info->lightextents[0] / gEngfuncs.Mod_SampleSizeForFace( r_drawsurf.surf ) ) + 1; - //r_lightwidth = (r_drawsurf.surf->extents[0]>>4)+1; + if( sample_size == 16 ) + r_lightwidth = ( r_drawsurf.surf->info->lightextents[0]>>4)+1; + else + r_lightwidth = ( r_drawsurf.surf->info->lightextents[0] / sample_size ) + 1; r_numhblocks = r_drawsurf.surfwidth >> blockdivshift; r_numvblocks = r_drawsurf.surfheight >> blockdivshift; //============================== - pblockdrawer = surfmiptable[r_drawsurf.surfmip]; + if( sample_size == 16 ) + pblockdrawer = surfmiptable[r_drawsurf.surfmip]; + else + pblockdrawer = R_DrawSurfaceBlock8_Generic; + // TODO: only needs to be set when there is a display settings change horzblockstep = blocksize; @@ -566,6 +582,61 @@ void R_DrawSurface (void) #if !id386 #define BLEND_LM(pix, light) vid.colormap[(pix >> 3) | ((light & 0x1f00) << 5)] | pix & 7; + +/* +================ +R_DrawSurfaceBlock8_Generic +================ +*/ +void R_DrawSurfaceBlock8_Generic (void) +{ + int v, i, b; + uint lightstep, lighttemp, light; + pixel_t pix, *psource, *prowdest; + + psource = pbasesource; + prowdest = prowdestbase; + + for (v=0 ; v> (4-r_drawsurf.surfmip); + lightrightstep = (r_lightptr[1] - lightright) >> (4-r_drawsurf.surfmip); + + for (i=0 ; i> (4-r_drawsurf.surfmip); + + light = lightright; + + for (b=blocksize-1; b>=0; b--) + { + pix = psource[b]; + prowdest[b] = BLEND_LM(pix, light); + if( pix == TRANSPARENT_COLOR ) + prowdest[b] = TRANSPARENT_COLOR; + //((unsigned char *)vid.colormap) + //[(light & 0xFF00) + pix]; + light += lightstep; + } + + psource += sourcetstep; + lightright += lightrightstep; + lightleft += lightleftstep; + prowdest += surfrowbytes; + } + + if (psource >= r_sourcemax) + psource -= r_stepback; + } +} + + /* ================ R_DrawSurfaceBlock8_mip0 @@ -590,14 +661,14 @@ void R_DrawSurfaceBlock8_mip0 (void) lightleftstep = (r_lightptr[0] - lightleft) >> 4; lightrightstep = (r_lightptr[1] - lightright) >> 4; - for (i=0 ; i> 4; light = lightright; - for (b=blocksize - 1; b>=0; b--) + for (b=15; b>=0; b--) { pix = psource[b]; prowdest[b] = BLEND_LM(pix, light); @@ -646,14 +717,14 @@ void R_DrawSurfaceBlock8_mip1 (void) lightleftstep = (r_lightptr[0] - lightleft) >> 3; lightrightstep = (r_lightptr[1] - lightright) >> 3; - for (i=0 ; i> 3; light = lightright; - for (b=blocksize-1; b>=0; b--) + for (b=7; b>=0; b--) { pix = psource[b]; prowdest[b] = BLEND_LM(pix, light); @@ -698,14 +769,14 @@ void R_DrawSurfaceBlock8_mip2 (void) lightleftstep = (r_lightptr[0] - lightleft) >> 2; lightrightstep = (r_lightptr[1] - lightright) >> 2; - for (i=0 ; i> 2; light = lightright; - for (b=blocksize-1; b>=0; b--) + for (b=3; b>=0; b--) { pix = psource[b]; prowdest[b] = BLEND_LM(pix, light);; @@ -750,14 +821,14 @@ void R_DrawSurfaceBlock8_mip3 (void) lightleftstep = (r_lightptr[0] - lightleft) >> 1; lightrightstep = (r_lightptr[1] - lightright) >> 1; - for (i=0 ; i> 1; light = lightright; - for (b=blocksize-1; b>=0; b--) + for (b=1; b>=0; b--) { pix = psource[b]; prowdest[b] = BLEND_LM(pix, light);; @@ -840,7 +911,7 @@ void D_FlushCaches( void ) qboolean newmap = !world || !Q_strcmp( tr.mapname, WORLDMODEL->name ); // if newmap, surfaces already freed - if( !newmap ) + if( !newmap && !tr.map_unload ) { for(c = sc_base ; c ; c = c->next ) { @@ -1141,13 +1212,13 @@ surfcache_t *D_CacheSurface (msurface_t *surface, int miplevel) { if( miplevel >= 1) { - surface->extents[0] = surface->info->lightextents[0] * gEngfuncs.Mod_SampleSizeForFace( r_drawsurf.surf ) * 2 ; - surface->texturemins[0] = -surface->info->lightextents[0] * gEngfuncs.Mod_SampleSizeForFace( r_drawsurf.surf ); + surface->extents[0] = surface->info->lightextents[0] * LM_SAMPLE_SIZE_AUTO( r_drawsurf.surf ) * 2 ; + surface->info->lightmapmins[0] = -surface->info->lightextents[0] * LM_SAMPLE_SIZE_AUTO( r_drawsurf.surf ); } else { - surface->extents[0] = surface->info->lightextents[0] * gEngfuncs.Mod_SampleSizeForFace( r_drawsurf.surf ) ; - surface->texturemins[0] = -surface->info->lightextents[0] * gEngfuncs.Mod_SampleSizeForFace( r_drawsurf.surf )/2; + surface->extents[0] = surface->info->lightextents[0] * LM_SAMPLE_SIZE_AUTO( r_drawsurf.surf ) ; + surface->info->lightmapmins[0] = -surface->info->lightextents[0] * LM_SAMPLE_SIZE_AUTO( r_drawsurf.surf )/2; } } /// todo: port this @@ -1194,8 +1265,10 @@ surfcache_t *D_CacheSurface (msurface_t *surface, int miplevel) // surfscale = 1.0 / (1<info->lightextents[0] >> miplevel; - //surface->extents[0] >> miplevel; + if( surface->flags & SURF_CONVEYOR ) + r_drawsurf.surfwidth = surface->extents[0] >> miplevel; + else + r_drawsurf.surfwidth = surface->info->lightextents[0] >> miplevel; r_drawsurf.rowbytes = r_drawsurf.surfwidth; r_drawsurf.surfheight = surface->info->lightextents[1] >> miplevel; //surface->extents[1] >> miplevel;