Exemplo n.º 1
0
/*
* R_AddPortalSurface
*/
portalSurface_t *R_AddPortalSurface( const entity_t *ent, const shader_t *shader, void *drawSurf ) {
	portalSurface_t *portalSurface;
	bool depthPortal;

	if( !shader ) {
		return NULL;
	}

	depthPortal = !( shader->flags & ( SHADER_PORTAL_CAPTURE | SHADER_PORTAL_CAPTURE2 ) );
	if( R_FASTSKY() && depthPortal ) {
		return NULL;
	}

	if( rn.numPortalSurfaces == MAX_PORTAL_SURFACES ) {
		// not enough space
		return NULL;
	}

	portalSurface = &rn.portalSurfaces[rn.numPortalSurfaces++];
	memset( portalSurface, 0, sizeof( portalSurface_t ) );
	portalSurface->entity = ent;
	portalSurface->shader = shader;
	portalSurface->skyPortal = NULL;
	ClearBounds( portalSurface->mins, portalSurface->maxs );
	memset( portalSurface->texures, 0, sizeof( portalSurface->texures ) );

	if( depthPortal ) {
		rn.numDepthPortalSurfaces++;
	}

	return portalSurface;
}
Exemplo 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++;
}
Exemplo 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++;
}
Exemplo n.º 4
0
/*
* R_AddPortalSurface
*/
portalSurface_t *R_AddPortalSurface( const entity_t *ent, const mesh_t *mesh, 
	const vec3_t mins, const vec3_t maxs, const shader_t *shader )
{
	unsigned int i;
	float dist;
	cplane_t plane, untransformed_plane;
	vec3_t v[3];
	portalSurface_t *portalSurface;

	if( !mesh ) {
		return NULL;
	}

	if( R_FASTSKY() && !( shader->flags & (SHADER_PORTAL_CAPTURE|SHADER_PORTAL_CAPTURE2) ) ) {
		// r_fastsky doesn't affect portalmaps
		return NULL;
	}

	for( i = 0; i < 3; i++ ) {
		VectorCopy( mesh->xyzArray[mesh->elems[i]], v[i] );
	}

	PlaneFromPoints( v, &untransformed_plane );
	untransformed_plane.dist += DotProduct( ent->origin, untransformed_plane.normal );
	CategorizePlane( &untransformed_plane );

	if( shader->flags & SHADER_AUTOSPRITE )
	{
		vec3_t centre;

		// autosprites are quads, facing the viewer
		if( mesh->numVerts < 4 ) {
			return NULL;
		}

		// compute centre as average of 4 vertices
		VectorCopy( mesh->xyzArray[mesh->elems[3]], centre );
		for( i = 0; i < 3; i++ )
			VectorAdd( centre, v[i], centre );
		VectorMA( ent->origin, 0.25, centre, centre );

		VectorNegate( &rn.viewAxis[AXIS_FORWARD], plane.normal );
		plane.dist = DotProduct( plane.normal, centre );
		CategorizePlane( &plane );
	}
	else
	{
		vec3_t temp;
		mat3_t entity_rotation;

		// regular surfaces
		if( !Matrix3_Compare( ent->axis, axis_identity ) )
		{
			Matrix3_Transpose( ent->axis, entity_rotation );

			for( i = 0; i < 3; i++ ) {
				VectorCopy( v[i], temp );
				Matrix3_TransformVector( entity_rotation, temp, v[i] ); 
				VectorMA( ent->origin, ent->scale, v[i], v[i] );
			}

			PlaneFromPoints( v, &plane );
			CategorizePlane( &plane );
		}
		else
		{
			plane = untransformed_plane;
		}
	}

	if( ( dist = PlaneDiff( rn.viewOrigin, &plane ) ) <= BACKFACE_EPSILON )
	{
		// behind the portal plane
		if( !( shader->flags & SHADER_PORTAL_CAPTURE2 ) ) {
			return NULL;
		}

		// we need to render the backplane view
	}

	// check if portal view is opaque due to alphagen portal
	if( shader->portalDistance && dist > shader->portalDistance ) {
		return NULL;
	}

	// find the matching portal plane
	for( i = 0; i < rn.numPortalSurfaces; i++ ) {
		portalSurface = &rn.portalSurfaces[i];

		if( portalSurface->entity == ent &&
			portalSurface->shader == shader &&
			DotProduct( portalSurface->plane.normal, plane.normal ) > 0.99f &&
			fabs( portalSurface->plane.dist - plane.dist ) < 0.1f ) {
				goto addsurface;
		}
	}

	if( i == MAX_PORTAL_SURFACES ) {
		// not enough space
		return NULL;
	}

	portalSurface = &rn.portalSurfaces[rn.numPortalSurfaces++];
	portalSurface->entity = ent;
	portalSurface->plane = plane;
	portalSurface->shader = shader;
	portalSurface->untransformed_plane = untransformed_plane;
	ClearBounds( portalSurface->mins, portalSurface->maxs );
	memset( portalSurface->texures, 0, sizeof( portalSurface->texures ) );

addsurface:
	AddPointToBounds( mins, portalSurface->mins, portalSurface->maxs );
	AddPointToBounds( maxs, portalSurface->mins, portalSurface->maxs );
	VectorAdd( portalSurface->mins, portalSurface->maxs, portalSurface->centre );
	VectorScale( portalSurface->centre, 0.5, portalSurface->centre );

	return portalSurface;
}
Exemplo n.º 5
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++;
}