1 /*
2 ===========================================================================
3 
4 Return to Castle Wolfenstein single player GPL Source Code
5 Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Return to Castle Wolfenstein single player GPL Source Code (“RTCW SP Source Code”).
8 
9 RTCW SP 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 RTCW SP 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 RTCW SP Source Code.  If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the RTCW SP 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 RTCW SP 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 "tr_local.h"
30 
31 // tr_shader.c -- this file deals with the parsing and definition of shaders
32 
33 static char *s_shaderText;
34 
35 // the shader is parsed into these global variables, then copied into
36 // dynamically allocated memory if it is valid.
37 static shaderStage_t stages[MAX_SHADER_STAGES];
38 static shader_t shader;
39 static texModInfo_t texMods[MAX_SHADER_STAGES][TR_MAX_TEXMODS];
40 
41 #define FILE_HASH_SIZE      4096
42 
43 static shader_t*       hashTable[FILE_HASH_SIZE];
44 
45 // Ridah
46 // Table containing string indexes for each shader found in the scripts, referenced by their checksum
47 // values.
48 typedef struct shaderStringPointer_s
49 {
50 	char *pStr;
51 	struct shaderStringPointer_s *next;
52 } shaderStringPointer_t;
53 //
54 shaderStringPointer_t shaderChecksumLookup[FILE_HASH_SIZE];
55 // done.
56 
57 /*
58 ================
59 return a hash value for the filename
60 ================
61 */
62 #ifdef __GNUCC__
63   #warning TODO: check if long is ok here
64 #endif
generateHashValue(const char * fname)65 static long generateHashValue( const char *fname ) {
66 	int i;
67 	long hash;
68 	char letter;
69 
70 	hash = 0;
71 	i = 0;
72 	while ( fname[i] != '\0' ) {
73 		letter = tolower( fname[i] );
74 		if ( letter == '.' ) {
75 			break;                          // don't include extension
76 		}
77 		if ( letter == '\\' ) {
78 			letter = '/';                   // damn path names
79 		}
80 		if ( letter == PATH_SEP ) {
81 			letter = '/';                           // damn path names
82 		}
83 		hash += (long)( letter ) * ( i + 119 );
84 		i++;
85 	}
86 	hash &= ( FILE_HASH_SIZE - 1 );
87 	return hash;
88 }
89 
R_RemapShader(const char * shaderName,const char * newShaderName,const char * timeOffset)90 void R_RemapShader( const char *shaderName, const char *newShaderName, const char *timeOffset ) {
91 	char strippedName[MAX_QPATH];
92 	int hash;
93 	shader_t    *sh, *sh2;
94 	qhandle_t h;
95 
96 	sh = R_FindShaderByName( shaderName );
97 	if ( sh == NULL || sh == tr.defaultShader ) {
98 		h = RE_RegisterShaderLightMap( shaderName, 0 );
99 		sh = R_GetShaderByHandle( h );
100 	}
101 	if ( sh == NULL || sh == tr.defaultShader ) {
102 		ri.Printf( PRINT_WARNING, "WARNING: R_RemapShader: shader %s not found\n", shaderName );
103 		return;
104 	}
105 
106 	sh2 = R_FindShaderByName( newShaderName );
107 	if ( sh2 == NULL || sh2 == tr.defaultShader ) {
108 		h = RE_RegisterShaderLightMap( newShaderName, 0 );
109 		sh2 = R_GetShaderByHandle( h );
110 	}
111 
112 	if ( sh2 == NULL || sh2 == tr.defaultShader ) {
113 		ri.Printf( PRINT_WARNING, "WARNING: R_RemapShader: new shader %s not found\n", newShaderName );
114 		return;
115 	}
116 
117 	// remap all the shaders with the given name
118 	// even tho they might have different lightmaps
119 	COM_StripExtension( shaderName, strippedName, sizeof( strippedName ) );
120 	hash = generateHashValue( strippedName );
121 	for ( sh = hashTable[hash]; sh; sh = sh->next ) {
122 		if ( Q_stricmp( sh->name, strippedName ) == 0 ) {
123 			if ( sh != sh2 ) {
124 				sh->remappedShader = sh2;
125 			} else {
126 				sh->remappedShader = NULL;
127 			}
128 		}
129 	}
130 	if ( timeOffset ) {
131 		sh2->timeOffset = atof( timeOffset );
132 	}
133 }
134 
135 /*
136 ===============
137 ParseVector
138 ===============
139 */
ParseVector(char ** text,int count,float * v)140 static qboolean ParseVector( char **text, int count, float *v ) {
141 	char    *token;
142 	int i;
143 
144 	// FIXME: spaces are currently required after parens, should change parseext...
145 	token = COM_ParseExt( text, qfalse );
146 	if ( strcmp( token, "(" ) ) {
147 		ri.Printf( PRINT_WARNING, "WARNING: missing parenthesis in shader '%s'\n", shader.name );
148 		return qfalse;
149 	}
150 
151 	for ( i = 0 ; i < count ; i++ ) {
152 		token = COM_ParseExt( text, qfalse );
153 		if ( !token[0] ) {
154 			ri.Printf( PRINT_WARNING, "WARNING: missing vector element in shader '%s'\n", shader.name );
155 			return qfalse;
156 		}
157 		v[i] = atof( token );
158 	}
159 
160 	token = COM_ParseExt( text, qfalse );
161 	if ( strcmp( token, ")" ) ) {
162 		ri.Printf( PRINT_WARNING, "WARNING: missing parenthesis in shader '%s'\n", shader.name );
163 		return qfalse;
164 	}
165 
166 	return qtrue;
167 }
168 
169 
170 /*
171 ===============
172 NameToAFunc
173 ===============
174 */
NameToAFunc(const char * funcname)175 static unsigned NameToAFunc( const char *funcname ) {
176 	if ( !Q_stricmp( funcname, "GT0" ) ) {
177 		return GLS_ATEST_GT_0;
178 	} else if ( !Q_stricmp( funcname, "LT128" ) )    {
179 		return GLS_ATEST_LT_80;
180 	} else if ( !Q_stricmp( funcname, "GE128" ) )    {
181 		return GLS_ATEST_GE_80;
182 	}
183 
184 	ri.Printf( PRINT_WARNING, "WARNING: invalid alphaFunc name '%s' in shader '%s'\n", funcname, shader.name );
185 	return 0;
186 }
187 
188 
189 /*
190 ===============
191 NameToSrcBlendMode
192 ===============
193 */
NameToSrcBlendMode(const char * name)194 static int NameToSrcBlendMode( const char *name ) {
195 	if ( !Q_stricmp( name, "GL_ONE" ) ) {
196 		return GLS_SRCBLEND_ONE;
197 	} else if ( !Q_stricmp( name, "GL_ZERO" ) )    {
198 		return GLS_SRCBLEND_ZERO;
199 	} else if ( !Q_stricmp( name, "GL_DST_COLOR" ) )    {
200 		return GLS_SRCBLEND_DST_COLOR;
201 	} else if ( !Q_stricmp( name, "GL_ONE_MINUS_DST_COLOR" ) )    {
202 		return GLS_SRCBLEND_ONE_MINUS_DST_COLOR;
203 	} else if ( !Q_stricmp( name, "GL_SRC_ALPHA" ) )    {
204 		return GLS_SRCBLEND_SRC_ALPHA;
205 	} else if ( !Q_stricmp( name, "GL_ONE_MINUS_SRC_ALPHA" ) )    {
206 		return GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA;
207 	} else if ( !Q_stricmp( name, "GL_DST_ALPHA" ) )    {
208 		if (r_ignoreDstAlpha->integer)
209 			return GLS_SRCBLEND_ONE;
210 		return GLS_SRCBLEND_DST_ALPHA;
211 	} else if ( !Q_stricmp( name, "GL_ONE_MINUS_DST_ALPHA" ) )    {
212 		if (r_ignoreDstAlpha->integer)
213 			return GLS_SRCBLEND_ZERO;
214 		return GLS_SRCBLEND_ONE_MINUS_DST_ALPHA;
215 	} else if ( !Q_stricmp( name, "GL_SRC_ALPHA_SATURATE" ) )    {
216 		return GLS_SRCBLEND_ALPHA_SATURATE;
217 	}
218 
219 	ri.Printf( PRINT_WARNING, "WARNING: unknown blend mode '%s' in shader '%s', substituting GL_ONE\n", name, shader.name );
220 	return GLS_SRCBLEND_ONE;
221 }
222 
223 /*
224 ===============
225 NameToDstBlendMode
226 ===============
227 */
NameToDstBlendMode(const char * name)228 static int NameToDstBlendMode( const char *name ) {
229 	if ( !Q_stricmp( name, "GL_ONE" ) ) {
230 		return GLS_DSTBLEND_ONE;
231 	} else if ( !Q_stricmp( name, "GL_ZERO" ) )    {
232 		return GLS_DSTBLEND_ZERO;
233 	} else if ( !Q_stricmp( name, "GL_SRC_ALPHA" ) )    {
234 		return GLS_DSTBLEND_SRC_ALPHA;
235 	} else if ( !Q_stricmp( name, "GL_ONE_MINUS_SRC_ALPHA" ) )    {
236 		return GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA;
237 	} else if ( !Q_stricmp( name, "GL_DST_ALPHA" ) )    {
238 		if (r_ignoreDstAlpha->integer)
239 			return GLS_DSTBLEND_ONE;
240 		return GLS_DSTBLEND_DST_ALPHA;
241 	} else if ( !Q_stricmp( name, "GL_ONE_MINUS_DST_ALPHA" ) )    {
242 		if (r_ignoreDstAlpha->integer)
243 			return GLS_DSTBLEND_ZERO;
244 		return GLS_DSTBLEND_ONE_MINUS_DST_ALPHA;
245 	} else if ( !Q_stricmp( name, "GL_SRC_COLOR" ) )    {
246 		return GLS_DSTBLEND_SRC_COLOR;
247 	} else if ( !Q_stricmp( name, "GL_ONE_MINUS_SRC_COLOR" ) )    {
248 		return GLS_DSTBLEND_ONE_MINUS_SRC_COLOR;
249 	}
250 
251 	ri.Printf( PRINT_WARNING, "WARNING: unknown blend mode '%s' in shader '%s', substituting GL_ONE\n", name, shader.name );
252 	return GLS_DSTBLEND_ONE;
253 }
254 
255 /*
256 ===============
257 NameToGenFunc
258 ===============
259 */
NameToGenFunc(const char * funcname)260 static genFunc_t NameToGenFunc( const char *funcname ) {
261 	if ( !Q_stricmp( funcname, "sin" ) ) {
262 		return GF_SIN;
263 	} else if ( !Q_stricmp( funcname, "square" ) )    {
264 		return GF_SQUARE;
265 	} else if ( !Q_stricmp( funcname, "triangle" ) )    {
266 		return GF_TRIANGLE;
267 	} else if ( !Q_stricmp( funcname, "sawtooth" ) )    {
268 		return GF_SAWTOOTH;
269 	} else if ( !Q_stricmp( funcname, "inversesawtooth" ) )    {
270 		return GF_INVERSE_SAWTOOTH;
271 	} else if ( !Q_stricmp( funcname, "noise" ) )    {
272 		return GF_NOISE;
273 	}
274 
275 	ri.Printf( PRINT_WARNING, "WARNING: invalid genfunc name '%s' in shader '%s'\n", funcname, shader.name );
276 	return GF_SIN;
277 }
278 
279 
280 /*
281 ===================
282 ParseWaveForm
283 ===================
284 */
ParseWaveForm(char ** text,waveForm_t * wave)285 static void ParseWaveForm( char **text, waveForm_t *wave ) {
286 	char *token;
287 
288 	token = COM_ParseExt( text, qfalse );
289 	if ( token[0] == 0 ) {
290 		ri.Printf( PRINT_WARNING, "WARNING: missing waveform parm in shader '%s'\n", shader.name );
291 		return;
292 	}
293 	wave->func = NameToGenFunc( token );
294 
295 	// BASE, AMP, PHASE, FREQ
296 	token = COM_ParseExt( text, qfalse );
297 	if ( token[0] == 0 ) {
298 		ri.Printf( PRINT_WARNING, "WARNING: missing waveform parm in shader '%s'\n", shader.name );
299 		return;
300 	}
301 	wave->base = atof( token );
302 
303 	token = COM_ParseExt( text, qfalse );
304 	if ( token[0] == 0 ) {
305 		ri.Printf( PRINT_WARNING, "WARNING: missing waveform parm in shader '%s'\n", shader.name );
306 		return;
307 	}
308 	wave->amplitude = atof( token );
309 
310 	token = COM_ParseExt( text, qfalse );
311 	if ( token[0] == 0 ) {
312 		ri.Printf( PRINT_WARNING, "WARNING: missing waveform parm in shader '%s'\n", shader.name );
313 		return;
314 	}
315 	wave->phase = atof( token );
316 
317 	token = COM_ParseExt( text, qfalse );
318 	if ( token[0] == 0 ) {
319 		ri.Printf( PRINT_WARNING, "WARNING: missing waveform parm in shader '%s'\n", shader.name );
320 		return;
321 	}
322 	wave->frequency = atof( token );
323 }
324 
325 
326 /*
327 ===================
328 ParseTexMod
329 ===================
330 */
ParseTexMod(char * _text,shaderStage_t * stage)331 static void ParseTexMod( char *_text, shaderStage_t *stage ) {
332 	const char *token;
333 	char **text = &_text;
334 	texModInfo_t *tmi;
335 
336 	if ( stage->bundle[0].numTexMods == TR_MAX_TEXMODS ) {
337 		ri.Error( ERR_DROP, "ERROR: too many tcMod stages in shader '%s'", shader.name );
338 		return;
339 	}
340 
341 	tmi = &stage->bundle[0].texMods[stage->bundle[0].numTexMods];
342 	stage->bundle[0].numTexMods++;
343 
344 	token = COM_ParseExt( text, qfalse );
345 
346 	//
347 	// swap
348 	//
349 	if ( !Q_stricmp( token, "swap" ) ) { // swap S/T coords (rotate 90d)
350 		tmi->type = TMOD_SWAP;
351 	}
352 	//
353 	// turb
354 	//
355 	// (SA) added 'else' so it wouldn't claim 'swap' was unknown.
356 	else if ( !Q_stricmp( token, "turb" ) ) {
357 		token = COM_ParseExt( text, qfalse );
358 		if ( token[0] == 0 ) {
359 			ri.Printf( PRINT_WARNING, "WARNING: missing tcMod turb parms in shader '%s'\n", shader.name );
360 			return;
361 		}
362 		tmi->wave.base = atof( token );
363 		token = COM_ParseExt( text, qfalse );
364 		if ( token[0] == 0 ) {
365 			ri.Printf( PRINT_WARNING, "WARNING: missing tcMod turb in shader '%s'\n", shader.name );
366 			return;
367 		}
368 		tmi->wave.amplitude = atof( token );
369 		token = COM_ParseExt( text, qfalse );
370 		if ( token[0] == 0 ) {
371 			ri.Printf( PRINT_WARNING, "WARNING: missing tcMod turb in shader '%s'\n", shader.name );
372 			return;
373 		}
374 		tmi->wave.phase = atof( token );
375 		token = COM_ParseExt( text, qfalse );
376 		if ( token[0] == 0 ) {
377 			ri.Printf( PRINT_WARNING, "WARNING: missing tcMod turb in shader '%s'\n", shader.name );
378 			return;
379 		}
380 		tmi->wave.frequency = atof( token );
381 
382 		tmi->type = TMOD_TURBULENT;
383 	}
384 	//
385 	// scale
386 	//
387 	else if ( !Q_stricmp( token, "scale" ) ) {
388 		token = COM_ParseExt( text, qfalse );
389 		if ( token[0] == 0 ) {
390 			ri.Printf( PRINT_WARNING, "WARNING: missing scale parms in shader '%s'\n", shader.name );
391 			return;
392 		}
393 		tmi->scale[0] = atof( token );
394 
395 		token = COM_ParseExt( text, qfalse );
396 		if ( token[0] == 0 ) {
397 			ri.Printf( PRINT_WARNING, "WARNING: missing scale parms in shader '%s'\n", shader.name );
398 			return;
399 		}
400 		tmi->scale[1] = atof( token );
401 		tmi->type = TMOD_SCALE;
402 	}
403 	//
404 	// scroll
405 	//
406 	else if ( !Q_stricmp( token, "scroll" ) ) {
407 		token = COM_ParseExt( text, qfalse );
408 		if ( token[0] == 0 ) {
409 			ri.Printf( PRINT_WARNING, "WARNING: missing scale scroll parms in shader '%s'\n", shader.name );
410 			return;
411 		}
412 		tmi->scroll[0] = atof( token );
413 		token = COM_ParseExt( text, qfalse );
414 		if ( token[0] == 0 ) {
415 			ri.Printf( PRINT_WARNING, "WARNING: missing scale scroll parms in shader '%s'\n", shader.name );
416 			return;
417 		}
418 		tmi->scroll[1] = atof( token );
419 		tmi->type = TMOD_SCROLL;
420 	}
421 	//
422 	// stretch
423 	//
424 	else if ( !Q_stricmp( token, "stretch" ) ) {
425 		token = COM_ParseExt( text, qfalse );
426 		if ( token[0] == 0 ) {
427 			ri.Printf( PRINT_WARNING, "WARNING: missing stretch parms in shader '%s'\n", shader.name );
428 			return;
429 		}
430 		tmi->wave.func = NameToGenFunc( token );
431 
432 		token = COM_ParseExt( text, qfalse );
433 		if ( token[0] == 0 ) {
434 			ri.Printf( PRINT_WARNING, "WARNING: missing stretch parms in shader '%s'\n", shader.name );
435 			return;
436 		}
437 		tmi->wave.base = atof( token );
438 
439 		token = COM_ParseExt( text, qfalse );
440 		if ( token[0] == 0 ) {
441 			ri.Printf( PRINT_WARNING, "WARNING: missing stretch parms in shader '%s'\n", shader.name );
442 			return;
443 		}
444 		tmi->wave.amplitude = atof( token );
445 
446 		token = COM_ParseExt( text, qfalse );
447 		if ( token[0] == 0 ) {
448 			ri.Printf( PRINT_WARNING, "WARNING: missing stretch parms in shader '%s'\n", shader.name );
449 			return;
450 		}
451 		tmi->wave.phase = atof( token );
452 
453 		token = COM_ParseExt( text, qfalse );
454 		if ( token[0] == 0 ) {
455 			ri.Printf( PRINT_WARNING, "WARNING: missing stretch parms in shader '%s'\n", shader.name );
456 			return;
457 		}
458 		tmi->wave.frequency = atof( token );
459 
460 		tmi->type = TMOD_STRETCH;
461 	}
462 	//
463 	// transform
464 	//
465 	else if ( !Q_stricmp( token, "transform" ) ) {
466 		token = COM_ParseExt( text, qfalse );
467 		if ( token[0] == 0 ) {
468 			ri.Printf( PRINT_WARNING, "WARNING: missing transform parms in shader '%s'\n", shader.name );
469 			return;
470 		}
471 		tmi->matrix[0][0] = atof( token );
472 
473 		token = COM_ParseExt( text, qfalse );
474 		if ( token[0] == 0 ) {
475 			ri.Printf( PRINT_WARNING, "WARNING: missing transform parms in shader '%s'\n", shader.name );
476 			return;
477 		}
478 		tmi->matrix[0][1] = atof( token );
479 
480 		token = COM_ParseExt( text, qfalse );
481 		if ( token[0] == 0 ) {
482 			ri.Printf( PRINT_WARNING, "WARNING: missing transform parms in shader '%s'\n", shader.name );
483 			return;
484 		}
485 		tmi->matrix[1][0] = atof( token );
486 
487 		token = COM_ParseExt( text, qfalse );
488 		if ( token[0] == 0 ) {
489 			ri.Printf( PRINT_WARNING, "WARNING: missing transform parms in shader '%s'\n", shader.name );
490 			return;
491 		}
492 		tmi->matrix[1][1] = atof( token );
493 
494 		token = COM_ParseExt( text, qfalse );
495 		if ( token[0] == 0 ) {
496 			ri.Printf( PRINT_WARNING, "WARNING: missing transform parms in shader '%s'\n", shader.name );
497 			return;
498 		}
499 		tmi->translate[0] = atof( token );
500 
501 		token = COM_ParseExt( text, qfalse );
502 		if ( token[0] == 0 ) {
503 			ri.Printf( PRINT_WARNING, "WARNING: missing transform parms in shader '%s'\n", shader.name );
504 			return;
505 		}
506 		tmi->translate[1] = atof( token );
507 
508 		tmi->type = TMOD_TRANSFORM;
509 	}
510 	//
511 	// rotate
512 	//
513 	else if ( !Q_stricmp( token, "rotate" ) ) {
514 		token = COM_ParseExt( text, qfalse );
515 		if ( token[0] == 0 ) {
516 			ri.Printf( PRINT_WARNING, "WARNING: missing tcMod rotate parms in shader '%s'\n", shader.name );
517 			return;
518 		}
519 		tmi->rotateSpeed = atof( token );
520 		tmi->type = TMOD_ROTATE;
521 	}
522 	//
523 	// entityTranslate
524 	//
525 	else if ( !Q_stricmp( token, "entityTranslate" ) ) {
526 		tmi->type = TMOD_ENTITY_TRANSLATE;
527 	} else
528 	{
529 		ri.Printf( PRINT_WARNING, "WARNING: unknown tcMod '%s' in shader '%s'\n", token, shader.name );
530 	}
531 }
532 
533 
534 /*
535 ===================
536 ParseStage
537 ===================
538 */
ParseStage(shaderStage_t * stage,char ** text)539 static qboolean ParseStage( shaderStage_t *stage, char **text ) {
540 	char *token;
541 	int depthMaskBits = GLS_DEPTHMASK_TRUE, blendSrcBits = 0, blendDstBits = 0, atestBits = 0, depthFuncBits = 0;
542 	qboolean depthMaskExplicit = qfalse;
543 
544 	stage->active = qtrue;
545 
546 	while ( 1 )
547 	{
548 		token = COM_ParseExt( text, qtrue );
549 		if ( !token[0] ) {
550 			ri.Printf( PRINT_WARNING, "WARNING: no matching '}' found\n" );
551 			return qfalse;
552 		}
553 
554 		if ( token[0] == '}' ) {
555 			break;
556 		}
557 		//
558 		// check special case for map16/map32/mapcomp/mapnocomp (compression enabled)
559 		if ( !Q_stricmp( token, "map16" ) ) {    // only use this texture if 16 bit color depth
560 			if ( glConfig.colorBits <= 16 ) {
561 				token = "map";   // use this map
562 			} else {
563 				COM_ParseExt( text, qfalse );   // ignore the map
564 				continue;
565 			}
566 		} else if ( !Q_stricmp( token, "map32" ) )    { // only use this texture if 16 bit color depth
567 			if ( glConfig.colorBits > 16 ) {
568 				token = "map";   // use this map
569 			} else {
570 				COM_ParseExt( text, qfalse );   // ignore the map
571 				continue;
572 			}
573 		} else if ( !Q_stricmp( token, "mapcomp" ) )    { // only use this texture if compression is enabled
574 			if ( glConfig.textureCompression && r_ext_compressed_textures->integer ) {
575 				token = "map";   // use this map
576 			} else {
577 				COM_ParseExt( text, qfalse );   // ignore the map
578 				continue;
579 			}
580 		} else if ( !Q_stricmp( token, "mapnocomp" ) )    { // only use this texture if compression is not available or disabled
581 			if ( !glConfig.textureCompression ) {
582 				token = "map";   // use this map
583 			} else {
584 				COM_ParseExt( text, qfalse );   // ignore the map
585 				continue;
586 			}
587 		} else if ( !Q_stricmp( token, "animmapcomp" ) )    { // only use this texture if compression is enabled
588 			if ( glConfig.textureCompression && r_ext_compressed_textures->integer ) {
589 				token = "animmap";   // use this map
590 			} else {
591 				while ( token[0] )
592 					COM_ParseExt( text, qfalse );   // ignore the map
593 				continue;
594 			}
595 		} else if ( !Q_stricmp( token, "animmapnocomp" ) )    { // only use this texture if compression is not available or disabled
596 			if ( !glConfig.textureCompression ) {
597 				token = "animmap";   // use this map
598 			} else {
599 				while ( token[0] )
600 					COM_ParseExt( text, qfalse );   // ignore the map
601 				continue;
602 			}
603 		}
604 		//
605 		// map <name>
606 		//
607 		if ( !Q_stricmp( token, "map" ) ) {
608 			token = COM_ParseExt( text, qfalse );
609 			if ( !token[0] ) {
610 				ri.Printf( PRINT_WARNING, "WARNING: missing parameter for 'map' keyword in shader '%s'\n", shader.name );
611 				return qfalse;
612 			}
613 
614 //----(SA)	fixes startup error and allows polygon shadows to work again
615 			if ( !Q_stricmp( token, "$whiteimage" ) || !Q_stricmp( token, "*white" ) ) {
616 //----(SA)	end
617 				stage->bundle[0].image[0] = tr.whiteImage;
618 				continue;
619 			}
620 //----(SA) added
621 			else if ( !Q_stricmp( token, "$dlight" ) ) {
622 				stage->bundle[0].image[0] = tr.dlightImage;
623 				continue;
624 			}
625 //----(SA) end
626 			else if ( !Q_stricmp( token, "$lightmap" ) ) {
627 				stage->bundle[0].isLightmap = qtrue;
628 				if ( shader.lightmapIndex < 0 || !tr.lightmaps ) {
629 					stage->bundle[0].image[0] = tr.whiteImage;
630 				} else {
631 					stage->bundle[0].image[0] = tr.lightmaps[shader.lightmapIndex];
632 				}
633 				continue;
634 			}
635 			else if ( !Q_stricmp( token, "$deluxemap" ) )
636 			{
637 				if (!tr.worldDeluxeMapping)
638 				{
639 					ri.Printf( PRINT_WARNING, "WARNING: shader '%s' wants a deluxe map in a map compiled without them\n", shader.name );
640 					return qfalse;
641 				}
642 
643 				stage->bundle[0].isLightmap = qtrue;
644 				if ( shader.lightmapIndex < 0 ) {
645 					stage->bundle[0].image[0] = tr.whiteImage;
646 				} else {
647 					stage->bundle[0].image[0] = tr.deluxemaps[shader.lightmapIndex];
648 				}
649 				continue;
650 			}
651 			else
652 			{
653 				imgType_t type = IMGTYPE_COLORALPHA;
654 				imgFlags_t flags = IMGFLAG_NONE;
655 
656 				if (!shader.noMipMaps)
657 					flags |= IMGFLAG_MIPMAP;
658 
659 				if (!shader.noPicMip)
660 					flags |= IMGFLAG_PICMIP;
661 
662 				if (stage->type == ST_NORMALMAP || stage->type == ST_NORMALPARALLAXMAP)
663 				{
664 					type = IMGTYPE_NORMAL;
665 					flags |= IMGFLAG_NOLIGHTSCALE;
666 
667 					if (stage->type == ST_NORMALPARALLAXMAP)
668 						type = IMGTYPE_NORMALHEIGHT;
669 				}
670 				else
671 				{
672 					if (r_genNormalMaps->integer)
673 						flags |= IMGFLAG_GENNORMALMAP;
674 				}
675 
676 				stage->bundle[0].image[0] = R_FindImageFileExt( token, type, flags, shader.characterMip );
677 				if ( !stage->bundle[0].image[0] ) {
678 					ri.Printf( PRINT_WARNING, "WARNING: R_FindImageFileExt could not find '%s' in shader '%s'\n", token, shader.name );
679 					return qfalse;
680 				}
681 			}
682 		}
683 		//
684 		// clampmap <name>
685 		//
686 		else if ( !Q_stricmp( token, "clampmap" ) ) {
687 			imgType_t type = IMGTYPE_COLORALPHA;
688 			imgFlags_t flags = IMGFLAG_CLAMPTOEDGE;
689 
690 			token = COM_ParseExt( text, qfalse );
691 			if ( !token[0] ) {
692 				ri.Printf( PRINT_WARNING, "WARNING: missing parameter for 'clampmap' keyword in shader '%s'\n", shader.name );
693 				return qfalse;
694 			}
695 
696 			if (!shader.noMipMaps)
697 				flags |= IMGFLAG_MIPMAP;
698 
699 			if (!shader.noPicMip)
700 				flags |= IMGFLAG_PICMIP;
701 
702 			if (stage->type == ST_NORMALMAP || stage->type == ST_NORMALPARALLAXMAP)
703 			{
704 				type = IMGTYPE_NORMAL;
705 				flags |= IMGFLAG_NOLIGHTSCALE;
706 
707 				if (stage->type == ST_NORMALPARALLAXMAP)
708 					type = IMGTYPE_NORMALHEIGHT;
709 			}
710 			else
711 			{
712 				if (r_genNormalMaps->integer)
713 					flags |= IMGFLAG_GENNORMALMAP;
714 			}
715 
716 			stage->bundle[0].image[0] = R_FindImageFileExt( token, type, flags, shader.characterMip );
717 			if ( !stage->bundle[0].image[0] ) {
718 				ri.Printf( PRINT_WARNING, "WARNING: R_FindImageFileExt could not find '%s' in shader '%s'\n", token, shader.name );
719 				return qfalse;
720 			}
721 		}
722 		//
723 		// animMap <frequency> <image1> .... <imageN>
724 		//
725 		else if ( !Q_stricmp( token, "animMap" ) ) {
726 			int	totalImages = 0;
727 
728 			token = COM_ParseExt( text, qfalse );
729 			if ( !token[0] ) {
730 				ri.Printf( PRINT_WARNING, "WARNING: missing parameter for 'animMap' keyword in shader '%s'\n", shader.name );
731 				return qfalse;
732 			}
733 			stage->bundle[0].imageAnimationSpeed = atof( token );
734 
735 			// parse up to MAX_IMAGE_ANIMATIONS animations
736 			while ( 1 ) {
737 				int num;
738 
739 				token = COM_ParseExt( text, qfalse );
740 				if ( !token[0] ) {
741 					break;
742 				}
743 				num = stage->bundle[0].numImageAnimations;
744 				if ( num < MAX_IMAGE_ANIMATIONS ) {
745 					imgFlags_t flags = IMGFLAG_NONE;
746 
747 					if (!shader.noMipMaps)
748 						flags |= IMGFLAG_MIPMAP;
749 
750 					if (!shader.noPicMip)
751 						flags |= IMGFLAG_PICMIP;
752 
753 					stage->bundle[0].image[num] = R_FindImageFileExt( token, IMGTYPE_COLORALPHA, flags, shader.characterMip );
754 					if ( !stage->bundle[0].image[num] ) {
755 						ri.Printf( PRINT_WARNING, "WARNING: R_FindImageFileExt could not find '%s' in shader '%s'\n", token, shader.name );
756 						return qfalse;
757 					}
758 					stage->bundle[0].numImageAnimations++;
759 				}
760 				totalImages++;
761 			}
762 
763 			if ( totalImages > MAX_IMAGE_ANIMATIONS ) {
764 				ri.Printf( PRINT_WARNING, "WARNING: ignoring excess images for 'animMap' (found %d, max is %d) in shader '%s'\n",
765 						totalImages, MAX_IMAGE_ANIMATIONS, shader.name );
766 			}
767 		} else if ( !Q_stricmp( token, "videoMap" ) )    {
768 			token = COM_ParseExt( text, qfalse );
769 			if ( !token[0] ) {
770 				ri.Printf( PRINT_WARNING, "WARNING: missing parameter for 'videoMap' keyword in shader '%s'\n", shader.name );
771 				return qfalse;
772 			}
773 			stage->bundle[0].videoMapHandle = ri.CIN_PlayCinematic( token, 0, 0, 256, 256, ( CIN_loop | CIN_silent | CIN_shader ) );
774 			if ( stage->bundle[0].videoMapHandle != -1 ) {
775 				stage->bundle[0].isVideoMap = qtrue;
776 				stage->bundle[0].image[0] = tr.scratchImage[stage->bundle[0].videoMapHandle];
777 			} else {
778 				ri.Printf( PRINT_WARNING, "WARNING: could not load '%s' for 'videoMap' keyword in shader '%s'\n", token, shader.name );
779 			}
780 		}
781 		//
782 		// alphafunc <func>
783 		//
784 		else if ( !Q_stricmp( token, "alphaFunc" ) ) {
785 			token = COM_ParseExt( text, qfalse );
786 			if ( !token[0] ) {
787 				ri.Printf( PRINT_WARNING, "WARNING: missing parameter for 'alphaFunc' keyword in shader '%s'\n", shader.name );
788 				return qfalse;
789 			}
790 
791 			atestBits = NameToAFunc( token );
792 		}
793 		//
794 		// depthFunc <func>
795 		//
796 		else if ( !Q_stricmp( token, "depthfunc" ) ) {
797 			token = COM_ParseExt( text, qfalse );
798 
799 			if ( !token[0] ) {
800 				ri.Printf( PRINT_WARNING, "WARNING: missing parameter for 'depthfunc' keyword in shader '%s'\n", shader.name );
801 				return qfalse;
802 			}
803 
804 			if ( !Q_stricmp( token, "lequal" ) ) {
805 				depthFuncBits = 0;
806 			} else if ( !Q_stricmp( token, "equal" ) )    {
807 				depthFuncBits = GLS_DEPTHFUNC_EQUAL;
808 			} else
809 			{
810 				ri.Printf( PRINT_WARNING, "WARNING: unknown depthfunc '%s' in shader '%s'\n", token, shader.name );
811 				continue;
812 			}
813 		}
814 		//
815 		// detail
816 		//
817 		else if ( !Q_stricmp( token, "detail" ) ) {
818 			stage->isDetail = qtrue;
819 		}
820 		//
821 		// fog
822 		//
823 		else if ( !Q_stricmp( token, "fog" ) ) {
824 			token = COM_ParseExt( text, qfalse );
825 			if ( token[0] == 0 ) {
826 				ri.Printf( PRINT_WARNING, "WARNING: missing parm for fog in shader '%s'\n", shader.name );
827 				continue;
828 			}
829 			if ( !Q_stricmp( token, "on" ) ) {
830 				stage->isFogged = qtrue;
831 			} else {
832 				stage->isFogged = qfalse;
833 			}
834 		}
835 		//
836 		// blendfunc <srcFactor> <dstFactor>
837 		// or blendfunc <add|filter|blend>
838 		//
839 		else if ( !Q_stricmp( token, "blendfunc" ) ) {
840 			token = COM_ParseExt( text, qfalse );
841 			if ( token[0] == 0 ) {
842 				ri.Printf( PRINT_WARNING, "WARNING: missing parm for blendFunc in shader '%s'\n", shader.name );
843 				continue;
844 			}
845 			// check for "simple" blends first
846 			if ( !Q_stricmp( token, "add" ) ) {
847 				blendSrcBits = GLS_SRCBLEND_ONE;
848 				blendDstBits = GLS_DSTBLEND_ONE;
849 			} else if ( !Q_stricmp( token, "filter" ) ) {
850 				blendSrcBits = GLS_SRCBLEND_DST_COLOR;
851 				blendDstBits = GLS_DSTBLEND_ZERO;
852 			} else if ( !Q_stricmp( token, "blend" ) ) {
853 				blendSrcBits = GLS_SRCBLEND_SRC_ALPHA;
854 				blendDstBits = GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA;
855 			} else {
856 				// complex double blends
857 				blendSrcBits = NameToSrcBlendMode( token );
858 
859 				token = COM_ParseExt( text, qfalse );
860 				if ( token[0] == 0 ) {
861 					ri.Printf( PRINT_WARNING, "WARNING: missing parm for blendFunc in shader '%s'\n", shader.name );
862 					continue;
863 				}
864 				blendDstBits = NameToDstBlendMode( token );
865 			}
866 
867 			// clear depth mask for blended surfaces
868 			if ( !depthMaskExplicit ) {
869 				depthMaskBits = 0;
870 			}
871 		}
872 		//
873 		// stage <type>
874 		//
875 		else if(!Q_stricmp(token, "stage"))
876 		{
877 			token = COM_ParseExt(text, qfalse);
878 			if(token[0] == 0)
879 			{
880 				ri.Printf(PRINT_WARNING, "WARNING: missing parameters for stage in shader '%s'\n", shader.name);
881 				continue;
882 			}
883 
884 			if(!Q_stricmp(token, "diffuseMap"))
885 			{
886 				stage->type = ST_DIFFUSEMAP;
887 			}
888 			else if(!Q_stricmp(token, "normalMap") || !Q_stricmp(token, "bumpMap"))
889 			{
890 				stage->type = ST_NORMALMAP;
891 				VectorSet4(stage->normalScale, r_baseNormalX->value, r_baseNormalY->value, 1.0f, r_baseParallax->value);
892 			}
893 			else if(!Q_stricmp(token, "normalParallaxMap") || !Q_stricmp(token, "bumpParallaxMap"))
894 			{
895 				if (r_parallaxMapping->integer)
896 					stage->type = ST_NORMALPARALLAXMAP;
897 				else
898 					stage->type = ST_NORMALMAP;
899 				VectorSet4(stage->normalScale, r_baseNormalX->value, r_baseNormalY->value, 1.0f, r_baseParallax->value);
900 			}
901 			else if(!Q_stricmp(token, "specularMap"))
902 			{
903 				stage->type = ST_SPECULARMAP;
904 				VectorSet4(stage->specularScale, 1.0f, 1.0f, 1.0f, 1.0f);
905 			}
906 			else
907 			{
908 				ri.Printf(PRINT_WARNING, "WARNING: unknown stage parameter '%s' in shader '%s'\n", token, shader.name);
909 				continue;
910 			}
911 		}
912 		//
913 		// specularReflectance <value>
914 		//
915 		else if (!Q_stricmp(token, "specularreflectance"))
916 		{
917 			token = COM_ParseExt(text, qfalse);
918 			if ( token[0] == 0 )
919 			{
920 				ri.Printf( PRINT_WARNING, "WARNING: missing parameter for specular reflectance in shader '%s'\n", shader.name );
921 				continue;
922 			}
923 
924 			if (r_pbr->integer)
925 			{
926 				// interpret specularReflectance < 0.5 as nonmetal
927 				stage->specularScale[1] = (atof(token) < 0.5f) ? 0.0f : 1.0f;
928 			}
929 			else
930 			{
931 				stage->specularScale[0] =
932 				stage->specularScale[1] =
933 				stage->specularScale[2] = atof( token );
934 			}
935 		}
936 		//
937 		// specularExponent <value>
938 		//
939 		else if (!Q_stricmp(token, "specularexponent"))
940 		{
941 			float exponent;
942 
943 			token = COM_ParseExt(text, qfalse);
944 			if ( token[0] == 0 )
945 			{
946 				ri.Printf( PRINT_WARNING, "WARNING: missing parameter for specular exponent in shader '%s'\n", shader.name );
947 				continue;
948 			}
949 
950 			exponent = atof( token );
951 
952 			if (r_pbr->integer)
953 				stage->specularScale[0] = 1.0f - powf(2.0f / (exponent + 2.0), 0.25);
954 			else
955 			{
956 				// Change shininess to gloss
957 				// Assumes max exponent of 8190 and min of 0, must change here if altered in lightall_fp.glsl
958 				exponent = CLAMP(exponent, 0.0f, 8190.0f);
959 				stage->specularScale[3] = (log2f(exponent + 2.0f) - 1.0f) / 12.0f;
960 			}
961 		}
962 		//
963 		// gloss <value>
964 		//
965 		else if (!Q_stricmp(token, "gloss"))
966 		{
967 			float gloss;
968 
969 			token = COM_ParseExt(text, qfalse);
970 			if ( token[0] == 0 )
971 			{
972 				ri.Printf( PRINT_WARNING, "WARNING: missing parameter for gloss in shader '%s'\n", shader.name );
973 				continue;
974 			}
975 
976 			gloss = atof(token);
977 
978 			if (r_pbr->integer)
979 				stage->specularScale[0] = 1.0f - exp2f(-3.0f * gloss);
980 			else
981 				stage->specularScale[3] = gloss;
982 		}
983 		//
984 		// roughness <value>
985 		//
986 		else if (!Q_stricmp(token, "roughness"))
987 		{
988 			float roughness;
989 
990 			token = COM_ParseExt(text, qfalse);
991 			if (token[0] == 0)
992 			{
993 				ri.Printf(PRINT_WARNING, "WARNING: missing parameter for roughness in shader '%s'\n", shader.name);
994 				continue;
995 			}
996 
997 			roughness = atof(token);
998 
999 			if (r_pbr->integer)
1000 				stage->specularScale[0] = 1.0 - roughness;
1001 			else
1002 			{
1003 				if (roughness >= 0.125)
1004 					stage->specularScale[3] = log2f(1.0f / roughness) / 3.0f;
1005 				else
1006 					stage->specularScale[3] = 1.0f;
1007 			}
1008 		}
1009 		//
1010 		// parallaxDepth <value>
1011 		//
1012 		else if (!Q_stricmp(token, "parallaxdepth"))
1013 		{
1014 			token = COM_ParseExt(text, qfalse);
1015 			if ( token[0] == 0 )
1016 			{
1017 				ri.Printf( PRINT_WARNING, "WARNING: missing parameter for parallaxDepth in shader '%s'\n", shader.name );
1018 				continue;
1019 			}
1020 
1021 			stage->normalScale[3] = atof( token );
1022 		}
1023 		//
1024 		// normalScale <xy>
1025 		// or normalScale <x> <y>
1026 		// or normalScale <x> <y> <height>
1027 		//
1028 		else if (!Q_stricmp(token, "normalscale"))
1029 		{
1030 			token = COM_ParseExt(text, qfalse);
1031 			if ( token[0] == 0 )
1032 			{
1033 				ri.Printf( PRINT_WARNING, "WARNING: missing parameter for normalScale in shader '%s'\n", shader.name );
1034 				continue;
1035 			}
1036 
1037 			stage->normalScale[0] = atof( token );
1038 
1039 			token = COM_ParseExt(text, qfalse);
1040 			if ( token[0] == 0 )
1041 			{
1042 				// one value, applies to X/Y
1043 				stage->normalScale[1] = stage->normalScale[0];
1044 				continue;
1045 			}
1046 
1047 			stage->normalScale[1] = atof( token );
1048 
1049 			token = COM_ParseExt(text, qfalse);
1050 			if ( token[0] == 0 )
1051 			{
1052 				// two values, no height
1053 				continue;
1054 			}
1055 
1056 			stage->normalScale[3] = atof( token );
1057 		}
1058 		//
1059 		// specularScale <rgb> <gloss>
1060 		// or specularScale <metallic> <smoothness> with r_pbr 1
1061 		// or specularScale <r> <g> <b>
1062 		// or specularScale <r> <g> <b> <gloss>
1063 		//
1064 		else if (!Q_stricmp(token, "specularscale"))
1065 		{
1066 			token = COM_ParseExt(text, qfalse);
1067 			if ( token[0] == 0 )
1068 			{
1069 				ri.Printf( PRINT_WARNING, "WARNING: missing parameter for specularScale in shader '%s'\n", shader.name );
1070 				continue;
1071 			}
1072 
1073 			stage->specularScale[0] = atof( token );
1074 
1075 			token = COM_ParseExt(text, qfalse);
1076 			if ( token[0] == 0 )
1077 			{
1078 				ri.Printf( PRINT_WARNING, "WARNING: missing parameter for specularScale in shader '%s'\n", shader.name );
1079 				continue;
1080 			}
1081 
1082 			stage->specularScale[1] = atof( token );
1083 
1084 			token = COM_ParseExt(text, qfalse);
1085 			if ( token[0] == 0 )
1086 			{
1087 				if (r_pbr->integer)
1088 				{
1089 					// two values, metallic then smoothness
1090 					float smoothness = stage->specularScale[1];
1091 					stage->specularScale[1] = (stage->specularScale[0] < 0.5f) ? 0.0f : 1.0f;
1092 					stage->specularScale[0] = smoothness;
1093 				}
1094 				else
1095 				{
1096 					// two values, rgb then gloss
1097 					stage->specularScale[3] = stage->specularScale[1];
1098 					stage->specularScale[1] =
1099 					stage->specularScale[2] = stage->specularScale[0];
1100 				}
1101 				continue;
1102 			}
1103 
1104 			stage->specularScale[2] = atof( token );
1105 
1106 			token = COM_ParseExt(text, qfalse);
1107 			if ( token[0] == 0 )
1108 			{
1109 				// three values, rgb
1110 				continue;
1111 			}
1112 
1113 			stage->specularScale[3] = atof( token );
1114 
1115 		}
1116 		//
1117 		// rgbGen
1118 		//
1119 		else if ( !Q_stricmp( token, "rgbGen" ) ) {
1120 			token = COM_ParseExt( text, qfalse );
1121 			if ( token[0] == 0 ) {
1122 				ri.Printf( PRINT_WARNING, "WARNING: missing parameters for rgbGen in shader '%s'\n", shader.name );
1123 				continue;
1124 			}
1125 
1126 			if ( !Q_stricmp( token, "wave" ) ) {
1127 				ParseWaveForm( text, &stage->rgbWave );
1128 				stage->rgbGen = CGEN_WAVEFORM;
1129 			} else if ( !Q_stricmp( token, "const" ) )    {
1130 				vec3_t color;
1131 
1132 				VectorClear( color );
1133 
1134 				ParseVector( text, 3, color );
1135 				stage->constantColor[0] = 255 * color[0];
1136 				stage->constantColor[1] = 255 * color[1];
1137 				stage->constantColor[2] = 255 * color[2];
1138 
1139 				stage->rgbGen = CGEN_CONST;
1140 			} else if ( !Q_stricmp( token, "identity" ) )    {
1141 				stage->rgbGen = CGEN_IDENTITY;
1142 			} else if ( !Q_stricmp( token, "identityLighting" ) )    {
1143 				stage->rgbGen = CGEN_IDENTITY_LIGHTING;
1144 			} else if ( !Q_stricmp( token, "entity" ) )    {
1145 				stage->rgbGen = CGEN_ENTITY;
1146 			} else if ( !Q_stricmp( token, "oneMinusEntity" ) )    {
1147 				stage->rgbGen = CGEN_ONE_MINUS_ENTITY;
1148 			} else if ( !Q_stricmp( token, "vertex" ) )    {
1149 				stage->rgbGen = CGEN_VERTEX;
1150 				if ( stage->alphaGen == 0 ) {
1151 					stage->alphaGen = AGEN_VERTEX;
1152 				}
1153 			} else if ( !Q_stricmp( token, "exactVertex" ) )    {
1154 				stage->rgbGen = CGEN_EXACT_VERTEX;
1155 			} else if ( !Q_stricmp( token, "vertexLit" ) )	{
1156 				stage->rgbGen = CGEN_VERTEX_LIT;
1157 				if ( stage->alphaGen == 0 ) {
1158 					stage->alphaGen = AGEN_VERTEX;
1159 				}
1160 			} else if ( !Q_stricmp( token, "exactVertexLit" ) )	{
1161 				stage->rgbGen = CGEN_EXACT_VERTEX_LIT;
1162 			} else if ( !Q_stricmp( token, "lightingDiffuse" ) )    {
1163 				stage->rgbGen = CGEN_LIGHTING_DIFFUSE;
1164 			} else if ( !Q_stricmp( token, "oneMinusVertex" ) )    {
1165 				stage->rgbGen = CGEN_ONE_MINUS_VERTEX;
1166 			} else
1167 			{
1168 				ri.Printf( PRINT_WARNING, "WARNING: unknown rgbGen parameter '%s' in shader '%s'\n", token, shader.name );
1169 				continue;
1170 			}
1171 		}
1172 		//
1173 		// alphaGen
1174 		//
1175 		else if ( !Q_stricmp( token, "alphaGen" ) ) {
1176 			token = COM_ParseExt( text, qfalse );
1177 			if ( token[0] == 0 ) {
1178 				ri.Printf( PRINT_WARNING, "WARNING: missing parameters for alphaGen in shader '%s'\n", shader.name );
1179 				continue;
1180 			}
1181 
1182 			if ( !Q_stricmp( token, "wave" ) ) {
1183 				ParseWaveForm( text, &stage->alphaWave );
1184 				stage->alphaGen = AGEN_WAVEFORM;
1185 			} else if ( !Q_stricmp( token, "const" ) )    {
1186 				token = COM_ParseExt( text, qfalse );
1187 				stage->constantColor[3] = 255 * atof( token );
1188 				stage->alphaGen = AGEN_CONST;
1189 			} else if ( !Q_stricmp( token, "identity" ) )    {
1190 				stage->alphaGen = AGEN_IDENTITY;
1191 			} else if ( !Q_stricmp( token, "entity" ) )    {
1192 				stage->alphaGen = AGEN_ENTITY;
1193 			} else if ( !Q_stricmp( token, "oneMinusEntity" ) )    {
1194 				stage->alphaGen = AGEN_ONE_MINUS_ENTITY;
1195 			}
1196 			// Ridah
1197 			else if ( !Q_stricmp( token, "normalzfade" ) ) {
1198 				stage->alphaGen = AGEN_NORMALZFADE;
1199 				token = COM_ParseExt( text, qfalse );
1200 				if ( token[0] ) {
1201 					stage->constantColor[3] = 255 * atof( token );
1202 				} else {
1203 					stage->constantColor[3] = 255;
1204 				}
1205 
1206 				token = COM_ParseExt( text, qfalse );
1207 				if ( token[0] ) {
1208 					stage->zFadeBounds[0] = atof( token );    // lower range
1209 					token = COM_ParseExt( text, qfalse );
1210 					stage->zFadeBounds[1] = atof( token );    // upper range
1211 				} else {
1212 					stage->zFadeBounds[0] = -1.0;   // lower range
1213 					stage->zFadeBounds[1] =  1.0;   // upper range
1214 				}
1215 
1216 			}
1217 			// done.
1218 			else if ( !Q_stricmp( token, "vertex" ) ) {
1219 				stage->alphaGen = AGEN_VERTEX;
1220 			} else if ( !Q_stricmp( token, "lightingSpecular" ) )    {
1221 				stage->alphaGen = AGEN_LIGHTING_SPECULAR;
1222 			} else if ( !Q_stricmp( token, "oneMinusVertex" ) )    {
1223 				stage->alphaGen = AGEN_ONE_MINUS_VERTEX;
1224 			} else if ( !Q_stricmp( token, "portal" ) )    {
1225 				stage->alphaGen = AGEN_PORTAL;
1226 				token = COM_ParseExt( text, qfalse );
1227 				if ( token[0] == 0 ) {
1228 					shader.portalRange = 256;
1229 					ri.Printf( PRINT_WARNING, "WARNING: missing range parameter for alphaGen portal in shader '%s', defaulting to 256\n", shader.name );
1230 				}
1231 				else
1232 				{
1233 					shader.portalRange = atof( token );
1234 				}
1235 			}
1236 			else
1237 			{
1238 				ri.Printf( PRINT_WARNING, "WARNING: unknown alphaGen parameter '%s' in shader '%s'\n", token, shader.name );
1239 				continue;
1240 			}
1241 		}
1242 		//
1243 		// tcGen <function>
1244 		//
1245 		else if ( !Q_stricmp( token, "texgen" ) || !Q_stricmp( token, "tcGen" ) ) {
1246 			token = COM_ParseExt( text, qfalse );
1247 			if ( token[0] == 0 ) {
1248 				ri.Printf( PRINT_WARNING, "WARNING: missing texgen parm in shader '%s'\n", shader.name );
1249 				continue;
1250 			}
1251 
1252 			if ( !Q_stricmp( token, "environment" ) ) {
1253 				stage->bundle[0].tcGen = TCGEN_ENVIRONMENT_MAPPED;
1254 			} else if ( !Q_stricmp( token, "firerisenv" ) )    {
1255 				stage->bundle[0].tcGen = TCGEN_FIRERISEENV_MAPPED;
1256 			} else if ( !Q_stricmp( token, "lightmap" ) )    {
1257 				stage->bundle[0].tcGen = TCGEN_LIGHTMAP;
1258 			} else if ( !Q_stricmp( token, "texture" ) || !Q_stricmp( token, "base" ) )     {
1259 				stage->bundle[0].tcGen = TCGEN_TEXTURE;
1260 			} else if ( !Q_stricmp( token, "vector" ) )    {
1261 				ParseVector( text, 3, stage->bundle[0].tcGenVectors[0] );
1262 				ParseVector( text, 3, stage->bundle[0].tcGenVectors[1] );
1263 
1264 				stage->bundle[0].tcGen = TCGEN_VECTOR;
1265 			} else
1266 			{
1267 				ri.Printf( PRINT_WARNING, "WARNING: unknown texgen parm in shader '%s'\n", shader.name );
1268 			}
1269 		}
1270 		//
1271 		// tcMod <type> <...>
1272 		//
1273 		else if ( !Q_stricmp( token, "tcMod" ) ) {
1274 			char buffer[1024] = "";
1275 
1276 			while ( 1 )
1277 			{
1278 				token = COM_ParseExt( text, qfalse );
1279 				if ( token[0] == 0 ) {
1280 					break;
1281 				}
1282 				Q_strcat( buffer, sizeof (buffer), token );
1283 				Q_strcat( buffer, sizeof (buffer), " " );
1284 			}
1285 
1286 			ParseTexMod( buffer, stage );
1287 
1288 			continue;
1289 		}
1290 		//
1291 		// depthmask
1292 		//
1293 		else if ( !Q_stricmp( token, "depthwrite" ) ) {
1294 			depthMaskBits = GLS_DEPTHMASK_TRUE;
1295 			depthMaskExplicit = qtrue;
1296 
1297 			continue;
1298 		} else
1299 		{
1300 			ri.Printf( PRINT_WARNING, "WARNING: unknown parameter '%s' in shader '%s'\n", token, shader.name );
1301 			return qfalse;
1302 		}
1303 	}
1304 
1305 	//
1306 	// if cgen isn't explicitly specified, use either identity or identitylighting
1307 	//
1308 	if ( stage->rgbGen == CGEN_BAD ) {
1309 		if ( blendSrcBits == 0 ||
1310 			 blendSrcBits == GLS_SRCBLEND_ONE ||
1311 			 blendSrcBits == GLS_SRCBLEND_SRC_ALPHA ) {
1312 			stage->rgbGen = CGEN_IDENTITY_LIGHTING;
1313 		} else {
1314 			stage->rgbGen = CGEN_IDENTITY;
1315 		}
1316 	}
1317 
1318 
1319 	//
1320 	// implicitly assume that a GL_ONE GL_ZERO blend mask disables blending
1321 	//
1322 	if ( ( blendSrcBits == GLS_SRCBLEND_ONE ) &&
1323 		 ( blendDstBits == GLS_DSTBLEND_ZERO ) ) {
1324 		blendDstBits = blendSrcBits = 0;
1325 		depthMaskBits = GLS_DEPTHMASK_TRUE;
1326 	}
1327 
1328 	// decide which agens we can skip
1329 	if ( stage->alphaGen == AGEN_IDENTITY ) {
1330 		if ( stage->rgbGen == CGEN_IDENTITY
1331 			 || stage->rgbGen == CGEN_LIGHTING_DIFFUSE ) {
1332 			stage->alphaGen = AGEN_SKIP;
1333 		}
1334 	}
1335 
1336 	//
1337 	// compute state bits
1338 	//
1339 	stage->stateBits = depthMaskBits |
1340 					   blendSrcBits | blendDstBits |
1341 					   atestBits |
1342 					   depthFuncBits;
1343 
1344 	return qtrue;
1345 }
1346 
1347 /*
1348 ===============
1349 ParseDeform
1350 
1351 deformVertexes wave <spread> <waveform> <base> <amplitude> <phase> <frequency>
1352 deformVertexes normal <frequency> <amplitude>
1353 deformVertexes move <vector> <waveform> <base> <amplitude> <phase> <frequency>
1354 deformVertexes bulge <bulgeWidth> <bulgeHeight> <bulgeSpeed>
1355 deformVertexes projectionShadow
1356 deformVertexes autoSprite
1357 deformVertexes autoSprite2
1358 deformVertexes text[0-7]
1359 ===============
1360 */
ParseDeform(char ** text)1361 static void ParseDeform( char **text ) {
1362 	char    *token;
1363 	deformStage_t   *ds;
1364 
1365 	token = COM_ParseExt( text, qfalse );
1366 	if ( token[0] == 0 ) {
1367 		ri.Printf( PRINT_WARNING, "WARNING: missing deform parm in shader '%s'\n", shader.name );
1368 		return;
1369 	}
1370 
1371 	if ( shader.numDeforms == MAX_SHADER_DEFORMS ) {
1372 		ri.Printf( PRINT_WARNING, "WARNING: MAX_SHADER_DEFORMS in '%s'\n", shader.name );
1373 		return;
1374 	}
1375 
1376 	ds = &shader.deforms[ shader.numDeforms ];
1377 	shader.numDeforms++;
1378 
1379 	if ( !Q_stricmp( token, "projectionShadow" ) ) {
1380 		ds->deformation = DEFORM_PROJECTION_SHADOW;
1381 		return;
1382 	}
1383 
1384 	if ( !Q_stricmp( token, "autosprite" ) ) {
1385 		ds->deformation = DEFORM_AUTOSPRITE;
1386 		return;
1387 	}
1388 
1389 	if ( !Q_stricmp( token, "autosprite2" ) ) {
1390 		ds->deformation = DEFORM_AUTOSPRITE2;
1391 		return;
1392 	}
1393 
1394 	if ( !Q_stricmpn( token, "text", 4 ) ) {
1395 		int n;
1396 
1397 		n = token[4] - '0';
1398 		if ( n < 0 || n > 7 ) {
1399 			n = 0;
1400 		}
1401 		ds->deformation = DEFORM_TEXT0 + n;
1402 		return;
1403 	}
1404 
1405 	if ( !Q_stricmp( token, "bulge" ) ) {
1406 		token = COM_ParseExt( text, qfalse );
1407 		if ( token[0] == 0 ) {
1408 			ri.Printf( PRINT_WARNING, "WARNING: missing deformVertexes bulge parm in shader '%s'\n", shader.name );
1409 			return;
1410 		}
1411 		ds->bulgeWidth = atof( token );
1412 
1413 		token = COM_ParseExt( text, qfalse );
1414 		if ( token[0] == 0 ) {
1415 			ri.Printf( PRINT_WARNING, "WARNING: missing deformVertexes bulge parm in shader '%s'\n", shader.name );
1416 			return;
1417 		}
1418 		ds->bulgeHeight = atof( token );
1419 
1420 		token = COM_ParseExt( text, qfalse );
1421 		if ( token[0] == 0 ) {
1422 			ri.Printf( PRINT_WARNING, "WARNING: missing deformVertexes bulge parm in shader '%s'\n", shader.name );
1423 			return;
1424 		}
1425 		ds->bulgeSpeed = atof( token );
1426 
1427 		ds->deformation = DEFORM_BULGE;
1428 		return;
1429 	}
1430 
1431 	if ( !Q_stricmp( token, "wave" ) ) {
1432 		token = COM_ParseExt( text, qfalse );
1433 		if ( token[0] == 0 ) {
1434 			ri.Printf( PRINT_WARNING, "WARNING: missing deformVertexes parm in shader '%s'\n", shader.name );
1435 			return;
1436 		}
1437 
1438 		if ( atof( token ) != 0 ) {
1439 			ds->deformationSpread = 1.0f / atof( token );
1440 		} else
1441 		{
1442 			ds->deformationSpread = 100.0f;
1443 			ri.Printf( PRINT_WARNING, "WARNING: illegal div value of 0 in deformVertexes command for shader '%s'\n", shader.name );
1444 		}
1445 
1446 		ParseWaveForm( text, &ds->deformationWave );
1447 		ds->deformation = DEFORM_WAVE;
1448 		return;
1449 	}
1450 
1451 	if ( !Q_stricmp( token, "normal" ) ) {
1452 		token = COM_ParseExt( text, qfalse );
1453 		if ( token[0] == 0 ) {
1454 			ri.Printf( PRINT_WARNING, "WARNING: missing deformVertexes parm in shader '%s'\n", shader.name );
1455 			return;
1456 		}
1457 		ds->deformationWave.amplitude = atof( token );
1458 
1459 		token = COM_ParseExt( text, qfalse );
1460 		if ( token[0] == 0 ) {
1461 			ri.Printf( PRINT_WARNING, "WARNING: missing deformVertexes parm in shader '%s'\n", shader.name );
1462 			return;
1463 		}
1464 		ds->deformationWave.frequency = atof( token );
1465 
1466 		ds->deformation = DEFORM_NORMALS;
1467 		return;
1468 	}
1469 
1470 	if ( !Q_stricmp( token, "move" ) ) {
1471 		int i;
1472 
1473 		for ( i = 0 ; i < 3 ; i++ ) {
1474 			token = COM_ParseExt( text, qfalse );
1475 			if ( token[0] == 0 ) {
1476 				ri.Printf( PRINT_WARNING, "WARNING: missing deformVertexes parm in shader '%s'\n", shader.name );
1477 				return;
1478 			}
1479 			ds->moveVector[i] = atof( token );
1480 		}
1481 
1482 		ParseWaveForm( text, &ds->deformationWave );
1483 		ds->deformation = DEFORM_MOVE;
1484 		return;
1485 	}
1486 
1487 	ri.Printf( PRINT_WARNING, "WARNING: unknown deformVertexes subtype '%s' found in shader '%s'\n", token, shader.name );
1488 }
1489 
1490 
1491 /*
1492 ===============
1493 ParseSkyParms
1494 
1495 skyParms <outerbox> <cloudheight> <innerbox>
1496 ===============
1497 */
ParseSkyParms(char ** text)1498 static void ParseSkyParms( char **text ) {
1499 	char        *token;
1500 	static char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
1501 	char pathname[MAX_QPATH];
1502 	int i;
1503 	imgFlags_t imgFlags = IMGFLAG_MIPMAP | IMGFLAG_PICMIP;
1504 
1505 	// outerbox
1506 	token = COM_ParseExt( text, qfalse );
1507 	if ( token[0] == 0 ) {
1508 		ri.Printf( PRINT_WARNING, "WARNING: 'skyParms' missing parameter in shader '%s'\n", shader.name );
1509 		return;
1510 	}
1511 	if ( strcmp( token, "-" ) ) {
1512 		for ( i = 0 ; i < 6 ; i++ ) {
1513 			Com_sprintf( pathname, sizeof( pathname ), "%s_%s.tga"
1514 						 , token, suf[i] );
1515 			shader.sky.outerbox[i] = R_FindImageFile( ( char * ) pathname, IMGTYPE_COLORALPHA, imgFlags | IMGFLAG_CLAMPTOEDGE );
1516 			if ( !shader.sky.outerbox[i] ) {
1517 				shader.sky.outerbox[i] = tr.defaultImage;
1518 			}
1519 		}
1520 	}
1521 
1522 	// cloudheight
1523 	token = COM_ParseExt( text, qfalse );
1524 	if ( token[0] == 0 ) {
1525 		ri.Printf( PRINT_WARNING, "WARNING: 'skyParms' missing parameter in shader '%s'\n", shader.name );
1526 		return;
1527 	}
1528 	shader.sky.cloudHeight = atof( token );
1529 	if ( !shader.sky.cloudHeight ) {
1530 		shader.sky.cloudHeight = 512;
1531 	}
1532 	R_InitSkyTexCoords( shader.sky.cloudHeight );
1533 
1534 
1535 	// innerbox
1536 	token = COM_ParseExt( text, qfalse );
1537 	if ( token[0] == 0 ) {
1538 		ri.Printf( PRINT_WARNING, "WARNING: 'skyParms' missing parameter in shader '%s'\n", shader.name );
1539 		return;
1540 	}
1541 	if ( strcmp( token, "-" ) ) {
1542 		for ( i = 0 ; i < 6 ; i++ ) {
1543 			Com_sprintf( pathname, sizeof( pathname ), "%s_%s.tga"
1544 						 , token, suf[i] );
1545 			shader.sky.innerbox[i] = R_FindImageFile( ( char * ) pathname, IMGTYPE_COLORALPHA, imgFlags );
1546 			if ( !shader.sky.innerbox[i] ) {
1547 				shader.sky.innerbox[i] = tr.defaultImage;
1548 			}
1549 		}
1550 	}
1551 
1552 	shader.isSky = qtrue;
1553 }
1554 
1555 
1556 /*
1557 =================
1558 ParseSort
1559 =================
1560 */
ParseSort(char ** text)1561 void ParseSort( char **text ) {
1562 	char    *token;
1563 
1564 	token = COM_ParseExt( text, qfalse );
1565 	if ( token[0] == 0 ) {
1566 		ri.Printf( PRINT_WARNING, "WARNING: missing sort parameter in shader '%s'\n", shader.name );
1567 		return;
1568 	}
1569 
1570 	if ( !Q_stricmp( token, "portal" ) ) {
1571 		shader.sort = SS_PORTAL;
1572 	} else if ( !Q_stricmp( token, "sky" ) ) {
1573 		shader.sort = SS_ENVIRONMENT;
1574 	} else if ( !Q_stricmp( token, "opaque" ) ) {
1575 		shader.sort = SS_OPAQUE;
1576 	} else if ( !Q_stricmp( token, "decal" ) )   {
1577 		shader.sort = SS_DECAL;
1578 	} else if ( !Q_stricmp( token, "seeThrough" ) ) {
1579 		shader.sort = SS_SEE_THROUGH;
1580 	} else if ( !Q_stricmp( token, "banner" ) ) {
1581 		shader.sort = SS_BANNER;
1582 	} else if ( !Q_stricmp( token, "additive" ) ) {
1583 		shader.sort = SS_BLEND1;
1584 	} else if ( !Q_stricmp( token, "nearest" ) ) {
1585 		shader.sort = SS_NEAREST;
1586 	} else if ( !Q_stricmp( token, "underwater" ) ) {
1587 		shader.sort = SS_UNDERWATER;
1588 	} else {
1589 		shader.sort = atof( token );
1590 	}
1591 }
1592 
1593 
1594 
1595 // this table is also present in q3map
1596 
1597 typedef struct {
1598 	char    *name;
1599 	int clearSolid, surfaceFlags, contents;
1600 } infoParm_t;
1601 
1602 infoParm_t infoParms[] = {
1603 	// server relevant contents
1604 
1605 //----(SA)	modified
1606 	{"clipmissile",  1,  0, CONTENTS_MISSILECLIP},       // impact only specific weapons (rl, gl)
1607 //----(SA)	end
1608 
1609 // RF, AI sight
1610 	{"ai_nosight",   1,  0,  CONTENTS_AI_NOSIGHT},
1611 	{"clipshot", 1,  0,  CONTENTS_CLIPSHOT},         // stops bullets
1612 // RF, end
1613 
1614 	{"water",        1,  0,  CONTENTS_WATER },
1615 	{"slag",     1,  0,  CONTENTS_SLIME },       // uses the CONTENTS_SLIME flag, but the shader reference is changed to 'slag'
1616 	// to idendify that this doesn't work the same as 'slime' did.
1617 	// (slime hurts instantly, slag doesn't)
1618 //	{"slime",		1,	0,	CONTENTS_SLIME },		// mildly damaging
1619 	{"lava",     1,  0,  CONTENTS_LAVA },        // very damaging
1620 	{"playerclip",   1,  0,  CONTENTS_PLAYERCLIP },
1621 	{"monsterclip",  1,  0,  CONTENTS_MONSTERCLIP },
1622 	{"nodrop",       1,  0,  CONTENTS_NODROP },      // don't drop items or leave bodies (death fog, lava, etc)
1623 	{"nonsolid", 1,  SURF_NONSOLID,  0},                     // clears the solid flag
1624 
1625 	// utility relevant attributes
1626 	{"origin",       1,  0,  CONTENTS_ORIGIN },      // center of rotating brushes
1627 	{"trans",        0,  0,  CONTENTS_TRANSLUCENT }, // don't eat contained surfaces
1628 	{"detail",       0,  0,  CONTENTS_DETAIL },      // don't include in structural bsp
1629 	{"structural",   0,  0,  CONTENTS_STRUCTURAL },  // force into structural bsp even if trnas
1630 	{"areaportal",   1,  0,  CONTENTS_AREAPORTAL },  // divides areas
1631 	{"clusterportal", 1,0,  CONTENTS_CLUSTERPORTAL },    // for bots
1632 	{"donotenter",  1,  0,  CONTENTS_DONOTENTER },       // for bots
1633 
1634 	// Rafael - nopass
1635 	{"donotenterlarge", 1, 0,    CONTENTS_DONOTENTER_LARGE }, // for larger bots
1636 
1637 	{"fog",          1,  0,  CONTENTS_FOG},          // carves surfaces entering
1638 	{"sky",          0,  SURF_SKY,       0 },        // emit light from an environment map
1639 	{"lightfilter",  0,  SURF_LIGHTFILTER, 0 },      // filter light going through it
1640 	{"alphashadow",  0,  SURF_ALPHASHADOW, 0 },      // test light on a per-pixel basis
1641 	{"hint",     0,  SURF_HINT,      0 },        // use as a primary splitter
1642 
1643 	// server attributes
1644 	{"slick",            0,  SURF_SLICK,     0 },
1645 	{"noimpact",     0,  SURF_NOIMPACT,  0 },        // don't make impact explosions or marks
1646 	{"nomarks",          0,  SURF_NOMARKS,   0 },        // don't make impact marks, but still explode
1647 	{"ladder",           0,  SURF_LADDER,    0 },
1648 	{"nodamage",     0,  SURF_NODAMAGE,  0 },
1649 
1650 	{"monsterslick", 0,  SURF_MONSTERSLICK,  0},     // surf only slick for monsters
1651 
1652 //	{"flesh",		0,	SURF_FLESH,		0 },
1653 	{"glass",        0,  SURF_GLASS,     0 },    //----(SA)	added
1654 	{"ceramic",      0,  SURF_CERAMIC,   0 },    //----(SA)	added
1655 
1656 	// steps
1657 	{"metal",        0,  SURF_METAL,     0 },
1658 	{"metalsteps",   0,  SURF_METAL,     0 },    // retain bw compatibility with Q3A metal shaders... (SA)
1659 	{"nosteps",      0,  SURF_NOSTEPS,   0 },
1660 	{"woodsteps",    0,  SURF_WOOD,      0 },
1661 	{"grasssteps",   0,  SURF_GRASS,     0 },
1662 	{"gravelsteps",  0,  SURF_GRAVEL,    0 },
1663 	{"carpetsteps",  0,  SURF_CARPET,    0 },
1664 	{"snowsteps",    0,  SURF_SNOW,      0 },
1665 	{"roofsteps",    0,  SURF_ROOF,      0 },    // tile roof
1666 
1667 	{"rubble", 0, SURF_RUBBLE, 0 },
1668 
1669 	// drawsurf attributes
1670 	{"nodraw",       0,  SURF_NODRAW,    0 },    // don't generate a drawsurface (or a lightmap)
1671 	{"pointlight",   0,  SURF_POINTLIGHT, 0 },   // sample lighting at vertexes
1672 	{"nolightmap",   0,  SURF_NOLIGHTMAP,0 },        // don't generate a lightmap
1673 	{"nodlight", 0,  SURF_NODLIGHT, 0 },     // don't ever add dynamic lights
1674 
1675 	{"monsterslicknorth",    0, SURF_MONSLICK_N,0},
1676 	{"monsterslickeast", 0, SURF_MONSLICK_E,0},
1677 	{"monsterslicksouth",    0, SURF_MONSLICK_S,0},
1678 	{"monsterslickwest", 0, SURF_MONSLICK_W,0}
1679 
1680 };
1681 
1682 
1683 /*
1684 ===============
1685 ParseSurfaceParm
1686 
1687 surfaceparm <name>
1688 ===============
1689 */
ParseSurfaceParm(char ** text)1690 static void ParseSurfaceParm( char **text ) {
1691 	char    *token;
1692 	int numInfoParms = ARRAY_LEN( infoParms );
1693 	int i;
1694 
1695 	token = COM_ParseExt( text, qfalse );
1696 	for ( i = 0 ; i < numInfoParms ; i++ ) {
1697 		if ( !Q_stricmp( token, infoParms[i].name ) ) {
1698 			shader.surfaceFlags |= infoParms[i].surfaceFlags;
1699 			shader.contentFlags |= infoParms[i].contents;
1700 #if 0
1701 			if ( infoParms[i].clearSolid ) {
1702 				si->contents &= ~CONTENTS_SOLID;
1703 			}
1704 #endif
1705 			break;
1706 		}
1707 	}
1708 }
1709 
1710 /*
1711 =================
1712 ParseShader
1713 
1714 The current text pointer is at the explicit text definition of the
1715 shader.  Parse it into the global shader variable.  Later functions
1716 will optimize it.
1717 =================
1718 */
ParseShader(char ** text)1719 static qboolean ParseShader( char **text ) {
1720 	char *token;
1721 	int s;
1722 
1723 	s = 0;
1724 
1725 	token = COM_ParseExt( text, qtrue );
1726 	if ( token[0] != '{' ) {
1727 		ri.Printf( PRINT_WARNING, "WARNING: expecting '{', found '%s' instead in shader '%s'\n", token, shader.name );
1728 		return qfalse;
1729 	}
1730 
1731 	while ( 1 )
1732 	{
1733 		token = COM_ParseExt( text, qtrue );
1734 		if ( !token[0] ) {
1735 			ri.Printf( PRINT_WARNING, "WARNING: no concluding '}' in shader %s\n", shader.name );
1736 			return qfalse;
1737 		}
1738 
1739 		// end of shader definition
1740 		if ( token[0] == '}' ) {
1741 			break;
1742 		}
1743 		// stage definition
1744 		else if ( token[0] == '{' ) {
1745 			if ( s >= MAX_SHADER_STAGES ) {
1746 				ri.Printf( PRINT_WARNING, "WARNING: too many stages in shader %s (max is %i)\n", shader.name, MAX_SHADER_STAGES );
1747 				return qfalse;
1748 			}
1749 
1750 			if ( !ParseStage( &stages[s], text ) ) {
1751 				return qfalse;
1752 			}
1753 			stages[s].active = qtrue;
1754 			s++;
1755 			continue;
1756 		}
1757 		// skip stuff that only the QuakeEdRadient needs
1758 		else if ( !Q_stricmpn( token, "qer", 3 ) ) {
1759 			SkipRestOfLine( text );
1760 			continue;
1761 		}
1762 		// sun parms
1763 		else if ( !Q_stricmp( token, "q3map_sun" ) || !Q_stricmp( token, "q3map_sunExt" ) || !Q_stricmp( token, "q3gl2_sun" ) ) {
1764 			float a, b;
1765 			qboolean isGL2Sun = qfalse;
1766 
1767 			if (!Q_stricmp( token, "q3gl2_sun" ) && r_sunShadows->integer )
1768 			{
1769 				isGL2Sun = qtrue;
1770 				tr.sunShadows = qtrue;
1771 			}
1772 
1773 			token = COM_ParseExt( text, qfalse );
1774 			tr.sunLight[0] = atof( token );
1775 			token = COM_ParseExt( text, qfalse );
1776 			tr.sunLight[1] = atof( token );
1777 			token = COM_ParseExt( text, qfalse );
1778 			tr.sunLight[2] = atof( token );
1779 
1780 			VectorNormalize( tr.sunLight );
1781 
1782 			token = COM_ParseExt( text, qfalse );
1783 			a = atof( token );
1784 			VectorScale( tr.sunLight, a, tr.sunLight );
1785 
1786 			token = COM_ParseExt( text, qfalse );
1787 			a = atof( token );
1788 			a = a / 180 * M_PI;
1789 
1790 			token = COM_ParseExt( text, qfalse );
1791 			b = atof( token );
1792 			b = b / 180 * M_PI;
1793 
1794 			tr.sunDirection[0] = cos( a ) * cos( b );
1795 			tr.sunDirection[1] = sin( a ) * cos( b );
1796 			tr.sunDirection[2] = sin( b );
1797 
1798 			if (isGL2Sun)
1799 			{
1800 				token = COM_ParseExt( text, qfalse );
1801 				tr.sunShadowScale = atof(token);
1802 
1803 				// parse twice, since older shaders may include mapLightScale before sunShadowScale
1804 				token = COM_ParseExt( text, qfalse );
1805 				if (token[0])
1806 					tr.sunShadowScale = atof(token);
1807 			}
1808 
1809 			SkipRestOfLine( text );
1810 			continue;
1811 		}
1812 		// tonemap parms
1813 		else if ( !Q_stricmp( token, "q3gl2_tonemap" ) ) {
1814 			token = COM_ParseExt( text, qfalse );
1815 			tr.toneMinAvgMaxLevel[0] = atof( token );
1816 			token = COM_ParseExt( text, qfalse );
1817 			tr.toneMinAvgMaxLevel[1] = atof( token );
1818 			token = COM_ParseExt( text, qfalse );
1819 			tr.toneMinAvgMaxLevel[2] = atof( token );
1820 
1821 			token = COM_ParseExt( text, qfalse );
1822 			tr.autoExposureMinMax[0] = atof( token );
1823 			token = COM_ParseExt( text, qfalse );
1824 			tr.autoExposureMinMax[1] = atof( token );
1825 
1826 			SkipRestOfLine( text );
1827 			continue;
1828 		} else if ( !Q_stricmp( token, "deformVertexes" ) )    {
1829 			ParseDeform( text );
1830 			continue;
1831 		} else if ( !Q_stricmp( token, "tesssize" ) )    {
1832 			SkipRestOfLine( text );
1833 			continue;
1834 		} else if ( !Q_stricmp( token, "clampTime" ) )    {
1835 			token = COM_ParseExt( text, qfalse );
1836 			if ( token[0] ) {
1837 				shader.clampTime = atof( token );
1838 			}
1839 		}
1840 		// skip stuff that only the q3map needs
1841 		else if ( !Q_stricmpn( token, "q3map", 5 ) ) {
1842 			SkipRestOfLine( text );
1843 			continue;
1844 		}
1845 		// skip stuff that only q3map or the server needs
1846 		else if ( !Q_stricmp( token, "surfaceParm" ) ) {
1847 			ParseSurfaceParm( text );
1848 			continue;
1849 		}
1850 		// no mip maps
1851 		else if ( !Q_stricmp( token, "nomipmaps" ) ) {
1852 			shader.noMipMaps = qtrue;
1853 			shader.noPicMip = qtrue;
1854 			continue;
1855 		}
1856 		// no picmip adjustment
1857 		else if ( !Q_stricmp( token, "nopicmip" ) ) {
1858 			shader.noPicMip = qtrue;
1859 			continue;
1860 		}
1861 		// character picmip adjustment
1862 		else if ( !Q_stricmp( token, "picmip2" ) ) {
1863 			shader.characterMip = qtrue;
1864 			continue;
1865 		}
1866 		// polygonOffset
1867 		else if ( !Q_stricmp( token, "polygonOffset" ) ) {
1868 			shader.polygonOffset = qtrue;
1869 			continue;
1870 		}
1871 		// entityMergable, allowing sprite surfaces from multiple entities
1872 		// to be merged into one batch.  This is a savings for smoke
1873 		// puffs and blood, but can't be used for anything where the
1874 		// shader calcs (not the surface function) reference the entity color or scroll
1875 		else if ( !Q_stricmp( token, "entityMergable" ) ) {
1876 			shader.entityMergable = qtrue;
1877 			continue;
1878 		}
1879 		// fogParms
1880 		else if ( !Q_stricmp( token, "fogParms" ) ) {
1881 			if ( !ParseVector( text, 3, shader.fogParms.color ) ) {
1882 				return qfalse;
1883 			}
1884 
1885 			if ( r_greyscale->integer )
1886 			{
1887 				float luminance;
1888 
1889 				luminance = LUMA( shader.fogParms.color[0], shader.fogParms.color[1], shader.fogParms.color[2] );
1890 				VectorSet( shader.fogParms.color, luminance, luminance, luminance );
1891 			}
1892 			else if ( r_greyscale->value )
1893 			{
1894 				float luminance;
1895 
1896 				luminance = LUMA( shader.fogParms.color[0], shader.fogParms.color[1], shader.fogParms.color[2] );
1897 				shader.fogParms.color[0] = LERP( shader.fogParms.color[0], luminance, r_greyscale->value );
1898 				shader.fogParms.color[1] = LERP( shader.fogParms.color[1], luminance, r_greyscale->value );
1899 				shader.fogParms.color[2] = LERP( shader.fogParms.color[2], luminance, r_greyscale->value );
1900 			}
1901 
1902 			token = COM_ParseExt( text, qfalse );
1903 			if ( !token[0] ) {
1904 				ri.Printf( PRINT_WARNING, "WARNING: missing parm for 'fogParms' keyword in shader '%s'\n", shader.name );
1905 				continue;
1906 			}
1907 			shader.fogParms.depthForOpaque = atof( token );
1908 
1909 			// skip any old gradient directions
1910 			SkipRestOfLine( text );
1911 			continue;
1912 		}
1913 		// portal
1914 		else if ( !Q_stricmp( token, "portal" ) ) {
1915 			shader.sort = SS_PORTAL;
1916 			shader.isPortal = qtrue;
1917 			continue;
1918 		}
1919 		// skyparms <cloudheight> <outerbox> <innerbox>
1920 		else if ( !Q_stricmp( token, "skyparms" ) ) {
1921 			ParseSkyParms( text );
1922 			continue;
1923 		}
1924 		// This is fixed fog for the skybox/clouds determined solely by the shader
1925 		// it will not change in a level and will not be necessary
1926 		// to force clients to use a sky fog the server says to.
1927 		// skyfogvars <(r,g,b)> <dist>
1928 		else if ( !Q_stricmp( token, "skyfogvars" ) ) {
1929 			vec3_t fogColor;
1930 
1931 			if ( !ParseVector( text, 3, fogColor ) ) {
1932 				return qfalse;
1933 			}
1934 			token = COM_ParseExt( text, qfalse );
1935 
1936 			if ( !token[0] ) {
1937 				ri.Printf( PRINT_WARNING, "WARNING: missing density value for sky fog\n" );
1938 				continue;
1939 			}
1940 
1941 			if ( atof( token ) > 1 ) {
1942 				ri.Printf( PRINT_WARNING, "WARNING: last value for skyfogvars is 'density' which needs to be 0.0-1.0\n" );
1943 				continue;
1944 			}
1945 
1946 			R_SetFog( FOG_SKY, 0, 5, fogColor[0], fogColor[1], fogColor[2], atof( token ) );
1947 			continue;
1948 		} else if ( !Q_stricmp( token, "sunshader" ) )        {
1949 			token = COM_ParseExt( text, qfalse );
1950 			if ( !token[0] ) {
1951 				ri.Printf( PRINT_WARNING, "WARNING: missing shader name for 'sunshader'\n" );
1952 				continue;
1953 			}
1954 //			tr.sunShaderName = CopyString( token );
1955 			tr.sunShaderName = "sun";
1956 		}
1957 //----(SA)	added
1958 		else if ( !Q_stricmp( token, "lightgridmulamb" ) ) { // ambient multiplier for lightgrid
1959 			token = COM_ParseExt( text, qfalse );
1960 			if ( !token[0] ) {
1961 				ri.Printf( PRINT_WARNING, "WARNING: missing value for 'lightgrid ambient multiplier'\n" );
1962 				continue;
1963 			}
1964 			if ( atof( token ) > 0 ) {
1965 				tr.lightGridMulAmbient = atof( token );
1966 			}
1967 		} else if ( !Q_stricmp( token, "lightgridmuldir" ) )        { // directional multiplier for lightgrid
1968 			token = COM_ParseExt( text, qfalse );
1969 			if ( !token[0] ) {
1970 				ri.Printf( PRINT_WARNING, "WARNING: missing value for 'lightgrid directional multiplier'\n" );
1971 				continue;
1972 			}
1973 			if ( atof( token ) > 0 ) {
1974 				tr.lightGridMulDirected = atof( token );
1975 			}
1976 		}
1977 //----(SA)	end
1978 		else if ( !Q_stricmp( token, "waterfogvars" ) ) {
1979 			vec3_t watercolor;
1980 			float fogvar;
1981 			char fogString[64];
1982 
1983 			if ( !ParseVector( text, 3, watercolor ) ) {
1984 				return qfalse;
1985 			}
1986 			token = COM_ParseExt( text, qfalse );
1987 
1988 			if ( !token[0] ) {
1989 				ri.Printf( PRINT_WARNING, "WARNING: missing density/distance value for water fog\n" );
1990 				continue;
1991 			}
1992 
1993 			fogvar = atof( token );
1994 
1995 			//----(SA)	right now allow one water color per map.  I'm sure this will need
1996 			//			to change at some point, but I'm not sure how to track fog parameters
1997 			//			on a "per-water volume" basis yet.
1998 
1999 			if ( fogvar == 0 ) {       // '0' specifies "use the map values for everything except the fog color
2000 				// TODO
2001 			} else if ( fogvar > 1 )      { // distance "linear" fog
2002 				Com_sprintf( fogString, sizeof( fogString ), "0 %d 1.1 %f %f %f 200", (int)fogvar, watercolor[0], watercolor[1], watercolor[2] );
2003 //				R_SetFog(FOG_WATER, 0, fogvar, watercolor[0], watercolor[1], watercolor[2], 1.1);
2004 			} else {                      // density "exp" fog
2005 				Com_sprintf( fogString, sizeof( fogString ), "0 5 %f %f %f %f 200", fogvar, watercolor[0], watercolor[1], watercolor[2] );
2006 //				R_SetFog(FOG_WATER, 0, 5, watercolor[0], watercolor[1], watercolor[2], fogvar);
2007 			}
2008 
2009 //		near
2010 //		far
2011 //		density
2012 //		r,g,b
2013 //		time to complete
2014 			ri.Cvar_Set( "r_waterFogColor", fogString );
2015 
2016 			continue;
2017 		}
2018 		// fogvars
2019 		else if ( !Q_stricmp( token, "fogvars" ) ) {
2020 			vec3_t fogColor;
2021 			float fogDensity;
2022 			int fogFar;
2023 
2024 			if ( !ParseVector( text, 3, fogColor ) ) {
2025 				return qfalse;
2026 			}
2027 
2028 			token = COM_ParseExt( text, qfalse );
2029 			if ( !token[0] ) {
2030 				ri.Printf( PRINT_WARNING, "WARNING: missing density value for the fog\n" );
2031 				continue;
2032 			}
2033 
2034 
2035 			//----(SA)	NOTE:	fogFar > 1 means the shader is setting the farclip, < 1 means setting
2036 			//					density (so old maps or maps that just need softening fog don't have to care about farclip)
2037 
2038 			fogDensity = atof( token );
2039 			if ( fogDensity >= 1 ) { // linear
2040 				fogFar      = fogDensity;
2041 			} else {
2042 				fogFar      = 5;
2043 			}
2044 
2045 //			R_SetFog(FOG_MAP, 0, fogFar, fogColor[0], fogColor[1], fogColor[2], fogDensity);
2046 			ri.Cvar_Set( "r_mapFogColor", va( "0 %d %f %f %f %f 0", fogFar, fogDensity, fogColor[0], fogColor[1], fogColor[2] ) );
2047 //			R_SetFog(FOG_CMD_SWITCHFOG, FOG_MAP, 50, 0, 0, 0, 0);
2048 
2049 			continue;
2050 		}
2051 		// done.
2052 		// Ridah, allow disable fog for some shaders
2053 		else if ( !Q_stricmp( token, "nofog" ) ) {
2054 			shader.noFog = qtrue;
2055 			continue;
2056 		}
2057 		// done.
2058 		// RF, allow each shader to permit compression if available
2059 		else if ( !Q_stricmp( token, "allowcompress" ) ) {
2060 			tr.allowCompress = qtrue;
2061 			continue;
2062 		} else if ( !Q_stricmp( token, "nocompress" ) )   {
2063 			tr.allowCompress = -1;
2064 			continue;
2065 		}
2066 		// done.
2067 		// light <value> determines flaring in q3map, not needed here
2068 		else if ( !Q_stricmp( token, "light" ) ) {
2069 			COM_ParseExt( text, qfalse );
2070 			continue;
2071 		}
2072 		// cull <face>
2073 		else if ( !Q_stricmp( token, "cull" ) ) {
2074 			token = COM_ParseExt( text, qfalse );
2075 			if ( token[0] == 0 ) {
2076 				ri.Printf( PRINT_WARNING, "WARNING: missing cull parms in shader '%s'\n", shader.name );
2077 				continue;
2078 			}
2079 
2080 			if ( !Q_stricmp( token, "none" ) || !Q_stricmp( token, "twosided" ) || !Q_stricmp( token, "disable" ) ) {
2081 				shader.cullType = CT_TWO_SIDED;
2082 			} else if ( !Q_stricmp( token, "back" ) || !Q_stricmp( token, "backside" ) || !Q_stricmp( token, "backsided" ) )      {
2083 				shader.cullType = CT_BACK_SIDED;
2084 			} else
2085 			{
2086 				ri.Printf( PRINT_WARNING, "WARNING: invalid cull parm '%s' in shader '%s'\n", token, shader.name );
2087 			}
2088 			continue;
2089 		}
2090 		// sort
2091 		else if ( !Q_stricmp( token, "sort" ) ) {
2092 			ParseSort( text );
2093 			continue;
2094 		} else
2095 		{
2096 			ri.Printf( PRINT_WARNING, "WARNING: unknown general shader parameter '%s' in '%s'\n", token, shader.name );
2097 			return qfalse;
2098 		}
2099 	}
2100 
2101 	//
2102 	// ignore shaders that don't have any stages, unless it is a sky or fog
2103 	//
2104 	if ( s == 0 && !shader.isSky && !( shader.contentFlags & CONTENTS_FOG ) ) {
2105 		return qfalse;
2106 	}
2107 
2108 	shader.explicitlyDefined = qtrue;
2109 
2110 	return qtrue;
2111 }
2112 
2113 /*
2114 ========================================================================================
2115 
2116 SHADER OPTIMIZATION AND FOGGING
2117 
2118 ========================================================================================
2119 */
2120 
2121 /*
2122 ===================
2123 ComputeStageIteratorFunc
2124 
2125 See if we can use on of the simple fastpath stage functions,
2126 otherwise set to the generic stage function
2127 ===================
2128 */
ComputeStageIteratorFunc(void)2129 static void ComputeStageIteratorFunc( void )
2130 {
2131 	shader.optimalStageIteratorFunc = RB_StageIteratorGeneric;
2132 
2133 	//
2134 	// see if this should go into the sky path
2135 	//
2136 	if ( shader.isSky )
2137 	{
2138 		shader.optimalStageIteratorFunc = RB_StageIteratorSky;
2139 		return;
2140 	}
2141 }
2142 
2143 /*
2144 ===================
2145 ComputeVertexAttribs
2146 
2147 Check which vertex attributes we only need, so we
2148 don't need to submit/copy all of them.
2149 ===================
2150 */
ComputeVertexAttribs(void)2151 static void ComputeVertexAttribs(void)
2152 {
2153 	int i, stage;
2154 
2155 	// dlights always need ATTR_NORMAL
2156 	shader.vertexAttribs = ATTR_POSITION | ATTR_NORMAL;
2157 
2158 	// portals always need normals, for SurfIsOffscreen()
2159 	if (shader.isPortal)
2160 	{
2161 		shader.vertexAttribs |= ATTR_NORMAL;
2162 	}
2163 
2164 	if (shader.defaultShader)
2165 	{
2166 		shader.vertexAttribs |= ATTR_TEXCOORD;
2167 		return;
2168 	}
2169 
2170 	if(shader.numDeforms)
2171 	{
2172 		for ( i = 0; i < shader.numDeforms; i++)
2173 		{
2174 			deformStage_t  *ds = &shader.deforms[i];
2175 
2176 			switch (ds->deformation)
2177 			{
2178 				case DEFORM_BULGE:
2179 					shader.vertexAttribs |= ATTR_NORMAL | ATTR_TEXCOORD;
2180 					break;
2181 
2182 				case DEFORM_AUTOSPRITE:
2183 					shader.vertexAttribs |= ATTR_NORMAL | ATTR_COLOR;
2184 					break;
2185 
2186 				case DEFORM_WAVE:
2187 				case DEFORM_NORMALS:
2188 				case DEFORM_TEXT0:
2189 				case DEFORM_TEXT1:
2190 				case DEFORM_TEXT2:
2191 				case DEFORM_TEXT3:
2192 				case DEFORM_TEXT4:
2193 				case DEFORM_TEXT5:
2194 				case DEFORM_TEXT6:
2195 				case DEFORM_TEXT7:
2196 					shader.vertexAttribs |= ATTR_NORMAL;
2197 					break;
2198 
2199 				default:
2200 				case DEFORM_NONE:
2201 				case DEFORM_MOVE:
2202 				case DEFORM_PROJECTION_SHADOW:
2203 				case DEFORM_AUTOSPRITE2:
2204 					break;
2205 			}
2206 		}
2207 	}
2208 
2209 	for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ )
2210 	{
2211 		shaderStage_t *pStage = &stages[stage];
2212 
2213 		if ( !pStage->active )
2214 		{
2215 			break;
2216 		}
2217 
2218 		if (pStage->glslShaderGroup == tr.lightallShader)
2219 		{
2220 			shader.vertexAttribs |= ATTR_NORMAL;
2221 
2222 			if ((pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK) && !(r_normalMapping->integer == 0 && r_specularMapping->integer == 0))
2223 			{
2224 				shader.vertexAttribs |= ATTR_TANGENT;
2225 			}
2226 
2227 			switch (pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK)
2228 			{
2229 				case LIGHTDEF_USE_LIGHTMAP:
2230 				case LIGHTDEF_USE_LIGHT_VERTEX:
2231 					shader.vertexAttribs |= ATTR_LIGHTDIRECTION;
2232 					break;
2233 				default:
2234 					break;
2235 			}
2236 		}
2237 
2238 		for (i = 0; i < NUM_TEXTURE_BUNDLES; i++)
2239 		{
2240 			if ( pStage->bundle[i].image[0] == 0 )
2241 			{
2242 				continue;
2243 			}
2244 
2245 			switch(pStage->bundle[i].tcGen)
2246 			{
2247 				case TCGEN_TEXTURE:
2248 					shader.vertexAttribs |= ATTR_TEXCOORD;
2249 					break;
2250 				case TCGEN_LIGHTMAP:
2251 					shader.vertexAttribs |= ATTR_LIGHTCOORD;
2252 					break;
2253 				case TCGEN_ENVIRONMENT_MAPPED:
2254 					shader.vertexAttribs |= ATTR_NORMAL;
2255 					break;
2256 
2257 				default:
2258 					break;
2259 			}
2260 		}
2261 
2262 		switch(pStage->rgbGen)
2263 		{
2264 			case CGEN_EXACT_VERTEX:
2265 			case CGEN_VERTEX:
2266 			case CGEN_EXACT_VERTEX_LIT:
2267 			case CGEN_VERTEX_LIT:
2268 			case CGEN_ONE_MINUS_VERTEX:
2269 				shader.vertexAttribs |= ATTR_COLOR;
2270 				break;
2271 
2272 			case CGEN_LIGHTING_DIFFUSE:
2273 				shader.vertexAttribs |= ATTR_NORMAL;
2274 				break;
2275 
2276 			default:
2277 				break;
2278 		}
2279 
2280 		switch(pStage->alphaGen)
2281 		{
2282 			case AGEN_LIGHTING_SPECULAR:
2283 				shader.vertexAttribs |= ATTR_NORMAL;
2284 				break;
2285 
2286 			case AGEN_NORMALZFADE:
2287 				break;
2288 			case AGEN_VERTEX:
2289 			case AGEN_ONE_MINUS_VERTEX:
2290 				shader.vertexAttribs |= ATTR_COLOR;
2291 				break;
2292 
2293 			default:
2294 				break;
2295 		}
2296 	}
2297 }
2298 
2299 
CollapseStagesToLightall(shaderStage_t * diffuse,shaderStage_t * normal,shaderStage_t * specular,shaderStage_t * lightmap,qboolean useLightVector,qboolean useLightVertex,qboolean parallax,qboolean tcgen)2300 static void CollapseStagesToLightall(shaderStage_t *diffuse,
2301 	shaderStage_t *normal, shaderStage_t *specular, shaderStage_t *lightmap,
2302 	qboolean useLightVector, qboolean useLightVertex, qboolean parallax, qboolean tcgen)
2303 {
2304 	int defs = 0;
2305 
2306 	//ri.Printf(PRINT_ALL, "shader %s has diffuse %s", shader.name, diffuse->bundle[0].image[0]->imgName);
2307 
2308 	// reuse diffuse, mark others inactive
2309 	diffuse->type = ST_GLSL;
2310 
2311 	if (lightmap)
2312 	{
2313 		//ri.Printf(PRINT_ALL, ", lightmap");
2314 		diffuse->bundle[TB_LIGHTMAP] = lightmap->bundle[0];
2315 		defs |= LIGHTDEF_USE_LIGHTMAP;
2316 	}
2317 	else if (useLightVector)
2318 	{
2319 		defs |= LIGHTDEF_USE_LIGHT_VECTOR;
2320 	}
2321 	else if (useLightVertex)
2322 	{
2323 		defs |= LIGHTDEF_USE_LIGHT_VERTEX;
2324 	}
2325 
2326 	if (r_deluxeMapping->integer && tr.worldDeluxeMapping && lightmap && shader.lightmapIndex >= 0)
2327 	{
2328 		//ri.Printf(PRINT_ALL, ", deluxemap");
2329 		diffuse->bundle[TB_DELUXEMAP] = lightmap->bundle[0];
2330 		diffuse->bundle[TB_DELUXEMAP].image[0] = tr.deluxemaps[shader.lightmapIndex];
2331 	}
2332 
2333 	if (r_normalMapping->integer)
2334 	{
2335 		image_t *diffuseImg;
2336 		if (normal)
2337 		{
2338 			//ri.Printf(PRINT_ALL, ", normalmap %s", normal->bundle[0].image[0]->imgName);
2339 			diffuse->bundle[TB_NORMALMAP] = normal->bundle[0];
2340 			if (parallax && r_parallaxMapping->integer)
2341 				defs |= LIGHTDEF_USE_PARALLAXMAP;
2342 
2343 			VectorCopy4(normal->normalScale, diffuse->normalScale);
2344 		}
2345 		else if ((lightmap || useLightVector || useLightVertex) && (diffuseImg = diffuse->bundle[TB_DIFFUSEMAP].image[0]))
2346 		{
2347 			char normalName[MAX_QPATH];
2348 			image_t *normalImg;
2349 			imgFlags_t normalFlags = (diffuseImg->flags & ~IMGFLAG_GENNORMALMAP) | IMGFLAG_NOLIGHTSCALE;
2350 
2351 			// try a normalheight image first
2352 			COM_StripExtension(diffuseImg->imgName, normalName, MAX_QPATH);
2353 			Q_strcat(normalName, MAX_QPATH, "_nh");
2354 
2355 			normalImg = R_FindImageFile(normalName, IMGTYPE_NORMALHEIGHT, normalFlags);
2356 
2357 			if (normalImg)
2358 			{
2359 				parallax = qtrue;
2360 			}
2361 			else
2362 			{
2363 				// try a normal image ("_n" suffix)
2364 				normalName[strlen(normalName) - 1] = '\0';
2365 				normalImg = R_FindImageFile(normalName, IMGTYPE_NORMAL, normalFlags);
2366 			}
2367 
2368 			if (normalImg)
2369 			{
2370 				diffuse->bundle[TB_NORMALMAP] = diffuse->bundle[0];
2371 				diffuse->bundle[TB_NORMALMAP].numImageAnimations = 0;
2372 				diffuse->bundle[TB_NORMALMAP].image[0] = normalImg;
2373 
2374 				if (parallax && r_parallaxMapping->integer)
2375 					defs |= LIGHTDEF_USE_PARALLAXMAP;
2376 
2377 				VectorSet4(diffuse->normalScale, r_baseNormalX->value, r_baseNormalY->value, 1.0f, r_baseParallax->value);
2378 			}
2379 		}
2380 	}
2381 
2382 	if (r_specularMapping->integer)
2383 	{
2384 		image_t *diffuseImg;
2385 		if (specular)
2386 		{
2387 			//ri.Printf(PRINT_ALL, ", specularmap %s", specular->bundle[0].image[0]->imgName);
2388 			diffuse->bundle[TB_SPECULARMAP] = specular->bundle[0];
2389 			VectorCopy4(specular->specularScale, diffuse->specularScale);
2390 		}
2391 		else if ((lightmap || useLightVector || useLightVertex) && (diffuseImg = diffuse->bundle[TB_DIFFUSEMAP].image[0]))
2392 		{
2393 			char specularName[MAX_QPATH];
2394 			image_t *specularImg;
2395 			imgFlags_t specularFlags = (diffuseImg->flags & ~IMGFLAG_GENNORMALMAP) | IMGFLAG_NOLIGHTSCALE;
2396 
2397 			COM_StripExtension(diffuseImg->imgName, specularName, MAX_QPATH);
2398 			Q_strcat(specularName, MAX_QPATH, "_s");
2399 
2400 			specularImg = R_FindImageFile(specularName, IMGTYPE_COLORALPHA, specularFlags);
2401 
2402 			if (specularImg)
2403 			{
2404 				diffuse->bundle[TB_SPECULARMAP] = diffuse->bundle[0];
2405 				diffuse->bundle[TB_SPECULARMAP].numImageAnimations = 0;
2406 				diffuse->bundle[TB_SPECULARMAP].image[0] = specularImg;
2407 
2408 				VectorSet4(diffuse->specularScale, 1.0f, 1.0f, 1.0f, 1.0f);
2409 			}
2410 		}
2411 	}
2412 
2413 	if (tcgen || diffuse->bundle[0].numTexMods)
2414 	{
2415 		defs |= LIGHTDEF_USE_TCGEN_AND_TCMOD;
2416 	}
2417 
2418 	//ri.Printf(PRINT_ALL, ".\n");
2419 
2420 	diffuse->glslShaderGroup = tr.lightallShader;
2421 	diffuse->glslShaderIndex = defs;
2422 }
2423 
2424 
CollapseStagesToGLSL(void)2425 static int CollapseStagesToGLSL(void)
2426 {
2427 	int i, j, numStages;
2428 	qboolean skip = qfalse;
2429 
2430 	// skip shaders with deforms
2431 	if (shader.numDeforms != 0)
2432 	{
2433 		skip = qtrue;
2434 	}
2435 
2436 	if (!skip)
2437 	{
2438 		// if 2+ stages and first stage is lightmap, switch them
2439 		// this makes it easier for the later bits to process
2440 		if (stages[0].active && stages[0].bundle[0].tcGen == TCGEN_LIGHTMAP && stages[1].active)
2441 		{
2442 			int blendBits = stages[1].stateBits & ( GLS_DSTBLEND_BITS | GLS_SRCBLEND_BITS );
2443 
2444 			if (blendBits == (GLS_DSTBLEND_SRC_COLOR | GLS_SRCBLEND_ZERO)
2445 				|| blendBits == (GLS_DSTBLEND_ZERO | GLS_SRCBLEND_DST_COLOR))
2446 			{
2447 				int stateBits0 = stages[0].stateBits;
2448 				int stateBits1 = stages[1].stateBits;
2449 				shaderStage_t swapStage;
2450 
2451 				swapStage = stages[0];
2452 				stages[0] = stages[1];
2453 				stages[1] = swapStage;
2454 
2455 				stages[0].stateBits = stateBits0;
2456 				stages[1].stateBits = stateBits1;
2457 			}
2458 		}
2459 	}
2460 
2461 	if (!skip)
2462 	{
2463 		// scan for shaders that aren't supported
2464 		for (i = 0; i < MAX_SHADER_STAGES; i++)
2465 		{
2466 			shaderStage_t *pStage = &stages[i];
2467 
2468 			if (!pStage->active)
2469 				continue;
2470 
2471 			if (pStage->adjustColorsForFog)
2472 			{
2473 				skip = qtrue;
2474 				break;
2475 			}
2476 
2477 			if (pStage->bundle[0].tcGen == TCGEN_LIGHTMAP)
2478 			{
2479 				int blendBits = pStage->stateBits & ( GLS_DSTBLEND_BITS | GLS_SRCBLEND_BITS );
2480 
2481 				if (blendBits != (GLS_DSTBLEND_SRC_COLOR | GLS_SRCBLEND_ZERO)
2482 					&& blendBits != (GLS_DSTBLEND_ZERO | GLS_SRCBLEND_DST_COLOR))
2483 				{
2484 					skip = qtrue;
2485 					break;
2486 				}
2487 			}
2488 
2489 			switch(pStage->bundle[0].tcGen)
2490 			{
2491 				case TCGEN_TEXTURE:
2492 				case TCGEN_LIGHTMAP:
2493 				case TCGEN_ENVIRONMENT_MAPPED:
2494 				case TCGEN_VECTOR:
2495 					break;
2496 				default:
2497 					skip = qtrue;
2498 					break;
2499 			}
2500 
2501 			switch(pStage->alphaGen)
2502 			{
2503 				case AGEN_LIGHTING_SPECULAR:
2504 				case AGEN_PORTAL:
2505 				case AGEN_NORMALZFADE:
2506 					skip = qtrue;
2507 					break;
2508 				default:
2509 					break;
2510 			}
2511 		}
2512 	}
2513 
2514 	if (!skip)
2515 	{
2516 		qboolean usedLightmap = qfalse;
2517 
2518 		for (i = 0; i < MAX_SHADER_STAGES; i++)
2519 		{
2520 			shaderStage_t *pStage = &stages[i];
2521 			shaderStage_t *diffuse, *normal, *specular, *lightmap;
2522 			qboolean parallax, tcgen, diffuselit, vertexlit;
2523 
2524 			if (!pStage->active)
2525 				continue;
2526 
2527 			// skip normal and specular maps
2528 			if (pStage->type != ST_COLORMAP)
2529 				continue;
2530 
2531 			// skip lightmaps
2532 			if (pStage->bundle[0].tcGen == TCGEN_LIGHTMAP)
2533 				continue;
2534 
2535 			diffuse  = pStage;
2536 			normal   = NULL;
2537 			parallax = qfalse;
2538 			specular = NULL;
2539 			lightmap = NULL;
2540 
2541 			// we have a diffuse map, find matching normal, specular, and lightmap
2542 			for (j = i + 1; j < MAX_SHADER_STAGES; j++)
2543 			{
2544 				shaderStage_t *pStage2 = &stages[j];
2545 
2546 				if (!pStage2->active)
2547 					continue;
2548 
2549 				switch(pStage2->type)
2550 				{
2551 					case ST_NORMALMAP:
2552 						if (!normal)
2553 						{
2554 							normal = pStage2;
2555 						}
2556 						break;
2557 
2558 					case ST_NORMALPARALLAXMAP:
2559 						if (!normal)
2560 						{
2561 							normal = pStage2;
2562 							parallax = qtrue;
2563 						}
2564 						break;
2565 
2566 					case ST_SPECULARMAP:
2567 						if (!specular)
2568 						{
2569 							specular = pStage2;
2570 						}
2571 						break;
2572 
2573 					case ST_COLORMAP:
2574 						if (pStage2->bundle[0].tcGen == TCGEN_LIGHTMAP)
2575 						{
2576 							int blendBits = pStage->stateBits & ( GLS_DSTBLEND_BITS | GLS_SRCBLEND_BITS );
2577 
2578 							// Only add lightmap to blendfunc filter stage if it's the first time lightmap is used
2579 							// otherwise it will cause the shader to be darkened by the lightmap multiple times.
2580 							if (!usedLightmap || (blendBits != (GLS_DSTBLEND_SRC_COLOR | GLS_SRCBLEND_ZERO)
2581 								&& blendBits != (GLS_DSTBLEND_ZERO | GLS_SRCBLEND_DST_COLOR)))
2582 							{
2583 								lightmap = pStage2;
2584 								usedLightmap = qtrue;
2585 							}
2586 						}
2587 						break;
2588 
2589 					default:
2590 						break;
2591 				}
2592 			}
2593 
2594 			tcgen = qfalse;
2595 			if (diffuse->bundle[0].tcGen == TCGEN_ENVIRONMENT_MAPPED
2596 				|| diffuse->bundle[0].tcGen == TCGEN_LIGHTMAP
2597 				|| diffuse->bundle[0].tcGen == TCGEN_VECTOR)
2598 			{
2599 				tcgen = qtrue;
2600 			}
2601 
2602 			diffuselit = qfalse;
2603 			if (diffuse->rgbGen == CGEN_LIGHTING_DIFFUSE)
2604 			{
2605 				diffuselit = qtrue;
2606 			}
2607 
2608 			vertexlit = qfalse;
2609 			if (diffuse->rgbGen == CGEN_VERTEX_LIT || diffuse->rgbGen == CGEN_EXACT_VERTEX_LIT)
2610 			{
2611 				vertexlit = qtrue;
2612 			}
2613 
2614 			CollapseStagesToLightall(diffuse, normal, specular, lightmap, diffuselit, vertexlit, parallax, tcgen);
2615 		}
2616 
2617 		// deactivate lightmap stages
2618 		for (i = 0; i < MAX_SHADER_STAGES; i++)
2619 		{
2620 			shaderStage_t *pStage = &stages[i];
2621 
2622 			if (!pStage->active)
2623 				continue;
2624 
2625 			if (pStage->bundle[0].tcGen == TCGEN_LIGHTMAP)
2626 			{
2627 				pStage->active = qfalse;
2628 			}
2629 		}
2630 	}
2631 
2632 	// deactivate normal and specular stages
2633 	for (i = 0; i < MAX_SHADER_STAGES; i++)
2634 	{
2635 		shaderStage_t *pStage = &stages[i];
2636 
2637 		if (!pStage->active)
2638 			continue;
2639 
2640 		if (pStage->type == ST_NORMALMAP)
2641 		{
2642 			pStage->active = qfalse;
2643 		}
2644 
2645 		if (pStage->type == ST_NORMALPARALLAXMAP)
2646 		{
2647 			pStage->active = qfalse;
2648 		}
2649 
2650 		if (pStage->type == ST_SPECULARMAP)
2651 		{
2652 			pStage->active = qfalse;
2653 		}
2654 	}
2655 
2656 	// remove inactive stages
2657 	numStages = 0;
2658 	for (i = 0; i < MAX_SHADER_STAGES; i++)
2659 	{
2660 		if (!stages[i].active)
2661 			continue;
2662 
2663 		if (i == numStages)
2664 		{
2665 			numStages++;
2666 			continue;
2667 		}
2668 
2669 		stages[numStages] = stages[i];
2670 		stages[i].active = qfalse;
2671 		numStages++;
2672 	}
2673 
2674 	// convert any remaining lightmap stages to a lighting pass with a white texture
2675 	// only do this with r_sunlightMode non-zero, as it's only for correct shadows.
2676 	if (r_sunlightMode->integer && shader.numDeforms == 0)
2677 	{
2678 		for (i = 0; i < MAX_SHADER_STAGES; i++)
2679 		{
2680 			shaderStage_t *pStage = &stages[i];
2681 
2682 			if (!pStage->active)
2683 				continue;
2684 
2685 			if (pStage->adjustColorsForFog)
2686 				continue;
2687 
2688 			if (pStage->bundle[TB_DIFFUSEMAP].tcGen == TCGEN_LIGHTMAP)
2689 			{
2690 				pStage->glslShaderGroup = tr.lightallShader;
2691 				pStage->glslShaderIndex = LIGHTDEF_USE_LIGHTMAP;
2692 				pStage->bundle[TB_LIGHTMAP] = pStage->bundle[TB_DIFFUSEMAP];
2693 				pStage->bundle[TB_DIFFUSEMAP].image[0] = tr.whiteImage;
2694 				pStage->bundle[TB_DIFFUSEMAP].isLightmap = qfalse;
2695 				pStage->bundle[TB_DIFFUSEMAP].tcGen = TCGEN_TEXTURE;
2696 			}
2697 		}
2698 	}
2699 
2700 	// convert any remaining lightingdiffuse stages to a lighting pass
2701 	if (shader.numDeforms == 0)
2702 	{
2703 		for (i = 0; i < MAX_SHADER_STAGES; i++)
2704 		{
2705 			shaderStage_t *pStage = &stages[i];
2706 
2707 			if (!pStage->active)
2708 				continue;
2709 
2710 			if (pStage->adjustColorsForFog)
2711 				continue;
2712 
2713 			if (pStage->rgbGen == CGEN_LIGHTING_DIFFUSE)
2714 			{
2715 				pStage->glslShaderGroup = tr.lightallShader;
2716 				pStage->glslShaderIndex = LIGHTDEF_USE_LIGHT_VECTOR;
2717 
2718 				if (pStage->bundle[0].tcGen != TCGEN_TEXTURE || pStage->bundle[0].numTexMods != 0)
2719 					pStage->glslShaderIndex |= LIGHTDEF_USE_TCGEN_AND_TCMOD;
2720 			}
2721 		}
2722 	}
2723 
2724 	return numStages;
2725 }
2726 
2727 /*
2728 =============
2729 FixRenderCommandList
2730 
2731 Arnout: this is a nasty issue. Shaders can be registered after drawsurfaces are generated
2732 but before the frame is rendered. This will, for the duration of one frame, cause drawsurfaces
2733 to be rendered with bad shaders. To fix this, need to go through all render commands and fix
2734 sortedIndex.
2735 ==============
2736 */
FixRenderCommandList(int newShader)2737 static void FixRenderCommandList( int newShader ) {
2738 	renderCommandList_t *cmdList = &backEndData->commands;
2739 
2740 	if ( cmdList ) {
2741 		const void *curCmd = cmdList->cmds;
2742 
2743 		while ( 1 ) {
2744 			curCmd = PADP(curCmd, sizeof(void *));
2745 
2746 			switch ( *(const int *)curCmd ) {
2747 			case RC_SET_COLOR:
2748 			{
2749 				const setColorCommand_t *sc_cmd = (const setColorCommand_t *)curCmd;
2750 				curCmd = (const void *)( sc_cmd + 1 );
2751 				break;
2752 			}
2753 			case RC_STRETCH_PIC:
2754 			case RC_STRETCH_PIC_GRADIENT:
2755 			{
2756 				const stretchPicCommand_t *sp_cmd = (const stretchPicCommand_t *)curCmd;
2757 				curCmd = (const void *)( sp_cmd + 1 );
2758 				break;
2759 			}
2760 			case RC_DRAW_SURFS:
2761 			{
2762 				int i;
2763 				drawSurf_t  *drawSurf;
2764 				shader_t    *shader;
2765 				int fogNum;
2766 				int entityNum;
2767 				int dlightMap;
2768 				int         pshadowMap;
2769 				int atiTess;
2770 				int sortedIndex;
2771 				const drawSurfsCommand_t *ds_cmd =  (const drawSurfsCommand_t *)curCmd;
2772 
2773 				for ( i = 0, drawSurf = ds_cmd->drawSurfs; i < ds_cmd->numDrawSurfs; i++, drawSurf++ ) {
2774 					R_DecomposeSort( drawSurf->sort, &entityNum, &shader, &fogNum, &dlightMap, &pshadowMap, &atiTess );
2775 					sortedIndex = ( ( drawSurf->sort >> QSORT_SHADERNUM_SHIFT ) & ( MAX_SHADERS - 1 ) );
2776 					if ( sortedIndex >= newShader ) {
2777 						sortedIndex++;
2778 						drawSurf->sort = (sortedIndex << QSORT_SHADERNUM_SHIFT) | entityNum | ( fogNum << QSORT_FOGNUM_SHIFT ) | ( (int)pshadowMap << QSORT_PSHADOW_SHIFT) | (int)dlightMap;
2779 					}
2780 				}
2781 				curCmd = (const void *)( ds_cmd + 1 );
2782 				break;
2783 			}
2784 			case RC_DRAW_BUFFER:
2785 			{
2786 				const drawBufferCommand_t *db_cmd = (const drawBufferCommand_t *)curCmd;
2787 				curCmd = (const void *)( db_cmd + 1 );
2788 				break;
2789 			}
2790 			case RC_SWAP_BUFFERS:
2791 			{
2792 				const swapBuffersCommand_t *sb_cmd = (const swapBuffersCommand_t *)curCmd;
2793 				curCmd = (const void *)( sb_cmd + 1 );
2794 				break;
2795 			}
2796 			case RC_END_OF_LIST:
2797 			default:
2798 				return;
2799 			}
2800 		}
2801 	}
2802 }
2803 
2804 /*
2805 ==============
2806 SortNewShader
2807 
2808 Positions the most recently created shader in the tr.sortedShaders[]
2809 array so that the shader->sort key is sorted relative to the other
2810 shaders.
2811 
2812 Sets shader->sortedIndex
2813 ==============
2814 */
SortNewShader(void)2815 static void SortNewShader( void ) {
2816 	int i;
2817 	float sort;
2818 	shader_t    *newShader;
2819 
2820 	newShader = tr.shaders[ tr.numShaders - 1 ];
2821 	sort = newShader->sort;
2822 
2823 	for ( i = tr.numShaders - 2 ; i >= 0 ; i-- ) {
2824 		if ( tr.sortedShaders[ i ]->sort <= sort ) {
2825 			break;
2826 		}
2827 		tr.sortedShaders[i + 1] = tr.sortedShaders[i];
2828 		tr.sortedShaders[i + 1]->sortedIndex++;
2829 	}
2830 
2831 	// Arnout: fix rendercommandlist
2832 	FixRenderCommandList( i + 1 );
2833 
2834 	newShader->sortedIndex = i + 1;
2835 	tr.sortedShaders[i + 1] = newShader;
2836 }
2837 
2838 
2839 /*
2840 ====================
2841 GeneratePermanentShader
2842 ====================
2843 */
GeneratePermanentShader(void)2844 static shader_t *GeneratePermanentShader( void ) {
2845 	shader_t    *newShader;
2846 	int i, b;
2847 	int size, hash;
2848 
2849 	if ( tr.numShaders == MAX_SHADERS ) {
2850 		ri.Printf( PRINT_WARNING, "WARNING: GeneratePermanentShader - MAX_SHADERS hit\n" );
2851 		return tr.defaultShader;
2852 	}
2853 
2854 	newShader = ri.Hunk_Alloc( sizeof( shader_t ), h_low );
2855 
2856 	*newShader = shader;
2857 
2858 	if ( shader.sort <= SS_OPAQUE ) {
2859 		newShader->fogPass = FP_EQUAL;
2860 	} else if ( shader.contentFlags & CONTENTS_FOG ) {
2861 		newShader->fogPass = FP_LE;
2862 	}
2863 
2864 	tr.shaders[ tr.numShaders ] = newShader;
2865 	newShader->index = tr.numShaders;
2866 
2867 	tr.sortedShaders[ tr.numShaders ] = newShader;
2868 	newShader->sortedIndex = tr.numShaders;
2869 
2870 	tr.numShaders++;
2871 
2872 	for ( i = 0 ; i < newShader->numUnfoggedPasses ; i++ ) {
2873 		if ( !stages[i].active ) {
2874 			newShader->stages[i] = NULL;    // Ridah, make sure it's null
2875 			break;
2876 		}
2877 		newShader->stages[i] = ri.Hunk_Alloc( sizeof( stages[i] ), h_low );
2878 		*newShader->stages[i] = stages[i];
2879 
2880 		for ( b = 0 ; b < NUM_TEXTURE_BUNDLES ; b++ ) {
2881 			if ( !newShader->stages[i]->bundle[b].numTexMods ) {
2882 				// make sure unalloc'd texMods aren't pointing to some random point in memory
2883 				newShader->stages[i]->bundle[b].texMods = NULL;
2884 				continue;
2885 			}
2886 			size = newShader->stages[i]->bundle[b].numTexMods * sizeof( texModInfo_t );
2887 			// Ridah, caching system
2888 			newShader->stages[i]->bundle[b].texMods = ri.Hunk_Alloc( size, h_low );
2889 			memcpy( newShader->stages[i]->bundle[b].texMods, stages[i].bundle[b].texMods, size );
2890 		}
2891 	}
2892 
2893 	SortNewShader();
2894 
2895 	hash = generateHashValue( newShader->name );
2896 	newShader->next = hashTable[hash];
2897 	hashTable[hash] = newShader;
2898 
2899 	return newShader;
2900 }
2901 
2902 /*
2903 =================
2904 VertexLightingCollapse
2905 
2906 If vertex lighting is enabled, only render a single
2907 pass, trying to guess which is the correct one to best aproximate
2908 what it is supposed to look like.
2909 =================
2910 */
VertexLightingCollapse(void)2911 static void VertexLightingCollapse( void ) {
2912 	int stage;
2913 	shaderStage_t   *bestStage;
2914 	int bestImageRank;
2915 	int rank;
2916 
2917 	// if we aren't opaque, just use the first pass
2918 	if ( shader.sort == SS_OPAQUE ) {
2919 
2920 		// pick the best texture for the single pass
2921 		bestStage = &stages[0];
2922 		bestImageRank = -999999;
2923 
2924 		for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ ) {
2925 			shaderStage_t *pStage = &stages[stage];
2926 
2927 			if ( !pStage->active ) {
2928 				break;
2929 			}
2930 			rank = 0;
2931 
2932 			if ( pStage->bundle[0].isLightmap ) {
2933 				rank -= 100;
2934 			}
2935 			if ( pStage->bundle[0].tcGen != TCGEN_TEXTURE ) {
2936 				rank -= 5;
2937 			}
2938 			if ( pStage->bundle[0].numTexMods ) {
2939 				rank -= 5;
2940 			}
2941 			if ( pStage->rgbGen != CGEN_IDENTITY && pStage->rgbGen != CGEN_IDENTITY_LIGHTING ) {
2942 				rank -= 3;
2943 			}
2944 
2945 			if ( rank > bestImageRank  ) {
2946 				bestImageRank = rank;
2947 				bestStage = pStage;
2948 			}
2949 		}
2950 
2951 		stages[0].bundle[0] = bestStage->bundle[0];
2952 		stages[0].stateBits &= ~( GLS_DSTBLEND_BITS | GLS_SRCBLEND_BITS );
2953 		stages[0].stateBits |= GLS_DEPTHMASK_TRUE;
2954 		if ( shader.lightmapIndex == LIGHTMAP_NONE ) {
2955 			stages[0].rgbGen = CGEN_LIGHTING_DIFFUSE;
2956 		} else {
2957 			stages[0].rgbGen = CGEN_EXACT_VERTEX;
2958 		}
2959 		stages[0].alphaGen = AGEN_SKIP;
2960 	} else {
2961 		// don't use a lightmap (tesla coils)
2962 		if ( stages[0].bundle[0].isLightmap ) {
2963 			stages[0] = stages[1];
2964 		}
2965 
2966 		// if we were in a cross-fade cgen, hack it to normal
2967 		if ( stages[0].rgbGen == CGEN_ONE_MINUS_ENTITY || stages[1].rgbGen == CGEN_ONE_MINUS_ENTITY ) {
2968 			stages[0].rgbGen = CGEN_IDENTITY_LIGHTING;
2969 		}
2970 		if ( ( stages[0].rgbGen == CGEN_WAVEFORM && stages[0].rgbWave.func == GF_SAWTOOTH )
2971 			 && ( stages[1].rgbGen == CGEN_WAVEFORM && stages[1].rgbWave.func == GF_INVERSE_SAWTOOTH ) ) {
2972 			stages[0].rgbGen = CGEN_IDENTITY_LIGHTING;
2973 		}
2974 		if ( ( stages[0].rgbGen == CGEN_WAVEFORM && stages[0].rgbWave.func == GF_INVERSE_SAWTOOTH )
2975 			 && ( stages[1].rgbGen == CGEN_WAVEFORM && stages[1].rgbWave.func == GF_SAWTOOTH ) ) {
2976 			stages[0].rgbGen = CGEN_IDENTITY_LIGHTING;
2977 		}
2978 	}
2979 
2980 	for ( stage = 1; stage < MAX_SHADER_STAGES; stage++ ) {
2981 		shaderStage_t *pStage = &stages[stage];
2982 
2983 		if ( !pStage->active ) {
2984 			break;
2985 		}
2986 
2987 		memset( pStage, 0, sizeof( *pStage ) );
2988 	}
2989 }
2990 
2991 /*
2992 ===============
2993 InitShader
2994 ===============
2995 */
InitShader(const char * name,int lightmapIndex)2996 static void InitShader( const char *name, int lightmapIndex ) {
2997 	int i;
2998 
2999 	// clear the global shader
3000 	Com_Memset( &shader, 0, sizeof( shader ) );
3001 	Com_Memset( &stages, 0, sizeof( stages ) );
3002 
3003 	Q_strncpyz( shader.name, name, sizeof( shader.name ) );
3004 	shader.lightmapIndex = lightmapIndex;
3005 
3006 	for ( i = 0 ; i < MAX_SHADER_STAGES ; i++ ) {
3007 		stages[i].bundle[0].texMods = texMods[i];
3008 
3009 		// default normal/specular
3010 		VectorSet4(stages[i].normalScale, 0.0f, 0.0f, 0.0f, 0.0f);
3011 		if (r_pbr->integer)
3012 		{
3013 			stages[i].specularScale[0] = r_baseGloss->value;
3014 		}
3015 		else
3016 		{
3017 			stages[i].specularScale[0] =
3018 			stages[i].specularScale[1] =
3019 			stages[i].specularScale[2] = r_baseSpecular->value;
3020 			stages[i].specularScale[3] = r_baseGloss->value;
3021 		}
3022 	}
3023 }
3024 
3025 /*
3026 =========================
3027 FinishShader
3028 
3029 Returns a freshly allocated shader with all the needed info
3030 from the current global working shader
3031 =========================
3032 */
FinishShader(void)3033 static shader_t *FinishShader( void ) {
3034 	int stage;
3035 	qboolean hasLightmapStage;
3036 	qboolean vertexLightmap;
3037 
3038 	hasLightmapStage = qfalse;
3039 	vertexLightmap = qfalse;
3040 
3041 	//
3042 	// set sky stuff appropriate
3043 	//
3044 	if ( shader.isSky ) {
3045 		shader.sort = SS_ENVIRONMENT;
3046 	}
3047 
3048 	//
3049 	// set polygon offset
3050 	//
3051 	if ( shader.polygonOffset && !shader.sort ) {
3052 		shader.sort = SS_DECAL;
3053 	}
3054 
3055 	//
3056 	// set appropriate stage information
3057 	//
3058 	for ( stage = 0; stage < MAX_SHADER_STAGES; ) {
3059 		shaderStage_t *pStage = &stages[stage];
3060 
3061 		if ( !pStage->active ) {
3062 			break;
3063 		}
3064 
3065 		// check for a missing texture
3066 		if ( !pStage->bundle[0].image[0] ) {
3067 			ri.Printf( PRINT_WARNING, "Shader %s has a stage with no image\n", shader.name );
3068 			pStage->active = qfalse;
3069 			stage++;
3070 			continue;
3071 		}
3072 
3073 		//
3074 		// ditch this stage if it's detail and detail textures are disabled
3075 		//
3076 		if ( pStage->isDetail && !r_detailTextures->integer )
3077 		{
3078 			int index;
3079 
3080 			for(index = stage + 1; index < MAX_SHADER_STAGES; index++)
3081 			{
3082 				if(!stages[index].active)
3083 					break;
3084 			}
3085 
3086 			if(index < MAX_SHADER_STAGES)
3087 				memmove(pStage, pStage + 1, sizeof(*pStage) * (index - stage));
3088 			else
3089 			{
3090 				if(stage + 1 < MAX_SHADER_STAGES)
3091 					memmove(pStage, pStage + 1, sizeof(*pStage) * (index - stage - 1));
3092 
3093 				Com_Memset(&stages[index - 1], 0, sizeof(*stages));
3094 			}
3095 			continue;
3096 		}
3097 
3098 		//
3099 		// default texture coordinate generation
3100 		//
3101 		if ( pStage->bundle[0].isLightmap ) {
3102 			if ( pStage->bundle[0].tcGen == TCGEN_BAD ) {
3103 				pStage->bundle[0].tcGen = TCGEN_LIGHTMAP;
3104 			}
3105 			hasLightmapStage = qtrue;
3106 		} else {
3107 			if ( pStage->bundle[0].tcGen == TCGEN_BAD ) {
3108 				pStage->bundle[0].tcGen = TCGEN_TEXTURE;
3109 			}
3110 		}
3111 
3112 
3113 		// not a true lightmap but we want to leave existing
3114 		// behaviour in place and not print out a warning
3115 		//if (pStage->rgbGen == CGEN_VERTEX) {
3116 		//  vertexLightmap = qtrue;
3117 		//}
3118 
3119 
3120 
3121 		//
3122 		// determine sort order and fog color adjustment
3123 		//
3124 		if ( ( pStage->stateBits & ( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS ) ) &&
3125 			 ( stages[0].stateBits & ( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS ) ) ) {
3126 			int blendSrcBits = pStage->stateBits & GLS_SRCBLEND_BITS;
3127 			int blendDstBits = pStage->stateBits & GLS_DSTBLEND_BITS;
3128 
3129 			// fog color adjustment only works for blend modes that have a contribution
3130 			// that aproaches 0 as the modulate values aproach 0 --
3131 			// GL_ONE, GL_ONE
3132 			// GL_ZERO, GL_ONE_MINUS_SRC_COLOR
3133 			// GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
3134 
3135 			// modulate, additive
3136 			if ( ( ( blendSrcBits == GLS_SRCBLEND_ONE ) && ( blendDstBits == GLS_DSTBLEND_ONE ) ) ||
3137 				 ( ( blendSrcBits == GLS_SRCBLEND_ZERO ) && ( blendDstBits == GLS_DSTBLEND_ONE_MINUS_SRC_COLOR ) ) ) {
3138 				pStage->adjustColorsForFog = ACFF_MODULATE_RGB;
3139 			}
3140 			// strict blend
3141 			else if ( ( blendSrcBits == GLS_SRCBLEND_SRC_ALPHA ) && ( blendDstBits == GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ) ) {
3142 				pStage->adjustColorsForFog = ACFF_MODULATE_ALPHA;
3143 			}
3144 			// premultiplied alpha
3145 			else if ( ( blendSrcBits == GLS_SRCBLEND_ONE ) && ( blendDstBits == GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ) ) {
3146 				pStage->adjustColorsForFog = ACFF_MODULATE_RGBA;
3147 			} else {
3148 				// we can't adjust this one correctly, so it won't be exactly correct in fog
3149 			}
3150 
3151 			// don't screw with sort order if this is a portal or environment
3152 			if ( !shader.sort ) {
3153 				// see through item, like a grill or grate
3154 				if ( pStage->stateBits & GLS_DEPTHMASK_TRUE ) {
3155 					shader.sort = SS_SEE_THROUGH;
3156 				} else {
3157 					shader.sort = SS_BLEND0;
3158 				}
3159 			}
3160 		}
3161 
3162 		stage++;
3163 	}
3164 
3165 	// there are times when you will need to manually apply a sort to
3166 	// opaque alpha tested shaders that have later blend passes
3167 	if ( !shader.sort ) {
3168 		shader.sort = SS_OPAQUE;
3169 	}
3170 
3171 	//
3172 	// if we are in r_vertexLight mode, never use a lightmap texture
3173 	//
3174 	if ( 0 && ( stage > 1 && ( ( r_vertexLight->integer && !r_uiFullScreen->integer ) || glConfig.hardwareType == GLHW_PERMEDIA2 ) ) ) {
3175 		VertexLightingCollapse();
3176 		hasLightmapStage = qfalse;
3177 	}
3178 
3179 	//
3180 	// look for multitexture potential
3181 	//
3182 	stage = CollapseStagesToGLSL();
3183 
3184 	if ( shader.lightmapIndex >= 0 && !hasLightmapStage ) {
3185 		if ( vertexLightmap ) {
3186 			ri.Printf( PRINT_DEVELOPER, "WARNING: shader '%s' has VERTEX forced lightmap!\n", shader.name );
3187 		} else {
3188 			ri.Printf( PRINT_DEVELOPER, "WARNING: shader '%s' has lightmap but no lightmap stage!\n", shader.name );
3189 			// Don't set this, it will just add duplicate shaders to the hash
3190   			//shader.lightmapIndex = LIGHTMAP_NONE;
3191 		}
3192 	}
3193 
3194 
3195 	//
3196 	// compute number of passes
3197 	//
3198 	shader.numUnfoggedPasses = stage;
3199 
3200 	// fogonly shaders don't have any normal passes
3201 	if (stage == 0 && !shader.isSky)
3202 		shader.sort = SS_FOG;
3203 
3204 	// determine which stage iterator function is appropriate
3205 	ComputeStageIteratorFunc();
3206 
3207 	// determine which vertex attributes this shader needs
3208 	ComputeVertexAttribs();
3209 
3210 	// RF default back to no compression for next shader
3211 	if ( r_ext_compressed_textures->integer == 2 ) {
3212 		tr.allowCompress = qfalse;
3213 	}
3214 
3215 	return GeneratePermanentShader();
3216 }
3217 
3218 //========================================================================================
3219 
3220 /*
3221 ====================
3222 FindShaderInShaderText
3223 
3224 Scans the combined text description of all the shader files for
3225 the given shader name.
3226 
3227 return NULL if not found
3228 
3229 If found, it will return a valid shader
3230 =====================
3231 */
FindShaderInShaderText(const char * shadername)3232 static char *FindShaderInShaderText( const char *shadername ) {
3233 	char *p = s_shaderText;
3234 	char *token;
3235 
3236 	if ( !p ) {
3237 		return NULL;
3238 	}
3239 
3240 	// Ridah, optimized shader loading
3241 	{
3242 		shaderStringPointer_t *pShaderString;
3243 		unsigned short int checksum;
3244 
3245 		checksum = generateHashValue( shadername );
3246 
3247 		// if it's known, skip straight to it's position
3248 		pShaderString = &shaderChecksumLookup[checksum];
3249 		while ( pShaderString && pShaderString->pStr ) {
3250 			p = pShaderString->pStr;
3251 
3252 			token = COM_ParseExt( &p, qtrue );
3253 
3254 			if ( ( token[0] != 0 ) && !Q_stricmp( token, shadername ) ) {
3255 				return p;
3256 			}
3257 
3258 			pShaderString = pShaderString->next;
3259 		}
3260 	}
3261 	// done.
3262 
3263 	/*
3264 	// look for label
3265 	// note that this could get confused if a shader name is used inside
3266 	// another shader definition
3267 	while ( 1 ) {
3268 		token = COM_ParseExt( &p, qtrue );
3269 		if ( token[0] == 0 ) {
3270 			break;
3271 		}
3272 
3273 		if ( token[0] == '{' ) {
3274 			// skip the definition
3275 			SkipBracedSection( &p, 0 );
3276 		} else if ( !Q_stricmp( token, shadername ) ) {
3277 			return p;
3278 		} else {
3279 			// skip to end of line
3280 			SkipRestOfLine( &p );
3281 		}
3282 	}
3283 	*/
3284 
3285 	return NULL;
3286 }
3287 
3288 /*
3289 ==================
3290 R_FindShaderByName
3291 
3292 Will always return a valid shader, but it might be the
3293 default shader if the real one can't be found.
3294 ==================
3295 */
R_FindShaderByName(const char * name)3296 shader_t *R_FindShaderByName( const char *name ) {
3297 	char strippedName[MAX_QPATH];
3298 	int hash;
3299 	shader_t    *sh;
3300 
3301 	if ( ( name == NULL ) || ( name[0] == 0 ) ) {
3302 		return tr.defaultShader;
3303 	}
3304 
3305 	COM_StripExtension( name, strippedName, sizeof( strippedName ) );
3306 
3307 	hash = generateHashValue( strippedName );
3308 
3309 	//
3310 	// see if the shader is already loaded
3311 	//
3312 	for ( sh = hashTable[hash]; sh; sh = sh->next ) {
3313 		// NOTE: if there was no shader or image available with the name strippedName
3314 		// then a default shader is created with lightmapIndex == LIGHTMAP_NONE, so we
3315 		// have to check all default shaders otherwise for every call to R_FindShader
3316 		// with that same strippedName a new default shader is created.
3317 		if ( Q_stricmp( sh->name, strippedName ) == 0 ) {
3318 			// match found
3319 			return sh;
3320 		}
3321 	}
3322 
3323 	return tr.defaultShader;
3324 }
3325 
3326 
3327 /*
3328 ===============
3329 R_FindShader
3330 
3331 Will always return a valid shader, but it might be the
3332 default shader if the real one can't be found.
3333 
3334 In the interest of not requiring an explicit shader text entry to
3335 be defined for every single image used in the game, three default
3336 shader behaviors can be auto-created for any image:
3337 
3338 If lightmapIndex == LIGHTMAP_NONE, then the image will have
3339 dynamic diffuse lighting applied to it, as apropriate for most
3340 entity skin surfaces.
3341 
3342 If lightmapIndex == LIGHTMAP_2D, then the image will be used
3343 for 2D rendering unless an explicit shader is found
3344 
3345 If lightmapIndex == LIGHTMAP_BY_VERTEX, then the image will use
3346 the vertex rgba modulate values, as apropriate for misc_model
3347 pre-lit surfaces.
3348 
3349 Other lightmapIndex values will have a lightmap stage created
3350 and src*dest blending applied with the texture, as apropriate for
3351 most world construction surfaces.
3352 
3353 ===============
3354 */
R_FindShader(const char * name,int lightmapIndex,qboolean mipRawImage)3355 shader_t *R_FindShader( const char *name, int lightmapIndex, qboolean mipRawImage ) {
3356 	char strippedName[MAX_QPATH];
3357 	int hash;
3358 	char        *shaderText;
3359 	image_t     *image;
3360 	shader_t    *sh;
3361 
3362 	if ( name[0] == 0 ) {
3363 		return tr.defaultShader;
3364 	}
3365 
3366 	// use (fullbright) vertex lighting if the bsp file doesn't have
3367 	// lightmaps
3368 	if ( lightmapIndex >= 0 && lightmapIndex >= tr.numLightmaps ) {
3369 		lightmapIndex = LIGHTMAP_BY_VERTEX;
3370 	} else if ( lightmapIndex < LIGHTMAP_2D ) {
3371 		// negative lightmap indexes cause stray pointers (think tr.lightmaps[lightmapIndex])
3372 		ri.Printf( PRINT_WARNING, "WARNING: shader '%s' has invalid lightmap index of %d\n", name, lightmapIndex  );
3373 		lightmapIndex = LIGHTMAP_BY_VERTEX;
3374 	}
3375 
3376 	COM_StripExtension( name, strippedName, sizeof( strippedName ) );
3377 
3378 	hash = generateHashValue( strippedName );
3379 
3380 	//
3381 	// see if the shader is already loaded
3382 	//
3383 	for ( sh = hashTable[hash]; sh; sh = sh->next ) {
3384 		// index by name
3385 
3386 		// Ridah, modified this so we don't keep trying to load an invalid lightmap shader
3387 /*
3388 		if ( sh->lightmapIndex == lightmapIndex &&
3389 			!Q_stricmp(sh->name, strippedName)) {
3390 			// match found
3391 			return sh;
3392 		}
3393 */
3394 		if ( ( ( sh->lightmapIndex == lightmapIndex ) || ( sh->lightmapIndex < 0 && lightmapIndex >= 0 ) ) &&
3395 			 !Q_stricmp( sh->name, strippedName ) ) {
3396 			// match found
3397 			return sh;
3398 		}
3399 	}
3400 
3401 	InitShader( strippedName, lightmapIndex );
3402 
3403 	//
3404 	// attempt to define shader from an explicit parameter file
3405 	//
3406 	shaderText = FindShaderInShaderText( strippedName );
3407 	if ( shaderText ) {
3408 		// enable this when building a pak file to get a global list
3409 		// of all explicit shaders
3410 		if ( r_printShaders->integer ) {
3411 			ri.Printf( PRINT_ALL, "*SHADER* %s\n", name );
3412 		}
3413 
3414 		if ( !ParseShader( &shaderText ) ) {
3415 			// had errors, so use default shader
3416 			shader.defaultShader = qtrue;
3417 		}
3418 		sh = FinishShader();
3419 		return sh;
3420 	}
3421 
3422 
3423 	//
3424 	// if not defined in the in-memory shader descriptions,
3425 	// look for a single supported image file
3426 	//
3427 	{
3428 		imgFlags_t flags;
3429 
3430 		flags = IMGFLAG_NONE;
3431 
3432 		if (mipRawImage)
3433 		{
3434 			flags |= IMGFLAG_MIPMAP | IMGFLAG_PICMIP;
3435 
3436 			if (r_genNormalMaps->integer)
3437 				flags |= IMGFLAG_GENNORMALMAP;
3438 		}
3439 		else
3440 		{
3441 			flags |= IMGFLAG_CLAMPTOEDGE;
3442 		}
3443 
3444 		image = R_FindImageFile( name, IMGTYPE_COLORALPHA, flags );
3445 		if ( !image ) {
3446 			ri.Printf( PRINT_DEVELOPER, "Couldn't find image file for shader %s\n", name );
3447 			shader.defaultShader = qtrue;
3448 			return FinishShader();
3449 		}
3450 	}
3451 
3452 	//
3453 	// create the default shading commands
3454 	//
3455 	if ( shader.lightmapIndex == LIGHTMAP_NONE ) {
3456 		// dynamic colors at vertexes
3457 		stages[0].bundle[0].image[0] = image;
3458 		stages[0].active = qtrue;
3459 		stages[0].rgbGen = CGEN_LIGHTING_DIFFUSE;
3460 		stages[0].stateBits = GLS_DEFAULT;
3461 	} else if ( shader.lightmapIndex == LIGHTMAP_BY_VERTEX ) {
3462 		// explicit colors at vertexes
3463 		stages[0].bundle[0].image[0] = image;
3464 		stages[0].active = qtrue;
3465 		stages[0].rgbGen = CGEN_EXACT_VERTEX;
3466 		stages[0].alphaGen = AGEN_SKIP;
3467 		stages[0].stateBits = GLS_DEFAULT;
3468 	} else if ( shader.lightmapIndex == LIGHTMAP_2D ) {
3469 		// GUI elements
3470 		stages[0].bundle[0].image[0] = image;
3471 		stages[0].active = qtrue;
3472 		stages[0].rgbGen = CGEN_VERTEX;
3473 		stages[0].alphaGen = AGEN_VERTEX;
3474 		stages[0].stateBits = GLS_DEPTHTEST_DISABLE |
3475 							  GLS_SRCBLEND_SRC_ALPHA |
3476 							  GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA;
3477 	} else if ( shader.lightmapIndex == LIGHTMAP_WHITEIMAGE ) {
3478 		// fullbright level
3479 		stages[0].bundle[0].image[0] = tr.whiteImage;
3480 		stages[0].active = qtrue;
3481 		stages[0].rgbGen = CGEN_IDENTITY_LIGHTING;
3482 		stages[0].stateBits = GLS_DEFAULT;
3483 
3484 		stages[1].bundle[0].image[0] = image;
3485 		stages[1].active = qtrue;
3486 		stages[1].rgbGen = CGEN_IDENTITY;
3487 		stages[1].stateBits |= GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO;
3488 	} else {
3489 		// two pass lightmap
3490 		stages[0].bundle[0].image[0] = tr.lightmaps[shader.lightmapIndex];
3491 		stages[0].bundle[0].isLightmap = qtrue;
3492 		stages[0].active = qtrue;
3493 		stages[0].rgbGen = CGEN_IDENTITY;   // lightmaps are scaled on creation
3494 		// for identitylight
3495 		stages[0].stateBits = GLS_DEFAULT;
3496 
3497 		stages[1].bundle[0].image[0] = image;
3498 		stages[1].active = qtrue;
3499 		stages[1].rgbGen = CGEN_IDENTITY;
3500 		stages[1].stateBits |= GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO;
3501 	}
3502 
3503 	return FinishShader();
3504 }
3505 
3506 
RE_RegisterShaderFromImage(const char * name,int lightmapIndex,image_t * image,qboolean mipRawImage)3507 qhandle_t RE_RegisterShaderFromImage( const char *name, int lightmapIndex, image_t *image, qboolean mipRawImage ) {
3508 	int hash;
3509 	shader_t    *sh;
3510 
3511 	hash = generateHashValue( name );
3512 
3513 	// probably not necessary since this function
3514 	// only gets called from tr_font.c with lightmapIndex == LIGHTMAP_2D
3515 	// but better safe than sorry.
3516 	if ( lightmapIndex >= tr.numLightmaps ) {
3517 		lightmapIndex = LIGHTMAP_WHITEIMAGE;
3518 	}
3519 
3520 	//
3521 	// see if the shader is already loaded
3522 	//
3523 	for ( sh = hashTable[hash]; sh; sh = sh->next ) {
3524 		// NOTE: if there was no shader or image available with the name strippedName
3525 		// then a default shader is created with lightmapIndex == LIGHTMAP_NONE, so we
3526 		// have to check all default shaders otherwise for every call to R_FindShader
3527 		// with that same strippedName a new default shader is created.
3528 		if ( ( sh->lightmapIndex == lightmapIndex || sh->defaultShader ) &&
3529 			 // index by name
3530 			 !Q_stricmp( sh->name, name ) ) {
3531 			// match found
3532 			return sh->index;
3533 		}
3534 	}
3535 
3536 	InitShader( name, lightmapIndex );
3537 
3538 	//
3539 	// create the default shading commands
3540 	//
3541 	if ( shader.lightmapIndex == LIGHTMAP_NONE ) {
3542 		// dynamic colors at vertexes
3543 		stages[0].bundle[0].image[0] = image;
3544 		stages[0].active = qtrue;
3545 		stages[0].rgbGen = CGEN_LIGHTING_DIFFUSE;
3546 		stages[0].stateBits = GLS_DEFAULT;
3547 	} else if ( shader.lightmapIndex == LIGHTMAP_BY_VERTEX ) {
3548 		// explicit colors at vertexes
3549 		stages[0].bundle[0].image[0] = image;
3550 		stages[0].active = qtrue;
3551 		stages[0].rgbGen = CGEN_EXACT_VERTEX;
3552 		stages[0].alphaGen = AGEN_SKIP;
3553 		stages[0].stateBits = GLS_DEFAULT;
3554 	} else if ( shader.lightmapIndex == LIGHTMAP_2D ) {
3555 		// GUI elements
3556 		stages[0].bundle[0].image[0] = image;
3557 		stages[0].active = qtrue;
3558 		stages[0].rgbGen = CGEN_VERTEX;
3559 		stages[0].alphaGen = AGEN_VERTEX;
3560 		stages[0].stateBits = GLS_DEPTHTEST_DISABLE |
3561 							  GLS_SRCBLEND_SRC_ALPHA |
3562 							  GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA;
3563 	} else if ( shader.lightmapIndex == LIGHTMAP_WHITEIMAGE ) {
3564 		// fullbright level
3565 		stages[0].bundle[0].image[0] = tr.whiteImage;
3566 		stages[0].active = qtrue;
3567 		stages[0].rgbGen = CGEN_IDENTITY_LIGHTING;
3568 		stages[0].stateBits = GLS_DEFAULT;
3569 
3570 		stages[1].bundle[0].image[0] = image;
3571 		stages[1].active = qtrue;
3572 		stages[1].rgbGen = CGEN_IDENTITY;
3573 		stages[1].stateBits |= GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO;
3574 	} else {
3575 		// two pass lightmap
3576 		stages[0].bundle[0].image[0] = tr.lightmaps[shader.lightmapIndex];
3577 		stages[0].bundle[0].isLightmap = qtrue;
3578 		stages[0].active = qtrue;
3579 		stages[0].rgbGen = CGEN_IDENTITY;   // lightmaps are scaled on creation
3580 		// for identitylight
3581 		stages[0].stateBits = GLS_DEFAULT;
3582 
3583 		stages[1].bundle[0].image[0] = image;
3584 		stages[1].active = qtrue;
3585 		stages[1].rgbGen = CGEN_IDENTITY;
3586 		stages[1].stateBits |= GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO;
3587 	}
3588 
3589 	sh = FinishShader();
3590 	return sh->index;
3591 }
3592 
3593 
3594 /*
3595 ====================
3596 RE_RegisterShaderLightMap
3597 
3598 This is the exported shader entry point for the rest of the system
3599 It will always return an index that will be valid.
3600 
3601 This should really only be used for explicit shaders, because there is no
3602 way to ask for different implicit lighting modes (vertex, lightmap, etc)
3603 ====================
3604 */
RE_RegisterShaderLightMap(const char * name,int lightmapIndex)3605 qhandle_t RE_RegisterShaderLightMap( const char *name, int lightmapIndex ) {
3606 	shader_t    *sh;
3607 
3608 	if ( strlen( name ) >= MAX_QPATH ) {
3609 		ri.Printf( PRINT_ALL, "Shader name exceeds MAX_QPATH\n" );
3610 		return 0;
3611 	}
3612 
3613 	sh = R_FindShader( name, lightmapIndex, qtrue );
3614 
3615 	// we want to return 0 if the shader failed to
3616 	// load for some reason, but R_FindShader should
3617 	// still keep a name allocated for it, so if
3618 	// something calls RE_RegisterShader again with
3619 	// the same name, we don't try looking for it again
3620 	if ( sh->defaultShader ) {
3621 		return 0;
3622 	}
3623 
3624 	return sh->index;
3625 }
3626 
3627 
3628 /*
3629 ====================
3630 RE_RegisterShader
3631 
3632 This is the exported shader entry point for the rest of the system
3633 It will always return an index that will be valid.
3634 
3635 This should really only be used for explicit shaders, because there is no
3636 way to ask for different implicit lighting modes (vertex, lightmap, etc)
3637 ====================
3638 */
RE_RegisterShader(const char * name)3639 qhandle_t RE_RegisterShader( const char *name ) {
3640 	shader_t    *sh;
3641 
3642 	if ( strlen( name ) >= MAX_QPATH ) {
3643 		ri.Printf( PRINT_ALL, "Shader name exceeds MAX_QPATH\n" );
3644 		return 0;
3645 	}
3646 
3647 	sh = R_FindShader( name, LIGHTMAP_2D, qtrue );
3648 
3649 	// we want to return 0 if the shader failed to
3650 	// load for some reason, but R_FindShader should
3651 	// still keep a name allocated for it, so if
3652 	// something calls RE_RegisterShader again with
3653 	// the same name, we don't try looking for it again
3654 	if ( sh->defaultShader ) {
3655 		return 0;
3656 	}
3657 
3658 	return sh->index;
3659 }
3660 
3661 
3662 /*
3663 ====================
3664 RE_RegisterShaderNoMip
3665 
3666 For menu graphics that should never be picmiped
3667 ====================
3668 */
RE_RegisterShaderNoMip(const char * name)3669 qhandle_t RE_RegisterShaderNoMip( const char *name ) {
3670 	shader_t    *sh;
3671 
3672 	if ( strlen( name ) >= MAX_QPATH ) {
3673 		ri.Printf( PRINT_ALL, "Shader name exceeds MAX_QPATH\n" );
3674 		return 0;
3675 	}
3676 
3677 	sh = R_FindShader( name, LIGHTMAP_2D, qfalse );
3678 
3679 	// we want to return 0 if the shader failed to
3680 	// load for some reason, but R_FindShader should
3681 	// still keep a name allocated for it, so if
3682 	// something calls RE_RegisterShader again with
3683 	// the same name, we don't try looking for it again
3684 	if ( sh->defaultShader ) {
3685 		return 0;
3686 	}
3687 
3688 	return sh->index;
3689 }
3690 
3691 
3692 /*
3693 ====================
3694 R_GetShaderByHandle
3695 
3696 When a handle is passed in by another module, this range checks
3697 it and returns a valid (possibly default) shader_t to be used internally.
3698 ====================
3699 */
R_GetShaderByHandle(qhandle_t hShader)3700 shader_t *R_GetShaderByHandle( qhandle_t hShader ) {
3701 	if ( hShader < 0 ) {
3702 		ri.Printf( PRINT_WARNING, "R_GetShaderByHandle: out of range hShader '%d'\n", hShader );
3703 		return tr.defaultShader;
3704 	}
3705 	if ( hShader >= tr.numShaders ) {
3706 		ri.Printf( PRINT_WARNING, "R_GetShaderByHandle: out of range hShader '%d'\n", hShader );
3707 		return tr.defaultShader;
3708 	}
3709 	return tr.shaders[hShader];
3710 }
3711 
3712 /*
3713 ===============
3714 R_ShaderList_f
3715 
3716 Dump information on all valid shaders to the console
3717 A second parameter will cause it to print in sorted order
3718 ===============
3719 */
R_ShaderList_f(void)3720 void    R_ShaderList_f( void ) {
3721 	int i;
3722 	int count;
3723 	shader_t    *shader;
3724 
3725 	ri.Printf( PRINT_ALL, "-----------------------\n" );
3726 
3727 	count = 0;
3728 	for ( i = 0 ; i < tr.numShaders ; i++ ) {
3729 		if ( ri.Cmd_Argc() > 1 ) {
3730 			shader = tr.sortedShaders[i];
3731 		} else {
3732 			shader = tr.shaders[i];
3733 		}
3734 
3735 		ri.Printf( PRINT_ALL, "%i ", shader->numUnfoggedPasses );
3736 
3737 		if ( shader->lightmapIndex >= 0 ) {
3738 			ri.Printf( PRINT_ALL, "L " );
3739 		} else {
3740 			ri.Printf( PRINT_ALL, "  " );
3741 		}
3742 		if ( shader->explicitlyDefined ) {
3743 			ri.Printf( PRINT_ALL, "E " );
3744 		} else {
3745 			ri.Printf( PRINT_ALL, "  " );
3746 		}
3747 
3748 		if ( shader->optimalStageIteratorFunc == RB_StageIteratorGeneric ) {
3749 			ri.Printf( PRINT_ALL, "gen " );
3750 		} else if ( shader->optimalStageIteratorFunc == RB_StageIteratorSky ) {
3751 			ri.Printf( PRINT_ALL, "sky " );
3752 		} else {
3753 			ri.Printf( PRINT_ALL, "    " );
3754 		}
3755 
3756 		if ( shader->defaultShader ) {
3757 			ri.Printf( PRINT_ALL,  ": %s (DEFAULTED)\n", shader->name );
3758 		} else {
3759 			ri.Printf( PRINT_ALL,  ": %s\n", shader->name );
3760 		}
3761 		count++;
3762 	}
3763 	ri.Printf( PRINT_ALL, "%i total shaders\n", count );
3764 	ri.Printf( PRINT_ALL, "------------------\n" );
3765 }
3766 
3767 // Ridah, optimized shader loading
3768 
3769 #define MAX_SHADER_STRING_POINTERS  100000
3770 shaderStringPointer_t shaderStringPointerList[MAX_SHADER_STRING_POINTERS];
3771 
3772 /*
3773 ====================
3774 BuildShaderChecksumLookup
3775 ====================
3776 */
BuildShaderChecksumLookup(void)3777 static void BuildShaderChecksumLookup( void ) {
3778 	char *p = s_shaderText, *pOld;
3779 	char *token;
3780 	unsigned short int checksum;
3781 	int numShaderStringPointers = 0;
3782 
3783 	// initialize the checksums
3784 	memset( shaderChecksumLookup, 0, sizeof( shaderChecksumLookup ) );
3785 
3786 	if ( !p ) {
3787 		return;
3788 	}
3789 
3790 	// loop for all labels
3791 	while ( 1 ) {
3792 
3793 		pOld = p;
3794 
3795 		token = COM_ParseExt( &p, qtrue );
3796 		if ( token[0] == 0 ) {
3797 			break;
3798 		}
3799 
3800 		if ( !Q_stricmp( token, "{" ) ) {
3801 			// skip braced section
3802 			SkipBracedSection( &p, 0 );
3803 			continue;
3804 		}
3805 
3806 		// get it's checksum
3807 		checksum = generateHashValue( token );
3808 
3809 		// if it's not currently used
3810 		if ( !shaderChecksumLookup[checksum].pStr ) {
3811 			shaderChecksumLookup[checksum].pStr = pOld;
3812 		} else {
3813 			// create a new list item
3814 			shaderStringPointer_t *newStrPtr;
3815 
3816 			if ( numShaderStringPointers >= MAX_SHADER_STRING_POINTERS ) {
3817 				ri.Error( ERR_DROP, "MAX_SHADER_STRING_POINTERS exceeded, too many shaders" );
3818 			}
3819 
3820 			newStrPtr = &shaderStringPointerList[numShaderStringPointers++]; //ri.Hunk_Alloc( sizeof( shaderStringPointer_t ), h_low );
3821 			newStrPtr->pStr = pOld;
3822 			newStrPtr->next = shaderChecksumLookup[checksum].next;
3823 			shaderChecksumLookup[checksum].next = newStrPtr;
3824 		}
3825 	}
3826 }
3827 // done.
3828 
3829 
3830 /*
3831 ====================
3832 ScanAndLoadShaderFiles
3833 
3834 Finds and loads all .shader files, combining them into
3835 a single large text block that can be scanned for shader names
3836 =====================
3837 */
3838 #define MAX_SHADER_FILES    4096
ScanAndLoadShaderFiles(void)3839 static void ScanAndLoadShaderFiles( void ) {
3840 	char **shaderFiles;
3841 	char *buffers[MAX_SHADER_FILES] = {NULL};
3842 	char *p;
3843 	int numShaderFiles;
3844 	int i;
3845 	char *token, *textEnd;
3846 	char shaderName[MAX_QPATH];
3847 	int shaderLine;
3848 
3849 	long sum = 0, summand;
3850 	// scan for shader files
3851 	shaderFiles = ri.FS_ListFiles( "scripts", ".shader", &numShaderFiles );
3852 
3853 	if ( !shaderFiles || !numShaderFiles ) {
3854 		ri.Printf( PRINT_WARNING, "WARNING: no shader files found\n" );
3855 		return;
3856 	}
3857 
3858 	if ( numShaderFiles > MAX_SHADER_FILES ) {
3859 		numShaderFiles = MAX_SHADER_FILES;
3860 	}
3861 
3862 	// load and parse shader files
3863 	for ( i = 0; i < numShaderFiles; i++ )
3864 	{
3865 		char filename[MAX_QPATH];
3866 
3867 		// look for a .mtr file first
3868 		{
3869 			char *ext;
3870 			Com_sprintf( filename, sizeof( filename ), "scripts/%s", shaderFiles[i] );
3871 			if ( (ext = strrchr(filename, '.')) )
3872 			{
3873 				strcpy(ext, ".mtr");
3874 			}
3875 
3876 			if ( ri.FS_ReadFile( filename, NULL ) <= 0 )
3877 			{
3878 				Com_sprintf( filename, sizeof( filename ), "scripts/%s", shaderFiles[i] );
3879 			}
3880 		}
3881 		ri.Printf( PRINT_DEVELOPER, "...loading '%s'\n", filename );
3882 		summand = ri.FS_ReadFile( filename, (void **)&buffers[i] );
3883 
3884 		if ( !buffers[i] )
3885 			ri.Error( ERR_DROP, "Couldn't load %s", filename );
3886 
3887 		// Do a simple check on the shader structure in that file to make sure one bad shader file cannot fuck up all other shaders.
3888 		p = buffers[i];
3889 		COM_BeginParseSession(filename);
3890 		while(1)
3891 		{
3892 			token = COM_ParseExt(&p, qtrue);
3893 
3894 			if(!*token)
3895 				break;
3896 
3897 			Q_strncpyz(shaderName, token, sizeof(shaderName));
3898 			shaderLine = COM_GetCurrentParseLine();
3899 
3900 			token = COM_ParseExt(&p, qtrue);
3901 			if( !Q_stricmp( shaderName, token ) ) {
3902 				ri.Printf(PRINT_WARNING, "WARNING: In shader file %s...Invalid shader name \"%s\" on line %d.\n",
3903 							filename, shaderName, shaderLine);
3904 				break;
3905 			}
3906 
3907 			if(token[0] != '{' || token[1] != '\0')
3908 			{
3909 				ri.Printf(PRINT_WARNING, "WARNING: In shader file %s...Shader \"%s\" on line %d is missing opening brace",
3910 							filename, shaderName, shaderLine);
3911 				if (token[0])
3912 				{
3913 					ri.Printf(PRINT_WARNING, " (found \"%s\" on line %d)", token, COM_GetCurrentParseLine());
3914 				}
3915 				ri.Printf(PRINT_WARNING, "...Ignored\n");
3916 				ri.FS_FreeFile(buffers[i]);
3917 				buffers[i] = NULL;
3918 				break;
3919 			}
3920 
3921 			if(!SkipBracedSection(&p, 1))
3922 			{
3923 				ri.Printf(PRINT_WARNING, "WARNING: In shader file %s...Shader \"%s\" on line %d is missing closing brace",
3924 							filename, shaderName, shaderLine);
3925 				if( !Q_stricmp( filename, "common.shader" ) ) { // HACK...Broken shader in pak0.pk3
3926 					ri.Printf(PRINT_WARNING, "...Ignored\n");
3927 					ri.FS_FreeFile(buffers[i]);
3928 					buffers[i] = NULL;
3929 					break;
3930 				} else {
3931 					ri.Printf(PRINT_WARNING, ".\n");
3932 				}
3933 			}
3934 		}
3935 
3936 		if (buffers[i])
3937 			sum += summand;
3938 	}
3939 
3940 	// build single large buffer
3941 	s_shaderText = ri.Hunk_Alloc( sum + numShaderFiles*2, h_low );
3942 	s_shaderText[ 0 ] = '\0';
3943 	textEnd = s_shaderText;
3944 
3945 	// free in reverse order, so the temp files are all dumped
3946 	for ( i = numShaderFiles - 1; i >= 0 ; i-- )
3947 	{
3948 		if ( !buffers[i] )
3949 			continue;
3950 
3951 		strcat( textEnd, buffers[i] );
3952 		strcat( textEnd, "\n" );
3953 		textEnd += strlen( textEnd );
3954 		ri.FS_FreeFile( buffers[i] );
3955 	}
3956 
3957 	COM_Compress( s_shaderText );
3958 
3959 	// free up memory
3960 	ri.FS_FreeFileList( shaderFiles );
3961 
3962 	// Ridah, optimized shader loading (18ms on a P3-500 for sfm1.bsp)
3963 	BuildShaderChecksumLookup();
3964 	// done.
3965 }
3966 
3967 
3968 /*
3969 ====================
3970 CreateInternalShaders
3971 ====================
3972 */
CreateInternalShaders(void)3973 static void CreateInternalShaders( void ) {
3974 	tr.numShaders = 0;
3975 
3976 	// init the default shader
3977 	InitShader( "<default>", LIGHTMAP_NONE );
3978 	stages[0].bundle[0].image[0] = tr.defaultImage;
3979 	stages[0].active = qtrue;
3980 	stages[0].stateBits = GLS_DEFAULT;
3981 	tr.defaultShader = FinishShader();
3982 
3983 	// shadow shader is just a marker
3984 	Q_strncpyz( shader.name, "<stencil shadow>", sizeof( shader.name ) );
3985 	shader.sort = SS_STENCIL_SHADOW;
3986 	tr.shadowShader = FinishShader();
3987 }
3988 
CreateExternalShaders(void)3989 static void CreateExternalShaders( void ) {
3990 //	tr.projectionShadowShader = R_FindShader( "projectionShadow", LIGHTMAP_NONE, qtrue );
3991 	tr.flareShader = R_FindShader( "flareShader", LIGHTMAP_NONE, qtrue );
3992 
3993 	// Hack to make fogging work correctly on flares. Fog colors are calculated
3994 	// in tr_flare.c already.
3995 	if(!tr.flareShader->defaultShader)
3996 	{
3997 		int index;
3998 
3999 		for(index = 0; index < tr.flareShader->numUnfoggedPasses; index++)
4000 		{
4001 			tr.flareShader->stages[index]->adjustColorsForFog = ACFF_NONE;
4002 			tr.flareShader->stages[index]->stateBits |= GLS_DEPTHTEST_DISABLE;
4003 		}
4004 	}
4005 
4006 	tr.spotFlareShader = R_FindShader( "spotLight", LIGHTMAP_NONE, qtrue );
4007 //	tr.sunShader = R_FindShader( "sun", LIGHTMAP_NONE, qtrue );	//----(SA)	let sky shader set this
4008 	tr.sunflareShader_old[0] = R_FindShader( "sunflare1", LIGHTMAP_NONE, qtrue );
4009 //	tr.dlightShader = R_FindShader( "dlightshader", LIGHTMAP_NONE, qtrue );
4010 
4011 	tr.sunFlareShader = R_FindShader( "sunflare1", LIGHTMAP_NONE, qtrue);
4012 
4013 	// HACK: if sunflare is missing, make one using the flare image or dlight image
4014 	if (tr.sunFlareShader->defaultShader)
4015 	{
4016 		image_t *image;
4017 
4018 		if (!tr.flareShader->defaultShader && tr.flareShader->stages[0] && tr.flareShader->stages[0]->bundle[0].image[0])
4019 			image = tr.flareShader->stages[0]->bundle[0].image[0];
4020 		else
4021 			image = tr.dlightImage;
4022 
4023 
4024 		InitShader( "sunflare1", LIGHTMAP_NONE );
4025 		stages[0].bundle[0].image[0] = image;
4026 		stages[0].active = qtrue;
4027 		stages[0].stateBits = GLS_DEFAULT;
4028 		tr.sunFlareShader = FinishShader();
4029 	}
4030 }
4031 
4032 /*
4033 ==================
4034 R_InitShaders
4035 ==================
4036 */
R_InitShaders(void)4037 void R_InitShaders( void ) {
4038 
4039 	glfogNum = FOG_NONE;
4040 	ri.Cvar_Set( "r_waterFogColor", "0" );  // clear fog
4041 	ri.Cvar_Set( "r_mapFogColor", "0" );        //
4042 	ri.Cvar_Set( "r_savegameFogColor", "0" );
4043 
4044 	ri.Printf( PRINT_ALL, "Initializing Shaders\n" );
4045 
4046 	memset( hashTable, 0, sizeof( hashTable ) );
4047 
4048 	CreateInternalShaders();
4049 
4050 	ScanAndLoadShaderFiles();
4051 
4052 	CreateExternalShaders();
4053 }
4054