-/*
+/* -------------------------------------------------------------------------------
+
Copyright (C) 1999-2007 id Software, Inc. and contributors.
For a list of contributors, see the accompanying CONTRIBUTORS file.
-/*
-
-this section handles drawsurface allocation and creation
-
-*/
-
/*
AllocDrawSurface()
ydnar: gs mods: changed to force an explicit type when allocating
void FinishSurface( mapDrawSurface_t *ds )
{
+ mapDrawSurface_t *ds2;
+
+
/* dummy check */
- if( ds == NULL || ds->shaderInfo == NULL )
+ if( ds->type <= SURFACE_BAD || ds->type >= NUM_SURFACE_TYPES || ds == NULL || ds->shaderInfo == NULL )
return;
/* ydnar: rocking tek-fu celshading */
if( ds->celShader != NULL )
MakeCelSurface( ds, ds->celShader );
+ /* backsides stop here */
+ if( ds->backSide )
+ return;
+
/* ydnar: rocking surface cloning (fur baby yeah!) */
- if( ds->shaderInfo->cloneShader[ 0 ] != '\0' )
+ if( ds->shaderInfo->cloneShader != NULL && ds->shaderInfo->cloneShader[ 0 ] != '\0' )
CloneSurface( ds, ShaderInfoForShader( ds->shaderInfo->cloneShader ) );
+
+ /* ydnar: q3map_backShader support */
+ if( ds->shaderInfo->backShader != NULL && ds->shaderInfo->backShader[ 0 ] != '\0' )
+ {
+ ds2 = CloneSurface( ds, ShaderInfoForShader( ds->shaderInfo->backShader ) );
+ ds2->backSide = qtrue;
+ }
}
out = &mapDrawSurfs[ i ];
/* walk the surface list again until a proper surface is found */
- for( j; j < numMapDrawSurfs; j++ )
+ for( ; j < numMapDrawSurfs; j++ )
{
/* get in surface */
in = &mapDrawSurfs[ j ];
/* walk the list of surfaces */
- for( numSurfs; numSurfs > 0; numSurfs--, ds++ )
+ for( ; numSurfs > 0; numSurfs--, ds++ )
{
/* ignore bogus (or flare) surfaces */
if( ds->type == SURFACE_BAD || ds->numVerts <= 0 )
/* walk the surface list */
for( i = e->firstDrawSurf; i < numMapDrawSurfs; i++ )
+ {
+ FinishSurface( &mapDrawSurfs[ i ] );
ClassifySurfaces( 1, &mapDrawSurfs[ i ] );
+ }
/* tidy things up */
TidyEntitySurfaces( e );
/* set cel shader */
ds->celShader = b->celShader;
- /* finish surface */
- FinishSurface( ds );
-
/* ydnar: gs mods: moved st biasing elsewhere */
return ds;
}
/* set cel shader */
ds->celShader = p->celShader;
- /* finish surface */
- FinishSurface( ds );
-
/* return the drawsurface */
return ds;
}
subdivides a face surface until it is smaller than the specified size (subdivisions)
*/
-static void SubdivideFace( entity_t *e, brush_t *brush, side_t *side, winding_t *w, int fogNum, float subdivisions )
+static void SubdivideFace_r( entity_t *e, brush_t *brush, side_t *side, winding_t *w, int fogNum, float subdivisions )
{
int i;
int axis;
if( w == NULL )
return;
if( w->numpoints < 3 )
- Error( "SubdivideFaceSurface: Bad w->numpoints" );
+ Error( "SubdivideFace_r: Bad w->numpoints (%d < 3)", w->numpoints );
/* determine surface bounds */
ClearBounds( bounds[ 0 ], bounds[ 1 ] );
w = frontWinding;
else
{
- SubdivideFace( e, brush, side, frontWinding, fogNum, subdivisions );
- SubdivideFace( e, brush, side, backWinding, fogNum, subdivisions );
+ SubdivideFace_r( e, brush, side, frontWinding, fogNum, subdivisions );
+ SubdivideFace_r( e, brush, side, backWinding, fogNum, subdivisions );
return;
}
}
ClearSurface( ds );
/* subdivide it */
- SubdivideFace( e, brush, side, w, fogNum, subdivisions );
+ SubdivideFace_r( e, brush, side, w, fogNum, subdivisions );
}
}
/* invert the surface if necessary */
- if( ds->shaderInfo->invert )
+ if( ds->backSide || ds->shaderInfo->invert )
{
bspDrawVert_t *dv1, *dv2, temp;
/* invert the surface if necessary */
- if( ds->shaderInfo->invert )
+ if( ds->backSide || ds->shaderInfo->invert )
{
/* walk the indexes, reverse the triangle order */
for( i = 0; i < ds->numIndexes; i += 3 )
/* ydnar: gs mods: handle lightmapped terrain (force to planar type) */
//% else if( VectorLength( ds->lightmapAxis ) <= 0.0f || ds->type == SURFACE_TRIANGLES || ds->type == SURFACE_FOGHULL || debugSurfaces )
- else if( (VectorLength( ds->lightmapAxis ) <= 0.0f && ds->planar == qfalse) || ds->type == SURFACE_TRIANGLES || ds->type == SURFACE_FOGHULL || debugSurfaces )
+ else if( (VectorLength( ds->lightmapAxis ) <= 0.0f && ds->planar == qfalse) ||
+ ds->type == SURFACE_TRIANGLES ||
+ ds->type == SURFACE_FOGHULL ||
+ ds->numVerts > maxLMSurfaceVerts ||
+ debugSurfaces )
out->surfaceType = MST_TRIANGLE_SOUP;
/* set to a planar face */
+/*
+VolumeColorMods() - ydnar
+applies brush/volumetric color/alpha modulation to vertexes
+*/
+
+static void VolumeColorMods( entity_t *e, mapDrawSurface_t *ds )
+{
+ int i, j;
+ float d;
+ brush_t *b;
+ plane_t *plane;
+
+
+ /* early out */
+ if( e->colorModBrushes == NULL )
+ return;
+
+ /* iterate brushes */
+ for( b = e->colorModBrushes; b != NULL; b = b->nextColorModBrush )
+ {
+ /* worldspawn alpha brushes affect all, grouped ones only affect original entity */
+ if( b->entityNum != 0 && b->entityNum != ds->entityNum )
+ continue;
+
+ /* test bbox */
+ if( b->mins[ 0 ] > ds->maxs[ 0 ] || b->maxs[ 0 ] < ds->mins[ 0 ] ||
+ b->mins[ 1 ] > ds->maxs[ 1 ] || b->maxs[ 1 ] < ds->mins[ 1 ] ||
+ b->mins[ 2 ] > ds->maxs[ 2 ] || b->maxs[ 2 ] < ds->mins[ 2 ] )
+ continue;
+
+ /* iterate verts */
+ for( i = 0; i < ds->numVerts; i++ )
+ {
+ /* iterate planes */
+ for( j = 0; j < b->numsides; j++ )
+ {
+ /* point-plane test */
+ plane = &mapplanes[ b->sides[ j ].planenum ];
+ d = DotProduct( ds->verts[ i ].xyz, plane->normal ) - plane->dist;
+ if( d > 1.0f )
+ break;
+ }
+
+ /* apply colormods */
+ if( j == b->numsides )
+ ColorMod( b->contentShader->colorMod, 1, &ds->verts[ i ] );
+ }
+ }
+}
+
+
+
/*
FilterDrawsurfsIntoTree()
upon completion, all drawsurfs that actually generate a reference
/* refs initially zero */
refs = 0;
- /* ydnar: apply alphamod */
- AlphaMod( ds->shaderInfo->alphaMod, ds->numVerts, ds->verts );
-
/* apply texture coordinate mods */
for( j = 0; j < ds->numVerts; j++ )
- TcMod( si->mod, ds->verts[ j ].st );
+ TCMod( si->mod, ds->verts[ j ].st );
+
+ /* ydnar: apply shader colormod */
+ ColorMod( ds->shaderInfo->colorMod, ds->numVerts, ds->verts );
+
+ /* ydnar: apply brush colormod */
+ VolumeColorMods( e, ds );
/* ydnar: make fur surfaces */
if( si->furNumLayers > 0 )
Foliage( ds );
/* create a flare surface if necessary */
- if( si->flareShader[ 0 ] )
+ if( si->flareShader != NULL && si->flareShader[ 0 ] )
AddSurfaceFlare( ds, e->origin );
/* ydnar: don't emit nodraw surfaces (like nodraw fog) */
}
}
+ /* ydnar: remap shader */
+ if( ds->shaderInfo->remapShader && ds->shaderInfo->remapShader[ 0 ] )
+ ds->shaderInfo = ShaderInfoForShader( ds->shaderInfo->remapShader );
+
/* ydnar: gs mods: handle the various types of surfaces */
switch( ds->type )
{