Exemplo n.º 1
0
/*
================
R_AddInGameGuis
================
*/
void R_AddInGameGuis( const drawSurf_t* const drawSurfs[], const int numDrawSurfs )
{
	SCOPED_PROFILE_EVENT( "R_AddInGameGuis" );
	
	// check for gui surfaces
	for( int i = 0; i < numDrawSurfs; i++ )
	{
		const drawSurf_t* drawSurf = drawSurfs[i];
		
		idUserInterface*	gui = drawSurf->material->GlobalGui();
		
		int guiNum = drawSurf->material->GetEntityGui() - 1;
		if( guiNum >= 0 && guiNum < MAX_RENDERENTITY_GUI )
		{
			if( drawSurf->space->entityDef != NULL )
			{
				gui = drawSurf->space->entityDef->parms.gui[ guiNum ];
			}
		}
		
		if( gui == NULL )
		{
			continue;
		}
		
		idBounds ndcBounds;
		if( !R_PreciseCullSurface( drawSurf, ndcBounds ) )
		{
			// did we ever use this to forward an entity color to a gui that didn't set color?
			//	memcpy( tr.guiShaderParms, shaderParms, sizeof( tr.guiShaderParms ) );
			R_RenderGuiSurf( gui, drawSurf );
		}
	}
}
Exemplo n.º 2
0
/*
=================
R_AddDrawSurf
=================
*/
void R_AddDrawSurf( const srfTriangles_t *tri, const viewEntity_t *space, const renderEntity_t *renderEntity, const idMaterial *shader, const idScreenRect &scissor )
{
	drawSurf_t		*drawSurf;
	const float		*shaderParms;
	static float	refRegs[MAX_EXPRESSION_REGISTERS];	// don't put on stack, or VC++ will do a page touch
	float			generatedShaderParms[MAX_ENTITY_SHADER_PARMS];
	
	drawSurf = ( drawSurf_t * ) R_FrameAlloc( sizeof( *drawSurf ) );
	drawSurf->geo = tri;
	drawSurf->space = space;
	drawSurf->material = shader;
	drawSurf->scissorRect = scissor;
	drawSurf->sort = shader->GetSort() + tr.sortOffset;
	drawSurf->dsFlags = 0;
	
	// bumping this offset each time causes surfaces with equal sort orders to still
	// deterministically draw in the order they are added
	tr.sortOffset += 0.000001f;
	
	// if it doesn't fit, resize the list
	if( tr.viewDef->numDrawSurfs == tr.viewDef->maxDrawSurfs )
	{
		drawSurf_t	**old = tr.viewDef->drawSurfs;
		int			count;
		
		if( tr.viewDef->maxDrawSurfs == 0 )
		{
			tr.viewDef->maxDrawSurfs = INITIAL_DRAWSURFS;
			count = 0;
		}
		else
		{
			count = tr.viewDef->maxDrawSurfs * sizeof( tr.viewDef->drawSurfs[0] );
			tr.viewDef->maxDrawSurfs *= 2;
		}
		tr.viewDef->drawSurfs = ( drawSurf_t ** ) R_FrameAlloc( tr.viewDef->maxDrawSurfs * sizeof( tr.viewDef->drawSurfs[0] ) );
		memcpy( tr.viewDef->drawSurfs, old, count );
	}
	tr.viewDef->drawSurfs[tr.viewDef->numDrawSurfs] = drawSurf;
	tr.viewDef->numDrawSurfs++;
	
	// process the shader expressions for conditionals / color / texcoords
	const float	*constRegs = shader->ConstantRegisters();
	
	if( constRegs )
	{
		// shader only uses constant values
		drawSurf->shaderRegisters = constRegs;
	}
	else
	{
		float *regs = ( float * ) R_FrameAlloc( shader->GetNumRegisters() * sizeof( float ) );
		
		drawSurf->shaderRegisters = regs;
		
		// a reference shader will take the calculated stage color value from another shader
		// and use that for the parm0-parm3 of the current shader, which allows a stage of
		// a light model and light flares to pick up different flashing tables from
		// different light shaders
		if( renderEntity->referenceShader )
		{
			// evaluate the reference shader to find our shader parms
			const shaderStage_t *pStage;
			
			renderEntity->referenceShader->EvaluateRegisters( refRegs, renderEntity->shaderParms, tr.viewDef, renderEntity->referenceSound );
			pStage = renderEntity->referenceShader->GetStage( 0 );
			
			memcpy( generatedShaderParms, renderEntity->shaderParms, sizeof( generatedShaderParms ) );
			generatedShaderParms[0] = refRegs[pStage->color.registers[0]];
			generatedShaderParms[1] = refRegs[pStage->color.registers[1]];
			generatedShaderParms[2] = refRegs[pStage->color.registers[2]];
			
			shaderParms = generatedShaderParms;
		}
		else
		{
			// evaluate with the entityDef's shader parms
			shaderParms = renderEntity->shaderParms;
		}
		float	oldFloatTime;
		int		oldTime;
		
		if( space->entityDef && space->entityDef->parms.timeGroup )
		{
			oldFloatTime = tr.viewDef->floatTime;
			oldTime = tr.viewDef->renderView.time;
			
			tr.viewDef->floatTime = game->GetTimeGroupTime( space->entityDef->parms.timeGroup ) * 0.001;
			tr.viewDef->renderView.time = game->GetTimeGroupTime( space->entityDef->parms.timeGroup );
		}
		shader->EvaluateRegisters( regs, shaderParms, tr.viewDef, renderEntity->referenceSound );
		
		if( space->entityDef && space->entityDef->parms.timeGroup )
		{
			tr.viewDef->floatTime = oldFloatTime;
			tr.viewDef->renderView.time = oldTime;
		}
	}
	
	// check for deformations
	R_DeformDrawSurf( drawSurf );
	
	// skybox surfaces need a dynamic texgen
	switch( shader->Texgen() )
	{
		case TG_SKYBOX_CUBE:
			R_SkyboxTexGen( drawSurf, tr.viewDef->renderView.vieworg );
			break;
		case TG_WOBBLESKY_CUBE:
			R_WobbleskyTexGen( drawSurf, tr.viewDef->renderView.vieworg );
			break;
		default:
			break;
	}
	
	// check for gui surfaces
	idUserInterface	*gui = NULL;
	
	if( !space->entityDef )
	{
		gui = shader->GlobalGui();
	}
	else
	{
		int guiNum = shader->GetEntityGui() - 1;
		
		if( guiNum >= 0 && guiNum < MAX_RENDERENTITY_GUI )
		{
			gui = renderEntity->gui[guiNum];
		}
		
		if( gui == NULL )
		{
			gui = shader->GlobalGui();
		}
	}
	
	if( gui )
	{
		// force guis on the fast time
		float	oldFloatTime;
		int		oldTime;
		
		oldFloatTime = tr.viewDef->floatTime;
		oldTime = tr.viewDef->renderView.time;
		
		tr.viewDef->floatTime = game->GetTimeGroupTime( 1 ) * 0.001;
		tr.viewDef->renderView.time = game->GetTimeGroupTime( 1 );
		
		idBounds ndcBounds;
		
		if( !R_PreciseCullSurface( drawSurf, ndcBounds ) )
		{
			R_RenderGuiSurf( gui, drawSurf );
		}
		tr.viewDef->floatTime = oldFloatTime;
		tr.viewDef->renderView.time = oldTime;
	}
	// we can't add subviews at this point, because that would
	// increment tr.viewCount, messing up the rest of the surface
	// adds for this view
}