Esempio n. 1
0
/*
* R_MarkLeafSurfaces
*/
static void R_MarkLeafSurfaces( msurface_t **mark, unsigned int clipFlags, 
	unsigned int dlightBits, unsigned int shadowBits )
{
	msurface_t *surf;
	unsigned int newDlightBits;
	unsigned int newShadowBits;
	drawSurfaceBSP_t *drawSurf;
	vec3_t centre;
	float distance;

	do
	{
		surf = *mark++;
		drawSurf = surf->drawSurf;

		if( R_CullSurface( rsc.worldent, surf, clipFlags ) ) {
			continue;
		}

		// avoid double-checking dlights that have already been added to drawSurf
		newDlightBits = dlightBits;
		if( drawSurf->dlightFrame == rsc.frameCount ) {
			newDlightBits &= ~drawSurf->dlightBits;
		}
		if( newDlightBits ) {
			newDlightBits = R_SurfaceDlightBits( surf, newDlightBits );
		}

		newShadowBits = R_SurfaceShadowBits( surf, shadowBits );

		if( surf->visFrame != rf.frameCount || newDlightBits || newShadowBits ) {
			VectorAdd( surf->mins, surf->maxs, centre );
			VectorScale( centre, 0.5, centre );
			distance = Distance( rn.refdef.vieworg, centre );

			R_AddSurfaceToDrawList( rsc.worldent, surf, surf->fog, 
				newDlightBits, newShadowBits, distance );
		}

		surf->visFrame = rf.frameCount;
	} while( *mark );
}
Esempio n. 2
0
/*
* R_AddSurfaceToDrawList
*/
static void R_AddSurfaceToDrawList( const entity_t *e, const msurface_t *surf, const mfog_t *fog,
	unsigned int clipFlags, unsigned int dlightBits, unsigned shadowBits, float dist )
{
	int order = 0;
	shader_t *shader;
	drawSurfaceBSP_t *drawSurf;

	if( R_CullSurface( e, surf, clipFlags ) ) {
		return;
	}

	if( r_drawworld->integer == 2 ) {
		shader = rsh.envShader;
	} else {
		shader = surf->shader;

		if( shader->flags & SHADER_SKY ) {
			if( !R_FASTSKY() ) {
				R_AddSkyToDrawList( surf );
				rn.numVisSurfaces++;
			}
			return;
		}
	}

	drawSurf = surf->drawSurf;
	if( drawSurf->visFrame != rf.frameCount ) {
		portalSurface_t *portalSurface = NULL;

		if( shader->flags & SHADER_PORTAL ) {
			// draw portals in front-to-back order
			dist = 1024 - dist / 100.0f; 
			if( dist < 1 ) dist = 1;

			portalSurface = R_AddPortalSurface( e, surf->mesh, surf->mins, surf->maxs, shader );
		}

		drawSurf->visFrame = rf.frameCount;

		if( !R_AddDSurfToDrawList( e, fog, shader, dist, order, portalSurface, drawSurf ) ) {
			return;
		}
	}

	// keep track of the actual vbo chunk we need to render
	R_AddVBOSlice( drawSurf - rsh.worldBrushModel->drawSurfaces, 
		surf->mesh->numVerts, surf->mesh->numElems,
		surf->firstDrawSurfVert, surf->firstDrawSurfElem );

	// dynamic lights that affect the surface
	if( dlightBits && R_SurfPotentiallyLit( surf ) ) {
		// ignore dlights that have already been marked as affectors
		if( drawSurf->dlightFrame == rsc.frameCount ) {
			drawSurf->dlightBits |= dlightBits;
		} else {
			drawSurf->dlightBits = dlightBits;
			drawSurf->dlightFrame = rsc.frameCount;
		}
	}

	// shadows that are projected onto the surface
	if( shadowBits && R_SurfPotentiallyShadowed( surf ) ) {
		// ignore shadows that have already been marked as affectors
		if( drawSurf->shadowFrame == rsc.frameCount ) {
			drawSurf->shadowBits |= shadowBits;
		} else {
			drawSurf->shadowBits = shadowBits;
			drawSurf->shadowFrame = rsc.frameCount;
		}
	}

	rf.stats.c_brush_polys++;
	rn.numVisSurfaces++;
}
Esempio n. 3
0
/*
* R_AddSurfaceToDrawList
*/
static void R_AddSurfaceToDrawList( const entity_t *e, const msurface_t *surf, const mfog_t *fog,
	unsigned int clipFlags, unsigned int dlightBits, unsigned shadowBits, float dist )
{
	shader_t *shader;
	drawSurfaceBSP_t *drawSurf = surf->drawSurf;
	portalSurface_t *portalSurface = NULL;

	if( R_CullSurface( e, surf, clipFlags ) ) {
		return;
	}

	if( r_drawworld->integer == 2 ) {
		shader = rsh.envShader;
	} else {
		shader = surf->shader;

		if( shader->flags & SHADER_SKY ) {
			bool addSurf = true, addSlice = false;

			if( R_FASTSKY() ) {
				return;
			}

			if( R_ClipSkySurface( surf ) ) {
				if( rn.refdef.rdflags & RDF_SKYPORTALINVIEW ) {
					// for skyportals, generate portal surface and
					// also add BSP surface to skybox if it's fogged to render
					// the fog hull later
					portalSurface = R_AddSkyportalSurface( e, shader, drawSurf );
					addSurf = portalSurface != NULL && surf->fog != NULL;
					addSlice = portalSurface != NULL;
				}

				if( addSurf ) {
					addSlice = R_AddSkySurfToDrawList( surf, portalSurface );
				}
				if( addSlice ) {
					R_AddSurfaceVBOSlice( surf, 0 );
				}
			}

			rn.numVisSurfaces++;
			return;
		}
	}
	
	
	if( drawSurf->visFrame != rf.frameCount ) {
		if( shader->flags & SHADER_PORTAL ) {
			// draw portals in front-to-back order
			dist = 1024 - dist / 100.0f; 
			if( dist < 1 ) dist = 1;

			portalSurface = R_AddPortalSurface( e, surf->mesh, surf->mins, surf->maxs, shader, drawSurf );
		}
		else {
			// just ignore the distance since we're drawing batched geometry anyway
			dist = 0;
		}
		drawSurf->visFrame = rf.frameCount;

		if( !R_AddSurfToDrawList( rn.meshlist, e, fog, shader, dist, 0, portalSurface, drawSurf ) ) {
			return;
		}
		if( portalSurface && !( shader->flags & (SHADER_PORTAL_CAPTURE|SHADER_PORTAL_CAPTURE2) ) ) {
			R_AddSurfToDrawList( rn.portalmasklist, e, NULL, rsh.skyShader, 0, 0, NULL, drawSurf );
		}
	}

	// keep track of the actual vbo chunk we need to render
	R_AddSurfaceVBOSlice( surf, 0 );

	// dynamic lights that affect the surface
	if( dlightBits ) {
		// ignore dlights that have already been marked as affectors
		if( drawSurf->dlightFrame == rsc.frameCount ) {
			drawSurf->dlightBits |= dlightBits;
		} else {
			drawSurf->dlightBits = dlightBits;
			drawSurf->dlightFrame = rsc.frameCount;
		}
	}

	// shadows that are projected onto the surface
	if( shadowBits ) {
		R_AddSurfaceVBOSlice( surf, rsh.worldBrushModel->numDrawSurfaces );

		// ignore shadows that have already been marked as affectors
		if( drawSurf->shadowFrame == rsc.frameCount ) {
			drawSurf->shadowBits |= shadowBits;
		} else {
			drawSurf->shadowBits = shadowBits;
			drawSurf->shadowFrame = rsc.frameCount;
		}
	}

	rf.stats.c_brush_polys++;
	rn.numVisSurfaces++;
}
Esempio n. 4
0
/*
=================
R_FindBmodelMirrors

Check all bmodel surfaces and make personal mirror chain
=================
*/
void R_FindBmodelMirrors( cl_entity_t *e, qboolean static_entity )
{
	mextrasurf_t	*extrasurf;
	vec3_t		mins, maxs;
	msurface_t	*psurf;
	model_t		*clmodel;
	qboolean		rotated;
	int		i, clipFlags;

	clmodel = e->model;

	if( static_entity )
	{
		Matrix4x4_LoadIdentity( RI.objectMatrix );

		if( R_CullBox( clmodel->mins, clmodel->maxs, RI.clipFlags ))
			return;

		VectorCopy( RI.cullorigin, tr.modelorg );
		clipFlags = RI.clipFlags;
	}
	else
	{
		if( !VectorIsNull( e->angles ))
		{
			for( i = 0; i < 3; i++ )
			{
				mins[i] = e->origin[i] - clmodel->radius;
				maxs[i] = e->origin[i] + clmodel->radius;
			}
			rotated = true;
		}
		else
		{
			VectorAdd( e->origin, clmodel->mins, mins );
			VectorAdd( e->origin, clmodel->maxs, maxs );
			rotated = false;
		}

		if( R_CullBox( mins, maxs, RI.clipFlags ))
			return;

		if( !VectorIsNull( e->origin ) || !VectorIsNull( e->angles ))
		{
			if( rotated ) Matrix4x4_CreateFromEntity( RI.objectMatrix, e->angles, e->origin, 1.0f );
			else Matrix4x4_CreateFromEntity( RI.objectMatrix, vec3_origin, e->origin, 1.0f );
		}
		else Matrix4x4_LoadIdentity( RI.objectMatrix );

		e->visframe = tr.framecount; // visible

		if( rotated ) Matrix4x4_VectorITransform( RI.objectMatrix, RI.cullorigin, tr.modelorg );
		else VectorSubtract( RI.cullorigin, e->origin, tr.modelorg );

		clipFlags = 0;
	}

	psurf = &clmodel->surfaces[clmodel->firstmodelsurface];
	for( i = 0; i < clmodel->nummodelsurfaces; i++, psurf++ )
	{
		if(!( psurf->flags & SURF_REFLECT ))
			continue;

		if( R_CullSurface( psurf, clipFlags ))
			continue;

		extrasurf = SURF_INFO( psurf, RI.currentmodel );
		extrasurf->mirrorchain = tr.mirror_entities[tr.num_mirror_entities].chain;
		tr.mirror_entities[tr.num_mirror_entities].chain = extrasurf;
	}

	// store new mirror entity
	if( !static_entity && tr.mirror_entities[tr.num_mirror_entities].chain != NULL )
	{
		tr.mirror_entities[tr.num_mirror_entities].ent = RI.currententity;
		tr.num_mirror_entities++;
	}
}
Esempio n. 5
0
/*
================
R_RecursiveMirrorNode
================
*/
void R_RecursiveMirrorNode( mnode_t *node, uint clipflags )
{
	mextrasurf_t	*extrasurf;
	const mplane_t	*clipplane;
	int		i, clipped;
	msurface_t	*surf, **mark;
	mleaf_t		*pleaf;
	int		c, side;
	float		dot;

	if( node->contents == CONTENTS_SOLID )
		return; // hit a solid leaf

	if( node->visframe != tr.visframecount )
		return;

	if( clipflags )
	{
		for( i = 0, clipplane = RI.frustum; i < 6; i++, clipplane++ )
		{
			if(!( clipflags & ( 1<<i )))
				continue;

			clipped = BoxOnPlaneSide( node->minmaxs, node->minmaxs + 3, clipplane );
			if( clipped == 2 ) return;
			if( clipped == 1 ) clipflags &= ~(1<<i);
		}
	}

	// if a leaf node, draw stuff
	if( node->contents < 0 )
	{
		pleaf = (mleaf_t *)node;

		mark = pleaf->firstmarksurface;
		c = pleaf->nummarksurfaces;

		if( c )
		{
			do
			{
				(*mark)->visframe = tr.framecount;
				mark++;
			} while( --c );
		}
		return;
	}

	// node is just a decision point, so go down the apropriate sides

	// find which side of the node we are on
	dot = PlaneDiff( tr.modelorg, node->plane );
	side = (dot >= 0) ? 0 : 1;

	// recurse down the children, front side first
	R_RecursiveMirrorNode( node->children[side], clipflags );

	// draw stuff
	for( c = node->numsurfaces, surf = cl.worldmodel->surfaces + node->firstsurface; c; c--, surf++ )
	{
		if(!( surf->flags & SURF_REFLECT ))
			continue;

		if( R_CullSurface( surf, clipflags ))
			continue;

		extrasurf = SURF_INFO( surf, RI.currentmodel );
		extrasurf->mirrorchain = tr.mirror_entities[0].chain;
		tr.mirror_entities[0].chain = extrasurf;
	}

	// recurse down the back side
	R_RecursiveMirrorNode( node->children[!side], clipflags );
}
Esempio n. 6
0
/*
* R_AddSurfaceToDrawList
*/
static void R_AddSurfaceToDrawList( const entity_t *e, const msurface_t *surf, const mfog_t *fog,
	unsigned int clipFlags, unsigned int dlightBits, unsigned shadowBits, float dist )
{
	int order = 0;
	shader_t *shader;
	drawSurfaceBSP_t *drawSurf;

	if( R_CullSurface( e, surf, clipFlags ) ) {
		return;
	}

	if( r_drawworld->integer == 2 ) {
		shader = rf.envShader;
	} else {
		shader = surf->shader;

		if( shader->flags & SHADER_SKY ) {
			if( !R_FASTSKY() ) {
				R_AddSkyToDrawList( surf );
			}

			// fallthrough, but add with skyclip shader, writing to depthbuffer
			// that will mask our skydome and prevent world geometry from
			// bleeding through it
			fog = NULL;
			shader = rf.skyclipShader;
			order = 1000;
		}
	}

	drawSurf = surf->drawSurf;
	if( drawSurf->visFrame != r_framecount ) {
		portalSurface_t *portalSurface = NULL;

		if( shader->flags & SHADER_PORTAL ) {
			portalSurface = R_AddPortalSurface( e, surf->mesh, surf->mins, surf->maxs, shader );
		}

		drawSurf->visFrame = r_framecount;

		if( !R_AddDSurfToDrawList( e, fog, shader, dist, order, portalSurface, drawSurf ) ) {
			return;
		}
	}

	// keep track of the actual vbo chunk we need to render
	R_AddVBOSlice( drawSurf - r_worldbrushmodel->drawSurfaces, 
		surf->mesh->numVerts, surf->mesh->numElems,
		surf->firstDrawSurfVert, surf->firstDrawSurfElem );

	// dynamic lights that affect the surface
	if( dlightBits && R_SurfPotentiallyLit( surf ) ) {
		// ignore dlights that have already been marked as affectors
		if( drawSurf->dlightFrame == rf.sceneFrameCount ) {
			drawSurf->dlightBits |= dlightBits;
		} else {
			drawSurf->dlightBits = dlightBits;
			drawSurf->dlightFrame = rf.sceneFrameCount;
		}
	}

	// shadows that are projected onto the surface
	if( shadowBits && R_SurfPotentiallyShadowed( surf ) ) {
		// ignore shadows that have already been marked as affectors
		if( drawSurf->shadowFrame == rf.sceneFrameCount ) {
			drawSurf->shadowBits |= shadowBits;
		} else {
			drawSurf->shadowBits = shadowBits;
			drawSurf->shadowFrame = rf.sceneFrameCount;
		}
	}

	c_brush_polys++;
	rn.numVisSurfaces++;
}
Esempio n. 7
0
/*
* R_AddBrushModelToDrawList
*/
bool R_AddBrushModelToDrawList( const entity_t *e )
{
	unsigned int i;
	vec3_t origin;
	vec3_t bmins, bmaxs;
	bool rotated;
	model_t	*model = e->model;
	mbrushmodel_t *bmodel = ( mbrushmodel_t * )model->extradata;
	msurface_t *surf;
	mfog_t *fog;
	float radius, distance;
	unsigned int bit, fullBits;
	unsigned int dlightBits, shadowBits;

	if( bmodel->nummodelsurfaces == 0 ) {
		return false;
	}

	radius = R_BrushModelBBox( e, bmins, bmaxs, &rotated );

	if( R_CullModelEntity( e, bmins, bmaxs, radius, rotated, false ) ) {
		return false;
	}

	// never render weapon models or non-occluders into shadowmaps
	if( rn.renderFlags & RF_SHADOWMAPVIEW ) {
		if( rsc.entShadowGroups[R_ENT2NUM(e)] != rn.shadowGroup->id ) {
			return true;
		}
	}

	VectorAdd( e->model->mins, e->model->maxs, origin );
	VectorMA( e->origin, 0.5, origin, origin );
	distance = Distance( origin, rn.refdef.vieworg );

	fog = R_FogForBounds( bmins, bmaxs );

	R_TransformPointToModelSpace( e, rotated, rn.refdef.vieworg, modelOrg );

	// check dynamic lights that matter in the instance against the model
	dlightBits = 0;
	for( i = 0, fullBits = rn.dlightBits, bit = 1; fullBits; i++, fullBits &= ~bit, bit <<= 1 ) {
		if( !( fullBits & bit ) ) {
			continue;
		}
		if( !BoundsAndSphereIntersect( bmins, bmaxs, rsc.dlights[i].origin, rsc.dlights[i].intensity ) ) {
			continue;
		}
		dlightBits |= bit;
	}

	// check shadowmaps that matter in the instance against the model
	shadowBits = 0;
	for( i = 0, fullBits = rn.shadowBits; fullBits; i++, fullBits &= ~bit ) {
		shadowGroup_t *grp = rsc.shadowGroups + i;
		bit = grp->bit;
		if( !( fullBits & bit ) ) {
			continue;
		}
		if( !BoundsIntersect( bmins, bmaxs, grp->visMins, grp->visMaxs ) ) {
			continue;
		}
		shadowBits |= bit;
	}

	for( i = 0, surf = bmodel->firstmodelsurface; i < bmodel->nummodelsurfaces; i++, surf++ ) {
		int surfDlightBits, surfShadowBits;

		if( !surf->drawSurf ) {
			continue;
		}
		if( surf->visFrame != rf.frameCount ) {
			surf->visFrame = rf.frameCount;

			if( R_CullSurface( e, surf, 0 ) ) {
				continue;
			}

			surfDlightBits = R_SurfPotentiallyLit( surf ) ? dlightBits : 0;
			surfShadowBits = R_SurfPotentiallyShadowed( surf ) ? shadowBits : 0;

			R_AddSurfaceToDrawList( e, surf, fog, surfDlightBits, surfShadowBits, distance );
		}
	}

	return true;
}