mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-05 19:45:05 +08:00
Compare commits
12 Commits
continuous
...
continuous
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b2273b1bce | ||
|
|
950d210ec5 | ||
|
|
55c1bddac5 | ||
|
|
ac50c762d7 | ||
|
|
5c2ab150b3 | ||
|
|
0870536405 | ||
|
|
b47ede477a | ||
|
|
eef5cc17b3 | ||
|
|
ad2191333d | ||
|
|
a85cac497d | ||
|
|
e0c69d7df5 | ||
|
|
ff3d91ceb4 |
@@ -14,6 +14,9 @@
|
||||
****/
|
||||
#ifndef CONST_H
|
||||
#define CONST_H
|
||||
|
||||
#include <stddef.h> // ptrdiff_t
|
||||
|
||||
//
|
||||
// Constants shared by the engine and dlls
|
||||
// This header file included by engine files and DLL files.
|
||||
@@ -721,7 +724,7 @@ enum
|
||||
};
|
||||
|
||||
typedef int func_t;
|
||||
typedef int string_t;
|
||||
typedef ptrdiff_t string_t;
|
||||
|
||||
typedef unsigned short word;
|
||||
|
||||
|
||||
@@ -56,6 +56,8 @@ color24 gTracerColors[] =
|
||||
};
|
||||
*/
|
||||
|
||||
#define TRACER_COLORINDEX_DEFAULT 4
|
||||
|
||||
// Temporary entity array
|
||||
#define TENTPRIORITY_LOW 0
|
||||
#define TENTPRIORITY_HIGH 1
|
||||
|
||||
@@ -250,7 +250,7 @@ static particle_t *R_AllocTracer( const vec3_t org, const vec3_t vel, float life
|
||||
VectorCopy( vel, p->vel );
|
||||
p->die = cl.time + life;
|
||||
p->ramp = tracerlength.value;
|
||||
p->color = 4; // select custom color
|
||||
p->color = TRACER_COLORINDEX_DEFAULT; // select custom color
|
||||
p->packedColor = 255; // alpha
|
||||
|
||||
return p;
|
||||
|
||||
@@ -524,9 +524,6 @@ static void SND_Spatialize( channel_t *ch )
|
||||
dist = VectorNormalizeLength( source_vec );
|
||||
dot = DotProduct( s_listener.right, source_vec );
|
||||
|
||||
// don't pan sounds with no attenuation
|
||||
if( ch->dist_mult <= 0.0f ) dot = 0.0f;
|
||||
|
||||
// fill out channel volumes for single location
|
||||
S_SpatializeChannel( &ch->leftvol, &ch->rightvol, ch->master_vol, gain, dot, dist * ch->dist_mult );
|
||||
|
||||
|
||||
@@ -126,14 +126,20 @@ dll_user_t *FS_FindLibrary( const char *dllname, qboolean directpath )
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
static void COM_GenerateCommonLibraryName( const char *name, const char *ext, char *out, size_t size )
|
||||
static void COM_GenerateCommonLibraryName( const char *name, const char *ext, const char *suffix, char *out, size_t size )
|
||||
{
|
||||
#if ( XASH_WIN32 || XASH_LINUX || XASH_APPLE ) && XASH_X86
|
||||
Q_snprintf( out, size, "%s.%s", name, ext );
|
||||
if( suffix )
|
||||
Q_snprintf( out, size, "%s_%s.%s", name, suffix, ext );
|
||||
else Q_snprintf( out, size, "%s.%s", name, ext );
|
||||
#elif ( XASH_WIN32 || XASH_LINUX || XASH_APPLE )
|
||||
Q_snprintf( out, size, "%s_%s.%s", name, Q_buildarch(), ext );
|
||||
if( suffix )
|
||||
Q_snprintf( out, size, "%s_%s_%s.%s", name, Q_buildarch(), suffix, ext );
|
||||
else Q_snprintf( out, size, "%s_%s.%s", name, Q_buildarch(), ext );
|
||||
#else
|
||||
Q_snprintf( out, size, "%s_%s_%s.%s", name, Q_buildos(), Q_buildarch(), ext );
|
||||
if( suffix )
|
||||
Q_snprintf( out, size, "%s_%s_%s_%s.%s", name, Q_buildos(), Q_buildarch(), suffix, ext );
|
||||
else Q_snprintf( out, size, "%s_%s_%s.%s", name, Q_buildos(), Q_buildarch(), ext );
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -154,7 +160,7 @@ static void COM_GenerateClientLibraryPath( const char *name, char *out, size_t s
|
||||
// we don't have any library prefixes, so we can safely append dll_path here
|
||||
Q_snprintf( dllpath, sizeof( dllpath ), "%s/%s", GI->dll_path, name );
|
||||
|
||||
COM_GenerateCommonLibraryName( dllpath, OS_LIB_EXT, out, size );
|
||||
COM_GenerateCommonLibraryName( dllpath, OS_LIB_EXT, NULL, out, size );
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -211,7 +217,13 @@ static void COM_GenerateServerLibraryPath( char *out, size_t size )
|
||||
COM_StripExtension( dllpath );
|
||||
COM_StripIntelSuffix( dllpath );
|
||||
|
||||
COM_GenerateCommonLibraryName( dllpath, ext, out, size );
|
||||
#if XASH_ARCH_USES_ONLY_ABI2
|
||||
COM_GenerateCommonLibraryName( dllpath, ext, NULL, out, size );
|
||||
#elif XASH_64BIT
|
||||
COM_GenerateCommonLibraryName( dllpath, ext, "st64", out, size );
|
||||
#else
|
||||
COM_GenerateCommonLibraryName( dllpath, ext, NULL, out, size );
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -420,7 +420,8 @@ void NET_InitMasters( void )
|
||||
// keep main master always there
|
||||
NET_AddMaster( MASTERSERVER_ADR, false );
|
||||
NET_AddMaster( "aaaa.mentality.rip:27010", false ); // IPv6-only
|
||||
NET_AddMaster( "mentality.rip:27011", false );
|
||||
NET_AddMaster( "mentality.rip:27011", false ); // testing server, might be offline
|
||||
NET_AddMaster( "aaaa.mentality.rip:27011", false ); // IPv6-only, testing server, might be offline
|
||||
|
||||
NET_LoadMasters( );
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ typedef struct enginefuncs_s
|
||||
void (*pfnAngleVectors)( const float *rgflVector, float *forward, float *right, float *up );
|
||||
edict_t* (*pfnCreateEntity)( void );
|
||||
void (*pfnRemoveEntity)( edict_t* e );
|
||||
edict_t* (*pfnCreateNamedEntity)( int className );
|
||||
edict_t* (*pfnCreateNamedEntity)( string_t className );
|
||||
void (*pfnMakeStatic)( edict_t *ent );
|
||||
int (*pfnEntIsOnFloor)( edict_t *e );
|
||||
int (*pfnDropToFloor)( edict_t* e );
|
||||
@@ -168,8 +168,8 @@ typedef struct enginefuncs_s
|
||||
void* (*pfnPvAllocEntPrivateData)( edict_t *pEdict, long cb );
|
||||
void* (*pfnPvEntPrivateData)( edict_t *pEdict );
|
||||
void (*pfnFreeEntPrivateData)( edict_t *pEdict );
|
||||
const char *(*pfnSzFromIndex)( int iString );
|
||||
int (*pfnAllocString)( const char *szValue );
|
||||
const char *(*pfnSzFromIndex)( string_t iString );
|
||||
string_t (*pfnAllocString)( const char *szValue );
|
||||
struct entvars_s *(*pfnGetVarsOfEnt)( edict_t *pEdict );
|
||||
edict_t* (*pfnPEntityOfEntOffset)( int iEntOffset );
|
||||
int (*pfnEntOffsetOfPEntity)( const edict_t *pEdict );
|
||||
|
||||
@@ -85,8 +85,8 @@ typedef struct entvars_s
|
||||
int modelindex;
|
||||
|
||||
string_t model;
|
||||
int viewmodel; // player's viewmodel
|
||||
int weaponmodel; // what other players see
|
||||
string_t viewmodel; // player's viewmodel
|
||||
string_t weaponmodel; // what other players see
|
||||
|
||||
vec3_t absmin; // BB max translated to world coord
|
||||
vec3_t absmax; // BB max translated to world coord
|
||||
@@ -144,7 +144,7 @@ typedef struct entvars_s
|
||||
int flags;
|
||||
|
||||
int colormap; // lowbyte topcolor, highbyte bottomcolor
|
||||
int team;
|
||||
string_t team;
|
||||
|
||||
float max_health;
|
||||
float teleport_time;
|
||||
|
||||
@@ -3000,25 +3000,6 @@ static void *GAME_EXPORT pfnPvEntPrivateData( edict_t *pEdict )
|
||||
}
|
||||
|
||||
|
||||
#ifdef XASH_64BIT
|
||||
static struct str64_s
|
||||
{
|
||||
size_t maxstringarray;
|
||||
qboolean allowdup;
|
||||
char *staticstringarray;
|
||||
char *pstringarray;
|
||||
char *pstringarraystatic;
|
||||
char *pstringbase;
|
||||
char *poldstringbase;
|
||||
char *plast;
|
||||
qboolean dynamic;
|
||||
size_t maxalloc;
|
||||
size_t numdups;
|
||||
size_t numoverflows;
|
||||
size_t totalalloc;
|
||||
} str64;
|
||||
#endif
|
||||
|
||||
/*
|
||||
==================
|
||||
SV_EmptyStringPool
|
||||
@@ -3028,17 +3009,7 @@ Free strings on server stop. Reset string pointer on 64 bits
|
||||
*/
|
||||
void SV_EmptyStringPool( void )
|
||||
{
|
||||
#ifdef XASH_64BIT
|
||||
if( str64.dynamic ) // switch only after array fill (more space for multiplayer games)
|
||||
str64.pstringbase = str64.pstringarray;
|
||||
else
|
||||
{
|
||||
str64.pstringbase = str64.poldstringbase = str64.pstringarraystatic;
|
||||
str64.plast = str64.pstringbase + 1;
|
||||
}
|
||||
#else
|
||||
Mem_EmptyPool( svgame.stringspool );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3052,23 +3023,8 @@ this helps not to lose strings that belongs to static game part
|
||||
*/
|
||||
void SV_SetStringArrayMode( qboolean dynamic )
|
||||
{
|
||||
#ifdef XASH_64BIT
|
||||
Con_Reportf( "%s(%d) %d\n", __func__, dynamic, str64.dynamic );
|
||||
|
||||
if( dynamic == str64.dynamic )
|
||||
return;
|
||||
|
||||
str64.dynamic = dynamic;
|
||||
|
||||
SV_EmptyStringPool();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if XASH_AMD64 && XASH_LINUX && !XASH_ANDROID
|
||||
#define USE_MMAP
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
==================
|
||||
SV_AllocStringPool
|
||||
@@ -3081,104 +3037,13 @@ this case need patched game dll with MAKE_STRING checking ptrdiff size
|
||||
*/
|
||||
static void SV_AllocStringPool( void )
|
||||
{
|
||||
#ifdef XASH_64BIT
|
||||
void *ptr = NULL;
|
||||
string lenstr;
|
||||
|
||||
Con_Reportf( "%s()\n", __func__ );
|
||||
if( Sys_GetParmFromCmdLine( "-str64alloc", lenstr ) )
|
||||
{
|
||||
str64.maxstringarray = Q_atoi( lenstr );
|
||||
if( str64.maxstringarray < 1024 || str64.maxstringarray >= INT_MAX )
|
||||
str64.maxstringarray = 65536;
|
||||
}
|
||||
else str64.maxstringarray = 65536;
|
||||
if( Sys_CheckParm( "-str64dup" ) )
|
||||
str64.allowdup = true;
|
||||
|
||||
#ifdef USE_MMAP
|
||||
{
|
||||
uint flags;
|
||||
size_t pagesize = sysconf( _SC_PAGESIZE );
|
||||
int arrlen = (str64.maxstringarray * 2) & ~(pagesize - 1);
|
||||
void *base = svgame.dllFuncs.pfnGameInit;
|
||||
void *start = svgame.hInstance - arrlen;
|
||||
|
||||
#if defined(MAP_ANON)
|
||||
flags = MAP_ANON | MAP_PRIVATE;
|
||||
#elif defined(MAP_ANONYMOUS)
|
||||
flags = MAP_ANONYMOUS | MAP_PRIVATE;
|
||||
#endif
|
||||
|
||||
while( start - base > INT_MIN )
|
||||
{
|
||||
void *mapptr = mmap((void*)((unsigned long)start & ~(pagesize - 1)), arrlen, PROT_READ | PROT_WRITE, flags, 0, 0 );
|
||||
if( mapptr && mapptr != (void*)-1 && mapptr - base > INT_MIN && mapptr - base < INT_MAX )
|
||||
{
|
||||
ptr = mapptr;
|
||||
break;
|
||||
}
|
||||
if( mapptr ) munmap( mapptr, arrlen );
|
||||
start -= arrlen;
|
||||
}
|
||||
|
||||
if( !ptr )
|
||||
{
|
||||
start = base;
|
||||
while( start - base < INT_MAX )
|
||||
{
|
||||
void *mapptr = mmap((void*)((unsigned long)start & ~(pagesize - 1)), arrlen, PROT_READ | PROT_WRITE, flags, 0, 0 );
|
||||
if( mapptr && mapptr != (void*)-1 && mapptr - base > INT_MIN && mapptr - base < INT_MAX )
|
||||
{
|
||||
ptr = mapptr;
|
||||
break;
|
||||
}
|
||||
if( mapptr ) munmap( mapptr, arrlen );
|
||||
start += arrlen;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( ptr )
|
||||
{
|
||||
Con_Reportf( "%s: Allocated string array near the server library: %p %p\n", __func__, base, ptr );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Reportf( "%s: Failed to allocate string array near the server library!\n", __func__ );
|
||||
ptr = str64.staticstringarray = Mem_Calloc( host.mempool, str64.maxstringarray * 2 );
|
||||
}
|
||||
}
|
||||
#else
|
||||
ptr = str64.staticstringarray = Mem_Calloc( host.mempool, str64.maxstringarray * 2 );
|
||||
#endif
|
||||
|
||||
str64.pstringarray = ptr;
|
||||
str64.pstringarraystatic = (byte*)ptr + str64.maxstringarray;
|
||||
str64.pstringbase = str64.poldstringbase = ptr;
|
||||
str64.plast = (byte*)ptr + 1;
|
||||
svgame.globals->pStringBase = ptr;
|
||||
#else
|
||||
svgame.stringspool = Mem_AllocPool( "Server Strings" );
|
||||
svgame.globals->pStringBase = "";
|
||||
#endif
|
||||
}
|
||||
|
||||
static void SV_FreeStringPool( void )
|
||||
{
|
||||
#ifdef XASH_64BIT
|
||||
Con_Reportf( "%s()\n", __func__ );
|
||||
|
||||
#ifdef USE_MMAP
|
||||
if( str64.pstringarray != str64.staticstringarray )
|
||||
munmap( str64.pstringarray, (str64.maxstringarray * 2) & ~(sysconf( _SC_PAGESIZE ) - 1) );
|
||||
else
|
||||
#endif
|
||||
Mem_Free( str64.staticstringarray );
|
||||
#else
|
||||
Mem_FreePool( &svgame.stringspool );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3249,9 +3114,6 @@ string_t GAME_EXPORT SV_AllocString( const char *szValue )
|
||||
{
|
||||
char *newString = NULL;
|
||||
uint len;
|
||||
#ifdef XASH_64BIT
|
||||
int cmp;
|
||||
#endif
|
||||
|
||||
if( svgame.physFuncs.pfnAllocString != NULL )
|
||||
{
|
||||
@@ -3267,67 +3129,16 @@ string_t GAME_EXPORT SV_AllocString( const char *szValue )
|
||||
return i;
|
||||
}
|
||||
|
||||
#ifdef XASH_64BIT
|
||||
cmp = 1;
|
||||
|
||||
if( !str64.allowdup )
|
||||
{
|
||||
for( newString = str64.poldstringbase + 1;
|
||||
newString < str64.plast && ( cmp = Q_strcmp( newString, szValue ) );
|
||||
newString += Q_strlen( newString ) + 1 );
|
||||
}
|
||||
|
||||
if( cmp )
|
||||
{
|
||||
uint len = SV_ProcessString( NULL, szValue );
|
||||
|
||||
if( str64.plast - str64.poldstringbase + len + 1 > str64.maxstringarray )
|
||||
{
|
||||
str64.plast = str64.pstringbase + 1;
|
||||
str64.poldstringbase = str64.pstringbase;
|
||||
str64.numoverflows++;
|
||||
}
|
||||
|
||||
//MsgDev( D_NOTE, "SV_AllocString: %ld %s\n", str64.plast - svgame.globals->pStringBase, szValue );
|
||||
SV_ProcessString( str64.plast, szValue );
|
||||
str64.totalalloc += len;
|
||||
|
||||
newString = str64.plast;
|
||||
str64.plast += len;
|
||||
}
|
||||
else
|
||||
{
|
||||
str64.numdups++;
|
||||
//MsgDev( D_NOTE, "SV_AllocString: dup %ld %s\n", newString - svgame.globals->pStringBase, szValue );
|
||||
}
|
||||
|
||||
if( newString - str64.pstringarray > str64.maxalloc )
|
||||
str64.maxalloc = newString - str64.pstringarray;
|
||||
|
||||
return newString - svgame.globals->pStringBase;
|
||||
#else
|
||||
len = SV_ProcessString( NULL, szValue );
|
||||
newString = Mem_Malloc( svgame.stringspool, len );
|
||||
SV_ProcessString( newString, szValue );
|
||||
|
||||
return newString - svgame.globals->pStringBase;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SV_PrintStr64Stats_f( void )
|
||||
{
|
||||
#ifdef XASH_64BIT
|
||||
Con_Printf( "====================\n" );
|
||||
Con_Printf( "64 bit string pool statistics\n" );
|
||||
Con_Printf( "====================\n" );
|
||||
Con_Printf( "string array size: %lu\n", str64.maxstringarray );
|
||||
Con_Printf( "total alloc %lu\n", str64.totalalloc );
|
||||
Con_Printf( "maximum array usage: %lu\n", str64.maxalloc );
|
||||
Con_Printf( "overflow counter: %lu\n", str64.numoverflows );
|
||||
Con_Printf( "dup string counter: %lu\n", str64.numdups );
|
||||
#else
|
||||
Con_Printf( "Not implemented\n" );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3341,17 +3152,8 @@ string_t SV_MakeString( const char *szValue )
|
||||
{
|
||||
if( svgame.physFuncs.pfnMakeString != NULL )
|
||||
return svgame.physFuncs.pfnMakeString( szValue );
|
||||
#ifdef XASH_64BIT
|
||||
{
|
||||
long long ptrdiff = szValue - svgame.globals->pStringBase;
|
||||
if( ptrdiff > INT_MAX || ptrdiff < INT_MIN )
|
||||
return SV_AllocString(szValue);
|
||||
else
|
||||
return (int)ptrdiff;
|
||||
}
|
||||
#else
|
||||
|
||||
return szValue - svgame.globals->pStringBase;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -445,6 +445,9 @@ void R_GenerateVBO( void );
|
||||
void R_ClearVBO( void );
|
||||
void R_AddDecalVBO( decal_t *pdecal, msurface_t *surf );
|
||||
void R_LightmapCoord( const vec3_t v, const msurface_t *surf, const float sample_size, vec2_t coords );
|
||||
qboolean R_HasGeneratedVBO( void );
|
||||
void R_EnableVBO( qboolean enable );
|
||||
qboolean R_HasEnabledVBO( void );
|
||||
|
||||
//
|
||||
// gl_rpart.c
|
||||
|
||||
@@ -742,10 +742,8 @@ static void R_RenderInfo_f( void )
|
||||
gEngfuncs.Con_Printf( "GL4ES_VERSION: %s\n", version );
|
||||
if( extensions )
|
||||
gEngfuncs.Con_Reportf( "GL4ES_EXTENSIONS: %s\n", extensions );
|
||||
|
||||
}
|
||||
|
||||
|
||||
gEngfuncs.Con_Printf( "GL_MAX_TEXTURE_SIZE: %i\n", glConfig.max_2d_texture_size );
|
||||
|
||||
if( GL_Support( GL_ARB_MULTITEXTURE ))
|
||||
@@ -1150,6 +1148,10 @@ void GL_InitExtensions( void )
|
||||
gEngfuncs.Cvar_SetValue( "gl_finish", 1 );
|
||||
#endif
|
||||
|
||||
// we do not want to write vbo code that does not use multitexture
|
||||
if( !GL_Support( GL_ARB_VERTEX_BUFFER_OBJECT_EXT ) || !GL_Support( GL_ARB_MULTITEXTURE ) || glConfig.max_texture_units < 2 )
|
||||
gEngfuncs.Cvar_FullSet( "gl_vbo", "0", FCVAR_READ_ONLY );
|
||||
|
||||
R_RenderInfo_f();
|
||||
|
||||
tr.framecount = tr.visframecount = 1;
|
||||
|
||||
@@ -1010,21 +1010,32 @@ void R_GammaChanged( qboolean do_reset_gamma )
|
||||
}
|
||||
}
|
||||
|
||||
static void R_CheckGamma( void )
|
||||
static void R_CheckCvars( void )
|
||||
{
|
||||
qboolean rebuild = false;
|
||||
|
||||
if( FBitSet( gl_overbright.flags, FCVAR_CHANGED ))
|
||||
{
|
||||
rebuild = true;
|
||||
ClearBits( gl_overbright.flags, FCVAR_CHANGED );
|
||||
rebuild = true;
|
||||
}
|
||||
|
||||
if( gl_overbright.value && ( FBitSet( r_vbo.flags, FCVAR_CHANGED ) || FBitSet( r_vbo_overbrightmode.flags, FCVAR_CHANGED ) ) )
|
||||
if( FBitSet( r_vbo.flags, FCVAR_CHANGED ))
|
||||
{
|
||||
rebuild = true;
|
||||
ClearBits( r_vbo.flags, FCVAR_CHANGED );
|
||||
|
||||
R_EnableVBO( r_vbo.value ? true : false );
|
||||
if( R_HasEnabledVBO( ))
|
||||
R_GenerateVBO();
|
||||
|
||||
if( gl_overbright.value )
|
||||
rebuild = true;
|
||||
}
|
||||
|
||||
if( FBitSet( r_vbo_overbrightmode.flags, FCVAR_CHANGED ) && gl_overbright.value )
|
||||
{
|
||||
ClearBits( r_vbo_overbrightmode.flags, FCVAR_CHANGED );
|
||||
rebuild = true;
|
||||
}
|
||||
|
||||
if( rebuild )
|
||||
@@ -1046,7 +1057,7 @@ void R_BeginFrame( qboolean clearScene )
|
||||
pglClear( GL_COLOR_BUFFER_BIT );
|
||||
}
|
||||
|
||||
R_CheckGamma();
|
||||
R_CheckCvars();
|
||||
|
||||
R_Set2DMode( true );
|
||||
|
||||
|
||||
@@ -147,7 +147,10 @@ void R_NewMap( void )
|
||||
}
|
||||
|
||||
GL_BuildLightmaps ();
|
||||
R_GenerateVBO();
|
||||
|
||||
R_ClearVBO();
|
||||
if( R_HasEnabledVBO( ))
|
||||
R_GenerateVBO();
|
||||
R_ResetRipples();
|
||||
|
||||
if( gEngfuncs.drawFuncs->R_NewMap != NULL )
|
||||
|
||||
@@ -229,10 +229,9 @@ void CL_DrawTracers( double frametime, particle_t *cl_active_tracers )
|
||||
VectorAdd( verts[0], delta, verts[2] );
|
||||
VectorAdd( verts[1], delta, verts[3] );
|
||||
|
||||
if( p->color > sizeof( gTracerColors ) / sizeof( gTracerColors[0] ))
|
||||
if( p->color < 0 || p->color > sizeof( gTracerColors ) / sizeof( gTracerColors[0] ))
|
||||
{
|
||||
gEngfuncs.Con_Printf( S_ERROR "UserTracer with color(%d) > %zu\n", p->color, sizeof( gTracerColors ) / sizeof( gTracerColors[0] ));
|
||||
p->color = 0;
|
||||
p->color = TRACER_COLORINDEX_DEFAULT;
|
||||
}
|
||||
|
||||
color = gTracerColors[p->color];
|
||||
|
||||
@@ -718,7 +718,7 @@ static void R_BuildLightMap( msurface_t *surf, byte *dest, int stride, qboolean
|
||||
tmax = ( info->lightextents[1] / sample_size ) + 1;
|
||||
size = smax * tmax;
|
||||
if( gl_overbright.value )
|
||||
lightscale = (r_vbo.value && !r_vbo_overbrightmode.value) ? 171 : 256;
|
||||
lightscale = ( R_HasEnabledVBO() && !r_vbo_overbrightmode.value) ? 171 : 256;
|
||||
else lightscale = ( pow( 2.0f, 1.0f / v_lightgamma->value ) * 256 ) + 0.5;
|
||||
|
||||
lm = surf->samples;
|
||||
@@ -927,7 +927,7 @@ static void R_BlendLightmaps( void )
|
||||
if( gl_overbright.value )
|
||||
{
|
||||
pglBlendFunc( GL_DST_COLOR, GL_SRC_COLOR );
|
||||
if(!( r_vbo.value && !r_vbo_overbrightmode.value ))
|
||||
if(!( R_HasEnabledVBO() && !r_vbo_overbrightmode.value ))
|
||||
pglColor4f( 128.0f / 192.0f, 128.0f / 192.0f, 128.0f / 192.0f, 1.0f );
|
||||
}
|
||||
else
|
||||
@@ -1135,6 +1135,148 @@ static void R_RenderDetails( int passes )
|
||||
GL_ResetFogColor();
|
||||
}
|
||||
|
||||
static void R_RenderFullbrightForSurface( msurface_t *fa, texture_t *t )
|
||||
{
|
||||
if( !t->fb_texturenum )
|
||||
return;
|
||||
|
||||
fa->info->lumachain = fullbright_surfaces[t->fb_texturenum];
|
||||
fullbright_surfaces[t->fb_texturenum] = fa->info;
|
||||
draw_fullbrights = true;
|
||||
}
|
||||
|
||||
static void R_RenderDetailsForSurface( msurface_t *fa, texture_t *t )
|
||||
{
|
||||
if( !r_detailtextures.value )
|
||||
return;
|
||||
|
||||
if( glState.isFogEnabled )
|
||||
{
|
||||
// don't apply detail textures for windows in the fog
|
||||
if( RI.currententity->curstate.rendermode != kRenderTransTexture )
|
||||
{
|
||||
if( t->dt_texturenum )
|
||||
{
|
||||
fa->info->detailchain = detail_surfaces[t->dt_texturenum];
|
||||
detail_surfaces[t->dt_texturenum] = fa->info;
|
||||
}
|
||||
else
|
||||
{
|
||||
// draw stub detail texture for underwater surfaces
|
||||
fa->info->detailchain = detail_surfaces[tr.grayTexture];
|
||||
detail_surfaces[tr.grayTexture] = fa->info;
|
||||
}
|
||||
draw_details = true;
|
||||
}
|
||||
}
|
||||
else if( t->dt_texturenum )
|
||||
{
|
||||
fa->info->detailchain = detail_surfaces[t->dt_texturenum];
|
||||
detail_surfaces[t->dt_texturenum] = fa->info;
|
||||
draw_details = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void R_RenderDecalsForSurface( msurface_t *fa, int cull_type )
|
||||
{
|
||||
if( RI.currententity->curstate.rendermode == kRenderNormal )
|
||||
{
|
||||
// batch decals to draw later
|
||||
if( tr.num_draw_decals < MAX_DECAL_SURFS && fa->pdecals )
|
||||
tr.draw_decals[tr.num_draw_decals++] = fa;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if rendermode != kRenderNormal draw decals sequentially
|
||||
DrawSurfaceDecals( fa, true, (cull_type == CULL_BACKSIDE));
|
||||
}
|
||||
}
|
||||
|
||||
static qboolean R_CheckLightMap( msurface_t *fa )
|
||||
{
|
||||
qboolean is_dynamic = false;
|
||||
int maps;
|
||||
|
||||
// check for lightmap modification
|
||||
for( maps = 0; maps < MAXLIGHTMAPS && fa->styles[maps] != 255; maps++ )
|
||||
{
|
||||
if( tr.lightstylevalue[fa->styles[maps]] != fa->cached_light[maps] )
|
||||
goto dynamic;
|
||||
}
|
||||
|
||||
// dynamic this frame or dynamic previously
|
||||
if( fa->dlightframe == tr.framecount )
|
||||
{
|
||||
dynamic:
|
||||
// NOTE: at this point we have only valid textures
|
||||
if( r_dynamic->value )
|
||||
is_dynamic = true;
|
||||
}
|
||||
|
||||
if( is_dynamic )
|
||||
{
|
||||
const int style = fa->styles[maps];
|
||||
|
||||
if( maps < MAXLIGHTMAPS && ( style >= 32 || style == 0 || style == 20 ) && fa->dlightframe != tr.framecount )
|
||||
{
|
||||
byte temp[132*132*4];
|
||||
mextrasurf_t *info = fa->info;
|
||||
int sample_size;
|
||||
int smax, tmax;
|
||||
|
||||
sample_size = gEngfuncs.Mod_SampleSizeForFace( fa );
|
||||
smax = ( info->lightextents[0] / sample_size ) + 1;
|
||||
tmax = ( info->lightextents[1] / sample_size ) + 1;
|
||||
|
||||
if( smax < 132 && tmax < 132 )
|
||||
R_BuildLightMap( fa, temp, smax * 4, true );
|
||||
else
|
||||
{
|
||||
smax = Q_min( smax, 132 );
|
||||
tmax = Q_min( tmax, 132 );
|
||||
memset( temp, 255, sizeof( temp ));
|
||||
//Host_MapDesignError( "%s: bad surface extents: %d %d", __func__, fa->extents[0], fa->extents[1] );
|
||||
}
|
||||
|
||||
R_SetCacheState( fa );
|
||||
|
||||
#ifdef XASH_WES
|
||||
GL_Bind( XASH_TEXTURE1, tr.lightmapTextures[fa->lightmaptexturenum] );
|
||||
pglTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE );
|
||||
#else
|
||||
GL_Bind( XASH_TEXTURE0, tr.lightmapTextures[fa->lightmaptexturenum] );
|
||||
#endif
|
||||
|
||||
pglTexSubImage2D( GL_TEXTURE_2D, 0, fa->light_s, fa->light_t, smax, tmax, GL_RGBA, GL_UNSIGNED_BYTE, temp );
|
||||
|
||||
#ifdef XASH_WES
|
||||
GL_SelectTexture( XASH_TEXTURE0 );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
return true; // add to dynamic chain
|
||||
}
|
||||
|
||||
return false; // updated
|
||||
}
|
||||
|
||||
static void R_RenderLightmapForSurface( msurface_t *fa )
|
||||
{
|
||||
if( !fa->polys || FBitSet( fa->flags, SURF_DRAWTILED ))
|
||||
return;
|
||||
|
||||
if( R_CheckLightMap( fa ))
|
||||
{
|
||||
fa->info->lightmapchain = gl_lms.dynamic_surfaces;
|
||||
gl_lms.dynamic_surfaces = fa;
|
||||
}
|
||||
else
|
||||
{
|
||||
fa->info->lightmapchain = gl_lms.lightmap_surfaces[fa->lightmaptexturenum];
|
||||
gl_lms.lightmap_surfaces[fa->lightmaptexturenum] = fa;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
R_RenderBrushPoly
|
||||
@@ -1142,8 +1284,6 @@ R_RenderBrushPoly
|
||||
*/
|
||||
static void R_RenderBrushPoly( msurface_t *fa, int cull_type )
|
||||
{
|
||||
qboolean is_dynamic = false;
|
||||
int maps;
|
||||
texture_t *t;
|
||||
|
||||
r_stats.c_world_polys++;
|
||||
@@ -1163,109 +1303,11 @@ static void R_RenderBrushPoly( msurface_t *fa, int cull_type )
|
||||
}
|
||||
else GL_Bind( XASH_TEXTURE0, t->gl_texturenum );
|
||||
|
||||
if( t->fb_texturenum )
|
||||
{
|
||||
fa->info->lumachain = fullbright_surfaces[t->fb_texturenum];
|
||||
fullbright_surfaces[t->fb_texturenum] = fa->info;
|
||||
draw_fullbrights = true;
|
||||
}
|
||||
|
||||
if( r_detailtextures.value )
|
||||
{
|
||||
if( glState.isFogEnabled )
|
||||
{
|
||||
// don't apply detail textures for windows in the fog
|
||||
if( RI.currententity->curstate.rendermode != kRenderTransTexture )
|
||||
{
|
||||
if( t->dt_texturenum )
|
||||
{
|
||||
fa->info->detailchain = detail_surfaces[t->dt_texturenum];
|
||||
detail_surfaces[t->dt_texturenum] = fa->info;
|
||||
}
|
||||
else
|
||||
{
|
||||
// draw stub detail texture for underwater surfaces
|
||||
fa->info->detailchain = detail_surfaces[tr.grayTexture];
|
||||
detail_surfaces[tr.grayTexture] = fa->info;
|
||||
}
|
||||
draw_details = true;
|
||||
}
|
||||
}
|
||||
else if( t->dt_texturenum )
|
||||
{
|
||||
fa->info->detailchain = detail_surfaces[t->dt_texturenum];
|
||||
detail_surfaces[t->dt_texturenum] = fa->info;
|
||||
draw_details = true;
|
||||
}
|
||||
}
|
||||
|
||||
R_RenderFullbrightForSurface( fa, t );
|
||||
R_RenderDetailsForSurface( fa, t );
|
||||
DrawGLPoly( fa->polys, 0.0f, 0.0f );
|
||||
|
||||
if( RI.currententity->curstate.rendermode == kRenderNormal )
|
||||
{
|
||||
// batch decals to draw later
|
||||
if( tr.num_draw_decals < MAX_DECAL_SURFS && fa->pdecals )
|
||||
tr.draw_decals[tr.num_draw_decals++] = fa;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if rendermode != kRenderNormal draw decals sequentially
|
||||
DrawSurfaceDecals( fa, true, (cull_type == CULL_BACKSIDE));
|
||||
}
|
||||
|
||||
if( FBitSet( fa->flags, SURF_DRAWTILED ))
|
||||
return; // no lightmaps anyway
|
||||
|
||||
// check for lightmap modification
|
||||
for( maps = 0; maps < MAXLIGHTMAPS && fa->styles[maps] != 255; maps++ )
|
||||
{
|
||||
if( tr.lightstylevalue[fa->styles[maps]] != fa->cached_light[maps] )
|
||||
goto dynamic;
|
||||
}
|
||||
|
||||
// dynamic this frame or dynamic previously
|
||||
if( fa->dlightframe == tr.framecount )
|
||||
{
|
||||
dynamic:
|
||||
// NOTE: at this point we have only valid textures
|
||||
if( r_dynamic->value ) is_dynamic = true;
|
||||
}
|
||||
|
||||
if( is_dynamic )
|
||||
{
|
||||
if(( maps < MAXLIGHTMAPS ) && ( fa->styles[maps] >= 32 || fa->styles[maps] == 0 || fa->styles[maps] == 20 ) && ( fa->dlightframe != tr.framecount ))
|
||||
{
|
||||
byte temp[132*132*4];
|
||||
mextrasurf_t *info = fa->info;
|
||||
int sample_size;
|
||||
int smax, tmax;
|
||||
|
||||
sample_size = gEngfuncs.Mod_SampleSizeForFace( fa );
|
||||
smax = ( info->lightextents[0] / sample_size ) + 1;
|
||||
tmax = ( info->lightextents[1] / sample_size ) + 1;
|
||||
|
||||
R_BuildLightMap( fa, temp, smax * 4, true );
|
||||
R_SetCacheState( fa );
|
||||
|
||||
GL_Bind( XASH_TEXTURE0, tr.lightmapTextures[fa->lightmaptexturenum] );
|
||||
|
||||
pglTexSubImage2D( GL_TEXTURE_2D, 0, fa->light_s, fa->light_t, smax, tmax,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, temp );
|
||||
|
||||
fa->info->lightmapchain = gl_lms.lightmap_surfaces[fa->lightmaptexturenum];
|
||||
gl_lms.lightmap_surfaces[fa->lightmaptexturenum] = fa;
|
||||
}
|
||||
else
|
||||
{
|
||||
fa->info->lightmapchain = gl_lms.dynamic_surfaces;
|
||||
gl_lms.dynamic_surfaces = fa;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fa->info->lightmapchain = gl_lms.lightmap_surfaces[fa->lightmaptexturenum];
|
||||
gl_lms.lightmap_surfaces[fa->lightmaptexturenum] = fa;
|
||||
}
|
||||
R_RenderDecalsForSurface( fa, cull_type );
|
||||
R_RenderLightmapForSurface( fa );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1541,7 +1583,7 @@ void R_DrawBrushModel( cl_entity_t *e )
|
||||
model_t *clmodel;
|
||||
qboolean rotated;
|
||||
dlight_t *l;
|
||||
qboolean allow_vbo = r_vbo.value;
|
||||
qboolean allow_vbo = R_HasEnabledVBO();
|
||||
|
||||
if( !RI.drawWorld ) return;
|
||||
|
||||
@@ -1791,6 +1833,10 @@ struct vbo_static_s
|
||||
int maxarraysplit_tex;
|
||||
int minarraysplit_lm;
|
||||
int maxarraysplit_lm;
|
||||
|
||||
// cvar state potentially might be changed during frame
|
||||
// so only enable VBO at the beginning of frame
|
||||
qboolean enabled;
|
||||
} vbos;
|
||||
|
||||
struct multitexturestate_s
|
||||
@@ -1827,7 +1873,6 @@ enum lightmap_state_e
|
||||
VBO_LIGHTMAP_DYNAMIC
|
||||
};
|
||||
|
||||
|
||||
static struct arraystate_s
|
||||
{
|
||||
enum array_state_e astate;
|
||||
@@ -1837,6 +1882,20 @@ static struct arraystate_s
|
||||
qboolean decal_mode;
|
||||
} vboarray;
|
||||
|
||||
qboolean R_HasGeneratedVBO( void )
|
||||
{
|
||||
return vbos.mempool != 0;
|
||||
}
|
||||
|
||||
void R_EnableVBO( qboolean enable )
|
||||
{
|
||||
vbos.enabled = enable;
|
||||
}
|
||||
|
||||
qboolean R_HasEnabledVBO( void )
|
||||
{
|
||||
return vbos.enabled;
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
@@ -1848,29 +1907,23 @@ Allocate memory for arrays, fill it with vertex attribs and upload to GPU
|
||||
void R_GenerateVBO( void )
|
||||
{
|
||||
model_t *world = WORLDMODEL;
|
||||
msurface_t *surfaces = world->surfaces;
|
||||
int numsurfaces = world->numsurfaces;
|
||||
int numtextures = world->numtextures;
|
||||
int numlightmaps = gl_lms.current_lightmap_texture;
|
||||
msurface_t *surfaces;
|
||||
int numsurfaces;
|
||||
int numtextures;
|
||||
const int numlightmaps = gl_lms.current_lightmap_texture;
|
||||
int k, len = 0;
|
||||
vboarray_t *vbo;
|
||||
uint maxindex = 0;
|
||||
double t1, t2, t3;
|
||||
|
||||
R_ClearVBO();
|
||||
|
||||
// we do not want to write vbo code that does not use multitexture
|
||||
if( !GL_Support( GL_ARB_VERTEX_BUFFER_OBJECT_EXT ) || !GL_Support( GL_ARB_MULTITEXTURE ) || glConfig.max_texture_units < 2 )
|
||||
{
|
||||
gEngfuncs.Cvar_FullSet( "gl_vbo", "0", FCVAR_READ_ONLY );
|
||||
if( R_HasGeneratedVBO() || !world || !world->surfaces )
|
||||
return;
|
||||
}
|
||||
|
||||
t1 = gEngfuncs.pfnTime();
|
||||
|
||||
// save in config if enabled manually
|
||||
if( r_vbo.value )
|
||||
r_vbo.flags |= FCVAR_ARCHIVE;
|
||||
surfaces = world->surfaces;
|
||||
numsurfaces = world->numsurfaces;
|
||||
numtextures = world->numtextures;
|
||||
|
||||
vbos.mempool = Mem_AllocPool("Render VBO Zone");
|
||||
|
||||
@@ -3021,14 +3074,14 @@ void R_DrawVBO( qboolean drawlightmap, qboolean drawtextures )
|
||||
int k;
|
||||
vboarray_t *vbo = vbos.arraylist;
|
||||
|
||||
if( !r_vbo.value )
|
||||
if( !R_HasGeneratedVBO() || !R_HasEnabledVBO() )
|
||||
return;
|
||||
|
||||
GL_SetupFogColorForSurfacesEx( 1, 0.5f, false );
|
||||
|
||||
R_SetupVBOArrayStatic( vbo, drawlightmap, drawtextures );
|
||||
mtst.skiptexture = !drawtextures;
|
||||
mtst.tmu_dt = glConfig.max_texture_units > 2 && r_vbo_detail.value == 2? XASH_TEXTURE2:-1;
|
||||
mtst.tmu_dt = glConfig.max_texture_units > 2 && r_vbo_detail.value == 2 ? XASH_TEXTURE2 : -1;
|
||||
|
||||
// setup limits
|
||||
if( vbos.minlightmap > vbos.minarraysplit_lm )
|
||||
@@ -3122,171 +3175,71 @@ void R_DrawVBO( qboolean drawlightmap, qboolean drawtextures )
|
||||
vbos.maxtexture = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
R_CheckLightMap
|
||||
|
||||
update surface's lightmap if needed and return true if it is dynamic
|
||||
================
|
||||
*/
|
||||
static qboolean R_CheckLightMap( msurface_t *fa )
|
||||
{
|
||||
int maps;
|
||||
qboolean is_dynamic = false;
|
||||
|
||||
// check for lightmap modification
|
||||
for( maps = 0; maps < MAXLIGHTMAPS && fa->styles[maps] != 255; maps++ )
|
||||
{
|
||||
if( tr.lightstylevalue[fa->styles[maps]] != fa->cached_light[maps] )
|
||||
{
|
||||
is_dynamic = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// already up to date
|
||||
if( !is_dynamic && ( fa->dlightframe != tr.framecount ))
|
||||
return false;
|
||||
|
||||
// build lightmap
|
||||
if(( maps < MAXLIGHTMAPS ) && ( fa->styles[maps] >= 32 || fa->styles[maps] == 0 ) && ( fa->dlightframe != tr.framecount ))
|
||||
{
|
||||
byte temp[132*132*4];
|
||||
int smax, tmax;
|
||||
int sample_size;
|
||||
mextrasurf_t *info;
|
||||
|
||||
info = fa->info;
|
||||
sample_size = gEngfuncs.Mod_SampleSizeForFace( fa );
|
||||
smax = ( info->lightextents[0] / sample_size ) + 1;
|
||||
tmax = ( info->lightextents[1] / sample_size ) + 1;
|
||||
|
||||
if( smax < 132 && tmax < 132 )
|
||||
{
|
||||
R_BuildLightMap( fa, temp, smax * 4, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
smax = Q_min( smax, 132 );
|
||||
tmax = Q_min( tmax, 132 );
|
||||
//Host_MapDesignError( "R_RenderBrushPoly: bad surface extents: %d %d", fa->extents[0], fa->extents[1] );
|
||||
memset( temp, 255, sizeof( temp ) );
|
||||
}
|
||||
|
||||
R_SetCacheState( fa );
|
||||
#ifdef XASH_WES
|
||||
GL_Bind( XASH_TEXTURE1, tr.lightmapTextures[fa->lightmaptexturenum] );
|
||||
|
||||
pglTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE );
|
||||
#else
|
||||
GL_Bind( XASH_TEXTURE0, tr.lightmapTextures[fa->lightmaptexturenum] );
|
||||
#endif
|
||||
|
||||
pglTexSubImage2D( GL_TEXTURE_2D, 0, fa->light_s, fa->light_t, smax, tmax,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, temp );
|
||||
#ifdef XASH_WES
|
||||
GL_SelectTexture( XASH_TEXTURE0 );
|
||||
#endif
|
||||
}
|
||||
// add to dynamic chain
|
||||
else
|
||||
return true;
|
||||
|
||||
// updated
|
||||
return false;
|
||||
}
|
||||
|
||||
qboolean R_AddSurfToVBO( msurface_t *surf, qboolean buildlightmap )
|
||||
{
|
||||
if( r_vbo.value && vbos.surfdata[surf - WORLDMODEL->surfaces].vbotexture )
|
||||
{
|
||||
// find vbotexture_t assotiated with this surface
|
||||
int idx = surf - WORLDMODEL->surfaces;
|
||||
vbotexture_t *vbotex = vbos.surfdata[idx].vbotexture;
|
||||
int texturenum = vbos.surfdata[idx].texturenum;
|
||||
const int idx = surf - WORLDMODEL->surfaces;
|
||||
vbotexture_t *vbotex;
|
||||
int texturenum;
|
||||
|
||||
if( !surf->polys )
|
||||
return true;
|
||||
if( !R_HasGeneratedVBO() || !R_HasEnabledVBO( ))
|
||||
return false;
|
||||
|
||||
if( vbos.maxlightmap < surf->lightmaptexturenum + 1 )
|
||||
vbos.maxlightmap = surf->lightmaptexturenum + 1;
|
||||
if( vbos.minlightmap > surf->lightmaptexturenum )
|
||||
vbos.minlightmap = surf->lightmaptexturenum;
|
||||
if( vbos.maxtexture < texturenum + 1 )
|
||||
vbos.maxtexture = texturenum + 1;
|
||||
if( vbos.mintexture > texturenum )
|
||||
vbos.mintexture = texturenum;
|
||||
// find vbotexture_t assotiated with this surface
|
||||
vbotex = vbos.surfdata[idx].vbotexture;
|
||||
texturenum = vbos.surfdata[idx].texturenum;
|
||||
|
||||
buildlightmap &= !r_fullbright->value && !!WORLDMODEL->lightdata;
|
||||
|
||||
/* draw details in regular way */
|
||||
if( r_vbo_detail.value == 0 )
|
||||
{
|
||||
if( r_detailtextures.value && surf->texinfo && surf->texinfo )
|
||||
{
|
||||
texture_t *t = surf->texinfo->texture;
|
||||
|
||||
if( glState.isFogEnabled )
|
||||
{
|
||||
// don't apply detail textures for windows in the fog
|
||||
if( RI.currententity->curstate.rendermode != kRenderTransTexture )
|
||||
{
|
||||
if( t->dt_texturenum )
|
||||
{
|
||||
surf->info->detailchain = detail_surfaces[t->dt_texturenum];
|
||||
detail_surfaces[t->dt_texturenum] = surf->info;
|
||||
}
|
||||
else
|
||||
{
|
||||
// draw stub detail texture for underwater surfaces
|
||||
surf->info->detailchain = detail_surfaces[tr.grayTexture];
|
||||
detail_surfaces[tr.grayTexture] = surf->info;
|
||||
}
|
||||
draw_details = true;
|
||||
}
|
||||
}
|
||||
else if( t->dt_texturenum )
|
||||
{
|
||||
surf->info->detailchain = detail_surfaces[t->dt_texturenum];
|
||||
detail_surfaces[t->dt_texturenum] = surf->info;
|
||||
draw_details = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( buildlightmap && R_CheckLightMap( surf ) )
|
||||
{
|
||||
// every vbotex has own lightmap chain (as we sorted if by textures to use multitexture)
|
||||
surf->info->lightmapchain = vbotex->dlightchain;
|
||||
vbotex->dlightchain = surf;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint indexbase = vbos.surfdata[idx].startindex;
|
||||
uint index;
|
||||
|
||||
// GL_TRIANGLE_FAN: 0 1 2 0 2 3 0 3 4 ...
|
||||
for( index = indexbase + 2; index < indexbase + surf->polys->numverts; index++ )
|
||||
{
|
||||
vbotex->indexarray[vbotex->curindex++] = indexbase;
|
||||
vbotex->indexarray[vbotex->curindex++] = index - 1;
|
||||
vbotex->indexarray[vbotex->curindex++] = index;
|
||||
}
|
||||
|
||||
// if surface has decals, add it to decal lightmapchain
|
||||
if( surf->pdecals )
|
||||
{
|
||||
surf->info->lightmapchain = vbos.decaldata->lm[vbotex->lightmaptexturenum];
|
||||
vbos.decaldata->lm[vbotex->lightmaptexturenum] = surf;
|
||||
}
|
||||
}
|
||||
|
||||
// now this path does not draw wapred surfaces, so count it as one poly
|
||||
r_stats.c_world_polys++;
|
||||
if( !vbotex )
|
||||
return false;
|
||||
|
||||
if( !surf->polys )
|
||||
return true;
|
||||
|
||||
if( vbos.maxlightmap < surf->lightmaptexturenum + 1 )
|
||||
vbos.maxlightmap = surf->lightmaptexturenum + 1;
|
||||
if( vbos.minlightmap > surf->lightmaptexturenum )
|
||||
vbos.minlightmap = surf->lightmaptexturenum;
|
||||
if( vbos.maxtexture < texturenum + 1 )
|
||||
vbos.maxtexture = texturenum + 1;
|
||||
if( vbos.mintexture > texturenum )
|
||||
vbos.mintexture = texturenum;
|
||||
|
||||
buildlightmap &= !r_fullbright->value && !!WORLDMODEL->lightdata;
|
||||
|
||||
// draw details in regular way
|
||||
if( r_vbo_detail.value == 0 && surf->texinfo )
|
||||
R_RenderDetailsForSurface( surf, surf->texinfo->texture );
|
||||
|
||||
if( buildlightmap && R_CheckLightMap( surf ))
|
||||
{
|
||||
// every vbotex has own lightmap chain (as we sorted if by textures to use multitexture)
|
||||
surf->info->lightmapchain = vbotex->dlightchain;
|
||||
vbotex->dlightchain = surf;
|
||||
}
|
||||
return false;
|
||||
else
|
||||
{
|
||||
uint indexbase = vbos.surfdata[idx].startindex;
|
||||
uint index;
|
||||
|
||||
// GL_TRIANGLE_FAN: 0 1 2 0 2 3 0 3 4 ...
|
||||
for( index = indexbase + 2; index < indexbase + surf->polys->numverts; index++ )
|
||||
{
|
||||
vbotex->indexarray[vbotex->curindex++] = indexbase;
|
||||
vbotex->indexarray[vbotex->curindex++] = index - 1;
|
||||
vbotex->indexarray[vbotex->curindex++] = index;
|
||||
}
|
||||
|
||||
// if surface has decals, add it to decal lightmapchain
|
||||
if( surf->pdecals )
|
||||
{
|
||||
surf->info->lightmapchain = vbos.decaldata->lm[vbotex->lightmaptexturenum];
|
||||
vbos.decaldata->lm[vbotex->lightmaptexturenum] = surf;
|
||||
}
|
||||
}
|
||||
|
||||
// now this path does not draw wapred surfaces, so count it as one poly
|
||||
r_stats.c_world_polys++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3624,7 +3577,7 @@ void R_DrawWorld( void )
|
||||
GL_ResetFogColor();
|
||||
R_BlendLightmaps();
|
||||
R_RenderFullbrights();
|
||||
R_RenderDetails( r_vbo.value? 2 : 3 );
|
||||
R_RenderDetails( R_HasEnabledVBO() ? 2 : 3 );
|
||||
|
||||
if( skychain )
|
||||
R_DrawSkyBox();
|
||||
|
||||
@@ -236,10 +236,9 @@ void GAME_EXPORT CL_DrawTracers( double frametime, particle_t *cl_active_tracers
|
||||
VectorAdd( verts[0], delta, verts[2] );
|
||||
VectorAdd( verts[1], delta, verts[3] );
|
||||
|
||||
if( p->color > sizeof( gTracerColors ) / sizeof( gTracerColors[0] ))
|
||||
if( p->color < 0 || p->color > sizeof( gTracerColors ) / sizeof( gTracerColors[0] ))
|
||||
{
|
||||
gEngfuncs.Con_Printf( S_ERROR "UserTracer with color(%d) > %zu\n", p->color, sizeof( gTracerColors ) / sizeof( gTracerColors[0] ));
|
||||
p->color = 0;
|
||||
p->color = TRACER_COLORINDEX_DEFAULT;
|
||||
}
|
||||
|
||||
color = gTracerColors[p->color];
|
||||
|
||||
@@ -27,7 +27,7 @@ WINSDK_LATEST=$(ls -1 "C:/Program Files (x86)/Windows Kits/10/bin" | grep -E '^1
|
||||
echo "Latest installed Windows SDK is $WINSDK_LATEST"
|
||||
|
||||
"C:/Program Files (x86)/Windows Kits/10/bin/$WINSDK_LATEST/x64/signtool.exe" \
|
||||
/f scripts/fwgs.pfx /fd SHA256 /p "$FWGS_PFX_PASSWORD" *.dll *.exe
|
||||
sign //f scripts/fwgs.pfx //fd SHA256 //p "$FWGS_PFX_PASSWORD" *.dll *.exe
|
||||
|
||||
if [ "$ARCH" = "i386" ]; then # VGUI is already signed
|
||||
cp 3rdparty/vgui_support/vgui-dev/lib/win32_vc6/vgui.dll .
|
||||
|
||||
Reference in New Issue
Block a user