18 Dec 2010

This commit is contained in:
g-cont 2010-12-18 00:00:00 +03:00 committed by Alibek Omarov
parent a45e9a9393
commit 03a5fb81ba
13 changed files with 1914 additions and 201 deletions

View File

@ -158,6 +158,7 @@ void CL_WeaponAnim( int iAnim, int body )
}
view->model = CM_ClipHandleToModel( view->curstate.modelindex );
view->index = cl.playernum + 1;
view->curstate.entityType = ET_NORMAL;
view->curstate.animtime = cl.time; // start immediately
view->curstate.framerate = 1.0f;
@ -632,6 +633,7 @@ void CL_AddEntities( void )
CL_FireEvents(); // so tempents can be created immediately
CL_AddTempEnts();
R_RunViewmodelEvents();
// perfomance test
CL_TestLights();

View File

@ -95,6 +95,7 @@ void CL_BeamKill( int deadEntity );
void TriVertex3fv( const float *v );
void TriNormal3fv( const float *v );
void TriColor4f( float r, float g, float b, float a );
int TriSpriteTexture( model_t *pSpriteModel, int frame );
int TriWorldToScreen( float *world, float *screen );
#endif//CL_TENT_H

View File

@ -34,9 +34,6 @@ void GL_BackendStartFrame( void )
{
r_speeds_msg[0] = '\0';
Mem_Set( &r_stats, 0, sizeof( r_stats ));
com.snprintf( r_speeds_msg, sizeof( r_speeds_msg ), "%3i static entities\n%3i normal entities",
r_numStatics, r_numEntities );
}
/*
@ -46,6 +43,20 @@ GL_BackendEndFrame
*/
void GL_BackendEndFrame( void )
{
if( r_speeds->integer <= 0 || !RI.drawWorld )
return;
switch( r_speeds->integer )
{
case 5:
com.snprintf( r_speeds_msg, sizeof( r_speeds_msg ), "%3i studio models drawn\n%3i sprites drawn",
r_stats.c_studio_models_drawn, r_stats.c_sprite_models_drawn );
break;
case 6:
com.snprintf( r_speeds_msg, sizeof( r_speeds_msg ), "%3i static entities\n%3i normal entities",
r_numStatics, r_numEntities );
break;
}
}
/*

View File

@ -7,6 +7,20 @@
#include "client.h"
#include "gl_local.h"
/*
=============================================================
FRUSTUM AND PVS CULLING
=============================================================
*/
/*
=================
R_CullBox
Returns true if the box is completely outside the frustum
=================
*/
qboolean R_CullBox( const vec3_t mins, const vec3_t maxs, uint clipflags )
{
uint i, bit;
@ -59,4 +73,171 @@ qboolean R_CullBox( const vec3_t mins, const vec3_t maxs, uint clipflags )
}
}
return false;
}
/*
=================
R_CullSphere
Returns true if the sphere is completely outside the frustum
=================
*/
qboolean R_CullSphere( const vec3_t centre, const float radius, const uint clipflags )
{
uint i, bit;
const mplane_t *p;
if( r_nocull->integer )
return false;
for( i = sizeof( RI.frustum ) / sizeof( RI.frustum[0] ), bit = 1, p = RI.frustum; i > 0; i--, bit<<=1, p++ )
{
if(!( clipflags & bit )) continue;
if( DotProduct( centre, p->normal ) - p->dist <= -radius )
return true;
}
return false;
}
/*
===================
R_VisCullBox
===================
*/
qboolean R_VisCullBox( const vec3_t mins, const vec3_t maxs )
{
int s, stackdepth = 0;
vec3_t extmins, extmaxs;
mnode_t *node, *localstack[4096];
if( !cl.worldmodel || !RI.drawWorld )
return false;
if( r_novis->integer )
return false;
for( s = 0; s < 3; s++ )
{
extmins[s] = mins[s] - 4;
extmaxs[s] = maxs[s] + 4;
}
for( node = cl.worldmodel->nodes; node; )
{
if( node->visframe != tr.visframecount )
{
if( !stackdepth )
return true;
node = localstack[--stackdepth];
continue;
}
if( node->contents < 0 )
return false;
s = BOX_ON_PLANE_SIDE( extmins, extmaxs, node->plane ) - 1;
if( s < 2 )
{
node = node->children[s];
continue;
}
// go down both sides
if( stackdepth < sizeof( localstack ) / sizeof( mnode_t* ))
localstack[stackdepth++] = node->children[0];
node = node->children[1];
}
return true;
}
/*
===================
R_VisCullSphere
===================
*/
qboolean R_VisCullSphere( const vec3_t origin, float radius )
{
float dist;
int stackdepth = 0;
mnode_t *node, *localstack[4096];
if( !cl.worldmodel || !RI.drawWorld )
return false;
if( r_novis->integer )
return false;
radius += 4;
for( node = cl.worldmodel->nodes; ; )
{
if( node->visframe != tr.visframecount )
{
if( !stackdepth )
return true;
node = localstack[--stackdepth];
continue;
}
if( node->contents < 0 )
return false;
dist = PlaneDiff( origin, node->plane );
if( dist > radius )
{
node = node->children[0];
continue;
}
else if( dist < -radius )
{
node = node->children[1];
continue;
}
// go down both sides
if( stackdepth < sizeof( localstack ) / sizeof( mnode_t* ))
localstack[stackdepth++] = node->children[0];
node = node->children[1];
}
return true;
}
/*
=============
R_CullModel
=============
*/
int R_CullModel( cl_entity_t *e, vec3_t mins, vec3_t maxs, float radius )
{
if( e == &clgame.viewent )
{
if( RI.params & RP_NONVIEWERREF )
return 1;
return 0;
}
// don't reflect this entity in mirrors
if( e->curstate.effects & EF_NOREFLECT && RI.params & RP_MIRRORVIEW )
return 1;
// draw only in mirrors
if( e->curstate.effects & EF_REFLECTONLY && !( RI.params & RP_MIRRORVIEW ))
return 1;
if( RP_LOCALCLIENT( e ) && !RI.thirdPerson )
{
if(!( RI.params & ( RP_MIRRORVIEW|RP_SHADOWMAPVIEW )))
return 1;
}
if( R_CullSphere( e->origin, radius, RI.clipFlags ))
return 1;
if( RI.rdflags & ( RDF_PORTALINVIEW|RDF_SKYPORTALINVIEW ) || ( RI.params & RP_SKYPORTALVIEW ))
{
if( R_VisCullSphere( e->origin, radius ))
return 2;
}
return 0;
}

