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 ) ); } }
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 ] ); } }