00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "tr_local.h"
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 typedef struct {
00038 int i2;
00039 int facing;
00040 } edgeDef_t;
00041
00042 #define MAX_EDGE_DEFS 32
00043
00044 static edgeDef_t edgeDefs[SHADER_MAX_VERTEXES][MAX_EDGE_DEFS];
00045 static int numEdgeDefs[SHADER_MAX_VERTEXES];
00046 static int facing[SHADER_MAX_INDEXES/3];
00047
00048 void R_AddEdgeDef( int i1, int i2, int facing ) {
00049 int c;
00050
00051 c = numEdgeDefs[ i1 ];
00052 if ( c == MAX_EDGE_DEFS ) {
00053 return;
00054 }
00055 edgeDefs[ i1 ][ c ].i2 = i2;
00056 edgeDefs[ i1 ][ c ].facing = facing;
00057
00058 numEdgeDefs[ i1 ]++;
00059 }
00060
00061 void R_RenderShadowEdges( void ) {
00062 int i;
00063
00064 #if 0
00065 int numTris;
00066
00067
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
00100
00101
00102
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
00125
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 }
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 void RB_ShadowTessEnd( void ) {
00155 int i;
00156 int numTris;
00157 vec3_t lightDir;
00158
00159
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
00171 for ( i = 0 ; i < tess.numVertexes ; i++ ) {
00172 VectorMA( tess.xyz[i], -512, lightDir, tess.xyz[i+tess.numVertexes] );
00173 }
00174
00175
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
00205 R_AddEdgeDef( i1, i2, facing[ i ] );
00206 R_AddEdgeDef( i2, i3, facing[ i ] );
00207 R_AddEdgeDef( i3, i1, facing[ i ] );
00208 }
00209
00210
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
00218 qglColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
00219
00220 qglEnable( GL_STENCIL_TEST );
00221 qglStencilFunc( GL_ALWAYS, 1, 255 );
00222
00223
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
00248 qglColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 void RB_ShadowFinish( void ) {
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
00283
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 }
00295
00296
00297
00298
00299
00300
00301
00302
00303 void RB_ProjectionShadowDeform( void ) {
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
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 }