View File

@ -19,6 +19,10 @@ extern byte *r_temppool;
#define MAX_LIGHTMAPS 64
#define SUBDIVIDE_SIZE 64
// renderer flags
#define RDF_PORTALINVIEW BIT( 0 ) // draw portal pass
#define RDF_SKYPORTALINVIEW BIT( 1 ) // draw skyportal instead of regular sky
// refparams
#define RP_NONE 0
#define RP_MIRRORVIEW BIT( 0 ) // lock pvs at vieworg
@ -27,7 +31,12 @@ extern byte *r_temppool;
#define RP_OLDVIEWLEAF BIT( 3 )
#define RP_CLIPPLANE BIT( 4 )
#define RP_FLIPFRONTFACE BIT( 5 ) // e.g. for mirrors drawing
#define RP_NOSKY BIT( 6 )
#define RP_SHADOWMAPVIEW BIT( 6 )
#define RP_SKYPORTALVIEW BIT( 7 )
#define RP_NOSKY BIT( 8 )
#define RP_NONVIEWERREF (RP_PORTALVIEW|RP_MIRRORVIEW|RP_ENVVIEW|RP_SKYPORTALVIEW|RP_SHADOWMAPVIEW)
#define RP_LOCALCLIENT( e ) (CL_GetLocalPlayer() && ((e)->index == CL_GetLocalPlayer()->index && e->player ))
typedef enum
{
@ -203,7 +212,9 @@ typedef struct
uint c_sprite_polys;
uint c_world_leafs;
uint c_studio_models;
uint c_studio_models_count;
uint c_studio_models_drawn;
uint c_sprite_models_drawn;
} ref_speeds_t;
extern ref_speeds_t r_stats;
@ -238,6 +249,15 @@ void GL_TexEnv( GLenum mode );
void GL_Cull( GLenum cull );
void R_ShowTextures( void );
//
// gl_cull.c
//
int R_CullModel( cl_entity_t *e, vec3_t mins, vec3_t maxs, float radius );
qboolean R_CullBox( const vec3_t mins, const vec3_t maxs, uint clipflags );
qboolean R_CullSphere( const vec3_t centre, const float radius, const uint clipflags );
qboolean R_VisCullBox( const vec3_t mins, const vec3_t maxs );
qboolean R_VisCullSphere( const vec3_t origin, float radius );
//
// gl_draw.c
//
@ -316,6 +336,7 @@ void R_DrawSpriteModel( cl_entity_t *e );
// gl_studio.c
//
void R_StudioInit( void );
void Mod_LoadStudioModel( model_t *mod, const void *buffer );
void R_DrawStudioModel( cl_entity_t *e );
//
@ -504,6 +525,7 @@ extern convar_t *r_lighting_direct;
extern convar_t *r_faceplanecull;
extern convar_t *r_drawentities;
extern convar_t *r_adjust_fov;
extern convar_t *r_lefthand;
extern convar_t *r_novis;
extern convar_t *r_nocull;
extern convar_t *r_lockpvs;

