2008-12-25 22:00:00 +01:00
//=======================================================================
// Copyright XashXT Group 2008 <20>
// view.cpp - view/refresh setup functions
//=======================================================================
# include "extdll.h"
2009-01-22 22:00:00 +01:00
# include "utils.h"
2009-01-11 22:00:00 +01:00
# include "ref_params.h"
2009-01-22 22:00:00 +01:00
# include "triangle_api.h"
# include "pm_movevars.h"
# include "studio_ref.h"
2009-09-13 22:00:00 +02:00
# include "user_cmd.h"
2008-12-25 22:00:00 +01:00
# include "hud.h"
2009-01-22 22:00:00 +01:00
# define ORIGIN_BACKUP 64
# define ORIGIN_MASK ( ORIGIN_BACKUP - 1 )
// global view containers
Vector v_origin , v_angles , v_cl_angles ; // base client vectors
float v_idlescale , v_lastDistance ; // misc variables
Vector ev_punchangle ; // client punchangles
edict_t * spot ;
typedef struct
{
Vector Origins [ ORIGIN_BACKUP ] ;
float OriginTime [ ORIGIN_BACKUP ] ;
Vector Angles [ ORIGIN_BACKUP ] ;
float AngleTime [ ORIGIN_BACKUP ] ;
int CurrentOrigin ;
int CurrentAngle ;
} viewinterp_t ;
2009-09-13 22:00:00 +02:00
typedef struct pitchdrift_s
{
int nodrift ;
float pitchvel ;
float driftmove ;
float laststop ;
} pitchdrift_t ;
2009-01-22 22:00:00 +01:00
static viewinterp_t ViewInterp ;
2009-09-13 22:00:00 +02:00
static pitchdrift_t pd ;
2009-01-22 22:00:00 +01:00
// view CVARS
cvar_t * scr_ofsx ;
cvar_t * scr_ofsy ;
cvar_t * scr_ofsz ;
cvar_t * cl_vsmoothing ;
2009-09-22 22:00:00 +02:00
cvar_t * cl_stairsmooth ;
2009-09-13 22:00:00 +02:00
cvar_t * cl_forwardspeed ;
2009-01-22 22:00:00 +01:00
cvar_t * r_mirrors ;
cvar_t * r_portals ;
cvar_t * r_screens ;
cvar_t * r_debug ;
cvar_t * cl_bobcycle ;
cvar_t * cl_bob ;
cvar_t * cl_bobup ;
cvar_t * cl_waterdist ;
cvar_t * cl_chasedist ;
cvar_t * v_centermove ;
cvar_t * v_centerspeed ;
cvar_t * v_iyaw_cycle ;
cvar_t * v_iroll_cycle ;
cvar_t * v_ipitch_cycle ;
cvar_t * v_iyaw_level ;
cvar_t * v_iroll_level ;
cvar_t * v_ipitch_level ;
//==============================================================================
// PASS MANAGER GLOBALS
//==============================================================================
// render manager global variables
bool g_FirstFrame = false ;
bool g_RenderReady = false ;
bool g_bFinalPass = false ;
bool g_bEndCalc = false ;
int m_RenderRefCount = 0 ; // refcounter (use for debug)
// passes info
bool g_bMirrorShouldpass = false ;
bool g_bScreenShouldpass = false ;
bool g_bPortalShouldpass = false ;
bool g_bSkyShouldpass = false ;
bool g_bMirrorPass = false ;
bool g_bPortalPass = false ;
bool g_bScreenPass = false ;
bool g_bSkyPass = false ;
// rendering info
int g_iTotalVisibleMirrors = 0 ;
int g_iTotalVisibleScreens = 0 ;
int g_iTotalVisiblePortals = 0 ;
int g_iTotalMirrors = 0 ;
int g_iTotalScreens = 0 ;
int g_iTotalPortals = 0 ;
// base origin and angles
Vector g_vecBaseOrigin ; // base origin - transformed always
Vector g_vecBaseAngles ; // base angles - transformed always
Vector g_vecCurrentOrigin ; // current origin
Vector g_vecCurrentAngles ; // current angles
//==============================================================================
// VIEW RENDERING
//==============================================================================
//==========================
// V_ThirdPerson
//==========================
void V_ThirdPerson ( void )
{
// no thirdperson in multiplayer
if ( GetMaxClients ( ) > 1 ) return ;
if ( ! gHUD . viewFlags )
gHUD . m_iLastCameraMode = gHUD . m_iCameraMode = 1 ;
else gHUD . m_iLastCameraMode = 1 ; // set new view after release camera
}
//==========================
// V_FirstPerson
//==========================
void V_FirstPerson ( void )
{
if ( ! gHUD . viewFlags )
gHUD . m_iLastCameraMode = gHUD . m_iCameraMode = 0 ;
else gHUD . m_iLastCameraMode = 0 ; // set new view after release camera
}
//==========================
// V_Init
//==========================
void V_Init ( void )
{
scr_ofsx = g_engfuncs . pfnRegisterVariable ( " scr_ofsx " , " 0 " , 0 , " screen offset by X " ) ;
scr_ofsy = g_engfuncs . pfnRegisterVariable ( " scr_ofsy " , " 0 " , 0 , " screen offset by Y " ) ;
scr_ofsz = g_engfuncs . pfnRegisterVariable ( " scr_ofsz " , " 0 " , 0 , " screen offset by Z " ) ;
2009-09-22 22:00:00 +02:00
cl_vsmoothing = g_engfuncs . pfnRegisterVariable ( " cl_vsmoothing " , " 0.05 " , 0 , " enables lepring in multiplayer " ) ;
cl_stairsmooth = g_engfuncs . pfnRegisterVariable ( " cl_vstairsmooth " , " 100 " , FCVAR_ARCHIVE , " how fast your view moves upward/downward when running up/down stairs " ) ;
2009-09-13 22:00:00 +02:00
cl_forwardspeed = g_engfuncs . pfnRegisterVariable ( " cl_forwardspeed " , " 200 " , 0 , " client forward speed limit " ) ;
2009-01-22 22:00:00 +01:00
v_iyaw_cycle = g_engfuncs . pfnRegisterVariable ( " v_iyaw_cycle " , " 2 " , 0 , " viewing inverse yaw cycle " ) ;
v_iroll_cycle = g_engfuncs . pfnRegisterVariable ( " v_iroll_cycle " , " 0.5 " , 0 , " viewing inverse roll cycle " ) ;
v_ipitch_cycle = g_engfuncs . pfnRegisterVariable ( " v_ipitch_cycle " , " 1 " , 0 , " viewing inverse pitch cycle " ) ;
v_iyaw_level = g_engfuncs . pfnRegisterVariable ( " v_iyaw_level " , " 0.3 " , 0 , " viewing inverse yaw level " ) ;
v_iroll_level = g_engfuncs . pfnRegisterVariable ( " v_iroll_level " , " 0.1 " , 0 , " viewing inverse roll level " ) ;
v_ipitch_level = g_engfuncs . pfnRegisterVariable ( " v_iyaw_level " , " 0.3 " , 0 , " viewing inverse pitch level " ) ;
v_centermove = g_engfuncs . pfnRegisterVariable ( " v_centermove " , " 0.15 " , 0 , " center moving scale " ) ;
2009-09-13 22:00:00 +02:00
v_centerspeed = g_engfuncs . pfnRegisterVariable ( " v_centerspeed " , " 500 " , 0 , " center moving speed " ) ;
2009-01-22 22:00:00 +01:00
cl_bobcycle = g_engfuncs . pfnRegisterVariable ( " cl_bobcycle " , " 0.8 " , 0 , " bob full cycle " ) ;
cl_bob = g_engfuncs . pfnRegisterVariable ( " cl_bob " , " 0.01 " , 0 , " bob value " ) ;
cl_bobup = g_engfuncs . pfnRegisterVariable ( " cl_bobup " , " 0.5 " , 0 , " bob upper limit " ) ;
cl_waterdist = g_engfuncs . pfnRegisterVariable ( " cl_waterdist " , " 4 " , 0 , " distance between viewofs and water plane " ) ;
cl_chasedist = g_engfuncs . pfnRegisterVariable ( " cl_chasedist " , " 112 " , 0 , " max distance to chase camera " ) ;
g_engfuncs . pfnAddCommand ( " thirdperson " , V_ThirdPerson , " change camera to thirdperson " ) ;
g_engfuncs . pfnAddCommand ( " firstperson " , V_FirstPerson , " change camera to firstperson " ) ;
r_mirrors = g_engfuncs . pfnRegisterVariable ( " r_mirrors " , " 0 " , FCVAR_ARCHIVE , " enable mirrors rendering " ) ;
r_portals = g_engfuncs . pfnRegisterVariable ( " r_portals " , " 0 " , FCVAR_ARCHIVE , " enable portals rendering " ) ;
r_screens = g_engfuncs . pfnRegisterVariable ( " r_screens " , " 0 " , FCVAR_ARCHIVE , " enable screens rendering " ) ;
r_debug = g_engfuncs . pfnRegisterVariable ( " r_debug " , " 0 " , 0 , " show renderer state " ) ;
}
2009-09-13 22:00:00 +02:00
//==========================
// V_StartPitchDrift
//==========================
void V_StartPitchDrift ( void )
{
if ( pd . laststop = = GetClientTime ( ) )
return ;
if ( pd . nodrift | | ! pd . pitchvel )
{
pd . pitchvel = v_centerspeed - > value ;
pd . nodrift = 0 ;
pd . driftmove = 0 ;
}
}
//==========================
// V_StopPitchDrift
//==========================
void V_StopPitchDrift ( void )
{
pd . laststop = GetClientTime ( ) ;
pd . nodrift = 1 ;
pd . pitchvel = 0 ;
}
//==========================
// V_DriftPitch
//==========================
void V_DriftPitch ( ref_params_t * pparams )
{
float delta , move ;
if ( pparams - > movetype = = MOVETYPE_NOCLIP | | ! pparams - > onground | | pparams - > demoplayback )
{
pd . driftmove = 0 ;
pd . pitchvel = 0 ;
return ;
}
if ( pd . nodrift )
{
if ( fabs ( ( float ) pparams - > cmd - > forwardmove ) < cl_forwardspeed - > value )
pd . driftmove = 0 ;
else pd . driftmove + = pparams - > frametime ;
if ( pd . driftmove > v_centermove - > value ) V_StartPitchDrift ( ) ;
return ;
}
delta = pparams - > idealpitch - pparams - > cl_viewangles [ PITCH ] ;
if ( ! delta )
{
pd . pitchvel = 0 ;
return ;
}
move = pparams - > frametime * pd . pitchvel ;
pd . pitchvel + = pparams - > frametime * v_centerspeed - > value ;
if ( delta > 0 )
{
if ( move > delta )
{
pd . pitchvel = 0 ;
move = delta ;
}
pparams - > cl_viewangles [ PITCH ] + = move ;
}
else if ( delta < 0 )
{
if ( move > - delta )
{
pd . pitchvel = 0 ;
move = - delta ;
}
pparams - > cl_viewangles [ PITCH ] - = move ;
}
}
2009-01-23 22:00:00 +01:00
//==========================
// V_CalcFov
//==========================
float V_CalcFov ( float fov_x , float width , float height )
2009-01-22 22:00:00 +01:00
{
2009-01-23 22:00:00 +01:00
float fov_y , x , rad = 360.0f * M_PI ;
// check to avoid division by zero
if ( fov_x = = 0 ) HOST_ERROR ( " V_CalcFov: null fov! \n " ) ;
// make sure that fov in-range
fov_x = bound ( 1 , fov_x , 179 ) ;
x = width / tan ( fov_x / rad ) ;
fov_y = atan2 ( height , x ) ;
fov_y = ( fov_y * rad ) ;
return fov_y ;
2009-01-22 22:00:00 +01:00
}
//==========================
// V_DropPunchAngle
//==========================
void V_DropPunchAngle ( float frametime , Vector & ev_punchangle )
{
float len ;
len = ev_punchangle . Length ( ) ;
ev_punchangle . Normalize ( ) ;
len - = ( 10.0 + len * 0.5 ) * frametime ;
len = max ( len , 0.0 ) ;
ev_punchangle * = len ;
}
//==========================
// V_CalcGunAngle
//==========================
void V_CalcGunAngle ( ref_params_t * pparams )
{
2009-09-18 22:00:00 +02:00
if ( pparams - > fov_x > 135 ) return ;
2009-01-22 22:00:00 +01:00
edict_t * viewent = GetViewModel ( ) ;
2009-09-18 22:00:00 +02:00
if ( ! viewent - > v . modelindex ) return ;
2009-01-22 22:00:00 +01:00
viewent - > serialnumber = - 1 ; // viewentity are handled with special number. don't change this
viewent - > v . effects | = EF_MINLIGHT ;
viewent - > v . angles [ YAW ] = pparams - > viewangles [ YAW ] + pparams - > crosshairangle [ YAW ] ;
viewent - > v . angles [ PITCH ] = pparams - > viewangles [ PITCH ] + pparams - > crosshairangle [ PITCH ] * 0.25 ;
viewent - > v . angles [ ROLL ] - = v_idlescale * sin ( pparams - > time * v_iroll_cycle - > value ) * v_iroll_level - > value ;
// don't apply all of the v_ipitch to prevent normally unseen parts of viewmodel from coming into view.
viewent - > v . angles [ PITCH ] - = v_idlescale * sin ( pparams - > time * v_ipitch_cycle - > value ) * ( v_ipitch_level - > value * 0.5 ) ;
viewent - > v . angles [ YAW ] - = v_idlescale * sin ( pparams - > time * v_iyaw_cycle - > value ) * v_iyaw_level - > value ;
2009-01-23 22:00:00 +01:00
}
2009-01-22 22:00:00 +01:00
2009-01-23 22:00:00 +01:00
//==========================
// V_PreRender
//==========================
void V_PreRender ( ref_params_t * pparams )
{
// input
pparams - > intermission = gHUD . m_iIntermission ;
2009-09-18 22:00:00 +02:00
if ( gHUD . m_iCameraMode ) pparams - > flags | = RDF_THIRDPERSON ;
else pparams - > flags & = ~ RDF_THIRDPERSON ;
2009-01-23 22:00:00 +01:00
// output
gHUD . m_CrosshairAngles = pparams - > crosshairangle ;
2009-09-19 22:00:00 +02:00
pparams - > fov_x = gHUD . m_flFOV ; // this is a final fov value
2009-01-23 22:00:00 +01:00
pparams - > fov_y = V_CalcFov ( pparams - > fov_x , pparams - > viewport [ 2 ] , pparams - > viewport [ 3 ] ) ;
2009-01-22 22:00:00 +01:00
}
//==========================
// V_CalcGlobalFog
//==========================
void V_CalcGlobalFog ( ref_params_t * pparams )
{
int bOn = ( pparams - > waterlevel < 2 ) & & ( gHUD . m_fStartDist > 0 ) & & ( gHUD . m_fEndDist > 0 ) ;
g_engfuncs . pTriAPI - > Fog ( gHUD . m_FogColor , gHUD . m_fStartDist , gHUD . m_fEndDist , bOn ) ;
}
//==========================
// V_CalcBob
//==========================
float V_CalcBob ( ref_params_t * pparams )
{
static double bobtime ;
static float bob ;
static float lasttime ;
float cycle ;
Vector vel ;
if ( ! pparams - > onground | | pparams - > time = = lasttime )
return bob ;
lasttime = pparams - > time ;
bobtime + = pparams - > frametime ;
cycle = bobtime - ( int ) ( bobtime / cl_bobcycle - > value ) * cl_bobcycle - > value ;
cycle / = cl_bobcycle - > value ;
2009-01-23 22:00:00 +01:00
if ( cycle < cl_bobup - > value ) cycle = M_PI * cycle / cl_bobup - > value ;
2009-01-22 22:00:00 +01:00
else cycle = M_PI + M_PI * ( cycle - cl_bobup - > value ) / ( 1.0 - cl_bobup - > value ) ;
2009-09-18 22:00:00 +02:00
vel = pparams - > simvel ;
2009-01-22 22:00:00 +01:00
vel [ 2 ] = 0 ;
bob = sqrt ( vel [ 0 ] * vel [ 0 ] + vel [ 1 ] * vel [ 1 ] ) * cl_bob - > value ;
2009-01-23 22:00:00 +01:00
bob = bob * 0.3 + bob * 0.7 * sin ( cycle ) ;
2009-01-22 22:00:00 +01:00
bob = min ( bob , 4 ) ;
bob = max ( bob , - 7 ) ;
return bob ;
}
//==========================
// V_AddIdle
//==========================
void V_AddIdle ( ref_params_t * pparams )
{
pparams - > viewangles [ ROLL ] + = v_idlescale * sin ( pparams - > time * v_iroll_cycle - > value ) * v_iroll_level - > value ;
pparams - > viewangles [ PITCH ] + = v_idlescale * sin ( pparams - > time * v_ipitch_cycle - > value ) * v_ipitch_level - > value ;
pparams - > viewangles [ YAW ] + = v_idlescale * sin ( pparams - > time * v_iyaw_cycle - > value ) * v_iyaw_level - > value ;
}
//==========================
// V_CalcViewRoll
//==========================
void V_CalcViewRoll ( ref_params_t * pparams )
{
float sign , side , value ;
2009-09-18 22:00:00 +02:00
edict_t * viewentity ;
2009-01-23 22:00:00 +01:00
Vector right ;
2009-09-18 22:00:00 +02:00
viewentity = GetEntityByIndex ( pparams - > viewentity ) ;
if ( ! viewentity ) return ;
if ( pparams - > health < = 0 & & ( pparams - > viewheight [ 2 ] ! = 0 ) )
2009-01-23 22:00:00 +01:00
{
2009-09-18 22:00:00 +02:00
GetViewModel ( ) - > v . modelindex = 0 ; // clear the viewmodel
2009-01-23 22:00:00 +01:00
pparams - > viewangles [ ROLL ] = 80 ; // dead view angle
return ;
}
2009-01-22 22:00:00 +01:00
2009-09-18 22:00:00 +02:00
AngleVectors ( viewentity - > v . angles , NULL , right , NULL ) ;
side = right . Dot ( pparams - > simvel ) ;
2009-01-22 22:00:00 +01:00
sign = side < 0 ? - 1 : 1 ;
side = fabs ( side ) ;
value = pparams - > movevars - > rollangle ;
if ( side < pparams - > movevars - > rollspeed )
side = side * value / pparams - > movevars - > rollspeed ;
else side = value ;
side = side * sign ;
pparams - > viewangles [ ROLL ] + = side ;
}
//==========================
// V_SetViewportRefdef
//==========================
void V_SetViewportRefdef ( ref_params_t * pparams )
{
pparams - > viewport [ 0 ] = 0 ;
pparams - > viewport [ 1 ] = 0 ;
pparams - > viewport [ 2 ] = VIEWPORT_SIZE ;
pparams - > viewport [ 3 ] = VIEWPORT_SIZE ;
}
//==========================
// V_KillViewportRefdef
//==========================
void V_KillViewportRefdef ( ref_params_t * pparams )
{
pparams - > viewport [ 0 ] = 0 ;
pparams - > viewport [ 1 ] = 0 ;
pparams - > viewport [ 2 ] = 1 ;
pparams - > viewport [ 3 ] = 1 ;
}
//==========================
// V_ResetViewportRefdef
//==========================
void V_ResetViewportRefdef ( ref_params_t * pparams )
{
pparams - > viewport [ 0 ] = 0 ;
pparams - > viewport [ 1 ] = 0 ;
2009-01-25 22:00:00 +01:00
pparams - > viewport [ 2 ] = ActualWidth ;
2009-01-22 22:00:00 +01:00
pparams - > viewport [ 2 ] & = ~ 7 ;
2009-01-25 22:00:00 +01:00
pparams - > viewport [ 3 ] = ActualHeight ;
2009-01-22 22:00:00 +01:00
pparams - > viewport [ 3 ] & = ~ 1 ;
}
//==========================
// V_GetChaseOrigin
//==========================
void V_GetChaseOrigin ( Vector angles , Vector origin , float distance , Vector & result )
{
Vector vecEnd ;
Vector forward ;
Vector vecStart ;
TraceResult tr ;
int maxLoops = 8 ;
edict_t * ent = NULL ;
edict_t * ignoreent = NULL ;
// trace back from the target using the player's view angles
AngleVectors ( angles , forward , NULL , NULL ) ;
forward * = - 1 ;
vecStart = origin ;
vecEnd . MA ( distance , vecStart , forward ) ;
while ( maxLoops > 0 )
{
g_engfuncs . pfnTraceLine ( vecStart , vecEnd , true , ignoreent , & tr ) ;
if ( tr . pHit = = NULL ) break ; // we hit the world or nothing, stop trace
ent = tr . pHit ;
// hit non-player solid BSP, stop here
2009-01-23 22:00:00 +01:00
if ( ent - > v . solid = = SOLID_BSP & & ! ( ent - > v . flags & FL_CLIENT ) )
break ;
2009-01-22 22:00:00 +01:00
// if close enought to end pos, stop, otherwise continue trace
2009-01-23 22:00:00 +01:00
if ( tr . vecEndPos . Distance ( vecEnd ) < 1.0f )
break ;
2009-01-22 22:00:00 +01:00
else
{
ignoreent = tr . pHit ; // ignore last hit entity
vecStart = tr . vecEndPos ;
}
maxLoops - - ;
}
result . MA ( 4 , tr . vecEndPos , tr . vecPlaneNormal ) ;
v_lastDistance = tr . vecEndPos . Distance ( origin ) ; // real distance without offset
}
//==========================
// V_GetChasePos
//==========================
2009-01-23 22:00:00 +01:00
void V_GetChasePos ( ref_params_t * pparams , edict_t * ent , float * cl_angles , Vector & origin , Vector & angles )
2009-01-22 22:00:00 +01:00
{
if ( ! ent )
{
// just copy a save in-map position
angles = Vector ( 0 , 0 , 0 ) ;
origin = Vector ( 0 , 0 , 0 ) ;
return ;
}
if ( cl_angles = = NULL )
{
// no mouse angles given, use entity angles ( locked mode )
angles = ent - > v . angles ;
angles . x * = - 1 ;
}
else angles = cl_angles ;
2009-01-23 22:00:00 +01:00
// refresh the position
2009-09-22 22:00:00 +02:00
origin = ent - > v . origin ;
2009-01-22 22:00:00 +01:00
origin [ 2 ] + = 28 ; // DEFAULT_VIEWHEIGHT - some offset
V_GetChaseOrigin ( angles , origin , cl_chasedist - > value , origin ) ;
}
//==========================
// V_CalcNextView
//==========================
void V_CalcNextView ( ref_params_t * pparams )
{
2009-01-23 22:00:00 +01:00
if ( g_FirstFrame ) // first time not actually
2009-01-22 22:00:00 +01:00
{
g_FirstFrame = false ;
g_RenderReady = false ;
// first time in this function
V_PreRender ( pparams ) ; // this set g_RenderReady at true if all is'ok
if ( ! g_RenderReady ) // no hardware capable?
{
g_bMirrorShouldpass = false ;
g_bScreenShouldpass = false ;
g_bPortalShouldpass = false ;
g_bSkyShouldpass = ( gHUD . m_iSkyMode ? true : false ) ; // sky must drawing always
}
else // all is'ok
{
g_bMirrorShouldpass = ( g_iTotalVisibleMirrors > 0 & & r_mirrors - > value ) ;
g_bScreenShouldpass = ( g_iTotalVisibleScreens > 0 & & r_screens - > value ) ;
g_bPortalShouldpass = ( g_iTotalVisiblePortals > 0 & & r_portals - > value ) ;
g_bSkyShouldpass = ( gHUD . m_iSkyMode ? true : false ) ;
}
m_RenderRefCount = 0 ; // reset debug counter
g_bMirrorPass = false ;
g_bScreenPass = false ;
g_bPortalPass = false ;
g_bSkyPass = false ;
g_bFinalPass = false ;
}
}
//==========================
// V_CalcCameraRefdef
//==========================
void V_CalcCameraRefdef ( ref_params_t * pparams )
{
if ( pparams - > intermission ) return ; // disable in intermission mode
if ( gHUD . viewFlags & CAMERA_ON )
{
// get viewentity and monster eyeposition
edict_t * viewentity = GetEntityByIndex ( gHUD . viewEntityIndex ) ;
if ( viewentity )
{
dstudiohdr_t * viewmonster = ( dstudiohdr_t * ) GetModelPtr ( viewentity ) ;
2009-09-18 22:00:00 +02:00
v_origin = viewentity - > v . origin ;
2009-01-23 22:00:00 +01:00
// calc monster view if supposed
if ( gHUD . viewFlags & MONSTER_VIEW & & viewmonster )
v_origin + = viewmonster - > eyeposition ;
2009-09-18 22:00:00 +02:00
v_angles = viewentity - > v . angles ;
2009-01-22 22:00:00 +01:00
if ( gHUD . viewFlags & INVERSE_X ) // inverse X coordinate
v_angles [ 0 ] = - v_angles [ 0 ] ;
2009-01-23 22:00:00 +01:00
HideCrosshair ( true ) ;
2009-01-22 22:00:00 +01:00
// refresh position
pparams - > viewangles = v_angles ;
pparams - > vieworg = v_origin ;
}
}
2009-01-23 22:00:00 +01:00
else HideCrosshair ( false ) ; // show crosshair again
2009-01-22 22:00:00 +01:00
}
edict_t * V_FindIntermisionSpot ( ref_params_t * pparams )
{
edict_t * ent ;
int spotindex [ 16 ] ; // max number of intermission spot
int k = 0 , j = 0 ;
2009-01-23 22:00:00 +01:00
// found intermission points
for ( int i = 0 ; i < pparams - > num_entities ; i + + )
2009-01-22 22:00:00 +01:00
{
ent = GetEntityByIndex ( i ) ;
if ( ent & & ! stricmp ( STRING ( ent - > v . classname ) , " info_intermission " ) )
{
if ( j > 15 ) break ; // spotlist is full
spotindex [ j ] = ent - > serialnumber ; // save entindex
j + + ;
}
}
// ok, we have list of intermission spots
if ( j )
{
if ( j > 1 ) k = g_engfuncs . pfnRandomLong ( 0 , j - 1 ) ;
ent = GetEntityByIndex ( spotindex [ k ] ) ;
}
else ent = GetLocalPlayer ( ) ; // just get view from player
return ent ;
}
//==========================
// V_CalcIntermisionRefdef
//==========================
void V_CalcIntermisionRefdef ( ref_params_t * pparams )
{
if ( ! pparams - > intermission ) return ;
edict_t * view ;
float old ;
if ( ! spot ) spot = V_FindIntermisionSpot ( pparams ) ;
view = GetViewModel ( ) ;
2009-01-23 22:00:00 +01:00
// need to lerping position ?
2009-01-22 22:00:00 +01:00
pparams - > vieworg = spot - > v . origin ;
pparams - > viewangles = spot - > v . angles ;
view - > v . modelindex = 0 ;
// allways idle in intermission
old = v_idlescale ;
v_idlescale = 1 ;
V_AddIdle ( pparams ) ;
v_idlescale = old ;
2009-01-23 22:00:00 +01:00
v_cl_angles = pparams - > cl_viewangles ;
2009-01-22 22:00:00 +01:00
v_origin = pparams - > vieworg ;
v_angles = pparams - > viewangles ;
}
//==========================
// V_PrintDebugInfo
// FIXME: use custom text drawing ?
//==========================
2009-01-23 22:00:00 +01:00
void V_PrintDebugInfo ( ref_params_t * pparams ) // for future extensions
2009-01-22 22:00:00 +01:00
{
if ( ! r_debug - > value ) return ; //show OpenGL renderer debug info
ALERT ( at_console , " Xash Renderer Info: " ) ;
if ( m_RenderRefCount > 1 ) ALERT ( at_console , " Total %d passes \n " , m_RenderRefCount ) ;
else ALERT ( at_console , " Use normal view, make one pass \n " ) ;
if ( g_iTotalMirrors ) ALERT ( at_console , " Visible mirrors: %d from %d \n " , g_iTotalVisibleMirrors , g_iTotalMirrors ) ;
if ( g_iTotalScreens ) ALERT ( at_console , " Visible screens: %d from %d \n " , g_iTotalVisibleScreens , g_iTotalScreens ) ;
if ( g_iTotalPortals ) ALERT ( at_console , " Visible portals: %d from %d \n " , g_iTotalVisiblePortals , g_iTotalPortals ) ;
}
2009-01-23 22:00:00 +01:00
//==========================
// V_CalcShake
//==========================
void V_CalcShake ( void )
{
float frametime ;
int i ;
float fraction , freq ;
if ( gHUD . m_Shake . time = = 0 )
return ;
if ( ( gHUD . m_flTime > gHUD . m_Shake . time ) | | gHUD . m_Shake . duration < = 0 | | gHUD . m_Shake . amplitude < = 0 | | gHUD . m_Shake . frequency < = 0 )
{
memset ( & gHUD . m_Shake , 0 , sizeof ( gHUD . m_Shake ) ) ;
return ;
}
frametime = gHUD . m_flTimeDelta ;
if ( gHUD . m_flTime > gHUD . m_Shake . nextShake )
{
// higher frequency means we recalc the extents more often and perturb the display again
gHUD . m_Shake . nextShake = gHUD . m_flTime + ( 1.0f / gHUD . m_Shake . frequency ) ;
// Compute random shake extents (the shake will settle down from this)
for ( i = 0 ; i < 3 ; i + + )
{
gHUD . m_Shake . offset [ i ] = RANDOM_FLOAT ( - gHUD . m_Shake . amplitude , gHUD . m_Shake . amplitude ) ;
}
gHUD . m_Shake . angle = RANDOM_FLOAT ( - gHUD . m_Shake . amplitude * 0.25 , gHUD . m_Shake . amplitude * 0.25 ) ;
}
// ramp down amplitude over duration (fraction goes from 1 to 0 linearly with slope 1/duration)
fraction = ( gHUD . m_Shake . time - gHUD . m_flTime ) / gHUD . m_Shake . duration ;
// ramp up frequency over duration
if ( fraction )
{
freq = ( gHUD . m_Shake . frequency / fraction ) ;
}
else
{
freq = 0 ;
}
// square fraction to approach zero more quickly
fraction * = fraction ;
// Sine wave that slowly settles to zero
fraction = fraction * sin ( gHUD . m_flTime * freq ) ;
// add to view origin
gHUD . m_Shake . appliedOffset = gHUD . m_Shake . offset * fraction ;
// add to roll
gHUD . m_Shake . appliedAngle = gHUD . m_Shake . angle * fraction ;
// drop amplitude a bit, less for higher frequency shakes
float localAmp = gHUD . m_Shake . amplitude * ( frametime / ( gHUD . m_Shake . duration * gHUD . m_Shake . frequency ) ) ;
gHUD . m_Shake . amplitude - = localAmp ;
}
//==========================
// V_ApplyShake
//==========================
void V_ApplyShake ( Vector & origin , Vector & angles , float factor )
{
origin . MA ( factor , origin , gHUD . m_Shake . appliedOffset ) ;
angles . z + = gHUD . m_Shake . appliedAngle * factor ;
}
2009-01-22 22:00:00 +01:00
//==========================
// V_CalcFinalPass
//==========================
void V_CalcFinalPass ( ref_params_t * pparams )
{
g_FirstFrame = true ; // enable calc next passes
V_ResetViewportRefdef ( pparams ) ; // reset view port as default
m_RenderRefCount + + ; // increase counter
}
//==========================
// V_CalcThirdPersonRefdef
//==========================
2009-01-23 22:00:00 +01:00
void V_CalcThirdPersonRefdef ( ref_params_t * pparams )
2009-01-22 22:00:00 +01:00
{
// passed only in third person
2009-01-23 22:00:00 +01:00
if ( gHUD . m_iCameraMode = = 0 | | pparams - > intermission )
return ;
// clear viewmodel for thirdperson
edict_t * viewent = GetViewModel ( ) ;
viewent - > v . modelindex = 0 ;
2009-01-22 22:00:00 +01:00
// get current values
2009-01-23 22:00:00 +01:00
v_cl_angles = pparams - > cl_viewangles ;
2009-01-22 22:00:00 +01:00
v_angles = pparams - > viewangles ;
v_origin = pparams - > vieworg ;
2009-01-23 22:00:00 +01:00
V_GetChasePos ( pparams , GetLocalPlayer ( ) , v_cl_angles , v_origin , v_angles ) ;
2009-01-22 22:00:00 +01:00
// write back new values
2009-01-23 22:00:00 +01:00
pparams - > cl_viewangles = v_cl_angles ;
2009-01-22 22:00:00 +01:00
pparams - > viewangles = v_angles ;
pparams - > vieworg = v_origin ;
2009-01-23 22:00:00 +01:00
// apply shake for thirdperson too
V_CalcShake ( ) ;
V_ApplyShake ( pparams - > vieworg , pparams - > viewangles , 1.0 ) ;
2009-01-22 22:00:00 +01:00
}
//==========================
// V_CalcSendOrigin
//==========================
void V_CalcSendOrigin ( ref_params_t * pparams )
{
// never let view origin sit exactly on a node line, because a water plane can
// dissapear when viewed with the eye exactly on it.
pparams - > vieworg [ 0 ] + = 1.0 / 32 ;
pparams - > vieworg [ 1 ] + = 1.0 / 32 ;
pparams - > vieworg [ 2 ] + = 1.0 / 32 ;
}
//==========================
// V_CalcWaterLevel
//==========================
float V_CalcWaterLevel ( ref_params_t * pparams )
{
float waterOffset = 0 ;
if ( pparams - > waterlevel > = 2 )
{
int i , contents , waterDist ;
waterDist = cl_waterdist - > value ;
TraceResult tr ;
Vector point ;
2009-09-18 22:00:00 +02:00
TRACE_HULL ( pparams - > simorg , Vector ( - 16 , - 16 , - 24 ) , Vector ( 16 , 16 , 32 ) , pparams - > simorg , 1 , GetLocalPlayer ( ) , & tr ) ;
2009-01-22 22:00:00 +01:00
if ( tr . pHit & & ! stricmp ( STRING ( tr . pHit - > v . classname ) , " func_water " ) )
waterDist + = ( tr . pHit - > v . scale * 16 ) ;
point = pparams - > vieworg ;
// eyes are above water, make sure we're above the waves
if ( pparams - > waterlevel = = 2 )
{
point [ 2 ] - = waterDist ;
for ( i = 0 ; i < waterDist ; i + + )
{
contents = POINT_CONTENTS ( point ) ;
if ( contents > CONTENTS_WATER ) break ;
point [ 2 ] + = 1 ;
}
waterOffset = ( point [ 2 ] + waterDist ) - pparams - > vieworg [ 2 ] ;
}
else
{
// eyes are under water. Make sure we're far enough under
point [ 2 ] + = waterDist ;
for ( i = 0 ; i < waterDist ; i + + )
{
contents = POINT_CONTENTS ( point ) ;
if ( contents < = CONTENTS_WATER ) break ;
point [ 2 ] - = 1 ;
}
waterOffset = ( point [ 2 ] - waterDist ) - pparams - > vieworg [ 2 ] ;
}
}
2009-01-23 22:00:00 +01:00
// underwater refraction
if ( pparams - > waterlevel = = 3 )
{
float f = sin ( pparams - > time * 0.4 * ( M_PI * 2.7 ) ) ;
pparams - > fov_x + = f ;
pparams - > fov_y - = f ;
}
2009-01-22 22:00:00 +01:00
pparams - > vieworg [ 2 ] + = waterOffset ;
return waterOffset ;
}
//==========================
// V_CalcScrOffset
//==========================
void V_CalcScrOffset ( ref_params_t * pparams )
{
// don't allow cheats in multiplayer
2009-09-18 22:00:00 +02:00
if ( pparams - > maxclients > 1 ) return ;
2009-01-22 22:00:00 +01:00
for ( int i = 0 ; i < 3 ; i + + )
{
pparams - > vieworg [ i ] + = scr_ofsx - > value * pparams - > forward [ i ] ;
pparams - > vieworg [ i ] + = scr_ofsy - > value * pparams - > right [ i ] ;
pparams - > vieworg [ i ] + = scr_ofsz - > value * pparams - > up [ i ] ;
}
}
//==========================
2009-09-22 22:00:00 +02:00
// V_InterpolatePos
2009-01-22 22:00:00 +01:00
//==========================
2009-09-22 22:00:00 +02:00
void V_InterpolatePos ( ref_params_t * pparams )
2008-12-25 22:00:00 +01:00
{
2009-01-22 22:00:00 +01:00
edict_t * view ;
// view is the weapon model (only visible from inside body )
view = GetViewModel ( ) ;
2009-09-22 22:00:00 +02:00
if ( cl_vsmoothing - > value & & ( pparams - > smoothing & & ( pparams - > maxclients > 1 ) ) )
2009-01-22 22:00:00 +01:00
{
2009-09-22 22:00:00 +02:00
int i , foundidx ;
float t ;
2009-01-22 22:00:00 +01:00
if ( cl_vsmoothing - > value < 0.0 ) CVAR_SET_FLOAT ( " cl_vsmoothing " , 0 ) ;
t = pparams - > time - cl_vsmoothing - > value ;
for ( i = 1 ; i < ORIGIN_MASK ; i + + )
{
foundidx = ViewInterp . CurrentOrigin - 1 - i ;
if ( ViewInterp . OriginTime [ foundidx & ORIGIN_MASK ] < = t ) break ;
}
if ( i < ORIGIN_MASK & & ViewInterp . OriginTime [ foundidx & ORIGIN_MASK ] ! = 0.0 )
{
// interpolate
Vector delta ;
double frac ;
double dt ;
Vector neworg ;
2009-09-22 22:00:00 +02:00
dt = ViewInterp . OriginTime [ ( foundidx + 1 ) & ORIGIN_MASK ] - ViewInterp . OriginTime [ foundidx & ORIGIN_MASK ] ;
2009-01-22 22:00:00 +01:00
if ( dt > 0.0 )
{
2009-09-22 22:00:00 +02:00
frac = ( t - ViewInterp . OriginTime [ foundidx & ORIGIN_MASK ] ) / dt ;
2009-01-22 22:00:00 +01:00
frac = min ( 1.0 , frac ) ;
delta = ViewInterp . Origins [ ( foundidx + 1 ) & ORIGIN_MASK ] - ViewInterp . Origins [ foundidx & ORIGIN_MASK ] ;
neworg . MA ( frac , ViewInterp . Origins [ foundidx & ORIGIN_MASK ] , delta ) ;
// don't interpolate large changes
if ( delta . Length ( ) < 64 )
{
2009-09-18 22:00:00 +02:00
delta = neworg - pparams - > simorg ;
pparams - > simorg + = delta ;
2009-01-22 22:00:00 +01:00
pparams - > vieworg + = delta ;
view - > v . origin + = delta ;
}
}
}
}
}
2009-09-22 22:00:00 +02:00
float V_CalcStairSmoothValue ( float oldz , float newz , float smoothtime , float stepheight )
{
if ( oldz < newz )
return bound ( newz - stepheight , oldz + smoothtime * cl_stairsmooth - > value , newz ) ;
else if ( oldz > newz )
return bound ( newz , oldz - smoothtime * cl_stairsmooth - > value , newz + stepheight ) ;
return 0.0 ;
}
2009-01-22 22:00:00 +01:00
//==========================
// V_CalcFirstPersonRefdef
//==========================
void V_CalcFirstPersonRefdef ( ref_params_t * pparams )
{
// don't pass in thirdperson or intermission
if ( gHUD . m_iCameraMode | | pparams - > intermission )
return ;
Vector angles ;
float bob , waterOffset ;
static float lasttime ;
edict_t * view = GetViewModel ( ) ;
int i ;
2009-09-13 22:00:00 +02:00
if ( g_bFinalPass ) V_DriftPitch ( pparams ) ;
2009-01-22 22:00:00 +01:00
bob = V_CalcBob ( pparams ) ;
2009-01-23 22:00:00 +01:00
// refresh the position
2009-09-22 22:00:00 +02:00
pparams - > vieworg = pparams - > simorg ;
pparams - > vieworg [ 2 ] + = ( bob ) ;
pparams - > vieworg + = pparams - > viewheight ;
2009-01-22 22:00:00 +01:00
2009-09-18 22:00:00 +02:00
pparams - > viewangles = pparams - > cl_viewangles ;
2009-01-22 22:00:00 +01:00
V_CalcShake ( ) ;
V_ApplyShake ( pparams - > vieworg , pparams - > viewangles , 1.0 ) ;
V_CalcSendOrigin ( pparams ) ;
waterOffset = V_CalcWaterLevel ( pparams ) ;
V_CalcViewRoll ( pparams ) ;
V_AddIdle ( pparams ) ;
// offsets
angles = pparams - > viewangles ;
AngleVectors ( angles , pparams - > forward , pparams - > right , pparams - > up ) ;
V_CalcScrOffset ( pparams ) ;
2009-01-23 22:00:00 +01:00
view - > v . angles = pparams - > cl_viewangles ;
2009-01-22 22:00:00 +01:00
V_CalcGunAngle ( pparams ) ;
// use predicted origin as view origin.
2009-09-22 22:00:00 +02:00
view - > v . origin = pparams - > simorg ;
2009-01-22 22:00:00 +01:00
view - > v . origin [ 2 ] + = ( waterOffset ) ;
2009-09-22 22:00:00 +02:00
view - > v . origin + = pparams - > viewheight ;
2009-01-22 22:00:00 +01:00
// Let the viewmodel shake at about 10% of the amplitude
V_ApplyShake ( view - > v . origin , view - > v . angles , 0.9 ) ;
2009-09-22 22:00:00 +02:00
for ( i = 0 ; i < 3 ; i + + ) view - > v . origin [ i ] + = bob * 0.4 * pparams - > forward [ i ] ;
view - > v . origin [ 2 ] + = bob ;
2009-01-22 22:00:00 +01:00
view - > v . angles [ YAW ] - = bob * 0.5 ;
view - > v . angles [ ROLL ] - = bob * 1 ;
view - > v . angles [ PITCH ] - = bob * 0.3 ;
2009-01-23 22:00:00 +01:00
view - > v . origin [ 2 ] - = 1 ;
2009-09-22 22:00:00 +02:00
// fudge position around to keep amount of weapon visible
// roughly equal with different FOV
if ( pparams - > viewsize = = 110 ) view - > v . origin [ 2 ] + = 1 ;
else if ( pparams - > viewsize = = 100 ) view - > v . origin [ 2 ] + = 2 ;
else if ( pparams - > viewsize = = 90 ) view - > v . origin [ 2 ] + = 1 ;
else if ( pparams - > viewsize = = 80 ) view - > v . origin [ 2 ] + = 0.5 ;
2009-01-22 22:00:00 +01:00
2009-01-25 22:00:00 +01:00
if ( g_bMirrorPass | | g_bPortalPass | | g_bScreenPass )
pparams - > punchangle = - pparams - > punchangle ; // make inverse for mirror
2009-09-22 22:00:00 +02:00
2009-09-18 22:00:00 +02:00
pparams - > viewangles + = pparams - > punchangle ;
2009-01-22 22:00:00 +01:00
pparams - > viewangles + = ev_punchangle ;
2009-09-22 22:00:00 +02:00
2009-01-22 22:00:00 +01:00
V_DropPunchAngle ( pparams - > frametime , ev_punchangle ) ;
2009-09-22 22:00:00 +02:00
static float stairoldtime = 0 ;
static float old_client_z = 0 ;
static float old_weapon_z = 0 ;
2009-09-18 22:00:00 +02:00
2009-09-22 22:00:00 +02:00
// calculate how much time has passed since the last V_CalcRefdef
float smoothtime = bound ( 0.0 , pparams - > time - stairoldtime , 0.1 ) ;
stairoldtime = pparams - > time ;
// smooth stair stepping, but only if onground and enabled
if ( ! pparams - > smoothing | | ! pparams - > onground | | cl_stairsmooth - > value < = 0 )
2009-01-22 22:00:00 +01:00
{
2009-09-22 22:00:00 +02:00
old_client_z = pparams - > vieworg [ 2 ] ;
old_weapon_z = pparams - > vieworg [ 2 ] ;
}
else
{
float result ;
float stepheight = pparams - > movevars - > stepheight ;
result = V_CalcStairSmoothValue ( old_client_z , pparams - > vieworg [ 2 ] , smoothtime , stepheight ) ;
if ( result ) pparams - > vieworg [ 2 ] = old_client_z = result ;
result = V_CalcStairSmoothValue ( old_weapon_z , view - > v . origin [ 2 ] , smoothtime , stepheight ) ;
if ( result ) view - > v . origin [ 2 ] = old_weapon_z = result ;
2009-01-22 22:00:00 +01:00
}
2009-09-18 22:00:00 +02:00
2009-01-22 22:00:00 +01:00
static Vector lastorg ;
Vector delta ;
2009-09-22 22:00:00 +02:00
delta = pparams - > simorg - lastorg ;
2009-01-22 22:00:00 +01:00
if ( delta . Length ( ) ! = 0.0 )
{
2009-09-18 22:00:00 +02:00
ViewInterp . Origins [ ViewInterp . CurrentOrigin & ORIGIN_MASK ] = pparams - > simorg ;
2009-01-22 22:00:00 +01:00
ViewInterp . OriginTime [ ViewInterp . CurrentOrigin & ORIGIN_MASK ] = pparams - > time ;
ViewInterp . CurrentOrigin + + ;
2009-09-22 22:00:00 +02:00
lastorg = pparams - > simorg ;
2009-01-22 22:00:00 +01:00
}
2009-09-22 22:00:00 +02:00
V_InterpolatePos ( pparams ) ; // smooth predicting moving in multiplayer
2009-01-22 22:00:00 +01:00
lasttime = pparams - > time ;
v_origin = pparams - > vieworg ;
}
//==========================
// V_CalcMainRefdef
//==========================
void V_CalcMainRefdef ( ref_params_t * pparams )
{
if ( g_FirstFrame ) g_bFinalPass = true ;
V_CalcFirstPersonRefdef ( pparams ) ;
V_CalcThirdPersonRefdef ( pparams ) ;
V_CalcIntermisionRefdef ( pparams ) ;
V_CalcCameraRefdef ( pparams ) ;
g_vecBaseOrigin = pparams - > vieworg ;
g_vecBaseAngles = pparams - > viewangles ;
}
//==========================
// V_CalcSkyRefdef
//==========================
bool V_CalcSkyRefdef ( ref_params_t * pparams )
{
if ( g_bSkyShouldpass )
{
g_bSkyShouldpass = false ;
V_CalcMainRefdef ( pparams ) ; // refresh position
pparams - > vieworg = gHUD . m_vecSkyPos ;
V_ResetViewportRefdef ( pparams ) ;
pparams - > nextView = 1 ;
g_bSkyPass = true ;
m_RenderRefCount + + ;
return true ;
}
if ( g_bSkyPass )
{
pparams - > nextView = 0 ;
g_bSkyPass = false ;
return false ;
}
return false ;
}
//==========================
// V_CalcMirrorsRefdef
//==========================
bool V_CalcMirrorsRefdef ( ref_params_t * pparams )
{
if ( g_bMirrorShouldpass )
{
if ( pparams - > nextView = = 0 )
{
g_bMirrorPass = true ;
// this is first pass rendering (setup mirror viewport and nextView's)
V_SetViewportRefdef ( pparams ) ;
// enable clip plane once in first mirror!
g_engfuncs . pTriAPI - > Enable ( TRI_CLIP_PLANE ) ;
V_CalcMainRefdef ( pparams ) ;
# ifdef XASH_RENDER
m_pCurrentMirror = NULL ;
R_SetupNewMirror ( pparams ) ;
R_SetupMirrorRenderPass ( pparams ) ;
# endif
pparams - > nextView = g_iTotalVisibleMirrors ;
m_RenderRefCount + + ;
return true ;
}
else if ( pparams - > nextView = = 1 )
{
# ifdef XASH_RENDER
R_NewMirrorRenderPass ( ) ; // capture view to texture
m_pCurrentMirror = NULL ;
# endif
g_engfuncs . pTriAPI - > Disable ( TRI_CLIP_PLANE ) ;
V_ResetViewportRefdef ( pparams ) ;
pparams - > nextView = 0 ;
g_bMirrorPass = false ;
g_bMirrorShouldpass = false ;
return false ;
}
else
{
# ifdef XASH_RENDER
R_NewMirrorRenderPass ( ) ; // capture view to texture
R_SetupNewMirror ( pparams ) ;
R_SetupMirrorRenderPass ( pparams ) ;
# endif
pparams - > nextView - - ;
m_RenderRefCount + + ;
return true ;
}
}
return false ;
}
//==========================
// V_CalcScreensRefdef
//==========================
bool V_CalcScreensRefdef ( ref_params_t * pparams )
{
if ( g_bScreenShouldpass )
{
if ( pparams - > nextView = = 0 )
{
// this is first pass rendering (setup screen viewport and nextView's)
g_bScreenPass = true ;
V_SetViewportRefdef ( pparams ) ;
# ifdef XASH_RENDER
m_pCurrentScreen = NULL ;
R_SetupNewScreen ( pparams ) ;
R_SetupScreenRenderPass ( pparams ) ;
# endif
pparams - > nextView = g_iTotalVisibleScreens ;
m_RenderRefCount + + ;
return true ; //end of pass
}
else if ( pparams - > nextView = = 1 )
{
# ifdef XASH_RENDER
R_NewScreenRenderPass ( ) ; // capture view to texture
m_pCurrentScreen = NULL ;
# endif
V_ResetViewportRefdef ( pparams ) ;
pparams - > nextView = 0 ;
g_bScreenShouldpass = false ;
return false ;
}
else
{
# ifdef XASH_RENDER
R_NewScreenRenderPass ( ) ; // capture view to texture
R_SetupNewScreen ( pparams ) ;
R_SetupScreenRenderPass ( pparams ) ;
# endif
pparams - > nextView - - ;
m_RenderRefCount + + ;
return true ;
}
}
return false ;
}
//==========================
// V_CalcPortalsRefdef
//==========================
bool V_CalcPortalsRefdef ( ref_params_t * pparams )
{
if ( g_bPortalShouldpass )
{
if ( pparams - > nextView = = 0 )
{
// this is first pass rendering (setup mirror viewport and nextView's)
g_bPortalPass = true ;
V_SetViewportRefdef ( pparams ) ;
V_CalcMainRefdef ( pparams ) ;
# ifdef XASH_RENDER
m_pCurrentPortal = NULL ;
R_SetupNewPortal ( pparams ) ;
R_SetupPortalRenderPass ( pparams ) ;
# endif
pparams - > nextView = g_iTotalVisiblePortals ;
m_RenderRefCount + + ;
return true ;
}
else if ( pparams - > nextView = = 1 )
{
# ifdef XASH_RENDER
R_NewPortalRenderPass ( ) ; // capture view to texture
m_pCurrentPortal = NULL ;
# endif
// restore for final pass
V_ResetViewportRefdef ( pparams ) ;
pparams - > nextView = 0 ;
g_bPortalShouldpass = false ;
return false ;
}
else
{
# ifdef XASH_RENDER
R_NewPortalRenderPass ( ) ; // capture view to texture
R_SetupNewPortal ( pparams ) ;
R_SetupPortalRenderPass ( pparams ) ;
# endif
pparams - > nextView - - ;
m_RenderRefCount + + ;
return true ;
}
}
return false ;
}
void V_CalcRefdef ( ref_params_t * pparams )
{
V_CalcNextView ( pparams ) ;
if ( V_CalcSkyRefdef ( pparams ) ) return ;
if ( V_CalcScreensRefdef ( pparams ) ) return ;
if ( V_CalcPortalsRefdef ( pparams ) ) return ;
if ( V_CalcMirrorsRefdef ( pparams ) ) return ;
V_CalcGlobalFog ( pparams ) ;
V_CalcFinalPass ( pparams ) ;
V_CalcMainRefdef ( pparams ) ;
V_PrintDebugInfo ( pparams ) ;
2008-12-25 22:00:00 +01:00
}