doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
tr_render.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 /*
35 
36  back end scene + lights rendering functions
37 
38 */
39 
40 
41 /*
42 =================
43 RB_DrawElementsImmediate
44 
45 Draws with immediate mode commands, which is going to be very slow.
46 This should never happen if the vertex cache is operating properly.
47 =================
48 */
50 
54 
55  if ( tri->ambientSurface != NULL ) {
56  if ( tri->indexes == tri->ambientSurface->indexes ) {
58  }
59  if ( tri->verts == tri->ambientSurface->verts ) {
61  }
62  }
63 
64  qglBegin( GL_TRIANGLES );
65  for ( int i = 0 ; i < tri->numIndexes ; i++ ) {
66  qglTexCoord2fv( tri->verts[ tri->indexes[i] ].st.ToFloatPtr() );
67  qglVertex3fv( tri->verts[ tri->indexes[i] ].xyz.ToFloatPtr() );
68  }
69  qglEnd();
70 }
71 
72 
73 /*
74 ================
75 RB_DrawElementsWithCounters
76 ================
77 */
79 
83 
84  if ( tri->ambientSurface != NULL ) {
85  if ( tri->indexes == tri->ambientSurface->indexes ) {
87  }
88  if ( tri->verts == tri->ambientSurface->verts ) {
90  }
91  }
92 
93  if ( tri->indexCache && r_useIndexBuffers.GetBool() ) {
94  qglDrawElements( GL_TRIANGLES,
95  r_singleTriangle.GetBool() ? 3 : tri->numIndexes,
97  (int *)vertexCache.Position( tri->indexCache ) );
99  } else {
100  if ( r_useIndexBuffers.GetBool() ) {
102  }
103  qglDrawElements( GL_TRIANGLES,
104  r_singleTriangle.GetBool() ? 3 : tri->numIndexes,
106  tri->indexes );
107  }
108 }
109 
110 /*
111 ================
112 RB_DrawShadowElementsWithCounters
113 
114 May not use all the indexes in the surface if caps are skipped
115 ================
116 */
117 void RB_DrawShadowElementsWithCounters( const srfTriangles_t *tri, int numIndexes ) {
119  backEnd.pc.c_shadowIndexes += numIndexes;
121 
122  if ( tri->indexCache && r_useIndexBuffers.GetBool() ) {
123  qglDrawElements( GL_TRIANGLES,
124  r_singleTriangle.GetBool() ? 3 : numIndexes,
126  (int *)vertexCache.Position( tri->indexCache ) );
127  backEnd.pc.c_vboIndexes += numIndexes;
128  } else {
129  if ( r_useIndexBuffers.GetBool() ) {
131  }
132  qglDrawElements( GL_TRIANGLES,
133  r_singleTriangle.GetBool() ? 3 : numIndexes,
135  tri->indexes );
136  }
137 }
138 
139 
140 /*
141 ===============
142 RB_RenderTriangleSurface
143 
144 Sets texcoord and vertex pointers
145 ===============
146 */
148  if ( !tri->ambientCache ) {
150  return;
151  }
152 
153 
155  qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() );
156  qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), ac->st.ToFloatPtr() );
157 
159 }
160 
161 /*
162 ===============
163 RB_T_RenderTriangleSurface
164 
165 ===============
166 */
168  RB_RenderTriangleSurface( surf->geo );
169 }
170 
171 /*
172 ===============
173 RB_EnterWeaponDepthHack
174 ===============
175 */
177  qglDepthRange( 0, 0.5 );
178 
179  float matrix[16];
180 
181  memcpy( matrix, backEnd.viewDef->projectionMatrix, sizeof( matrix ) );
182 
183  matrix[14] *= 0.25;
184 
185  qglMatrixMode(GL_PROJECTION);
186  qglLoadMatrixf( matrix );
187  qglMatrixMode(GL_MODELVIEW);
188 }
189 
190 /*
191 ===============
192 RB_EnterModelDepthHack
193 ===============
194 */
196  qglDepthRange( 0.0f, 1.0f );
197 
198  float matrix[16];
199 
200  memcpy( matrix, backEnd.viewDef->projectionMatrix, sizeof( matrix ) );
201 
202  matrix[14] -= depth;
203 
204  qglMatrixMode(GL_PROJECTION);
205  qglLoadMatrixf( matrix );
206  qglMatrixMode(GL_MODELVIEW);
207 }
208 
209 /*
210 ===============
211 RB_LeaveDepthHack
212 ===============
213 */
215  qglDepthRange( 0, 1 );
216 
217  qglMatrixMode(GL_PROJECTION);
219  qglMatrixMode(GL_MODELVIEW);
220 }
221 
222 /*
223 ====================
224 RB_RenderDrawSurfListWithFunction
225 
226 The triangle functions can check backEnd.currentSpace != surf->space
227 to see if they need to perform any new matrix setup. The modelview
228 matrix will already have been loaded, and backEnd.currentSpace will
229 be updated after the triangle function completes.
230 ====================
231 */
232 void RB_RenderDrawSurfListWithFunction( drawSurf_t **drawSurfs, int numDrawSurfs,
233  void (*triFunc_)( const drawSurf_t *) ) {
234  int i;
235  const drawSurf_t *drawSurf;
236 
238 
239  for (i = 0 ; i < numDrawSurfs ; i++ ) {
240  drawSurf = drawSurfs[i];
241 
242  // change the matrix if needed
243  if ( drawSurf->space != backEnd.currentSpace ) {
244  qglLoadMatrixf( drawSurf->space->modelViewMatrix );
245  }
246 
247  if ( drawSurf->space->weaponDepthHack ) {
249  }
250 
251  if ( drawSurf->space->modelDepthHack != 0.0f ) {
253  }
254 
255  // change the scissor if needed
256  if ( r_useScissor.GetBool() && !backEnd.currentScissor.Equals( drawSurf->scissorRect ) ) {
257  backEnd.currentScissor = drawSurf->scissorRect;
262  }
263 
264  // render it
265  triFunc_( drawSurf );
266 
267  if ( drawSurf->space->weaponDepthHack || drawSurf->space->modelDepthHack != 0.0f ) {
269  }
270 
271  backEnd.currentSpace = drawSurf->space;
272  }
273 }
274 
275 /*
276 ======================
277 RB_RenderDrawSurfChainWithFunction
278 ======================
279 */
281  void (*triFunc_)( const drawSurf_t *) ) {
282  const drawSurf_t *drawSurf;
283 
285 
286  for ( drawSurf = drawSurfs ; drawSurf ; drawSurf = drawSurf->nextOnLight ) {
287  // change the matrix if needed
288  if ( drawSurf->space != backEnd.currentSpace ) {
289  qglLoadMatrixf( drawSurf->space->modelViewMatrix );
290  }
291 
292  if ( drawSurf->space->weaponDepthHack ) {
294  }
295 
296  if ( drawSurf->space->modelDepthHack ) {
298  }
299 
300  // change the scissor if needed
301  if ( r_useScissor.GetBool() && !backEnd.currentScissor.Equals( drawSurf->scissorRect ) ) {
302  backEnd.currentScissor = drawSurf->scissorRect;
307  }
308 
309  // render it
310  triFunc_( drawSurf );
311 
312  if ( drawSurf->space->weaponDepthHack || drawSurf->space->modelDepthHack != 0.0f ) {
314  }
315 
316  backEnd.currentSpace = drawSurf->space;
317  }
318 }
319 
320 /*
321 ======================
322 RB_GetShaderTextureMatrix
323 ======================
324 */
325 void RB_GetShaderTextureMatrix( const float *shaderRegisters,
326  const textureStage_t *texture, float matrix[16] ) {
327  matrix[0] = shaderRegisters[ texture->matrix[0][0] ];
328  matrix[4] = shaderRegisters[ texture->matrix[0][1] ];
329  matrix[8] = 0;
330  matrix[12] = shaderRegisters[ texture->matrix[0][2] ];
331 
332  // we attempt to keep scrolls from generating incredibly large texture values, but
333  // center rotations and center scales can still generate offsets that need to be > 1
334  if ( matrix[12] < -40 || matrix[12] > 40 ) {
335  matrix[12] -= (int)matrix[12];
336  }
337 
338  matrix[1] = shaderRegisters[ texture->matrix[1][0] ];
339  matrix[5] = shaderRegisters[ texture->matrix[1][1] ];
340  matrix[9] = 0;
341  matrix[13] = shaderRegisters[ texture->matrix[1][2] ];
342  if ( matrix[13] < -40 || matrix[13] > 40 ) {
343  matrix[13] -= (int)matrix[13];
344  }
345 
346  matrix[2] = 0;
347  matrix[6] = 0;
348  matrix[10] = 1;
349  matrix[14] = 0;
350 
351  matrix[3] = 0;
352  matrix[7] = 0;
353  matrix[11] = 0;
354  matrix[15] = 1;
355 }
356 
357 /*
358 ======================
359 RB_LoadShaderTextureMatrix
360 ======================
361 */
362 void RB_LoadShaderTextureMatrix( const float *shaderRegisters, const textureStage_t *texture ) {
363  float matrix[16];
364 
365  RB_GetShaderTextureMatrix( shaderRegisters, texture, matrix );
366  qglMatrixMode( GL_TEXTURE );
367  qglLoadMatrixf( matrix );
368  qglMatrixMode( GL_MODELVIEW );
369 }
370 
371 /*
372 ======================
373 RB_BindVariableStageImage
374 
375 Handles generating a cinematic frame if needed
376 ======================
377 */
378 void RB_BindVariableStageImage( const textureStage_t *texture, const float *shaderRegisters ) {
379  if ( texture->cinematic ) {
380  cinData_t cin;
381 
382  if ( r_skipDynamicTextures.GetBool() ) {
384  return;
385  }
386 
387  // offset time by shaderParm[7] (FIXME: make the time offset a parameter of the shader?)
388  // We make no attempt to optimize for multiple identical cinematics being in view, or
389  // for cinematics going at a lower framerate than the renderer.
390  cin = texture->cinematic->ImageForTime( (int)(1000 * ( backEnd.viewDef->floatTime + backEnd.viewDef->renderView.shaderParms[11] ) ) );
391 
392  if ( cin.image ) {
394  } else {
396  }
397  } else {
398  //FIXME: see why image is invalid
399  if (texture->image) {
400  texture->image->Bind();
401  }
402  }
403 }
404 
405 /*
406 ======================
407 RB_BindStageTexture
408 ======================
409 */
410 void RB_BindStageTexture( const float *shaderRegisters, const textureStage_t *texture, const drawSurf_t *surf ) {
411  // image
412  RB_BindVariableStageImage( texture, shaderRegisters );
413 
414  // texgens
415  if ( texture->texgen == TG_DIFFUSE_CUBE ) {
416  qglTexCoordPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ((idDrawVert *)vertexCache.Position( surf->geo->ambientCache ))->normal.ToFloatPtr() );
417  }
418  if ( texture->texgen == TG_SKYBOX_CUBE || texture->texgen == TG_WOBBLESKY_CUBE ) {
419  qglTexCoordPointer( 3, GL_FLOAT, 0, vertexCache.Position( surf->dynamicTexCoords ) );
420  }
421  if ( texture->texgen == TG_REFLECT_CUBE ) {
422  qglEnable( GL_TEXTURE_GEN_S );
423  qglEnable( GL_TEXTURE_GEN_T );
424  qglEnable( GL_TEXTURE_GEN_R );
425  qglTexGenf( GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT );
426  qglTexGenf( GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT );
427  qglTexGenf( GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT );
428  qglEnableClientState( GL_NORMAL_ARRAY );
429  qglNormalPointer( GL_FLOAT, sizeof( idDrawVert ), ((idDrawVert *)vertexCache.Position( surf->geo->ambientCache ))->normal.ToFloatPtr() );
430 
431  qglMatrixMode( GL_TEXTURE );
432  float mat[16];
433 
435 
436  qglLoadMatrixf( mat );
437  qglMatrixMode( GL_MODELVIEW );
438  }
439 
440  // matrix
441  if ( texture->hasMatrix ) {
442  RB_LoadShaderTextureMatrix( shaderRegisters, texture );
443  }
444 }
445 
446 /*
447 ======================
448 RB_FinishStageTexture
449 ======================
450 */
452  if ( texture->texgen == TG_DIFFUSE_CUBE || texture->texgen == TG_SKYBOX_CUBE
453  || texture->texgen == TG_WOBBLESKY_CUBE ) {
454  qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ),
455  (void *)&(((idDrawVert *)vertexCache.Position( surf->geo->ambientCache ))->st) );
456  }
457 
458  if ( texture->texgen == TG_REFLECT_CUBE ) {
459  qglDisable( GL_TEXTURE_GEN_S );
460  qglDisable( GL_TEXTURE_GEN_T );
461  qglDisable( GL_TEXTURE_GEN_R );
462  qglTexGenf( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
463  qglTexGenf( GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
464  qglTexGenf( GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
465  qglDisableClientState( GL_NORMAL_ARRAY );
466 
467  qglMatrixMode( GL_TEXTURE );
468  qglLoadIdentity();
469  qglMatrixMode( GL_MODELVIEW );
470  }
471 
472  if ( texture->hasMatrix ) {
473  qglMatrixMode( GL_TEXTURE );
474  qglLoadIdentity();
475  qglMatrixMode( GL_MODELVIEW );
476  }
477 }
478 
479 
480 
481 //=============================================================================================
482 
483 
484 /*
485 =================
486 RB_DetermineLightScale
487 
488 Sets:
489 backEnd.lightScale
490 backEnd.overBright
491 
492 Find out how much we are going to need to overscale the lighting, so we
493 can down modulate the pre-lighting passes.
494 
495 We only look at light calculations, but an argument could be made that
496 we should also look at surface evaluations, which would let surfaces
497 overbright past 1.0
498 =================
499 */
501  viewLight_t *vLight;
502  const idMaterial *shader;
503  float max;
504  int i, j, numStages;
505  const shaderStage_t *stage;
506 
507  // the light scale will be based on the largest color component of any surface
508  // that will be drawn.
509  // should we consider separating rgb scales?
510 
511  // if there are no lights, this will remain at 1.0, so GUI-only
512  // rendering will not lose any bits of precision
513  max = 1.0;
514 
515  for ( vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) {
516  // lights with no surfaces or shaderparms may still be present
517  // for debug display
518  if ( !vLight->localInteractions && !vLight->globalInteractions
519  && !vLight->translucentInteractions ) {
520  continue;
521  }
522 
523  shader = vLight->lightShader;
524  numStages = shader->GetNumStages();
525  for ( i = 0 ; i < numStages ; i++ ) {
526  stage = shader->GetStage( i );
527  for ( j = 0 ; j < 3 ; j++ ) {
528  float v = r_lightScale.GetFloat() * vLight->shaderRegisters[ stage->color.registers[j] ];
529  if ( v > max ) {
530  max = v;
531  }
532  }
533  }
534  }
535 
537  if ( max <= tr.backEndRendererMaxLight ) {
539  backEnd.overBright = 1.0;
540  } else {
543  }
544 }
545 
546 
547 /*
548 =================
549 RB_BeginDrawingView
550 
551 Any mirrored or portaled views have already been drawn, so prepare
552 to actually render the visible surfaces for this view
553 =================
554 */
555 void RB_BeginDrawingView (void) {
556  // set the modelview matrix for the viewer
557  qglMatrixMode(GL_PROJECTION);
559  qglMatrixMode(GL_MODELVIEW);
560 
561  // set the window clipping
566 
567  // the scissor may be smaller than the viewport for subviews
573 
574  // ensures that depth writes are enabled for the depth clear
576 
577  // we don't have to clear the depth / stencil buffer for 2D rendering
578  if ( backEnd.viewDef->viewEntitys ) {
579  qglStencilMask( 0xff );
580  // some cards may have 7 bit stencil buffers, so don't assume this
581  // should be 128
583  qglClear( GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
584  qglEnable( GL_DEPTH_TEST );
585  } else {
586  qglDisable( GL_DEPTH_TEST );
587  qglDisable( GL_STENCIL_TEST );
588  }
589 
590  backEnd.glState.faceCulling = -1; // force face culling to set next time
592 
593 }
594 
595 /*
596 ==================
597 R_SetDrawInteractions
598 ==================
599 */
600 void R_SetDrawInteraction( const shaderStage_t *surfaceStage, const float *surfaceRegs,
601  idImage **image, idVec4 matrix[2], float color[4] ) {
602  *image = surfaceStage->texture.image;
603  if ( surfaceStage->texture.hasMatrix ) {
604  matrix[0][0] = surfaceRegs[surfaceStage->texture.matrix[0][0]];
605  matrix[0][1] = surfaceRegs[surfaceStage->texture.matrix[0][1]];
606  matrix[0][2] = 0;
607  matrix[0][3] = surfaceRegs[surfaceStage->texture.matrix[0][2]];
608 
609  matrix[1][0] = surfaceRegs[surfaceStage->texture.matrix[1][0]];
610  matrix[1][1] = surfaceRegs[surfaceStage->texture.matrix[1][1]];
611  matrix[1][2] = 0;
612  matrix[1][3] = surfaceRegs[surfaceStage->texture.matrix[1][2]];
613 
614  // we attempt to keep scrolls from generating incredibly large texture values, but
615  // center rotations and center scales can still generate offsets that need to be > 1
616  if ( matrix[0][3] < -40 || matrix[0][3] > 40 ) {
617  matrix[0][3] -= (int)matrix[0][3];
618  }
619  if ( matrix[1][3] < -40 || matrix[1][3] > 40 ) {
620  matrix[1][3] -= (int)matrix[1][3];
621  }
622  } else {
623  matrix[0][0] = 1;
624  matrix[0][1] = 0;
625  matrix[0][2] = 0;
626  matrix[0][3] = 0;
627 
628  matrix[1][0] = 0;
629  matrix[1][1] = 1;
630  matrix[1][2] = 0;
631  matrix[1][3] = 0;
632  }
633 
634  if ( color ) {
635  for ( int i = 0 ; i < 4 ; i++ ) {
636  color[i] = surfaceRegs[surfaceStage->color.registers[i]];
637  // clamp here, so card with greater range don't look different.
638  // we could perform overbrighting like we do for lights, but
639  // it doesn't currently look worth it.
640  if ( color[i] < 0 ) {
641  color[i] = 0;
642  } else if ( color[i] > 1.0 ) {
643  color[i] = 1.0;
644  }
645  }
646  }
647 }
648 
649 /*
650 =================
651 RB_SubmittInteraction
652 =================
653 */
654 static void RB_SubmittInteraction( drawInteraction_t *din, void (*DrawInteraction)(const drawInteraction_t *) ) {
655  if ( !din->bumpImage ) {
656  return;
657  }
658 
659  if ( !din->diffuseImage || r_skipDiffuse.GetBool() ) {
661  }
662  if ( !din->specularImage || r_skipSpecular.GetBool() || din->ambientLight ) {
664  }
665  if ( !din->bumpImage || r_skipBump.GetBool() ) {
667  }
668 
669  // if we wouldn't draw anything, don't call the Draw function
670  if (
671  ( ( din->diffuseColor[0] > 0 ||
672  din->diffuseColor[1] > 0 ||
673  din->diffuseColor[2] > 0 ) && din->diffuseImage != globalImages->blackImage )
674  || ( ( din->specularColor[0] > 0 ||
675  din->specularColor[1] > 0 ||
676  din->specularColor[2] > 0 ) && din->specularImage != globalImages->blackImage ) ) {
677  DrawInteraction( din );
678  }
679 }
680 
681 /*
682 =============
683 RB_CreateSingleDrawInteractions
684 
685 This can be used by different draw_* backends to decompose a complex light / surface
686 interaction into primitive interactions
687 =============
688 */
689 void RB_CreateSingleDrawInteractions( const drawSurf_t *surf, void (*DrawInteraction)(const drawInteraction_t *) ) {
690  const idMaterial *surfaceShader = surf->material;
691  const float *surfaceRegs = surf->shaderRegisters;
692  const viewLight_t *vLight = backEnd.vLight;
693  const idMaterial *lightShader = vLight->lightShader;
694  const float *lightRegs = vLight->shaderRegisters;
695  drawInteraction_t inter;
696 
697  if ( r_skipInteractions.GetBool() || !surf->geo || !surf->geo->ambientCache ) {
698  return;
699  }
700 
701  if ( tr.logFile ) {
702  RB_LogComment( "---------- RB_CreateSingleDrawInteractions %s on %s ----------\n", lightShader->GetName(), surfaceShader->GetName() );
703  }
704 
705  // change the matrix and light projection vectors if needed
706  if ( surf->space != backEnd.currentSpace ) {
707  backEnd.currentSpace = surf->space;
709  }
710 
711  // change the scissor if needed
718  }
719 
720  // hack depth range if needed
721  if ( surf->space->weaponDepthHack ) {
723  }
724 
725  if ( surf->space->modelDepthHack ) {
727  }
728 
729  inter.surf = surf;
730  inter.lightFalloffImage = vLight->falloffImage;
731 
734  inter.localLightOrigin[3] = 0;
735  inter.localViewOrigin[3] = 1;
736  inter.ambientLight = lightShader->IsAmbientLight();
737 
738  // the base projections may be modified by texture matrix on light stages
739  idPlane lightProject[4];
740  for ( int i = 0 ; i < 4 ; i++ ) {
741  R_GlobalPlaneToLocal( surf->space->modelMatrix, backEnd.vLight->lightProject[i], lightProject[i] );
742  }
743 
744  for ( int lightStageNum = 0 ; lightStageNum < lightShader->GetNumStages() ; lightStageNum++ ) {
745  const shaderStage_t *lightStage = lightShader->GetStage( lightStageNum );
746 
747  // ignore stages that fail the condition
748  if ( !lightRegs[ lightStage->conditionRegister ] ) {
749  continue;
750  }
751 
752  inter.lightImage = lightStage->texture.image;
753 
754  memcpy( inter.lightProjection, lightProject, sizeof( inter.lightProjection ) );
755  // now multiply the texgen by the light texture matrix
756  if ( lightStage->texture.hasMatrix ) {
757  RB_GetShaderTextureMatrix( lightRegs, &lightStage->texture, backEnd.lightTextureMatrix );
758  RB_BakeTextureMatrixIntoTexgen( reinterpret_cast<class idPlane *>(inter.lightProjection), backEnd.lightTextureMatrix );
759  }
760 
761  inter.bumpImage = NULL;
762  inter.specularImage = NULL;
763  inter.diffuseImage = NULL;
764  inter.diffuseColor[0] = inter.diffuseColor[1] = inter.diffuseColor[2] = inter.diffuseColor[3] = 0;
765  inter.specularColor[0] = inter.specularColor[1] = inter.specularColor[2] = inter.specularColor[3] = 0;
766 
767  float lightColor[4];
768 
769  // backEnd.lightScale is calculated so that lightColor[] will never exceed
770  // tr.backEndRendererMaxLight
771  lightColor[0] = backEnd.lightScale * lightRegs[ lightStage->color.registers[0] ];
772  lightColor[1] = backEnd.lightScale * lightRegs[ lightStage->color.registers[1] ];
773  lightColor[2] = backEnd.lightScale * lightRegs[ lightStage->color.registers[2] ];
774  lightColor[3] = lightRegs[ lightStage->color.registers[3] ];
775 
776  // go through the individual stages
777  for ( int surfaceStageNum = 0 ; surfaceStageNum < surfaceShader->GetNumStages() ; surfaceStageNum++ ) {
778  const shaderStage_t *surfaceStage = surfaceShader->GetStage( surfaceStageNum );
779 
780  switch( surfaceStage->lighting ) {
781  case SL_AMBIENT: {
782  // ignore ambient stages while drawing interactions
783  break;
784  }
785  case SL_BUMP: {
786  // ignore stage that fails the condition
787  if ( !surfaceRegs[ surfaceStage->conditionRegister ] ) {
788  break;
789  }
790  // draw any previous interaction
791  RB_SubmittInteraction( &inter, DrawInteraction );
792  inter.diffuseImage = NULL;
793  inter.specularImage = NULL;
794  R_SetDrawInteraction( surfaceStage, surfaceRegs, &inter.bumpImage, inter.bumpMatrix, NULL );
795  break;
796  }
797  case SL_DIFFUSE: {
798  // ignore stage that fails the condition
799  if ( !surfaceRegs[ surfaceStage->conditionRegister ] ) {
800  break;
801  }
802  if ( inter.diffuseImage ) {
803  RB_SubmittInteraction( &inter, DrawInteraction );
804  }
805  R_SetDrawInteraction( surfaceStage, surfaceRegs, &inter.diffuseImage,
806  inter.diffuseMatrix, inter.diffuseColor.ToFloatPtr() );
807  inter.diffuseColor[0] *= lightColor[0];
808  inter.diffuseColor[1] *= lightColor[1];
809  inter.diffuseColor[2] *= lightColor[2];
810  inter.diffuseColor[3] *= lightColor[3];
811  inter.vertexColor = surfaceStage->vertexColor;
812  break;
813  }
814  case SL_SPECULAR: {
815  // ignore stage that fails the condition
816  if ( !surfaceRegs[ surfaceStage->conditionRegister ] ) {
817  break;
818  }
819  if ( inter.specularImage ) {
820  RB_SubmittInteraction( &inter, DrawInteraction );
821  }
822  R_SetDrawInteraction( surfaceStage, surfaceRegs, &inter.specularImage,
823  inter.specularMatrix, inter.specularColor.ToFloatPtr() );
824  inter.specularColor[0] *= lightColor[0];
825  inter.specularColor[1] *= lightColor[1];
826  inter.specularColor[2] *= lightColor[2];
827  inter.specularColor[3] *= lightColor[3];
828  inter.vertexColor = surfaceStage->vertexColor;
829  break;
830  }
831  }
832  }
833 
834  // draw the final interaction
835  RB_SubmittInteraction( &inter, DrawInteraction );
836  }
837 
838  // unhack depth range if needed
839  if ( surf->space->weaponDepthHack || surf->space->modelDepthHack != 0.0f ) {
841  }
842 }
843 
844 /*
845 =============
846 RB_DrawView
847 =============
848 */
849 void RB_DrawView( const void *data ) {
850  const drawSurfsCommand_t *cmd;
851 
852  cmd = (const drawSurfsCommand_t *)data;
853 
854  backEnd.viewDef = cmd->viewDef;
855 
856  // we will need to do a new copyTexSubImage of the screen
857  // when a SS_POST_PROCESS material is used
859 
860  // if there aren't any drawsurfs, do nothing
861  if ( !backEnd.viewDef->numDrawSurfs ) {
862  return;
863  }
864 
865  // skip render bypasses everything that has models, assuming
866  // them to be 3D views, but leaves 2D rendering visible
868  return;
869  }
870 
871  // skip render context sets the wgl context to NULL,
872  // which should factor out the API cost, under the assumption
873  // that all gl calls just return if the context isn't valid
876  }
877 
879 
880  RB_ShowOverdraw();
881 
882  // render the scene, jumping to the hardware specific interaction renderers
883  RB_STD_DrawView();
884 
885  // restore the context for 2D drawing if we were stubbing it out
889  }
890 }
bool weaponDepthHack
Definition: tr_local.h:357
byte color[4]
Definition: MegaTexture.cpp:54
idVec4 localLightOrigin
Definition: tr_local.h:453
#define qglTexCoordPointer
Definition: qgl_linked.h:318
#define qglLoadMatrixf
Definition: qgl_linked.h:188
const srfTriangles_t * geo
Definition: tr_local.h:112
viewEntity_t worldSpace
Definition: tr_local.h:373
Definition: Image.h:146
#define qglScissor
Definition: qgl_linked.h:280
idImage * falloffImage
Definition: tr_local.h:328
#define qglEnableClientState
Definition: qgl_linked.h:102
#define qglDisable
Definition: qgl_linked.h:92
#define qglDisableClientState
Definition: qgl_linked.h:93
float overBright
Definition: tr_local.h:656
int numVerts
Definition: Model.h:98
void RB_DrawShadowElementsWithCounters(const srfTriangles_t *tri, int numIndexes)
Definition: tr_render.cpp:117
void RB_RenderDrawSurfChainWithFunction(const drawSurf_t *drawSurfs, void(*triFunc_)(const drawSurf_t *))
Definition: tr_render.cpp:280
idCVar r_useIndexBuffers("r_useIndexBuffers","0", CVAR_RENDERER|CVAR_ARCHIVE|CVAR_INTEGER,"use ARB_vertex_buffer_object for indexes", 0, 1, idCmdSystem::ArgCompletion_Integer< 0, 1 >)
stageVertexColor_t vertexColor
Definition: tr_local.h:447
short x2
Definition: tr_local.h:55
float GetFloat(void) const
Definition: CVarSystem.h:144
const GLdouble * v
Definition: glext.h:2936
backEndCounters_t pc
Definition: tr_local.h:642
const int GetNumStages(void) const
Definition: Material.h:365
idCVar r_skipDynamicTextures("r_skipDynamicTextures","0", CVAR_RENDERER|CVAR_BOOL,"don't dynamically create textures")
int conditionRegister
Definition: Material.h:204
GLuint GLenum matrix
Definition: glext.h:5179
void RB_RenderDrawSurfListWithFunction(drawSurf_t **drawSurfs, int numDrawSurfs, void(*triFunc_)(const drawSurf_t *))
Definition: tr_render.cpp:232
idCVar r_singleTriangle("r_singleTriangle","0", CVAR_RENDERER|CVAR_BOOL,"only draw a single triangle per primitive")
const float * ToFloatPtr(void) const
Definition: Vector.h:719
float floatTime
Definition: tr_local.h:377
void RB_STD_DrawView(void)
float maxLightValue
Definition: tr_local.h:633
idVec3 xyz
Definition: DrawVert.h:42
texgen_t texgen
Definition: Material.h:162
#define qglTexCoord2fv
Definition: qgl_linked.h:297
idVec4 diffuseMatrix[2]
Definition: tr_local.h:457
void RB_LeaveDepthHack()
Definition: tr_render.cpp:214
idCVar r_skipSpecular("r_skipSpecular","0", CVAR_RENDERER|CVAR_BOOL|CVAR_CHEAT|CVAR_ARCHIVE,"use black for specular1")
case const int
Definition: Callbacks.cpp:52
void RB_T_RenderTriangleSurface(const drawSurf_t *surf)
Definition: tr_render.cpp:167
void RB_DrawView(const void *data)
Definition: tr_render.cpp:849
stageLighting_t lighting
Definition: Material.h:205
#define qglBegin
Definition: qgl_linked.h:33
idScreenRect scissorRect
Definition: tr_local.h:118
const int GLS_DEFAULT
Definition: tr_local.h:1047
const char * GetName(void) const
Definition: DeclManager.h:140
idScreenRect viewport
Definition: tr_local.h:398
#define qglDepthRange
Definition: qgl_linked.h:91
GLenum GLsizei GLenum GLenum const GLvoid * image
Definition: glext.h:2855
const drawSurf_t * surf
Definition: tr_local.h:437
#define qglVertex3fv
Definition: qgl_linked.h:350
GLint GLint GLsizei GLsizei GLsizei depth
Definition: glext.h:2878
void RB_CreateSingleDrawInteractions(const drawSurf_t *surf, void(*DrawInteraction)(const drawInteraction_t *))
Definition: tr_render.cpp:689
void RB_BakeTextureMatrixIntoTexgen(idPlane lightProject[3], const float *textureMatrix)
Definition: draw_common.cpp:38
const struct drawSurf_s * globalInteractions
Definition: tr_local.h:333
idImage * diffuseImage
Definition: tr_local.h:442
float lightScale
Definition: tr_local.h:653
short x1
Definition: tr_local.h:55
float modelDepthHack
Definition: tr_local.h:358
#define qglViewport
Definition: qgl_linked.h:364
const struct viewEntity_s * space
Definition: tr_local.h:113
struct vertCache_s * ambientCache
Definition: Model.h:137
int i
Definition: process.py:33
const idMaterial * material
Definition: tr_local.h:114
float projectionMatrix[16]
Definition: tr_local.h:372
bool IsAmbientLight() const
Definition: Material.h:464
#define qglEnable
Definition: qgl_linked.h:101
const viewEntity_t * currentSpace
Definition: tr_local.h:644
const idMaterial * lightShader
Definition: tr_local.h:326
idImage * flatNormalMap
Definition: Image.h:393
struct srfTriangles_s * ambientSurface
Definition: Model.h:130
void RB_LoadShaderTextureMatrix(const float *shaderRegisters, const textureStage_t *texture)
Definition: tr_render.cpp:362
backEndState_t backEnd
Definition: tr_backend.cpp:35
void RB_DrawElementsWithCounters(const srfTriangles_t *tri)
Definition: tr_render.cpp:78
void GL_Cull(int cullType)
Definition: tr_backend.cpp:161
#define GL_REFLECTION_MAP_EXT
Definition: glext.h:1722
idVec4 diffuseColor
Definition: tr_local.h:445
struct viewLight_s * next
Definition: tr_local.h:299
idImage * specularImage
Definition: tr_local.h:443
struct viewLight_s * viewLights
Definition: tr_local.h:415
viewDef_t * viewDef
Definition: tr_local.h:493
idVec2 st
Definition: DrawVert.h:43
#define GL_INDEX_TYPE
Definition: Model.h:51
#define qglTexGenf
Definition: qgl_linked.h:325
int registers[4]
Definition: Material.h:145
void RB_BeginDrawingView(void)
Definition: tr_render.cpp:555
viewLight_t * vLight
Definition: tr_local.h:648
Definition: Vector.h:808
#define qglDrawElements
Definition: qgl_linked.h:96
idImage * lightImage
Definition: tr_local.h:439
const shaderStage_t * GetStage(const int index) const
Definition: Material.h:368
idCVar r_skipBump("r_skipBump","0", CVAR_RENDERER|CVAR_BOOL|CVAR_ARCHIVE,"uses a flat surface instead of the bump map")
idImage * defaultImage
Definition: Image.h:392
idImage * lightFalloffImage
Definition: tr_local.h:440
void UploadScratch(const byte *pic, int width, int height)
void RB_BindStageTexture(const float *shaderRegisters, const textureStage_t *texture, const drawSurf_t *surf)
Definition: tr_render.cpp:410
renderView_t renderView
Definition: tr_local.h:370
idCVar r_skipRender("r_skipRender","0", CVAR_RENDERER|CVAR_BOOL,"skip 3D rendering, but pass 2D")
idVec4 specularColor
Definition: tr_local.h:446
void RB_RenderTriangleSurface(const srfTriangles_t *tri)
Definition: tr_render.cpp:147
#define NULL
Definition: Lib.h:88
struct vertCache_s * dynamicTexCoords
Definition: tr_local.h:120
GLsizei GLsizei GLenum GLenum const GLvoid * data
Definition: glext.h:2853
void RB_EnterWeaponDepthHack()
Definition: tr_render.cpp:176
glstate_t glState
Definition: tr_local.h:663
#define qglEnd
Definition: qgl_linked.h:103
idImageManager * globalImages
Definition: Image_init.cpp:74
idVec4 bumpMatrix[2]
Definition: tr_local.h:456
Definition: Plane.h:71
float lightTextureMatrix[16]
Definition: tr_local.h:650
idImage * image
Definition: Material.h:161
void GLimp_DeactivateContext(void)
Definition: dedicated.cpp:87
idCVar r_skipInteractions("r_skipInteractions","0", CVAR_RENDERER|CVAR_BOOL,"skip all light/surface interaction drawing")
void RB_DrawElementsImmediate(const srfTriangles_t *tri)
Definition: tr_render.cpp:49
colorStage_t color
Definition: Material.h:207
float backEndRendererMaxLight
Definition: tr_local.h:764
float shaderParms[MAX_GLOBAL_SHADER_PARMS]
Definition: RenderWorld.h:223
idVec4 specularMatrix[2]
Definition: tr_local.h:458
const struct drawSurf_s * translucentInteractions
Definition: tr_local.h:334
idImage * blackImage
Definition: Image.h:399
idCVar r_lightScale("r_lightScale","2", CVAR_RENDERER|CVAR_FLOAT,"all light intensities are multiplied by this")
void RB_SetDefaultGLState(void)
Definition: tr_backend.cpp:46
const byte * image
Definition: Cinematic.h:57
#define qglClearStencil
Definition: qgl_linked.h:44
bool currentRenderCopied
Definition: tr_local.h:660
float modelMatrix[16]
Definition: tr_local.h:360
const float * ToFloatPtr(void) const
Definition: Vector.h:1051
void R_TransposeGLMatrix(const float in[16], float out[16])
Definition: tr_main.cpp:821
void RB_ShowOverdraw(void)
idCVar r_skipRenderContext("r_skipRenderContext","0", CVAR_RENDERER|CVAR_BOOL,"NULL the rendering context during backend 3D rendering")
const float * shaderRegisters
Definition: tr_local.h:327
void R_GlobalPointToLocal(const float modelMatrix[16], const idVec3 &in, idVec3 &out)
Definition: tr_main.cpp:522
idVec3 vieworg
Definition: RenderWorld.h:215
void RB_LogComment(const char *comment,...)
Definition: tr_backend.cpp:112
int matrix[2][3]
Definition: Material.h:164
struct viewEntity_s * viewEntitys
Definition: tr_local.h:416
void RB_GetShaderTextureMatrix(const float *shaderRegisters, const textureStage_t *texture, float matrix[16])
Definition: tr_render.cpp:325
bool GetBool(void) const
Definition: CVarSystem.h:142
glconfig_t glConfig
void UnbindIndex()
bool hasMatrix
Definition: Material.h:163
#define qglStencilMask
Definition: qgl_linked.h:284
tuple f
Definition: idal.py:89
textureStage_t texture
Definition: Material.h:210
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
int viewportOffset[2]
Definition: tr_local.h:758
void RB_BindVariableStageImage(const textureStage_t *texture, const float *shaderRegisters)
Definition: tr_render.cpp:378
GLuint texture
Definition: glext.h:3871
void * Position(vertCache_t *buffer)
GLfloat * st
Definition: qgl.h:89
void RB_EnterModelDepthHack(float depth)
Definition: tr_render.cpp:195
idScreenRect scissor
Definition: tr_local.h:400
const struct drawSurf_s * nextOnLight
Definition: tr_local.h:117
#define qglClear
Definition: qgl_linked.h:39
idImage * bumpImage
Definition: tr_local.h:441
float modelViewMatrix[16]
Definition: tr_local.h:361
void RB_FinishStageTexture(const textureStage_t *texture, const drawSurf_t *surf)
Definition: tr_render.cpp:451
stageVertexColor_t vertexColor
Definition: Material.h:211
int numDrawSurfs
Definition: tr_local.h:412
glIndex_t * indexes
Definition: Model.h:102
idVertexCache vertexCache
Definition: VertexCache.cpp:41
idRenderSystemLocal tr
idVec3 globalLightOrigin
Definition: tr_local.h:322
idPlane lightProject[4]
Definition: tr_local.h:323
const idVec3 & ToVec3(void) const
Definition: Vector.h:1043
void GL_State(int stateBits)
Definition: tr_backend.cpp:239
short y1
Definition: tr_local.h:55
void RB_DetermineLightScale(void)
Definition: tr_render.cpp:500
#define qglLoadIdentity
Definition: qgl_linked.h:186
GLint j
Definition: qgl.h:264
int numIndexes
Definition: Model.h:101
idCVar r_useScissor("r_useScissor","1", CVAR_RENDERER|CVAR_BOOL,"scissor clip as portals and lights are processed")
#define qglNormalPointer
Definition: qgl_linked.h:217
idImage * cinematicImage
Definition: Image.h:404
virtual cinData_t ImageForTime(int milliseconds)
Definition: Cinematic.cpp:243
struct vertCache_s * indexCache
Definition: Model.h:136
#define max(x, y)
Definition: os.h:70
short y2
Definition: tr_local.h:55
idCVar r_skipDiffuse("r_skipDiffuse","0", CVAR_RENDERER|CVAR_BOOL,"use black for diffuse")
void GLimp_ActivateContext(void)
Definition: dedicated.cpp:89
void Bind()
idScreenRect currentScissor
Definition: tr_local.h:645
void R_SetDrawInteraction(const shaderStage_t *surfaceStage, const float *surfaceRegs, idImage **image, idVec4 matrix[2], float color[4])
Definition: tr_render.cpp:600
idCinematic * cinematic
Definition: Material.h:160
#define qglMatrixMode
Definition: qgl_linked.h:203
#define qglVertexPointer
Definition: qgl_linked.h:363
void R_GlobalPlaneToLocal(const float modelMatrix[16], const idPlane &in, idPlane &out)
Definition: tr_main.cpp:547
const float * shaderRegisters
Definition: tr_local.h:116
int imageWidth
Definition: Cinematic.h:56
int imageHeight
Definition: Cinematic.h:56
idDrawVert * verts
Definition: Model.h:99
bool Equals(const idScreenRect &rect) const
Definition: tr_main.cpp:133
int faceCulling
Definition: tr_local.h:607
int stencilBits
Definition: RenderSystem.h:60
idVec4 localViewOrigin
Definition: tr_local.h:454
const viewDef_t * viewDef
Definition: tr_local.h:641