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