Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

tr_shadows.c File Reference

#include "tr_local.h"

Include dependency graph for tr_shadows.c:

Include dependency graph

Go to the source code of this file.

Data Structures

struct  edgeDef_t

Defines

#define MAX_EDGE_DEFS   32

Functions

void R_AddEdgeDef (int i1, int i2, int facing)
void R_RenderShadowEdges (void)
void RB_ProjectionShadowDeform (void)
void RB_ShadowFinish (void)
void RB_ShadowTessEnd (void)

Variables

edgeDef_t edgeDefs [SHADER_MAX_VERTEXES][MAX_EDGE_DEFS]
int facing [SHADER_MAX_INDEXES/3]
int numEdgeDefs [SHADER_MAX_VERTEXES]


Define Documentation

#define MAX_EDGE_DEFS   32
 

Definition at line 42 of file tr_shadows.c.


Function Documentation

void R_AddEdgeDef int  i1,
int  i2,
int  facing
 

Definition at line 48 of file tr_shadows.c.

References c, edgeDefs, edgeDef_t::facing, edgeDef_t::i2, and numEdgeDefs.

Referenced by RB_ShadowTessEnd().

00048                                                 {
00049     int     c;
00050 
00051     c = numEdgeDefs[ i1 ];
00052     if ( c == MAX_EDGE_DEFS ) {
00053         return;     // overflow
00054     }
00055     edgeDefs[ i1 ][ c ].i2 = i2;
00056     edgeDefs[ i1 ][ c ].facing = facing;
00057 
00058     numEdgeDefs[ i1 ]++;
00059 }

void R_RenderShadowEdges void   ) 
 

Definition at line 61 of file tr_shadows.c.

References c, edgeDefs, edgeDef_t::facing, facing, i, i1, edgeDef_t::i2, i2, shaderCommands_s::indexes, j, k, numEdgeDefs, shaderCommands_s::numIndexes, shaderCommands_s::numVertexes, qglBegin, qglEnd, qglVertex3fv, tess, and shaderCommands_s::xyz.

Referenced by RB_ShadowTessEnd().

00061                                  {
00062     int     i;
00063 
00064 #if 0
00065     int     numTris;
00066 
00067     // dumb way -- render every triangle's edges
00068     numTris = tess.numIndexes / 3;
00069 
00070     for ( i = 0 ; i < numTris ; i++ ) {
00071         int     i1, i2, i3;
00072 
00073         if ( !facing[i] ) {
00074             continue;
00075         }
00076 
00077         i1 = tess.indexes[ i*3 + 0 ];
00078         i2 = tess.indexes[ i*3 + 1 ];
00079         i3 = tess.indexes[ i*3 + 2 ];
00080 
00081         qglBegin( GL_TRIANGLE_STRIP );
00082         qglVertex3fv( tess.xyz[ i1 ] );
00083         qglVertex3fv( tess.xyz[ i1 + tess.numVertexes ] );
00084         qglVertex3fv( tess.xyz[ i2 ] );
00085         qglVertex3fv( tess.xyz[ i2 + tess.numVertexes ] );
00086         qglVertex3fv( tess.xyz[ i3 ] );
00087         qglVertex3fv( tess.xyz[ i3 + tess.numVertexes ] );
00088         qglVertex3fv( tess.xyz[ i1 ] );
00089         qglVertex3fv( tess.xyz[ i1 + tess.numVertexes ] );
00090         qglEnd();
00091     }
00092 #else
00093     int     c, c2;
00094     int     j, k;
00095     int     i2;
00096     int     c_edges, c_rejected;
00097     int     hit[2];
00098 
00099     // an edge is NOT a silhouette edge if its face doesn't face the light,
00100     // or if it has a reverse paired edge that also faces the light.
00101     // A well behaved polyhedron would have exactly two faces for each edge,
00102     // but lots of models have dangling edges or overfanned edges
00103     c_edges = 0;
00104     c_rejected = 0;
00105 
00106     for ( i = 0 ; i < tess.numVertexes ; i++ ) {
00107         c = numEdgeDefs[ i ];
00108         for ( j = 0 ; j < c ; j++ ) {
00109             if ( !edgeDefs[ i ][ j ].facing ) {
00110                 continue;
00111             }
00112 
00113             hit[0] = 0;
00114             hit[1] = 0;
00115 
00116             i2 = edgeDefs[ i ][ j ].i2;
00117             c2 = numEdgeDefs[ i2 ];
00118             for ( k = 0 ; k < c2 ; k++ ) {
00119                 if ( edgeDefs[ i2 ][ k ].i2 == i ) {
00120                     hit[ edgeDefs[ i2 ][ k ].facing ]++;
00121                 }
00122             }
00123 
00124             // if it doesn't share the edge with another front facing
00125             // triangle, it is a sil edge
00126             if ( hit[ 1 ] == 0 ) {
00127                 qglBegin( GL_TRIANGLE_STRIP );
00128                 qglVertex3fv( tess.xyz[ i ] );
00129                 qglVertex3fv( tess.xyz[ i + tess.numVertexes ] );
00130                 qglVertex3fv( tess.xyz[ i2 ] );
00131                 qglVertex3fv( tess.xyz[ i2 + tess.numVertexes ] );
00132                 qglEnd();
00133                 c_edges++;
00134             } else {
00135                 c_rejected++;
00136             }
00137         }
00138     }
00139 #endif
00140 }

