doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
draw_nv20.cpp
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 
29 #include "../idlib/precompiled.h"
30 #pragma hdrstop
31 
32 #include "tr_local.h"
33 
34 typedef enum {
39 
42 
43 GLuint fragmentDisplayListBase; // FPROG_NUM_FRAGMENT_PROGRAMS lists
44 
46 void RB_NV20_DependentAmbientPass( void );
47 
48 /*
49 =========================================================================================
50 
51 GENERAL INTERACTION RENDERING
52 
53 =========================================================================================
54 */
55 
56 /*
57 ====================
58 GL_SelectTextureNoClient
59 ====================
60 */
61 void GL_SelectTextureNoClient( int unit ) {
62  backEnd.glState.currenttmu = unit;
63  qglActiveTextureARB( GL_TEXTURE0_ARB + unit );
64  RB_LogComment( "glActiveTextureARB( %i )\n", unit );
65 }
66 
67 /*
68 ==================
69 RB_NV20_BumpAndLightFragment
70 ==================
71 */
72 static void RB_NV20_BumpAndLightFragment( void ) {
75  return;
76  }
77 
78  // program the nvidia register combiners
79  qglCombinerParameteriNV( GL_NUM_GENERAL_COMBINERS_NV, 3 );
80 
81  // stage 0 rgb performs the dot product
82  // SPARE0 = TEXTURE0 dot TEXTURE1
83  qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV,
85  qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV,
87  qglCombinerOutputNV( GL_COMBINER0_NV, GL_RGB,
89  GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE );
90 
91 
92  // stage 1 rgb multiplies texture 2 and 3 together
93  // SPARE1 = TEXTURE2 * TEXTURE3
94  qglCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_A_NV,
96  qglCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_B_NV,
98  qglCombinerOutputNV( GL_COMBINER1_NV, GL_RGB,
100  GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE );
101 
102  // stage 1 alpha does nohing
103 
104  // stage 2 color multiplies spare0 * spare 1 just for debugging
105  // SPARE0 = SPARE0 * SPARE1
106  qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_A_NV,
108  qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_B_NV,
110  qglCombinerOutputNV( GL_COMBINER2_NV, GL_RGB,
112  GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE );
113 
114  // stage 2 alpha multiples spare0 * spare 1
115  // SPARE0 = SPARE0 * SPARE1
116  qglCombinerInputNV( GL_COMBINER2_NV, GL_ALPHA, GL_VARIABLE_A_NV,
118  qglCombinerInputNV( GL_COMBINER2_NV, GL_ALPHA, GL_VARIABLE_B_NV,
120  qglCombinerOutputNV( GL_COMBINER2_NV, GL_ALPHA,
122  GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE );
123 
124  // final combiner
125  qglFinalCombinerInputNV( GL_VARIABLE_D_NV, GL_SPARE0_NV,
126  GL_UNSIGNED_IDENTITY_NV, GL_RGB );
127  qglFinalCombinerInputNV( GL_VARIABLE_A_NV, GL_ZERO,
128  GL_UNSIGNED_IDENTITY_NV, GL_RGB );
129  qglFinalCombinerInputNV( GL_VARIABLE_B_NV, GL_ZERO,
130  GL_UNSIGNED_IDENTITY_NV, GL_RGB );
131  qglFinalCombinerInputNV( GL_VARIABLE_C_NV, GL_ZERO,
132  GL_UNSIGNED_IDENTITY_NV, GL_RGB );
133  qglFinalCombinerInputNV( GL_VARIABLE_G_NV, GL_SPARE0_NV,
134  GL_UNSIGNED_IDENTITY_NV, GL_ALPHA );
135 }
136 
137 /*
138 ==================
139 RB_NV20_DI_BumpAndLightPass
140 
141 We are going to write alpha as light falloff * ( bump dot light ) * lightProjection
142 If the light isn't a monoLightShader, the lightProjection will be skipped, because
143 it will have to be done on an itterated basis
144 ==================
145 */
146 static void RB_NV20_DI_BumpAndLightPass( const drawInteraction_t *din, bool monoLightShader ) {
147  RB_LogComment( "---------- RB_NV_BumpAndLightPass ----------\n" );
148 
150 
151  // texture 0 is the normalization cube map
152  // GL_TEXTURE0_ARB will be the normalized vector
153  // towards the light source
154 #ifdef MACOS_X
155  GL_SelectTexture( 0 );
156  qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
157 #else
159 #endif
160  if ( din->ambientLight ) {
162  } else {
164  }
165 
166  // texture 1 will be the per-surface bump map
167 #ifdef MACOS_X
168  GL_SelectTexture( 1 );
169  qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
170 #else
172 #endif
173  din->bumpImage->Bind();
174 
175  // texture 2 will be the light falloff texture
176 #ifdef MACOS_X
177  GL_SelectTexture( 2 );
178  qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
179 #else
181 #endif
182  din->lightFalloffImage->Bind();
183 
184  // texture 3 will be the light projection texture
185 #ifdef MACOS_X
186  GL_SelectTexture( 3 );
187  qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
188 #else
190 #endif
191  if ( monoLightShader ) {
192  din->lightImage->Bind();
193  } else {
194  // if the projected texture is multi-colored, we
195  // will need to do it in subsequent passes
197  }
198 
199  // bind our "fragment program"
200  RB_NV20_BumpAndLightFragment();
201 
202  // draw it
205 }
206 
207 
208 /*
209 ==================
210 RB_NV20_DiffuseColorFragment
211 ==================
212 */
213 static void RB_NV20_DiffuseColorFragment( void ) {
216  return;
217  }
218 
219  // program the nvidia register combiners
220  qglCombinerParameteriNV( GL_NUM_GENERAL_COMBINERS_NV, 1 );
221 
222  // stage 0 is free, so we always do the multiply of the vertex color
223  // when the vertex color is inverted, qglCombinerInputNV(GL_VARIABLE_B_NV) will be changed
224  qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV,
226  qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV,
228  qglCombinerOutputNV( GL_COMBINER0_NV, GL_RGB,
230  GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE );
231 
232  qglCombinerOutputNV( GL_COMBINER0_NV, GL_ALPHA,
234  GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE );
235 
236 
237  // for GL_CONSTANT_COLOR0_NV * TEXTURE0 * TEXTURE1
238  qglFinalCombinerInputNV( GL_VARIABLE_A_NV, GL_CONSTANT_COLOR0_NV,
239  GL_UNSIGNED_IDENTITY_NV, GL_RGB );
240  qglFinalCombinerInputNV( GL_VARIABLE_B_NV, GL_E_TIMES_F_NV,
241  GL_UNSIGNED_IDENTITY_NV, GL_RGB );
242  qglFinalCombinerInputNV( GL_VARIABLE_C_NV, GL_ZERO,
243  GL_UNSIGNED_IDENTITY_NV, GL_RGB );
244  qglFinalCombinerInputNV( GL_VARIABLE_D_NV, GL_ZERO,
245  GL_UNSIGNED_IDENTITY_NV, GL_RGB );
246  qglFinalCombinerInputNV( GL_VARIABLE_E_NV, GL_TEXTURE0_ARB,
247  GL_UNSIGNED_IDENTITY_NV, GL_RGB );
248  qglFinalCombinerInputNV( GL_VARIABLE_F_NV, GL_TEXTURE1_ARB,
249  GL_UNSIGNED_IDENTITY_NV, GL_RGB );
250  qglFinalCombinerInputNV( GL_VARIABLE_G_NV, GL_ZERO,
251  GL_UNSIGNED_IDENTITY_NV, GL_ALPHA );
252 
253 }
254 
255 /*
256 ==================
257 RB_NV20_DI_DiffuseColorPass
258 
259 ==================
260 */
261 static void RB_NV20_DI_DiffuseColorPass( const drawInteraction_t *din ) {
262  RB_LogComment( "---------- RB_NV20_DiffuseColorPass ----------\n" );
263 
265  | backEnd.depthFunc );
266 
267  // texture 0 will be the per-surface diffuse map
268 #ifdef MACOS_X
269  GL_SelectTexture( 0 );
270  qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
271 #else
273 #endif
274  din->diffuseImage->Bind();
275 
276  // texture 1 will be the light projected texture
277 #ifdef MACOS_X
278  GL_SelectTexture( 1 );
279  qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
280 #else
282 #endif
283  din->lightImage->Bind();
284 
285  // texture 2 is disabled
286 #ifdef MACOS_X
287  GL_SelectTexture( 2 );
288  qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
289 #else
291 #endif
293 
294  // texture 3 is disabled
295 #ifdef MACOS_X
296  GL_SelectTexture( 3 );
297  qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
298 #else
300 #endif
302 
303  // bind our "fragment program"
304  RB_NV20_DiffuseColorFragment();
305 
306  // override one parameter for inverted vertex color
307  if ( din->vertexColor == SVC_INVERSE_MODULATE ) {
308  qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV,
310  }
311 
312  // draw it
315 }
316 
317 
318 /*
319 ==================
320 RB_NV20_SpecularColorFragment
321 ==================
322 */
323 static void RB_NV20_SpecularColorFragment( void ) {
326  return;
327  }
328 
329  // program the nvidia register combiners
330  qglCombinerParameteriNV( GL_NUM_GENERAL_COMBINERS_NV, 4 );
331 
332  // we want GL_CONSTANT_COLOR1_NV * PRIMARY_COLOR * TEXTURE2 * TEXTURE3 * specular( TEXTURE0 * TEXTURE1 )
333 
334  // stage 0 rgb performs the dot product
335  // GL_SPARE0_NV = ( TEXTURE0 dot TEXTURE1 - 0.5 ) * 2
336  // TEXTURE2 = TEXTURE2 * PRIMARY_COLOR
337  // the scale and bias steepen the specular curve
338  qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV,
340  qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV,
342  qglCombinerOutputNV( GL_COMBINER0_NV, GL_RGB,
344  GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_TRUE, GL_FALSE, GL_FALSE );
345 
346  // stage 0 alpha does nothing
347 
348  // stage 1 color takes bump * bump
349  // GL_SPARE0_NV = ( GL_SPARE0_NV * GL_SPARE0_NV - 0.5 ) * 2
350  // the scale and bias steepen the specular curve
351  qglCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_A_NV,
353  qglCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_B_NV,
355  qglCombinerOutputNV( GL_COMBINER1_NV, GL_RGB,
357  GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE );
358 
359  // stage 1 alpha does nothing
360 
361  // stage 2 color
362  // GL_SPARE0_NV = GL_SPARE0_NV * TEXTURE3
363  // SECONDARY_COLOR = CONSTANT_COLOR * TEXTURE2
364  qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_A_NV,
366  qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_B_NV,
368  qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_C_NV,
370  qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_D_NV,
372  qglCombinerOutputNV( GL_COMBINER2_NV, GL_RGB,
374  GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE );
375 
376  // stage 2 alpha does nothing
377 
378 
379  // stage 3 scales the texture by the vertex color
380  qglCombinerInputNV( GL_COMBINER3_NV, GL_RGB, GL_VARIABLE_A_NV,
382  qglCombinerInputNV( GL_COMBINER3_NV, GL_RGB, GL_VARIABLE_B_NV,
384  qglCombinerOutputNV( GL_COMBINER3_NV, GL_RGB,
386  GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE );
387 
388  // stage 3 alpha does nothing
389 
390  // final combiner = GL_SPARE0_NV * SECONDARY_COLOR + PRIMARY_COLOR * SECONDARY_COLOR
391  qglFinalCombinerInputNV( GL_VARIABLE_A_NV, GL_SPARE0_NV,
392  GL_UNSIGNED_IDENTITY_NV, GL_RGB );
393  qglFinalCombinerInputNV( GL_VARIABLE_B_NV, GL_SECONDARY_COLOR_NV,
394  GL_UNSIGNED_IDENTITY_NV, GL_RGB );
395  qglFinalCombinerInputNV( GL_VARIABLE_C_NV, GL_ZERO,
396  GL_UNSIGNED_IDENTITY_NV, GL_RGB );
397  qglFinalCombinerInputNV( GL_VARIABLE_D_NV, GL_E_TIMES_F_NV,
398  GL_UNSIGNED_IDENTITY_NV, GL_RGB );
399  qglFinalCombinerInputNV( GL_VARIABLE_E_NV, GL_SPARE0_NV,
400  GL_UNSIGNED_IDENTITY_NV, GL_RGB );
401  qglFinalCombinerInputNV( GL_VARIABLE_F_NV, GL_SECONDARY_COLOR_NV,
402  GL_UNSIGNED_IDENTITY_NV, GL_RGB );
403  qglFinalCombinerInputNV( GL_VARIABLE_G_NV, GL_ZERO,
404  GL_UNSIGNED_IDENTITY_NV, GL_ALPHA );
405 }
406 
407 
408 /*
409 ==================
410 RB_NV20_DI_SpecularColorPass
411 
412 ==================
413 */
414 static void RB_NV20_DI_SpecularColorPass( const drawInteraction_t *din ) {
415  RB_LogComment( "---------- RB_NV20_SpecularColorPass ----------\n" );
416 
418  | backEnd.depthFunc );
419 
420  // texture 0 is the normalization cube map for the half angle
421 #ifdef MACOS_X
422  GL_SelectTexture( 0 );
423  qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
424 #else
426 #endif
428 
429  // texture 1 will be the per-surface bump map
430 #ifdef MACOS_X
431  GL_SelectTexture( 1 );
432  qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
433 #else
435 #endif
436  din->bumpImage->Bind();
437 
438  // texture 2 will be the per-surface specular map
439 #ifdef MACOS_X
440  GL_SelectTexture( 2 );
441  qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
442 #else
444 #endif
445  din->specularImage->Bind();
446 
447  // texture 3 will be the light projected texture
448 #ifdef MACOS_X
449  GL_SelectTexture( 3 );
450  qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
451 #else
453 #endif
454  din->lightImage->Bind();
455 
456  // bind our "fragment program"
457  RB_NV20_SpecularColorFragment();
458 
459  // override one parameter for inverted vertex color
460  if ( din->vertexColor == SVC_INVERSE_MODULATE ) {
461  qglCombinerInputNV( GL_COMBINER3_NV, GL_RGB, GL_VARIABLE_B_NV,
463  }
464 
465  // draw it
468 }
469 
470 
471 
472 /*
473 ==================
474 RB_NV20_DiffuseAndSpecularColorFragment
475 ==================
476 */
477 static void RB_NV20_DiffuseAndSpecularColorFragment( void ) {
480  return;
481  }
482 
483  // program the nvidia register combiners
484  qglCombinerParameteriNV( GL_NUM_GENERAL_COMBINERS_NV, 3 );
485 
486  // GL_CONSTANT_COLOR0_NV will be the diffuse color
487  // GL_CONSTANT_COLOR1_NV will be the specular color
488 
489  // stage 0 rgb performs the dot product
490  // GL_SECONDARY_COLOR_NV = ( TEXTURE0 dot TEXTURE1 - 0.5 ) * 2
491  // the scale and bias steepen the specular curve
492  qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV,
494  qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV,
496  qglCombinerOutputNV( GL_COMBINER0_NV, GL_RGB,
498  GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_TRUE, GL_FALSE, GL_FALSE );
499 
500  // stage 0 alpha does nothing
501 
502  // stage 1 color takes bump * bump
503  // PRIMARY_COLOR = ( GL_SECONDARY_COLOR_NV * GL_SECONDARY_COLOR_NV - 0.5 ) * 2
504  // the scale and bias steepen the specular curve
505  qglCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_A_NV,
507  qglCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_B_NV,
509  qglCombinerOutputNV( GL_COMBINER1_NV, GL_RGB,
511  GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE );
512 
513  // stage 1 alpha does nothing
514 
515  // stage 2 color
516  // PRIMARY_COLOR = ( PRIMARY_COLOR * TEXTURE3 ) * 2
517  // SPARE0 = 1.0 * 1.0 (needed for final combiner)
518  qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_A_NV,
520  qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_B_NV,
522  qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_C_NV,
523  GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB );
524  qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_D_NV,
525  GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB );
526  qglCombinerOutputNV( GL_COMBINER2_NV, GL_RGB,
528  GL_SCALE_BY_TWO_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE );
529 
530  // stage 2 alpha does nothing
531 
532  // final combiner = TEXTURE2_ARB * CONSTANT_COLOR0_NV + PRIMARY_COLOR_NV * CONSTANT_COLOR1_NV
533  // alpha = GL_ZERO
534  qglFinalCombinerInputNV( GL_VARIABLE_A_NV, GL_CONSTANT_COLOR1_NV,
535  GL_UNSIGNED_IDENTITY_NV, GL_RGB );
536  qglFinalCombinerInputNV( GL_VARIABLE_B_NV, GL_SECONDARY_COLOR_NV,
537  GL_UNSIGNED_IDENTITY_NV, GL_RGB );
538  qglFinalCombinerInputNV( GL_VARIABLE_C_NV, GL_ZERO,
539  GL_UNSIGNED_IDENTITY_NV, GL_RGB );
540  qglFinalCombinerInputNV( GL_VARIABLE_D_NV, GL_E_TIMES_F_NV,
541  GL_UNSIGNED_IDENTITY_NV, GL_RGB );
542  qglFinalCombinerInputNV( GL_VARIABLE_E_NV, GL_TEXTURE2_ARB,
543  GL_UNSIGNED_IDENTITY_NV, GL_RGB );
544  qglFinalCombinerInputNV( GL_VARIABLE_F_NV, GL_CONSTANT_COLOR0_NV,
545  GL_UNSIGNED_IDENTITY_NV, GL_RGB );
546  qglFinalCombinerInputNV( GL_VARIABLE_G_NV, GL_ZERO,
547  GL_UNSIGNED_IDENTITY_NV, GL_ALPHA );
548 }
549 
550 
551 /*
552 ==================
553 RB_NV20_DI_DiffuseAndSpecularColorPass
554 
555 ==================
556 */
557 static void RB_NV20_DI_DiffuseAndSpecularColorPass( const drawInteraction_t *din ) {
558  RB_LogComment( "---------- RB_NV20_DI_DiffuseAndSpecularColorPass ----------\n" );
559 
561 
562  // texture 0 is the normalization cube map for the half angle
563 // still bound from RB_NV_BumpAndLightPass
564 // GL_SelectTextureNoClient( 0 );
565 // GL_Bind( tr.normalCubeMapImage );
566 
567  // texture 1 is the per-surface bump map
568 // still bound from RB_NV_BumpAndLightPass
569 // GL_SelectTextureNoClient( 1 );
570 // GL_Bind( din->bumpImage );
571 
572  // texture 2 is the per-surface diffuse map
573 #ifdef MACOS_X
574  GL_SelectTexture( 2 );
575  qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
576 #else
578 #endif
579  din->diffuseImage->Bind();
580 
581  // texture 3 is the per-surface specular map
582 #ifdef MACOS_X
583  GL_SelectTexture( 3 );
584  qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
585 #else
587 #endif
588  din->specularImage->Bind();
589 
590  // bind our "fragment program"
591  RB_NV20_DiffuseAndSpecularColorFragment();
592 
593  // draw it
596 }
597 
598 
599 /*
600 ==================
601 RB_NV20_DrawInteraction
602 ==================
603 */
604 static void RB_NV20_DrawInteraction( const drawInteraction_t *din ) {
605  const drawSurf_t *surf = din->surf;
606 
607  // load all the vertex program parameters
620 
621  // set the constant colors
622  qglCombinerParameterfvNV( GL_CONSTANT_COLOR0_NV, din->diffuseColor.ToFloatPtr() );
623  qglCombinerParameterfvNV( GL_CONSTANT_COLOR1_NV, din->specularColor.ToFloatPtr() );
624 
625  // vertex color passes should be pretty rare (cross-faded bump map surfaces), so always
626  // run them down as three-passes
627  if ( din->vertexColor != SVC_IGNORE ) {
628  qglEnableClientState( GL_COLOR_ARRAY );
629  RB_NV20_DI_BumpAndLightPass( din, false );
630  RB_NV20_DI_DiffuseColorPass( din );
631  RB_NV20_DI_SpecularColorPass( din );
632  qglDisableClientState( GL_COLOR_ARRAY );
633  return;
634  }
635 
636  qglColor3f( 1, 1, 1 );
637 
638  // on an ideal card, we would now just bind the textures and call a
639  // single pass vertex / fragment program, but
640  // on NV20, we need to decide which single / dual / tripple pass set of programs to use
641 
642  // ambient light could be done as a single pass if we want to optimize for it
643 
644  // monochrome light is two passes
646  if ( ( r_useNV20MonoLights.GetInteger() == 2 ) ||
648  // do a two-pass rendering
649  RB_NV20_DI_BumpAndLightPass( din, true );
650  RB_NV20_DI_DiffuseAndSpecularColorPass( din );
651  } else {
652  // general case is three passes
653  // ( bump dot lightDir ) * lightFalloff
654  // diffuse * lightProject
655  // specular * ( bump dot halfAngle extended ) * lightProject
656  RB_NV20_DI_BumpAndLightPass( din, false );
657  RB_NV20_DI_DiffuseColorPass( din );
658  RB_NV20_DI_SpecularColorPass( din );
659  }
660 }
661 
662 
663 /*
664 =============
665 RB_NV20_CreateDrawInteractions
666 
667 =============
668 */
669 static void RB_NV20_CreateDrawInteractions( const drawSurf_t *surf ) {
670  if ( !surf ) {
671  return;
672  }
673 
676 
677 #ifdef MACOS_X
678  GL_SelectTexture(0);
679  qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
680 #else
681  qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
682 
687 #endif
688 
689  for ( ; surf ; surf=surf->nextOnLight ) {
690  // set the vertex pointers
692  qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( idDrawVert ), ac->color );
693 #ifdef MACOS_X
694  GL_SelectTexture( 0 );
695  qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), ac->st.ToFloatPtr() );
696  GL_SelectTexture( 1 );
697  qglTexCoordPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->tangents[0].ToFloatPtr() );
698  GL_SelectTexture( 2 );
699  qglTexCoordPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->tangents[1].ToFloatPtr() );
700  GL_SelectTexture( 3 );
701  qglTexCoordPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->normal.ToFloatPtr() );
702  GL_SelectTexture( 0 );
703 #else
704  qglVertexAttribPointerARB( 11, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->normal.ToFloatPtr() );
705  qglVertexAttribPointerARB( 10, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[1].ToFloatPtr() );
706  qglVertexAttribPointerARB( 9, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[0].ToFloatPtr() );
707  qglVertexAttribPointerARB( 8, 2, GL_FLOAT, false, sizeof( idDrawVert ), ac->st.ToFloatPtr() );
708 #endif
709  qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() );
710 
711  RB_CreateSingleDrawInteractions( surf, RB_NV20_DrawInteraction );
712  }
713 
714 #ifndef MACOS_X
719 #endif
720 
721  // disable features
722 #ifdef MACOS_X
723  GL_SelectTexture( 3 );
725  qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
726 
727  GL_SelectTexture( 2 );
729  qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
730 
731  GL_SelectTexture( 1 );
733  qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
734 #else
737 
740 
743 #endif
744 
746  GL_SelectTexture( 0 );
747 
748  qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
749 
752 }
753 
754 
755 //======================================================================================
756 
757 
758 /*
759 ==================
760 RB_NV20_DrawInteractions
761 ==================
762 */
764  viewLight_t *vLight;
765 
766  //
767  // for each light, perform adding and shadowing
768  //
769  for ( vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) {
770  // do fogging later
771  if ( vLight->lightShader->IsFogLight() ) {
772  continue;
773  }
774  if ( vLight->lightShader->IsBlendLight() ) {
775  continue;
776  }
777  if ( !vLight->localInteractions && !vLight->globalInteractions
778  && !vLight->translucentInteractions ) {
779  continue;
780  }
781 
782  backEnd.vLight = vLight;
783 
784  RB_LogComment( "---------- RB_RenderViewLight 0x%p ----------\n", vLight );
785 
786  // clear the stencil buffer if needed
787  if ( vLight->globalShadows || vLight->localShadows ) {
789  if ( r_useScissor.GetBool() ) {
794  }
795  qglClear( GL_STENCIL_BUFFER_BIT );
796  } else {
797  // no shadows, so no need to read or write the stencil buffer
798  // we might in theory want to use GL_ALWAYS instead of disabling
799  // completely, to satisfy the invarience rules
800  qglStencilFunc( GL_ALWAYS, 128, 255 );
801  }
802 
804 
809  RB_NV20_CreateDrawInteractions( vLight->localInteractions );
813  RB_NV20_CreateDrawInteractions( vLight->globalInteractions );
814  qglDisable( GL_VERTEX_PROGRAM_ARB ); // if there weren't any globalInteractions, it would have stayed on
815  } else {
817  RB_NV20_CreateDrawInteractions( vLight->localInteractions );
819  RB_NV20_CreateDrawInteractions( vLight->globalInteractions );
820  }
821 
822  // translucent surfaces never get stencil shadowed
823  if ( r_skipTranslucent.GetBool() ) {
824  continue;
825  }
826 
827  qglStencilFunc( GL_ALWAYS, 128, 255 );
828 
830  RB_NV20_CreateDrawInteractions( vLight->translucentInteractions );
831 
833  }
834 }
835 
836 //=======================================================================
837 
838 /*
839 ==================
840 R_NV20_Init
841 
842 ==================
843 */
844 void R_NV20_Init( void ) {
845  glConfig.allowNV20Path = false;
846 
847  common->Printf( "---------- R_NV20_Init ----------\n" );
848 
850  common->Printf( "Not available.\n" );
851  return;
852  }
853 
854  GL_CheckErrors();
855 
856  // create our "fragment program" display lists
858 
859  // force them to issue commands to build the list
860  bool temp = r_useCombinerDisplayLists.GetBool();
862 
864  RB_NV20_BumpAndLightFragment();
865  qglEndList();
866 
868  RB_NV20_DiffuseColorFragment();
869  qglEndList();
870 
872  RB_NV20_SpecularColorFragment();
873  qglEndList();
874 
876  RB_NV20_DiffuseAndSpecularColorFragment();
877  qglEndList();
878 
880 
881  common->Printf( "---------------------------------\n" );
882 
883  glConfig.allowNV20Path = true;
884 }
885 
const int GLS_DSTBLEND_ONE
Definition: tr_local.h:1017
idVec4 localLightOrigin
Definition: tr_local.h:453
#define qglTexCoordPointer
Definition: qgl_linked.h:318
const srfTriangles_t * geo
Definition: tr_local.h:112
const int GLS_DEPTHFUNC_LESS
Definition: tr_local.h:1040
#define qglScissor
Definition: qgl_linked.h:280
#define GL_COMBINER2_NV
Definition: glext.h:1828
void GL_SelectTextureNoClient(int unit)
Definition: draw_nv20.cpp:61
PFNGLVERTEXATTRIBPOINTERARBPROC qglVertexAttribPointerARB
#define qglEnableClientState
Definition: qgl_linked.h:102
#define GL_VARIABLE_A_NV
Definition: glext.h:1784
#define qglDisable
Definition: qgl_linked.h:92
#define qglDisableClientState
Definition: qgl_linked.h:93
#define qglGenLists
Definition: qgl_linked.h:126
void GL_CheckErrors(void)
bool isMonochrome
Definition: Image.h:241
stageVertexColor_t vertexColor
Definition: tr_local.h:447
short x2
Definition: tr_local.h:55
#define GL_UNSIGNED_INVERT_NV
Definition: glext.h:1801
#define GL_DISCARD_NV
Definition: glext.h:1797
#define GL_TEXTURE1_ARB
Definition: glext.h:378
int internalFormat
Definition: Image.h:250
idCVar r_skipTranslucent("r_skipTranslucent","0", CVAR_RENDERER|CVAR_BOOL,"skip the translucent interaction rendering")
idCVar r_useShadowVertexProgram("r_useShadowVertexProgram","1", CVAR_RENDERER|CVAR_BOOL,"do the shadow projection in the vertex program on capable cards")
const float * ToFloatPtr(void) const
Definition: Vector.h:719
idScreenRect scissorRect
Definition: tr_local.h:307
const int GLS_ALPHAMASK
Definition: tr_local.h:1033
const int GLS_COLORMASK
Definition: tr_local.h:1034
idVec3 xyz
Definition: DrawVert.h:42
idVec4 diffuseMatrix[2]
Definition: tr_local.h:457
idVec3 tangents[2]
Definition: DrawVert.h:45
PFNGLDISABLEVERTEXATTRIBARRAYARBPROC qglDisableVertexAttribArrayARB
GLuint fragmentDisplayListBase
Definition: draw_nv20.cpp:43
const struct drawSurf_s * localShadows
Definition: tr_local.h:332
idScreenRect viewport
Definition: tr_local.h:398
const drawSurf_t * surf
Definition: tr_local.h:437
#define GL_VARIABLE_G_NV
Definition: glext.h:1790
const struct drawSurf_s * globalInteractions
Definition: tr_local.h:333
idImage * diffuseImage
Definition: tr_local.h:442
#define GL_COMBINER3_NV
Definition: glext.h:1829
idCVar r_useNV20MonoLights("r_useNV20MonoLights","1", CVAR_RENDERER|CVAR_INTEGER,"use pass optimization for mono lights")
bool IsBlendLight() const
Definition: Material.h:461
short x1
Definition: tr_local.h:55
bool allowNV20Path
Definition: RenderSystem.h:93
#define qglCallList
Definition: qgl_linked.h:37
struct vertCache_s * ambientCache
Definition: Model.h:137
int currenttmu
Definition: tr_local.h:605
#define GL_SPARE0_NV
Definition: glext.h:1795
#define qglEnable
Definition: qgl_linked.h:101
#define GL_TEXTURE2_ARB
Definition: glext.h:379
const idMaterial * lightShader
Definition: tr_local.h:326
void RB_NV20_DrawInteractions(void)
Definition: draw_nv20.cpp:763
#define GL_VARIABLE_D_NV
Definition: glext.h:1787
backEndState_t backEnd
Definition: tr_backend.cpp:35
idVec4 diffuseColor
Definition: tr_local.h:445
const int GLS_DEPTHFUNC_EQUAL
Definition: tr_local.h:1039
void RB_CreateSingleDrawInteractions(const drawSurf_t *surf, void(*DrawInteraction)(const drawInteraction_t *))
Definition: tr_render.cpp:689
struct viewLight_s * next
Definition: tr_local.h:299
idImage * specularImage
Definition: tr_local.h:443
idImage * ambientNormalMap
Definition: Image.h:394
struct viewLight_s * viewLights
Definition: tr_local.h:415
idVec2 st
Definition: DrawVert.h:43
#define qglStencilFunc
Definition: qgl_linked.h:283
viewLight_t * vLight
Definition: tr_local.h:648
#define GL_NUM_GENERAL_COMBINERS_NV
Definition: glext.h:1824
idImage * normalCubeMapImage
Definition: Image.h:400
idImage * lightImage
Definition: tr_local.h:439
PFNGLENABLEVERTEXATTRIBARRAYARBPROC qglEnableVertexAttribArrayARB
#define GL_E_TIMES_F_NV
Definition: glext.h:1798
idImage * lightFalloffImage
Definition: tr_local.h:440
idCommon * common
Definition: Common.cpp:206
#define qglEndList
Definition: qgl_linked.h:104
PFNGLBINDPROGRAMARBPROC qglBindProgramARB
idVec4 specularColor
Definition: tr_local.h:446
#define GL_PRIMARY_COLOR_NV
Definition: glext.h:1793
int GetInteger(void) const
Definition: CVarSystem.h:143
#define GL_TEXTURE3_ARB
Definition: glext.h:380
glstate_t glState
Definition: tr_local.h:663
#define GL_CONSTANT_COLOR0_NV
Definition: glext.h:1791
idImageManager * globalImages
Definition: Image_init.cpp:74
bool ARBVertexProgramAvailable
Definition: RenderSystem.h:74
#define qglColor3f
Definition: qgl_linked.h:50
idImage * whiteImage
Definition: Image.h:398
idVec4 bumpMatrix[2]
Definition: tr_local.h:456
#define GL_CONSTANT_COLOR1_NV
Definition: glext.h:1792
idVec4 specularMatrix[2]
Definition: tr_local.h:458
fragmentProgram_t
Definition: draw_nv20.cpp:34
const struct drawSurf_s * translucentInteractions
Definition: tr_local.h:334
idVec3 normal
Definition: DrawVert.h:44
bool registerCombinersAvailable
Definition: RenderSystem.h:68
#define GL_VARIABLE_E_NV
Definition: glext.h:1788
#define GL_SECONDARY_COLOR_NV
Definition: glext.h:1794
void R_NV20_Init(void)
Definition: draw_nv20.cpp:844
void RB_NV20_DependentAmbientPass(void)
virtual void Printf(const char *fmt,...) id_attribute((format(printf
#define GL_REGISTER_COMBINERS_NV
Definition: glext.h:1783
void RB_DrawElementsWithCounters(const srfTriangles_t *tri)
Definition: tr_render.cpp:78
const float * ToFloatPtr(void) const
Definition: Vector.h:1051
const int GLS_SRCBLEND_DST_ALPHA
Definition: tr_local.h:1011
#define GL_SCALE_BY_TWO_NV
Definition: glext.h:1808
#define GL_SPARE1_NV
Definition: glext.h:1796
void RB_LogComment(const char *comment,...)
Definition: tr_backend.cpp:112
#define qglColorPointer
Definition: qgl_linked.h:80
bool GetBool(void) const
Definition: CVarSystem.h:142
glconfig_t glConfig
const struct drawSurf_s * globalShadows
Definition: tr_local.h:330
idVec4 lightProjection[4]
Definition: tr_local.h:455
const struct drawSurf_s * localInteractions
Definition: tr_local.h:331
const float * ToFloatPtr(void) const
Definition: Vector.h:301
#define qglNewList
Definition: qgl_linked.h:206
#define GL_VARIABLE_C_NV
Definition: glext.h:1786
void * Position(vertCache_t *buffer)
const struct drawSurf_s * nextOnLight
Definition: tr_local.h:117
#define GL_VERTEX_PROGRAM_ARB
Definition: glext.h:594
#define qglClear
Definition: qgl_linked.h:39
idImage * bumpImage
Definition: tr_local.h:441
PFNGLPROGRAMENVPARAMETER4FVARBPROC qglProgramEnvParameter4fvARB
byte color[4]
Definition: DrawVert.h:46
#define GL_COMBINER0_NV
Definition: glext.h:1826
int maxTextureUnits
Definition: RenderSystem.h:55
#define GL_EXPAND_NORMAL_NV
Definition: glext.h:1802
#define GL_VARIABLE_B_NV
Definition: glext.h:1785
bool IsFogLight() const
Definition: Material.h:458
idVertexCache vertexCache
Definition: VertexCache.cpp:41
#define GL_COMBINER1_NV
Definition: glext.h:1827
#define GL_TEXTURE0_ARB
Definition: glext.h:377
void SetBool(const bool value)
Definition: CVarSystem.h:147
void GL_State(int stateBits)
Definition: tr_backend.cpp:239
void RB_StencilShadowPass(const drawSurf_t *drawSurfs)
idCVar r_useCombinerDisplayLists("r_useCombinerDisplayLists","1", CVAR_RENDERER|CVAR_BOOL|CVAR_NOCHEAT,"put all nvidia register combiner programming in display lists")
#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV
Definition: glext.h:1811
short y1
Definition: tr_local.h:55
GLenum internalFormat
Definition: glext.h:4176
idCVar r_useScissor("r_useScissor","1", CVAR_RENDERER|CVAR_BOOL,"scissor clip as portals and lights are processed")
void GL_SelectTexture(int unit)
Definition: tr_backend.cpp:135
#define GL_UNSIGNED_IDENTITY_NV
Definition: glext.h:1800
short y2
Definition: tr_local.h:55
typedef GLuint(APIENTRYP PFNGLGENASYNCMARKERSSGIXPROC)(GLsizei range)
void Bind()
idScreenRect currentScissor
Definition: tr_local.h:645
void RB_NV20_DependentSpecularPass(const drawInteraction_t *din)
#define qglVertexPointer
Definition: qgl_linked.h:363
#define GL_VARIABLE_F_NV
Definition: glext.h:1789
const int GLS_DEPTHMASK
Definition: tr_local.h:1029
idVec4 localViewOrigin
Definition: tr_local.h:454
const viewDef_t * viewDef
Definition: tr_local.h:641