Ejemplo n.º 1
0
/*
* R_AddSkyportalSurface
*/
portalSurface_t *R_AddSkyportalSurface( const entity_t *ent, const shader_t *shader, void *drawSurf )
{
	portalSurface_t *portalSurface;

	if( rn.skyportalSurface ) {
		portalSurface = rn.skyportalSurface;
	}
	else if( rn.numPortalSurfaces == MAX_PORTAL_SURFACES ) {
		// not enough space
		return NULL;
	}
	else {
		portalSurface = &rn.portalSurfaces[rn.numPortalSurfaces++];
		memset( portalSurface, 0, sizeof( *portalSurface ) );
		rn.skyportalSurface = portalSurface;
		rn.numDepthPortalSurfaces++;
	}

	R_AddSurfToDrawList( rn.portalmasklist, ent, NULL, rsh.skyShader, 0, 0, NULL, drawSurf );
	
	portalSurface->entity = ent;
	portalSurface->shader = shader;
	portalSurface->skyPortal = &rn.refdef.skyportal;
	return rn.skyportalSurface;
}
Ejemplo n.º 2
0
/*
* R_RenderDebugSurface
*/
static void R_RenderDebugSurface( const refdef_t *fd )
{
	rtrace_t tr;
	vec3_t forward;
	vec3_t start, end;
	msurface_t *surf;

	if( fd->rdflags & RDF_NOWORLDMODEL )
		return;

	if( r_speeds->integer != 4 && r_speeds->integer != 5 )
		return;

	VectorCopy( &fd->viewaxis[AXIS_FORWARD], forward );
	VectorCopy( fd->vieworg, start );
	VectorMA( start, 4096, forward, end );

	surf = R_TraceLine( &tr, start, end, 0 );
	if( surf && surf->drawSurf && !r_showtris->integer )
	{
		R_ClearDrawList( rn.meshlist );

		R_ClearDrawList( rn.portalmasklist );

		if( !R_AddSurfToDrawList( rn.meshlist, R_NUM2ENT(tr.ent), NULL, surf->shader, 0, 0, NULL, surf->drawSurf ) ) {
			return;
		}

		if( rn.refdef.rdflags & RDF_FLIPPED )
			RB_FlipFrontFace();

		rsc.debugSurface = surf;

		if( r_speeds->integer == 5 ) {
			// VBO debug mode
			R_AddVBOSlice( surf->drawSurf - rsh.worldBrushModel->drawSurfaces, 
				surf->drawSurf->numVerts, surf->drawSurf->numElems,
				0, 0 );
		}
		else {
			// classic mode (showtris for individual surface)
			R_AddVBOSlice( surf->drawSurf - rsh.worldBrushModel->drawSurfaces, 
				surf->mesh->numVerts, surf->mesh->numElems,
				surf->firstDrawSurfVert, surf->firstDrawSurfElem );
		}

		R_DrawOutlinedSurfaces( rn.meshlist );

		if( rn.refdef.rdflags & RDF_FLIPPED )
			RB_FlipFrontFace();
	}
}
Ejemplo 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++;
}
Ejemplo n.º 4
0
/*
* R_AddSkySurfToDrawList
*/
void *R_AddSkySurfToDrawList( drawList_t *list, const shader_t *shader,const portalSurface_t *portalSurf, drawSurfaceSky_t *drawSurf ) {
	return R_AddSurfToDrawList( rn.meshlist, rsc.skyent, NULL, shader, 0, 0, portalSurf, drawSurf );
}
Ejemplo n.º 5
0
/*
* R_AddAliasModelToDrawList
*
* Returns true if the entity is added to draw list
*/
bool R_AddAliasModelToDrawList( const entity_t *e )
{
	int i, j;
	const model_t *mod;
	const maliasmodel_t *aliasmodel;
	const mfog_t *fog;
	const shader_t *shader;
	const maliasmesh_t *mesh;
	vec3_t mins, maxs;
	float radius;
	float distance;
	int clipped;

	mod = R_AliasModelLOD( e );
	if( !( aliasmodel = ( ( const maliasmodel_t * )mod->extradata ) ) || !aliasmodel->nummeshes )
		return false;

	radius = R_AliasModelLerpBBox( e, mod, mins, maxs );
	clipped = R_CullModelEntity( e, mins, maxs, radius, true, aliasmodel->numtris > 100 );
	if( clipped )
		return false;

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

	// make sure weapon model is always closest to the viewer
	if( e->renderfx & RF_WEAPONMODEL ) {
		distance = 0;
	}
	else {
		distance = Distance( e->origin, rn.viewOrigin ) + 1;
	}

	fog = R_FogForSphere( e->origin, radius );
#if 0
	if( !( e->flags & RF_WEAPONMODEL ) && fog )
	{
		R_AliasModelLerpBBox( e, mod );
		if( R_CompletelyFogged( fog, e->origin, radius ) )
			return false;
	}
#endif

	for( i = 0, mesh = aliasmodel->meshes; i < aliasmodel->nummeshes; i++, mesh++ )
	{
		shader = NULL;

		if( e->customSkin ) {
			shader = R_FindShaderForSkinFile( e->customSkin, mesh->name );
		} else if( e->customShader ) {
			shader = e->customShader;
		} else if( mesh->numskins ) 	{
			for( j = 0; j < mesh->numskins; j++ ) {
				shader = mesh->skins[j].shader;
				if( shader ) {
					R_AddSurfToDrawList( rn.meshlist, e, fog, shader, distance, 0, NULL, aliasmodel->drawSurfs + i );
				}
			}
			continue;
		}

		if( shader ) {
			R_AddSurfToDrawList( rn.meshlist, e, fog, shader, distance, 0, NULL, aliasmodel->drawSurfs + i );
		}
	}

	return true;
}