void RB_ProjectionShadowDeform void   ) 
 

Definition at line 303 of file tr_shadows.c.

References orientationr_t::axis, backEnd, backEndState_t::currentEntity, d, DotProduct, trRefEntity_t::e, h(), i, trRefEntity_t::lightDir, shaderCommands_s::numVertexes, backEndState_t::or, orientationr_t::origin, refEntity_t::shadowPlane, tess, vec3_t, VectorCopy, VectorMA, and shaderCommands_s::xyz.

Referenced by RB_DeformTessGeometry().

00303                                        {
00304     float   *xyz;
00305     int     i;
00306     float   h;
00307     vec3_t  ground;
00308     vec3_t  light;
00309     float   groundDist;
00310     float   d;
00311     vec3_t  lightDir;
00312 
00313     xyz = ( float * ) tess.xyz;
00314 
00315     ground[0] = backEnd.or.axis[0][2];
00316     ground[1] = backEnd.or.axis[1][2];
00317     ground[2] = backEnd.or.axis[2][2];
00318 
00319     groundDist = backEnd.or.origin[2] - backEnd.currentEntity->e.shadowPlane;
00320 
00321     VectorCopy( backEnd.currentEntity->lightDir, lightDir );
00322     d = DotProduct( lightDir, ground );
00323     // don't let the shadows get too long or go negative
00324     if ( d < 0.5 ) {
00325         VectorMA( lightDir, (0.5 - d), ground, lightDir );
00326         d = DotProduct( lightDir, ground );
00327     }
00328     d = 1.0 / d;
00329 
00330     light[0] = lightDir[0] * d;
00331     light[1] = lightDir[1] * d;
00332     light[2] = lightDir[2] * d;
00333 
00334     for ( i = 0; i < tess.numVertexes; i++, xyz += 4 ) {
00335         h = DotProduct( xyz, ground ) + groundDist;
00336 
00337         xyz[0] -= light[0] * h;
00338         xyz[1] -= light[1] * h;
00339         xyz[2] -= light[2] * h;
00340     }
00341 }

Here is the call graph for this function:

void RB_ShadowFinish void   ) 
 

Definition at line 262 of file tr_shadows.c.

References f, GL_Bind(), GL_State(), glConfig, GLS_DEPTHMASK_TRUE, GLS_DSTBLEND_ZERO, GLS_SRCBLEND_DST_COLOR, cvar_s::integer, qglBegin, qglColor3f, qglColor4f, qglDisable, qglEnable, qglEnd, qglLoadIdentity, qglStencilFunc, qglVertex3f, r_shadows, glconfig_t::stencilBits, tr, and trGlobals_t::whiteImage.

Referenced by RB_RenderDrawSurfList().

00262                              {
00263     if ( r_shadows->integer != 2 ) {
00264         return;
00265     }
00266     if ( glConfig.stencilBits < 4 ) {
00267         return;
00268     }
00269     qglEnable( GL_STENCIL_TEST );
00270     qglStencilFunc( GL_NOTEQUAL, 0, 255 );
00271 
00272     qglDisable (GL_CLIP_PLANE0);
00273     qglDisable (GL_CULL_FACE);
00274 
00275     GL_Bind( tr.whiteImage );
00276 
00277     qglLoadIdentity ();
00278 
00279     qglColor3f( 0.6f, 0.6f, 0.6f );
00280     GL_State( GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO );
00281 
00282 //  qglColor3f( 1, 0, 0 );
00283 //  GL_State( GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
00284 
00285     qglBegin( GL_QUADS );
00286     qglVertex3f( -100, 100, -10 );
00287     qglVertex3f( 100, 100, -10 );
00288     qglVertex3f( 100, -100, -10 );
00289     qglVertex3f( -100, -100, -10 );
00290     qglEnd ();
00291 
00292     qglColor4f(1,1,1,1);
00293     qglDisable( GL_STENCIL_TEST );
00294 }

Here is the call graph for this function:

void RB_ShadowTessEnd void   ) 
 

Definition at line 154 of file tr_shadows.c.

