Example #1
0
static void FillCloudBox( const shader_t *shader, int stage )
{
	int i;

	for ( i = 0; i < 6; i++ )
	{
		int   sky_mins_subd[ 2 ], sky_maxs_subd[ 2 ];
		int   s, t;
		float MIN_T;

		//if ( FIXME? shader->sky.fullClouds )
		{
			MIN_T = -HALF_SKY_SUBDIVISIONS;

			// still don't want to draw the bottom, even if fullClouds
			if ( i == 5 )
			{
				continue;
			}
		}
		/*else
		{
			switch ( i )
			{
				case 0:
				case 1:
				case 2:
				case 3:
					MIN_T = -1;
					break;

				case 5:
					// don't draw clouds beneath you
					continue;

				case 4: // top
				default:
					MIN_T = -HALF_SKY_SUBDIVISIONS;
					break;
			}
		}*/

		sky_mins[ 0 ][ i ] = floor( sky_mins[ 0 ][ i ] * HALF_SKY_SUBDIVISIONS ) / HALF_SKY_SUBDIVISIONS;
		sky_mins[ 1 ][ i ] = floor( sky_mins[ 1 ][ i ] * HALF_SKY_SUBDIVISIONS ) / HALF_SKY_SUBDIVISIONS;
		sky_maxs[ 0 ][ i ] = ceil( sky_maxs[ 0 ][ i ] * HALF_SKY_SUBDIVISIONS ) / HALF_SKY_SUBDIVISIONS;
		sky_maxs[ 1 ][ i ] = ceil( sky_maxs[ 1 ][ i ] * HALF_SKY_SUBDIVISIONS ) / HALF_SKY_SUBDIVISIONS;

		if ( ( sky_mins[ 0 ][ i ] >= sky_maxs[ 0 ][ i ] ) || ( sky_mins[ 1 ][ i ] >= sky_maxs[ 1 ][ i ] ) )
		{
			continue;
		}

		sky_mins_subd[ 0 ] = XreaL_Q_ftol( sky_mins[ 0 ][ i ] * HALF_SKY_SUBDIVISIONS );
		sky_mins_subd[ 1 ] = XreaL_Q_ftol( sky_mins[ 1 ][ i ] * HALF_SKY_SUBDIVISIONS );
		sky_maxs_subd[ 0 ] = XreaL_Q_ftol( sky_maxs[ 0 ][ i ] * HALF_SKY_SUBDIVISIONS );
		sky_maxs_subd[ 1 ] = XreaL_Q_ftol( sky_maxs[ 1 ][ i ] * HALF_SKY_SUBDIVISIONS );

		if ( sky_mins_subd[ 0 ] < -HALF_SKY_SUBDIVISIONS )
		{
			sky_mins_subd[ 0 ] = -HALF_SKY_SUBDIVISIONS;
		}
		else if ( sky_mins_subd[ 0 ] > HALF_SKY_SUBDIVISIONS )
		{
			sky_mins_subd[ 0 ] = HALF_SKY_SUBDIVISIONS;
		}

		if ( sky_mins_subd[ 1 ] < MIN_T )
		{
			sky_mins_subd[ 1 ] = MIN_T;
		}
		else if ( sky_mins_subd[ 1 ] > HALF_SKY_SUBDIVISIONS )
		{
			sky_mins_subd[ 1 ] = HALF_SKY_SUBDIVISIONS;
		}

		if ( sky_maxs_subd[ 0 ] < -HALF_SKY_SUBDIVISIONS )
		{
			sky_maxs_subd[ 0 ] = -HALF_SKY_SUBDIVISIONS;
		}
		else if ( sky_maxs_subd[ 0 ] > HALF_SKY_SUBDIVISIONS )
		{
			sky_maxs_subd[ 0 ] = HALF_SKY_SUBDIVISIONS;
		}

		if ( sky_maxs_subd[ 1 ] < MIN_T )
		{
			sky_maxs_subd[ 1 ] = MIN_T;
		}
		else if ( sky_maxs_subd[ 1 ] > HALF_SKY_SUBDIVISIONS )
		{
			sky_maxs_subd[ 1 ] = HALF_SKY_SUBDIVISIONS;
		}

		// iterate through the subdivisions
		for ( t = sky_mins_subd[ 1 ] + HALF_SKY_SUBDIVISIONS; t <= sky_maxs_subd[ 1 ] + HALF_SKY_SUBDIVISIONS; t++ )
		{
			for ( s = sky_mins_subd[ 0 ] + HALF_SKY_SUBDIVISIONS; s <= sky_maxs_subd[ 0 ] + HALF_SKY_SUBDIVISIONS; s++ )
			{
				MakeSkyVec( ( s - HALF_SKY_SUBDIVISIONS ) / ( float ) HALF_SKY_SUBDIVISIONS,
				            ( t - HALF_SKY_SUBDIVISIONS ) / ( float ) HALF_SKY_SUBDIVISIONS, i, NULL, s_skyPoints[ t ][ s ] );

				s_skyTexCoords[ t ][ s ][ 0 ] = s_cloudTexCoords[ i ][ t ][ s ][ 0 ];
				s_skyTexCoords[ t ][ s ][ 1 ] = s_cloudTexCoords[ i ][ t ][ s ][ 1 ];
			}
		}

		// only add indexes for first stage
		FillCloudySkySide( sky_mins_subd, sky_maxs_subd, ( qboolean )( stage == 0 ) );
	}
}
Example #2
0
static void ProjectDecalOntoWinding( decalProjector_t *dp, int numPoints, vec3_t points[ 2 ][ MAX_DECAL_VERTS ], bspSurface_t *surf,
                                     bspModel_t *bmodel )
{
    int        i, pingPong, count, axis;
    float      pd, d, d2, alpha = 1.f;
    vec4_t     plane;
    vec3_t     absNormal;
    decal_t    *decal, *oldest;
    polyVert_t *vert;

    /* make a plane from the winding */
    if ( !PlaneFromPoints( plane, points[ 0 ][ 0 ], points[ 0 ][ 1 ], points[ 0 ][ 2 ] ) )
    {
        return;
    }

    /* omnidirectional projectors need plane type */
    if ( dp->omnidirectional )
    {
        /* compiler warnings be gone */
        pd = 1.0f;

        /* fade by distance from plane */
        d = DotProduct( dp->center, plane ) - plane[ 3 ];
        alpha = 1.0f - ( fabs( d ) / dp->radius );

        if ( alpha < 0.0f )
        {
            return;
        }

        if ( alpha > 1.0f )
        {
            alpha = 1.0f;
        }

        /* set projection axis */
        absNormal[ 0 ] = fabs( plane[ 0 ] );
        absNormal[ 1 ] = fabs( plane[ 1 ] );
        absNormal[ 2 ] = fabs( plane[ 2 ] );

        if ( absNormal[ 2 ] >= absNormal[ 0 ] && absNormal[ 2 ] >= absNormal[ 1 ] )
        {
            axis = 2;
        }
        else if ( absNormal[ 0 ] >= absNormal[ 1 ] && absNormal[ 0 ] >= absNormal[ 2 ] )
        {
            axis = 0;
        }
        else
        {
            axis = 1;
        }
    }
    else
    {
        /* backface check */
        pd = DotProduct( dp->planes[ 0 ], plane );

        if ( pd < -0.0001f )
        {
            return;
        }

        /* directional decals use first texture matrix */
        axis = 0;
    }

    /* chop the winding by all the projector planes */
    pingPong = 0;

    for ( i = 0; i < dp->numPlanes; i++ ) //%    dp->numPlanes
    {
        ChopWindingBehindPlane( numPoints, points[ pingPong ], &numPoints, points[ !pingPong ], dp->planes[ i ], 0.0f );
        pingPong ^= 1;

        if ( numPoints < 3 )
        {
            return;
        }

        if ( numPoints == MAX_DECAL_VERTS )
        {
            break;
        }
    }

    /* find first free decal (fixme: optimize this) */
    count = ( bmodel == tr.world->models ? MAX_WORLD_DECALS : MAX_ENTITY_DECALS );
    oldest = &bmodel->decals[ 0 ];
    decal = bmodel->decals;

    for ( i = 0; i < count; i++, decal++ )
    {
        /* try to find an empty decal slot */
        if ( decal->shader == NULL )
        {
            break;
        }

        /* find oldest decal */
        if ( decal->fadeEndTime < oldest->fadeEndTime )
        {
            oldest = decal;
        }
    }

    /* guess we have to use the oldest decal */
    if ( i >= count )
    {
        decal = oldest;
    }

    /* r_speeds useful info */
    tr.pc.c_decalSurfacesCreated++;

    /* set it up (fixme: get the shader before this happens) */
    decal->parent = surf;
    decal->shader = dp->shader;
    decal->fadeStartTime = dp->fadeStartTime;
    decal->fadeEndTime = dp->fadeEndTime;
    decal->fogIndex = surf->fogIndex;

    /* add points */
    decal->numVerts = numPoints;
    vert = decal->verts;

    for ( i = 0; i < numPoints; i++, vert++ )
    {
        /* set xyz */
        VectorCopy( points[ pingPong ][ i ], vert->xyz );

        /* set st */
        vert->st[ 0 ] = DotProduct( vert->xyz, dp->texMat[ axis ][ 0 ] ) + dp->texMat[ axis ][ 0 ][ 3 ];
        vert->st[ 1 ] = DotProduct( vert->xyz, dp->texMat[ axis ][ 1 ] ) + dp->texMat[ axis ][ 1 ][ 3 ];

        /* unidirectional decals fade by half distance from front->back planes */
        if ( !dp->omnidirectional )
        {
            /* set alpha */
            d = DotProduct( vert->xyz, dp->planes[ 0 ] ) - dp->planes[ 0 ][ 3 ];
            d2 = DotProduct( vert->xyz, dp->planes[ 1 ] ) - dp->planes[ 1 ][ 3 ];
            alpha = 2.0f * d2 / ( d + d2 );

            if ( alpha > 1.0f )
            {
                alpha = 1.0f;
            }
            else if ( alpha < 0.0f )
            {
                alpha = 0.0f;
            }
        }

        /* set color */
        vert->modulate[ 0 ] = XreaL_Q_ftol( pd * alpha * dp->color[ 0 ] );
        vert->modulate[ 1 ] = XreaL_Q_ftol( pd * alpha * dp->color[ 1 ] );
        vert->modulate[ 2 ] = XreaL_Q_ftol( pd * alpha * dp->color[ 2 ] );
        vert->modulate[ 3 ] = XreaL_Q_ftol( alpha * dp->color[ 3 ] );
    }
}