diff options
| -rw-r--r-- | code/cgame/cg_draw.c | 123 | ||||
| -rw-r--r-- | code/cgame/cg_local.h | 3 | ||||
| -rw-r--r-- | code/cgame/cg_main.c | 2 | ||||
| -rw-r--r-- | code/client/cl_main.c | 2 | ||||
| -rw-r--r-- | code/client/cl_scrn.c | 4 | ||||
| -rw-r--r-- | code/qcommon/cvar.c | 21 | ||||
| -rw-r--r-- | code/renderer/tr_backend.c | 46 | ||||
| -rw-r--r-- | code/renderer/tr_cmds.c | 4 | ||||
| -rw-r--r-- | code/renderer/tr_main.c | 21 | ||||
| -rw-r--r-- | code/renderer/tr_types.h | 40 | 
10 files changed, 175 insertions, 91 deletions
diff --git a/code/cgame/cg_draw.c b/code/cgame/cg_draw.c index a525e5c..7fe0558 100644 --- a/code/cgame/cg_draw.c +++ b/code/cgame/cg_draw.c @@ -1861,7 +1861,8 @@ CROSSHAIR  CG_DrawCrosshair  =================  */ -static void CG_DrawCrosshair(void) { +static void CG_DrawCrosshair(void) +{  	float		w, h;  	qhandle_t	hShader;  	float		f; @@ -1915,6 +1916,82 @@ static void CG_DrawCrosshair(void) {  		w, h, 0, 0, 1, 1, hShader );  } +/* +================= +CG_DrawCrosshair3D +================= +*/ +static void CG_DrawCrosshair3D(void) +{ +	float		w, h; +	qhandle_t	hShader; +	float		f; +	int			ca; + +	trace_t trace; +	vec3_t endpos; +	float stereoSep, zProj, maxdist, xmax; +	char rendererinfos[128]; +	refEntity_t ent; + +	if ( !cg_drawCrosshair.integer ) { +		return; +	} + +	if ( cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR) { +		return; +	} + +	if ( cg.renderingThirdPerson ) { +		return; +	} + +	w = h = cg_crosshairSize.value; + +	// pulse the size of the crosshair when picking up items +	f = cg.time - cg.itemPickupBlendTime; +	if ( f > 0 && f < ITEM_BLOB_TIME ) { +		f /= ITEM_BLOB_TIME; +		w *= ( 1 + f ); +		h *= ( 1 + f ); +	} + +	ca = cg_drawCrosshair.integer; +	if (ca < 0) { +		ca = 0; +	} +	hShader = cgs.media.crosshairShader[ ca % NUM_CROSSHAIRS ]; + +	// Use a different method rendering the crosshair so players don't see two of them when +	// focusing their eyes at distant objects with high stereo separation +	// We are going to trace to the next shootable object and place the crosshair in front of it. + +	// first get all the important renderer information +	trap_Cvar_VariableStringBuffer("r_zProj", rendererinfos, sizeof(rendererinfos)); +	zProj = atof(rendererinfos); +	trap_Cvar_VariableStringBuffer("r_stereoSeparation", rendererinfos, sizeof(rendererinfos)); +	stereoSep = zProj / atof(rendererinfos); +	 +	xmax = zProj * tan(cg.refdef.fov_x * M_PI / 360.0f); +	 +	// let the trace run through until a change in stereo separation of the crosshair becomes less than one pixel. +	maxdist = cgs.glconfig.vidWidth * stereoSep * zProj / (2 * xmax); +	VectorMA(cg.refdef.vieworg, maxdist, cg.refdef.viewaxis[0], endpos); +	CG_Trace(&trace, cg.refdef.vieworg, NULL, NULL, endpos, 0, MASK_SHOT); +	 +	memset(&ent, 0, sizeof(ent)); +	ent.reType = RT_SPRITE; +	ent.renderfx = RF_DEPTHHACK | RF_CROSSHAIR; +	 +	VectorCopy(trace.endpos, ent.origin); +	 +	// scale the crosshair so it appears the same size for all distances +	ent.radius = w / 640 * xmax * trace.fraction * maxdist / zProj; +	ent.customShader = hShader; + +	trap_R_AddRefEntityToScene(&ent); +} +  /* @@ -2439,7 +2516,8 @@ void CG_DrawTimedMenus( void ) {  CG_Draw2D  =================  */ -static void CG_Draw2D( void ) { +static void CG_Draw2D(stereoFrame_t stereoFrame) +{  #ifdef MISSIONPACK  	if (cgs.orderPending && cg.time > cgs.orderTime) {  		CG_CheckOrderPending(); @@ -2466,7 +2544,10 @@ static void CG_Draw2D( void ) {  */  	if ( cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR ) {  		CG_DrawSpectator(); -		CG_DrawCrosshair(); + +		if(stereoFrame == STEREO_CENTER) +			CG_DrawCrosshair(); +  		CG_DrawCrosshairNames();  	} else {  		// don't draw any status if dead or the scoreboard is being explicitly shown @@ -2486,7 +2567,8 @@ static void CG_Draw2D( void ) {  #ifdef MISSIONPACK  			CG_DrawProxWarning();  #endif       -			CG_DrawCrosshair(); +			if(stereoFrame == STEREO_CENTER) +				CG_DrawCrosshair();  			CG_DrawCrosshairNames();  			CG_DrawWeaponSelect(); @@ -2550,9 +2632,6 @@ Perform all drawing needed to completely fill the screen  =====================  */  void CG_DrawActive( stereoFrame_t stereoView ) { -	float		separation; -	vec3_t		baseOrg; -  	// optionally draw the info screen instead  	if ( !cg.snap ) {  		CG_DrawInformation(); @@ -2566,41 +2645,17 @@ void CG_DrawActive( stereoFrame_t stereoView ) {  		return;  	} -	switch ( stereoView ) { -	case STEREO_CENTER: -		separation = 0; -		break; -	case STEREO_LEFT: -		separation = -cg_stereoSeparation.value / 2; -		break; -	case STEREO_RIGHT: -		separation = cg_stereoSeparation.value / 2; -		break; -	default: -		separation = 0; -		CG_Error( "CG_DrawActive: Undefined stereoView" ); -	} - -  	// clear around the rendered view if sized down  	CG_TileClear(); -	// offset vieworg appropriately if we're doing stereo separation -	VectorCopy( cg.refdef.vieworg, baseOrg ); -	if ( separation != 0 ) { -		VectorMA( cg.refdef.vieworg, -separation, cg.refdef.viewaxis[1], cg.refdef.vieworg ); -	} +	if(stereoView != STEREO_CENTER) +		CG_DrawCrosshair3D();  	// draw 3D view  	trap_R_RenderScene( &cg.refdef ); -	// restore original viewpoint if running stereo -	if ( separation != 0 ) { -		VectorCopy( baseOrg, cg.refdef.vieworg ); -	} -  	// draw status bar and other floating elements - 	CG_Draw2D(); + 	CG_Draw2D(stereoView);  } diff --git a/code/cgame/cg_local.h b/code/cgame/cg_local.h index 71598a6..d000916 100644 --- a/code/cgame/cg_local.h +++ b/code/cgame/cg_local.h @@ -1134,7 +1134,6 @@ extern	vmCvar_t		cg_zoomFov;  extern	vmCvar_t		cg_thirdPersonRange;  extern	vmCvar_t		cg_thirdPersonAngle;  extern	vmCvar_t		cg_thirdPerson; -extern	vmCvar_t		cg_stereoSeparation;  extern	vmCvar_t		cg_lagometer;  extern	vmCvar_t		cg_drawAttacker;  extern	vmCvar_t		cg_synchronousClients; @@ -1288,7 +1287,7 @@ void CG_InitTeamChat( void );  void CG_GetTeamColor(vec4_t *color);  const char *CG_GetGameStatusText( void );  const char *CG_GetKillerText( void ); -void CG_Draw3DModel( float x, float y, float w, float h, qhandle_t model, qhandle_t skin, vec3_t origin, vec3_t angles ); +void CG_Draw3DModel(float x, float y, float w, float h, qhandle_t model, qhandle_t skin, vec3_t origin, vec3_t angles);  void CG_Text_PaintChar(float x, float y, float width, float height, float scale, float s, float t, float s2, float t2, qhandle_t hShader);  void CG_CheckOrderPending( void );  const char *CG_GameTypeString( void ); diff --git a/code/cgame/cg_main.c b/code/cgame/cg_main.c index 15f4db5..15a5539 100644 --- a/code/cgame/cg_main.c +++ b/code/cgame/cg_main.c @@ -142,7 +142,6 @@ vmCvar_t	cg_zoomFov;  vmCvar_t	cg_thirdPerson;  vmCvar_t	cg_thirdPersonRange;  vmCvar_t	cg_thirdPersonAngle; -vmCvar_t	cg_stereoSeparation;  vmCvar_t	cg_lagometer;  vmCvar_t	cg_drawAttacker;  vmCvar_t	cg_synchronousClients; @@ -211,7 +210,6 @@ static cvarTable_t cvarTable[] = {  	{ &cg_zoomFov, "cg_zoomfov", "22.5", CVAR_ARCHIVE },  	{ &cg_fov, "cg_fov", "90", CVAR_ARCHIVE },  	{ &cg_viewsize, "cg_viewsize", "100", CVAR_ARCHIVE }, -	{ &cg_stereoSeparation, "cg_stereoSeparation", "0.4", CVAR_ARCHIVE  },  	{ &cg_shadows, "cg_shadows", "1", CVAR_ARCHIVE  },  	{ &cg_gibs, "cg_gibs", "1", CVAR_ARCHIVE  },  	{ &cg_draw2D, "cg_draw2D", "1", CVAR_ARCHIVE  }, diff --git a/code/client/cl_main.c b/code/client/cl_main.c index ef50e0b..d130620 100644 --- a/code/client/cl_main.c +++ b/code/client/cl_main.c @@ -2743,6 +2743,8 @@ void CL_Init( void ) {  	// cgame might not be initialized before menu is used  	Cvar_Get ("cg_viewsize", "100", CVAR_ARCHIVE ); +	// Make sure cg_stereoSeparation is zero as that variable is deprecated and should not be used anymore. +	Cvar_Get ("cg_stereoSeparation", "0", CVAR_ROM);  	//  	// register our commands diff --git a/code/client/cl_scrn.c b/code/client/cl_scrn.c index 3172f3d..fd4c38b 100644 --- a/code/client/cl_scrn.c +++ b/code/client/cl_scrn.c @@ -474,7 +474,7 @@ void SCR_DrawScreenField( stereoFrame_t stereoFrame ) {  		case CA_LOADING:  		case CA_PRIMED:  			// draw the game information screen and loading progress -			CL_CGameRendering(STEREO_CENTER); +			CL_CGameRendering(stereoFrame);  			// also draw the connection information, so it doesn't  			// flash away too briefly on local or lan games @@ -484,7 +484,7 @@ void SCR_DrawScreenField( stereoFrame_t stereoFrame ) {  			break;  		case CA_ACTIVE:  			// always supply STEREO_CENTER as vieworg offset is now done by the engine. -			CL_CGameRendering(STEREO_CENTER); +			CL_CGameRendering(stereoFrame);  			SCR_DrawDemoRecording();  			break;  		} diff --git a/code/qcommon/cvar.c b/code/qcommon/cvar.c index 9dfff2e..2526e38 100644 --- a/code/qcommon/cvar.c +++ b/code/qcommon/cvar.c @@ -228,6 +228,17 @@ cvar_t *Cvar_Get( const char *var_name, const char *var_value, int flags ) {  			Z_Free( var->resetString );  			var->resetString = CopyString( var_value ); +			if(flags & CVAR_ROM) +			{ +				// this variable was set by the user, +				// so force it to value given by the engine. + +				if(var->latchedString) +					Z_Free(var->latchedString); +				 +				var->latchedString = CopyString(var_value); +			} +  			// ZOID--needs to be set so that cvars the game sets as   			// SERVERINFO get sent to clients  			cvar_modifiedFlags |= flags; @@ -239,16 +250,6 @@ cvar_t *Cvar_Get( const char *var_name, const char *var_value, int flags ) {  			// we don't have a reset string yet  			Z_Free( var->resetString );  			var->resetString = CopyString( var_value ); -			 -			// if there is no reset string yet this means the variable was set by the user, -			// so force it to value given by the engine. -			if(var->flags & CVAR_ROM) -			{ -				if(var->latchedString) -					Z_Free(var->latchedString); -				 -				var->latchedString = CopyString(var_value); -			}  		} else if ( var_value[0] && strcmp( var->resetString, var_value ) ) {  			Com_DPrintf( "Warning: cvar \"%s\" given initial values: \"%s\" and \"%s\"\n",  				var_name, var->resetString, var_value ); diff --git a/code/renderer/tr_backend.c b/code/renderer/tr_backend.c index 904c7d4..15e32c5 100644 --- a/code/renderer/tr_backend.c +++ b/code/renderer/tr_backend.c @@ -521,7 +521,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {  	int				fogNum, oldFogNum;  	int				entityNum, oldEntityNum;  	int				dlighted, oldDlighted; -	qboolean		depthRange, oldDepthRange; +	qboolean		depthRange, oldDepthRange, isCrosshair, wasCrosshair;  	int				i;  	drawSurf_t		*drawSurf;  	int				oldSort; @@ -539,6 +539,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {  	oldShader = NULL;  	oldFogNum = -1;  	oldDepthRange = qfalse; +	wasCrosshair = qfalse;  	oldDlighted = qfalse;  	oldSort = -1;  	depthRange = qfalse; @@ -573,7 +574,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {  		// change the modelview matrix if needed  		//  		if ( entityNum != oldEntityNum ) { -			depthRange = qfalse; +			depthRange = isCrosshair = qfalse;  			if ( entityNum != ENTITYNUM_WORLD ) {  				backEnd.currentEntity = &backEnd.refdef.entities[entityNum]; @@ -590,9 +591,13 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {  					R_TransformDlights( backEnd.refdef.num_dlights, backEnd.refdef.dlights, &backEnd.or );  				} -				if ( backEnd.currentEntity->e.renderfx & RF_DEPTHHACK ) { +				if(backEnd.currentEntity->e.renderfx & RF_DEPTHHACK) +				{  					// hack the depth range to prevent view model from poking into walls  					depthRange = qtrue; +					 +					if(backEnd.currentEntity->e.renderfx & RF_CROSSHAIR) +						isCrosshair = qtrue;  				}  			} else {  				backEnd.currentEntity = &tr.worldEntity; @@ -610,26 +615,40 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {  			// change depthrange. Also change projection matrix so first person weapon does not look like coming  			// out of the screen.  			// -			if (oldDepthRange != depthRange) +			if (oldDepthRange != depthRange || wasCrosshair != isCrosshair)  			{  				if (depthRange)  				{  					if(backEnd.viewParms.stereoFrame != STEREO_CENTER)  					{ -						viewParms_t temp = backEnd.viewParms; -					 -						R_SetupProjection(&temp, r_znear->value, qfalse); - -						qglMatrixMode(GL_PROJECTION); -						qglLoadMatrixf(temp.projectionMatrix); -						qglMatrixMode(GL_MODELVIEW); +						if(isCrosshair) +						{ +							if(oldDepthRange) +							{ +								// was not a crosshair but now is, change back proj matrix +								qglMatrixMode(GL_PROJECTION); +								qglLoadMatrixf(backEnd.viewParms.projectionMatrix); +								qglMatrixMode(GL_MODELVIEW); +							} +						} +						else +						{ +							viewParms_t temp = backEnd.viewParms; + +							R_SetupProjection(&temp, r_znear->value, qfalse); + +							qglMatrixMode(GL_PROJECTION); +							qglLoadMatrixf(temp.projectionMatrix); +							qglMatrixMode(GL_MODELVIEW); +						}  					} -					qglDepthRange (0, 0.3); +					if(!oldDepthRange) +						qglDepthRange (0, 0.3);  				}  				else  				{ -					if(backEnd.viewParms.stereoFrame != STEREO_CENTER) +					if(!wasCrosshair && backEnd.viewParms.stereoFrame != STEREO_CENTER)  					{  						qglMatrixMode(GL_PROJECTION);  						qglLoadMatrixf(backEnd.viewParms.projectionMatrix); @@ -640,6 +659,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {  				}  				oldDepthRange = depthRange; +				wasCrosshair = isCrosshair;  			}  			oldEntityNum = entityNum; diff --git a/code/renderer/tr_cmds.c b/code/renderer/tr_cmds.c index 06a18e8..d506986 100644 --- a/code/renderer/tr_cmds.c +++ b/code/renderer/tr_cmds.c @@ -319,9 +319,9 @@ void R_SetColorMode(GLboolean *rgba, stereoFrame_t stereoFrame, int colormode)  		rgba[0] = GL_FALSE;  		if(colormode == MODE_RED_BLUE) -			rgba[1] = 0; +			rgba[1] = GL_FALSE;  		else if(colormode == MODE_RED_GREEN) -			rgba[2] = 0; +			rgba[2] = GL_FALSE;  	}  } diff --git a/code/renderer/tr_main.c b/code/renderer/tr_main.c index c5996ba..feda105 100644 --- a/code/renderer/tr_main.c +++ b/code/renderer/tr_main.c @@ -456,7 +456,7 @@ void R_SetupFrustum (viewParms_t *dest, float xmin, float xmax, float ymax, floa  	float oppleg, adjleg, length;  	int i; -	if(stereoSep == 0) +	if(stereoSep == 0 && xmin != -xmax)  	{  		// symmetric case can be simplified  		VectorCopy(dest->or.origin, ofsorigin); @@ -513,19 +513,22 @@ R_SetupProjection  void R_SetupProjection(viewParms_t *dest, float zProj, qboolean computeFrustum)  {  	float	xmin, xmax, ymin, ymax; -	float	width, height, stereoSep; +	float	width, height, stereoSep = r_stereoSeparation->value;  	/*  	 * offset the view origin of the viewer for stereo rendering   	 * by setting the projection matrix appropriately.  	 */ -	  -	if(dest->stereoFrame == STEREO_LEFT) -		stereoSep = zProj / r_stereoSeparation->value; -	else if(dest->stereoFrame == STEREO_RIGHT) -		stereoSep = zProj / -r_stereoSeparation->value; -	else -		stereoSep = 0; + +	if(stereoSep != 0) +	{ +		if(dest->stereoFrame == STEREO_LEFT) +			stereoSep = zProj / r_stereoSeparation->value; +		else if(dest->stereoFrame == STEREO_RIGHT) +			stereoSep = zProj / -r_stereoSeparation->value; +		else +			stereoSep = 0; +	}  	ymax = zProj * tan(dest->fovY * M_PI / 360.0f);  	ymin = -ymax; diff --git a/code/renderer/tr_types.h b/code/renderer/tr_types.h index bb917cf..2a10342 100644 --- a/code/renderer/tr_types.h +++ b/code/renderer/tr_types.h @@ -24,27 +24,33 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA  #define __TR_TYPES_H -#define	MAX_DLIGHTS		32			// can't be increased, because bit flags are used on surfaces -#define	MAX_ENTITIES	1023		// can't be increased without changing drawsurf bit packing +#define	MAX_DLIGHTS		32		// can't be increased, because bit flags are used on surfaces +#define	MAX_ENTITIES		1023		// can't be increased without changing drawsurf bit packing  // renderfx flags -#define	RF_MINLIGHT			1		// allways have some light (viewmodel, some items) -#define	RF_THIRD_PERSON		2		// don't draw through eyes, only mirrors (player bodies, chat sprites) -#define	RF_FIRST_PERSON		4		// only draw through eyes (view weapon, damage blood blob) -#define	RF_DEPTHHACK		8		// for view weapon Z crunching -#define	RF_NOSHADOW			64		// don't add stencil shadows - -#define RF_LIGHTING_ORIGIN	128		// use refEntity->lightingOrigin instead of refEntity->origin -									// for lighting.  This allows entities to sink into the floor -									// with their origin going solid, and allows all parts of a -									// player to get the same lighting -#define	RF_SHADOW_PLANE		256		// use refEntity->shadowPlane -#define	RF_WRAP_FRAMES		512		// mod the model frames by the maxframes to allow continuous -									// animation without needing to know the frame count +#define	RF_MINLIGHT		0x0001		// allways have some light (viewmodel, some items) +#define	RF_THIRD_PERSON		0x0002		// don't draw through eyes, only mirrors (player bodies, chat sprites) +#define	RF_FIRST_PERSON		0x0004		// only draw through eyes (view weapon, damage blood blob) +#define	RF_DEPTHHACK		0x0008		// for view weapon Z crunching + +#define RF_CROSSHAIR		0x0010		// This item is a cross hair and will draw over everything similar to +						// DEPTHHACK in stereo rendering mode, with the difference that the +						// projection matrix won't be hacked to reduce the stereo separation as +						// is done for the gun. + +#define	RF_NOSHADOW		0x0040		// don't add stencil shadows + +#define RF_LIGHTING_ORIGIN	0x0080		// use refEntity->lightingOrigin instead of refEntity->origin +						// for lighting.  This allows entities to sink into the floor +						// with their origin going solid, and allows all parts of a +						// player to get the same lighting + +#define	RF_SHADOW_PLANE		0x0100		// use refEntity->shadowPlane +#define	RF_WRAP_FRAMES		0x0200		// mod the model frames by the maxframes to allow continuous  // refdef flags -#define RDF_NOWORLDMODEL	1		// used for player configuration screen -#define RDF_HYPERSPACE		4		// teleportation effect +#define RDF_NOWORLDMODEL	0x0001		// used for player configuration screen +#define RDF_HYPERSPACE		0x0004		// teleportation effect  typedef struct {  	vec3_t		xyz;  | 
