05 Nov 2017

This commit is contained in:
g-cont 2017-11-05 00:00:00 +03:00 committed by Alibek Omarov
parent 030f081591
commit 4dc689321e
10 changed files with 181 additions and 79 deletions

View File

@ -136,7 +136,8 @@ BRUSH MODELS
#define EXTRA_LUMPS 12 // count of the extra lumps
// texture flags
#define TEX_SPECIAL BIT( 0 ) // sky or slime, no lightmap or 256 subdivision
#define TEX_SPECIAL BIT( 0 ) // sky or slime, no lightmap or 256 subdivision
#define TEX_WORLD_LUXELS BIT( 1 ) // alternative lightmap matrix will be used (luxels per world units instead of luxels per texels)
// ambient sound types
enum

View File

@ -200,6 +200,10 @@ typedef struct mextrasurf_s
int mirrortexturenum; // gl texnum
float mirrormatrix[4][4];
short lightmapmins[2]; // lightmatrix
short lightextents[2];
float lmvecs[2][4];
struct mextrasurf_s *mirrorchain; // for gl_texsort drawing
struct mextrasurf_s *detailchain; // for detail textures drawing
struct msurface_s *lightmapchain; // lightmapped polys

View File

@ -438,7 +438,7 @@ void CL_AddLinksToPmove( frame_t *frame )
if(( state->owner != 0 ) && ( state->owner == cl.playernum + 1 ))
continue;
if(( model->hulls[1].firstclipnode || model->type == mod_studio ) && clgame.pmove->numvisent < MAX_PHYSENTS )
if(( model->hulls[1].lastclipnode || model->type == mod_studio ) && clgame.pmove->numvisent < MAX_PHYSENTS )
{
pe = &clgame.pmove->visents[clgame.pmove->numvisent];
CL_CopyEntityToPhysEnt( pe, state, true );
@ -456,7 +456,7 @@ void CL_AddLinksToPmove( frame_t *frame )
if( VectorIsNull( state->mins ) && VectorIsNull( state->maxs ))
continue;
if ( !model->hulls[1].firstclipnode && model->type != mod_studio )
if ( !model->hulls[1].lastclipnode && model->type != mod_studio )
continue;
if( state->solid == SOLID_NOT && state->skin < CONTENTS_EMPTY )

View File

@ -374,7 +374,9 @@ static void R_DecalVertsLight( float *v, msurface_t *surf, int vertCount )
{
float s, t;
mtexinfo_t *tex;
int j, sample_size;
mextrasurf_t *info = surf->info;
float sample_size;
int j;
sample_size = Mod_SampleSizeForFace( surf );
tex = surf->texinfo;
@ -382,14 +384,14 @@ static void R_DecalVertsLight( float *v, msurface_t *surf, int vertCount )
for( j = 0; j < vertCount; j++, v += VERTEXSIZE )
{
// lightmap texture coordinates
s = DotProduct( v, tex->vecs[0] ) + tex->vecs[0][3] - surf->texturemins[0];
s = DotProduct( v, info->lmvecs[0] ) + info->lmvecs[0][3] - info->lightmapmins[0];
s += surf->light_s * sample_size;
s += sample_size >> 1;
s += sample_size * 0.5;
s /= BLOCK_SIZE * sample_size; //fa->texinfo->texture->width;
t = DotProduct( v, tex->vecs[1] ) + tex->vecs[1][3] - surf->texturemins[1];
t = DotProduct( v, info->lmvecs[1] ) + info->lmvecs[1][3] - info->lightmapmins[1];
t += surf->light_t * sample_size;
t += sample_size >> 1;
t += sample_size * 0.5;
t /= BLOCK_SIZE * sample_size; //fa->texinfo->texture->height;
v[5] = s;

View File

@ -29,6 +29,7 @@ static rgbdata_t r_image; // generic pixelbuffer used for internal textures
// internal tables
static vec3_t r_luminanceTable[256]; // RGB to luminance
#define IsLightMap( tex ) (!Q_strncmp( (tex)->name, "*lightmap", 9 ) || !Q_strncmp( (tex)->name, "*dlight", 7 ))
/*
=================
R_GetTexture
@ -147,7 +148,7 @@ void GL_ApplyTextureParams( gltexture_t *tex )
}
else if( FBitSet( tex->flags, TF_NOMIPMAP ) || tex->numMips <= 1 )
{
if( FBitSet( tex->flags, TF_NEAREST ) || ( !Q_strncmp( tex->name, "*lightmap", 9 ) && gl_lightmap_nearest->value ))
if( FBitSet( tex->flags, TF_NEAREST ) || ( IsLightMap( tex ) && gl_lightmap_nearest->value ))
{
pglTexParameteri( tex->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
pglTexParameteri( tex->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
@ -262,7 +263,7 @@ static void GL_UpdateTextureParams( int iTexture )
if( GL_Support( GL_TEXTURE_LOD_BIAS ) && ( tex->numMips > 1 ) && !FBitSet( tex->flags, TF_DEPTHMAP ))
pglTexParameterf( tex->target, GL_TEXTURE_LOD_BIAS_EXT, gl_texture_lodbias->value );
if( !Q_strncmp( tex->name, "*lightmap", 9 ))
if( IsLightMap( tex ))
{
if( gl_lightmap_nearest->value )
{

View File

@ -228,7 +228,8 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
{
float front, back, frac, midf;
int i, map, side, size, s, t;
int sample_size;
float sample_size;
mextrasurf_t *info;
msurface_t *surf;
mtexinfo_t *tex;
color24 *lm;
@ -271,14 +272,15 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
for( i = 0; i < node->numsurfaces; i++, surf++ )
{
tex = surf->texinfo;
info = surf->info;
if( FBitSet( surf->flags, SURF_DRAWTILED ))
continue; // no lightmaps
s = DotProduct( mid, tex->vecs[0] ) + tex->vecs[0][3] - surf->texturemins[0];
t = DotProduct( mid, tex->vecs[1] ) + tex->vecs[1][3] - surf->texturemins[1];
s = DotProduct( mid, info->lmvecs[0] ) + info->lmvecs[0][3] - info->lightmapmins[0];
t = DotProduct( mid, info->lmvecs[1] ) + info->lmvecs[1][3] - info->lightmapmins[1];
if(( s < 0 || s > surf->extents[0] ) || ( t < 0 || t > surf->extents[1] ))
if(( s < 0 || s > info->lightextents[0] ) || ( t < 0 || t > info->lightextents[1] ))
continue;
cv->r = cv->g = cv->b = cv->a = 0;
@ -290,8 +292,8 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
s /= sample_size;
t /= sample_size;
lm = surf->samples + (t * ((surf->extents[0] / sample_size) + 1) + s);
size = ((surf->extents[0] / sample_size) + 1) * ((surf->extents[1] / sample_size) + 1);
lm = surf->samples + (t * ((info->lightextents[0] / (int)sample_size) + 1) + s);
size = ((info->lightextents[0] / (int)sample_size) + 1) * ((info->lightextents[1] / sample_size) + 1);
g_trace_fraction = midf;
for( map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++ )

View File

@ -81,13 +81,14 @@ static void BoundPoly( int numverts, float *verts, vec3_t mins, vec3_t maxs )
static void SubdividePolygon_r( msurface_t *warpface, int numverts, float *verts )
{
int i, j, k, f, b;
int sample_size;
vec3_t mins, maxs;
float m, frac, s, t, *v, vertsDiv;
vec3_t front[SUBDIVIDE_SIZE], back[SUBDIVIDE_SIZE], total;
float dist[SUBDIVIDE_SIZE], total_s, total_t, total_ls, total_lt;
glpoly_t *poly;
int i, j, k, f, b;
float sample_size;
vec3_t mins, maxs;
float m, frac, s, t, *v, vertsDiv;
vec3_t front[SUBDIVIDE_SIZE], back[SUBDIVIDE_SIZE], total;
float dist[SUBDIVIDE_SIZE], total_s, total_t, total_ls, total_lt;
mextrasurf_t *warpinfo = warpface->info;
glpoly_t *poly;
if( numverts > ( SUBDIVIDE_SIZE - 4 ))
Host_Error( "Mod_SubdividePolygon: too many vertexes on face ( %i )\n", numverts );
@ -185,16 +186,16 @@ static void SubdividePolygon_r( msurface_t *warpface, int numverts, float *verts
if( !( warpface->flags & SURF_DRAWTURB ))
{
// lightmap texture coordinates
s = DotProduct( verts, warpface->texinfo->vecs[0] ) + warpface->texinfo->vecs[0][3];
s -= warpface->texturemins[0];
s = DotProduct( verts, warpinfo->lmvecs[0] ) + warpinfo->lmvecs[0][3];
s -= warpinfo->lightmapmins[0];
s += warpface->light_s * sample_size;
s += sample_size >> 1;
s += sample_size * 0.5;
s /= BLOCK_SIZE * sample_size; //fa->texinfo->texture->width;
t = DotProduct( verts, warpface->texinfo->vecs[1] ) + warpface->texinfo->vecs[1][3];
t -= warpface->texturemins[1];
t = DotProduct( verts, warpinfo->lmvecs[1] ) + warpinfo->lmvecs[1][3];
t -= warpinfo->lightmapmins[1];
t += warpface->light_t * sample_size;
t += sample_size >> 1;
t += sample_size * 0.5;
t /= BLOCK_SIZE * sample_size; //fa->texinfo->texture->height;
poly->verts[i+1][5] = s;
@ -290,8 +291,10 @@ GL_BuildPolygonFromSurface
void GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa )
{
int i, lindex, lnumverts;
int vertpage, sample_size;
medge_t *pedges, *r_pedge;
mextrasurf_t *info = fa->info;
float sample_size;
int vertpage;
texture_t *tex;
gltexture_t *glt;
float *vec;
@ -355,16 +358,16 @@ void GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa )
poly->verts[i][4] = t;
// lightmap texture coordinates
s = DotProduct( vec, fa->texinfo->vecs[0] ) + fa->texinfo->vecs[0][3];
s -= fa->texturemins[0];
s = DotProduct( vec, info->lmvecs[0] ) + info->lmvecs[0][3];
s -= info->lightmapmins[0];
s += fa->light_s * sample_size;
s += sample_size >> 1;
s += sample_size / 2.0;
s /= BLOCK_SIZE * sample_size; //fa->texinfo->texture->width;
t = DotProduct( vec, fa->texinfo->vecs[1] ) + fa->texinfo->vecs[1][3];
t -= fa->texturemins[1];
t = DotProduct( vec, info->lmvecs[1] ) + info->lmvecs[1][3];
t -= info->lightmapmins[1];
t += fa->light_t * sample_size;
t += sample_size >> 1;
t += sample_size / 2.0;
t /= BLOCK_SIZE * sample_size; //fa->texinfo->texture->height;
poly->verts[i][5] = s;
@ -483,7 +486,9 @@ void R_AddDynamicLights( msurface_t *surf )
int lnum, s, t, sd, td, smax, tmax;
float sl, tl, sacc, tacc;
vec3_t impact, origin_l;
int sample_size;
mextrasurf_t *info = surf->info;
int sample_frac = 1.0;
float sample_size;
mtexinfo_t *tex;
dlight_t *dl;
uint *bl;
@ -492,10 +497,17 @@ void R_AddDynamicLights( msurface_t *surf )
if( !R_CountSurfaceDlights( surf )) return;
sample_size = Mod_SampleSizeForFace( surf );
smax = (surf->extents[0] / sample_size) + 1;
tmax = (surf->extents[1] / sample_size) + 1;
smax = (info->lightextents[0] / sample_size) + 1;
tmax = (info->lightextents[1] / sample_size) + 1;
tex = surf->texinfo;
if( FBitSet( tex->flags, TEX_WORLD_LUXELS ))
{
if( surf->texinfo->faceinfo )
sample_frac = surf->texinfo->faceinfo->texture_step;
else sample_frac = LM_SAMPLE_SIZE;
}
for( lnum = 0; lnum < MAX_DLIGHTS; lnum++ )
{
if( !FBitSet( surf->dlightbits, BIT( lnum )))
@ -526,18 +538,18 @@ void R_AddDynamicLights( msurface_t *surf )
}
else VectorMA( origin_l, -dist, surf->plane->normal, impact );
sl = DotProduct( impact, tex->vecs[0] ) + tex->vecs[0][3] - surf->texturemins[0];
tl = DotProduct( impact, tex->vecs[1] ) + tex->vecs[1][3] - surf->texturemins[1];
sl = DotProduct( impact, info->lmvecs[0] ) + info->lmvecs[0][3] - info->lightmapmins[0];
tl = DotProduct( impact, info->lmvecs[1] ) + info->lmvecs[1][3] - info->lightmapmins[1];
bl = r_blocklights;
for( t = 0, tacc = 0; t < tmax; t++, tacc += sample_size )
{
td = tl - tacc;
td = (tl - tacc) * sample_frac;
if( td < 0 ) td = -td;
for( s = 0, sacc = 0; s < smax; s++, sacc += sample_size, bl += 3 )
{
sd = sl - sacc;
sd = (sl - sacc) * sample_frac;
if( sd < 0 ) sd = -sd;
if( sd > td ) dist = sd + (td >> 1);
@ -671,15 +683,16 @@ format in r_blocklights
*/
static void R_BuildLightMap( msurface_t *surf, byte *dest, int stride, qboolean dynamic )
{
int smax, tmax;
uint *bl, scale;
int i, map, size, s, t;
int sample_size;
color24 *lm;
int smax, tmax;
uint *bl, scale;
int i, map, size, s, t;
int sample_size;
mextrasurf_t *info = surf->info;
color24 *lm;
sample_size = Mod_SampleSizeForFace( surf );
smax = ( surf->extents[0] / sample_size ) + 1;
tmax = ( surf->extents[1] / sample_size ) + 1;
smax = ( info->lightextents[0] / sample_size ) + 1;
tmax = ( info->lightextents[1] / sample_size ) + 1;
size = smax * tmax;
lm = surf->samples;
@ -894,13 +907,14 @@ void R_BlendLightmaps( void )
for( surf = gl_lms.dynamic_surfaces; surf != NULL; surf = surf->info->lightmapchain )
{
int smax, tmax;
int sample_size;
byte *base;
int smax, tmax;
int sample_size;
mextrasurf_t *info = surf->info;
byte *base;
sample_size = Mod_SampleSizeForFace( surf );
smax = ( surf->extents[0] / sample_size ) + 1;
tmax = ( surf->extents[1] / sample_size ) + 1;
smax = ( info->lightextents[0] / sample_size ) + 1;
tmax = ( info->lightextents[1] / sample_size ) + 1;
if( LM_AllocBlock( smax, tmax, &surf->info->dlight_s, &surf->info->dlight_t ))
{
@ -1195,13 +1209,14 @@ dynamic:
{
if(( fa->styles[maps] >= 32 || fa->styles[maps] == 0 || fa->styles[maps] == 20 ) && ( fa->dlightframe != tr.framecount ))
{
byte temp[132*132*4];
int sample_size;
int smax, tmax;
byte temp[132*132*4];
mextrasurf_t *info = fa->info;
int sample_size;
int smax, tmax;
sample_size = Mod_SampleSizeForFace( fa );
smax = ( fa->extents[0] / sample_size ) + 1;
tmax = ( fa->extents[1] / sample_size ) + 1;
smax = ( info->lightextents[0] / sample_size ) + 1;
tmax = ( info->lightextents[1] / sample_size ) + 1;
R_BuildLightMap( fa, temp, smax * 4, true );
R_SetCacheState( fa );
@ -2097,17 +2112,18 @@ GL_CreateSurfaceLightmap
*/
void GL_CreateSurfaceLightmap( msurface_t *surf )
{
int smax, tmax;
int sample_size;
byte *base;
int smax, tmax;
int sample_size;
mextrasurf_t *info = surf->info;
byte *base;
if( !cl.worldmodel->lightdata ) return;
if( surf->flags & SURF_DRAWTILED )
return;
sample_size = Mod_SampleSizeForFace( surf );
smax = ( surf->extents[0] / sample_size ) + 1;
tmax = ( surf->extents[1] / sample_size ) + 1;
smax = ( info->lightextents[0] / sample_size ) + 1;
tmax = ( info->lightextents[1] / sample_size ) + 1;
if( !LM_AllocBlock( smax, tmax, &surf->light_s, &surf->light_t ))
{

View File

@ -499,10 +499,54 @@ return the current lightmap resolution per face
*/
int Mod_SampleSizeForFace( msurface_t *surf )
{
if( !surf || !surf->texinfo || !surf->texinfo->faceinfo )
if( !surf || !surf->texinfo )
return LM_SAMPLE_SIZE;
return surf->texinfo->faceinfo->texture_step;
if( FBitSet( surf->texinfo->flags, TEX_WORLD_LUXELS ))
return 1;
if( surf->texinfo->faceinfo )
return surf->texinfo->faceinfo->texture_step;
return LM_SAMPLE_SIZE;
}
/*
==================
Mod_SampleSizeForFace
return the current lightmap resolution per face
==================
*/
static void Mod_LightMatrixFromTexMatrix( const mtexinfo_t *tx, float lmvecs[2][4] )
{
float lmscale = LM_SAMPLE_SIZE;
int i, j;
if( tx->faceinfo )
lmscale = tx->faceinfo->texture_step;
// copy texmatrix into lightmap matrix fisrt
for( i = 0; i < 2; i++ )
{
for( j = 0; j < 4; j++ )
{
lmvecs[i][j] = tx->vecs[i][j];
}
}
if( !FBitSet( tx->flags, TEX_WORLD_LUXELS ))
return; // just use texmatrix
VectorNormalize( lmvecs[0] );
VectorNormalize( lmvecs[1] );
// put the lighting origin at center the poly
VectorScale( lmvecs[0], (1.0 / lmscale), lmvecs[0] );
VectorScale( lmvecs[1], -(1.0 / lmscale), lmvecs[1] );
lmvecs[0][3] = lmscale * 0.5;
lmvecs[1][3] = -lmscale * 0.5;
}
/*
@ -1275,16 +1319,21 @@ Fills in surf->texturemins[] and surf->extents[]
static void Mod_CalcSurfaceExtents( msurface_t *surf )
{
float mins[2], maxs[2], val;
float lmmins[2], lmmaxs[2];
int bmins[2], bmaxs[2];
int i, j, e, sample_size;
mextrasurf_t *info = surf->info;
int facenum = surf - loadmodel->surfaces;
mtexinfo_t *tex;
mvertex_t *v;
sample_size = Mod_SampleSizeForFace( surf );
tex = surf->texinfo;
mins[0] = mins[1] = 999999;
maxs[0] = maxs[1] = -999999;
Mod_LightMatrixFromTexMatrix( tex, info->lmvecs );
mins[0] = lmmins[0] = mins[1] = lmmins[1] = 999999;
maxs[0] = lmmaxs[0] = maxs[1] = lmmaxs[1] =-999999;
for( i = 0; i < surf->numedges; i++ )
{
@ -1299,8 +1348,15 @@ static void Mod_CalcSurfaceExtents( msurface_t *surf )
for( j = 0; j < 2; j++ )
{
val = DotProduct( v->position, surf->texinfo->vecs[j] ) + surf->texinfo->vecs[j][3];
if( val < mins[j] ) mins[j] = val;
if( val > maxs[j] ) maxs[j] = val;
mins[j] = Q_min( val, mins[j] );
maxs[j] = Q_max( val, maxs[j] );
}
for( j = 0; j < 2; j++ )
{
val = DotProduct( v->position, info->lmvecs[j] ) + info->lmvecs[j][3];
lmmins[j] = Q_min( val, lmmins[j] );
lmmaxs[j] = Q_max( val, lmmaxs[j] );
}
}
@ -1312,6 +1368,21 @@ static void Mod_CalcSurfaceExtents( msurface_t *surf )
surf->texturemins[i] = bmins[i] * sample_size;
surf->extents[i] = (bmaxs[i] - bmins[i]) * sample_size;
if( FBitSet( tex->flags, TEX_WORLD_LUXELS ))
{
lmmins[i] = floor( lmmins[i] );
lmmaxs[i] = ceil( lmmaxs[i] );
info->lightmapmins[i] = lmmins[i];
info->lightextents[i] = (lmmaxs[i] - lmmins[i]);
}
else
{
// just copy texturemins
info->lightmapmins[i] = surf->texturemins[i];
info->lightextents[i] = surf->extents[i];
}
if( !FBitSet( tex->flags, TEX_SPECIAL ) && surf->extents[i] > 4096 )
MsgDev( D_ERROR, "Bad surface extents %i\n", surf->extents[i] );
}
@ -2072,6 +2143,9 @@ static void Mod_SetupHull( model_t *mod, byte *mempool, int headnode, int hullnu
if(( headnode == -1 ) || ( hullnum != 1 && headnode == 0 ))
return; // hull missed
if( headnode >= world.numclipnodes )
return; // ZHLT weird empty hulls
switch( hullnum )
{
case 1:

View File

@ -223,7 +223,7 @@ qboolean PM_RecursiveHullCheck( hull_t *hull, int num, float p1f, float p2f, vec
if( hull->firstclipnode >= hull->lastclipnode )
{
// studiotrace issues
// empty hull?
trace->allsolid = false;
trace->inopen = true;
return true;

View File

@ -1377,7 +1377,8 @@ static qboolean SV_RecursiveLightPoint( model_t *model, mnode_t *node, const vec
mtexinfo_t *tex;
float front, back, scale, frac;
int i, map, size, s, t;
int sample_size;
float sample_size;
mextrasurf_t *info;
color24 *lm;
vec3_t mid;
@ -1419,14 +1420,15 @@ static qboolean SV_RecursiveLightPoint( model_t *model, mnode_t *node, const vec
for( i = 0; i < node->numsurfaces; i++, surf++ )
{
tex = surf->texinfo;
info = surf->info;
if( surf->flags & SURF_DRAWTILED )
continue; // no lightmaps
s = DotProduct( mid, tex->vecs[0] ) + tex->vecs[0][3] - surf->texturemins[0];
t = DotProduct( mid, tex->vecs[1] ) + tex->vecs[1][3] - surf->texturemins[1];
s = DotProduct( mid, info->lmvecs[0] ) + info->lmvecs[0][3] - info->lightmapmins[0];
t = DotProduct( mid, info->lmvecs[1] ) + info->lmvecs[1][3] - info->lightmapmins[1];
if(( s < 0.0f || s > surf->extents[0] ) || ( t < 0.0f || t > surf->extents[1] ))
if(( s < 0 || s > info->lightextents[0] ) || ( t < 0 || t > info->lightextents[1] ))
continue;
if( !surf->samples )
@ -1438,8 +1440,8 @@ static qboolean SV_RecursiveLightPoint( model_t *model, mnode_t *node, const vec
VectorClear( sv_pointColor );
lm = surf->samples + (t * ((surf->extents[0] / sample_size) + 1) + s);
size = ((surf->extents[0] / sample_size) + 1) * ((surf->extents[1] / sample_size) + 1);
lm = surf->samples + (t * ((info->lightextents[0] / (int)sample_size) + 1) + s);
size = ((info->lightextents[0] / (int)sample_size) + 1) * ((info->lightextents[1] / sample_size) + 1);
for( map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++ )
{