1 /*
2 ===========================================================================
3 Copyright (C) 1999-2005 Id Software, Inc.
4 
5 This file is part of Quake III Arena source code.
6 
7 Quake III Arena source code is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the License,
10 or (at your option) any later version.
11 
12 Quake III Arena source code is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Quake III Arena source code; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 ===========================================================================
21 */
22 // tr_shade.c
23 
24 #include "tr_local.h"
25 #if idppc_altivec && !defined(MACOS_X)
26 #include <altivec.h>
27 #endif
28 
29 /*
30 
31   THIS ENTIRE FILE IS BACK END
32 
33   This file deals with applying shaders to surface data in the tess struct.
34 */
35 
36 /*
37  * R_GLSL_GetProgramByHandle
38  * Return adress of program for supplied handle
39  */
R_GLSL_GetProgramByHandle(qhandle_t index)40 static glslProgram_t *R_GLSL_GetProgramByHandle(qhandle_t index) {
41 	glslProgram_t *program;
42 
43 	/* out of range gets the default program */
44 	if (index < 1 || index >= tr.numPrograms)
45 		return tr.programs[0];
46 
47 	program = tr.programs[index];
48 
49 	return program;
50 }
51 
52 /*
53  * R_GLSL_UseProgram
54  * Use specified program or switch back to standard rendering pipeline
55  */
R_GLSL_UseProgram(qhandle_t index)56 void R_GLSL_UseProgram(qhandle_t index) {
57 	glslProgram_t	*program;
58 
59 	if (!vertexShaders)
60 			return;
61 
62 	/* are we allready running the program? */
63 	if (index == glState.currentProgram)
64 		return;
65 
66 	/* disable the glsl rendering path */
67 	if (!index) {
68 		qglUseProgramObjectARB(0);
69 		glState.currentProgram = 0;
70 		return;
71 	}
72 
73 	/* bad program specified */
74 	program = R_GLSL_GetProgramByHandle(index);
75 	if (!program->valid)
76 		program = R_GLSL_GetProgramByHandle(tr.defaultProgram);
77 
78 	qglUseProgramObjectARB(program->program);
79 	glState.currentProgram = program->index;
80 }
81 
82 /*
83 ================
84 R_ArrayElementDiscrete
85 
86 This is just for OpenGL conformance testing, it should never be the fastest
87 ================
88 */
R_ArrayElementDiscrete(GLint index)89 static void APIENTRY R_ArrayElementDiscrete( GLint index ) {
90 	qglColor4ubv( tess.svars.colors[ index ] );
91 	if ( glState.currenttmu ) {
92 		qglMultiTexCoord2fARB( 0, tess.svars.texcoords[ 0 ][ index ][0], tess.svars.texcoords[ 0 ][ index ][1] );
93 		qglMultiTexCoord2fARB( 1, tess.svars.texcoords[ 1 ][ index ][0], tess.svars.texcoords[ 1 ][ index ][1] );
94 	} else {
95 		qglTexCoord2fv( tess.svars.texcoords[ 0 ][ index ] );
96 	}
97 	qglVertex3fv( tess.xyz[ index ] );
98 }
99 
100 /*
101 ===================
102 R_DrawStripElements
103 
104 ===================
105 */
106 static int		c_vertexes;		// for seeing how long our average strips are
107 static int		c_begins;
R_DrawStripElements(int numIndexes,const glIndex_t * indexes,void (APIENTRY * element)(GLint))108 static void R_DrawStripElements( int numIndexes, const glIndex_t *indexes, void ( APIENTRY *element )(GLint) ) {
109 	int i;
110 	int last[3] = { -1, -1, -1 };
111 	qboolean even;
112 
113 	c_begins++;
114 
115 	if ( numIndexes <= 0 ) {
116 		return;
117 	}
118 
119 	qglBegin( GL_TRIANGLE_STRIP );
120 
121 	// prime the strip
122 	element( indexes[0] );
123 	element( indexes[1] );
124 	element( indexes[2] );
125 	c_vertexes += 3;
126 
127 	last[0] = indexes[0];
128 	last[1] = indexes[1];
129 	last[2] = indexes[2];
130 
131 	even = qfalse;
132 
133 	for ( i = 3; i < numIndexes; i += 3 )
134 	{
135 		// odd numbered triangle in potential strip
136 		if ( !even )
137 		{
138 			// check previous triangle to see if we're continuing a strip
139 			if ( ( indexes[i+0] == last[2] ) && ( indexes[i+1] == last[1] ) )
140 			{
141 				element( indexes[i+2] );
142 				c_vertexes++;
143 				assert( indexes[i+2] < tess.numVertexes );
144 				even = qtrue;
145 			}
146 			// otherwise we're done with this strip so finish it and start
147 			// a new one
148 			else
149 			{
150 				qglEnd();
151 
152 				qglBegin( GL_TRIANGLE_STRIP );
153 				c_begins++;
154 
155 				element( indexes[i+0] );
156 				element( indexes[i+1] );
157 				element( indexes[i+2] );
158 
159 				c_vertexes += 3;
160 
161 				even = qfalse;
162 			}
163 		}
164 		else
165 		{
166 			// check previous triangle to see if we're continuing a strip
167 			if ( ( last[2] == indexes[i+1] ) && ( last[0] == indexes[i+0] ) )
168 			{
169 				element( indexes[i+2] );
170 				c_vertexes++;
171 
172 				even = qfalse;
173 			}
174 			// otherwise we're done with this strip so finish it and start
175 			// a new one
176 			else
177 			{
178 				qglEnd();
179 
180 				qglBegin( GL_TRIANGLE_STRIP );
181 				c_begins++;
182 
183 				element( indexes[i+0] );
184 				element( indexes[i+1] );
185 				element( indexes[i+2] );
186 				c_vertexes += 3;
187 
188 				even = qfalse;
189 			}
190 		}
191 
192 		// cache the last three vertices
193 		last[0] = indexes[i+0];
194 		last[1] = indexes[i+1];
195 		last[2] = indexes[i+2];
196 	}
197 
198 	qglEnd();
199 }
200 
201 
202 
203 /*
204 ==================
205 R_DrawElements
206 
207 Optionally performs our own glDrawElements that looks for strip conditions
208 instead of using the single glDrawElements call that may be inefficient
209 without compiled vertex arrays.
210 ==================
211 */
R_DrawElements(int numIndexes,const glIndex_t * indexes)212 static void R_DrawElements( int numIndexes, const glIndex_t *indexes ) {
213 	int		primitives;
214 
215 	primitives = r_primitives->integer;
216 
217 	// default is to use triangles if compiled vertex arrays are present
218 	if ( primitives == 0 ) {
219 		if ( qglLockArraysEXT ) {
220 			primitives = 2;
221 		} else {
222 			primitives = 1;
223 		}
224 	}
225 
226 
227 	if ( primitives == 2 ) {
228 		qglDrawElements( GL_TRIANGLES,
229 						numIndexes,
230 						GL_INDEX_TYPE,
231 						indexes );
232 		return;
233 	}
234 
235 	if ( primitives == 1 ) {
236 		R_DrawStripElements( numIndexes,  indexes, qglArrayElement );
237 		return;
238 	}
239 
240 	if ( primitives == 3 ) {
241 		R_DrawStripElements( numIndexes,  indexes, R_ArrayElementDiscrete );
242 		return;
243 	}
244 
245 	// anything else will cause no drawing
246 }
247 
248 
249 /*
250 =============================================================
251 
252 SURFACE SHADERS
253 
254 =============================================================
255 */
256 
257 shaderCommands_t	tess;
258 static qboolean	setArraysOnce;
259 
260 /*
261 =================
262 R_BindAnimatedImage
263 
264 =================
265 */
R_BindAnimatedImage(textureBundle_t * bundle)266 static void R_BindAnimatedImage( textureBundle_t *bundle ) {
267 	int		index;
268 
269 	if ( bundle->isVideoMap ) {
270 		ri.CIN_RunCinematic(bundle->videoMapHandle);
271 		ri.CIN_UploadCinematic(bundle->videoMapHandle);
272 		return;
273 	}
274 
275 	if ( bundle->numImageAnimations <= 1 ) {
276 		GL_Bind( bundle->image[0] );
277 		return;
278 	}
279 
280 	// it is necessary to do this messy calc to make sure animations line up
281 	// exactly with waveforms of the same frequency
282 	index = myftol( tess.shaderTime * bundle->imageAnimationSpeed * FUNCTABLE_SIZE );
283 	index >>= FUNCTABLE_SIZE2;
284 
285 	if ( index < 0 ) {
286 		index = 0;	// may happen with shader time offsets
287 	}
288 	index %= bundle->numImageAnimations;
289 
290 	GL_Bind( bundle->image[ index ] );
291 }
292 
293 /*
294 ================
295 DrawTris
296 
297 Draws triangle outlines for debugging
298 ================
299 */
DrawTris(shaderCommands_t * input)300 static void DrawTris (shaderCommands_t *input) {
301 	GL_Bind( tr.whiteImage );
302 	qglColor3f (1,1,1);
303 
304 	GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE );
305 	qglDepthRange( 0, 0 );
306 
307 	qglDisableClientState (GL_COLOR_ARRAY);
308 	qglDisableClientState (GL_TEXTURE_COORD_ARRAY);
309 
310 	qglVertexPointer (3, GL_FLOAT, 16, input->xyz);	// padded for SIMD
311 
312 	if (qglLockArraysEXT) {
313 		qglLockArraysEXT(0, input->numVertexes);
314 		GLimp_LogComment( "glLockArraysEXT\n" );
315 	}
316 
317 	R_DrawElements( input->numIndexes, input->indexes );
318 
319 	if (qglUnlockArraysEXT) {
320 		qglUnlockArraysEXT();
321 		GLimp_LogComment( "glUnlockArraysEXT\n" );
322 	}
323 	qglDepthRange( 0, 1 );
324 }
325 
326 
327 /*
328 ================
329 DrawNormals
330 
331 Draws vertex normals for debugging
332 ================
333 */
DrawNormals(shaderCommands_t * input)334 static void DrawNormals (shaderCommands_t *input) {
335 	int		i;
336 	vec3_t	temp;
337 
338 	GL_Bind( tr.whiteImage );
339 	qglColor3f (1,1,1);
340 	qglDepthRange( 0, 0 );	// never occluded
341 	GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE );
342 
343 	qglBegin (GL_LINES);
344 	for (i = 0 ; i < input->numVertexes ; i++) {
345 		qglVertex3fv (input->xyz[i]);
346 		VectorMA (input->xyz[i], 2, input->normal[i], temp);
347 		qglVertex3fv (temp);
348 	}
349 	qglEnd ();
350 
351 	qglDepthRange( 0, 1 );
352 }
353 
354 /*
355 ==============
356 RB_BeginSurface
357 
358 We must set some things up before beginning any tesselation,
359 because a surface may be forced to perform a RB_End due
360 to overflow.
361 ==============
362 */
RB_BeginSurface(shader_t * shader,int fogNum)363 void RB_BeginSurface( shader_t *shader, int fogNum ) {
364 
365 	shader_t *state = (shader->remappedShader) ? shader->remappedShader : shader;
366 
367 	tess.numIndexes = 0;
368 	tess.numVertexes = 0;
369 	tess.shader = state;
370 	tess.fogNum = fogNum;
371 	tess.dlightBits = 0;		// will be OR'd in by surface functions
372 	tess.xstages = state->stages;
373 	tess.numPasses = state->numUnfoggedPasses;
374 	tess.currentStageIteratorFunc = state->optimalStageIteratorFunc;
375 
376 	tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset;
377 	if (tess.shader->clampTime && tess.shaderTime >= tess.shader->clampTime) {
378 		tess.shaderTime = tess.shader->clampTime;
379 	}
380 
381 
382 }
383 
384 /*
385 ===================
386 DrawMultitextured
387 
388 output = t0 * t1 or t0 + t1
389 
390 t0 = most upstream according to spec
391 t1 = most downstream according to spec
392 ===================
393 */
DrawMultitextured(shaderCommands_t * input,int stage)394 static void DrawMultitextured( shaderCommands_t *input, int stage ) {
395 	shaderStage_t	*pStage;
396 
397 	pStage = tess.xstages[stage];
398 
399 	GL_State( pStage->stateBits );
400 
401 	// this is an ugly hack to work around a GeForce driver
402 	// bug with multitexture and clip planes
403 	if ( backEnd.viewParms.isPortal ) {
404 		qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
405 	}
406 
407 	//
408 	// base
409 	//
410 	GL_SelectTexture( 0 );
411 	qglTexCoordPointer( 2, GL_FLOAT, 0, input->svars.texcoords[0] );
412 	R_BindAnimatedImage( &pStage->bundle[0] );
413 
414 	//
415 	// lightmap/secondary pass
416 	//
417 	GL_SelectTexture( 1 );
418 	qglEnable( GL_TEXTURE_2D );
419 	qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
420 
421 	if ( r_lightmap->integer ) {
422 		GL_TexEnv( GL_REPLACE );
423 	} else {
424 		GL_TexEnv( tess.shader->multitextureEnv );
425 	}
426 
427 	qglTexCoordPointer( 2, GL_FLOAT, 0, input->svars.texcoords[1] );
428 
429 	R_BindAnimatedImage( &pStage->bundle[1] );
430 
431 	R_DrawElements( input->numIndexes, input->indexes );
432 
433 	//
434 	// disable texturing on TEXTURE1, then select TEXTURE0
435 	//
436 	//qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
437 	qglDisable( GL_TEXTURE_2D );
438 
439 	GL_SelectTexture( 0 );
440 }
441 
442 
443 
444 /*
445 ===================
446 ProjectDlightTexture
447 
448 Perform dynamic lighting with another rendering pass
449 ===================
450 */
451 #if idppc_altivec
ProjectDlightTexture_altivec(void)452 static void ProjectDlightTexture_altivec( void ) {
453 	int		i, l;
454 	vec_t	origin0, origin1, origin2;
455 	float   texCoords0, texCoords1;
456 	vector float floatColorVec0, floatColorVec1;
457 	vector float modulateVec, colorVec, zero;
458 	vector short colorShort;
459 	vector signed int colorInt;
460 	vector unsigned char floatColorVecPerm, modulatePerm, colorChar;
461 	vector unsigned char vSel = VECCONST_UINT8(0x00, 0x00, 0x00, 0xff,
462                                                0x00, 0x00, 0x00, 0xff,
463                                                0x00, 0x00, 0x00, 0xff,
464                                                0x00, 0x00, 0x00, 0xff);
465 	float	*texCoords;
466 	byte	*colors;
467 	byte	clipBits[SHADER_MAX_VERTEXES];
468 	float	texCoordsArray[SHADER_MAX_VERTEXES][2];
469 	byte	colorArray[SHADER_MAX_VERTEXES][4];
470 	unsigned	hitIndexes[SHADER_MAX_INDEXES];
471 	int		numIndexes;
472 	float	scale;
473 	float	radius;
474 	vec3_t	floatColor;
475 	float	modulate = 0.0f;
476 
477 	if ( !backEnd.refdef.num_dlights ) {
478 		return;
479 	}
480 
481 	// There has to be a better way to do this so that floatColor
482 	// and/or modulate are already 16-byte aligned.
483 	floatColorVecPerm = vec_lvsl(0,(float *)floatColor);
484 	modulatePerm = vec_lvsl(0,(float *)&modulate);
485 	modulatePerm = (vector unsigned char)vec_splat((vector unsigned int)modulatePerm,0);
486 	zero = (vector float)vec_splat_s8(0);
487 
488 	for ( l = 0 ; l < backEnd.refdef.num_dlights ; l++ ) {
489 		dlight_t	*dl;
490 
491 		if ( !( tess.dlightBits & ( 1 << l ) ) ) {
492 			continue;	// this surface definately doesn't have any of this light
493 		}
494 		texCoords = texCoordsArray[0];
495 		colors = colorArray[0];
496 
497 		dl = &backEnd.refdef.dlights[l];
498 		origin0 = dl->transformed[0];
499 		origin1 = dl->transformed[1];
500 		origin2 = dl->transformed[2];
501 		radius = dl->radius;
502 		scale = 1.0f / radius;
503 
504 		if(r_greyscale->integer)
505 		{
506 			float luminance;
507 
508 			luminance = LUMA(dl->color[0], dl->color[1], dl->color[2]) * 255.0f;
509 			floatColor[0] = floatColor[1] = floatColor[2] = luminance;
510 		}
511 		else if(r_monolightmaps->integer)
512 		{
513 			float luminance;
514 
515 			luminance = LUMA(dl->color[0], dl->color[1], dl->color[2]) * 255.0f;
516 			floatColor[0] = floatColor[1] = floatColor[2] = luminance;
517 		}
518 
519 		else if(r_greyscale->value)
520 		{
521 			float luminance;
522 
523 			luminance = LUMA(dl->color[0], dl->color[1], dl->color[2]) * 255.0f;
524 			floatColor[0] = LERP(dl->color[0] * 255.0f, luminance, r_greyscale->value);
525 			floatColor[1] = LERP(dl->color[1] * 255.0f, luminance, r_greyscale->value);
526 			floatColor[2] = LERP(dl->color[2] * 255.0f, luminance, r_greyscale->value);
527 		}
528 		else
529 		{
530 			floatColor[0] = dl->color[0] * 255.0f;
531 			floatColor[1] = dl->color[1] * 255.0f;
532 			floatColor[2] = dl->color[2] * 255.0f;
533 		}
534 		floatColorVec0 = vec_ld(0, floatColor);
535 		floatColorVec1 = vec_ld(11, floatColor);
536 		floatColorVec0 = vec_perm(floatColorVec0,floatColorVec0,floatColorVecPerm);
537 		for ( i = 0 ; i < tess.numVertexes ; i++, texCoords += 2, colors += 4 ) {
538 			int		clip = 0;
539 			vec_t dist0, dist1, dist2;
540 
541 			dist0 = origin0 - tess.xyz[i][0];
542 			dist1 = origin1 - tess.xyz[i][1];
543 			dist2 = origin2 - tess.xyz[i][2];
544 
545 			backEnd.pc.c_dlightVertexes++;
546 
547 			texCoords0 = 0.5f + dist0 * scale;
548 			texCoords1 = 0.5f + dist1 * scale;
549 
550 			if( !r_dlightBacks->integer &&
551 					// dist . tess.normal[i]
552 					( dist0 * tess.normal[i][0] +
553 					dist1 * tess.normal[i][1] +
554 					dist2 * tess.normal[i][2] ) < 0.0f ) {
555 				clip = 63;
556 			} else {
557 				if ( texCoords0 < 0.0f ) {
558 					clip |= 1;
559 				} else if ( texCoords0 > 1.0f ) {
560 					clip |= 2;
561 				}
562 				if ( texCoords1 < 0.0f ) {
563 					clip |= 4;
564 				} else if ( texCoords1 > 1.0f ) {
565 					clip |= 8;
566 				}
567 				texCoords[0] = texCoords0;
568 				texCoords[1] = texCoords1;
569 
570 				// modulate the strength based on the height and color
571 				if ( dist2 > radius ) {
572 					clip |= 16;
573 					modulate = 0.0f;
574 				} else if ( dist2 < -radius ) {
575 					clip |= 32;
576 					modulate = 0.0f;
577 				} else {
578 					dist2 = Q_fabs(dist2);
579 					if ( dist2 < radius * 0.5f ) {
580 						modulate = 1.0f;
581 					} else {
582 						modulate = 2.0f * (radius - dist2) * scale;
583 					}
584 				}
585 			}
586 			clipBits[i] = clip;
587 
588 			modulateVec = vec_ld(0,(float *)&modulate);
589 			modulateVec = vec_perm(modulateVec,modulateVec,modulatePerm);
590 			colorVec = vec_madd(floatColorVec0,modulateVec,zero);
591 			colorInt = vec_cts(colorVec,0);	// RGBx
592 			colorShort = vec_pack(colorInt,colorInt);		// RGBxRGBx
593 			colorChar = vec_packsu(colorShort,colorShort);	// RGBxRGBxRGBxRGBx
594 			colorChar = vec_sel(colorChar,vSel,vSel);		// RGBARGBARGBARGBA replace alpha with 255
595 			vec_ste((vector unsigned int)colorChar,0,(unsigned int *)colors);	// store color
596 		}
597 
598 		// build a list of triangles that need light
599 		numIndexes = 0;
600 		for ( i = 0 ; i < tess.numIndexes ; i += 3 ) {
601 			int		a, b, c;
602 
603 			a = tess.indexes[i];
604 			b = tess.indexes[i+1];
605 			c = tess.indexes[i+2];
606 			if ( clipBits[a] & clipBits[b] & clipBits[c] ) {
607 				continue;	// not lighted
608 			}
609 			hitIndexes[numIndexes] = a;
610 			hitIndexes[numIndexes+1] = b;
611 			hitIndexes[numIndexes+2] = c;
612 			numIndexes += 3;
613 		}
614 
615 		if ( !numIndexes ) {
616 			continue;
617 		}
618 
619 		qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
620 		qglTexCoordPointer( 2, GL_FLOAT, 0, texCoordsArray[0] );
621 
622 		qglEnableClientState( GL_COLOR_ARRAY );
623 		qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, colorArray );
624 
625 		GL_Bind( tr.dlightImage );
626 		// include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light
627 		// where they aren't rendered
628 		if ( dl->additive ) {
629 			GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL );
630 		}
631 		else {
632 			GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL );
633 		}
634 		R_DrawElements( numIndexes, hitIndexes );
635 		backEnd.pc.c_totalIndexes += numIndexes;
636 		backEnd.pc.c_dlightIndexes += numIndexes;
637 	}
638 }
639 #endif
640 
641 
ProjectDlightTexture_scalar(void)642 static void ProjectDlightTexture_scalar( void ) {
643 	int		i, l;
644 	vec3_t	origin;
645 	float	*texCoords;
646 	byte	*colors;
647 	byte	clipBits[SHADER_MAX_VERTEXES];
648 	float	texCoordsArray[SHADER_MAX_VERTEXES][2];
649 	byte	colorArray[SHADER_MAX_VERTEXES][4];
650 	unsigned	hitIndexes[SHADER_MAX_INDEXES];
651 	int		numIndexes;
652 	float	scale;
653 	float	radius;
654 	vec3_t	floatColor;
655 	float	modulate = 0.0f;
656 
657 	if ( !backEnd.refdef.num_dlights ) {
658 		return;
659 	}
660 
661 	for ( l = 0 ; l < backEnd.refdef.num_dlights ; l++ ) {
662 		dlight_t	*dl;
663 
664 		if ( !( tess.dlightBits & ( 1 << l ) ) ) {
665 			continue;	// this surface definately doesn't have any of this light
666 		}
667 		texCoords = texCoordsArray[0];
668 		colors = colorArray[0];
669 
670 		dl = &backEnd.refdef.dlights[l];
671 		VectorCopy( dl->transformed, origin );
672 		radius = dl->radius;
673 		scale = 1.0f / radius;
674 
675 		if(r_greyscale->integer)
676 		{
677 			float luminance;
678 
679 			luminance = LUMA(dl->color[0], dl->color[1], dl->color[2]) * 255.0f;
680 			floatColor[0] = floatColor[1] = floatColor[2] = luminance;
681 		}
682 		else if(r_monolightmaps->integer)
683 		{
684 			float luminance;
685 
686 			luminance = LUMA(dl->color[0], dl->color[1], dl->color[2]) * 255.0f;
687 			floatColor[0] = floatColor[1] = floatColor[2] = luminance;
688 		}
689 		else if(r_greyscale->value)
690 		{
691 			float luminance;
692 
693 			luminance = LUMA(dl->color[0], dl->color[1], dl->color[2]) * 255.0f;
694 			floatColor[0] = LERP(dl->color[0] * 255.0f, luminance, r_greyscale->value);
695 			floatColor[1] = LERP(dl->color[1] * 255.0f, luminance, r_greyscale->value);
696 			floatColor[2] = LERP(dl->color[2] * 255.0f, luminance, r_greyscale->value);
697 		}
698 		else
699 		{
700 			floatColor[0] = dl->color[0] * 255.0f;
701 			floatColor[1] = dl->color[1] * 255.0f;
702 			floatColor[2] = dl->color[2] * 255.0f;
703 		}
704 
705 		for ( i = 0 ; i < tess.numVertexes ; i++, texCoords += 2, colors += 4 ) {
706 			int		clip = 0;
707 			vec3_t	dist;
708 
709 			VectorSubtract( origin, tess.xyz[i], dist );
710 
711 			backEnd.pc.c_dlightVertexes++;
712 
713 			texCoords[0] = 0.5f + dist[0] * scale;
714 			texCoords[1] = 0.5f + dist[1] * scale;
715 
716 			if( !r_dlightBacks->integer &&
717 					// dist . tess.normal[i]
718 					( dist[0] * tess.normal[i][0] +
719 					dist[1] * tess.normal[i][1] +
720 					dist[2] * tess.normal[i][2] ) < 0.0f ) {
721 				clip = 63;
722 			} else {
723 				if ( texCoords[0] < 0.0f ) {
724 					clip |= 1;
725 				} else if ( texCoords[0] > 1.0f ) {
726 					clip |= 2;
727 				}
728 				if ( texCoords[1] < 0.0f ) {
729 					clip |= 4;
730 				} else if ( texCoords[1] > 1.0f ) {
731 					clip |= 8;
732 				}
733 				texCoords[0] = texCoords[0];
734 				texCoords[1] = texCoords[1];
735 
736 				// modulate the strength based on the height and color
737 				if ( dist[2] > radius ) {
738 					clip |= 16;
739 					modulate = 0.0f;
740 				} else if ( dist[2] < -radius ) {
741 					clip |= 32;
742 					modulate = 0.0f;
743 				} else {
744 					dist[2] = Q_fabs(dist[2]);
745 					if ( dist[2] < radius * 0.5f ) {
746 						modulate = 1.0f;
747 					} else {
748 						modulate = 2.0f * (radius - dist[2]) * scale;
749 					}
750 				}
751 			}
752 			clipBits[i] = clip;
753 			colors[0] = myftol(floatColor[0] * modulate);
754 			colors[1] = myftol(floatColor[1] * modulate);
755 			colors[2] = myftol(floatColor[2] * modulate);
756 			colors[3] = 255;
757 		}
758 
759 		// build a list of triangles that need light
760 		numIndexes = 0;
761 		for ( i = 0 ; i < tess.numIndexes ; i += 3 ) {
762 			int		a, b, c;
763 
764 			a = tess.indexes[i];
765 			b = tess.indexes[i+1];
766 			c = tess.indexes[i+2];
767 			if ( clipBits[a] & clipBits[b] & clipBits[c] ) {
768 				continue;	// not lighted
769 			}
770 			hitIndexes[numIndexes] = a;
771 			hitIndexes[numIndexes+1] = b;
772 			hitIndexes[numIndexes+2] = c;
773 			numIndexes += 3;
774 		}
775 
776 		if ( !numIndexes ) {
777 			continue;
778 		}
779 
780 		qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
781 		qglTexCoordPointer( 2, GL_FLOAT, 0, texCoordsArray[0] );
782 
783 		qglEnableClientState( GL_COLOR_ARRAY );
784 		qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, colorArray );
785 
786 		GL_Bind( tr.dlightImage );
787 		// include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light
788 		// where they aren't rendered
789 		if ( dl->additive ) {
790 			GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL );
791 		}
792 		else {
793 			GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL );
794 		}
795 		R_DrawElements( numIndexes, hitIndexes );
796 		backEnd.pc.c_totalIndexes += numIndexes;
797 		backEnd.pc.c_dlightIndexes += numIndexes;
798 	}
799 }
800 
ProjectDlightTexture(void)801 static void ProjectDlightTexture( void ) {
802 #if idppc_altivec
803 	if (com_altivec->integer) {
804 		// must be in a seperate function or G3 systems will crash.
805 		ProjectDlightTexture_altivec();
806 		return;
807 	}
808 #endif
809 	ProjectDlightTexture_scalar();
810 }
811 
812 
813 /*
814 ===================
815 RB_FogPass
816 
817 Blends a fog texture on top of everything else
818 ===================
819 */
RB_FogPass(void)820 static void RB_FogPass( void ) {
821 	fog_t		*fog;
822 	int			i;
823 
824 	qglEnableClientState( GL_COLOR_ARRAY );
825 	qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.svars.colors );
826 
827 	qglEnableClientState( GL_TEXTURE_COORD_ARRAY);
828 	qglTexCoordPointer( 2, GL_FLOAT, 0, tess.svars.texcoords[0] );
829 
830 	fog = tr.world->fogs + tess.fogNum;
831 
832 	for ( i = 0; i < tess.numVertexes; i++ ) {
833 		* ( int * )&tess.svars.colors[i] = fog->colorInt;
834 	}
835 
836 	RB_CalcFogTexCoords( ( float * ) tess.svars.texcoords[0] );
837 
838 	GL_Bind( tr.fogImage );
839 
840 	if ( tess.shader->fogPass == FP_EQUAL ) {
841 		GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_EQUAL );
842 	} else {
843 		GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA );
844 	}
845 
846 	R_DrawElements( tess.numIndexes, tess.indexes );
847 }
848 
849 /*
850 ===============
851 ComputeColors
852 ===============
853 */
ComputeColors(shaderStage_t * pStage)854 static void ComputeColors( shaderStage_t *pStage )
855 {
856 	int		i;
857 
858 	//
859 	// rgbGen
860 	//
861 	switch ( pStage->rgbGen )
862 	{
863 		case CGEN_IDENTITY:
864 			Com_Memset( tess.svars.colors, 0xff, tess.numVertexes * 4 );
865 			break;
866 		default:
867 		case CGEN_IDENTITY_LIGHTING:
868 			Com_Memset( tess.svars.colors, tr.identityLightByte, tess.numVertexes * 4 );
869 			break;
870 		case CGEN_LIGHTING_DIFFUSE:
871 			RB_CalcDiffuseColor( ( unsigned char * ) tess.svars.colors );
872 	if(r_monolightmaps->integer)
873 	{
874 		int scale;
875 		for(i = 0; i < tess.numVertexes; i++)
876 		{
877 			scale = LUMA(tess.svars.colors[i][0], tess.svars.colors[i][1], tess.svars.colors[i][2]);
878  			tess.svars.colors[i][0] = tess.svars.colors[i][1] = tess.svars.colors[i][2] = scale;
879 		}
880 	}
881 			break;
882 		case CGEN_LIGHTING_UNIFORM:
883 			RB_CalcUniformColor( ( unsigned char * ) tess.svars.colors );
884 			break;
885 		case CGEN_LIGHTING_DYNAMIC:
886 			RB_CalcDynamicColor( ( unsigned char * ) tess.svars.colors );
887 			break;
888 		case CGEN_EXACT_VERTEX:
889 			Com_Memcpy( tess.svars.colors, tess.vertexColors, tess.numVertexes * sizeof( tess.vertexColors[0] ) );
890 			break;
891 		case CGEN_CONST:
892 			for ( i = 0; i < tess.numVertexes; i++ ) {
893 				*(int *)tess.svars.colors[i] = *(int *)pStage->constantColor;
894 			}
895 			break;
896 		case CGEN_VERTEX:
897 			if ( tr.identityLight == 1 )
898 			{
899 				Com_Memcpy( tess.svars.colors, tess.vertexColors, tess.numVertexes * sizeof( tess.vertexColors[0] ) );
900 			}
901 			else
902 			{
903 				for ( i = 0; i < tess.numVertexes; i++ )
904 				{
905 					tess.svars.colors[i][0] = tess.vertexColors[i][0] * tr.identityLight;
906 					tess.svars.colors[i][1] = tess.vertexColors[i][1] * tr.identityLight;
907 					tess.svars.colors[i][2] = tess.vertexColors[i][2] * tr.identityLight;
908 					tess.svars.colors[i][3] = tess.vertexColors[i][3];
909 				}
910 			}
911 			break;
912 		case CGEN_ONE_MINUS_VERTEX:
913 			if ( tr.identityLight == 1 )
914 			{
915 				for ( i = 0; i < tess.numVertexes; i++ )
916 				{
917 					tess.svars.colors[i][0] = 255 - tess.vertexColors[i][0];
918 					tess.svars.colors[i][1] = 255 - tess.vertexColors[i][1];
919 					tess.svars.colors[i][2] = 255 - tess.vertexColors[i][2];
920 				}
921 			}
922 			else
923 			{
924 				for ( i = 0; i < tess.numVertexes; i++ )
925 				{
926 					tess.svars.colors[i][0] = ( 255 - tess.vertexColors[i][0] ) * tr.identityLight;
927 					tess.svars.colors[i][1] = ( 255 - tess.vertexColors[i][1] ) * tr.identityLight;
928 					tess.svars.colors[i][2] = ( 255 - tess.vertexColors[i][2] ) * tr.identityLight;
929 				}
930 			}
931 			break;
932 		case CGEN_FOG:
933 			{
934 				fog_t		*fog;
935 
936 				fog = tr.world->fogs + tess.fogNum;
937 
938 				for ( i = 0; i < tess.numVertexes; i++ ) {
939 					* ( int * )&tess.svars.colors[i] = fog->colorInt;
940 				}
941 			}
942 			break;
943 		case CGEN_WAVEFORM:
944 			RB_CalcWaveColor( &pStage->rgbWave, ( unsigned char * ) tess.svars.colors );
945 			break;
946 		case CGEN_ENTITY:
947 			RB_CalcColorFromEntity( ( unsigned char * ) tess.svars.colors );
948 			break;
949 		case CGEN_ONE_MINUS_ENTITY:
950 			RB_CalcColorFromOneMinusEntity( ( unsigned char * ) tess.svars.colors );
951 			break;
952 	}
953 
954 	//
955 	// alphaGen
956 	//
957 	switch ( pStage->alphaGen )
958 	{
959 	case AGEN_SKIP:
960 		break;
961 	case AGEN_IDENTITY:
962 		if ( pStage->rgbGen != CGEN_IDENTITY ) {
963 			if ( ( pStage->rgbGen == CGEN_VERTEX && tr.identityLight != 1 ) ||
964 				 pStage->rgbGen != CGEN_VERTEX ) {
965 				for ( i = 0; i < tess.numVertexes; i++ ) {
966 					tess.svars.colors[i][3] = 0xff;
967 				}
968 			}
969 		}
970 		break;
971 	case AGEN_CONST:
972 		if ( pStage->rgbGen != CGEN_CONST ) {
973 			for ( i = 0; i < tess.numVertexes; i++ ) {
974 				tess.svars.colors[i][3] = pStage->constantColor[3];
975 			}
976 		}
977 		break;
978 	case AGEN_WAVEFORM:
979 		RB_CalcWaveAlpha( &pStage->alphaWave, ( unsigned char * ) tess.svars.colors );
980 		break;
981 	case AGEN_LIGHTING_SPECULAR:
982 		if ( r_specMode->integer == 1)
983 			RB_CalcSpecularAlphaNew( ( unsigned char * ) tess.svars.colors );
984 		else
985 			RB_CalcSpecularAlpha( ( unsigned char * ) tess.svars.colors );
986 		break;
987 	case AGEN_ENTITY:
988 		RB_CalcAlphaFromEntity( ( unsigned char * ) tess.svars.colors );
989 		break;
990 	case AGEN_ONE_MINUS_ENTITY:
991 		RB_CalcAlphaFromOneMinusEntity( ( unsigned char * ) tess.svars.colors );
992 		break;
993     case AGEN_VERTEX:
994 		if ( pStage->rgbGen != CGEN_VERTEX ) {
995 			for ( i = 0; i < tess.numVertexes; i++ ) {
996 				tess.svars.colors[i][3] = tess.vertexColors[i][3];
997 			}
998 		}
999         break;
1000     case AGEN_ONE_MINUS_VERTEX:
1001         for ( i = 0; i < tess.numVertexes; i++ )
1002         {
1003 			tess.svars.colors[i][3] = 255 - tess.vertexColors[i][3];
1004         }
1005         break;
1006 	case AGEN_PORTAL:
1007 		{
1008 			unsigned char alpha;
1009 
1010 			for ( i = 0; i < tess.numVertexes; i++ )
1011 			{
1012 				float len;
1013 				vec3_t v;
1014 
1015 				VectorSubtract( tess.xyz[i], backEnd.viewParms.or.origin, v );
1016 				len = VectorLength( v );
1017 
1018 				len /= tess.shader->portalRange;
1019 
1020 				if ( len < 0 )
1021 				{
1022 					alpha = 0;
1023 				}
1024 				else if ( len > 1 )
1025 				{
1026 					alpha = 0xff;
1027 				}
1028 				else
1029 				{
1030 					alpha = len * 0xff;
1031 				}
1032 
1033 				tess.svars.colors[i][3] = alpha;
1034 			}
1035 		}
1036 		break;
1037 	}
1038 
1039 	//
1040 	// fog adjustment for colors to fade out as fog increases
1041 	//
1042 	if ( tess.fogNum )
1043 	{
1044 		switch ( pStage->adjustColorsForFog )
1045 		{
1046 		case ACFF_MODULATE_RGB:
1047 			RB_CalcModulateColorsByFog( ( unsigned char * ) tess.svars.colors );
1048 			break;
1049 		case ACFF_MODULATE_ALPHA:
1050 			RB_CalcModulateAlphasByFog( ( unsigned char * ) tess.svars.colors );
1051 			break;
1052 		case ACFF_MODULATE_RGBA:
1053 			RB_CalcModulateRGBAsByFog( ( unsigned char * ) tess.svars.colors );
1054 			break;
1055 		case ACFF_NONE:
1056 			break;
1057 		}
1058 	}
1059 
1060 	// if in greyscale rendering mode turn all color values into greyscale.
1061 	if(r_greyscale->integer)
1062 	{
1063 		int scale;
1064 		for(i = 0; i < tess.numVertexes; i++)
1065 		{
1066 			scale = LUMA(tess.svars.colors[i][0], tess.svars.colors[i][1], tess.svars.colors[i][2]);
1067  			tess.svars.colors[i][0] = tess.svars.colors[i][1] = tess.svars.colors[i][2] = scale;
1068 		}
1069 	}
1070 	else if(r_greyscale->value)
1071 	{
1072 		float scale;
1073 
1074 		for(i = 0; i < tess.numVertexes; i++)
1075 		{
1076 			scale = LUMA(tess.svars.colors[i][0], tess.svars.colors[i][1], tess.svars.colors[i][2]);
1077 			tess.svars.colors[i][0] = LERP(tess.svars.colors[i][0], scale, r_greyscale->value);
1078 			tess.svars.colors[i][1] = LERP(tess.svars.colors[i][1], scale, r_greyscale->value);
1079 			tess.svars.colors[i][2] = LERP(tess.svars.colors[i][2], scale, r_greyscale->value);
1080 		}
1081 	}
1082 }
1083 
1084 /*
1085 ===============
1086 ComputeTexCoords
1087 ===============
1088 */
ComputeTexCoords(shaderStage_t * pStage)1089 static void ComputeTexCoords( shaderStage_t *pStage ) {
1090 	int		i;
1091 	int		b;
1092 
1093 	for ( b = 0; b < NUM_TEXTURE_BUNDLES; b++ ) {
1094 		int tm;
1095 
1096 		//
1097 		// generate the texture coordinates
1098 		//
1099 		switch ( pStage->bundle[b].tcGen )
1100 		{
1101 		case TCGEN_IDENTITY:
1102 			Com_Memset( tess.svars.texcoords[b], 0, sizeof( float ) * 2 * tess.numVertexes );
1103 			break;
1104 		case TCGEN_TEXTURE:
1105 			for ( i = 0 ; i < tess.numVertexes ; i++ ) {
1106 				tess.svars.texcoords[b][i][0] = tess.texCoords[i][0][0];
1107 				tess.svars.texcoords[b][i][1] = tess.texCoords[i][0][1];
1108 			}
1109 			break;
1110 		case TCGEN_LIGHTMAP:
1111 			for ( i = 0 ; i < tess.numVertexes ; i++ ) {
1112 				tess.svars.texcoords[b][i][0] = tess.texCoords[i][1][0];
1113 				tess.svars.texcoords[b][i][1] = tess.texCoords[i][1][1];
1114 			}
1115 			break;
1116 		case TCGEN_VECTOR:
1117 			for ( i = 0 ; i < tess.numVertexes ; i++ ) {
1118 				tess.svars.texcoords[b][i][0] = DotProduct( tess.xyz[i], pStage->bundle[b].tcGenVectors[0] );
1119 				tess.svars.texcoords[b][i][1] = DotProduct( tess.xyz[i], pStage->bundle[b].tcGenVectors[1] );
1120 			}
1121 			break;
1122 		case TCGEN_FOG:
1123 			RB_CalcFogTexCoords( ( float * ) tess.svars.texcoords[b] );
1124 			break;
1125 		case TCGEN_ENVIRONMENT_MAPPED:
1126 			if ( r_envMode->integer == 1 ) {
1127 				RB_CalcEnvironmentTexCoordsNew( ( float * ) tess.svars.texcoords[b] );
1128 			} // new dancing one
1129 			else if ( r_envMode->integer == 2 ) {
1130 				RB_CalcEnvironmentTexCoordsHW();
1131 			} // odin's
1132 			else {
1133 				RB_CalcEnvironmentTexCoords( ( float * ) tess.svars.texcoords[b] );
1134 			} // old one
1135 			break;
1136 		case TCGEN_ENVIRONMENT_CELSHADE_MAPPED:
1137 			RB_CalcEnvironmentCelShadeTexCoords( ( float * ) tess.svars.texcoords[b] );
1138 			break;
1139 		case TCGEN_BAD:
1140 			return;
1141 		}
1142 
1143 		//
1144 		// alter texture coordinates
1145 		//
1146 		for ( tm = 0; tm < pStage->bundle[b].numTexMods ; tm++ ) {
1147 			switch ( pStage->bundle[b].texMods[tm].type )
1148 			{
1149 			case TMOD_NONE:
1150 				tm = TR_MAX_TEXMODS;		// break out of for loop
1151 				break;
1152 
1153 			case TMOD_TURBULENT:
1154 				RB_CalcTurbulentTexCoords( &pStage->bundle[b].texMods[tm].wave,
1155 						                 ( float * ) tess.svars.texcoords[b] );
1156 				break;
1157 
1158 			case TMOD_ENTITY_TRANSLATE:
1159 				RB_CalcScrollTexCoords( backEnd.currentEntity->e.shaderTexCoord,
1160 									 ( float * ) tess.svars.texcoords[b] );
1161 				break;
1162 
1163 			case TMOD_SCROLL:
1164 				RB_CalcScrollTexCoords( pStage->bundle[b].texMods[tm].scroll,
1165 										 ( float * ) tess.svars.texcoords[b] );
1166 				break;
1167 
1168 			case TMOD_SCALE:
1169 				RB_CalcScaleTexCoords( pStage->bundle[b].texMods[tm].scale,
1170 									 ( float * ) tess.svars.texcoords[b] );
1171 				break;
1172 
1173 			case TMOD_STRETCH:
1174 				RB_CalcStretchTexCoords( &pStage->bundle[b].texMods[tm].wave,
1175 						               ( float * ) tess.svars.texcoords[b] );
1176 				break;
1177 
1178 			case TMOD_TRANSFORM:
1179 				RB_CalcTransformTexCoords( &pStage->bundle[b].texMods[tm],
1180 						                 ( float * ) tess.svars.texcoords[b] );
1181 				break;
1182 
1183 			case TMOD_ROTATE:
1184 				RB_CalcRotateTexCoords( pStage->bundle[b].texMods[tm].rotateSpeed,
1185 										( float * ) tess.svars.texcoords[b] );
1186 				break;
1187 
1188 			default:
1189 				ri.Error( ERR_DROP, "ERROR: unknown texmod '%d' in shader '%s'\n", pStage->bundle[b].texMods[tm].type, tess.shader->name );
1190 				break;
1191 			}
1192 		}
1193 	}
1194 }
1195 
1196 // GLSL Feeder
GLSL_Feeder(shaderStage_t * pStage,shaderCommands_t * input)1197 void GLSL_Feeder(shaderStage_t *pStage, shaderCommands_t *input)
1198 {
1199 
1200 	glslProgram_t	*program;
1201 	if (pStage->program)
1202 		/* use specified program */
1203 		R_GLSL_UseProgram(pStage->program);
1204 	else
1205 		/* use default program */
1206 		R_GLSL_UseProgram(tr.defaultProgram);
1207 
1208 	program = tr.programs[glState.currentProgram];
1209 
1210 	/* alphaGen */
1211 	if (program->u_AlphaGen > -1)
1212 		R_GLSL_SetUniform_AlphaGen(program, pStage->alphaGen);
1213 
1214 	/* ambient light */
1215 	if (program->u_AmbientLight > -1)
1216 		R_GLSL_SetUniform_AmbientLight(program, backEnd.currentEntity->ambientLight);
1217 
1218 	/* dynamic light */
1219 	if (program->u_DynamicLight > -1)
1220 		R_GLSL_SetUniform_DynamicLight(program, backEnd.currentEntity->dynamicLight);
1221 
1222 	/* light distance */
1223 	if (program->u_LightDistance > -1)
1224 		R_GLSL_SetUniform_LightDistance(program, backEnd.currentEntity->lightDistance);
1225 
1226 	/* rgbGen */
1227 	if (program->u_ColorGen > -1)
1228 		R_GLSL_SetUniform_ColorGen(program, pStage->rgbGen);
1229 
1230 	/* constant color */
1231 	if (program->u_ConstantColor > -1)
1232 		R_GLSL_SetUniform_ConstantColor(program, pStage->constantColor);
1233 
1234 	/* directed light */
1235 	if (program->u_DirectedLight > -1)
1236 		R_GLSL_SetUniform_DirectedLight(program, backEnd.currentEntity->directedLight);
1237 
1238 	/* entity color */
1239 	if (program->u_EntityColor > -1)
1240 		R_GLSL_SetUniform_EntityColor(program, backEnd.currentEntity->e.shaderRGBA);
1241 
1242 	/* fog color */
1243 	if (program->u_FogColor > -1 && tess.fogNum)
1244 		R_GLSL_SetUniform_FogColor(program, (tr.world->fogs + tess.fogNum)->colorInt);
1245 
1246 	/* greyscale */
1247 	if (program->u_Greyscale > -1)
1248 		R_GLSL_SetUniform_Greyscale(program, r_greyscale->integer);
1249 
1250 	/* identity light */
1251 	if (program->u_IdentityLight > -1)
1252 		R_GLSL_SetUniform_IdentityLight(program, tr.identityLight);
1253 
1254 	/* light direction */
1255 	if (program->u_LightDirection > -1)
1256 		R_GLSL_SetUniform_LightDirection(program, backEnd.currentEntity->lightDir);
1257 
1258 	/* model view matrix */
1259 	if (program->u_ModelViewMatrix > -1)
1260 		R_GLSL_SetUniform_ModelViewMatrix(program, glState.currentModelViewMatrix);
1261 
1262 	/* model view projection matrix */
1263 	if (program->u_ModelViewProjectionMatrix > -1)
1264 		R_GLSL_SetUniform_ModelViewProjectionMatrix(program, glState.currentModelViewProjectionMatrix);
1265 
1266 	/* projection matrix */
1267 	if (program->u_ProjectionMatrix > -1)
1268 		R_GLSL_SetUniform_ProjectionMatrix(program, glState.currentProjectionMatrix);
1269 
1270 	/* texture coordinates 0 */
1271 	if (program->u_TCGen0 > -1)
1272 		R_GLSL_SetUniform_TCGen0(program, pStage->bundle[0].tcGen);
1273 
1274 	/* texture coordinates 1 */
1275 	if (program->u_TCGen1 > -1)
1276 		R_GLSL_SetUniform_TCGen1(program, pStage->bundle[1].tcGen);
1277 
1278 	/* tex env */
1279 	if (program->u_TexEnv > -1) {
1280 		if (r_lightmap->integer)
1281 			R_GLSL_SetUniform_TexEnv(program, GL_REPLACE);
1282 		else
1283 			R_GLSL_SetUniform_TexEnv(program, input->shader->multitextureEnv);
1284 	}
1285 
1286 	/* texture unit 0 */
1287 	if (program->u_Texture0 > -1 && pStage->bundle[0].image[0]) {
1288 		GL_SelectTexture(0);
1289 
1290 		if (pStage->bundle[0].vertexLightmap && ((r_vertexLight->integer && !r_uiFullScreen->integer) || glConfig.hardwareType == GLHW_PERMEDIA2) && r_lightmap->integer)
1291 			GL_Bind(tr.whiteImage);
1292 		else
1293 			R_BindAnimatedImage(&pStage->bundle[0]);
1294 	}
1295 
1296 	/* texture unit 1 */
1297 	if (program->u_Texture1 > -1 && pStage->bundle[1].image[0]) {
1298 		GL_SelectTexture(1);
1299 		qglEnable(GL_TEXTURE_2D);
1300 		R_BindAnimatedImage(&pStage->bundle[1]);
1301 	}
1302 
1303 	/* texture unit 2 */
1304 	if (program->u_Texture2 > -1 && pStage->bundle[2].image[0]) {
1305 		GL_SelectTexture(2);
1306 		qglEnable(GL_TEXTURE_2D);
1307 		R_BindAnimatedImage(&pStage->bundle[2]);
1308 	}
1309 
1310 	/* texture unit 3 */
1311 	if (program->u_Texture3 > -1 && pStage->bundle[3].image[0]) {
1312 		GL_SelectTexture(3);
1313 		qglEnable(GL_TEXTURE_2D);
1314 		R_BindAnimatedImage(&pStage->bundle[3]);
1315 	}
1316 
1317 	/* texture unit 4 */
1318 	if (program->u_Texture4 > -1 && pStage->bundle[4].image[0]) {
1319 		GL_SelectTexture(4);
1320 		qglEnable(GL_TEXTURE_2D);
1321 		R_BindAnimatedImage(&pStage->bundle[4]);
1322 	}
1323 
1324 	/* texture unit 5 */
1325 	if (program->u_Texture5 > -1 && pStage->bundle[5].image[0]) {
1326 		GL_SelectTexture(5);
1327 		qglEnable(GL_TEXTURE_2D);
1328 		R_BindAnimatedImage(&pStage->bundle[5]);
1329 	}
1330 
1331 	/* texture unit 6 */
1332 	if (program->u_Texture6 > -1 && pStage->bundle[6].image[0]) {
1333 		GL_SelectTexture(6);
1334 		qglEnable(GL_TEXTURE_2D);
1335 		R_BindAnimatedImage(&pStage->bundle[6]);
1336 	}
1337 
1338 	/* texture unit 7 */
1339 	if (program->u_Texture7 > -1 && pStage->bundle[7].image[0]) {
1340 		GL_SelectTexture(7);
1341 		qglEnable(GL_TEXTURE_2D);
1342 		R_BindAnimatedImage(&pStage->bundle[7]);
1343 	}
1344 
1345 	/* time */
1346 	if (program->u_Time > -1)
1347 		R_GLSL_SetUniform_Time(program, input->shaderTime);
1348 
1349 	/* view origin */
1350 	if (program->u_ViewOrigin > -1)
1351 		R_GLSL_SetUniform_ViewOrigin(program, backEnd.or.viewOrigin);
1352 
1353 }
1354 
1355 // GLSL Clean
GLSL_Clean(void)1356 void GLSL_Clean(void)
1357 {
1358 	glslProgram_t	*program;
1359 	program = tr.programs[glState.currentProgram];
1360 
1361 	/* disable texture unit 7 */
1362 	if (program->u_Texture7 > -1)
1363 		qglDisable(GL_TEXTURE_2D);
1364 
1365 	/* disable texture unit 6 */
1366 	if (program->u_Texture6 > -1) {
1367 		GL_SelectTexture(6);
1368 		qglDisable(GL_TEXTURE_2D);
1369 	}
1370 
1371 	/* disable texture unit 5 */
1372 	if (program->u_Texture5 > -1) {
1373 		GL_SelectTexture(5);
1374 		qglDisable(GL_TEXTURE_2D);
1375 	}
1376 
1377 	/* disable texture unit 4 */
1378 	if (program->u_Texture4 > -1) {
1379 		GL_SelectTexture(4);
1380 		qglDisable(GL_TEXTURE_2D);
1381 	}
1382 
1383 	/* disable texture unit 3 */
1384 	if (program->u_Texture3 > -1) {
1385 		GL_SelectTexture(3);
1386 		qglDisable(GL_TEXTURE_2D);
1387 	}
1388 
1389 	/* disable texture unit 2 */
1390 	if (program->u_Texture2 > -1) {
1391 		GL_SelectTexture(2);
1392 		qglDisable(GL_TEXTURE_2D);
1393 	}
1394 
1395 	/* disable texture unit 1 */
1396 	if (program->u_Texture1 > -1) {
1397 		GL_SelectTexture(1);
1398 		qglDisable(GL_TEXTURE_2D);
1399 		qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
1400 	}
1401 
1402 	/* switch to texture unit 0 */
1403 	GL_SelectTexture(0);
1404 	R_GLSL_UseProgram(0);
1405 
1406 }
1407 /*
1408 ** RB_IterateStagesGeneric
1409 */
RB_IterateStagesGeneric(shaderCommands_t * input)1410 static void RB_IterateStagesGeneric( shaderCommands_t *input )
1411 {
1412 	int stage;
1413 
1414 	for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ )
1415 	{
1416 		shaderStage_t *pStage = tess.xstages[stage];
1417 
1418 		if (!pStage || (vertexShaders && pStage->program == tr.skipProgram))
1419 		{
1420 			break;
1421 		}
1422 
1423 		ComputeColors( pStage );
1424 		ComputeTexCoords( pStage );
1425 
1426 		if ( !setArraysOnce )
1427 		{
1428 			qglEnableClientState( GL_COLOR_ARRAY );
1429 			qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, input->svars.colors );
1430 		}
1431 
1432 		if (pStage->isGLSL && vertexShaders && pStage->program && tr.programs[pStage->program]->valid)
1433 		{
1434 		GLSL_Feeder(pStage, input);
1435 		GL_State( pStage->stateBits );
1436 		R_DrawElements( input->numIndexes, input->indexes );
1437 		GLSL_Clean();
1438 		}
1439 		else
1440 		{
1441 		//
1442 		// do multitexture
1443 		//
1444 		if ( pStage->bundle[1].image[0] != 0 )
1445 		{
1446 			DrawMultitextured( input, stage );
1447 		}
1448 		else
1449 		{
1450 			if ( !setArraysOnce )
1451 			{
1452 				qglTexCoordPointer( 2, GL_FLOAT, 0, input->svars.texcoords[0] );
1453 			}
1454 
1455 			//
1456 			// set state
1457 			//
1458 			if ( pStage->bundle[0].vertexLightmap && ( (r_vertexLight->integer && !r_uiFullScreen->integer) || glConfig.hardwareType == GLHW_PERMEDIA2 ) && r_lightmap->integer )
1459 			{
1460 				GL_Bind( tr.whiteImage );
1461 			}
1462 			else
1463 				R_BindAnimatedImage( &pStage->bundle[0] );
1464 
1465 			GL_State( pStage->stateBits );
1466 
1467 			//
1468 			// draw
1469 			//
1470 			R_DrawElements( input->numIndexes, input->indexes );
1471 		}
1472 
1473 		// odin's patch adapted
1474 		if ( r_envMode->integer == 2) {
1475 			if ( pStage->bundle[0].tcGen == TCGEN_ENVIRONMENT_MAPPED ) {
1476 				qglDisable(GL_TEXTURE_GEN_S);
1477 				qglDisable(GL_TEXTURE_GEN_T);
1478 				qglDisable(GL_TEXTURE_GEN_R);
1479 			}
1480 		}
1481 	}
1482 		// allow skipping out to show just lightmaps during development
1483 		if ( r_lightmap->integer && ( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap || pStage->bundle[0].vertexLightmap ) )
1484 		{
1485 			break;
1486 		}
1487 	}
1488 }
1489 
1490 
1491 /*
1492 ** RB_StageIteratorGeneric
1493 */
RB_StageIteratorGeneric(void)1494 void RB_StageIteratorGeneric( void )
1495 {
1496 	shaderCommands_t *input;
1497 
1498 	input = &tess;
1499 
1500 	RB_DeformTessGeometry();
1501 
1502 	//
1503 	// log this call
1504 	//
1505 	if ( r_logFile->integer )
1506 	{
1507 		// don't just call LogComment, or we will get
1508 		// a call to va() every frame!
1509 		GLimp_LogComment( va("--- RB_StageIteratorGeneric( %s ) ---\n", tess.shader->name) );
1510 	}
1511 
1512 	//
1513 	// set face culling appropriately
1514 	//
1515 	GL_Cull( input->shader->cullType );
1516 
1517 	// set polygon offset if necessary
1518 	if ( input->shader->polygonOffset )
1519 	{
1520 		qglEnable( GL_POLYGON_OFFSET_FILL );
1521 		qglPolygonOffset( r_offsetFactor->value, r_offsetUnits->value );
1522 	}
1523 
1524 	//
1525 	// if there is only a single pass then we can enable color
1526 	// and texture arrays before we compile, otherwise we need
1527 	// to avoid compiling those arrays since they will change
1528 	// during multipass rendering
1529 	//
1530 	if ( tess.numPasses > 1 || input->shader->multitextureEnv )
1531 	{
1532 		setArraysOnce = qfalse;
1533 		qglDisableClientState (GL_COLOR_ARRAY);
1534 		qglDisableClientState (GL_TEXTURE_COORD_ARRAY);
1535 	}
1536 	else
1537 	{
1538 		setArraysOnce = qtrue;
1539 
1540 		qglEnableClientState( GL_COLOR_ARRAY);
1541 		qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.svars.colors );
1542 
1543 		qglEnableClientState( GL_TEXTURE_COORD_ARRAY);
1544 		qglTexCoordPointer( 2, GL_FLOAT, 0, tess.svars.texcoords[0] );
1545 	}
1546 
1547 	//
1548 	// lock XYZ
1549 	//
1550 	qglVertexPointer (3, GL_FLOAT, 16, input->xyz);	// padded for SIMD
1551 	if (qglLockArraysEXT)
1552 	{
1553 		qglLockArraysEXT(0, input->numVertexes);
1554 		GLimp_LogComment( "glLockArraysEXT\n" );
1555 	}
1556 
1557 	//
1558 	// enable color and texcoord arrays after the lock if necessary
1559 	//
1560 	if ( !setArraysOnce )
1561 	{
1562 		qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
1563 		qglEnableClientState( GL_COLOR_ARRAY );
1564 	}
1565 
1566 	//
1567 	// call shader function
1568 	//
1569 	RB_IterateStagesGeneric( input );
1570 
1571 	//
1572 	// now do any dynamic lighting needed
1573 	//
1574 	if (vertexShaders) qglPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
1575 	if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE
1576 		&& !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) ) {
1577 		ProjectDlightTexture();
1578 	}
1579 	if (vertexShaders) qglPopClientAttrib();
1580 
1581 	//
1582 	// now do fog
1583 	//
1584 	if ( tess.fogNum && tess.shader->fogPass ) {
1585 		RB_FogPass();
1586 	}
1587 
1588 	//
1589 	// unlock arrays
1590 	//
1591 	if (qglUnlockArraysEXT)
1592 	{
1593 		qglUnlockArraysEXT();
1594 		GLimp_LogComment( "glUnlockArraysEXT\n" );
1595 	}
1596 
1597 	//
1598 	// reset polygon offset
1599 	//
1600 	if ( input->shader->polygonOffset )
1601 	{
1602 		qglDisable( GL_POLYGON_OFFSET_FILL );
1603 	}
1604 }
1605 
1606 
1607 /*
1608 ** RB_StageIteratorVertexLitTexture
1609 */
RB_StageIteratorVertexLitTexture(void)1610 void RB_StageIteratorVertexLitTexture( void )
1611 {
1612 	shaderCommands_t *input;
1613 //	shader_t		*shader;
1614 
1615 	input = &tess;
1616 
1617 //	shader = input->shader;
1618 
1619 	//
1620 	// compute colors
1621 	//
1622 	RB_CalcDiffuseColor( ( unsigned char * ) tess.svars.colors );
1623 
1624 	//
1625 	// log this call
1626 	//
1627 	if ( r_logFile->integer )
1628 	{
1629 		// don't just call LogComment, or we will get
1630 		// a call to va() every frame!
1631 		GLimp_LogComment( va("--- RB_StageIteratorVertexLitTexturedUnfogged( %s ) ---\n", tess.shader->name) );
1632 	}
1633 
1634 	//
1635 	// set face culling appropriately
1636 	//
1637 	GL_Cull( input->shader->cullType );
1638 
1639 	//
1640 	// set arrays and lock
1641 	//
1642 	qglEnableClientState( GL_COLOR_ARRAY);
1643 	qglEnableClientState( GL_TEXTURE_COORD_ARRAY);
1644 
1645 	qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.svars.colors );
1646 	qglTexCoordPointer( 2, GL_FLOAT, 16, tess.texCoords[0][0] );
1647 	qglVertexPointer (3, GL_FLOAT, 16, input->xyz);
1648 
1649 	if ( qglLockArraysEXT )
1650 	{
1651 		qglLockArraysEXT(0, input->numVertexes);
1652 		GLimp_LogComment( "glLockArraysEXT\n" );
1653 	}
1654 
1655 	//
1656 	// call special shade routine
1657 	//
1658 	R_BindAnimatedImage( &tess.xstages[0]->bundle[0] );
1659 	GL_State( tess.xstages[0]->stateBits );
1660 	R_DrawElements( input->numIndexes, input->indexes );
1661 
1662 	//
1663 	// now do any dynamic lighting needed
1664 	//
1665 	if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE ) {
1666 		ProjectDlightTexture();
1667 	}
1668 
1669 	//
1670 	// now do fog
1671 	//
1672 	if ( tess.fogNum && tess.shader->fogPass ) {
1673 		RB_FogPass();
1674 	}
1675 
1676 	//
1677 	// unlock arrays
1678 	//
1679 	if (qglUnlockArraysEXT)
1680 	{
1681 		qglUnlockArraysEXT();
1682 		GLimp_LogComment( "glUnlockArraysEXT\n" );
1683 	}
1684 }
1685 
1686 //define	REPLACE_MODE
1687 
RB_StageIteratorLightmappedMultitexture(void)1688 void RB_StageIteratorLightmappedMultitexture( void ) {
1689 	shaderCommands_t *input;
1690 
1691 	input = &tess;
1692 
1693 	//
1694 	// log this call
1695 	//
1696 	if ( r_logFile->integer ) {
1697 		// don't just call LogComment, or we will get
1698 		// a call to va() every frame!
1699 		GLimp_LogComment( va("--- RB_StageIteratorLightmappedMultitexture( %s ) ---\n", tess.shader->name) );
1700 	}
1701 
1702 	//
1703 	// set face culling appropriately
1704 	//
1705 	GL_Cull( input->shader->cullType );
1706 
1707 	//
1708 	// set color, pointers, and lock
1709 	//
1710 	GL_State( GLS_DEFAULT );
1711 	qglVertexPointer( 3, GL_FLOAT, 16, input->xyz );
1712 
1713 #ifdef REPLACE_MODE
1714 	qglDisableClientState( GL_COLOR_ARRAY );
1715 	qglColor3f( 1, 1, 1 );
1716 	qglShadeModel( GL_FLAT );
1717 #else
1718 	qglEnableClientState( GL_COLOR_ARRAY );
1719 	qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.constantColor255 );
1720 #endif
1721 
1722 	//
1723 	// select base stage
1724 	//
1725 	GL_SelectTexture( 0 );
1726 
1727 	qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
1728 	R_BindAnimatedImage( &tess.xstages[0]->bundle[0] );
1729 	qglTexCoordPointer( 2, GL_FLOAT, 16, tess.texCoords[0][0] );
1730 
1731 	//
1732 	// configure second stage
1733 	//
1734 	GL_SelectTexture( 1 );
1735 	qglEnable( GL_TEXTURE_2D );
1736 	if ( r_lightmap->integer ) {
1737 		GL_TexEnv( GL_REPLACE );
1738 	} else {
1739 		GL_TexEnv( GL_MODULATE );
1740 	}
1741 	R_BindAnimatedImage( &tess.xstages[0]->bundle[1] );
1742 	qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
1743 	qglTexCoordPointer( 2, GL_FLOAT, 16, tess.texCoords[0][1] );
1744 
1745 	//
1746 	// lock arrays
1747 	//
1748 	if ( qglLockArraysEXT ) {
1749 		qglLockArraysEXT(0, input->numVertexes);
1750 		GLimp_LogComment( "glLockArraysEXT\n" );
1751 	}
1752 
1753 	R_DrawElements( input->numIndexes, input->indexes );
1754 
1755 	//
1756 	// disable texturing on TEXTURE1, then select TEXTURE0
1757 	//
1758 	qglDisable( GL_TEXTURE_2D );
1759 	qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
1760 
1761 	GL_SelectTexture( 0 );
1762 #ifdef REPLACE_MODE
1763 	GL_TexEnv( GL_MODULATE );
1764 	qglShadeModel( GL_SMOOTH );
1765 #endif
1766 
1767 	//
1768 	// now do any dynamic lighting needed
1769 	//
1770 	if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE ) {
1771 		ProjectDlightTexture();
1772 	}
1773 
1774 	//
1775 	// now do fog
1776 	//
1777 	if ( tess.fogNum && tess.shader->fogPass ) {
1778 		RB_FogPass();
1779 	}
1780 
1781 	//
1782 	// unlock arrays
1783 	//
1784 	if ( qglUnlockArraysEXT ) {
1785 		qglUnlockArraysEXT();
1786 		GLimp_LogComment( "glUnlockArraysEXT\n" );
1787 	}
1788 }
1789 
1790 /*
1791  * RB_GLSL_IterateStagesGeneric
1792  * Iterate over each stage of a shader
1793  */
1794 //static void RB_GLSL_IterateStagesGeneric(shaderCommands_t *input) {
1795 //	RB_IterateStagesGeneric(input);
1796 //}
1797 
1798 /*
1799  * RB_GLSL_StageIteratorGeneric
1800  * Stage iterator for GLSL programs
1801  */
RB_GLSL_StageIteratorGeneric(void)1802 void RB_GLSL_StageIteratorGeneric(void) {
1803 	RB_StageIteratorGeneric();
1804 }
1805 
1806 /*
1807  * RB_GLSL_StageIteratorVertexLitTexture
1808  * Stage iterator for GLSL vertex lit texture program
1809  */
RB_GLSL_StageIteratorVertexLitTexture(void)1810 void RB_GLSL_StageIteratorVertexLitTexture(void) {
1811 	RB_StageIteratorVertexLitTexture(); // TODO: placeholder
1812 }
1813 
1814 /*
1815  * RB_GLSL_StageIteratorLightmappedMultitexture
1816  * Stage iterator for GLSL lightmapped multitexture program
1817  */
RB_GLSL_StageIteratorLightmappedMultitexture(void)1818 void RB_GLSL_StageIteratorLightmappedMultitexture(void) {
1819 	RB_StageIteratorLightmappedMultitexture(); // TODO: placeholder
1820 }
1821 
1822 /*
1823 ** RB_EndSurface
1824 */
RB_EndSurface(void)1825 void RB_EndSurface( void ) {
1826 	shaderCommands_t *input;
1827 
1828 	input = &tess;
1829 
1830 	if (input->numIndexes == 0) {
1831 		return;
1832 	}
1833 
1834 	if (input->indexes[SHADER_MAX_INDEXES-1] != 0) {
1835 		ri.Error (ERR_DROP, "RB_EndSurface() - SHADER_MAX_INDEXES hit");
1836 	}
1837 	if (input->xyz[SHADER_MAX_VERTEXES-1][0] != 0) {
1838 		ri.Error (ERR_DROP, "RB_EndSurface() - SHADER_MAX_VERTEXES hit");
1839 	}
1840 
1841 	if ( tess.shader == tr.shadowShader ) {
1842 		RB_ShadowTessEnd();
1843 		return;
1844 	}
1845 
1846 	// for debugging of sort order issues, stop rendering after a given sort value
1847 	if ( r_debugSort->integer && r_debugSort->integer < tess.shader->sort ) {
1848 		return;
1849 	}
1850 
1851 	//
1852 	// update performance counters
1853 	//
1854 	backEnd.pc.c_shaders++;
1855 	backEnd.pc.c_vertexes += tess.numVertexes;
1856 	backEnd.pc.c_indexes += tess.numIndexes;
1857 	backEnd.pc.c_totalIndexes += tess.numIndexes * tess.numPasses;
1858 
1859 	//
1860 	// call off to shader specific tess end function
1861 	//
1862 	tess.currentStageIteratorFunc();
1863 
1864 	//
1865 	// draw debugging stuff
1866 	//
1867 	if ( r_showtris->integer ) {
1868 		DrawTris (input);
1869 	}
1870 	if ( r_shownormals->integer ) {
1871 		DrawNormals (input);
1872 	}
1873 	// clear shader so we can tell we don't have any unclosed surfaces
1874 	tess.numIndexes = 0;
1875 
1876 	GLimp_LogComment( "----------\n" );
1877 }
1878 
1879