]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/renderer/draw_common.cpp
Various Mac OS X tweaks to get this to build. Probably breaking things.
[icculus/iodoom3.git] / neo / renderer / draw_common.cpp
1 /*
2 ===========================================================================
3
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. 
6
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).  
8
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code.  If not, see <http://www.gnu.org/licenses/>.
21
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code.  If not, please request a copy in writing from id Software at the address below.
23
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25
26 ===========================================================================
27 */
28 #include "../idlib/precompiled.h"
29 #pragma hdrstop
30
31 #include "tr_local.h"
32
33 /*
34 =====================
35 RB_BakeTextureMatrixIntoTexgen
36 =====================
37 */
38 void RB_BakeTextureMatrixIntoTexgen( idPlane lightProject[3], const float *textureMatrix ) {
39         float   genMatrix[16];
40         float   final[16];
41
42         genMatrix[0] = lightProject[0][0];
43         genMatrix[4] = lightProject[0][1];
44         genMatrix[8] = lightProject[0][2];
45         genMatrix[12] = lightProject[0][3];
46
47         genMatrix[1] = lightProject[1][0];
48         genMatrix[5] = lightProject[1][1];
49         genMatrix[9] = lightProject[1][2];
50         genMatrix[13] = lightProject[1][3];
51
52         genMatrix[2] = 0;
53         genMatrix[6] = 0;
54         genMatrix[10] = 0;
55         genMatrix[14] = 0;
56
57         genMatrix[3] = lightProject[2][0];
58         genMatrix[7] = lightProject[2][1];
59         genMatrix[11] = lightProject[2][2];
60         genMatrix[15] = lightProject[2][3];
61
62         myGlMultMatrix( genMatrix, backEnd.lightTextureMatrix, final );
63
64         lightProject[0][0] = final[0];
65         lightProject[0][1] = final[4];
66         lightProject[0][2] = final[8];
67         lightProject[0][3] = final[12];
68
69         lightProject[1][0] = final[1];
70         lightProject[1][1] = final[5];
71         lightProject[1][2] = final[9];
72         lightProject[1][3] = final[13];
73 }
74
75 /*
76 ================
77 RB_PrepareStageTexturing
78 ================
79 */
80 void RB_PrepareStageTexturing( const shaderStage_t *pStage,  const drawSurf_t *surf, idDrawVert *ac ) {
81         // set privatePolygonOffset if necessary
82         if ( pStage->privatePolygonOffset ) {
83                 qglEnable( GL_POLYGON_OFFSET_FILL );
84                 qglPolygonOffset( r_offsetFactor.GetFloat(), r_offsetUnits.GetFloat() * pStage->privatePolygonOffset );
85         }
86
87         // set the texture matrix if needed
88         if ( pStage->texture.hasMatrix ) {
89                 RB_LoadShaderTextureMatrix( surf->shaderRegisters, &pStage->texture );
90         }
91
92         // texgens
93         if ( pStage->texture.texgen == TG_DIFFUSE_CUBE ) {
94                 qglTexCoordPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->normal.ToFloatPtr() );
95         }
96         if ( pStage->texture.texgen == TG_SKYBOX_CUBE || pStage->texture.texgen == TG_WOBBLESKY_CUBE ) {
97                 qglTexCoordPointer( 3, GL_FLOAT, 0, vertexCache.Position( surf->dynamicTexCoords ) );
98         }
99         if ( pStage->texture.texgen == TG_SCREEN ) {
100                 qglEnable( GL_TEXTURE_GEN_S );
101                 qglEnable( GL_TEXTURE_GEN_T );
102                 qglEnable( GL_TEXTURE_GEN_Q );
103
104                 float   mat[16], plane[4];
105                 myGlMultMatrix( surf->space->modelViewMatrix, backEnd.viewDef->projectionMatrix, mat );
106
107                 plane[0] = mat[0];
108                 plane[1] = mat[4];
109                 plane[2] = mat[8];
110                 plane[3] = mat[12];
111                 qglTexGenfv( GL_S, GL_OBJECT_PLANE, plane );
112
113                 plane[0] = mat[1];
114                 plane[1] = mat[5];
115                 plane[2] = mat[9];
116                 plane[3] = mat[13];
117                 qglTexGenfv( GL_T, GL_OBJECT_PLANE, plane );
118
119                 plane[0] = mat[3];
120                 plane[1] = mat[7];
121                 plane[2] = mat[11];
122                 plane[3] = mat[15];
123                 qglTexGenfv( GL_Q, GL_OBJECT_PLANE, plane );
124         }
125
126         if ( pStage->texture.texgen == TG_SCREEN2 ) {
127                 qglEnable( GL_TEXTURE_GEN_S );
128                 qglEnable( GL_TEXTURE_GEN_T );
129                 qglEnable( GL_TEXTURE_GEN_Q );
130
131                 float   mat[16], plane[4];
132                 myGlMultMatrix( surf->space->modelViewMatrix, backEnd.viewDef->projectionMatrix, mat );
133
134                 plane[0] = mat[0];
135                 plane[1] = mat[4];
136                 plane[2] = mat[8];
137                 plane[3] = mat[12];
138                 qglTexGenfv( GL_S, GL_OBJECT_PLANE, plane );
139
140                 plane[0] = mat[1];
141                 plane[1] = mat[5];
142                 plane[2] = mat[9];
143                 plane[3] = mat[13];
144                 qglTexGenfv( GL_T, GL_OBJECT_PLANE, plane );
145
146                 plane[0] = mat[3];
147                 plane[1] = mat[7];
148                 plane[2] = mat[11];
149                 plane[3] = mat[15];
150                 qglTexGenfv( GL_Q, GL_OBJECT_PLANE, plane );
151         }
152
153         if ( pStage->texture.texgen == TG_GLASSWARP ) {
154                 if ( tr.backEndRenderer == BE_ARB2 /*|| tr.backEndRenderer == BE_NV30*/ ) {
155                         qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_GLASSWARP );
156                         qglEnable( GL_FRAGMENT_PROGRAM_ARB );
157
158                         GL_SelectTexture( 2 );
159                         globalImages->scratchImage->Bind();
160
161                         GL_SelectTexture( 1 );
162                         globalImages->scratchImage2->Bind();
163
164                         qglEnable( GL_TEXTURE_GEN_S );
165                         qglEnable( GL_TEXTURE_GEN_T );
166                         qglEnable( GL_TEXTURE_GEN_Q );
167
168                         float   mat[16], plane[4];
169                         myGlMultMatrix( surf->space->modelViewMatrix, backEnd.viewDef->projectionMatrix, mat );
170
171                         plane[0] = mat[0];
172                         plane[1] = mat[4];
173                         plane[2] = mat[8];
174                         plane[3] = mat[12];
175                         qglTexGenfv( GL_S, GL_OBJECT_PLANE, plane );
176
177                         plane[0] = mat[1];
178                         plane[1] = mat[5];
179                         plane[2] = mat[9];
180                         plane[3] = mat[13];
181                         qglTexGenfv( GL_T, GL_OBJECT_PLANE, plane );
182
183                         plane[0] = mat[3];
184                         plane[1] = mat[7];
185                         plane[2] = mat[11];
186                         plane[3] = mat[15];
187                         qglTexGenfv( GL_Q, GL_OBJECT_PLANE, plane );
188
189                         GL_SelectTexture( 0 );
190                 }
191         }
192
193         if ( pStage->texture.texgen == TG_REFLECT_CUBE ) {
194                 if ( tr.backEndRenderer == BE_ARB2 ) {
195                         // see if there is also a bump map specified
196                         const shaderStage_t *bumpStage = surf->material->GetBumpStage();
197                         if ( bumpStage ) {
198                                 // per-pixel reflection mapping with bump mapping
199                                 GL_SelectTexture( 1 );
200                                 bumpStage->texture.image->Bind();
201                                 GL_SelectTexture( 0 );
202
203                                 qglNormalPointer( GL_FLOAT, sizeof( idDrawVert ), ac->normal.ToFloatPtr() );
204                                 qglVertexAttribPointerARB( 10, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[1].ToFloatPtr() );
205                                 qglVertexAttribPointerARB( 9, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[0].ToFloatPtr() );
206
207                                 qglEnableVertexAttribArrayARB( 9 );
208                                 qglEnableVertexAttribArrayARB( 10 );
209                                 qglEnableClientState( GL_NORMAL_ARRAY );
210
211                                 // Program env 5, 6, 7, 8 have been set in RB_SetProgramEnvironmentSpace
212
213                                 qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_BUMPY_ENVIRONMENT );
214                                 qglEnable( GL_FRAGMENT_PROGRAM_ARB );
215                                 qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_BUMPY_ENVIRONMENT );
216                                 qglEnable( GL_VERTEX_PROGRAM_ARB );
217                         } else {
218                                 // per-pixel reflection mapping without a normal map
219                                 qglNormalPointer( GL_FLOAT, sizeof( idDrawVert ), ac->normal.ToFloatPtr() );
220                                 qglEnableClientState( GL_NORMAL_ARRAY );
221
222                                 qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_ENVIRONMENT );
223                                 qglEnable( GL_FRAGMENT_PROGRAM_ARB );
224                                 qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_ENVIRONMENT );
225                                 qglEnable( GL_VERTEX_PROGRAM_ARB );
226                         }
227                 } else {
228                         qglEnable( GL_TEXTURE_GEN_S );
229                         qglEnable( GL_TEXTURE_GEN_T );
230                         qglEnable( GL_TEXTURE_GEN_R );
231                         qglTexGenf( GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT );
232                         qglTexGenf( GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT );
233                         qglTexGenf( GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT );
234                         qglEnableClientState( GL_NORMAL_ARRAY );
235                         qglNormalPointer( GL_FLOAT, sizeof( idDrawVert ), ac->normal.ToFloatPtr() );
236
237                         qglMatrixMode( GL_TEXTURE );
238                         float   mat[16];
239
240                         R_TransposeGLMatrix( backEnd.viewDef->worldSpace.modelViewMatrix, mat );
241
242                         qglLoadMatrixf( mat );
243                         qglMatrixMode( GL_MODELVIEW );
244                 }
245         }
246 }
247
248 /*
249 ================
250 RB_FinishStageTexturing
251 ================
252 */
253 void RB_FinishStageTexturing( const shaderStage_t *pStage, const drawSurf_t *surf, idDrawVert *ac ) {
254         // unset privatePolygonOffset if necessary
255         if ( pStage->privatePolygonOffset && !surf->material->TestMaterialFlag(MF_POLYGONOFFSET) ) {
256                 qglDisable( GL_POLYGON_OFFSET_FILL );
257         }
258
259         if ( pStage->texture.texgen == TG_DIFFUSE_CUBE || pStage->texture.texgen == TG_SKYBOX_CUBE
260                 || pStage->texture.texgen == TG_WOBBLESKY_CUBE ) {
261                 qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), (void *)&ac->st );
262         }
263
264         if ( pStage->texture.texgen == TG_SCREEN ) {
265                 qglDisable( GL_TEXTURE_GEN_S );
266                 qglDisable( GL_TEXTURE_GEN_T );
267                 qglDisable( GL_TEXTURE_GEN_Q );
268         }
269         if ( pStage->texture.texgen == TG_SCREEN2 ) {
270                 qglDisable( GL_TEXTURE_GEN_S );
271                 qglDisable( GL_TEXTURE_GEN_T );
272                 qglDisable( GL_TEXTURE_GEN_Q );
273         }
274
275         if ( pStage->texture.texgen == TG_GLASSWARP ) {
276                 if ( tr.backEndRenderer == BE_ARB2 /*|| tr.backEndRenderer == BE_NV30*/ ) {
277                         GL_SelectTexture( 2 );
278                         globalImages->BindNull();
279
280                         GL_SelectTexture( 1 );
281                         if ( pStage->texture.hasMatrix ) {
282                                 RB_LoadShaderTextureMatrix( surf->shaderRegisters, &pStage->texture );
283                         }
284                         qglDisable( GL_TEXTURE_GEN_S );
285                         qglDisable( GL_TEXTURE_GEN_T );
286                         qglDisable( GL_TEXTURE_GEN_Q );
287                         qglDisable( GL_FRAGMENT_PROGRAM_ARB );
288                         globalImages->BindNull();
289                         GL_SelectTexture( 0 );
290                 }
291         }
292
293         if ( pStage->texture.texgen == TG_REFLECT_CUBE ) {
294                 if ( tr.backEndRenderer == BE_ARB2 ) {
295                         // see if there is also a bump map specified
296                         const shaderStage_t *bumpStage = surf->material->GetBumpStage();
297                         if ( bumpStage ) {
298                                 // per-pixel reflection mapping with bump mapping
299                                 GL_SelectTexture( 1 );
300                                 globalImages->BindNull();
301                                 GL_SelectTexture( 0 );
302
303                                 qglDisableVertexAttribArrayARB( 9 );
304                                 qglDisableVertexAttribArrayARB( 10 );
305                         } else {
306                                 // per-pixel reflection mapping without bump mapping
307                         }
308
309                         qglDisableClientState( GL_NORMAL_ARRAY );
310                         qglDisable( GL_FRAGMENT_PROGRAM_ARB );
311                         qglDisable( GL_VERTEX_PROGRAM_ARB );
312                         // Fixme: Hack to get around an apparent bug in ATI drivers.  Should remove as soon as it gets fixed.
313                         qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, 0 );
314                 } else {
315                         qglDisable( GL_TEXTURE_GEN_S );
316                         qglDisable( GL_TEXTURE_GEN_T );
317                         qglDisable( GL_TEXTURE_GEN_R );
318                         qglTexGenf( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
319                         qglTexGenf( GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
320                         qglTexGenf( GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
321                         qglDisableClientState( GL_NORMAL_ARRAY );
322
323                         qglMatrixMode( GL_TEXTURE );
324                         qglLoadIdentity();
325                         qglMatrixMode( GL_MODELVIEW );
326                 }
327         }
328
329         if ( pStage->texture.hasMatrix ) {
330                 qglMatrixMode( GL_TEXTURE );
331                 qglLoadIdentity();
332                 qglMatrixMode( GL_MODELVIEW );
333         }
334 }
335
336 /*
337 =============================================================================================
338
339 FILL DEPTH BUFFER
340
341 =============================================================================================
342 */
343
344
345 /*
346 ==================
347 RB_T_FillDepthBuffer
348 ==================
349 */
350 void RB_T_FillDepthBuffer( const drawSurf_t *surf ) {
351         int                     stage;
352         const idMaterial        *shader;
353         const shaderStage_t *pStage;
354         const float     *regs;
355         float           color[4];
356         const srfTriangles_t    *tri;
357
358         tri = surf->geo;
359         shader = surf->material;
360
361         // update the clip plane if needed
362         if ( backEnd.viewDef->numClipPlanes && surf->space != backEnd.currentSpace ) {
363                 GL_SelectTexture( 1 );
364                 
365                 idPlane plane;
366
367                 R_GlobalPlaneToLocal( surf->space->modelMatrix, backEnd.viewDef->clipPlanes[0], plane );
368                 plane[3] += 0.5;        // the notch is in the middle
369                 qglTexGenfv( GL_S, GL_OBJECT_PLANE, plane.ToFloatPtr() );
370                 GL_SelectTexture( 0 );
371         }
372
373         if ( !shader->IsDrawn() ) {
374                 return;
375         }
376
377         // some deforms may disable themselves by setting numIndexes = 0
378         if ( !tri->numIndexes ) {
379                 return;
380         }
381
382         // translucent surfaces don't put anything in the depth buffer and don't
383         // test against it, which makes them fail the mirror clip plane operation
384         if ( shader->Coverage() == MC_TRANSLUCENT ) {
385                 return;
386         }
387
388         if ( !tri->ambientCache ) {
389                 common->Printf( "RB_T_FillDepthBuffer: !tri->ambientCache\n" );
390                 return;
391         }
392
393         // get the expressions for conditionals / color / texcoords
394         regs = surf->shaderRegisters;
395
396         // if all stages of a material have been conditioned off, don't do anything
397         for ( stage = 0; stage < shader->GetNumStages() ; stage++ ) {           
398                 pStage = shader->GetStage(stage);
399                 // check the stage enable condition
400                 if ( regs[ pStage->conditionRegister ] != 0 ) {
401                         break;
402                 }
403         }
404         if ( stage == shader->GetNumStages() ) {
405                 return;
406         }
407
408         // set polygon offset if necessary
409         if ( shader->TestMaterialFlag(MF_POLYGONOFFSET) ) {
410                 qglEnable( GL_POLYGON_OFFSET_FILL );
411                 qglPolygonOffset( r_offsetFactor.GetFloat(), r_offsetUnits.GetFloat() * shader->GetPolygonOffset() );
412         }
413
414         // subviews will just down-modulate the color buffer by overbright
415         if ( shader->GetSort() == SS_SUBVIEW ) {
416                 GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO | GLS_DEPTHFUNC_LESS );
417                 color[0] =
418                 color[1] = 
419                 color[2] = ( 1.0 / backEnd.overBright );
420                 color[3] = 1;
421         } else {
422                 // others just draw black
423                 color[0] = 0;
424                 color[1] = 0;
425                 color[2] = 0;
426                 color[3] = 1;
427         }
428
429         idDrawVert *ac = (idDrawVert *)vertexCache.Position( tri->ambientCache );
430         qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() );
431         qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), reinterpret_cast<void *>(&ac->st) );
432
433         bool drawSolid = false;
434
435         if ( shader->Coverage() == MC_OPAQUE ) {
436                 drawSolid = true;
437         }
438
439         // we may have multiple alpha tested stages
440         if ( shader->Coverage() == MC_PERFORATED ) {
441                 // if the only alpha tested stages are condition register omitted,
442                 // draw a normal opaque surface
443                 bool    didDraw = false;
444
445                 qglEnable( GL_ALPHA_TEST );
446                 // perforated surfaces may have multiple alpha tested stages
447                 for ( stage = 0; stage < shader->GetNumStages() ; stage++ ) {           
448                         pStage = shader->GetStage(stage);
449
450                         if ( !pStage->hasAlphaTest ) {
451                                 continue;
452                         }
453
454                         // check the stage enable condition
455                         if ( regs[ pStage->conditionRegister ] == 0 ) {
456                                 continue;
457                         }
458
459                         // if we at least tried to draw an alpha tested stage,
460                         // we won't draw the opaque surface
461                         didDraw = true;
462
463                         // set the alpha modulate
464                         color[3] = regs[ pStage->color.registers[3] ];
465
466                         // skip the entire stage if alpha would be black
467                         if ( color[3] <= 0 ) {
468                                 continue;
469                         }
470                         qglColor4fv( color );
471
472                         qglAlphaFunc( GL_GREATER, regs[ pStage->alphaTestRegister ] );
473
474                         // bind the texture
475                         pStage->texture.image->Bind();
476
477                         // set texture matrix and texGens
478                         RB_PrepareStageTexturing( pStage, surf, ac );
479
480                         // draw it
481                         RB_DrawElementsWithCounters( tri );
482
483                         RB_FinishStageTexturing( pStage, surf, ac );
484                 }
485                 qglDisable( GL_ALPHA_TEST );
486                 if ( !didDraw ) {
487                         drawSolid = true;
488                 }
489         }
490
491         // draw the entire surface solid
492         if ( drawSolid ) {
493                 qglColor4fv( color );
494                 globalImages->whiteImage->Bind();
495
496                 // draw it
497                 RB_DrawElementsWithCounters( tri );
498         }
499
500
501         // reset polygon offset
502         if ( shader->TestMaterialFlag(MF_POLYGONOFFSET) ) {
503                 qglDisable( GL_POLYGON_OFFSET_FILL );
504         }
505
506         // reset blending
507         if ( shader->GetSort() == SS_SUBVIEW ) {
508                 GL_State( GLS_DEPTHFUNC_LESS );
509         }
510
511 }
512
513 /*
514 =====================
515 RB_STD_FillDepthBuffer
516
517 If we are rendering a subview with a near clip plane, use a second texture
518 to force the alpha test to fail when behind that clip plane
519 =====================
520 */
521 void RB_STD_FillDepthBuffer( drawSurf_t **drawSurfs, int numDrawSurfs ) {
522         // if we are just doing 2D rendering, no need to fill the depth buffer
523         if ( !backEnd.viewDef->viewEntitys ) {
524                 return;
525         }
526
527         RB_LogComment( "---------- RB_STD_FillDepthBuffer ----------\n" );
528
529         // enable the second texture for mirror plane clipping if needed
530         if ( backEnd.viewDef->numClipPlanes ) {
531                 GL_SelectTexture( 1 );
532                 globalImages->alphaNotchImage->Bind();
533                 qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
534                 qglEnable( GL_TEXTURE_GEN_S );
535                 qglTexCoord2f( 1, 0.5 );
536         }
537
538         // the first texture will be used for alpha tested surfaces
539         GL_SelectTexture( 0 );
540         qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
541
542         // decal surfaces may enable polygon offset
543         qglPolygonOffset( r_offsetFactor.GetFloat(), r_offsetUnits.GetFloat() );
544
545         GL_State( GLS_DEPTHFUNC_LESS );
546
547         // Enable stencil test if we are going to be using it for shadows.
548         // If we didn't do this, it would be legal behavior to get z fighting
549         // from the ambient pass and the light passes.
550         qglEnable( GL_STENCIL_TEST );
551         qglStencilFunc( GL_ALWAYS, 1, 255 );
552
553         RB_RenderDrawSurfListWithFunction( drawSurfs, numDrawSurfs, RB_T_FillDepthBuffer );
554
555         if ( backEnd.viewDef->numClipPlanes ) {
556                 GL_SelectTexture( 1 );
557                 globalImages->BindNull();
558                 qglDisable( GL_TEXTURE_GEN_S );
559                 GL_SelectTexture( 0 );
560         }
561
562 }
563
564 /*
565 =============================================================================================
566
567 SHADER PASSES
568
569 =============================================================================================
570 */
571
572 /*
573 ==================
574 RB_SetProgramEnvironment
575
576 Sets variables that can be used by all vertex programs
577 ==================
578 */
579 void RB_SetProgramEnvironment( void ) {
580         float   parm[4];
581         int             pot;
582
583         if ( !glConfig.ARBVertexProgramAvailable ) {
584                 return;
585         }
586
587 #if 0
588         // screen power of two correction factor, one pixel in so we don't get a bilerp
589         // of an uncopied pixel
590         int      w = backEnd.viewDef->viewport.x2 - backEnd.viewDef->viewport.x1 + 1;
591         pot = globalImages->currentRenderImage->uploadWidth;
592         if ( w == pot ) {
593                 parm[0] = 1.0;
594         } else {
595                 parm[0] = (float)(w-1) / pot;
596         }
597
598         int      h = backEnd.viewDef->viewport.y2 - backEnd.viewDef->viewport.y1 + 1;
599         pot = globalImages->currentRenderImage->uploadHeight;
600         if ( h == pot ) {
601                 parm[1] = 1.0;
602         } else {
603                 parm[1] = (float)(h-1) / pot;
604         }
605
606         parm[2] = 0;
607         parm[3] = 1;
608         qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 0, parm );
609 #else
610         // screen power of two correction factor, assuming the copy to _currentRender
611         // also copied an extra row and column for the bilerp
612         int      w = backEnd.viewDef->viewport.x2 - backEnd.viewDef->viewport.x1 + 1;
613         pot = globalImages->currentRenderImage->uploadWidth;
614         parm[0] = (float)w / pot;
615
616         int      h = backEnd.viewDef->viewport.y2 - backEnd.viewDef->viewport.y1 + 1;
617         pot = globalImages->currentRenderImage->uploadHeight;
618         parm[1] = (float)h / pot;
619
620         parm[2] = 0;
621         parm[3] = 1;
622         qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 0, parm );
623 #endif
624
625         qglProgramEnvParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 0, parm );
626
627         // window coord to 0.0 to 1.0 conversion
628         parm[0] = 1.0 / w;
629         parm[1] = 1.0 / h;
630         parm[2] = 0;
631         parm[3] = 1;
632         qglProgramEnvParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 1, parm );
633
634         //
635         // set eye position in global space
636         //
637         parm[0] = backEnd.viewDef->renderView.vieworg[0];
638         parm[1] = backEnd.viewDef->renderView.vieworg[1];
639         parm[2] = backEnd.viewDef->renderView.vieworg[2];
640         parm[3] = 1.0;
641         qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 1, parm );
642
643
644 }
645
646 /*
647 ==================
648 RB_SetProgramEnvironmentSpace
649
650 Sets variables related to the current space that can be used by all vertex programs
651 ==================
652 */
653 void RB_SetProgramEnvironmentSpace( void ) {
654         if ( !glConfig.ARBVertexProgramAvailable ) {
655                 return;
656         }
657
658         const struct viewEntity_s *space = backEnd.currentSpace;
659         float   parm[4];
660
661         // set eye position in local space
662         R_GlobalPointToLocal( space->modelMatrix, backEnd.viewDef->renderView.vieworg, *(idVec3 *)parm );
663         parm[3] = 1.0;
664         qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 5, parm );
665
666         // we need the model matrix without it being combined with the view matrix
667         // so we can transform local vectors to global coordinates
668         parm[0] = space->modelMatrix[0];
669         parm[1] = space->modelMatrix[4];
670         parm[2] = space->modelMatrix[8];
671         parm[3] = space->modelMatrix[12];
672         qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 6, parm );
673         parm[0] = space->modelMatrix[1];
674         parm[1] = space->modelMatrix[5];
675         parm[2] = space->modelMatrix[9];
676         parm[3] = space->modelMatrix[13];
677         qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 7, parm );
678         parm[0] = space->modelMatrix[2];
679         parm[1] = space->modelMatrix[6];
680         parm[2] = space->modelMatrix[10];
681         parm[3] = space->modelMatrix[14];
682         qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 8, parm );
683 }
684
685 /*
686 ==================
687 RB_STD_T_RenderShaderPasses
688
689 This is also called for the generated 2D rendering
690 ==================
691 */
692 void RB_STD_T_RenderShaderPasses( const drawSurf_t *surf ) {
693         int                     stage;
694         const idMaterial        *shader;
695         const shaderStage_t *pStage;
696         const float     *regs;
697         float           color[4];
698         const srfTriangles_t    *tri;
699
700         tri = surf->geo;
701         shader = surf->material;
702
703         if ( !shader->HasAmbient() ) {
704                 return;
705         }
706
707         if ( shader->IsPortalSky() ) {
708                 return;
709         }
710
711         // change the matrix if needed
712         if ( surf->space != backEnd.currentSpace ) {
713                 qglLoadMatrixf( surf->space->modelViewMatrix );
714                 backEnd.currentSpace = surf->space;
715                 RB_SetProgramEnvironmentSpace();
716         }
717
718         // change the scissor if needed
719         if ( r_useScissor.GetBool() && !backEnd.currentScissor.Equals( surf->scissorRect ) ) {
720                 backEnd.currentScissor = surf->scissorRect;
721                 qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1, 
722                         backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1,
723                         backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1,
724                         backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 );
725         }
726
727         // some deforms may disable themselves by setting numIndexes = 0
728         if ( !tri->numIndexes ) {
729                 return;
730         }
731
732         if ( !tri->ambientCache ) {
733                 common->Printf( "RB_T_RenderShaderPasses: !tri->ambientCache\n" );
734                 return;
735         }
736
737         // get the expressions for conditionals / color / texcoords
738         regs = surf->shaderRegisters;
739
740         // set face culling appropriately
741         GL_Cull( shader->GetCullType() );
742
743         // set polygon offset if necessary
744         if ( shader->TestMaterialFlag(MF_POLYGONOFFSET) ) {
745                 qglEnable( GL_POLYGON_OFFSET_FILL );
746                 qglPolygonOffset( r_offsetFactor.GetFloat(), r_offsetUnits.GetFloat() * shader->GetPolygonOffset() );
747         }
748         
749         if ( surf->space->weaponDepthHack ) {
750                 RB_EnterWeaponDepthHack();
751         }
752
753         if ( surf->space->modelDepthHack != 0.0f ) {
754                 RB_EnterModelDepthHack( surf->space->modelDepthHack );
755         }
756
757         idDrawVert *ac = (idDrawVert *)vertexCache.Position( tri->ambientCache );
758         qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() );
759         qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), reinterpret_cast<void *>(&ac->st) );
760
761         for ( stage = 0; stage < shader->GetNumStages() ; stage++ ) {           
762                 pStage = shader->GetStage(stage);
763
764                 // check the enable condition
765                 if ( regs[ pStage->conditionRegister ] == 0 ) {
766                         continue;
767                 }
768
769                 // skip the stages involved in lighting
770                 if ( pStage->lighting != SL_AMBIENT ) {
771                         continue;
772                 }
773
774                 // skip if the stage is ( GL_ZERO, GL_ONE ), which is used for some alpha masks
775                 if ( ( pStage->drawStateBits & (GLS_SRCBLEND_BITS|GLS_DSTBLEND_BITS) ) == ( GLS_SRCBLEND_ZERO | GLS_DSTBLEND_ONE ) ) {
776                         continue;
777                 }
778
779                 // see if we are a new-style stage
780                 newShaderStage_t *newStage = pStage->newStage;
781                 if ( newStage ) {
782                         //--------------------------
783                         //
784                         // new style stages
785                         //
786                         //--------------------------
787
788                         // completely skip the stage if we don't have the capability
789                         if ( tr.backEndRenderer != BE_ARB2 ) {
790                                 continue;
791                         }
792                         if ( r_skipNewAmbient.GetBool() ) {
793                                 continue;
794                         }
795                         qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( idDrawVert ), (void *)&ac->color );
796                         qglVertexAttribPointerARB( 9, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[0].ToFloatPtr() );
797                         qglVertexAttribPointerARB( 10, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[1].ToFloatPtr() );
798                         qglNormalPointer( GL_FLOAT, sizeof( idDrawVert ), ac->normal.ToFloatPtr() );
799
800                         qglEnableClientState( GL_COLOR_ARRAY );
801                         qglEnableVertexAttribArrayARB( 9 );
802                         qglEnableVertexAttribArrayARB( 10 );
803                         qglEnableClientState( GL_NORMAL_ARRAY );
804
805                         GL_State( pStage->drawStateBits );
806                         
807                         qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, newStage->vertexProgram );
808                         qglEnable( GL_VERTEX_PROGRAM_ARB );
809
810                         // megaTextures bind a lot of images and set a lot of parameters
811                         if ( newStage->megaTexture ) {
812                                 newStage->megaTexture->SetMappingForSurface( tri );
813                                 idVec3  localViewer;
814                                 R_GlobalPointToLocal( surf->space->modelMatrix, backEnd.viewDef->renderView.vieworg, localViewer );
815                                 newStage->megaTexture->BindForViewOrigin( localViewer );
816                         }
817
818                         for ( int i = 0 ; i < newStage->numVertexParms ; i++ ) {
819                                 float   parm[4];
820                                 parm[0] = regs[ newStage->vertexParms[i][0] ];
821                                 parm[1] = regs[ newStage->vertexParms[i][1] ];
822                                 parm[2] = regs[ newStage->vertexParms[i][2] ];
823                                 parm[3] = regs[ newStage->vertexParms[i][3] ];
824                                 qglProgramLocalParameter4fvARB( GL_VERTEX_PROGRAM_ARB, i, parm );
825                         }
826
827                         for ( int i = 0 ; i < newStage->numFragmentProgramImages ; i++ ) {
828                                 if ( newStage->fragmentProgramImages[i] ) {
829                                         GL_SelectTexture( i );
830                                         newStage->fragmentProgramImages[i]->Bind();
831                                 }
832                         }
833                         qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, newStage->fragmentProgram );
834                         qglEnable( GL_FRAGMENT_PROGRAM_ARB );
835
836                         // draw it
837                         RB_DrawElementsWithCounters( tri );
838
839                         for ( int i = 1 ; i < newStage->numFragmentProgramImages ; i++ ) {
840                                 if ( newStage->fragmentProgramImages[i] ) {
841                                         GL_SelectTexture( i );
842                                         globalImages->BindNull();
843                                 }
844                         }
845                         if ( newStage->megaTexture ) {
846                                 newStage->megaTexture->Unbind();
847                         }
848
849                         GL_SelectTexture( 0 );
850
851                         qglDisable( GL_VERTEX_PROGRAM_ARB );
852                         qglDisable( GL_FRAGMENT_PROGRAM_ARB );
853                         // Fixme: Hack to get around an apparent bug in ATI drivers.  Should remove as soon as it gets fixed.
854                         qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, 0 );
855
856                         qglDisableClientState( GL_COLOR_ARRAY );
857                         qglDisableVertexAttribArrayARB( 9 );
858                         qglDisableVertexAttribArrayARB( 10 );
859                         qglDisableClientState( GL_NORMAL_ARRAY );
860                         continue;
861                 }
862
863                 //--------------------------
864                 //
865                 // old style stages
866                 //
867                 //--------------------------
868
869                 // set the color
870                 color[0] = regs[ pStage->color.registers[0] ];
871                 color[1] = regs[ pStage->color.registers[1] ];
872                 color[2] = regs[ pStage->color.registers[2] ];
873                 color[3] = regs[ pStage->color.registers[3] ];
874
875                 // skip the entire stage if an add would be black
876                 if ( ( pStage->drawStateBits & (GLS_SRCBLEND_BITS|GLS_DSTBLEND_BITS) ) == ( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE ) 
877                         && color[0] <= 0 && color[1] <= 0 && color[2] <= 0 ) {
878                         continue;
879                 }
880
881                 // skip the entire stage if a blend would be completely transparent
882                 if ( ( pStage->drawStateBits & (GLS_SRCBLEND_BITS|GLS_DSTBLEND_BITS) ) == ( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA )
883                         && color[3] <= 0 ) {
884                         continue;
885                 }
886
887                 // select the vertex color source
888                 if ( pStage->vertexColor == SVC_IGNORE ) {
889                         qglColor4fv( color );
890                 } else {
891                         qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( idDrawVert ), (void *)&ac->color );
892                         qglEnableClientState( GL_COLOR_ARRAY );
893
894                         if ( pStage->vertexColor == SVC_INVERSE_MODULATE ) {
895                                 GL_TexEnv( GL_COMBINE_ARB );
896                                 qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE );
897                                 qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE );
898                                 qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB );
899                                 qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
900                                 qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_ONE_MINUS_SRC_COLOR );
901                                 qglTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1 );
902                         }
903
904                         // for vertex color and modulated color, we need to enable a second
905                         // texture stage
906                         if ( color[0] != 1 || color[1] != 1 || color[2] != 1 || color[3] != 1 ) {
907                                 GL_SelectTexture( 1 );
908
909                                 globalImages->whiteImage->Bind();
910                                 GL_TexEnv( GL_COMBINE_ARB );
911
912                                 qglTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color );
913
914                                 qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE );
915                                 qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB );
916                                 qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_CONSTANT_ARB );
917                                 qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
918                                 qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
919                                 qglTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1 );
920
921                                 qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE );
922                                 qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB );
923                                 qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_CONSTANT_ARB );
924                                 qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA );
925                                 qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA );
926                                 qglTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1 );
927
928                                 GL_SelectTexture( 0 );
929                         }
930                 }
931
932                 // bind the texture
933                 RB_BindVariableStageImage( &pStage->texture, regs );
934
935                 // set the state
936                 GL_State( pStage->drawStateBits );
937                 
938                 RB_PrepareStageTexturing( pStage, surf, ac );
939
940                 // draw it
941                 RB_DrawElementsWithCounters( tri );
942
943                 RB_FinishStageTexturing( pStage, surf, ac );
944                 
945                 if ( pStage->vertexColor != SVC_IGNORE ) {
946                         qglDisableClientState( GL_COLOR_ARRAY );
947
948                         GL_SelectTexture( 1 );
949                         GL_TexEnv( GL_MODULATE );
950                         globalImages->BindNull();
951                         GL_SelectTexture( 0 );
952                         GL_TexEnv( GL_MODULATE );
953                 }
954         }
955
956         // reset polygon offset
957         if ( shader->TestMaterialFlag(MF_POLYGONOFFSET) ) {
958                 qglDisable( GL_POLYGON_OFFSET_FILL );
959         }
960         if ( surf->space->weaponDepthHack || surf->space->modelDepthHack != 0.0f ) {
961                 RB_LeaveDepthHack();
962         }
963 }
964
965 /*
966 =====================
967 RB_STD_DrawShaderPasses
968
969 Draw non-light dependent passes
970 =====================
971 */
972 int RB_STD_DrawShaderPasses( drawSurf_t **drawSurfs, int numDrawSurfs ) {
973         int                             i;
974
975         // only obey skipAmbient if we are rendering a view
976         if ( backEnd.viewDef->viewEntitys && r_skipAmbient.GetBool() ) {
977                 return numDrawSurfs;
978         }
979
980         RB_LogComment( "---------- RB_STD_DrawShaderPasses ----------\n" );
981
982         // if we are about to draw the first surface that needs
983         // the rendering in a texture, copy it over
984         if ( drawSurfs[0]->material->GetSort() >= SS_POST_PROCESS ) {
985                 if ( r_skipPostProcess.GetBool() ) {
986                         return 0;
987                 }
988
989                 // only dump if in a 3d view
990                 if ( backEnd.viewDef->viewEntitys && tr.backEndRenderer == BE_ARB2 ) {
991                         globalImages->currentRenderImage->CopyFramebuffer( backEnd.viewDef->viewport.x1,
992                                 backEnd.viewDef->viewport.y1,  backEnd.viewDef->viewport.x2 -  backEnd.viewDef->viewport.x1 + 1,
993                                 backEnd.viewDef->viewport.y2 -  backEnd.viewDef->viewport.y1 + 1, true );
994                 }
995                 backEnd.currentRenderCopied = true;
996         }
997
998         GL_SelectTexture( 1 );
999         globalImages->BindNull();
1000
1001         GL_SelectTexture( 0 );
1002         qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
1003
1004         RB_SetProgramEnvironment();
1005
1006         // we don't use RB_RenderDrawSurfListWithFunction()
1007         // because we want to defer the matrix load because many
1008         // surfaces won't draw any ambient passes
1009         backEnd.currentSpace = NULL;
1010         for (i = 0  ; i < numDrawSurfs ; i++ ) {
1011                 if ( drawSurfs[i]->material->SuppressInSubview() ) {
1012                         continue;
1013                 }
1014
1015                 if ( backEnd.viewDef->isXraySubview && drawSurfs[i]->space->entityDef ) {
1016                         if ( drawSurfs[i]->space->entityDef->parms.xrayIndex != 2 ) {
1017                                 continue;
1018                         }
1019                 }
1020
1021                 // we need to draw the post process shaders after we have drawn the fog lights
1022                 if ( drawSurfs[i]->material->GetSort() >= SS_POST_PROCESS
1023                         && !backEnd.currentRenderCopied ) {
1024                         break;
1025                 }
1026
1027                 RB_STD_T_RenderShaderPasses( drawSurfs[i] );
1028         }
1029
1030         GL_Cull( CT_FRONT_SIDED );
1031         qglColor3f( 1, 1, 1 );
1032
1033         return i;
1034 }
1035
1036
1037
1038 /*
1039 ==============================================================================
1040
1041 BACK END RENDERING OF STENCIL SHADOWS
1042
1043 ==============================================================================
1044 */
1045
1046 /*
1047 =====================
1048 RB_T_Shadow
1049
1050 the shadow volumes face INSIDE
1051 =====================
1052 */
1053 static void RB_T_Shadow( const drawSurf_t *surf ) {
1054         const srfTriangles_t    *tri;
1055
1056         // set the light position if we are using a vertex program to project the rear surfaces
1057         if ( tr.backEndRendererHasVertexPrograms && r_useShadowVertexProgram.GetBool()
1058                 && surf->space != backEnd.currentSpace ) {
1059                 idVec4 localLight;
1060
1061                 R_GlobalPointToLocal( surf->space->modelMatrix, backEnd.vLight->globalLightOrigin, localLight.ToVec3() );
1062                 localLight.w = 0.0f;
1063                 qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_ORIGIN, localLight.ToFloatPtr() );
1064         }
1065
1066         tri = surf->geo;
1067
1068         if ( !tri->shadowCache ) {
1069                 return;
1070         }
1071
1072         qglVertexPointer( 4, GL_FLOAT, sizeof( shadowCache_t ), vertexCache.Position(tri->shadowCache) );
1073
1074         // we always draw the sil planes, but we may not need to draw the front or rear caps
1075         int     numIndexes;
1076         bool external = false;
1077
1078         if ( !r_useExternalShadows.GetInteger() ) {
1079                 numIndexes = tri->numIndexes;
1080         } else if ( r_useExternalShadows.GetInteger() == 2 ) { // force to no caps for testing
1081                 numIndexes = tri->numShadowIndexesNoCaps;
1082         } else if ( !(surf->dsFlags & DSF_VIEW_INSIDE_SHADOW) ) { 
1083                 // if we aren't inside the shadow projection, no caps are ever needed needed
1084                 numIndexes = tri->numShadowIndexesNoCaps;
1085                 external = true;
1086         } else if ( !backEnd.vLight->viewInsideLight && !(surf->geo->shadowCapPlaneBits & SHADOW_CAP_INFINITE) ) {
1087                 // if we are inside the shadow projection, but outside the light, and drawing
1088                 // a non-infinite shadow, we can skip some caps
1089                 if ( backEnd.vLight->viewSeesShadowPlaneBits & surf->geo->shadowCapPlaneBits ) {
1090                         // we can see through a rear cap, so we need to draw it, but we can skip the
1091                         // caps on the actual surface
1092                         numIndexes = tri->numShadowIndexesNoFrontCaps;
1093                 } else {
1094                         // we don't need to draw any caps
1095                         numIndexes = tri->numShadowIndexesNoCaps;
1096                 }
1097                 external = true;
1098         } else {
1099                 // must draw everything
1100                 numIndexes = tri->numIndexes;
1101         }
1102
1103         // set depth bounds
1104         if( glConfig.depthBoundsTestAvailable && r_useDepthBoundsTest.GetBool() ) {
1105                 qglDepthBoundsEXT( surf->scissorRect.zmin, surf->scissorRect.zmax );
1106         }
1107
1108         // debug visualization
1109         if ( r_showShadows.GetInteger() ) {
1110                 if ( r_showShadows.GetInteger() == 3 ) {
1111                         if ( external ) {
1112                                 qglColor3f( 0.1/backEnd.overBright, 1/backEnd.overBright, 0.1/backEnd.overBright );
1113                         } else {
1114                                 // these are the surfaces that require the reverse
1115                                 qglColor3f( 1/backEnd.overBright, 0.1/backEnd.overBright, 0.1/backEnd.overBright );
1116                         }
1117                 } else {
1118                         // draw different color for turboshadows
1119                         if ( surf->geo->shadowCapPlaneBits & SHADOW_CAP_INFINITE ) {
1120                                 if ( numIndexes == tri->numIndexes ) {
1121                                         qglColor3f( 1/backEnd.overBright, 0.1/backEnd.overBright, 0.1/backEnd.overBright );
1122                                 } else {
1123                                         qglColor3f( 1/backEnd.overBright, 0.4/backEnd.overBright, 0.1/backEnd.overBright );
1124                                 }
1125                         } else {
1126                                 if ( numIndexes == tri->numIndexes ) {
1127                                         qglColor3f( 0.1/backEnd.overBright, 1/backEnd.overBright, 0.1/backEnd.overBright );
1128                                 } else if ( numIndexes == tri->numShadowIndexesNoFrontCaps ) {
1129                                         qglColor3f( 0.1/backEnd.overBright, 1/backEnd.overBright, 0.6/backEnd.overBright );
1130                                 } else {
1131                                         qglColor3f( 0.6/backEnd.overBright, 1/backEnd.overBright, 0.1/backEnd.overBright );
1132                                 }
1133                         }
1134                 }
1135
1136                 qglStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
1137                 qglDisable( GL_STENCIL_TEST );
1138                 GL_Cull( CT_TWO_SIDED );
1139                 RB_DrawShadowElementsWithCounters( tri, numIndexes );
1140                 GL_Cull( CT_FRONT_SIDED );
1141                 qglEnable( GL_STENCIL_TEST );
1142
1143                 return;
1144         }
1145
1146         // patent-free work around
1147         if ( !external ) {
1148                 // "preload" the stencil buffer with the number of volumes
1149                 // that get clipped by the near or far clip plane
1150                 qglStencilOp( GL_KEEP, tr.stencilDecr, tr.stencilDecr );
1151                 GL_Cull( CT_FRONT_SIDED );
1152                 RB_DrawShadowElementsWithCounters( tri, numIndexes );
1153                 qglStencilOp( GL_KEEP, tr.stencilIncr, tr.stencilIncr );
1154                 GL_Cull( CT_BACK_SIDED );
1155                 RB_DrawShadowElementsWithCounters( tri, numIndexes );
1156         }
1157
1158         // traditional depth-pass stencil shadows
1159         qglStencilOp( GL_KEEP, GL_KEEP, tr.stencilIncr );
1160         GL_Cull( CT_FRONT_SIDED );
1161         RB_DrawShadowElementsWithCounters( tri, numIndexes );
1162
1163         qglStencilOp( GL_KEEP, GL_KEEP, tr.stencilDecr );
1164         GL_Cull( CT_BACK_SIDED );
1165         RB_DrawShadowElementsWithCounters( tri, numIndexes );
1166 }
1167
1168 /*
1169 =====================
1170 RB_StencilShadowPass
1171
1172 Stencil test should already be enabled, and the stencil buffer should have
1173 been set to 128 on any surfaces that might receive shadows
1174 =====================
1175 */
1176 void RB_StencilShadowPass( const drawSurf_t *drawSurfs ) {
1177         if ( !r_shadows.GetBool() ) {
1178                 return;
1179         }
1180
1181         if ( !drawSurfs ) {
1182                 return;
1183         }
1184
1185         RB_LogComment( "---------- RB_StencilShadowPass ----------\n" );
1186
1187         globalImages->BindNull();
1188         qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
1189
1190         // for visualizing the shadows
1191         if ( r_showShadows.GetInteger() ) {
1192                 if ( r_showShadows.GetInteger() == 2 ) {
1193                         // draw filled in
1194                         GL_State( GLS_DEPTHMASK | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_LESS  );
1195                 } else {
1196                         // draw as lines, filling the depth buffer
1197                         GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_POLYMODE_LINE | GLS_DEPTHFUNC_ALWAYS  );
1198                 }
1199         } else {
1200                 // don't write to the color buffer, just the stencil buffer
1201                 GL_State( GLS_DEPTHMASK | GLS_COLORMASK | GLS_ALPHAMASK | GLS_DEPTHFUNC_LESS );
1202         }
1203
1204         if ( r_shadowPolygonFactor.GetFloat() || r_shadowPolygonOffset.GetFloat() ) {
1205                 qglPolygonOffset( r_shadowPolygonFactor.GetFloat(), -r_shadowPolygonOffset.GetFloat() );
1206                 qglEnable( GL_POLYGON_OFFSET_FILL );
1207         }
1208
1209         qglStencilFunc( GL_ALWAYS, 1, 255 );
1210
1211         if ( glConfig.depthBoundsTestAvailable && r_useDepthBoundsTest.GetBool() ) {
1212                 qglEnable( GL_DEPTH_BOUNDS_TEST_EXT );
1213         }
1214
1215         RB_RenderDrawSurfChainWithFunction( drawSurfs, RB_T_Shadow );
1216
1217         GL_Cull( CT_FRONT_SIDED );
1218
1219         if ( r_shadowPolygonFactor.GetFloat() || r_shadowPolygonOffset.GetFloat() ) {
1220                 qglDisable( GL_POLYGON_OFFSET_FILL );
1221         }
1222
1223         if ( glConfig.depthBoundsTestAvailable && r_useDepthBoundsTest.GetBool() ) {
1224                 qglDisable( GL_DEPTH_BOUNDS_TEST_EXT );
1225         }
1226
1227         qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
1228
1229         qglStencilFunc( GL_GEQUAL, 128, 255 );
1230         qglStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
1231 }
1232
1233
1234
1235 /*
1236 =============================================================================================
1237
1238 BLEND LIGHT PROJECTION
1239
1240 =============================================================================================
1241 */
1242
1243 /*
1244 =====================
1245 RB_T_BlendLight
1246
1247 =====================
1248 */
1249 static void RB_T_BlendLight( const drawSurf_t *surf ) {
1250         const srfTriangles_t *tri;
1251
1252         tri = surf->geo;
1253
1254         if ( backEnd.currentSpace != surf->space ) {
1255                 idPlane lightProject[4];
1256                 int             i;
1257
1258                 for ( i = 0 ; i < 4 ; i++ ) {
1259                         R_GlobalPlaneToLocal( surf->space->modelMatrix, backEnd.vLight->lightProject[i], lightProject[i] );
1260                 }
1261
1262                 GL_SelectTexture( 0 );
1263                 qglTexGenfv( GL_S, GL_OBJECT_PLANE, lightProject[0].ToFloatPtr() );
1264                 qglTexGenfv( GL_T, GL_OBJECT_PLANE, lightProject[1].ToFloatPtr() );
1265                 qglTexGenfv( GL_Q, GL_OBJECT_PLANE, lightProject[2].ToFloatPtr() );
1266
1267                 GL_SelectTexture( 1 );
1268                 qglTexGenfv( GL_S, GL_OBJECT_PLANE, lightProject[3].ToFloatPtr() );
1269         }
1270
1271         // this gets used for both blend lights and shadow draws
1272         if ( tri->ambientCache ) {
1273                 idDrawVert      *ac = (idDrawVert *)vertexCache.Position( tri->ambientCache );
1274                 qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() );
1275         } else if ( tri->shadowCache ) {
1276                 shadowCache_t   *sc = (shadowCache_t *)vertexCache.Position( tri->shadowCache );
1277                 qglVertexPointer( 3, GL_FLOAT, sizeof( shadowCache_t ), sc->xyz.ToFloatPtr() );
1278         }
1279
1280         RB_DrawElementsWithCounters( tri );
1281 }
1282
1283
1284 /*
1285 =====================
1286 RB_BlendLight
1287
1288 Dual texture together the falloff and projection texture with a blend
1289 mode to the framebuffer, instead of interacting with the surface texture
1290 =====================
1291 */
1292 static void RB_BlendLight( const drawSurf_t *drawSurfs,  const drawSurf_t *drawSurfs2 ) {
1293         const idMaterial        *lightShader;
1294         const shaderStage_t     *stage;
1295         int                                     i;
1296         const float     *regs;
1297
1298         if ( !drawSurfs ) {
1299                 return;
1300         }
1301         if ( r_skipBlendLights.GetBool() ) {
1302                 return;
1303         }
1304         RB_LogComment( "---------- RB_BlendLight ----------\n" );
1305
1306         lightShader = backEnd.vLight->lightShader;
1307         regs = backEnd.vLight->shaderRegisters;
1308
1309         // texture 1 will get the falloff texture
1310         GL_SelectTexture( 1 );
1311         qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
1312         qglEnable( GL_TEXTURE_GEN_S );
1313         qglTexCoord2f( 0, 0.5 );
1314         backEnd.vLight->falloffImage->Bind();
1315
1316         // texture 0 will get the projected texture
1317         GL_SelectTexture( 0 );
1318         qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
1319         qglEnable( GL_TEXTURE_GEN_S );
1320         qglEnable( GL_TEXTURE_GEN_T );
1321         qglEnable( GL_TEXTURE_GEN_Q );
1322
1323         for ( i = 0 ; i < lightShader->GetNumStages() ; i++ ) {
1324                 stage = lightShader->GetStage(i);
1325
1326                 if ( !regs[ stage->conditionRegister ] ) {
1327                         continue;
1328                 }
1329
1330                 GL_State( GLS_DEPTHMASK | stage->drawStateBits | GLS_DEPTHFUNC_EQUAL );
1331
1332                 GL_SelectTexture( 0 );
1333                 stage->texture.image->Bind();
1334
1335                 if ( stage->texture.hasMatrix ) {
1336                         RB_LoadShaderTextureMatrix( regs, &stage->texture );
1337                 }
1338
1339                 // get the modulate values from the light, including alpha, unlike normal lights
1340                 backEnd.lightColor[0] = regs[ stage->color.registers[0] ];
1341                 backEnd.lightColor[1] = regs[ stage->color.registers[1] ];
1342                 backEnd.lightColor[2] = regs[ stage->color.registers[2] ];
1343                 backEnd.lightColor[3] = regs[ stage->color.registers[3] ];
1344                 qglColor4fv( backEnd.lightColor );
1345
1346                 RB_RenderDrawSurfChainWithFunction( drawSurfs, RB_T_BlendLight );
1347                 RB_RenderDrawSurfChainWithFunction( drawSurfs2, RB_T_BlendLight );
1348
1349                 if ( stage->texture.hasMatrix ) {
1350                         GL_SelectTexture( 0 );
1351                         qglMatrixMode( GL_TEXTURE );
1352                         qglLoadIdentity();
1353                         qglMatrixMode( GL_MODELVIEW );
1354                 }
1355         }
1356
1357         GL_SelectTexture( 1 );
1358         qglDisable( GL_TEXTURE_GEN_S );
1359         globalImages->BindNull();
1360
1361         GL_SelectTexture( 0 );
1362         qglDisable( GL_TEXTURE_GEN_S );
1363         qglDisable( GL_TEXTURE_GEN_T );
1364         qglDisable( GL_TEXTURE_GEN_Q );
1365 }
1366
1367
1368 //========================================================================
1369
1370 static idPlane  fogPlanes[4];
1371
1372 /*
1373 =====================
1374 RB_T_BasicFog
1375
1376 =====================
1377 */
1378 static void RB_T_BasicFog( const drawSurf_t *surf ) {
1379         if ( backEnd.currentSpace != surf->space ) {
1380                 idPlane local;
1381
1382                 GL_SelectTexture( 0 );
1383
1384                 R_GlobalPlaneToLocal( surf->space->modelMatrix, fogPlanes[0], local );
1385                 local[3] += 0.5;
1386                 qglTexGenfv( GL_S, GL_OBJECT_PLANE, local.ToFloatPtr() );
1387
1388 //              R_GlobalPlaneToLocal( surf->space->modelMatrix, fogPlanes[1], local );
1389 //              local[3] += 0.5;
1390 local[0] = local[1] = local[2] = 0; local[3] = 0.5;
1391                 qglTexGenfv( GL_T, GL_OBJECT_PLANE, local.ToFloatPtr() );
1392
1393                 GL_SelectTexture( 1 );
1394
1395                 // GL_S is constant per viewer
1396                 R_GlobalPlaneToLocal( surf->space->modelMatrix, fogPlanes[2], local );
1397                 local[3] += FOG_ENTER;
1398                 qglTexGenfv( GL_T, GL_OBJECT_PLANE, local.ToFloatPtr() );
1399
1400                 R_GlobalPlaneToLocal( surf->space->modelMatrix, fogPlanes[3], local );
1401                 qglTexGenfv( GL_S, GL_OBJECT_PLANE, local.ToFloatPtr() );
1402         }
1403
1404         RB_T_RenderTriangleSurface( surf );
1405 }
1406
1407
1408
1409 /*
1410 ==================
1411 RB_FogPass
1412 ==================
1413 */
1414 static void RB_FogPass( const drawSurf_t *drawSurfs,  const drawSurf_t *drawSurfs2 ) {
1415         const srfTriangles_t*frustumTris;
1416         drawSurf_t                      ds;
1417         const idMaterial        *lightShader;
1418         const shaderStage_t     *stage;
1419         const float                     *regs;
1420
1421         RB_LogComment( "---------- RB_FogPass ----------\n" );
1422
1423         // create a surface for the light frustom triangles, which are oriented drawn side out
1424         frustumTris = backEnd.vLight->frustumTris;
1425
1426         // if we ran out of vertex cache memory, skip it
1427         if ( !frustumTris->ambientCache ) {
1428                 return;
1429         }
1430         memset( &ds, 0, sizeof( ds ) );
1431         ds.space = &backEnd.viewDef->worldSpace;
1432         ds.geo = frustumTris;
1433         ds.scissorRect = backEnd.viewDef->scissor;
1434
1435         // find the current color and density of the fog
1436         lightShader = backEnd.vLight->lightShader;
1437         regs = backEnd.vLight->shaderRegisters;
1438         // assume fog shaders have only a single stage
1439         stage = lightShader->GetStage(0);
1440
1441         backEnd.lightColor[0] = regs[ stage->color.registers[0] ];
1442         backEnd.lightColor[1] = regs[ stage->color.registers[1] ];
1443         backEnd.lightColor[2] = regs[ stage->color.registers[2] ];
1444         backEnd.lightColor[3] = regs[ stage->color.registers[3] ];
1445
1446         qglColor3fv( backEnd.lightColor );
1447
1448         // calculate the falloff planes
1449         float   a;
1450
1451         // if they left the default value on, set a fog distance of 500
1452         if ( backEnd.lightColor[3] <= 1.0 ) {
1453                 a = -0.5f / DEFAULT_FOG_DISTANCE;
1454         } else {
1455                 // otherwise, distance = alpha color
1456                 a = -0.5f / backEnd.lightColor[3];
1457         }
1458
1459         GL_State( GLS_DEPTHMASK | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_EQUAL );
1460
1461         // texture 0 is the falloff image
1462         GL_SelectTexture( 0 );
1463         globalImages->fogImage->Bind();
1464         //GL_Bind( tr.whiteImage );
1465         qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
1466         qglEnable( GL_TEXTURE_GEN_S );
1467         qglEnable( GL_TEXTURE_GEN_T );
1468         qglTexCoord2f( 0.5f, 0.5f );            // make sure Q is set
1469
1470         fogPlanes[0][0] = a * backEnd.viewDef->worldSpace.modelViewMatrix[2];
1471         fogPlanes[0][1] = a * backEnd.viewDef->worldSpace.modelViewMatrix[6];
1472         fogPlanes[0][2] = a * backEnd.viewDef->worldSpace.modelViewMatrix[10];
1473         fogPlanes[0][3] = a * backEnd.viewDef->worldSpace.modelViewMatrix[14];
1474
1475         fogPlanes[1][0] = a * backEnd.viewDef->worldSpace.modelViewMatrix[0];
1476         fogPlanes[1][1] = a * backEnd.viewDef->worldSpace.modelViewMatrix[4];
1477         fogPlanes[1][2] = a * backEnd.viewDef->worldSpace.modelViewMatrix[8];
1478         fogPlanes[1][3] = a * backEnd.viewDef->worldSpace.modelViewMatrix[12];
1479
1480
1481         // texture 1 is the entering plane fade correction
1482         GL_SelectTexture( 1 );
1483         globalImages->fogEnterImage->Bind();
1484         qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
1485         qglEnable( GL_TEXTURE_GEN_S );
1486         qglEnable( GL_TEXTURE_GEN_T );
1487
1488         // T will get a texgen for the fade plane, which is always the "top" plane on unrotated lights
1489         fogPlanes[2][0] = 0.001f * backEnd.vLight->fogPlane[0];
1490         fogPlanes[2][1] = 0.001f * backEnd.vLight->fogPlane[1];
1491         fogPlanes[2][2] = 0.001f * backEnd.vLight->fogPlane[2];
1492         fogPlanes[2][3] = 0.001f * backEnd.vLight->fogPlane[3];
1493
1494         // S is based on the view origin
1495         float s = backEnd.viewDef->renderView.vieworg * fogPlanes[2].Normal() + fogPlanes[2][3];
1496
1497         fogPlanes[3][0] = 0;
1498         fogPlanes[3][1] = 0;
1499         fogPlanes[3][2] = 0;
1500         fogPlanes[3][3] = FOG_ENTER + s;
1501
1502         qglTexCoord2f( FOG_ENTER + s, FOG_ENTER );
1503
1504
1505         // draw it
1506         RB_RenderDrawSurfChainWithFunction( drawSurfs, RB_T_BasicFog );
1507         RB_RenderDrawSurfChainWithFunction( drawSurfs2, RB_T_BasicFog );
1508
1509         // the light frustum bounding planes aren't in the depth buffer, so use depthfunc_less instead
1510         // of depthfunc_equal
1511         GL_State( GLS_DEPTHMASK | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_LESS );
1512         GL_Cull( CT_BACK_SIDED );
1513         RB_RenderDrawSurfChainWithFunction( &ds, RB_T_BasicFog );
1514         GL_Cull( CT_FRONT_SIDED );
1515
1516         GL_SelectTexture( 1 );
1517         qglDisable( GL_TEXTURE_GEN_S );
1518         qglDisable( GL_TEXTURE_GEN_T );
1519         globalImages->BindNull();
1520
1521         GL_SelectTexture( 0 );
1522         qglDisable( GL_TEXTURE_GEN_S );
1523         qglDisable( GL_TEXTURE_GEN_T );
1524 }
1525
1526
1527 /*
1528 ==================
1529 RB_STD_FogAllLights
1530 ==================
1531 */
1532 void RB_STD_FogAllLights( void ) {
1533         viewLight_t     *vLight;
1534
1535         if ( r_skipFogLights.GetBool() || r_showOverDraw.GetInteger() != 0 
1536                  || backEnd.viewDef->isXraySubview /* dont fog in xray mode*/
1537                  ) {
1538                 return;
1539         }
1540
1541         RB_LogComment( "---------- RB_STD_FogAllLights ----------\n" );
1542
1543         qglDisable( GL_STENCIL_TEST );
1544
1545         for ( vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) {
1546                 backEnd.vLight = vLight;
1547
1548                 if ( !vLight->lightShader->IsFogLight() && !vLight->lightShader->IsBlendLight() ) {
1549                         continue;
1550                 }
1551
1552 #if 0 // _D3XP disabled that
1553                 if ( r_ignore.GetInteger() ) {
1554                         // we use the stencil buffer to guarantee that no pixels will be
1555                         // double fogged, which happens in some areas that are thousands of
1556                         // units from the origin
1557                         backEnd.currentScissor = vLight->scissorRect;
1558                         if ( r_useScissor.GetBool() ) {
1559                                 qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1, 
1560                                         backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1,
1561                                         backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1,
1562                                         backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 );
1563                         }
1564                         qglClear( GL_STENCIL_BUFFER_BIT );
1565
1566                         qglEnable( GL_STENCIL_TEST );
1567
1568                         // only pass on the cleared stencil values
1569                         qglStencilFunc( GL_EQUAL, 128, 255 );
1570
1571                         // when we pass the stencil test and depth test and are going to draw,
1572                         // increment the stencil buffer so we don't ever draw on that pixel again
1573                         qglStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
1574                 }
1575 #endif
1576
1577                 if ( vLight->lightShader->IsFogLight() ) {
1578                         RB_FogPass( vLight->globalInteractions, vLight->localInteractions );
1579                 } else if ( vLight->lightShader->IsBlendLight() ) {
1580                         RB_BlendLight( vLight->globalInteractions, vLight->localInteractions );
1581                 }
1582                 qglDisable( GL_STENCIL_TEST );
1583         }
1584
1585         qglEnable( GL_STENCIL_TEST );
1586 }
1587
1588 //=========================================================================================
1589
1590 /*
1591 ==================
1592 RB_STD_LightScale
1593
1594 Perform extra blending passes to multiply the entire buffer by
1595 a floating point value
1596 ==================
1597 */
1598 void RB_STD_LightScale( void ) {
1599         float   v, f;
1600
1601         if ( backEnd.overBright == 1.0f ) {
1602                 return;
1603         }
1604
1605         if ( r_skipLightScale.GetBool() ) {
1606                 return;
1607         }
1608
1609         RB_LogComment( "---------- RB_STD_LightScale ----------\n" );
1610
1611         // the scissor may be smaller than the viewport for subviews
1612         if ( r_useScissor.GetBool() ) {
1613                 qglScissor( backEnd.viewDef->viewport.x1 + backEnd.viewDef->scissor.x1, 
1614                         backEnd.viewDef->viewport.y1 + backEnd.viewDef->scissor.y1, 
1615                         backEnd.viewDef->scissor.x2 - backEnd.viewDef->scissor.x1 + 1,
1616                         backEnd.viewDef->scissor.y2 - backEnd.viewDef->scissor.y1 + 1 );
1617                 backEnd.currentScissor = backEnd.viewDef->scissor;
1618         }
1619
1620         // full screen blends
1621         qglLoadIdentity();
1622         qglMatrixMode( GL_PROJECTION );
1623         qglPushMatrix();
1624         qglLoadIdentity(); 
1625     qglOrtho( 0, 1, 0, 1, -1, 1 );
1626
1627         GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_SRC_COLOR );
1628         GL_Cull( CT_TWO_SIDED );        // so mirror views also get it
1629         globalImages->BindNull();
1630         qglDisable( GL_DEPTH_TEST );
1631         qglDisable( GL_STENCIL_TEST );
1632
1633         v = 1;
1634         while ( idMath::Fabs( v - backEnd.overBright ) > 0.01 ) {       // a little extra slop
1635                 f = backEnd.overBright / v;
1636                 f /= 2;
1637                 if ( f > 1 ) {
1638                         f = 1;
1639                 }
1640                 qglColor3f( f, f, f );
1641                 v = v * f * 2;
1642
1643                 qglBegin( GL_QUADS );
1644                 qglVertex2f( 0,0 );     
1645                 qglVertex2f( 0,1 );
1646                 qglVertex2f( 1,1 );     
1647                 qglVertex2f( 1,0 );     
1648                 qglEnd();
1649         }
1650
1651
1652         qglPopMatrix();
1653         qglEnable( GL_DEPTH_TEST );
1654         qglMatrixMode( GL_MODELVIEW );
1655         GL_Cull( CT_FRONT_SIDED );
1656 }
1657
1658 //=========================================================================================
1659
1660 /*
1661 =============
1662 RB_STD_DrawView
1663
1664 =============
1665 */
1666 void    RB_STD_DrawView( void ) {
1667         drawSurf_t       **drawSurfs;
1668         int                     numDrawSurfs;
1669
1670         RB_LogComment( "---------- RB_STD_DrawView ----------\n" );
1671
1672         backEnd.depthFunc = GLS_DEPTHFUNC_EQUAL;
1673
1674         drawSurfs = (drawSurf_t **)&backEnd.viewDef->drawSurfs[0];
1675         numDrawSurfs = backEnd.viewDef->numDrawSurfs;
1676
1677         // clear the z buffer, set the projection matrix, etc
1678         RB_BeginDrawingView();
1679
1680         // decide how much overbrighting we are going to do
1681         RB_DetermineLightScale();
1682
1683         // fill the depth buffer and clear color buffer to black except on
1684         // subviews
1685         RB_STD_FillDepthBuffer( drawSurfs, numDrawSurfs );
1686
1687         // main light renderer
1688         switch( tr.backEndRenderer ) {
1689         case BE_ARB:
1690                 RB_ARB_DrawInteractions();
1691                 break;
1692         case BE_ARB2:
1693                 RB_ARB2_DrawInteractions();
1694                 break;
1695         case BE_NV20:
1696                 RB_NV20_DrawInteractions();
1697                 break;
1698         case BE_NV10:
1699                 RB_NV10_DrawInteractions();
1700                 break;
1701         case BE_R200:
1702                 RB_R200_DrawInteractions();
1703                 break;
1704         }
1705
1706         // disable stencil shadow test
1707         qglStencilFunc( GL_ALWAYS, 128, 255 );
1708
1709         // uplight the entire screen to crutch up not having better blending range
1710         RB_STD_LightScale();
1711
1712         // now draw any non-light dependent shading passes
1713         int     processed = RB_STD_DrawShaderPasses( drawSurfs, numDrawSurfs );
1714
1715         // fob and blend lights
1716         RB_STD_FogAllLights();
1717
1718         // now draw any post-processing effects using _currentRender
1719         if ( processed < numDrawSurfs ) {
1720                 RB_STD_DrawShaderPasses( drawSurfs+processed, numDrawSurfs-processed );
1721         }
1722
1723         RB_RenderDebugTools( drawSurfs, numDrawSurfs );
1724
1725 }