References backEnd, Com_Memset(), CrossProduct(), backEndState_t::currentEntity, d, DotProduct, f, facing, GL_Bind(), GL_State(), glConfig, GLS_DSTBLEND_ZERO, GLS_SRCBLEND_ONE, i, i1, i2, shaderCommands_s::indexes, viewParms_t::isMirror, trRefEntity_t::lightDir, numEdgeDefs, shaderCommands_s::numIndexes, shaderCommands_s::numVertexes, qglColor3f, qglColorMask, qglCullFace, qglEnable, qglStencilFunc, qglStencilOp, R_AddEdgeDef(), R_RenderShadowEdges(), SHADER_MAX_VERTEXES, glconfig_t::stencilBits, tess, tr, v1, v2, vec3_t, VectorCopy, VectorMA, VectorSubtract, backEndState_t::viewParms, trGlobals_t::whiteImage, and shaderCommands_s::xyz.

Referenced by RB_EndSurface().

00154                               {
00155     int     i;
00156     int     numTris;
00157     vec3_t  lightDir;
00158 
00159     // we can only do this if we have enough space in the vertex buffers
00160     if ( tess.numVertexes >= SHADER_MAX_VERTEXES / 2 ) {
00161         return;
00162     }
00163 
00164     if ( glConfig.stencilBits < 4 ) {
00165         return;
00166     }
00167 
00168     VectorCopy( backEnd.currentEntity->lightDir, lightDir );
00169 
00170     // project vertexes away from light direction
00171     for ( i = 0 ; i < tess.numVertexes ; i++ ) {
00172         VectorMA( tess.xyz[i], -512, lightDir, tess.xyz[i+tess.numVertexes] );
00173     }
00174 
00175     // decide which triangles face the light
00176     Com_Memset( numEdgeDefs, 0, 4 * tess.numVertexes );
00177 
00178     numTris = tess.numIndexes / 3;
00179     for ( i = 0 ; i < numTris ; i++ ) {
00180         int     i1, i2, i3;
00181         vec3_t  d1, d2, normal;
00182         float   *v1, *v2, *v3;
00183         float   d;
00184 
00185         i1 = tess.indexes[ i*3 + 0 ];
00186         i2 = tess.indexes[ i*3 + 1 ];
00187         i3 = tess.indexes[ i*3 + 2 ];
00188 
00189         v1 = tess.xyz[ i1 ];
00190         v2 = tess.xyz[ i2 ];
00191         v3 = tess.xyz[ i3 ];
00192 
00193         VectorSubtract( v2, v1, d1 );
00194         VectorSubtract( v3, v1, d2 );
00195         CrossProduct( d1, d2, normal );
00196 
00197         d = DotProduct( normal, lightDir );
00198         if ( d > 0 ) {
00199             facing[ i ] = 1;
00200         } else {
00201             facing[ i ] = 0;
00202         }
00203 
00204         // create the edges
00205         R_AddEdgeDef( i1, i2, facing[ i ] );
00206         R_AddEdgeDef( i2, i3, facing[ i ] );
00207         R_AddEdgeDef( i3, i1, facing[ i ] );
00208     }
00209 
00210     // draw the silhouette edges
00211 
00212     GL_Bind( tr.whiteImage );
00213     qglEnable( GL_CULL_FACE );
00214     GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
00215     qglColor3f( 0.2f, 0.2f, 0.2f );
00216 
00217     // don't write to the color buffer
00218     qglColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
00219 
00220     qglEnable( GL_STENCIL_TEST );
00221     qglStencilFunc( GL_ALWAYS, 1, 255 );
00222 
00223     // mirrors have the culling order reversed
00224     if ( backEnd.viewParms.isMirror ) {
00225         qglCullFace( GL_FRONT );
00226         qglStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
00227 
00228         R_RenderShadowEdges();
00229 
00230         qglCullFace( GL_BACK );
00231         qglStencilOp( GL_KEEP, GL_KEEP, GL_DECR );
00232 
00233         R_RenderShadowEdges();
00234     } else {
00235         qglCullFace( GL_BACK );
00236         qglStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
00237 
00238         R_RenderShadowEdges();
00239 
00240         qglCullFace( GL_FRONT );
00241         qglStencilOp( GL_KEEP, GL_KEEP, GL_DECR );
00242 
00243         R_RenderShadowEdges();
00244     }
00245 
00246 
00247     // reenable writing to the color buffer
00248     qglColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
00249 }

Here is the call graph for this function:


Variable Documentation

edgeDef_t edgeDefs[SHADER_MAX_VERTEXES][MAX_EDGE_DEFS] [static]
 

Definition at line 44 of file tr_shadows.c.

Referenced by R_AddEdgeDef(), and R_RenderShadowEdges().

int facing[SHADER_MAX_INDEXES/3] [static]
 

Definition at line 46 of file tr_shadows.c.

Referenced by R_RenderShadowEdges(), and RB_ShadowTessEnd().

int numEdgeDefs[SHADER_MAX_VERTEXES] [static]
 

Definition at line 45 of file tr_shadows.c.

Referenced by R_AddEdgeDef(), R_RenderShadowEdges(), and RB_ShadowTessEnd().


Generated on Thu Aug 25 15:25:20 2005 for Quake III Arena by  doxygen 1.3.9.1