Пример #1
0
// Returns qtrue if another view has been rendered
qboolean R_MirrorViewBySurface (drawSurf_t *drawSurf, int entityNum) {
	vector4			clipDest[128];
	viewParms_t		newParms;
	viewParms_t		oldParms;
	orientation_t	surface, camera;

	// don't recursively mirror
	if (tr.viewParms.isPortal) {
		ri->Printf( PRINT_DEVELOPER, "WARNING: recursive mirror/portal found\n" );
		return qfalse;
	}

	if ( r_noportals->integer || (r_fastsky->integer == 1) ) {
		return qfalse;
	}

	// trivially reject portal/mirror
	if ( SurfIsOffscreen( drawSurf, clipDest ) ) {
		return qfalse;
	}

	// save old viewParms so we can return to it after the mirror view
	oldParms = tr.viewParms;

	newParms = tr.viewParms;
	newParms.isPortal = qtrue;
	if ( !R_GetPortalOrientations( drawSurf, entityNum, &surface, &camera, 
		&newParms.pvsOrigin, &newParms.isMirror ) ) {
		return qfalse;		// bad portal, no portalentity
	}

	R_MirrorPoint (&oldParms.or.origin, &surface, &camera, &newParms.or.origin );

	VectorSubtract( &vec3_origin, &camera.axis[0], &newParms.portalPlane.normal );
	newParms.portalPlane.dist = DotProduct( &camera.origin, &newParms.portalPlane.normal );
	
	R_MirrorVector (&oldParms.or.axis[0], &surface, &camera, &newParms.or.axis[0]);
	R_MirrorVector (&oldParms.or.axis[1], &surface, &camera, &newParms.or.axis[1]);
	R_MirrorVector (&oldParms.or.axis[2], &surface, &camera, &newParms.or.axis[2]);

	// OPTIMIZE: restrict the viewport on the mirrored view

	// render the mirror view
	R_RenderView (&newParms);

	tr.viewParms = oldParms;

	return qtrue;
}
Пример #2
0
/*
========================
R_MirrorViewBySurface
========================
*/
static viewDef_t *R_MirrorViewBySurface( drawSurf_t *drawSurf ) {
	viewDef_t		*parms;
	orientation_t	surface, camera;
	idPlane			originalPlane, plane;

	// copy the viewport size from the original
	parms = (viewDef_t *)R_FrameAlloc( sizeof( *parms ) );
	*parms = *tr.viewDef;
	parms->renderView.viewID = 0;	// clear to allow player bodies to show up, and suppress view weapons

	parms->isSubview = true;
	parms->isMirror = true;

	// create plane axis for the portal we are seeing
	R_PlaneForSurface( drawSurf->geo, originalPlane );
	R_LocalPlaneToGlobal( drawSurf->space->modelMatrix, originalPlane, plane );

	surface.origin = plane.Normal() * -plane[3];
	surface.axis[0] = plane.Normal();
	surface.axis[0].NormalVectors( surface.axis[1], surface.axis[2] );
	surface.axis[2] = -surface.axis[2];

	camera.origin = surface.origin;
	camera.axis[0] = -surface.axis[0];
	camera.axis[1] = surface.axis[1];
	camera.axis[2] = surface.axis[2];

	// set the mirrored origin and axis
	R_MirrorPoint( tr.viewDef->renderView.vieworg, &surface, &camera, parms->renderView.vieworg );

	R_MirrorVector( tr.viewDef->renderView.viewaxis[0], &surface, &camera, parms->renderView.viewaxis[0] );
	R_MirrorVector( tr.viewDef->renderView.viewaxis[1], &surface, &camera, parms->renderView.viewaxis[1] );
	R_MirrorVector( tr.viewDef->renderView.viewaxis[2], &surface, &camera, parms->renderView.viewaxis[2] );

	// make the view origin 16 units away from the center of the surface
	idVec3	viewOrigin = ( drawSurf->geo->bounds[0] + drawSurf->geo->bounds[1] ) * 0.5;
	viewOrigin += ( originalPlane.Normal() * 16 );

	R_LocalPointToGlobal( drawSurf->space->modelMatrix, viewOrigin, parms->initialViewAreaOrigin );

	// set the mirror clip plane
	parms->numClipPlanes = 1;
	parms->clipPlanes[0] = -camera.axis[0];

	parms->clipPlanes[0][3] = -( camera.origin * parms->clipPlanes[0].Normal() );
	
	return parms;
}
Пример #3
0
/*
========================
R_DoWaterView 

Returns qtrue if another view has been rendered
========================
*/
qboolean R_DoWaterView (drawSurf_t *drawSurf, int entityNum) {
//	vec4_t			clipDest[128];
	viewParms_t		newParms;
	viewParms_t		oldParms;
	orientation_t	surface, camera;
	cplane_t		plane;
	srfSurfaceStatic_t *srf;
		
	// don't recursively do water
	if (tr.viewParms.doWater) {
		// tesselated water has this issue - so we just ignore and not spam console
		// ri.Printf( PRINT_DEVELOPER, "WARNING: recursive water found\n" );
		return qfalse;
	}

	srf = (srfSurfaceStatic_t *)drawSurf->surface;
	// trivially reject portal/mirror
	//This wont work because vbo surfs dont fill out tess...
	//if ( SurfIsOffscreen( drawSurf, clipDest ) ) {
	//	return qfalse;
	//}

	//Set plane
	tr.viewParms.doWater = qtrue;
	tr.viewParms.waterPlane.normal[0] = 0;
	tr.viewParms.waterPlane.normal[1] = 0;
	tr.viewParms.waterPlane.normal[2] = -1;
	tr.viewParms.waterPlane.dist = srf->origin[2];

	if ( DotProduct(tr.viewParms.waterPlane.normal,tr.viewParms.or.origin)+tr.viewParms.waterPlane.dist >0)
	{
		tr.viewParms.isUnderwater=qtrue;	
	}

	// save old viewParms so we can return to it after the mirror view
	oldParms = tr.viewParms;

	newParms = tr.viewParms;
	newParms.isWater = 1;
	newParms.viewportWidth=WATER_RES_X;
	newParms.viewportHeight=WATER_RES_Y;
	newParms.viewportX =0;//tr.refdef.x;
	newParms.viewportY =0;// glConfig.vidHeight - ( tr.refdef.y + WATER_RES_Y );


	tr.refdef.rdflags|= RDF_NOEFFECTS ;

	// render the mirror view
	R_RenderView (&newParms);

	//Do the second view now
	newParms = tr.viewParms;
	newParms.isWater = 2;
	newParms.isMirror = qtrue;
	newParms.viewportWidth = WATER_RES_X;
	newParms.viewportHeight = WATER_RES_Y;
	newParms.viewportX = 0;//tr.refdef.x;
	newParms.viewportY = 0;//glConfig.vidHeight - ( tr.refdef.y + WATER_RES_Y );
	

	plane.dist=tr.viewParms.waterPlane.dist;
	plane.normal[0]=-tr.viewParms.waterPlane.normal[0];
	plane.normal[1]=-tr.viewParms.waterPlane.normal[1];
	plane.normal[2]=-tr.viewParms.waterPlane.normal[2];

	R_GetSurfaceOrientations( &plane, &surface, &camera );

	R_MirrorPoint (oldParms.or.origin, &surface, &camera, newParms.or.origin );
	R_MirrorVector (oldParms.or.axis[0], &surface, &camera, newParms.or.axis[0]);
	R_MirrorVector (oldParms.or.axis[1], &surface, &camera, newParms.or.axis[1]);
	R_MirrorVector (oldParms.or.axis[2], &surface, &camera, newParms.or.axis[2]);


	// render the mirror view
	tr.refdef.rdflags|= RDF_NOEFFECTS;
	R_RenderView (&newParms); 

	tr.viewParms = oldParms;
	tr.refdef.rdflags&= ~RDF_NOEFFECTS;
	
	return qtrue; 
}
/*
========================
R_MirrorViewBySurface
========================
*/
static viewDef_t* R_MirrorViewBySurface( const drawSurf_t* drawSurf )
{
	// copy the viewport size from the original
	viewDef_t* parms = ( viewDef_t* )R_FrameAlloc( sizeof( *parms ) );
	*parms = *tr.viewDef;
	parms->renderView.viewID = 0;	// clear to allow player bodies to show up, and suppress view weapons
	
	parms->isSubview = true;
	parms->isMirror = true;
	parms->isObliqueProjection = false;
	
	// create plane axis for the portal we are seeing
	idPlane originalPlane, plane;
	R_PlaneForSurface( drawSurf->frontEndGeo, originalPlane );
	R_LocalPlaneToGlobal( drawSurf->space->modelMatrix, originalPlane, plane );
	
	orientation_t surface;
	surface.origin = plane.Normal() * -plane[3];
	surface.axis[0] = plane.Normal();
	surface.axis[0].NormalVectors( surface.axis[1], surface.axis[2] );
	surface.axis[2] = -surface.axis[2];
	
	orientation_t camera;
	camera.origin = surface.origin;
	camera.axis[0] = -surface.axis[0];
	camera.axis[1] = surface.axis[1];
	camera.axis[2] = surface.axis[2];
	
	// set the mirrored origin and axis
	R_MirrorPoint( tr.viewDef->renderView.vieworg, &surface, &camera, parms->renderView.vieworg );
	
	R_MirrorVector( tr.viewDef->renderView.viewaxis[0], &surface, &camera, parms->renderView.viewaxis[0] );
	R_MirrorVector( tr.viewDef->renderView.viewaxis[1], &surface, &camera, parms->renderView.viewaxis[1] );
	R_MirrorVector( tr.viewDef->renderView.viewaxis[2], &surface, &camera, parms->renderView.viewaxis[2] );
	
	// make the view origin 16 units away from the center of the surface
	const idVec3 center = (drawSurf->frontEndGeo->bounds[0] + drawSurf->frontEndGeo->bounds[1]) * 0.5f;
	const idVec3 viewOrigin = center + (originalPlane.Normal() * 16.0f);

	R_LocalPointToGlobal(drawSurf->space->modelMatrix, viewOrigin, parms->initialViewAreaOrigin);

	// set the mirror clip plane
	parms->numClipPlanes = 1;
	parms->clipPlanes[0] = -camera.axis[0];
	
	parms->clipPlanes[0][3] = -( camera.origin * parms->clipPlanes[0].Normal() );
	
	if (r_waterReflectFix.GetBool() && !parms->is2Dgui && drawSurf->material->GetSurfaceType() == SURFTYPE_MIRROR)
	{
		parms->isObliqueProjection = true;
		float dist = parms->clipPlanes[0].Dist();
		float viewdist = parms->renderView.vieworg * parms->clipPlanes[0].Normal();
		float fDist = -dist + viewdist;
		static const float fudge = 2.f;	//fudge avoids depth precision artifacts when performing oblique projection
		if (fDist > fudge || fDist < -fudge)
		{
			if (fDist < 0.f)
				fDist += fudge;
			else
				fDist -= fudge;
		}

		parms->clipPlanes[0][3] = fDist;		

		R_SetupViewMatrix(parms);
		R_SetupProjectionMatrix(parms);
		R_ObliqueProjection(parms);
	}

	return parms;
}