#include "tr_local.h"
Include dependency graph for tr_shadows.c:

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] |
|
|
Definition at line 42 of file tr_shadows.c. |
|
||||||||||||||||
|
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 }
|
|
|
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 }
|
|
|
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:

|
|
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:

|
|
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:

|
|
Definition at line 44 of file tr_shadows.c. Referenced by R_AddEdgeDef(), and R_RenderShadowEdges(). |
|
|
Definition at line 46 of file tr_shadows.c. Referenced by R_RenderShadowEdges(), and RB_ShadowTessEnd(). |
|
|
Definition at line 45 of file tr_shadows.c. Referenced by R_AddEdgeDef(), R_RenderShadowEdges(), and RB_ShadowTessEnd(). |
1.3.9.1