Пример #1
0
/*
====================
RE_SetGlobalFog
	rgb = colour
	depthForOpaque is depth for opaque

	the restore flag can be used to restore the original level fog
	duration can be set to fade over a certain period
====================
*/
void RE_SetGlobalFog(qboolean restore, int duration, float r, float g, float b, float depthForOpaque)
{
	ri.Printf(PRINT_DEVELOPER, "RE_SetGlobalFog( restore = %i, duration = %i, r = %f, g = %f, b = %f, depthForOpaque = %f )\n",
							restore, duration, r, g, b, depthForOpaque);

	if(restore)
	{
		if(duration > 0)
		{
			VectorCopy(tr.world->fogs[tr.world->globalFog].fogParms.color, tr.world->globalTransStartFog);
			tr.world->globalTransStartFog[3] = tr.world->fogs[tr.world->globalFog].fogParms.depthForOpaque;

			Vector4Copy(tr.world->globalOriginalFog, tr.world->globalTransEndFog);

			tr.world->globalFogTransStartTime = tr.refdef.time;
			tr.world->globalFogTransEndTime = tr.refdef.time + duration;
		}
		else
		{
			VectorCopy(tr.world->globalOriginalFog, tr.world->fogs[tr.world->globalFog].fogParms.color);

			tr.world->fogs[tr.world->globalFog].fogParms.colorInt =
				ColorBytes4(tr.world->globalOriginalFog[0] * tr.identityLight, tr.world->globalOriginalFog[1] * tr.identityLight,
							tr.world->globalOriginalFog[2] * tr.identityLight, 1.0);

			tr.world->fogs[tr.world->globalFog].fogParms.depthForOpaque = tr.world->globalOriginalFog[3];
			tr.world->fogs[tr.world->globalFog].tcScale =
				1.0f / (tr.world->fogs[tr.world->globalFog].fogParms.depthForOpaque);
		}
	}
	else
	{
		if(duration > 0)
		{
			VectorCopy(tr.world->fogs[tr.world->globalFog].fogParms.color, tr.world->globalTransStartFog);
			tr.world->globalTransStartFog[3] = tr.world->fogs[tr.world->globalFog].fogParms.depthForOpaque;

			VectorSet(tr.world->globalTransEndFog, r, g, b);
			tr.world->globalTransEndFog[3] = depthForOpaque < 1 ? 1 : depthForOpaque;

			tr.world->globalFogTransStartTime = tr.refdef.time;
			tr.world->globalFogTransEndTime = tr.refdef.time + duration;
		}
		else
		{
			VectorSet(tr.world->fogs[tr.world->globalFog].fogParms.color, r, g, b);

			tr.world->fogs[tr.world->globalFog].fogParms.colorInt = ColorBytes4(r * tr.identityLight,
																						g * tr.identityLight,
																						b * tr.identityLight, 1.0);

			tr.world->fogs[tr.world->globalFog].fogParms.depthForOpaque = depthForOpaque < 1 ? 1 : depthForOpaque;
			tr.world->fogs[tr.world->globalFog].tcScale =
				1.0f / (tr.world->fogs[tr.world->globalFog].fogParms.depthForOpaque);
		}
	}
}
Пример #2
0
/*
====================
RE_SetGlobalFog
	rgb = colour
	depthForOpaque is depth for opaque

	the restore flag can be used to restore the original level fog
	duration can be set to fade over a certain period
====================
*/
void RE_SetGlobalFog(bool restore, int duration, float r, float g, float b, float depthForOpaque)
{
	if(restore)
	{
		if(duration > 0)
		{
			VectorCopy(tr.world->fogs[tr.world->globalFog].shader->fogParms.color, tr.world->globalTransStartFog);
			tr.world->globalTransStartFog[3] = tr.world->fogs[tr.world->globalFog].shader->fogParms.depthForOpaque;

			Vector4Copy(tr.world->globalOriginalFog, tr.world->globalTransEndFog);

			tr.world->globalFogTransStartTime = tr.refdef.time;
			tr.world->globalFogTransEndTime = tr.refdef.time + duration;
		}
		else
		{
			VectorCopy(tr.world->globalOriginalFog, tr.world->fogs[tr.world->globalFog].shader->fogParms.color);
			tr.world->fogs[tr.world->globalFog].shader->fogParms.colorInt =
				ColorBytes4(tr.world->globalOriginalFog[0] * tr.identityLight, tr.world->globalOriginalFog[1] * tr.identityLight,
							tr.world->globalOriginalFog[2] * tr.identityLight, 1.0);
			tr.world->fogs[tr.world->globalFog].shader->fogParms.depthForOpaque = tr.world->globalOriginalFog[3];
			tr.world->fogs[tr.world->globalFog].shader->fogParms.tcScale =
				1.0f / (tr.world->fogs[tr.world->globalFog].shader->fogParms.depthForOpaque);
		}
	}
	else
	{
		if(duration > 0)
		{
			VectorCopy(tr.world->fogs[tr.world->globalFog].shader->fogParms.color, tr.world->globalTransStartFog);
			tr.world->globalTransStartFog[3] = tr.world->fogs[tr.world->globalFog].shader->fogParms.depthForOpaque;

			VectorSet(tr.world->globalTransEndFog, r, g, b);
			tr.world->globalTransEndFog[3] = depthForOpaque < 1 ? 1 : depthForOpaque;

			tr.world->globalFogTransStartTime = tr.refdef.time;
			tr.world->globalFogTransEndTime = tr.refdef.time + duration;
		}
		else
		{
			VectorSet(tr.world->fogs[tr.world->globalFog].shader->fogParms.color, r, g, b);
			tr.world->fogs[tr.world->globalFog].shader->fogParms.colorInt = ColorBytes4(r * tr.identityLight,
																						g * tr.identityLight,
																						b * tr.identityLight, 1.0);
			tr.world->fogs[tr.world->globalFog].shader->fogParms.depthForOpaque = depthForOpaque < 1 ? 1 : depthForOpaque;
			tr.world->fogs[tr.world->globalFog].shader->fogParms.tcScale =
				1.0f / (tr.world->fogs[tr.world->globalFog].shader->fogParms.depthForOpaque);
		}
	}
}
Пример #3
0
/************************************************************************************************
 * R_FogColor_f                                                                                 *
 *    Console command to change the global fog color.  Specifying nothing on the command will   *
 *    display the current global fog color.  Specifying a float R G B values between 0.0 and    *
 *    1.0 will change the fog color.                                                            *
 *                                                                                              *
 * Input                                                                                        *
 *    none                                                                                      *
 *                                                                                              *
 * Output / Return                                                                              *
 *    none                                                                                      *
 *                                                                                              *
 ************************************************************************************************/