View File

@ -14,6 +14,8 @@ void R_NewMap( void )
tr.framecount = tr.visframecount = 1;
CL_ClearEffects ();
GL_BuildLightmaps ();
R_SetupSky( cl.refdef.movevars->skyName );

View File

@ -15,9 +15,11 @@
// it's a Valve default value for LoadMapSprite (probably must be power of two)
#define MAPSPRITE_SIZE 128
convar_t *r_sprite_lerping;
char sprite_name[64];
char group_suffix[8];
convar_t *r_sprite_lerping;
char sprite_name[64];
char group_suffix[8];
static vec3_t sprite_mins, sprite_maxs;
static float sprite_radius;
/*
====================
@ -620,6 +622,62 @@ float R_GetSpriteFrameInterpolant( cl_entity_t *ent, mspriteframe_t **oldframe,
return lerpFrac;
}
/*
================
R_StudioComputeBBox
Compute a full bounding box for current sequence
================
*/
qboolean R_SpriteComputeBBox( cl_entity_t *e, vec3_t bbox[8] )
{
float scale = 1.0f;
vec3_t p1;
int i;
// copy original bbox (no rotation for sprites)
VectorCopy( e->model->mins, sprite_mins );
VectorCopy( e->model->maxs, sprite_maxs );
// compute a full bounding box
for( i = 0; bbox && i < 8; i++ )
{
p1[0] = ( i & 1 ) ? sprite_mins[0] : sprite_maxs[0];
p1[1] = ( i & 2 ) ? sprite_mins[1] : sprite_maxs[1];
p1[2] = ( i & 4 ) ? sprite_mins[2] : sprite_maxs[2];
VectorCopy( p1, bbox[i] );
}
if( e->curstate.scale > 0.0f )
scale = e->curstate.scale;
sprite_radius = RadiusFromBounds( sprite_mins, sprite_maxs ) * scale;
return true;
}
/*
================
R_CullSpriteModel
Cull sprite model by bbox
================
*/
qboolean R_CullSpriteModel( cl_entity_t *e )
{
if( !e->model->cache.data )
return true;
if( e == &clgame.viewent && r_lefthand->integer >= 2 )
return true;
if( !R_SpriteComputeBBox( e, NULL ))
return true; // invalid frame
return R_CullModel( e, sprite_mins, sprite_maxs, sprite_radius );
}
/*
================
R_GlowSightDistance
@ -700,13 +758,8 @@ qboolean R_SpriteOccluded( cl_entity_t *e, vec3_t origin )
}
else
{
vec3_t mins, maxs;
VectorAdd( origin, e->model->mins, mins );
VectorAdd( origin, e->model->maxs, maxs );
if( R_CullBox( mins, maxs, RI.clipFlags ))
return true; // culled
if( R_CullSpriteModel( e ))
return true;
}
return false;
}
@ -786,6 +839,8 @@ void R_DrawSpriteModel( cl_entity_t *e )
if( R_SpriteOccluded( e, origin ))
return; // sprite culled
r_stats.c_sprite_models_drawn++;
if( psprite->texFormat == SPR_ALPHTEST )
state |= GLSTATE_AFUNC_GE128|GLSTATE_DEPTHWRITE;

File diff suppressed because it is too large Load Diff

View File

@ -50,6 +50,7 @@ convar_t *r_lighting_direct;
convar_t *r_faceplanecull;
convar_t *r_drawentities;
convar_t *r_adjust_fov;
convar_t *r_lefthand;
convar_t *r_novis;
convar_t *r_nocull;
convar_t *r_lockpvs;
@ -1379,7 +1380,8 @@ void GL_InitCommands( void )
r_shadows = Cvar_Get( "r_shadows", "0", CVAR_ARCHIVE, "enable model shadows" );
r_fastsky = Cvar_Get( "r_fastsky", "0", CVAR_ARCHIVE, "enable algorhytm fo fast sky rendering (for old machines)" );
r_drawentities = Cvar_Get( "r_drawentities", "1", CVAR_CHEAT|CVAR_ARCHIVE, "render entities" );
r_lefthand = Cvar_Get( "hand", "0", CVAR_ARCHIVE, "viewmodel handedness" );
gl_picmip = Cvar_Get( "gl_picmip", "0", CVAR_RENDERINFO|CVAR_LATCH_VIDEO, "reduces resolution of textures by powers of 2" );
gl_skymip = Cvar_Get( "gl_skymip", "0", CVAR_RENDERINFO|CVAR_LATCH_VIDEO, "reduces resolution of skybox textures by powers of 2" );
gl_ignorehwgamma = Cvar_Get( "gl_ignorehwgamma", "0", CVAR_ARCHIVE|CVAR_LATCH_VIDEO, "ignore hardware gamma (e.g. not support)" );

View File

@ -82,6 +82,7 @@ void Mod_UnloadSpriteModel( struct model_s *mod );
void Mod_UnloadStudioModel( struct model_s *mod );
void Mod_UnloadBrushModel( struct model_s *mod );
void GL_SetRenderMode( int mode );
void R_RunViewmodelEvents( void );
int R_GetSpriteTexture( const struct model_s *m_pSpriteModel, int frame );
void R_LightForPoint( const vec3_t point, color24 *ambientLight, qboolean invLight );
qboolean R_DecalShoot( int texture, int ent, int model, vec3_t pos, vec3_t saxis, int flags, rgba_t color );

View File

@ -63,31 +63,6 @@ void Mod_SetupHulls( float mins[4][3], float maxs[4][3] )
Mem_Copy( maxs, cm_hullmaxs, sizeof( cm_hullmaxs ));
}
/*
================
Mod_StudioBodyVariations
================
*/
static int Mod_StudioBodyVariations( model_t *mod )
{
studiohdr_t *pstudiohdr;
mstudiobodyparts_t *pbodypart;
int i, count;
pstudiohdr = (studiohdr_t *)Mod_Extradata( mod );
if( !pstudiohdr ) return 0;
count = 1;
pbodypart = (mstudiobodyparts_t *)((byte *)pstudiohdr + pstudiohdr->bodypartindex);
// each body part has nummodels variations so there are as many total variations as there
// are in a matrix of each part by each other part
for( i = 0; i < pstudiohdr->numbodyparts; i++ )
count = count * pbodypart[i].nummodels;
return count;
}
/*
===================
Mod_CompressVis
@ -1441,39 +1416,6 @@ static void Mod_LoadBrushModel( model_t *mod, const void *buffer )
}
}
/*
=================
Mod_LoadStudioModel
=================
*/
static void Mod_LoadStudioModel( model_t *mod, byte *buffer )
{
studiohdr_t *phdr;
mstudioseqdesc_t *pseqdesc;
int i;
phdr = (studiohdr_t *)buffer;
i = phdr->version;
if( i != STUDIO_VERSION )
{
MsgDev( D_ERROR, "%s has wrong version number (%i should be %i)\n", loadmodel->name, i, STUDIO_VERSION );
return;
}
loadmodel->type = mod_studio;
pseqdesc = (mstudioseqdesc_t *)((byte *)phdr + phdr->seqindex);
loadmodel->numframes = pseqdesc[0].numframes;
loadmodel->mempool = Mem_AllocPool( va("^2%s^7", loadmodel->name ));
loadmodel->cache.data = Mem_Alloc( loadmodel->mempool, phdr->length );
Mem_Copy( loadmodel->cache.data, buffer, phdr->length );
// setup bounding box
VectorCopy( phdr->bbmin, loadmodel->mins );
VectorCopy( phdr->bbmax, loadmodel->maxs );
}
/*
==================
Mod_FindName
@ -1685,10 +1627,7 @@ void Mod_GetFrames( int handle, int *numFrames )
return;
}
if( mod->type == mod_sprite )
*numFrames = mod->numframes;
else if( mod->type == mod_studio )
*numFrames = Mod_StudioBodyVariations( mod );
*numFrames = mod->numframes;
if( *numFrames < 1 ) *numFrames = 1;
}

View File

@ -437,7 +437,7 @@ static mstudioanim_t *PM_StudioGetAnim( model_t *m_pSubModel, mstudioseqdesc_t *
}
// check for already loaded
if( !Cache_Check( m_pSubModel->mempool, ( cache_user_t *)&( paSequences[pseqdesc->seqgroup] )))
if( !Mod_CacheCheck(( cache_user_t *)&( paSequences[pseqdesc->seqgroup] )))
{
string filepath, modelname, modelpath;
@ -446,11 +446,13 @@ static mstudioanim_t *PM_StudioGetAnim( model_t *m_pSubModel, mstudioseqdesc_t *
com.snprintf( filepath, sizeof( filepath ), "%s/%s%i%i.mdl", modelpath, modelname, pseqdesc->seqgroup / 10, pseqdesc->seqgroup % 10 );
buf = FS_LoadFile( filepath, &filesize );
if( !buf || !filesize ) Host_Error( "CM_StudioGetAnim: can't load %s\n", modelpath );
if( !buf || !filesize ) Host_Error( "StudioGetAnim: can't load %s\n", filepath );
if( IDSEQGRPHEADER != *(uint *)buf )
Host_Error( "PM_StudioGetAnim: %s is corrupted\n", modelpath );
Host_Error( "StudioGetAnim: %s is corrupted\n", filepath );
paSequences[pseqdesc->seqgroup].data = Mem_Alloc( m_pSubModel->mempool, filesize );
MsgDev( D_INFO, "loading: %s\n", filepath );
paSequences[pseqdesc->seqgroup].data = Mem_Alloc( com_studiocache, filesize );
Mem_Copy( paSequences[pseqdesc->seqgroup].data, buf, filesize );
Mem_Free( buf );
}

View File

@ -441,7 +441,7 @@ static mstudioanim_t *SV_StudioGetAnim( model_t *m_pSubModel, mstudioseqdesc_t *
}
// check for already loaded
if( !Cache_Check( m_pSubModel->mempool, ( cache_user_t *)&( paSequences[pseqdesc->seqgroup] )))
if( !Mod_CacheCheck(( cache_user_t *)&( paSequences[pseqdesc->seqgroup] )))
{
string filepath, modelname, modelpath;
@ -450,11 +450,13 @@ static mstudioanim_t *SV_StudioGetAnim( model_t *m_pSubModel, mstudioseqdesc_t *
com.snprintf( filepath, sizeof( filepath ), "%s/%s%i%i.mdl", modelpath, modelname, pseqdesc->seqgroup / 10, pseqdesc->seqgroup % 10 );
buf = FS_LoadFile( filepath, &filesize );
if( !buf || !filesize ) Host_Error( "CM_StudioGetAnim: can't load %s\n", modelpath );
if( !buf || !filesize ) Host_Error( "StudioGetAnim: can't load %s\n", filepath );
if( IDSEQGRPHEADER != *(uint *)buf )
Host_Error( "SV_StudioGetAnim: %s is corrupted\n", modelpath );
Host_Error( "StudioGetAnim: %s is corrupted\n", filepath );
paSequences[pseqdesc->seqgroup].data = Mem_Alloc( m_pSubModel->mempool, filesize );
MsgDev( D_INFO, "loading: %s\n", filepath );
paSequences[pseqdesc->seqgroup].data = Mem_Alloc( com_studiocache, filesize );
Mem_Copy( paSequences[pseqdesc->seqgroup].data, buf, filesize );
Mem_Free( buf );
}