Exemple #1
0
/*
===============
R_DrawCubemapView
===============
*/
void R_DrawCubemapView( const vec3_t origin, const vec3_t angles, int size )
{
	ref_params_t *fd;

	if( clgame.drawFuncs.R_DrawCubemapView != NULL )
	{
		if( clgame.drawFuncs.R_DrawCubemapView( origin, angles, size ))
			return;
	}

	fd = &RI.refdef;
	*fd = r_lastRefdef;
	fd->time = 0;
	fd->viewport[0] = 0;
	fd->viewport[1] = 0;
	fd->viewport[2] = size;
	fd->viewport[3] = size;
	fd->fov_x = 90;
	fd->fov_y = 90;
	VectorCopy( origin, fd->vieworg );
	VectorCopy( angles, fd->viewangles );
	VectorCopy( fd->vieworg, RI.pvsorigin );
		
	// setup viewport
	RI.viewport[0] = fd->viewport[0];
	RI.viewport[1] = fd->viewport[1];
	RI.viewport[2] = fd->viewport[2];
	RI.viewport[3] = fd->viewport[3];

	R_RenderScene( fd );

	r_oldviewleaf = r_viewleaf = NULL;		// force markleafs next frame
}
Exemple #2
0
void CLWS_RenderScene( const wsrefdef_t* gameRefdef ) {
	refdef_t rd;
	Com_Memset( &rd, 0, sizeof ( rd ) );
	rd.x = gameRefdef->x;
	rd.y = gameRefdef->y;
	rd.width = gameRefdef->width;
	rd.height = gameRefdef->height;
	rd.fov_x = gameRefdef->fov_x;
	rd.fov_y = gameRefdef->fov_y;
	VectorCopy( gameRefdef->vieworg, rd.vieworg );
	AxisCopy( gameRefdef->viewaxis, rd.viewaxis );
	rd.time = gameRefdef->time;
	rd.rdflags = gameRefdef->rdflags & ( RDF_NOWORLDMODEL | RDF_HYPERSPACE |
										 RDF_SKYBOXPORTAL | RDF_UNDERWATER | RDF_DRAWINGSKY | RDF_SNOOPERVIEW );
	if ( gameRefdef->rdflags & WSRDF_DRAWSKYBOX ) {
		rd.rdflags |= RDF_DRAWSKYBOX;
	}
	Com_Memcpy( rd.areamask, gameRefdef->areamask, sizeof ( rd.areamask ) );
	Com_Memcpy( rd.text, gameRefdef->text, sizeof ( rd.text ) );
	rd.glfog.mode = gameRefdef->glfog.mode;
	rd.glfog.hint = gameRefdef->glfog.hint;
	rd.glfog.startTime = gameRefdef->glfog.startTime;
	rd.glfog.finishTime = gameRefdef->glfog.finishTime;
	Vector4Copy( gameRefdef->glfog.color, rd.glfog.color );
	rd.glfog.start = gameRefdef->glfog.start;
	rd.glfog.end = gameRefdef->glfog.end;
	rd.glfog.useEndForClip = gameRefdef->glfog.useEndForClip;
	rd.glfog.density = gameRefdef->glfog.density;
	rd.glfog.registered = gameRefdef->glfog.registered;
	rd.glfog.drawsky = gameRefdef->glfog.drawsky;
	rd.glfog.clearscreen = gameRefdef->glfog.clearscreen;
	rd.glfog.dirty = gameRefdef->glfog.dirty;
	R_RenderScene( &rd );
}
Exemple #3
0
//	cl.refdef must be set before the first call
static void VQH_RenderScene() {
	R_ClearScene();

	if ( GGameType & GAME_QuakeWorld ) {
		CLQW_EmitEntities();
	} else if ( GGameType & GAME_Quake ) {
		CLQ1_EmitEntities();
	} else if ( GGameType & GAME_HexenWorld ) {
		CLHW_EmitEntities();
	} else {
		CLH2_EmitEntities();
	}

	VQH_AddViewModel();

	if ( GGameType & GAME_Hexen2 ) {
		CLH2_UpdateEffects();
	}

	CL_AddDLights();

	CL_AddLightStyles();
	CL_AddParticles();

	cl.refdef.time = cl.serverTime;

	R_RenderScene( &cl.refdef );

	VQH_DrawColourBlend();
}
Exemple #4
0
/*
================
R_RenderView
================
*/
void R_RenderView (void)
{
	double	time1, time2;

	if (r_norefresh.value)
		return;

	if (!cl.worldmodel)
		Sys_Error ("R_RenderView: NULL worldmodel");

	time1 = 0; /* avoid compiler warning */
	if (r_speeds.value)
	{
		//glFinish ();
		time1 = Sys_DoubleTime ();

		//johnfitz -- rendering statistics
		rs_brushpolys = rs_aliaspolys = rs_skypolys = rs_particles = rs_fogpolys = rs_megatexels =
		rs_dynamiclightmaps = rs_aliaspasses = rs_skypasses = rs_brushpasses = 0;
	}
	//else if (gl_finish.value)
	//	glFinish ();

	R_SetupView (); //johnfitz -- this does everything that should be done once per frame

	R_RenderScene ();

	//johnfitz

	//johnfitz -- modified r_speeds output
	time2 = Sys_DoubleTime ();
	if (r_pos.value)
		Con_Printf ("x %i y %i z %i (pitch %i yaw %i roll %i)\n",
			(int)cl_entities[cl.viewentity].origin[0],
			(int)cl_entities[cl.viewentity].origin[1],
			(int)cl_entities[cl.viewentity].origin[2],
			(int)cl.viewangles[PITCH],
			(int)cl.viewangles[YAW],
			(int)cl.viewangles[ROLL]);
	else if (r_speeds.value == 2)
		Con_Printf ("%3i ms  %4i/%4i wpoly %4i/%4i epoly %3i lmap %4i/%4i sky %1.1f mtex\n",
					(int)((time2-time1)*1000),
					rs_brushpolys,
					rs_brushpasses,
					rs_aliaspolys,
					rs_aliaspasses,
					rs_dynamiclightmaps,
					rs_skypolys,
					rs_skypasses,
					TexMgr_FrameUsage ());
	else if (r_speeds.value)
		Con_Printf ("%3i ms  %4i wpoly %4i epoly %3i lmap\n",
					(int)((time2-time1)*1000),
					rs_brushpolys,
					rs_aliaspolys,
					rs_dynamiclightmaps);
	//johnfitz
}
/*
================
R_RenderView

r_refdef must be set before the first call
================
*/
void R_RenderView (void)
{
	double time1 = 0.0;
	double time2;
	GLfloat colors[4] = {(GLfloat) 0.0, (GLfloat) 0.0, (GLfloat) 1, (GLfloat) 0.20};

	if (r_norefresh.value)
		return;

	if (!r_worldentity.model || !cl.worldmodel)
		Sys_Error ("R_RenderView: NULL worldmodel");

	if (r_speeds.value)
	{
		glFinish ();
		time1 = Sys_FloatTime ();
		c_brush_polys = 0;
		c_alias_polys = 0;
	}

	mirror = false;

	if (gl_finish.value)
		glFinish ();

	R_Clear ();

	// render normal view

/***** Experimental silly looking fog ******
****** Use r_fullbright if you enable ******
	glFogi(GL_FOG_MODE, GL_LINEAR);
	glFogfv(GL_FOG_COLOR, colors);
	glFogf(GL_FOG_END, 512.0);
	glEnable(GL_FOG);
********************************************/

	R_RenderScene ();
	R_DrawViewModel ();
	R_DrawWaterSurfaces ();

//  More fog right here :)
//	glDisable(GL_FOG);
//  End of all fog code...

	// render mirror view
	R_Mirror ();

	R_PolyBlend ();

	if (r_speeds.value)
	{
//		glFinish ();
		time2 = Sys_FloatTime ();
		Con_Printf ("%3i ms  %4i wpoly %4i epoly\n", (int)((time2-time1)*1000), c_brush_polys, c_alias_polys);
	}
}
Exemple #6
0
/*
===============
R_RenderFrame
===============
*/
void R_RenderFrame( const ref_params_t *fd, qboolean drawWorld )
{
	if( r_norefresh->integer )
		return;

	tr.realframecount++;

	if( RI.drawOrtho != gl_overview->integer )
		tr.fResetVis = true;

	// completely override rendering
	if( clgame.drawFuncs.GL_RenderFrame != NULL )
	{
		if( clgame.drawFuncs.GL_RenderFrame( fd, drawWorld ))
		{
			RI.drawWorld = drawWorld;
			tr.fResetVis = true;
			return;
		}
	}

	if( drawWorld ) r_lastRefdef = *fd;

	RI.params = RP_NONE;
	RI.farClip = 0;
	RI.clipFlags = 15;
	RI.drawWorld = drawWorld;
	RI.thirdPerson = cl.thirdperson;
	RI.drawOrtho = (RI.drawWorld) ? gl_overview->integer : 0;

	GL_BackendStartFrame();

	if( !r_lockcull->integer )
		VectorCopy( fd->vieworg, RI.cullorigin );
	VectorCopy( fd->vieworg, RI.pvsorigin );

	// setup viewport
	RI.viewport[0] = fd->viewport[0];
	RI.viewport[1] = fd->viewport[1];
	RI.viewport[2] = fd->viewport[2];
	RI.viewport[3] = fd->viewport[3];

	if( gl_finish->integer && drawWorld )
		pglFinish();

	if( gl_allow_mirrors->integer )
	{
		// render mirrors
		R_FindMirrors( fd );
		R_DrawMirrors ();
	}

	R_RenderScene( fd );

	GL_BackendEndFrame();
}
Exemple #7
0
// CSQC_UpdateView - Called every rendered frame on the client.  Useful for HUD drawing operations.
void CSQC_UpdateView(float vwidth, float vheight)
{	
	R_ClearScene();// ALWAYS Clear Current Scene First
	// Assign Standard Viewflags
	R_SetView(VF_DRAWWORLD, 1);// Draw the World (and sky) - this MUST be set to 1!
	R_SetView(VF_DRAWCROSSHAIR, 1);// Draw the Crosshair
	R_SetView(VF_DRAWENGINESBAR, 0);//Don't draw Quake status bar
	// Setup Entities to be Rendered (include all base types; normal, engine and viewmodels)
	View_UpdateEveryFrame();
	R_SetView(VF_ORIGIN, CSQC_VIEW);
	R_AddEntities(MASK_ENGINE | MASK_ENGINEVIEWMODELS | MASK_NORMAL );
	// Render the Scene
	R_RenderScene();
	GUI_HudDraw();
}
Exemple #8
0
/*
================
R_RenderView

r_refdef must be set before the first call
================
*/
void R_RenderView (void)
{
	double	time1 = 0, time2;

	if (r_norefresh.value)
		return;

	if (!r_worldentity.model || !cl.worldmodel)
		Sys_Error ("R_RenderView: NULL worldmodel");

	if (r_speeds.value)
	{
		glFinish ();
		time1 = Sys_DoubleTime ();
		c_brush_polys = 0;
		c_alias_polys = 0;
	}

	mirror = false;

	if (gl_finish.value)
		glFinish ();

	R_Clear ();

	// render normal view
	R_RenderScene ();
	R_DrawViewModel ();
	R_DrawWaterSurfaces ();

	// render mirror view
//	R_Mirror ();

	R_PolyBlend ();

	if (r_speeds.value)
	{
//		glFinish ();
		time2 = Sys_DoubleTime ();
		Con_Printf ("%3i ms  %4i wpoly %4i epoly\n", (int)((time2-time1)*1000), c_brush_polys, c_alias_polys); 
	}
}
/*
================
R_RenderView
================
*/
void R_RenderView (void)
{
	double	time1, time2;

	if (r_norefresh.value)
		return;

	if (!cl.worldmodel)
		Sys_Error ("R_RenderView: NULL worldmodel");

	time1 = 0; /* avoid compiler warning */
	if (r_speeds.value)
	{
		glFinish ();
		time1 = Sys_DoubleTime ();

		//johnfitz -- rendering statistics
		rs_brushpolys = rs_aliaspolys = rs_skypolys = rs_particles = rs_fogpolys = rs_megatexels =
		rs_dynamiclightmaps = rs_aliaspasses = rs_skypasses = rs_brushpasses = 0;
	}
	else if (gl_finish.value)
		glFinish ();

	if (vr_enabled.value)
	{
		VR_SetupView (); // jeremiah sypult -- allow VR to get in there before R_SetupView
	}
	else
	{
		R_SetupView (); //johnfitz -- this does everything that should be done once per frame
	}

	//johnfitz -- stereo rendering -- full of hacky goodness
	if (r_stereo.value)
	{
		float eyesep = CLAMP(-8.0f, r_stereo.value, 8.0f);
		float fdepth = CLAMP(32.0f, r_stereodepth.value, 1024.0f);

		AngleVectors (r_refdef.viewangles, vpn, vright, vup);

		//render left eye (red)
		glColorMask(1, 0, 0, 1);
		VectorMA (r_refdef.vieworg, -0.5f * eyesep, vright, r_refdef.vieworg);
		frustum_skew = 0.5 * eyesep * gl_nearclip.value / fdepth;
		srand((int) (cl.time * 1000)); //sync random stuff between eyes

		R_RenderScene ();

		//render right eye (cyan)
		glClear (GL_DEPTH_BUFFER_BIT);
		glColorMask(0, 1, 1, 1);
		VectorMA (r_refdef.vieworg, 1.0f * eyesep, vright, r_refdef.vieworg);
		frustum_skew = -frustum_skew;
		srand((int) (cl.time * 1000)); //sync random stuff between eyes

		R_RenderScene ();

		//restore
		glColorMask(1, 1, 1, 1);
		VectorMA (r_refdef.vieworg, -0.5f * eyesep, vright, r_refdef.vieworg);
		frustum_skew = 0.0f;
	}
	else
	{
		R_RenderScene ();
	}
	//johnfitz

	//johnfitz -- modified r_speeds output
	time2 = Sys_DoubleTime ();
	if (r_speeds.value == 2)
		Con_Printf ("%3i ms  %4i/%4i wpoly %4i/%4i epoly %3i lmap %4i/%4i sky %1.1f mtex\n",
					(int)((time2-time1)*1000),
					rs_brushpolys,
					rs_brushpasses,
					rs_aliaspolys,
					rs_aliaspasses,
					rs_dynamiclightmaps,
					rs_skypolys,
					rs_skypasses,
					TexMgr_FrameUsage ());
	else if (r_speeds.value)
		Con_Printf ("%3i ms  %4i wpoly %4i epoly %3i lmap\n",
					(int)((time2-time1)*1000),
					rs_brushpolys,
					rs_aliaspolys,
					rs_dynamiclightmaps);
	//johnfitz
}
Exemple #10
0
/*
=============
R_Mirror
=============
*/
void R_Mirror (void)
{
	float		d;
	msurface_t	*s;
	entity_t	*ent;

	if (!mirror)
		return;

	memcpy (r_base_world_matrix, r_world_matrix, sizeof(r_base_world_matrix));

	d = DotProduct (r_refdef.vieworg, mirror_plane->normal) - mirror_plane->dist;
	VectorMA (r_refdef.vieworg, -2*d, mirror_plane->normal, r_refdef.vieworg);

	d = DotProduct (vpn, mirror_plane->normal);
	VectorMA (vpn, -2*d, mirror_plane->normal, vpn);

	r_refdef.viewangles[0] = -asin (vpn[2])/M_PI*180;
	r_refdef.viewangles[1] = atan2 (vpn[1], vpn[0])/M_PI*180;
	r_refdef.viewangles[2] = -r_refdef.viewangles[2];

	ent = &cl_entities[cl.viewentity];
	if (cl_numvisedicts < MAX_VISEDICTS)
	{
		cl_visedicts[cl_numvisedicts] = ent;
		cl_numvisedicts++;
	}

	gldepthmin = 0.5;
	gldepthmax = 1;
	glDepthRange (gldepthmin, gldepthmax);
	glDepthFunc (GL_LEQUAL);

	R_RenderScene ();
	R_DrawWaterSurfaces ();

	gldepthmin = 0;
	gldepthmax = 0.5;
	glDepthRange (gldepthmin, gldepthmax);
	glDepthFunc (GL_LEQUAL);

	// blend on top
	glEnable (GL_BLEND);
	glMatrixMode(GL_PROJECTION);
	if (mirror_plane->normal[2])
		glScalef (1,-1,1);
	else
		glScalef (-1,1,1);
	glCullFace(GL_FRONT);
	glMatrixMode(GL_MODELVIEW);

	glLoadMatrixf (r_base_world_matrix);

	glColor4f (1,1,1,r_mirroralpha.value);
	s = cl.worldmodel->textures[mirrortexturenum]->texturechain;
	for ( ; s ; s=s->texturechain)
		R_RenderBrushPoly (s);
	cl.worldmodel->textures[mirrortexturenum]->texturechain = NULL;
	glDisable (GL_BLEND);
	glColor4f (1,1,1,1);
}
void R_RenderView (void)
{
	double	time1 = 0,
			time2;

	if (r_norefresh.value)
		return;

	if (!cl.worldmodel)
		Sys_Error ("R_RenderView: NULL worldmodel");

	if(r_speeds.value)
	{
		glFinish ();
		time1 = System_DoubleTime();

		//johnfitz -- rendering statistics
		rs_brushpolys = rs_aliaspolys = rs_skypolys = rs_particles = rs_fogpolys = rs_megatexels =
		rs_dynamiclightmaps = rs_aliaspasses = rs_skypasses = rs_brushpasses = 0;
	}

	R_SetupView (); //johnfitz -- this does everything that should be done once per frame

	Video_ClearBuffer();

	//johnfitz -- stereo rendering -- full of hacky goodness
	if (r_stereo.value)
	{
		float	eyesep = Math_Clamp(-8.0f, r_stereo.value, 8.0f),
			fdepth = Math_Clamp(32.0f, r_stereodepth.value, 1024.0f);

		Math_AngleVectors(r_refdef.viewangles, vpn, vright, vup);

		// Render left eye (red)
		glColorMask(true,false,false,true);
		Math_VectorMA (r_refdef.vieworg, -0.5f * eyesep, vright, r_refdef.vieworg);
		frustum_skew = 0.5f*eyesep*NEARCLIP/fdepth;
		srand((int) (cl.time * 1000)); //sync random stuff between eyes

		R_RenderScene();

		// Render right eye (cyan)
		glClear (GL_DEPTH_BUFFER_BIT);
		glColorMask(0, 1, 1, 1);
		Math_VectorMA (r_refdef.vieworg, 1.0f * eyesep, vright, r_refdef.vieworg);
		frustum_skew = -frustum_skew;
		srand((int) (cl.time * 1000)); //sync random stuff between eyes

		R_RenderScene();

		// Restore
		glColorMask(true,true,true,true);
		Math_VectorMA (r_refdef.vieworg, -0.5f * eyesep, vright, r_refdef.vieworg);
		frustum_skew = 0.0f;
	}
	else
		R_RenderScene();
	//johnfitz

	//johnfitz -- modified r_speeds output
	time2 = System_DoubleTime();
	if(r_speeds.value == 2)
		Con_Printf(	"%3i ms  %4i/%4i wpoly %4i/%4i epoly %3i lmap %4i/%4i sky %1.1f mtex\n",
					(int)((time2-time1)*1000),
					rs_brushpolys,
					rs_brushpasses,
					rs_aliaspolys,
					rs_aliaspasses,
					rs_dynamiclightmaps,
					rs_skypolys,
					rs_skypasses,
					TexMgr_FrameUsage ());
	else if(r_speeds.value)
		Con_Printf ("%3i ms  %4i wpoly %4i epoly %3i lmap\n",
					(int)((time2-time1)*1000),
					rs_brushpolys,
					rs_aliaspolys,
					rs_dynamiclightmaps);
	//johnfitz
}
Exemple #12
0
/*
================
R_DrawMirrors

Draw all viewpasess from mirror position
Mirror textures will be drawn in normal pass
================
*/
void R_DrawMirrors( void )
{
	ref_instance_t	oldRI;
	mplane_t		plane;
	msurface_t	*surf, *surf2;
	int		i, oldframecount;
	mextrasurf_t	*es, *tmp, *mirrorchain;
	vec3_t		forward, right, up;
	vec3_t		origin, angles;
	matrix4x4		mirrormatrix;
	cl_entity_t	*e;
	model_t		*m;
	float		d;

	if( !tr.num_mirror_entities ) return; // mo mirrors for this frame

	oldRI = RI; // make refinst backup
	oldframecount = tr.framecount;

	for( i = 0; i < tr.num_mirror_entities; i++ )
	{
		mirrorchain = tr.mirror_entities[i].chain;

		for( es = mirrorchain; es != NULL; es = es->mirrorchain )
		{
			RI.currententity = e = tr.mirror_entities[i].ent;
			RI.currentmodel = m = RI.currententity->model;

			surf = INFO_SURF( es, m );

			ASSERT( RI.currententity != NULL );
			ASSERT( RI.currentmodel != NULL );

			// NOTE: copy mirrortexture and mirrormatrix from another surfaces
			// from this entity\world that has same planes and reduce number of viewpasses

			// make sure what we have one pass at least
			if( es != mirrorchain )
			{
				for( tmp = mirrorchain; tmp != es; tmp = tmp->mirrorchain )
				{
					surf2 = INFO_SURF( tmp, m );

					if( !tmp->mirrortexturenum )
						continue;	// not filled?

					if( surf->plane->dist != surf2->plane->dist )
						continue;

					if( !VectorCompare( surf->plane->normal, surf2->plane->normal ))
						continue;

					// found surface with same plane!
					break;
				}

				if( tmp != es && tmp && tmp->mirrortexturenum )
				{
					// just copy reflection texture from surface with same plane
					Matrix4x4_Copy( es->mirrormatrix, tmp->mirrormatrix );
					es->mirrortexturenum = tmp->mirrortexturenum;
					continue;	// pass skiped
				}
			} 

			R_PlaneForMirror( surf, &plane, mirrormatrix );

			d = -2.0f * ( DotProduct( RI.vieworg, plane.normal ) - plane.dist );
			VectorMA( RI.vieworg, d, plane.normal, origin );

			d = -2.0f * DotProduct( RI.vforward, plane.normal );
			VectorMA( RI.vforward, d, plane.normal, forward );
			VectorNormalize( forward );

			d = -2.0f * DotProduct( RI.vright, plane.normal );
			VectorMA( RI.vright, d, plane.normal, right );
			VectorNormalize( right );

			d = -2.0f * DotProduct( RI.vup, plane.normal );
			VectorMA( RI.vup, d, plane.normal, up );
			VectorNormalize( up );

			VectorsAngles( forward, right, up, angles );
			angles[ROLL] = -angles[ROLL];

			RI.params = RP_MIRRORVIEW|RP_CLIPPLANE|RP_OLDVIEWLEAF;

			RI.clipPlane = plane;
			RI.clipFlags |= ( 1<<5 );

			RI.frustum[5] = plane;
			RI.frustum[5].signbits = SignbitsForPlane( RI.frustum[5].normal );
			RI.frustum[5].type = PLANE_NONAXIAL;

			RI.refdef.viewangles[0] = anglemod( angles[0] );
			RI.refdef.viewangles[1] = anglemod( angles[1] );
			RI.refdef.viewangles[2] = anglemod( angles[2] );
			VectorCopy( origin, RI.refdef.vieworg );
			VectorCopy( origin, RI.cullorigin );

			// put pvsorigin before the mirror plane to avoid get full visibility on world mirrors
			if( RI.currententity == clgame.entities )
			{
				VectorMA( es->origin, 1.0f, plane.normal, origin );
			}
			else
			{
				Matrix4x4_VectorTransform( mirrormatrix, es->origin, origin );
				VectorMA( origin, 1.0f, plane.normal, origin );
			}

			VectorCopy( origin, RI.pvsorigin );

			// combine two leafs from client and mirror views
			r_viewleaf = Mod_PointInLeaf( oldRI.pvsorigin, cl.worldmodel->nodes );
			r_viewleaf2 = Mod_PointInLeaf( RI.pvsorigin, cl.worldmodel->nodes );

			if( GL_Support( GL_ARB_TEXTURE_NPOT_EXT ))
			{
				// allow screen size
				RI.viewport[2] = bound( 96, RI.viewport[2], 1024 );
				RI.viewport[3] = bound( 72, RI.viewport[3], 768 );
			}
			else
			{
				RI.viewport[2] = NearestPOW( RI.viewport[2], true );
				RI.viewport[3] = NearestPOW( RI.viewport[3], true );
				RI.viewport[2] = bound( 128, RI.viewport[2], 1024 );
				RI.viewport[3] = bound( 64, RI.viewport[3], 512 );
			}

			tr.framecount++;
			R_RenderScene( &RI.refdef );
			r_stats.c_mirror_passes++;

			es->mirrortexturenum = R_AllocateMirrorTexture();

			// create personal projection matrix for mirror
			if( VectorIsNull( e->origin ) && VectorIsNull( e->angles ))
			{
				Matrix4x4_Copy( es->mirrormatrix, RI.worldviewProjectionMatrix );
			}
			else
			{
				Matrix4x4_ConcatTransforms( RI.modelviewMatrix, RI.worldviewMatrix, mirrormatrix );
				Matrix4x4_Concat( es->mirrormatrix, RI.projectionMatrix, RI.modelviewMatrix );
			}			

			RI = oldRI; // restore ref instance
		}

		// clear chain for this entity
		for( es = mirrorchain; es != NULL; )
		{
			tmp = es->mirrorchain;
			es->mirrorchain = NULL;
			es = tmp;
		}

		tr.mirror_entities[i].chain = NULL; // done
		tr.mirror_entities[i].ent = NULL;
	}

	r_oldviewleaf = r_viewleaf = NULL;	// force markleafs next frame
	tr.framecount = oldframecount;	// restore real framecount
	tr.num_mirror_entities = 0;
	tr.num_mirrors_used = 0;
}
void __cdecl R_GenerateReflectionRawData(DiskGfxReflectionProbe* probeRawData)
{
	if (!*g_ffDir)
	{
		sprintf_s(g_ffDir, "%s/%s/", Dvar_GetString("fs_basepath"), Dvar_GetString("fs_game"));
	}

	refdef_s refdef;
	char* ptr = *((char**)0x02FF5354);
	refdef_s* refsrc = (refdef_s*)(ptr + 0x8C100);
	memcpy(&refdef, refsrc, sizeof(refdef_s));

	refdef.vieworg[1] = probeRawData->origin[0];
	refdef.vieworg[2] = probeRawData->origin[1];
	refdef.yaw = probeRawData->origin[2];

	R_InitPrimaryLights(refdef.primaryLights[0].dir);

	for (int cubemapShot = 1; cubemapShot < 7; cubemapShot++)
	{
		R_BeginCubemapShot(256, 0);
		R_BeginFrame();

		GfxCmdArray* s_cmdList = *(GfxCmdArray**)0x03B370C0;
		GfxBackEndData* frontEndDataOut = *(GfxBackEndData**)0x03B3708C;
		frontEndDataOut->cmds = &s_cmdList->cmds[s_cmdList->usedTotal];
		frontEndDataOut->viewInfo[frontEndDataOut->viewInfoCount].cmds = NULL;

		R_ClearScene(0);
		FX_BeginUpdate(0);
		R_CalcCubeMapViewValues(&refdef, cubemapShot, 256);

		float* vec = (float*)0x3AC3060;
		vec[0] = refdef.vieworg[0];
		vec[1] = refdef.vieworg[1];
		vec[2] = refdef.vieworg[2];

		int* unk1 = (int*)0x3AC3058;		*unk1 = refdef.time;
		float* unk2 = (float*)0x3AC305C;	*unk2 = refdef.time * 0.001f;

		R_UpdateFrameFog(refdef.localClientNum);
		R_UpdateFrameSun();

		float zFar = R_GetFarPlaneDist();
		FxCameraUpdate fxUpdateCmd;
		memset(&fxUpdateCmd, 0, sizeof(FxCameraUpdate));
		FxCmd cmd;
		memset(&cmd, 0, sizeof(FxCmd));

		FX_GetCameraUpdateFromRefdefAndZFar(&fxUpdateCmd, &refdef, zFar);
		FX_SetNextUpdateCamera(0, &fxUpdateCmd);
		FX_FillUpdateCmd(0, &cmd);
		Sys_ResetUpdateSpotLightEffectEvent();
		Sys_AddWorkerCmdInternal((void*)0x00BA5420, &cmd, 0);
		Sys_ResetUpdateNonDependentEffectsEvent();
		Sys_AddWorkerCmdInternal((void*)0x00BA52E0, &cmd, 0);
		Sys_AddWorkerCmdInternal((void*)0x00BA5300, &cmd, 0);
		Sys_AddWorkerCmdInternal((void*)0x00BA5330, &cmd, 0);

		R_RenderScene(&refdef, 0);
		R_EndFrame();

		R_IssueRenderCommands(3);
		R_EndCubemapShot(cubemapShot);
	}

	R_CreateReflectionRawDataFromCubemapShot(probeRawData);
}