void R_FogColor_f(void)
{
	if (!tr.world)
	{
		ri.Printf(PRINT_ALL, "R_FogColor_f: World is not initialized\n");
		return;
	}

	if (tr.world->globalFog == -1)
	{
		ri.Printf(PRINT_ALL, "R_FogColor_f: World does not have a global fog\n");
		return;
	}

	if (ri.Cmd_Argc() <= 1)
	{
		unsigned	i = tr.world->fogs[tr.world->globalFog].colorInt;

		ri.Printf(PRINT_ALL, "R_FogColor_f: Current Color: %0f %0f %0f\n",
			( (byte *)&i )[0] / 255.0,
			( (byte *)&i )[1] / 255.0,
			( (byte *)&i )[2] / 255.0);
		return;
	}

	if (ri.Cmd_Argc() != 4)
	{
		ri.Printf(PRINT_ALL, "R_FogColor_f: Invalid number of arguments to set color\n");
		return;
	}

	tr.world->fogs[tr.world->globalFog].colorInt = ColorBytes4 ( atof(ri.Cmd_Argv(1)) * tr.identityLight, 
			                          atof(ri.Cmd_Argv(2)) * tr.identityLight, 
			                          atof(ri.Cmd_Argv(3)) * tr.identityLight, 1.0 );
}
Пример #4
0
void RE_LAGoggles( void )
{
	tr.refdef.rdflags |= (RDF_doLAGoggles|RDF_doFullbright);
	tr.refdef.doLAGoggles = qtrue;

	fog_t		*fog = &tr.world->fogs[tr.world->numfogs];

	fog->parms.color[0] = 0.75f;
	fog->parms.color[1] = 0.42f + random() * 0.025f;
	fog->parms.color[2] = 0.07f;
	fog->parms.depthForOpaque = 10000;
	fog->colorInt = ColorBytes4(fog->parms.color[0], fog->parms.color[1], fog->parms.color[2], 1.0f);
	fog->tcScale = 2.0f / ( fog->parms.depthForOpaque * (1.0f + cos( tr.refdef.floatTime) * 0.1f));
}
Пример #5
0
/*
===================
RB_HazePass

Blends a fog texture on top of everything but the skybox
===================
*/
static void RB_HazePass( void ) {
	int			i;
	unsigned int color[3], colorInt;

	// TODO; Get color from worlspawn. Use black for now.
	color[0] = 0;
	color[1] = 0;
	color[2] = 0;
	
	colorInt = ColorBytes4( color[0] * tr.identityLight, color[1] * tr.identityLight, color[2] * tr.identityLight, 1.0 );

	qglEnableClientState( GL_COLOR_ARRAY );
	qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.svars.colors );

	qglEnableClientState( GL_TEXTURE_COORD_ARRAY);
	qglTexCoordPointer( 2, GL_FLOAT, 0, tess.svars.texcoords[0] );

	//fog = tr.world->fogs + tess.fogNum;

	for ( i = 0; i < tess.numVertexes; i++ ) {
		* ( int * )&tess.svars.colors[i] = colorInt;
	}


	RB_CalcFogTexCoords( ( float * ) tess.svars.texcoords[0] );

	GL_Bind( tr.fogImage );

	if ( tess.shader->fogPass == FP_EQUAL ) {
		GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_EQUAL );
	} else {
		GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA );
	}

	R_DrawElements( tess.numIndexes, tess.indexes );
}
Пример #6
0
/*
=================
R_LoadFogs

=================
*/
static	void R_LoadFogs( lump_t *l, lump_t *brushesLump, lump_t *sidesLump ) {
    int			i;
    fog_t		*out;
    dfog_t		*fogs;
    dbrush_t 	*brushes, *brush;
    dbrushside_t	*sides;
    int			count, brushesCount, sidesCount;
    int			sideNum;
    int			planeNum;
    shader_t	*shader;
    float		d;
    int			firstSide=0;
    int			lightmaps[MAXLIGHTMAPS] = { LIGHTMAP_NONE } ;

    fogs = (dfog_t *)(fileBase + l->fileofs);
    if (l->filelen % sizeof(*fogs)) {
        ri.Error (ERR_DROP, "LoadMap: funny lump size in %s",s_worldData.name);
    }
    count = l->filelen / sizeof(*fogs);

    // create fog structres for them
    // NOTE: we allocate memory for an extra one so that the LA goggles can turn on their own fog
    s_worldData.numfogs = count + 1;
    s_worldData.fogs = (fog_t *)ri.Hunk_Alloc (( s_worldData.numfogs + 1)*sizeof(*out), qtrue );
    s_worldData.globalFog = -1;
    out = s_worldData.fogs + 1;

    if ( !count ) {
        return;
    }

    brushes = (dbrush_t *)(fileBase + brushesLump->fileofs);
    if (brushesLump->filelen % sizeof(*brushes)) {
        ri.Error (ERR_DROP, "LoadMap: funny lump size in %s",s_worldData.name);
    }
    brushesCount = brushesLump->filelen / sizeof(*brushes);

    sides = (dbrushside_t *)(fileBase + sidesLump->fileofs);
    if (sidesLump->filelen % sizeof(*sides)) {
        ri.Error (ERR_DROP, "LoadMap: funny lump size in %s",s_worldData.name);
    }
    sidesCount = sidesLump->filelen / sizeof(*sides);

    for ( i=0 ; i<count ; i++, fogs++) {
        out->originalBrushNumber = LittleLong( fogs->brushNum );
        if (out->originalBrushNumber == -1)
        {
            out->bounds[0][0] = out->bounds[0][1] = out->bounds[0][2] = MIN_WORLD_COORD;
            out->bounds[1][0] = out->bounds[1][1] = out->bounds[1][2] = MAX_WORLD_COORD;
            s_worldData.globalFog = i+1;
        }
        else
        {
            if ( (unsigned)out->originalBrushNumber >= brushesCount ) {
                ri.Error( ERR_DROP, "fog brushNumber out of range" );
            }
            brush = brushes + out->originalBrushNumber;

            firstSide = LittleLong( brush->firstSide );

            if ( (unsigned)firstSide > sidesCount - 6 ) {
                ri.Error( ERR_DROP, "fog brush sideNumber out of range" );
            }

            // brushes are always sorted with the axial sides first
            sideNum = firstSide + 0;
            planeNum = LittleLong( sides[ sideNum ].planeNum );
            out->bounds[0][0] = -s_worldData.planes[ planeNum ].dist;

            sideNum = firstSide + 1;
            planeNum = LittleLong( sides[ sideNum ].planeNum );
            out->bounds[1][0] = s_worldData.planes[ planeNum ].dist;

            sideNum = firstSide + 2;
            planeNum = LittleLong( sides[ sideNum ].planeNum );
            out->bounds[0][1] = -s_worldData.planes[ planeNum ].dist;

            sideNum = firstSide + 3;
            planeNum = LittleLong( sides[ sideNum ].planeNum );
            out->bounds[1][1] = s_worldData.planes[ planeNum ].dist;

            sideNum = firstSide + 4;
            planeNum = LittleLong( sides[ sideNum ].planeNum );
            out->bounds[0][2] = -s_worldData.planes[ planeNum ].dist;

            sideNum = firstSide + 5;
            planeNum = LittleLong( sides[ sideNum ].planeNum );
            out->bounds[1][2] = s_worldData.planes[ planeNum ].dist;
        }

        // get information from the shader for fog parameters
        shader = R_FindShader( fogs->shader, lightmaps, stylesDefault, qtrue );

        out->parms = shader->fogParms;
        out->colorInt = ColorBytes4 ( shader->fogParms.color[0] * tr.identityLight,
                                      shader->fogParms.color[1] * tr.identityLight,
                                      shader->fogParms.color[2] * tr.identityLight, 1.0 );

        d = shader->fogParms.depthForOpaque < 1 ? 1 : shader->fogParms.depthForOpaque;
        out->tcScale = 1.0 / ( d * 8 );

        // set the gradient vector
        sideNum = LittleLong( fogs->visibleSide );

        if ( sideNum == -1 ) {
            out->hasSurface = qfalse;
        } else {
            out->hasSurface = qtrue;
            planeNum = LittleLong( sides[ firstSide + sideNum ].planeNum );
            VectorSubtract( vec3_origin, s_worldData.planes[ planeNum ].normal, out->surface );
            out->surface[3] = -s_worldData.planes[ planeNum ].dist;
        }

        out++;
    }

    // Initialise the last fog so we can use it with the LA Goggles
    // NOTE: We are might appear to be off the end of the array, but we allocated an extra memory slot above but [purposely] didn't
    //	increment the total world numFogs to match our array size
    VectorSet(out->bounds[0], MIN_WORLD_COORD, MIN_WORLD_COORD, MIN_WORLD_COORD);
    VectorSet(out->bounds[1], MAX_WORLD_COORD, MAX_WORLD_COORD, MAX_WORLD_COORD);
    out->originalBrushNumber = -1;
    out->parms.color[0] = 0.0f;
    out->parms.color[1] = 0.0f;
    out->parms.color[2] = 0.0f;
    out->parms.color[3] = 0.0f;
    out->parms.depthForOpaque = 0.0f;
    out->colorInt = 0x00000000;
    out->tcScale = 0.0f;
    out->hasSurface = false;
}
Пример #7
0
void R_RMGInit(void)
{
	char			newSky[MAX_QPATH];
	char			newFog[MAX_QPATH];
	shader_t		*fog;
	fog_t			*gfog;
	mgrid_t			*grid;
	char			temp[MAX_QPATH];
	int				i;
	unsigned short	*pos;

	ri.Cvar_VariableStringBuffer("RMG_sky", newSky, MAX_QPATH);
	// Get sunlight - this should set up all the sunlight data
	R_FindShader( newSky, lightmapsNone, stylesDefault, qfalse );

	// Remap sky
	R_RemapShader("textures/tools/_sky", newSky, NULL);

	// Fill in the lightgrid with sunlight
	if(tr.world->lightGridData)
	{
		grid = tr.world->lightGridData;
		grid->ambientLight[0][0] = (byte)Com_Clampi(0, 255, tr.sunAmbient[0] * 255.0f);
		grid->ambientLight[0][1] = (byte)Com_Clampi(0, 255, tr.sunAmbient[1] * 255.0f);
		grid->ambientLight[0][2] = (byte)Com_Clampi(0, 255, tr.sunAmbient[2] * 255.0f);
		R_ColorShiftLightingBytes(grid->ambientLight[0], grid->ambientLight[0]);

		grid->directLight[0][0] = (byte)Com_Clampi(0, 255, tr.sunLight[0]);
		grid->directLight[0][1] = (byte)Com_Clampi(0, 255, tr.sunLight[1]);
		grid->directLight[0][2] = (byte)Com_Clampi(0, 255, tr.sunLight[2]);
		R_ColorShiftLightingBytes(grid->directLight[0], grid->directLight[0]);

		NormalToLatLong(tr.sunDirection, grid->latLong);

		pos = tr.world->lightGridArray;
		for(i=0;i<tr.world->numGridArrayElements;i++)
		{
			*pos = 0;
			pos++;
		}
	}

	// Override the global fog with the defined one
	if(tr.world->globalFog != -1)
	{
		ri.Cvar_VariableStringBuffer("RMG_fog", newFog, MAX_QPATH);
		fog = R_FindShader( newFog, lightmapsNone, stylesDefault, qfalse);
		if (fog != tr.defaultShader)
		{
			gfog = tr.world->fogs + tr.world->globalFog;
			gfog->parms = *fog->fogParms;
			if (gfog->parms.depthForOpaque)
			{
				gfog->tcScale = 1.0f / ( gfog->parms.depthForOpaque * 8.0f );
				tr.distanceCull = gfog->parms.depthForOpaque;
				tr.distanceCullSquared = tr.distanceCull * tr.distanceCull;
				ri.Cvar_Set("RMG_distancecull", va("%f", tr.distanceCull));
			}
			else
			{
				gfog->tcScale = 1.0f;
			}
			gfog->colorInt = ColorBytes4 ( gfog->parms.color[0], 
										  gfog->parms.color[1], 
										  gfog->parms.color[2], 1.0f );
		}
	}

	ri.Cvar_VariableStringBuffer("RMG_weather", temp, MAX_QPATH);

	// Set up any weather effects
	switch(atol(temp))
	{
	case 0:
		break;
	case 1:
		RE_WorldEffectCommand("rain init 1000");
		RE_WorldEffectCommand("rain outside");
		break;
	case 2:
		RE_WorldEffectCommand("snow init 1000 outside");
		RE_WorldEffectCommand("snow outside");
		break;
	}
}
Пример #8
0
/*
=================
R_LoadFogs

=================
*/
static	void R_LoadFogs( lump_t *l, lump_t *brushesLump, lump_t *sidesLump, world_t &worldData, int index ) {
	int			i;
	fog_t		*out;
	dfog_t		*fogs;
	dbrush_t 	*brushes, *brush;
	dbrushside_t	*sides;
	int			count, brushesCount, sidesCount;
	int			sideNum;
	int			planeNum;
	shader_t	*shader;
	float		d;
	int			firstSide=0;
	int			lightmaps[MAXLIGHTMAPS] = { LIGHTMAP_NONE } ;

	fogs = (dfog_t *)(fileBase + l->fileofs);
	if (l->filelen % sizeof(*fogs)) {
		Com_Error (ERR_DROP, "LoadMap: funny lump size in %s",worldData.name);
	}
	count = l->filelen / sizeof(*fogs);

	// create fog strucutres for them
	worldData.numfogs = count + 1;
	worldData.fogs = (fog_t *)R_Hunk_Alloc ( (worldData.numfogs+1)*sizeof(*out), qtrue);
	worldData.globalFog = -1;
	out = worldData.fogs + 1;

	// Copy the global fog from the main world into the bsp instance
	if(index)
	{
		if(tr.world && (tr.world->globalFog != -1))
		{
			// Use the nightvision fog slot
			worldData.fogs[worldData.numfogs] = tr.world->fogs[tr.world->globalFog];
			worldData.globalFog = worldData.numfogs;
			worldData.numfogs++;
		}
	}

	if ( !count ) {
		return;
	}

	brushes = (dbrush_t *)(fileBase + brushesLump->fileofs);
	if (brushesLump->filelen % sizeof(*brushes)) {
		Com_Error (ERR_DROP, "LoadMap: funny lump size in %s",worldData.name);
	}
	brushesCount = brushesLump->filelen / sizeof(*brushes);

	sides = (dbrushside_t *)(fileBase + sidesLump->fileofs);
	if (sidesLump->filelen % sizeof(*sides)) {
		Com_Error (ERR_DROP, "LoadMap: funny lump size in %s",worldData.name);
	}
	sidesCount = sidesLump->filelen / sizeof(*sides);

	for ( i=0 ; i<count ; i++, fogs++) {
		out->originalBrushNumber = LittleLong( fogs->brushNum );
		if (out->originalBrushNumber == -1)
		{
			if(index)
			{
				Com_Error (ERR_DROP, "LoadMap: global fog not allowed in bsp instances - %s", worldData.name);
			}
			VectorSet(out->bounds[0], MIN_WORLD_COORD, MIN_WORLD_COORD, MIN_WORLD_COORD);
			VectorSet(out->bounds[1], MAX_WORLD_COORD, MAX_WORLD_COORD, MAX_WORLD_COORD);
			worldData.globalFog = i + 1;
		}
		else
		{
			if ( (unsigned)out->originalBrushNumber >= (unsigned)brushesCount ) {
				Com_Error( ERR_DROP, "fog brushNumber out of range" );
			}
			brush = brushes + out->originalBrushNumber;

			firstSide = LittleLong( brush->firstSide );

				if ( (unsigned)firstSide > (unsigned)(sidesCount - 6) ) {
				Com_Error( ERR_DROP, "fog brush sideNumber out of range" );
			}

			// brushes are always sorted with the axial sides first
			sideNum = firstSide + 0;
			planeNum = LittleLong( sides[ sideNum ].planeNum );
			out->bounds[0][0] = -worldData.planes[ planeNum ].dist;

			sideNum = firstSide + 1;
			planeNum = LittleLong( sides[ sideNum ].planeNum );
			out->bounds[1][0] = worldData.planes[ planeNum ].dist;

			sideNum = firstSide + 2;
			planeNum = LittleLong( sides[ sideNum ].planeNum );
			out->bounds[0][1] = -worldData.planes[ planeNum ].dist;

			sideNum = firstSide + 3;
			planeNum = LittleLong( sides[ sideNum ].planeNum );
			out->bounds[1][1] = worldData.planes[ planeNum ].dist;

			sideNum = firstSide + 4;
			planeNum = LittleLong( sides[ sideNum ].planeNum );
			out->bounds[0][2] = -worldData.planes[ planeNum ].dist;

			sideNum = firstSide + 5;
			planeNum = LittleLong( sides[ sideNum ].planeNum );
			out->bounds[1][2] = worldData.planes[ planeNum ].dist;
		}

		// get information from the shader for fog parameters
		shader = R_FindShader( fogs->shader, lightmaps, stylesDefault, qtrue );

		assert(shader->fogParms);
		if (!shader->fogParms)
		{//bad shader!!
			out->parms.color[0] = 1.0f;
			out->parms.color[1] = 0.0f;
			out->parms.color[2] = 0.0f;
			out->parms.depthForOpaque = 250.0f;
		}
		else
		{
			out->parms = *shader->fogParms;
		}
		out->colorInt = ColorBytes4 ( out->parms.color[0],
			out->parms.color[1],
			out->parms.color[2], 1.0 );

		d = out->parms.depthForOpaque < 1 ? 1 : out->parms.depthForOpaque;
		out->tcScale = 1.0f / ( d * 8 );

		// set the gradient vector
		sideNum = LittleLong( fogs->visibleSide );

		if ( sideNum == -1 ) {
			out->hasSurface = qfalse;
		} else {
			out->hasSurface = qtrue;
			planeNum = LittleLong( sides[ firstSide + sideNum ].planeNum );
			VectorSubtract( vec3_origin, worldData.planes[ planeNum ].normal, out->surface );
			out->surface[3] = -worldData.planes[ planeNum ].dist;
		}

		out++;
	}

	if (!index)
	{
		// Initialise the last fog so we can use it with the LA Goggles
		// NOTE: We are might appear to be off the end of the array, but we allocated an extra memory slot above but [purposely] didn't
		//	increment the total world numFogs to match our array size
		VectorSet(out->bounds[0], MIN_WORLD_COORD, MIN_WORLD_COORD, MIN_WORLD_COORD);
		VectorSet(out->bounds[1], MAX_WORLD_COORD, MAX_WORLD_COORD, MAX_WORLD_COORD);
		out->originalBrushNumber = -1;
		out->parms.color[0] = 0.0f;
		out->parms.color[1] = 0.0f;
		out->parms.color[2] = 0.0f;
		out->parms.depthForOpaque = 0.0f;
		out->colorInt = 0x00000000;
		out->tcScale = 0.0f;
		out->hasSurface = qfalse;
	}
}
Пример #9
0
/*
@@@@@@@@@@@@@@@@@@@@@
RE_RenderScene

Draw a 3D view into a part of the window, then return
to 2D drawing.

Rendering a scene may require multiple views to be rendered
to handle mirrors,
@@@@@@@@@@@@@@@@@@@@@
*/
void RE_RenderScene( const refdef_t *vmRefDef, int vmRefDefSize ) {
	refdef_t		fd;
	viewParms_t		parms;
	int				startTime;

	if ( !tr.registered ) {
		return;
	}
	GLimp_LogComment( "====== RE_RenderScene =====\n" );

	if ( r_norefresh->integer ) {
		return;
	}

	startTime = ri.Milliseconds();

	Com_Memcpy2( &fd, sizeof ( refdef_t ), vmRefDef, vmRefDefSize );

	if (!tr.world && !( fd.rdflags & RDF_NOWORLDMODEL ) ) {
		ri.Error (ERR_DROP, "R_RenderScene: NULL worldmodel");
	}

	Com_Memcpy( tr.refdef.text, fd.text, sizeof( tr.refdef.text ) );

	tr.refdef.x = fd.x;
	tr.refdef.y = fd.y;
	tr.refdef.width = fd.width;
	tr.refdef.height = fd.height;
	tr.refdef.fov_x = fd.fov_x;
	tr.refdef.fov_y = fd.fov_y;

	VectorCopy( fd.vieworg, tr.refdef.vieworg );
	VectorCopy( fd.viewaxis[0], tr.refdef.viewaxis[0] );
	VectorCopy( fd.viewaxis[1], tr.refdef.viewaxis[1] );
	VectorCopy( fd.viewaxis[2], tr.refdef.viewaxis[2] );

	tr.refdef.time = fd.time;
	tr.refdef.rdflags = fd.rdflags;

	tr.refdef.skyAlpha = fd.skyAlpha;

	tr.refdef.fogType = fd.fogType;
	if ( tr.refdef.fogType < FT_NONE || tr.refdef.fogType >= FT_MAX_FOG_TYPE ) {
		tr.refdef.fogType = FT_NONE;
	}

	tr.refdef.fogColor[0] = fd.fogColor[0] * tr.identityLight;
	tr.refdef.fogColor[1] = fd.fogColor[1] * tr.identityLight;
	tr.refdef.fogColor[2] = fd.fogColor[2] * tr.identityLight;

	tr.refdef.fogColorInt = ColorBytes4( tr.refdef.fogColor[0],
									  tr.refdef.fogColor[1],
									  tr.refdef.fogColor[2], 1.0 );

	tr.refdef.fogDensity = fd.fogDensity;

	if ( r_zfar->value ) {
		tr.refdef.fogDepthForOpaque = r_zfar->value < 1 ? 1 : r_zfar->value;
	} else {
		tr.refdef.fogDepthForOpaque = fd.fogDepthForOpaque < 1 ? 1 : fd.fogDepthForOpaque;
	}
	tr.refdef.fogTcScale = R_FogTcScale( tr.refdef.fogType, tr.refdef.fogDepthForOpaque, tr.refdef.fogDensity );

	// copy the areamask data over and note if it has changed, which
	// will force a reset of the visible leafs even if the view hasn't moved
	tr.refdef.areamaskModified = qfalse;
	if ( ! (tr.refdef.rdflags & RDF_NOWORLDMODEL) ) {
		int		areaDiff;
		int		i;

		// compare the area bits
		areaDiff = 0;
		for (i = 0 ; i < MAX_MAP_AREA_BYTES/4 ; i++) {
			areaDiff |= ((int *)tr.refdef.areamask)[i] ^ ((int *)fd.areamask)[i];
			((int *)tr.refdef.areamask)[i] = ((int *)fd.areamask)[i];
		}

		if ( areaDiff ) {
			// a door just opened or something
			tr.refdef.areamaskModified = qtrue;
		}
	}


	// derived info

	tr.refdef.floatTime = tr.refdef.time * 0.001f;

	tr.refdef.numDrawSurfs = r_firstSceneDrawSurf;
	tr.refdef.drawSurfs = backEndData->drawSurfs;

	tr.refdef.numSkins = r_numskins;
	tr.refdef.skins = backEndData->skins;

	tr.refdef.num_entities = r_numentities - r_firstSceneEntity;
	tr.refdef.entities = &backEndData->entities[r_firstSceneEntity];

	tr.refdef.num_dlights = r_numdlights - r_firstSceneDlight;
	tr.refdef.dlights = &backEndData->dlights[r_firstSceneDlight];
	tr.refdef.dlightBits = 0;

	tr.refdef.num_coronas = r_numcoronas - r_firstSceneCorona;
	tr.refdef.coronas = &backEndData->coronas[r_firstSceneCorona];

	tr.refdef.numPolys = r_numpolys - r_firstScenePoly;
	tr.refdef.polys = &backEndData->polys[r_firstScenePoly];

	tr.refdef.numPolyBuffers = r_numpolybuffers - r_firstScenePolybuffer;
	tr.refdef.polybuffers = &backEndData->polybuffers[r_firstScenePolybuffer];

	// turn off dynamic lighting globally by clearing all the
	// dlights if it needs to be disabled or if vertex lighting is enabled
	if ( r_dynamiclight->integer == 0 ||
		 r_vertexLight->integer == 1 ) {
		tr.refdef.num_dlights = 0;
	}

	// a single frame may have multiple scenes draw inside it --
	// a 3D game view, 3D status bar renderings, 3D menus, etc.
	// They need to be distinguished by the light flare code, because
	// the visibility state for a given surface may be different in
	// each scene / view.
	tr.frameSceneNum++;
	tr.sceneCount++;

	// setup view parms for the initial view
	//
	// set up viewport
	// The refdef takes 0-at-the-top y coordinates, so
	// convert to GL's 0-at-the-bottom space
	//
	Com_Memset( &parms, 0, sizeof( parms ) );
	parms.viewportX = tr.refdef.x;
	parms.viewportY = glConfig.vidHeight - ( tr.refdef.y + tr.refdef.height );
	parms.viewportWidth = tr.refdef.width;
	parms.viewportHeight = tr.refdef.height;
	parms.isPortal = qfalse;

	parms.fovX = tr.refdef.fov_x;
	parms.fovY = tr.refdef.fov_y;
	
	parms.stereoFrame = tr.refdef.stereoFrame;

	VectorCopy( fd.vieworg, parms.or.origin );
	VectorCopy( fd.viewaxis[0], parms.or.axis[0] );
	VectorCopy( fd.viewaxis[1], parms.or.axis[1] );
	VectorCopy( fd.viewaxis[2], parms.or.axis[2] );

	VectorCopy( fd.vieworg, parms.pvsOrigin );

	R_RenderView( &parms );

	// the next scene rendered in this frame will tack on after this one
	r_firstSceneDrawSurf = tr.refdef.numDrawSurfs;
	r_firstSceneEntity = r_numentities;
	r_firstSceneDlight = r_numdlights;
	r_firstScenePoly = r_numpolys;
	r_firstScenePolybuffer = r_numpolybuffers;

	tr.frontEndMsec += ri.Milliseconds() - startTime;
}
Пример #10
0
/*
==============
R_SetFrameFog
==============
*/
void R_SetFrameFog()
{
	if(!tr.world)
		return;

	// Arnout: new style global fog transitions
	if(tr.world->globalFogTransEndTime)
	{
		if(tr.world->globalFogTransEndTime >= tr.refdef.time)
		{
			float           lerpPos;
			int             fadeTime;

			fadeTime = tr.world->globalFogTransEndTime - tr.world->globalFogTransStartTime;
			lerpPos = (float)(tr.refdef.time - tr.world->globalFogTransStartTime) / (float)fadeTime;
			if(lerpPos > 1)
			{
				lerpPos = 1;
			}

			tr.world->fogs[tr.world->globalFog].fogParms.color[0] =
				tr.world->globalTransStartFog[0] +
				((tr.world->globalTransEndFog[0] - tr.world->globalTransStartFog[0]) * lerpPos);
			tr.world->fogs[tr.world->globalFog].fogParms.color[1] =
				tr.world->globalTransStartFog[1] +
				((tr.world->globalTransEndFog[1] - tr.world->globalTransStartFog[1]) * lerpPos);
			tr.world->fogs[tr.world->globalFog].fogParms.color[2] =
				tr.world->globalTransStartFog[2] +
				((tr.world->globalTransEndFog[2] - tr.world->globalTransStartFog[2]) * lerpPos);

			tr.world->fogs[tr.world->globalFog].fogParms.colorInt =
				ColorBytes4(tr.world->fogs[tr.world->globalFog].fogParms.color[0] * tr.identityLight,
							tr.world->fogs[tr.world->globalFog].fogParms.color[1] * tr.identityLight,
							tr.world->fogs[tr.world->globalFog].fogParms.color[2] * tr.identityLight, 1.0);

			tr.world->fogs[tr.world->globalFog].fogParms.depthForOpaque =
				tr.world->globalTransStartFog[3] +
				((tr.world->globalTransEndFog[3] - tr.world->globalTransStartFog[3]) * lerpPos);
			tr.world->fogs[tr.world->globalFog].tcScale =
				1.0f / (tr.world->fogs[tr.world->globalFog].fogParms.depthForOpaque * 8);
		}
		else
		{
			// transition complete
			VectorCopy(tr.world->globalTransEndFog, tr.world->fogs[tr.world->globalFog].fogParms.color);
			
			tr.world->fogs[tr.world->globalFog].fogParms.colorInt =
				ColorBytes4(tr.world->globalTransEndFog[0] * tr.identityLight, tr.world->globalTransEndFog[1] * tr.identityLight,
							tr.world->globalTransEndFog[2] * tr.identityLight, 1.0);

			tr.world->fogs[tr.world->globalFog].fogParms.depthForOpaque = tr.world->globalTransEndFog[3];
			tr.world->fogs[tr.world->globalFog].tcScale =
				1.0f / (tr.world->fogs[tr.world->globalFog].fogParms.depthForOpaque * 8);

			tr.world->globalFogTransEndTime = 0;
		}
	}

	if(r_speeds->integer == RSPEEDS_FOG)
	{
		if(!tr.glfogsettings[FOG_TARGET].registered)
		{
			ri.Printf(PRINT_ALL, "no fog - calc zFar: %0.1f\n", tr.viewParms.zFar);
			return;
		}
	}

	// DHM - Nerve :: If fog is not valid, don't use it
	if(!tr.glfogsettings[FOG_TARGET].registered)
	{
		return;
	}

	// still fading
	if(tr.glfogsettings[FOG_TARGET].finishTime && tr.glfogsettings[FOG_TARGET].finishTime >= tr.refdef.time)
	{
		float           lerpPos;
		int             fadeTime;

		// transitioning from density to distance
#if !defined(USE_D3D10)
		if(tr.glfogsettings[FOG_LAST].mode == GL_EXP && tr.glfogsettings[FOG_TARGET].mode == GL_LINEAR)
		{
			// for now just fast transition to the target when dissimilar fogs are
			memcpy(&tr.glfogsettings[FOG_CURRENT], &tr.glfogsettings[FOG_TARGET], sizeof(glfog_t));
			tr.glfogsettings[FOG_TARGET].finishTime = 0;
		}
		// transitioning from distance to density
		else if(tr.glfogsettings[FOG_LAST].mode == GL_LINEAR && tr.glfogsettings[FOG_TARGET].mode == GL_EXP)
		{
			memcpy(&tr.glfogsettings[FOG_CURRENT], &tr.glfogsettings[FOG_TARGET], sizeof(glfog_t));
			tr.glfogsettings[FOG_TARGET].finishTime = 0;
		}
		// transitioning like fog modes
		else
		{

			fadeTime = tr.glfogsettings[FOG_TARGET].finishTime - tr.glfogsettings[FOG_TARGET].startTime;
			if(fadeTime <= 0)
			{
				fadeTime = 1;	// avoid divide by zero


			}
			lerpPos = (float)(tr.refdef.time - tr.glfogsettings[FOG_TARGET].startTime) / (float)fadeTime;
			if(lerpPos > 1)
			{
				lerpPos = 1;
			}

			// lerp near/far
			tr.glfogsettings[FOG_CURRENT].start =
				tr.glfogsettings[FOG_LAST].start + ((tr.glfogsettings[FOG_TARGET].start - tr.glfogsettings[FOG_LAST].start) * lerpPos);
			tr.glfogsettings[FOG_CURRENT].end =
				tr.glfogsettings[FOG_LAST].end + ((tr.glfogsettings[FOG_TARGET].end - tr.glfogsettings[FOG_LAST].end) * lerpPos);

			// lerp color
			tr.glfogsettings[FOG_CURRENT].color[0] =
				tr.glfogsettings[FOG_LAST].color[0] +
				((tr.glfogsettings[FOG_TARGET].color[0] - tr.glfogsettings[FOG_LAST].color[0]) * lerpPos);
			tr.glfogsettings[FOG_CURRENT].color[1] =
				tr.glfogsettings[FOG_LAST].color[1] +
				((tr.glfogsettings[FOG_TARGET].color[1] - tr.glfogsettings[FOG_LAST].color[1]) * lerpPos);
			tr.glfogsettings[FOG_CURRENT].color[2] =
				tr.glfogsettings[FOG_LAST].color[2] +
				((tr.glfogsettings[FOG_TARGET].color[2] - tr.glfogsettings[FOG_LAST].color[2]) * lerpPos);

			tr.glfogsettings[FOG_CURRENT].density = tr.glfogsettings[FOG_TARGET].density;
			tr.glfogsettings[FOG_CURRENT].mode = tr.glfogsettings[FOG_TARGET].mode;
			tr.glfogsettings[FOG_CURRENT].registered = qtrue;

			// if either fog in the transition clears the screen, clear the background this frame to avoid hall of mirrors
			tr.glfogsettings[FOG_CURRENT].clearscreen = (qboolean)(tr.glfogsettings[FOG_TARGET].clearscreen ||
													  tr.glfogsettings[FOG_LAST].clearscreen);
		}
#endif
	}
	else
	{
		// probably usually not necessary to copy the whole thing.
		// potential FIXME: since this is the most common occurance, diff first and only set changes
		memcpy(&tr.glfogsettings[FOG_CURRENT], &tr.glfogsettings[FOG_TARGET], sizeof(glfog_t));
	}


	// shorten the far clip if the fog opaque distance is closer than the procedural farcip dist
#if defined(USE_D3D10)
	// TODO
#else
	if(tr.glfogsettings[FOG_CURRENT].mode == GL_LINEAR)
#endif
	{
		if(tr.glfogsettings[FOG_CURRENT].end < tr.viewParms.zFar)
		{
			tr.viewParms.zFar = tr.glfogsettings[FOG_CURRENT].end;
		}
	}
//  else
//      tr.glfogsettings[FOG_CURRENT].end = 5;


	if(r_speeds->integer == RSPEEDS_FOG)
	{
#if !defined(USE_D3D10)
		if(tr.glfogsettings[FOG_CURRENT].mode == GL_LINEAR)
		{
			ri.Printf(PRINT_ALL, "farclip fog - den: %0.1f  calc zFar: %0.1f  fog zfar: %0.1f\n",
					  tr.glfogsettings[FOG_CURRENT].density, tr.viewParms.zFar, tr.glfogsettings[FOG_CURRENT].end);
		}
		else
		{
			ri.Printf(PRINT_ALL, "density fog - den: %0.4f  calc zFar: %0.1f  fog zFar: %0.1f\n",
					  tr.glfogsettings[FOG_CURRENT].density, tr.viewParms.zFar, tr.glfogsettings[FOG_CURRENT].end);
		}
#endif
	}
}