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