12 Mar 2017

This commit is contained in:
g-cont 2017-03-12 00:00:00 +03:00 committed by Alibek Omarov
parent 44166415b9
commit 7c3769b3b9
25 changed files with 398 additions and 426 deletions

View File

@ -94,6 +94,8 @@ static dllfunc_t cdll_new_exports[] = // allowed only in SDK 2.3 and higher
{ NULL, NULL }
};
static void pfnSPR_DrawHoles( int frame, int x, int y, const wrect_t *prc );
/*
====================
CL_GetEntityByIndex
@ -522,6 +524,7 @@ static void SPR_DrawGeneric( int frame, float x, float y, float width, float hei
SPR_AdjustSize( &x, &y, &width, &height );
texnum = R_GetSpriteTexture( clgame.ds.pSprite, frame );
pglColor4ubv( clgame.ds.spriteColor );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
R_DrawStretchPic( x, y, width, height, s1, t1, s2, t2, texnum );
}
@ -864,13 +867,15 @@ void CL_DrawCrosshair( void )
y += ( clgame.viewport[3] >> 1 ) * screen[1] + 0.5f;
}
clgame.ds.pSprite = clgame.ds.pCrosshair;
// move at center the screen
x -= 0.5f * width;
y -= 0.5f * height;
GL_SetRenderMode( kRenderTransTexture );
clgame.ds.pSprite = clgame.ds.pCrosshair;
*(int *)clgame.ds.spriteColor = *(int *)clgame.ds.rgbaCrosshair;
SPR_EnableScissor( x - 0.5f * width, y - 0.5f * height, width, height );
SPR_DrawGeneric( 0, x - 0.5f * width, y - 0.5f * height, -1, -1, &clgame.ds.rcCrosshair );
SPR_EnableScissor( x, y, width, height );
pfnSPR_DrawHoles( 0, x, y, &clgame.ds.rcCrosshair );
SPR_DisableScissor();
}
@ -1318,11 +1323,6 @@ static void pfnSPR_Set( HSPRITE hPic, int r, int g, int b )
clgame.ds.spriteColor[1] = bound( 0, g, 255 );
clgame.ds.spriteColor[2] = bound( 0, b, 255 );
clgame.ds.spriteColor[3] = 255;
// set default state
pglDisable( GL_BLEND );
pglDisable( GL_ALPHA_TEST );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
}
/*
@ -1333,7 +1333,6 @@ pfnSPR_Draw
*/
static void pfnSPR_Draw( int frame, int x, int y, const wrect_t *prc )
{
pglEnable( GL_ALPHA_TEST );
SPR_DrawGeneric( frame, x, y, -1, -1, prc );
}
@ -1345,8 +1344,14 @@ pfnSPR_DrawHoles
*/
static void pfnSPR_DrawHoles( int frame, int x, int y, const wrect_t *prc )
{
GL_SetRenderMode( kRenderTransAlpha );
pglEnable( GL_ALPHA_TEST );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
pglEnable( GL_BLEND );
SPR_DrawGeneric( frame, x, y, -1, -1, prc );
pglDisable( GL_ALPHA_TEST );
pglDisable( GL_BLEND );
}
/*
@ -1357,8 +1362,12 @@ pfnSPR_DrawAdditive
*/
static void pfnSPR_DrawAdditive( int frame, int x, int y, const wrect_t *prc )
{
GL_SetRenderMode( kRenderTransAdd );
pglEnable( GL_BLEND );
pglBlendFunc( GL_ONE, GL_ONE );
SPR_DrawGeneric( frame, x, y, -1, -1, prc );
pglDisable( GL_BLEND );
}
/*
@ -1440,19 +1449,31 @@ CL_FillRGBA
=============
*/
void CL_FillRGBA( int x, int y, int width, int height, int r, int g, int b, int a )
void CL_FillRGBA( int x, int y, int w, int h, int r, int g, int b, int a )
{
r = bound( 0, r, 255 );
g = bound( 0, g, 255 );
b = bound( 0, b, 255 );
a = bound( 0, a, 255 );
pglColor4ub( r, g, b, a );
SPR_AdjustSize( (float *)&x, (float *)&y, (float *)&width, (float *)&height );
SPR_AdjustSize( (float *)&x, (float *)&y, (float *)&w, (float *)&h );
GL_SetRenderMode( kRenderTransAdd );
R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, tr.whiteTexture );
pglColor4ub( 255, 255, 255, 255 );
pglDisable( GL_TEXTURE_2D );
pglEnable( GL_BLEND );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE );
pglColor4f( r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f );
pglBegin( GL_QUADS );
pglVertex2f( x, y );
pglVertex2f( x + w, y );
pglVertex2f( x + w, y + h );
pglVertex2f( x, y + h );
pglEnd ();
pglColor3f( 1.0f, 1.0f, 1.0f );
pglEnable( GL_TEXTURE_2D );
pglDisable( GL_BLEND );
}
/*
@ -2181,11 +2202,12 @@ int CL_FindModelIndex( const char *m )
return i;
}
if( cls.state == ca_active && Q_strnicmp( m, "models/player/", 14 ))
if( cls.state == ca_active )
{
// tell user about problem (but don't spam console about playermodel)
MsgDev( D_NOTE, "CL_ModelIndex: %s not precached\n", m );
}
return 0;
}
@ -2820,23 +2842,31 @@ CL_FillRGBABlend
=============
*/
void CL_FillRGBABlend( int x, int y, int width, int height, int r, int g, int b, int a )
void CL_FillRGBABlend( int x, int y, int w, int h, int r, int g, int b, int a )
{
r = bound( 0, r, 255 );
g = bound( 0, g, 255 );
b = bound( 0, b, 255 );
a = bound( 0, a, 255 );
pglColor4ub( r, g, b, a );
SPR_AdjustSize( (float *)&x, (float *)&y, (float *)&width, (float *)&height );
SPR_AdjustSize( (float *)&x, (float *)&y, (float *)&w, (float *)&h );
pglDisable( GL_TEXTURE_2D );
pglEnable( GL_BLEND );
pglDisable( GL_ALPHA_TEST );
pglBlendFunc( GL_ONE_MINUS_SRC_ALPHA, GL_ONE );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
pglColor4f( r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f );
R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, tr.whiteTexture );
pglColor4ub( 255, 255, 255, 255 );
pglBegin( GL_QUADS );
pglVertex2f( x, y );
pglVertex2f( x + w, y );
pglVertex2f( x + w, y + h );
pglVertex2f( x, y + h );
pglEnd ();
pglColor3f( 1.0f, 1.0f, 1.0f );
pglEnable( GL_TEXTURE_2D );
pglDisable( GL_BLEND );
}
/*
@ -2879,6 +2909,7 @@ void TriRenderMode( int mode )
switch( mode )
{
case kRenderNormal:
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
pglDisable( GL_BLEND );
pglDepthMask( GL_TRUE );
break;

View File

@ -2275,6 +2275,9 @@ void Host_ClientBegin( void )
// evaluate console animation
Con_RunConsole ();
// exec console commands
Cbuf_Execute ();
// finalize connection process if needs
CL_CheckClientState();
@ -2314,6 +2317,7 @@ void Host_ClientFrame( void )
// Voice_Idle( host.frametime );
// emit visible entities
CL_EmitEntities ();
// in case we lost connection

View File

@ -571,35 +571,11 @@ void CL_WeaponAnim( int iAnim, int body )
{
cl_entity_t *view = &clgame.viewent;
cl.local.weaponstarttime = 0;
cl.local.weaponstarttime = 0.0f;
cl.local.weaponsequence = iAnim;
// anim is changed. update latchedvars
if( iAnim != view->curstate.sequence )
{
int i;
// save current blends to right lerping from last sequence
for( i = 0; i < 2; i++ )
view->latched.prevseqblending[i] = view->curstate.blending[i];
view->latched.prevsequence = view->curstate.sequence; // save old sequence
// save animtime
view->latched.prevanimtime = view->curstate.animtime;
view->latched.sequencetime = 0.0f;
}
view->curstate.animtime = cl.time; // start immediately
view->curstate.framerate = 1.0f;
view->curstate.sequence = iAnim;
view->latched.prevframe = 0.0f;
view->curstate.scale = 1.0f;
view->curstate.frame = 0.0f;
view->curstate.body = body;
view->curstate.rendermode = kRenderNormal;
view->curstate.renderamt = 255;
#if 0 // g-cont. for GlowShell testing
view->curstate.renderfx = kRenderFxGlowShell;
view->curstate.rendercolor.r = 255;
@ -965,6 +941,10 @@ void CL_ParseClientData( sizebuf_t *msg )
MSG_ReadWeaponData( msg, &from_wd[idx], &to_wd[idx], cl.mtime[0] );
}
// shared predicted viewmodel actual index with clientdata
if( CL_LocalWeapons() && cl.local.viewmodel && frame->clientdata.viewmodel )
frame->clientdata.viewmodel = cl.local.viewmodel;
// make a local copy of physinfo
Q_strncpy( cls.physinfo, frame->clientdata.physinfo, sizeof( cls.physinfo ));

View File

@ -1256,10 +1256,13 @@ void CL_PredictMovement( qboolean repredicting )
VectorCopy( frame->clientdata.origin, cl.simorg );
VectorCopy( frame->clientdata.punchangle, cl.punchangle );
VectorCopy( frame->clientdata.view_ofs, cl.viewheight );
cl.local.onground = frame->playerstate[cl.playernum].onground;
cl.local.usehull = frame->playerstate[cl.playernum].usehull;
cl.local.waterlevel = frame->clientdata.waterlevel;
if( FBitSet( frame->clientdata.flags, FL_ONGROUND ))
cl.local.onground = frame->playerstate[cl.playernum].onground;
else cl.local.onground = -1;
// we need to perform cl_lw prediction while cl_predict is disabled
// because cl_lw is enabled by default in Half-Life
if( !CL_LocalWeapons( ))
@ -1314,6 +1317,12 @@ void CL_PredictMovement( qboolean repredicting )
to_cmd = from_cmd;
}
if( !CL_IsPredicted( ))
{
cl.local.viewmodel = to->client.viewmodel;
return;
}
// now interpolate some fraction of the final frame
if( to_cmd->senttime == from_cmd->senttime )
{

View File

@ -80,14 +80,36 @@ V_SetupViewModel
void V_SetupViewModel( void )
{
cl_entity_t *view = &clgame.viewent;
player_info_t *info = &cl.players[cl.playernum];
static qboolean model_changing = false;
static int skipframe = 0;
if( CL_LocalWeapons() && view->curstate.modelindex != cl.local.viewmodel && !model_changing )
{
model_changing = true;
skipframe = 2; // server ack & server responce
}
// setup the viewent variables
view->model = Mod_Handle( cl.local.viewmodel );
view->curstate.modelindex = cl.local.viewmodel;
view->curstate.colormap = (info->topcolor & 0xFFFF)|((info->bottomcolor << 8) & 0xFFFF);
view->curstate.number = cl.playernum + 1;
view->index = cl.playernum + 1;
view->curstate.colormap = 0;
view->curstate.frame = 0;
view->curstate.frame = 0.0f;
if( skipframe <= 0 )
{
if( !cl.local.weaponstarttime )
cl.local.weaponstarttime = cl.time;
view->model = Mod_Handle( cl.local.viewmodel );
view->curstate.modelindex = cl.local.viewmodel;
view->curstate.animtime = cl.local.weaponstarttime;
view->curstate.sequence = cl.local.weaponsequence;
model_changing = false;
}
else
{
skipframe--;
}
}
/*
@ -305,7 +327,6 @@ void V_RenderView( void )
R_Set2DMode( false );
SCR_DirtyScreen();
GL_BackendStartFrame ();
tr.realframecount++;
do
{

View File

@ -148,6 +148,13 @@ typedef struct
float weaponstarttime;
} cl_local_data_t;
typedef struct
{
char name[MAX_OSPATH];
char modelname[MAX_OSPATH];
model_t *model;
} player_model_t;
// the client_t structure is wiped completely at every
// server map change
typedef struct
@ -191,6 +198,7 @@ typedef struct
float timedelta; // floating delta between two updates
char serverinfo[MAX_SERVERINFO_STRING];
player_model_t player_models[MAX_CLIENTS]; // cache of player models
player_info_t players[MAX_CLIENTS]; // collected info about all other players include himself
event_state_t events;
@ -799,6 +807,7 @@ void CL_SetupPMove( playermove_t *pmove, local_state_t *from, usercmd_t *ucmd, q
pmtrace_t CL_VisTraceLine( vec3_t start, vec3_t end, int flags );
pmtrace_t CL_TraceLine( vec3_t start, vec3_t end, int flags );
void CL_MoveSpectatorCamera( void );
qboolean CL_LocalWeapons( void );
void CL_SetLastUpdate( void );
void CL_RedoPrediction( void );
void CL_ClearPhysEnts( void );

View File

@ -1224,16 +1224,19 @@ void R_BeamDraw( BEAM *pbeam, float frametime )
switch( pbeam->type )
{
case TE_BEAMTORUS:
GL_Cull( GL_NONE );
TriBegin( TRI_TRIANGLE_STRIP );
R_DrawTorus( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments );
TriEnd();
break;
case TE_BEAMDISK:
GL_Cull( GL_NONE );
TriBegin( TRI_TRIANGLE_STRIP );
R_DrawDisk( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments );
TriEnd();
break;
case TE_BEAMCYLINDER:
GL_Cull( GL_NONE );
TriBegin( TRI_TRIANGLE_STRIP );
R_DrawCylinder( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments );
TriEnd();
@ -1249,11 +1252,14 @@ void R_BeamDraw( BEAM *pbeam, float frametime )
TriEnd();
break;
case TE_BEAMRING:
GL_Cull( GL_NONE );
TriBegin( TRI_TRIANGLE_STRIP );
R_DrawRing( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments );
TriEnd();
break;
}
GL_Cull( GL_FRONT );
}
/*
@ -1323,7 +1329,7 @@ void R_BeamDrawCustomEntity( cl_entity_t *ent )
SetBits( beam.flags, FBEAM_SHADEOUT );
// draw it
R_BeamDraw( &beam, cl.time - cl.oldtime );
R_BeamDraw( &beam, tr.frametime );
}
/*
@ -1512,6 +1518,8 @@ void CL_DrawBeams( int fTrans )
if( !cl_draw_beams->value )
return;
pglShadeModel( GL_SMOOTH );
// server beams don't allocate beam chains
// all params are stored in cl_entity_t
@ -1532,9 +1540,6 @@ void CL_DrawBeams( int fTrans )
RI.currentbeam = NULL;
if( !cl_active_beams )
return;
// draw temporary entity beams
for( pBeam = cl_active_beams; pBeam; pBeam = pNext )
{
@ -1565,6 +1570,8 @@ void CL_DrawBeams( int fTrans )
r_stats.c_view_beams_count++;
pPrev = pBeam;
}
pglShadeModel( GL_FLAT );
}
/*

View File

@ -258,6 +258,8 @@ void R_Set2DMode( qboolean enable )
pglDepthMask( GL_FALSE );
pglDisable( GL_DEPTH_TEST );
pglEnable( GL_ALPHA_TEST );
pglAlphaFunc( GL_NOTEQUAL, 0.0f );
pglColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
glState.in2DMode = true;

View File

@ -48,7 +48,7 @@ extern byte *r_temppool;
#define RP_NONVIEWERREF (RP_MIRRORVIEW|RP_ENVVIEW)
#define R_StudioOpaque( rm ) ( rm == kRenderNormal || rm == kRenderTransAlpha )
#define RP_LOCALCLIENT( e ) ((e)->index == ( cl.playernum + 1 ) && e->player )
#define RP_LOCALCLIENT( e ) ((e) != NULL && (e)->index == ( cl.playernum + 1 ) && e->player )
#define RP_NORMALPASS() ((RI.params & RP_NONVIEWERREF) == 0 )
#define TF_SKY (TF_SKYSIDE|TF_UNCOMPRESSED|TF_NOMIPMAP|TF_NOPICMIP)
@ -192,12 +192,10 @@ typedef struct
gl_entity_t mirror_entities[MAX_VISIBLE_PACKET]; // an entities that has mirror
cl_entity_t *solid_entities[MAX_VISIBLE_PACKET]; // opaque moving or alpha brushes
cl_entity_t *trans_entities[MAX_VISIBLE_PACKET]; // translucent brushes
cl_entity_t *child_entities[MAX_VISIBLE_PACKET]; // entities with MOVETYPE_FOLLOW
uint num_static_entities;
uint num_mirror_entities;
uint num_solid_entities;
uint num_trans_entities;
uint num_child_entities;
// OpenGL matrix states
qboolean modelviewIdentity;
@ -245,7 +243,7 @@ extern mleaf_t *r_viewleaf, *r_oldviewleaf;
extern mleaf_t *r_viewleaf2, *r_oldviewleaf2;
extern dlight_t cl_dlights[MAX_DLIGHTS];
extern dlight_t cl_elights[MAX_ELIGHTS];
#define r_numEntities (tr.num_solid_entities + tr.num_trans_entities + tr.num_child_entities + tr.num_static_entities)
#define r_numEntities (tr.num_solid_entities + tr.num_trans_entities + tr.num_static_entities)
#define r_numStatics (r_stats.c_client_ents)
extern struct beam_s *cl_active_beams;
@ -418,6 +416,7 @@ void R_DrawSpriteModel( cl_entity_t *e );
void R_StudioInit( void );
void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded );
void R_StudioLerpMovement( cl_entity_t *e, double time, vec3_t origin, vec3_t angles );
float CL_GetSequenceDuration( cl_entity_t *ent, int sequence );
struct mstudiotex_s *R_StudioGetTexture( cl_entity_t *e );
float CL_GetStudioEstimatedFrame( cl_entity_t *ent );
void R_DrawStudioModel( cl_entity_t *e );

View File

@ -276,14 +276,13 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
// check for impact on this node
surf = model->surfaces + node->firstsurface;
sample_size = Mod_SampleSizeForFace( surf );
VectorCopy( mid, g_trace_lightspot );
for( i = 0; i < node->numsurfaces; i++, surf++ )
{
tex = surf->texinfo;
if( surf->flags & ( SURF_DRAWSKY|SURF_DRAWTURB ))
if( FBitSet( surf->flags, SURF_DRAWTILED ))
continue; // no lightmaps
s = DotProduct( mid, tex->vecs[0] ) + tex->vecs[0][3] - surf->texturemins[0];
@ -292,14 +291,15 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
if(( s < 0 || s > surf->extents[0] ) || ( t < 0 || t > surf->extents[1] ))
continue;
s /= sample_size;
t /= sample_size;
cv->r = cv->g = cv->b = cv->a = 0;
if( !surf->samples )
return true;
sample_size = Mod_SampleSizeForFace( surf );
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);
g_trace_fraction = midf;

View File

@ -77,28 +77,6 @@ static qboolean R_StaticEntity( cl_entity_t *ent )
return true;
}
/*
===============
R_FollowEntity
Follow entity is attached to another studiomodel and used last cached bones
from parent
===============
*/
static qboolean R_FollowEntity( cl_entity_t *ent )
{
if( ent->model->type != mod_studio )
return false;
if( ent->curstate.movetype != MOVETYPE_FOLLOW )
return false;
if( ent->curstate.aiment <= 0 )
return false;
return true;
}
/*
===============
R_OpaqueEntity
@ -264,7 +242,7 @@ void R_ClearScene( void )
{
tr.num_solid_entities = tr.num_trans_entities = 0;
tr.num_static_entities = tr.num_mirror_entities = 0;
tr.num_child_entities = cl.num_custombeams = 0;
cl.num_custombeams = 0;
}
/*
@ -289,18 +267,6 @@ qboolean R_AddEntity( struct cl_entity_s *clent, int type )
if( type == ET_FRAGMENTED )
r_stats.c_client_ents++;
if( R_FollowEntity( clent ))
{
// follow entity
if( tr.num_child_entities >= MAX_VISIBLE_PACKET )
return false;
tr.child_entities[tr.num_child_entities] = clent;
tr.num_child_entities++;
return true;
}
if( R_OpaqueEntity( clent ))
{
if( R_StaticEntity( clent ))
@ -331,6 +297,7 @@ qboolean R_AddEntity( struct cl_entity_s *clent, int type )
tr.trans_entities[tr.num_trans_entities] = clent;
tr.num_trans_entities++;
}
return true;
}
@ -634,9 +601,6 @@ static void R_SetupFrame( void )
// setup viewplane dist
RI.viewplanedist = DotProduct( RI.vieworg, RI.vforward );
// prepare events for viewmodel (e.g. muzzleflashes)
R_RunViewmodelEvents();
// sort opaque entities by model type to avoid drawing model shadows under alpha-surfaces
qsort( tr.solid_entities, tr.num_solid_entities, sizeof( cl_entity_t* ), R_SolidEntityCompare );
@ -1063,6 +1027,9 @@ some type of screenshots
*/
qboolean R_DoResetGamma( void )
{
// FIXME: this looks ugly. apply the backward gamma changes to the output image
return false;
switch( cls.scrshot_action )
{
case scrshot_normal:
@ -1196,6 +1163,9 @@ void R_RenderFrame( const ref_viewpass_t *rvp )
}
}
R_RunViewmodelEvents();
tr.realframecount++; // right called after viewmodel events
if( gl_allow_mirrors->value )
{
// render mirrors

View File

@ -219,16 +219,12 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui
// install palette
switch( psprite->texFormat )
{
case SPR_ADDITIVE:
pal = FS_LoadImage( "#normal.pal", src, 768 );
break;
case SPR_INDEXALPHA:
pal = FS_LoadImage( "#decal.pal", src, 768 );
pal = FS_LoadImage( "#gradient.pal", src, 768 );
break;
case SPR_ALPHTEST:
pal = FS_LoadImage( "#transparent.pal", src, 768 );
pal = FS_LoadImage( "#masked.pal", src, 768 );
break;
case SPR_NORMAL:
default:
pal = FS_LoadImage( "#normal.pal", src, 768 );
break;
@ -746,7 +742,7 @@ R_GlowSightDistance
Set sprite brightness factor
================
*/
static float R_SpriteGlowBlend( vec3_t origin, int rendermode, int renderfx, int alpha, float *pscale )
static float R_SpriteGlowBlend( vec3_t origin, int rendermode, int renderfx, float *pscale )
{
float dist, brightness;
vec3_t glowDist;
@ -764,7 +760,7 @@ static float R_SpriteGlowBlend( vec3_t origin, int rendermode, int renderfx, int
}
if( renderfx == kRenderFxNoDissipation )
return (float)alpha * (1.0f / 255.0f);
return 1.0f;
brightness = GLARE_FALLOFF / ( dist * dist );
brightness = bound( 0.05f, brightness, 1.0f );
@ -782,11 +778,11 @@ R_SpriteOccluded
Do occlusion test for glow-sprites
================
*/
qboolean R_SpriteOccluded( cl_entity_t *e, vec3_t origin, int *alpha, float *pscale )
qboolean R_SpriteOccluded( cl_entity_t *e, vec3_t origin, float *pscale )
{
if( e->curstate.rendermode == kRenderGlow || e->curstate.rendermode == kRenderWorldGlow )
{
float blend = 1.0f;
float blend;
vec3_t v;
// don't reflect this entity in mirrors
@ -804,8 +800,8 @@ qboolean R_SpriteOccluded( cl_entity_t *e, vec3_t origin, int *alpha, float *psc
if( v[1] < RI.viewport[1] || v[1] > RI.viewport[1] + RI.viewport[3] )
return true; // do scissor
blend *= R_SpriteGlowBlend( origin, e->curstate.rendermode, e->curstate.renderfx, *alpha, pscale );
*alpha *= blend;
blend = R_SpriteGlowBlend( origin, e->curstate.rendermode, e->curstate.renderfx, pscale );
tr.blend *= blend;
if( blend <= 0.01f )
return true; // faded
@ -887,8 +883,8 @@ void R_DrawSpriteModel( cl_entity_t *e )
mspriteframe_t *frame, *oldframe;
msprite_t *psprite;
model_t *model;
int i, alpha, type;
float angle, dot, sr, cr, flAlpha;
int i, type;
float angle, dot, sr, cr;
float lerp = 1.0f, ilerp, scale;
vec3_t v_forward, v_right, v_up;
vec3_t origin, color, color2;
@ -918,11 +914,10 @@ void R_DrawSpriteModel( cl_entity_t *e )
}
}
alpha = e->curstate.renderamt;
scale = e->curstate.scale;
if( !scale ) scale = 1.0f;
if( R_SpriteOccluded( e, origin, &alpha, &scale ))
if( R_SpriteOccluded( e, origin, &scale ))
return; // sprite culled
r_stats.c_sprite_models_drawn++;
@ -1044,15 +1039,13 @@ void R_DrawSpriteModel( cl_entity_t *e )
break;
}
flAlpha = (float)alpha * ( 1.0f / 255.0f );
if( psprite->facecull == SPR_CULL_NONE )
GL_Cull( GL_NONE );
if( oldframe == frame )
{
// draw the single non-lerped frame
pglColor4f( color[0], color[1], color[2], flAlpha );
pglColor4f( color[0], color[1], color[2], tr.blend );
GL_Bind( GL_TEXTURE0, frame->gl_texturenum );
R_DrawSpriteQuad( frame, origin, v_right, v_up, scale );
}
@ -1064,14 +1057,14 @@ void R_DrawSpriteModel( cl_entity_t *e )
if( ilerp != 0.0f )
{
pglColor4f( color[0], color[1], color[2], flAlpha * ilerp );
pglColor4f( color[0], color[1], color[2], tr.blend * ilerp );
GL_Bind( GL_TEXTURE0, oldframe->gl_texturenum );
R_DrawSpriteQuad( oldframe, origin, v_right, v_up, scale );
}
if( lerp != 0.0f )
{
pglColor4f( color[0], color[1], color[2], flAlpha * lerp );
pglColor4f( color[0], color[1], color[2], tr.blend * lerp );
GL_Bind( GL_TEXTURE0, frame->gl_texturenum );
R_DrawSpriteQuad( frame, origin, v_right, v_up, scale );
}
@ -1086,7 +1079,7 @@ void R_DrawSpriteModel( cl_entity_t *e )
pglBlendFunc( GL_ZERO, GL_SRC_COLOR );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
pglColor4f( color2[0], color2[1], color2[2], flAlpha );
pglColor4f( color2[0], color2[1], color2[2], tr.blend );
GL_Bind( GL_TEXTURE0, tr.whiteTexture );
R_DrawSpriteQuad( frame, origin, v_right, v_up, scale );

View File

@ -27,6 +27,9 @@ GNU General Public License for more details.
#define EVENT_CLIENT 5000 // less than this value it's a server-side studio events
#define MAX_LOCALLIGHTS 4
CVAR_DEFINE_AUTO( r_glowshellfreq, "2.2", 0, "glowing shell frequency update" );
CVAR_DEFINE_AUTO( r_shadows, "0", 0, "enable shadows from studiomodels" );
static vec3_t hullcolor[8] =
{
{ 1.0f, 1.0f, 1.0f },
@ -99,8 +102,6 @@ typedef struct
float locallightR2[MAX_LOCALLIGHTS];
} studio_draw_state_t;
CVAR_DEFINE_AUTO( r_shadows, "0", 0, "enable shadows from studiomodels" );
// studio-related cvars
convar_t *r_studio_lambert;
convar_t *r_studio_sort_textures;
@ -132,10 +133,12 @@ void R_StudioInit( void )
{
r_studio_lambert = Cvar_Get( "r_studio_lambert", "2", FCVAR_ARCHIVE, "bonelighting lambert value" );
cl_himodels = Cvar_Get( "cl_himodels", "1", FCVAR_ARCHIVE, "draw high-resolution player models in multiplayer" );
r_studio_sort_textures = Cvar_Get( "r_studio_sort_textures", "0", FCVAR_ARCHIVE, "sort additive and normal textures for right drawing" );
r_studio_sort_textures = Cvar_Get( "r_studio_sort_textures", "0", FCVAR_ARCHIVE, "change draw order for additive meshes" );
r_drawviewmodel = Cvar_Get( "r_drawviewmodel", "1", 0, "draw firstperson weapon model" );
Matrix3x4_LoadIdentity( g_studio.rotationmatrix );
Cvar_RegisterVariable( &r_glowshellfreq );
// Cvar_RegisterVariable( &r_shadows );
g_studio.interpolate = true;
g_studio.framecount = 0;
@ -234,23 +237,23 @@ R_StudioComputeBBox
Compute a full bounding box for current sequence
================
*/
static qboolean R_StudioComputeBBox( cl_entity_t *e, vec3_t bbox[8] )
static qboolean R_StudioComputeBBox( vec3_t bbox[8] )
{
studiohdr_t *pstudiohdr = (studiohdr_t *)Mod_Extradata( e->model );
vec3_t studio_mins, studio_maxs;
vec3_t mins, maxs, p1, p2;
cl_entity_t *e = RI.currententity;
mstudioseqdesc_t *pseqdesc;
int i;
if( !pstudiohdr )
if( !m_pStudioHeader )
return false;
// check if we have valid mins\maxs
if( !VectorCompare( vec3_origin, e->model->mins ))
if( !VectorCompare( vec3_origin, RI.currentmodel->mins ))
{
// clipping bounding box
VectorCopy( e->model->mins, mins );
VectorCopy( e->model->maxs, maxs );
VectorCopy( RI.currentmodel->mins, mins );
VectorCopy( RI.currentmodel->maxs, maxs );
}
else
{
@ -258,10 +261,10 @@ static qboolean R_StudioComputeBBox( cl_entity_t *e, vec3_t bbox[8] )
}
// check sequence range
if( e->curstate.sequence < 0 || e->curstate.sequence >= pstudiohdr->numseq )
if( e->curstate.sequence < 0 || e->curstate.sequence >= m_pStudioHeader->numseq )
e->curstate.sequence = 0;
pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + e->curstate.sequence;
pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + e->curstate.sequence;
// add sequence box to the model box
AddPointToBounds( pseqdesc->bbmin, mins, maxs );
@ -348,7 +351,7 @@ pfnGetEngineTimes
*/
static void pfnGetEngineTimes( int *framecount, double *current, double *old )
{
if( framecount ) *framecount = tr.framecount;
if( framecount ) *framecount = tr.realframecount;
if( current ) *current = g_studio.time;
if( old ) *old = g_studio.time - g_studio.frametime;
}
@ -625,6 +628,34 @@ float CL_GetStudioEstimatedFrame( cl_entity_t *ent )
return 0;
}
/*
====================
CL_GetSequenceDuration
====================
*/
float CL_GetSequenceDuration( cl_entity_t *ent, int sequence )
{
studiohdr_t *pstudiohdr;
mstudioseqdesc_t *pseqdesc;
if( ent->model != NULL && ent->model->type == mod_studio )
{
pstudiohdr = (studiohdr_t *)Mod_Extradata( ent->model );
if( pstudiohdr )
{
sequence = bound( 0, sequence, pstudiohdr->numseq - 1 );
pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + sequence;
if( pseqdesc->numframes > 1 && pseqdesc->fps > 0 )
return (float)pseqdesc->numframes / (float)pseqdesc->fps;
}
}
return 0.1f;
}
/*
====================
StudioGetAnim
@ -1112,7 +1143,7 @@ void R_StudioSetupBones( cl_entity_t *e )
f = R_StudioEstimateFrame( e, pseqdesc );
panim = R_StudioGetAnim( m_pStudioHeader, e->model, pseqdesc );
panim = R_StudioGetAnim( m_pStudioHeader, RI.currentmodel, pseqdesc );
R_StudioCalcRotations( e, pos, q, pseqdesc, panim, f );
if( pseqdesc->numblends > 1 )
@ -1152,7 +1183,7 @@ void R_StudioSetupBones( cl_entity_t *e )
float s;
pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + e->latched.prevsequence;
panim = R_StudioGetAnim( m_pStudioHeader, e->model, pseqdesc );
panim = R_StudioGetAnim( m_pStudioHeader, RI.currentmodel, pseqdesc );
// clip prevframe
R_StudioCalcRotations( e, pos1b, q1b, pseqdesc, panim, e->latched.prevframe );
@ -1202,7 +1233,7 @@ void R_StudioSetupBones( cl_entity_t *e )
pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + m_pPlayerInfo->gaitsequence;
panim = R_StudioGetAnim( m_pStudioHeader, e->model, pseqdesc );
panim = R_StudioGetAnim( m_pStudioHeader, RI.currentmodel, pseqdesc );
R_StudioCalcRotations( e, pos2, q2, pseqdesc, panim, m_pPlayerInfo->gaitframe );
for( i = 0; i < m_pStudioHeader->numbones; i++ )
@ -1270,6 +1301,7 @@ NOTE: m_pSubModel must be set
*/
void R_StudioBuildNormalTable( void )
{
cl_entity_t *e = RI.currententity;
mstudiomesh_t *pmesh;
int i, j;
@ -1300,6 +1332,14 @@ void R_StudioBuildNormalTable( void )
}
}
}
g_studio.chrome_origin[0] = cos( r_glowshellfreq.value * g_studio.time ) * 4000.0f;
g_studio.chrome_origin[1] = sin( r_glowshellfreq.value * g_studio.time ) * 4000.0f;
g_studio.chrome_origin[2] = cos( r_glowshellfreq.value * g_studio.time * 0.33f ) * 4000.0f;
if( e->curstate.rendercolor.r || e->curstate.rendercolor.g || e->curstate.rendercolor.b )
TriColor4ub( e->curstate.rendercolor.r, e->curstate.rendercolor.g, e->curstate.rendercolor.b, 255 );
else TriColor4ub( 255, 255, 255, 255 );
}
/*
@ -1422,23 +1462,10 @@ void R_StudioSetupChrome( float *pchrome, int bone, vec3_t normal )
tmp[2] += g_studio.bonestransform[bone][2][3];
VectorNormalize( tmp );
if( g_nForceFaceFlags & STUDIO_NF_CHROME )
{
float sr, cr;
// g-cont. rotate texture for glowshell effect
SinCos( DEG2RAD( g_studio.time * 40 ), &sr, &cr );
VectorMAMAM( -cr, RI.vright, sr, RI.vup, 0.0f, vec3_origin, chromerightvec );
VectorMAMAM( sr, RI.vright, cr, RI.vup, 0.0f, vec3_origin, chromeupvec );
}
else
{
CrossProduct( tmp, RI.vright, chromeupvec );
VectorNormalize( chromeupvec );
CrossProduct( tmp, chromeupvec, chromerightvec );
VectorNormalize( chromerightvec );
}
CrossProduct( tmp, RI.vright, chromeupvec );
VectorNormalize( chromeupvec );
CrossProduct( tmp, chromeupvec, chromerightvec );
VectorNormalize( chromerightvec );
Matrix3x4_VectorIRotate( g_studio.bonestransform[bone], chromeupvec, g_studio.chromeup[bone] );
Matrix3x4_VectorIRotate( g_studio.bonestransform[bone], chromerightvec, g_studio.chromeright[bone] );
@ -1527,12 +1554,10 @@ R_StudioCheckBBox
*/
static int R_StudioCheckBBox( void )
{
cl_entity_t *e = RI.currententity;
if( !e || !e->model || !e->model->cache.data )
if( !RI.currententity || !RI.currentmodel )
return false;
return R_StudioComputeBBox( e, NULL );
return R_StudioComputeBBox( NULL );
}
/*
@ -1570,7 +1595,14 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight )
else VectorSet( lightDir, 0.0f, 0.0f, -1.0f );
if( ent == RI.currententity )
Matrix3x4_OriginFromMatrix( g_studio.rotationmatrix, origin );
{
int sequence = bound( 0, ent->curstate.sequence, m_pStudioHeader->numseq - 1 );
mstudioseqdesc_t *pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + sequence;
if( !FBitSet( pseqdesc->flags, STUDIO_LOOPING ) && !pseqdesc->activity )
Matrix3x4_OriginFromMatrix( g_studio.lighttransform[0], origin );
else Matrix3x4_OriginFromMatrix( g_studio.rotationmatrix, origin );
}
else VectorCopy( ent->origin, origin );
VectorSet( vecSrc, origin[0], origin[1], origin[2] - lightDir[2] * 8.0f );
@ -1578,7 +1610,8 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight )
if(( mv->skycolor_r + mv->skycolor_g + mv->skycolor_b ) != 0 )
{
msurface_t *psurf;
msurface_t *psurf = NULL;
pmtrace_t trace;
if( FBitSet( host.features, ENGINE_WRITE_LARGE_COORD ))
{
@ -1593,8 +1626,10 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight )
vecEnd[2] = origin[2] - mv->skyvec_z * 8192.0f;
}
psurf = PM_TraceSurface( clgame.pmove->physents, vecSrc, vecEnd );
trace = CL_TraceLine( vecSrc, vecEnd, PM_STUDIO_IGNORE );
if( trace.ent > 0 ) psurf = PM_TraceSurface( &clgame.pmove->physents[trace.ent], vecSrc, vecEnd );
else psurf = PM_TraceSurface( clgame.pmove->physents, vecSrc, vecEnd );
if( FBitSet( ent->model->flags, STUDIO_FORCE_SKYLIGHT ) || ( psurf && FBitSet( psurf->flags, SURF_DRAWSKY )))
{
VectorSet( lightDir, mv->skyvec_x, mv->skyvec_y, mv->skyvec_z );
@ -1615,9 +1650,6 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight )
light = R_LightVec( vecSrc, vecEnd, g_studio.lightspot );
// NOTE: we can't compute fake direction with using root bone origin
// because bone may some fluctuating and this looks ugly
Matrix3x4_OriginFromMatrix( g_studio.rotationmatrix, vecSrc );
VectorScale( lightDir, 2048.0f, vecEnd );
VectorAdd( vecEnd, vecSrc, vecEnd );
@ -2233,10 +2265,7 @@ static void R_StudioDrawPoints( void )
// generate shared normals for properly scaling glowing shell
if( RI.currententity->curstate.renderfx == kRenderFxGlowShell )
{
color24 *clr = &RI.currententity->curstate.rendercolor;
shellscale = RI.currententity->curstate.renderamt * (1.0f / 255.0f);
pglColor4ub( clr->r, clr->g, clr->b, 255 );
shellscale = RI.currententity->curstate.renderamt * (1.0f/255.0f);
R_StudioBuildNormalTable();
R_StudioGenerateNormals();
}
@ -2281,12 +2310,8 @@ static void R_StudioDrawPoints( void )
g_nFaceFlags = ptexture[pskinref[pmesh->skinref]].flags | g_nForceFaceFlags;
if( RI.currententity->curstate.renderfx != kRenderFxGlowShell )
{
s = 1.0f / (float)ptexture[pskinref[pmesh->skinref]].width;
t = 1.0f / (float)ptexture[pskinref[pmesh->skinref]].height;
}
else s = t = (1.0f / 256.0f);
s = 1.0f / (float)ptexture[pskinref[pmesh->skinref]].width;
t = 1.0f / (float)ptexture[pskinref[pmesh->skinref]].height;
if( FBitSet( g_nFaceFlags, STUDIO_NF_MASKED ))
{
@ -2311,6 +2336,7 @@ static void R_StudioDrawPoints( void )
if( FBitSet( g_nFaceFlags, STUDIO_NF_MASKED ))
{
pglAlphaFunc( GL_NOTEQUAL, 0.0f );
pglDisable( GL_ALPHA_TEST );
}
else if( FBitSet( g_nFaceFlags, STUDIO_NF_ADDITIVE ) && R_StudioOpaque( RI.currententity->curstate.rendermode ))
@ -2339,7 +2365,8 @@ static void R_StudioDrawHulls( void )
alpha = 0.5f;
else alpha = 1.0f;
pglDisable( GL_TEXTURE_2D );
GL_Bind( GL_TEXTURE0, tr.whiteTexture );
pglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
for( i = 0; i < m_pStudioHeader->numhitboxes; i++ )
{
@ -2374,8 +2401,6 @@ static void R_StudioDrawHulls( void )
}
TriEnd();
}
pglEnable( GL_TEXTURE_2D );
}
/*
@ -2394,10 +2419,10 @@ static void R_StudioDrawAbsBBox( void )
if( RI.currententity == &clgame.viewent )
return;
if( !R_StudioComputeBBox( RI.currententity, p ))
if( !R_StudioComputeBBox( p ))
return;
pglDisable( GL_TEXTURE_2D );
GL_Bind( GL_TEXTURE0, tr.whiteTexture );
TriColor4f( 0.5f, 0.5f, 1.0f, 0.5f );
TriRenderMode( kRenderTransAdd );
@ -2415,8 +2440,6 @@ static void R_StudioDrawAbsBBox( void )
TriVertex3fv( p[boxpnt[i][3]] );
}
TriEnd();
pglEnable( GL_TEXTURE_2D );
}
/*
@ -2528,19 +2551,6 @@ R_StudioSetRemapColors
*/
void R_StudioSetRemapColors( int newTop, int newBottom )
{
// update colors for viewentity
if( RI.currententity == &clgame.viewent )
{
player_info_t *pLocalPlayer;
// copy top and bottom colors for viewmodel
if(( pLocalPlayer = pfnPlayerInfo( clgame.viewent.curstate.number - 1 )) != NULL )
{
newTop = bound( 0, pLocalPlayer->topcolor, 360 );
newBottom = bound( 0, pLocalPlayer->bottomcolor, 360 );
}
}
CL_AllocRemapInfo( newTop, newBottom );
if( CL_GetRemapInfoForEntity( RI.currententity ))
@ -2559,7 +2569,7 @@ R_StudioSetupPlayerModel
static model_t *R_StudioSetupPlayerModel( int index )
{
player_info_t *info;
string modelpath;
player_model_t *state;
if( !RI.drawWorld )
{
@ -2568,31 +2578,38 @@ static model_t *R_StudioSetupPlayerModel( int index )
}
else
{
if( index < 0 || index > cl.maxclients )
if( index < 0 || index >= cl.maxclients )
return NULL; // bad client ?
info = &cl.players[index];
}
// set to invisible, skip
if( !info->model[0] ) return NULL;
state = &cl.player_models[index];
if( !Q_stricmp( info->model, "player" ))
if(( host.developer || !Host_IsLocalGame( )) && info->model[0] )
{
Q_strncpy( modelpath, "models/player.mdl", sizeof( modelpath ));
if( Q_strcmp( state->name, info->model ))
{
Q_strncpy( state->name, info->model, sizeof( state->name ));
state->name[sizeof( state->name ) - 1] = 0;
Q_snprintf( state->modelname, sizeof( state->modelname ), "models/player/%s/%s.mdl", info->model, info->model );
if( FS_FileExists( state->modelname, false ))
state->model = Mod_ForName( state->modelname, false );
else state->model = NULL;
if( !state->model )
state->model = RI.currententity->model;
}
}
else
{
Q_snprintf( modelpath, sizeof( modelpath ), "models/player/%s/%s.mdl", info->model, info->model );
// replace with default if missed
if( !FS_FileExists( modelpath, false ))
Q_strncpy( modelpath, "models/player.mdl", sizeof( modelpath ));
if( state->model != RI.currententity->model )
state->model = RI.currententity->model;
state->name[0] = 0;
}
if( !FS_FileExists( modelpath, false ))
return NULL;
return Mod_ForName( modelpath, false );
return state->model;
}
/*
@ -2707,10 +2724,10 @@ R_StudioSetupRenderer
*/
static void R_StudioSetupRenderer( int rendermode )
{
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
g_studio.rendermode = bound( 0, rendermode, kRenderTransAdd );
if( clgame.ds.cullMode != GL_NONE ) GL_Cull( GL_FRONT );
pglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
pglShadeModel( GL_SMOOTH );
}
@ -2727,7 +2744,6 @@ static void R_StudioRestoreRenderer( void )
if( g_studio.rendermode != kRenderNormal )
pglDisable( GL_BLEND );
m_fDoRemap = false;
}
@ -2830,6 +2846,7 @@ void GL_StudioSetRenderMode( int rendermode )
switch( rendermode )
{
case kRenderNormal:
pglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
break;
case kRenderTransColor:
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
@ -2839,7 +2856,7 @@ void GL_StudioSetRenderMode( int rendermode )
case kRenderTransAdd:
pglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
pglColor4f( tr.blend, tr.blend, tr.blend, 1.0f );
pglBlendFunc( GL_ONE, GL_ONE );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE );
pglDepthMask( GL_FALSE );
pglEnable( GL_BLEND );
break;
@ -2862,46 +2879,25 @@ NOTE: this code sucessfully working with ShadowHack only in Release build
*/
static void GL_StudioDrawShadow( void )
{
int rendermode;
float shadow_alpha;
float shadow_alpha2;
GLenum depthmode;
GLenum depthmode2;
pglDepthMask( GL_TRUE );
if( r_shadows.value != 0.0f )
if( r_shadows.value && g_studio.rendermode != kRenderTransAdd && !FBitSet( RI.currentmodel->flags, STUDIO_AMBIENT_LIGHT ))
{
if( RI.currententity->baseline.movetype != MOVETYPE_FLY )
{
rendermode = RI.currententity->baseline.rendermode;
float color = 1.0 - (tr.blend * 0.5);
if( rendermode == kRenderNormal && RI.currententity != &clgame.viewent )
{
shadow_alpha = 1.0f - (tr.blend * 0.5f);
pglDisable( GL_TEXTURE_2D );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
pglEnable( GL_BLEND );
pglShadeModel( GL_FLAT );
shadow_alpha2 = 1.0f - shadow_alpha;
pglDisable( GL_TEXTURE_2D );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
pglEnable( GL_BLEND );
pglColor4f( 0.0f, 0.0f, 0.0f, 1.0f - color );
pglColor4f( 0.0f, 0.0f, 0.0f, shadow_alpha2 );
pglDepthFunc( GL_LESS );
R_StudioDrawPointsShadow();
pglDepthFunc( GL_LEQUAL );
depthmode = GL_LESS;
pglDepthFunc( depthmode );
R_StudioDrawPointsShadow();
depthmode2 = GL_LEQUAL;
pglDepthFunc( depthmode2 );
pglEnable( GL_TEXTURE_2D );
pglDisable( GL_BLEND );
pglColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
pglShadeModel( GL_SMOOTH );
}
}
pglEnable( GL_TEXTURE_2D );
pglDisable( GL_BLEND );
pglColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
pglShadeModel( GL_SMOOTH );
}
}
@ -3000,7 +2996,7 @@ void R_StudioEstimateGait( entity_state_t *pplayer )
dt = bound( 0.0f, g_studio.frametime, 1.0f );
if( dt == 0.0f || m_pPlayerInfo->renderframe == tr.framecount )
if( dt == 0.0f || m_pPlayerInfo->renderframe == tr.realframecount )
{
m_flGaitMovement = 0;
return;
@ -3190,7 +3186,7 @@ static int R_StudioDrawPlayer( int flags, entity_state_t *pplayer )
R_StudioSetupBones( RI.currententity );
R_StudioSaveBones( );
m_pPlayerInfo->renderframe = tr.framecount;
m_pPlayerInfo->renderframe = tr.realframecount;
m_pPlayerInfo = NULL;
if( flags & STUDIO_EVENTS )
@ -3360,58 +3356,24 @@ static int R_StudioDrawModel( int flags )
/*
=================
R_DrawStudioModel
R_StudioDrawModelInternal
=================
*/
void R_DrawStudioModelInternal( cl_entity_t *e, qboolean follow_entity )
void R_StudioDrawModelInternal( cl_entity_t *e, int flags )
{
int i, flags, result;
if( RI.params & RP_ENVVIEW )
return;
if( !Mod_Extradata( e->model ))
return;
ASSERT( pStudioDraw != NULL );
if( e == &clgame.viewent )
flags = STUDIO_RENDER;
else flags = STUDIO_RENDER|STUDIO_EVENTS;
R_StudioSetupTimings();
// prevent to crash some mods like HLFX in menu Customize
if( !RI.drawWorld )
{
if( e->player )
result = R_StudioDrawPlayer( flags, &e->curstate );
else result = R_StudioDrawModel( flags );
R_StudioDrawPlayer( flags, &e->curstate );
else R_StudioDrawModel( flags );
}
else
{
// select the properly method
if( e->player )
result = pStudioDraw->StudioDrawPlayer( flags, R_StudioGetPlayerState( e->index - 1 ));
else result = pStudioDraw->StudioDrawModel( flags );
pStudioDraw->StudioDrawPlayer( flags, R_StudioGetPlayerState( e->index - 1 ));
else pStudioDraw->StudioDrawModel( flags );
}
if( !result || follow_entity ) return;
// NOTE: we must draw all followed entities
// immediately after drawing parent when cached bones is valid
for( i = 0; i < tr.num_child_entities; i++ )
{
if( CL_GetEntityByIndex( tr.child_entities[i]->curstate.aiment ) == e )
{
// copy the parent origin for right frustum culling
VectorCopy( e->origin, tr.child_entities[i]->origin );
RI.currententity = tr.child_entities[i];
RI.currentmodel = RI.currententity->model;
R_DrawStudioModelInternal( RI.currententity, true );
}
}
}
/*
@ -3421,7 +3383,26 @@ R_DrawStudioModel
*/
void R_DrawStudioModel( cl_entity_t *e )
{
R_DrawStudioModelInternal( e, false );
if( FBitSet( RI.params, RP_ENVVIEW ))
return;
R_StudioSetupTimings();
if( e->player )
{
R_StudioDrawModelInternal( e, STUDIO_RENDER|STUDIO_EVENTS );
}
else
{
if( e->curstate.movetype == MOVETYPE_FOLLOW )
{
RI.currententity = CL_GetEntityByIndex( e->curstate.aiment );
R_StudioDrawModelInternal( RI.currententity, 0 );
RI.currententity = e;
}
R_StudioDrawModelInternal( e, STUDIO_RENDER|STUDIO_EVENTS );
}
}
/*
@ -3431,33 +3412,26 @@ R_RunViewmodelEvents
*/
void R_RunViewmodelEvents( void )
{
if( RI.onlyClientDraw || r_drawviewmodel->value == 0 )
int i;
if( cl.local.thirdperson || RI.onlyClientDraw || r_drawviewmodel->value == 0 )
return;
// ignore in thirdperson, camera view or client is died
if( cl.local.thirdperson || cl.local.health <= 0 || cl.viewentity != ( cl.playernum + 1 ))
return;
if( RI.params & RP_NONVIEWERREF )
return;
if( !Mod_Extradata( clgame.viewent.model ))
if( !RP_NORMALPASS() || cl.local.health <= 0 || cl.viewentity != ( cl.playernum + 1 ))
return;
RI.currententity = &clgame.viewent;
RI.currentmodel = RI.currententity->model;
if( !RI.currentmodel ) return;
if( !RI.currententity->model )
return;
R_StudioSetupTimings();
if( !cl.local.weaponstarttime ) cl.local.weaponstarttime = g_studio.time;
RI.currententity->curstate.animtime = cl.local.weaponstarttime;
RI.currententity->curstate.sequence = cl.local.weaponsequence;
for( i = 0; i < 4; i++ )
VectorCopy( cl.simorg, RI.currententity->attachment[i] );
pStudioDraw->StudioDrawModel( STUDIO_EVENTS );
RI.currententity = NULL;
RI.currentmodel = NULL;
R_StudioDrawModelInternal( RI.currententity, STUDIO_EVENTS );
}
/*
@ -3467,26 +3441,24 @@ R_DrawViewModel
*/
void R_DrawViewModel( void )
{
if( RI.onlyClientDraw || r_drawviewmodel->value == 0 )
cl_entity_t *view = &clgame.viewent;
if( cl.local.thirdperson || RI.onlyClientDraw || r_drawviewmodel->value == 0 )
return;
// ignore in thirdperson, camera view or client is died
if( cl.local.thirdperson || cl.local.health <= 0 || cl.viewentity != ( cl.playernum + 1 ))
if( !RP_NORMALPASS() || cl.local.health <= 0 || cl.viewentity != ( cl.playernum + 1 ))
return;
if( RI.params & RP_NONVIEWERREF )
tr.blend = CL_FxBlend( view ) / 255.0f;
if( !R_StudioOpaque( view->curstate.rendermode ) && tr.blend <= 0.0f )
return; // invisible ?
RI.currententity = view;
if( !RI.currententity->model )
return;
if( !Mod_Extradata( clgame.viewent.model ))
return;
tr.blend = CL_FxBlend( &clgame.viewent ) / 255.0f;
if( tr.blend <= 0.0f ) return; // invisible ?
RI.currententity = &clgame.viewent;
RI.currentmodel = RI.currententity->model;
if( !RI.currentmodel ) return;
R_StudioSetupTimings();
// hack the depth range to prevent view model from poking into walls
@ -3499,11 +3471,7 @@ void R_DrawViewModel( void )
g_studio.flipmodel = true;
}
if( !cl.local.weaponstarttime ) cl.local.weaponstarttime = g_studio.time;
RI.currententity->curstate.animtime = cl.local.weaponstarttime;
RI.currententity->curstate.sequence = cl.local.weaponsequence;
pStudioDraw->StudioDrawModel( STUDIO_RENDER );
R_StudioDrawModelInternal( RI.currententity, STUDIO_RENDER );
// restore depth range
pglDepthRange( gldepthmin, gldepthmax );
@ -3514,9 +3482,6 @@ void R_DrawViewModel( void )
GL_FrontFace( !glState.frontFace );
g_studio.flipmodel = false;
}
RI.currententity = NULL;
RI.currentmodel = NULL;
}
/*

View File

@ -510,6 +510,7 @@ void Host_GetCommands( void )
cmd = Con_Input();
if( cmd ) Cbuf_AddText( cmd );
Cbuf_Execute ();
}
/*
@ -604,8 +605,8 @@ void Host_Frame( float time )
return;
Host_InputFrame (); // input frame
Host_GetCommands (); // dedicated in
Host_ClientBegin (); // begin client
Host_GetCommands (); // dedicated in
Host_ServerFrame (); // server frame
Host_ClientFrame (); // client frame

View File

@ -257,10 +257,9 @@ typedef struct dds_s
enum
{
LUMP_NORMAL = 0,
LUMP_TRANSPARENT,
LUMP_DECAL,
LUMP_QFONT,
LUMP_NORMAL = 0, // no alpha
LUMP_MASKED, // 1-bit alpha channel masked texture
LUMP_GRADIENT, // gradient image (decals)
LUMP_EXTENDED // bmp images have extened palette with alpha-channel
};

View File

@ -299,7 +299,17 @@ void Image_SetPalette( const byte *pal, uint *d_table )
// setup palette
switch( image.d_rendermode )
{
case LUMP_DECAL:
case LUMP_NORMAL:
for( i = 0; i < 256; i++ )
{
rgba[0] = pal[i*3+0];
rgba[1] = pal[i*3+1];
rgba[2] = pal[i*3+2];
rgba[3] = 0xFF;
d_table[i] = *(uint *)rgba;
}
break;
case LUMP_GRADIENT:
for( i = 0; i < 256; i++ )
{
rgba[0] = pal[765];
@ -309,34 +319,18 @@ void Image_SetPalette( const byte *pal, uint *d_table )
d_table[i] = *(uint *)rgba;
}
break;
case LUMP_TRANSPARENT:
case LUMP_MASKED:
for( i = 0; i < 256; i++ )
{
rgba[0] = pal[i*3+0];
rgba[1] = pal[i*3+1];
rgba[2] = pal[i*3+2];
rgba[3] = pal[i] == 255 ? pal[i] : 0xFF;
d_table[i] = *(uint *)rgba;
}
break;
case LUMP_QFONT:
for( i = 0; i < 256; i++ )
{
rgba[0] = pal[i*3+0];
rgba[1] = pal[i*3+1];
rgba[2] = pal[i*3+2];
rgba[3] = 0xFF;
d_table[i] = *(uint *)rgba;
}
break;
case LUMP_NORMAL:
for( i = 0; i < 256; i++ )
{
rgba[0] = pal[i*3+0];
rgba[1] = pal[i*3+1];
rgba[2] = pal[i*3+2];
rgba[3] = 0xFF;
d_table[i] = *(uint *)rgba;
if( i != 255 )
{
rgba[0] = pal[i*3+0];
rgba[1] = pal[i*3+1];
rgba[2] = pal[i*3+2];
rgba[3] = 0xFF;
d_table[i] = *(uint *)rgba;
}
else d_table[i] = 0;
}
break;
case LUMP_EXTENDED:
@ -362,6 +356,7 @@ void Image_GetPaletteQ1( void )
d_8toQ1table[255] = 0; // 255 is transparent
q1palette_init = true;
}
image.d_currentpal = d_8toQ1table;
}
@ -372,9 +367,9 @@ void Image_GetPaletteHL( void )
if( !hlpalette_init )
{
Image_SetPalette( palette_hl, d_8toHLtable );
d_8toHLtable[255] = 0; // 255 is transparent
hlpalette_init = true;
}
image.d_currentpal = d_8toHLtable;
}
@ -396,15 +391,6 @@ void Image_GetPaletteLMP( const byte *pal, int rendermode )
if( pal )
{
Image_SetPalette( pal, d_8to24table );
if( rendermode != LUMP_DECAL )
d_8to24table[255] &= 0xFFFFFF;
image.d_currentpal = d_8to24table;
}
else if( rendermode == LUMP_QFONT )
{
// quake1 base palette and font palette have some diferences
Image_SetPalette( palette_q1, d_8to24table );
d_8to24table[0] = 0;
image.d_currentpal = d_8to24table;
}
else Image_GetPaletteHL(); // default half-life palette
@ -549,7 +535,7 @@ qboolean Image_Copy8bitRGBA( const byte *in, byte *out, int pixels )
{
int *iout = (int *)out;
byte *fin = (byte *)in;
rgba_t *col;
byte *col;
int i;
if( !image.d_currentpal )
@ -574,14 +560,26 @@ qboolean Image_Copy8bitRGBA( const byte *in, byte *out, int pixels )
// check for color
for( i = 0; i < 256; i++ )
{
col = (rgba_t *)&image.d_currentpal[i];
col = (byte *)&image.d_currentpal[i];
if( col[0] != col[1] || col[1] != col[2] )
{
image.flags |= IMAGE_HAS_COLOR;
break;
}
}
#if 0
for( i = 0; i < image.width * image.height; i++ )
{
col = (byte *)&image.d_currentpal[fin[i]];
*out++ = col[0];
*out++ = col[1];
*out++ = col[2];
if( image.d_rendermode == LUMP_GRADIENT )
*out++ = fin[i];
else *out++ = col[3];
}
#else
while( pixels >= 8 )
{
iout[0] = image.d_currentpal[in[0]];
@ -618,7 +616,7 @@ qboolean Image_Copy8bitRGBA( const byte *in, byte *out, int pixels )
if( pixels & 1 ) // last byte
iout[0] = image.d_currentpal[in[0]];
#endif
image.type = PF_RGBA_32; // update image type;
return true;
@ -1299,8 +1297,8 @@ qboolean Image_Decompress( const byte *data )
if( image.flags & IMAGE_HAS_ALPHA )
{
if( image.flags & IMAGE_COLORINDEX )
Image_GetPaletteLMP( image.palette, LUMP_DECAL );
else Image_GetPaletteLMP( image.palette, LUMP_TRANSPARENT );
Image_GetPaletteLMP( image.palette, LUMP_GRADIENT );
else Image_GetPaletteLMP( image.palette, LUMP_MASKED );
}
else Image_GetPaletteLMP( image.palette, LUMP_NORMAL );
// intentional falltrough

View File

@ -40,12 +40,10 @@ qboolean Image_LoadPAL( const char *name, const byte *buffer, size_t filesize )
// using palette name as rendermode
if( Q_stristr( name, "normal" ))
rendermode = LUMP_NORMAL;
else if( Q_stristr( name, "transparent" ))
rendermode = LUMP_TRANSPARENT;
else if( Q_stristr( name, "decal" ))
rendermode = LUMP_DECAL;
else if( Q_stristr( name, "qfont" ))
rendermode = LUMP_QFONT;
else if( Q_stristr( name, "masked" ))
rendermode = LUMP_MASKED;
else if( Q_stristr( name, "gradient" ))
rendermode = LUMP_GRADIENT;
else if( Q_stristr( name, "valve" ))
buffer = NULL; // force to get HL palette
}
@ -109,7 +107,7 @@ qboolean Image_LoadFNT( const char *name, const byte *buffer, size_t filesize )
if( numcolors == 768 || numcolors == 256 )
{
// g-cont. make sure that is didn't hit anything
Image_GetPaletteLMP( pal, LUMP_QFONT );
Image_GetPaletteLMP( pal, LUMP_MASKED );
image.flags |= IMAGE_HAS_ALPHA; // fonts always have transparency
}
else
@ -152,14 +150,11 @@ qboolean Image_LoadMDL( const char *name, const byte *buffer, size_t filesize )
if( filesize < ( sizeof( *pin ) + pixels + 768 ))
return false;
if( flags & STUDIO_NF_MASKED )
if( FBitSet( flags, STUDIO_NF_MASKED ))
{
byte *pal = fin + pixels;
// make transparent color is black, blue color looks ugly
pal[255*3+0] = pal[255*3+1] = pal[255*3+2] = 0;
Image_GetPaletteLMP( pal, LUMP_TRANSPARENT );
Image_GetPaletteLMP( pal, LUMP_MASKED );
image.flags |= IMAGE_HAS_ALPHA;
}
else Image_GetPaletteLMP( fin + pixels, LUMP_NORMAL );
@ -222,16 +217,12 @@ qboolean Image_LoadSPR( const char *name, const byte *buffer, size_t filesize )
// detect alpha-channel by palette type
switch( image.d_rendermode )
{
case LUMP_DECAL:
case LUMP_TRANSPARENT:
image.flags |= IMAGE_HAS_ALPHA;
case LUMP_GRADIENT:
case LUMP_MASKED:
SetBits( image.flags, IMAGE_HAS_ALPHA );
break;
}
// make transparent color is black, blue color looks ugly
if( image.d_rendermode == LUMP_TRANSPARENT )
image.d_currentpal[255] = 0;
return Image_AddIndexedImageToPack( (byte *)(pin + 1), image.width, image.height );
}
@ -261,7 +252,7 @@ qboolean Image_LoadLMP( const char *name, const byte *buffer, size_t filesize )
memcpy( &lmp, fin, sizeof( lmp ));
image.width = lmp.width;
image.height = lmp.height;
rendermode = LUMP_NORMAL;
rendermode = LUMP_MASKED;
fin += sizeof( lmp );
pixels = image.width * image.height;
@ -294,8 +285,8 @@ qboolean Image_LoadLMP( const char *name, const byte *buffer, size_t filesize )
return false;
}
if( fin[0] == 255 ) image.flags |= IMAGE_HAS_ALPHA;
Image_GetPaletteLMP( pal, rendermode );
image.flags |= IMAGE_HAS_ALPHA; // FIXME: detect it properly
image.type = PF_INDEXED_32; // 32-bit palete
image.depth = 1;
@ -348,20 +339,13 @@ qboolean Image_LoadMIP( const char *name, const byte *buffer, size_t filesize )
{
if( !host.decal_loading )
{
rendermode = LUMP_TRANSPARENT;
// make transparent color is black, blue color looks ugly
pal[255*3+0] = pal[255*3+1] = pal[255*3+2] = 0;
rendermode = LUMP_MASKED;
}
else
{
// clear blue color for 'transparent' decals
if( pal[255*3+0] == 0 && pal[255*3+1] == 0 && pal[255*3+2] == 255 )
pal[255*3+0] = pal[255*3+1] = pal[255*3+2] = 0;
// apply decal palette immediately
image.flags |= IMAGE_COLORINDEX;
rendermode = LUMP_DECAL;
rendermode = LUMP_GRADIENT;
}
image.flags |= IMAGE_HAS_ALPHA;

View File

@ -379,8 +379,6 @@ void Host_InputFrame( void )
Sys_SendKeyEvents ();
Cbuf_Execute ();
if( !in_mouseinitialized )
return;

Binary file not shown.

Binary file not shown.

View File

@ -35,9 +35,7 @@ typedef float vec_t;
typedef vec_t vec2_t[2];
typedef vec_t vec3_t[3];
typedef vec_t vec4_t[4];
typedef vec_t quat_t[4];
typedef byte rgba_t[4]; // unsigned byte colorpack
typedef byte rgb_t[3]; // unsigned byte colorpack
typedef vec_t matrix3x4[3][4];
typedef vec_t matrix4x4[4][4];

View File

@ -43,7 +43,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MD /W3 /GX /O2 /Op- /Oy- /I "./" /I "common" /I "common/imagelib" /I "common/soundlib" /I "server" /I "client" /I "client/vgui" /I "../common" /I "../game_shared" /I "../pm_shared" /I "../utils/vgui/include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "./" /I "common" /I "common/imagelib" /I "common/soundlib" /I "server" /I "client" /I "client/vgui" /I "../common" /I "../game_shared" /I "../pm_shared" /I "../utils/vgui/include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
# SUBTRACT CPP /Fr /YX
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
@ -102,7 +102,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386
# ADD LINK32 msvcrtd.lib user32.lib gdi32.lib shell32.lib advapi32.lib winmm.lib mpeg_dbg.lib ../utils/vgui/lib/win32_vc6/vgui.lib /nologo /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"libcmtd" /out:"..\temp\engine\!debug/xash.dll" /pdbtype:sept /libpath:"./common/soundlib"
# ADD LINK32 msvcrtd.lib user32.lib gdi32.lib shell32.lib advapi32.lib winmm.lib mpeg_dbg.lib ../utils/vgui/lib/win32_vc6/vgui.lib /nologo /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"libcd.lib" /out:"..\temp\engine\!debug/xash.dll" /pdbtype:sept /libpath:"./common/soundlib"
# SUBTRACT LINK32 /incremental:no /map /nodefaultlib
# Begin Custom Build
TargetDir=\Xash3D\src_main\temp\engine\!debug

View File

@ -590,6 +590,7 @@ void SV_UpdateBaseVelocity( edict_t *ent );
byte *pfnSetFatPVS( const float *org );
byte *pfnSetFatPAS( const float *org );
int pfnPrecacheModel( const char *s );
void pfnRemoveEntity( edict_t* e );
int pfnNumberOfEntities( void );
void SV_RestartStaticEnts( void );
char *SV_Localinfo( void );

View File

@ -198,7 +198,7 @@ qboolean SV_RunThink( edict_t *ent )
{
float thinktime;
if(!( ent->v.flags & FL_KILLME ))
if( !FBitSet( ent->v.flags, FL_KILLME ))
{
thinktime = ent->v.nextthink;
if( thinktime <= 0.0f || thinktime > sv.time + sv.frametime )
@ -213,7 +213,7 @@ qboolean SV_RunThink( edict_t *ent )
svgame.dllFuncs.pfnThink( ent );
}
if( ent->v.flags & FL_KILLME )
if( FBitSet( ent->v.flags, FL_KILLME ))
SV_FreeEdict( ent );
return !ent->free;
@ -250,7 +250,10 @@ qboolean SV_PlayerRunThink( edict_t *ent, float frametime, double time )
}
if( FBitSet( ent->v.flags, FL_KILLME ))
SV_FreeEdict( ent );
{
MsgDev( D_ERROR, "client can't be deleted!\n" );
ClearBits( ent->v.flags, FL_KILLME );
}
return !ent->free;
}

View File

@ -1523,7 +1523,6 @@ static qboolean SV_RecursiveLightPoint( model_t *model, mnode_t *node, const vec
// check for impact on this node
surf = model->surfaces + node->firstsurface;
sample_size = Mod_SampleSizeForFace( surf );
for( i = 0; i < node->numsurfaces; i++, surf++ )
{
@ -1538,12 +1537,13 @@ static qboolean SV_RecursiveLightPoint( model_t *model, mnode_t *node, const vec
if(( s < 0.0f || s > surf->extents[0] ) || ( t < 0.0f || t > surf->extents[1] ))
continue;
s /= sample_size;
t /= sample_size;
if( !surf->samples )
return true;
sample_size = Mod_SampleSizeForFace( surf );
s /= sample_size;
t /= sample_size;
VectorClear( sv_pointColor );
lm = surf->samples + (t * ((surf->extents[0] / sample_size) + 1) + s);