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