doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
tr_rendertools.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 #include "simplex.h" // line font definition
34 
35 #define MAX_DEBUG_LINES 16384
36 
37 typedef struct debugLine_s {
41  bool depthTest;
42  int lifeTime;
43 } debugLine_t;
44 
48 
49 #define MAX_DEBUG_TEXT 512
50 
51 typedef struct debugText_s {
54  float scale;
57  int align;
58  int lifeTime;
59  bool depthTest;
60 } debugText_t;
61 
65 
66 #define MAX_DEBUG_POLYGONS 8192
67 
68 typedef struct debugPolygon_s {
71  bool depthTest;
72  int lifeTime;
74 
78 
79 static void RB_DrawText( const char *text, const idVec3 &origin, float scale, const idVec4 &color, const idMat3 &viewAxis, const int align );
80 
81 /*
82 ================
83 RB_DrawBounds
84 ================
85 */
86 void RB_DrawBounds( const idBounds &bounds ) {
87  if ( bounds.IsCleared() ) {
88  return;
89  }
90 
91  qglBegin( GL_LINE_LOOP );
92  qglVertex3f( bounds[0][0], bounds[0][1], bounds[0][2] );
93  qglVertex3f( bounds[0][0], bounds[1][1], bounds[0][2] );
94  qglVertex3f( bounds[1][0], bounds[1][1], bounds[0][2] );
95  qglVertex3f( bounds[1][0], bounds[0][1], bounds[0][2] );
96  qglEnd();
97  qglBegin( GL_LINE_LOOP );
98  qglVertex3f( bounds[0][0], bounds[0][1], bounds[1][2] );
99  qglVertex3f( bounds[0][0], bounds[1][1], bounds[1][2] );
100  qglVertex3f( bounds[1][0], bounds[1][1], bounds[1][2] );
101  qglVertex3f( bounds[1][0], bounds[0][1], bounds[1][2] );
102  qglEnd();
103 
104  qglBegin( GL_LINES );
105  qglVertex3f( bounds[0][0], bounds[0][1], bounds[0][2] );
106  qglVertex3f( bounds[0][0], bounds[0][1], bounds[1][2] );
107 
108  qglVertex3f( bounds[0][0], bounds[1][1], bounds[0][2] );
109  qglVertex3f( bounds[0][0], bounds[1][1], bounds[1][2] );
110 
111  qglVertex3f( bounds[1][0], bounds[0][1], bounds[0][2] );
112  qglVertex3f( bounds[1][0], bounds[0][1], bounds[1][2] );
113 
114  qglVertex3f( bounds[1][0], bounds[1][1], bounds[0][2] );
115  qglVertex3f( bounds[1][0], bounds[1][1], bounds[1][2] );
116  qglEnd();
117 }
118 
119 
120 /*
121 ================
122 RB_SimpleSurfaceSetup
123 ================
124 */
125 void RB_SimpleSurfaceSetup( const drawSurf_t *drawSurf ) {
126  // change the matrix if needed
127  if ( drawSurf->space != backEnd.currentSpace ) {
128  qglLoadMatrixf( drawSurf->space->modelViewMatrix );
129  backEnd.currentSpace = drawSurf->space;
130  }
131 
132  // change the scissor if needed
133  if ( r_useScissor.GetBool() && !backEnd.currentScissor.Equals( drawSurf->scissorRect ) ) {
134  backEnd.currentScissor = drawSurf->scissorRect;
139  }
140 }
141 
142 /*
143 ================
144 RB_SimpleWorldSetup
145 ================
146 */
147 void RB_SimpleWorldSetup( void ) {
150 
156 }
157 
158 /*
159 =================
160 RB_PolygonClear
161 
162 This will cover the entire screen with normal rasterization.
163 Texturing is disabled, but the existing glColor, glDepthMask,
164 glColorMask, and the enabled state of depth buffering and
165 stenciling will matter.
166 =================
167 */
168 void RB_PolygonClear( void ) {
169  qglPushMatrix();
170  qglPushAttrib( GL_ALL_ATTRIB_BITS );
171  qglLoadIdentity();
172  qglDisable( GL_TEXTURE_2D );
173  qglDisable( GL_DEPTH_TEST );
174  qglDisable( GL_CULL_FACE );
175  qglDisable( GL_SCISSOR_TEST );
176  qglBegin( GL_POLYGON );
177  qglVertex3f( -20, -20, -10 );
178  qglVertex3f( 20, -20, -10 );
179  qglVertex3f( 20, 20, -10 );
180  qglVertex3f( -20, 20, -10 );
181  qglEnd();
182  qglPopAttrib();
183  qglPopMatrix();
184 }
185 
186 /*
187 ====================
188 RB_ShowDestinationAlpha
189 ====================
190 */
193  qglColor3f( 1, 1, 1 );
194  RB_PolygonClear();
195 }
196 
197 /*
198 ===================
199 RB_ScanStencilBuffer
200 
201 Debugging tool to see what values are in the stencil buffer
202 ===================
203 */
204 void RB_ScanStencilBuffer( void ) {
205  int counts[256];
206  int i;
207  byte *stencilReadback;
208 
209  memset( counts, 0, sizeof( counts ) );
210 
211  stencilReadback = (byte *)R_StaticAlloc( glConfig.vidWidth * glConfig.vidHeight );
212  qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencilReadback );
213 
214  for ( i = 0; i < glConfig.vidWidth * glConfig.vidHeight; i++ ) {
215  counts[ stencilReadback[i] ]++;
216  }
217 
218  R_StaticFree( stencilReadback );
219 
220  // print some stats (not supposed to do from back end in SMP...)
221  common->Printf( "stencil values:\n" );
222  for ( i = 0 ; i < 255 ; i++ ) {
223  if ( counts[i] ) {
224  common->Printf( "%i: %i\n", i, counts[i] );
225  }
226  }
227 }
228 
229 
230 /*
231 ===================
232 RB_CountStencilBuffer
233 
234 Print an overdraw count based on stencil index values
235 ===================
236 */
237 void RB_CountStencilBuffer( void ) {
238  int count;
239  int i;
240  byte *stencilReadback;
241 
242 
243  stencilReadback = (byte *)R_StaticAlloc( glConfig.vidWidth * glConfig.vidHeight );
244  qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencilReadback );
245 
246  count = 0;
247  for ( i = 0; i < glConfig.vidWidth * glConfig.vidHeight; i++ ) {
248  count += stencilReadback[i];
249  }
250 
251  R_StaticFree( stencilReadback );
252 
253  // print some stats (not supposed to do from back end in SMP...)
254  common->Printf( "overdraw: %5.1f\n", (float)count/(glConfig.vidWidth * glConfig.vidHeight) );
255 }
256 
257 /*
258 ===================
259 R_ColorByStencilBuffer
260 
261 Sets the screen colors based on the contents of the
262 stencil buffer. Stencil of 0 = black, 1 = red, 2 = green,
263 3 = blue, ..., 7+ = white
264 ===================
265 */
266 static void R_ColorByStencilBuffer( void ) {
267  int i;
268  static float colors[8][3] = {
269  {0,0,0},
270  {1,0,0},
271  {0,1,0},
272  {0,0,1},
273  {0,1,1},
274  {1,0,1},
275  {1,1,0},
276  {1,1,1},
277  };
278 
279  // clear color buffer to white (>6 passes)
280  qglClearColor( 1, 1, 1, 1 );
281  qglDisable( GL_SCISSOR_TEST );
282  qglClear( GL_COLOR_BUFFER_BIT );
283 
284  // now draw color for each stencil value
285  qglStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
286  for ( i = 0 ; i < 6 ; i++ ) {
287  qglColor3fv( colors[i] );
288  qglStencilFunc( GL_EQUAL, i, 255 );
289  RB_PolygonClear();
290  }
291 
292  qglStencilFunc( GL_ALWAYS, 0, 255 );
293 }
294 
295 //======================================================================
296 
297 /*
298 ==================
299 RB_ShowOverdraw
300 ==================
301 */
302 void RB_ShowOverdraw( void ) {
303  const idMaterial * material;
304  int i;
305  drawSurf_t * * drawSurfs;
306  const drawSurf_t * surf;
307  int numDrawSurfs;
308  viewLight_t * vLight;
309 
310  if ( r_showOverDraw.GetInteger() == 0 ) {
311  return;
312  }
313 
314  material = declManager->FindMaterial( "textures/common/overdrawtest", false );
315  if ( material == NULL ) {
316  return;
317  }
318 
319  drawSurfs = backEnd.viewDef->drawSurfs;
320  numDrawSurfs = backEnd.viewDef->numDrawSurfs;
321 
322  int interactions = 0;
323  for ( vLight = backEnd.viewDef->viewLights; vLight; vLight = vLight->next ) {
324  for ( surf = vLight->localInteractions; surf; surf = surf->nextOnLight ) {
325  interactions++;
326  }
327  for ( surf = vLight->globalInteractions; surf; surf = surf->nextOnLight ) {
328  interactions++;
329  }
330  }
331 
332  drawSurf_t **newDrawSurfs = (drawSurf_t **)R_FrameAlloc( numDrawSurfs + interactions * sizeof( newDrawSurfs[0] ) );
333 
334  for ( i = 0; i < numDrawSurfs; i++ ) {
335  surf = drawSurfs[i];
336  if ( surf->material ) {
337  const_cast<drawSurf_t *>(surf)->material = material;
338  }
339  newDrawSurfs[i] = const_cast<drawSurf_t *>(surf);
340  }
341 
342  for ( vLight = backEnd.viewDef->viewLights; vLight; vLight = vLight->next ) {
343  for ( surf = vLight->localInteractions; surf; surf = surf->nextOnLight ) {
344  const_cast<drawSurf_t *>(surf)->material = material;
345  newDrawSurfs[i++] = const_cast<drawSurf_t *>(surf);
346  }
347  for ( surf = vLight->globalInteractions; surf; surf = surf->nextOnLight ) {
348  const_cast<drawSurf_t *>(surf)->material = material;
349  newDrawSurfs[i++] = const_cast<drawSurf_t *>(surf);
350  }
351  vLight->localInteractions = NULL;
352  vLight->globalInteractions = NULL;
353  }
354 
355  switch( r_showOverDraw.GetInteger() ) {
356  case 1: // geometry overdraw
357  const_cast<viewDef_t *>(backEnd.viewDef)->drawSurfs = newDrawSurfs;
358  const_cast<viewDef_t *>(backEnd.viewDef)->numDrawSurfs = numDrawSurfs;
359  break;
360  case 2: // light interaction overdraw
361  const_cast<viewDef_t *>(backEnd.viewDef)->drawSurfs = &newDrawSurfs[numDrawSurfs];
362  const_cast<viewDef_t *>(backEnd.viewDef)->numDrawSurfs = interactions;
363  break;
364  case 3: // geometry + light interaction overdraw
365  const_cast<viewDef_t *>(backEnd.viewDef)->drawSurfs = newDrawSurfs;
366  const_cast<viewDef_t *>(backEnd.viewDef)->numDrawSurfs += interactions;
367  break;
368  }
369 }
370 
371 /*
372 ===================
373 RB_ShowIntensity
374 
375 Debugging tool to see how much dynamic range a scene is using.
376 The greatest of the rgb values at each pixel will be used, with
377 the resulting color shading from red at 0 to green at 128 to blue at 255
378 ===================
379 */
380 void RB_ShowIntensity( void ) {
381  byte *colorReadback;
382  int i, j, c;
383 
384  if ( !r_showIntensity.GetBool() ) {
385  return;
386  }
387 
388  colorReadback = (byte *)R_StaticAlloc( glConfig.vidWidth * glConfig.vidHeight * 4 );
389  qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_RGBA, GL_UNSIGNED_BYTE, colorReadback );
390 
392  for ( i = 0; i < c ; i+=4 ) {
393  j = colorReadback[i];
394  if ( colorReadback[i+1] > j ) {
395  j = colorReadback[i+1];
396  }
397  if ( colorReadback[i+2] > j ) {
398  j = colorReadback[i+2];
399  }
400  if ( j < 128 ) {
401  colorReadback[i+0] = 2*(128-j);
402  colorReadback[i+1] = 2*j;
403  colorReadback[i+2] = 0;
404  } else {
405  colorReadback[i+0] = 0;
406  colorReadback[i+1] = 2*(255-j);
407  colorReadback[i+2] = 2*(j-128);
408  }
409  }
410 
411  // draw it back to the screen
412  qglLoadIdentity();
413  qglMatrixMode( GL_PROJECTION );
415  qglPushMatrix();
416  qglLoadIdentity();
417  qglOrtho( 0, 1, 0, 1, -1, 1 );
418  qglRasterPos2f( 0, 0 );
419  qglPopMatrix();
420  qglColor3f( 1, 1, 1 );
422  qglMatrixMode( GL_MODELVIEW );
423 
424  qglDrawPixels( glConfig.vidWidth, glConfig.vidHeight, GL_RGBA , GL_UNSIGNED_BYTE, colorReadback );
425 
426  R_StaticFree( colorReadback );
427 }
428 
429 
430 /*
431 ===================
432 RB_ShowDepthBuffer
433 
434 Draw the depth buffer as colors
435 ===================
436 */
437 void RB_ShowDepthBuffer( void ) {
438  void *depthReadback;
439 
440  if ( !r_showDepth.GetBool() ) {
441  return;
442  }
443 
444  qglPushMatrix();
445  qglLoadIdentity();
446  qglMatrixMode( GL_PROJECTION );
447  qglPushMatrix();
448  qglLoadIdentity();
449  qglOrtho( 0, 1, 0, 1, -1, 1 );
450  qglRasterPos2f( 0, 0 );
451  qglPopMatrix();
452  qglMatrixMode( GL_MODELVIEW );
453  qglPopMatrix();
454 
456  qglColor3f( 1, 1, 1 );
458 
459  depthReadback = R_StaticAlloc( glConfig.vidWidth * glConfig.vidHeight*4 );
460  memset( depthReadback, 0, glConfig.vidWidth * glConfig.vidHeight*4 );
461 
462  qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_DEPTH_COMPONENT , GL_FLOAT, depthReadback );
463 
464 #if 0
465  for ( i = 0 ; i < glConfig.vidWidth * glConfig.vidHeight ; i++ ) {
466  ((byte *)depthReadback)[i*4] =
467  ((byte *)depthReadback)[i*4+1] =
468  ((byte *)depthReadback)[i*4+2] = 255 * ((float *)depthReadback)[i];
469  ((byte *)depthReadback)[i*4+3] = 1;
470  }
471 #endif
472 
473  qglDrawPixels( glConfig.vidWidth, glConfig.vidHeight, GL_RGBA , GL_UNSIGNED_BYTE, depthReadback );
474  R_StaticFree( depthReadback );
475 }
476 
477 /*
478 =================
479 RB_ShowLightCount
480 
481 This is a debugging tool that will draw each surface with a color
482 based on how many lights are effecting it
483 =================
484 */
485 void RB_ShowLightCount( void ) {
486  int i;
487  const drawSurf_t *surf;
488  const viewLight_t *vLight;
489 
490  if ( !r_showLightCount.GetBool() ) {
491  return;
492  }
493 
495 
497  qglClearStencil( 0 );
498  qglClear( GL_STENCIL_BUFFER_BIT );
499 
500  qglEnable( GL_STENCIL_TEST );
501 
502  // optionally count everything through walls
503  if ( r_showLightCount.GetInteger() >= 2 ) {
504  qglStencilOp( GL_KEEP, GL_INCR, GL_INCR );
505  } else {
506  qglStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
507  }
508 
509  qglStencilFunc( GL_ALWAYS, 1, 255 );
510 
512 
513  for ( vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) {
514  for ( i = 0 ; i < 2 ; i++ ) {
515  for ( surf = i ? vLight->localInteractions: vLight->globalInteractions; surf; surf = (drawSurf_t *)surf->nextOnLight ) {
516  RB_SimpleSurfaceSetup( surf );
517  if ( !surf->geo->ambientCache ) {
518  continue;
519  }
520 
521  const idDrawVert *ac = (idDrawVert *)vertexCache.Position( surf->geo->ambientCache );
522  qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), &ac->xyz );
524  }
525  }
526  }
527 
528  // display the results
529  R_ColorByStencilBuffer();
530 
531  if ( r_showLightCount.GetInteger() > 2 ) {
533  }
534 }
535 
536 
537 /*
538 =================
539 RB_ShowSilhouette
540 
541 Blacks out all edges, then adds color for each edge that a shadow
542 plane extends from, allowing you to see doubled edges
543 =================
544 */
545 void RB_ShowSilhouette( void ) {
546  int i;
547  const drawSurf_t *surf;
548  const viewLight_t *vLight;
549 
550  if ( !r_showSilhouette.GetBool() ) {
551  return;
552  }
553 
554  //
555  // clear all triangle edges to black
556  //
557  qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
559  qglDisable( GL_TEXTURE_2D );
560  qglDisable( GL_STENCIL_TEST );
561 
562  qglColor3f( 0, 0, 0 );
563 
565 
567  qglDisable( GL_DEPTH_TEST );
568 
571 
572 
573  //
574  // now blend in edges that cast silhouettes
575  //
577  qglColor3f( 0.5, 0, 0 );
579 
580  for ( vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) {
581  for ( i = 0 ; i < 2 ; i++ ) {
582  for ( surf = i ? vLight->localShadows : vLight->globalShadows
583  ; surf ; surf = (drawSurf_t *)surf->nextOnLight ) {
584  RB_SimpleSurfaceSetup( surf );
585 
586  const srfTriangles_t *tri = surf->geo;
587 
588  qglVertexPointer( 3, GL_FLOAT, sizeof( shadowCache_t ), vertexCache.Position( tri->shadowCache ) );
589  qglBegin( GL_LINES );
590 
591  for ( int j = 0 ; j < tri->numIndexes ; j+=3 ) {
592  int i1 = tri->indexes[j+0];
593  int i2 = tri->indexes[j+1];
594  int i3 = tri->indexes[j+2];
595 
596  if ( (i1 & 1) + (i2 & 1) + (i3 & 1) == 1 ) {
597  if ( (i1 & 1) + (i2 & 1) == 0 ) {
598  qglArrayElement( i1 );
599  qglArrayElement( i2 );
600  } else if ( (i1 & 1 ) + (i3 & 1) == 0 ) {
601  qglArrayElement( i1 );
602  qglArrayElement( i3 );
603  }
604  }
605  }
606  qglEnd();
607 
608  }
609  }
610  }
611 
612  qglEnable( GL_DEPTH_TEST );
613 
615  qglColor3f( 1,1,1 );
617 }
618 
619 
620 
621 /*
622 =================
623 RB_ShowShadowCount
624 
625 This is a debugging tool that will draw only the shadow volumes
626 and count up the total fill usage
627 =================
628 */
629 static void RB_ShowShadowCount( void ) {
630  int i;
631  const drawSurf_t *surf;
632  const viewLight_t *vLight;
633 
634  if ( !r_showShadowCount.GetBool() ) {
635  return;
636  }
637 
639 
640  qglClearStencil( 0 );
641  qglClear( GL_STENCIL_BUFFER_BIT );
642 
643  qglEnable( GL_STENCIL_TEST );
644 
645  qglStencilOp( GL_KEEP, GL_INCR, GL_INCR );
646 
647  qglStencilFunc( GL_ALWAYS, 1, 255 );
648 
650 
651  // draw both sides
653 
654  for ( vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) {
655  for ( i = 0 ; i < 2 ; i++ ) {
656  for ( surf = i ? vLight->localShadows : vLight->globalShadows
657  ; surf ; surf = (drawSurf_t *)surf->nextOnLight ) {
658  RB_SimpleSurfaceSetup( surf );
659  const srfTriangles_t *tri = surf->geo;
660  if ( !tri->shadowCache ) {
661  continue;
662  }
663 
664  if ( r_showShadowCount.GetInteger() == 3 ) {
665  // only show turboshadows
666  if ( tri->numShadowIndexesNoCaps != tri->numIndexes ) {
667  continue;
668  }
669  }
670  if ( r_showShadowCount.GetInteger() == 4 ) {
671  // only show static shadows
672  if ( tri->numShadowIndexesNoCaps == tri->numIndexes ) {
673  continue;
674  }
675  }
676 
678  qglVertexPointer( 4, GL_FLOAT, sizeof( *cache ), &cache->xyz );
680  }
681  }
682  }
683 
684  // display the results
685  R_ColorByStencilBuffer();
686 
687  if ( r_showShadowCount.GetInteger() == 2 ) {
688  common->Printf( "all shadows " );
689  } else if ( r_showShadowCount.GetInteger() == 3 ) {
690  common->Printf( "turboShadows " );
691  } else if ( r_showShadowCount.GetInteger() == 4 ) {
692  common->Printf( "static shadows " );
693  }
694 
695  if ( r_showShadowCount.GetInteger() >= 2 ) {
697  }
698 
700 }
701 
702 
703 /*
704 ===============
705 RB_T_RenderTriangleSurfaceAsLines
706 
707 ===============
708 */
710  const srfTriangles_t *tri = surf->geo;
711 
712  if ( !tri->verts ) {
713  return;
714  }
715 
716  qglBegin( GL_LINES );
717  for ( int i = 0 ; i < tri->numIndexes ; i+= 3 ) {
718  for ( int j = 0 ; j < 3 ; j++ ) {
719  int k = ( j + 1 ) % 3;
720  qglVertex3fv( tri->verts[ tri->silIndexes[i+j] ].xyz.ToFloatPtr() );
721  qglVertex3fv( tri->verts[ tri->silIndexes[i+k] ].xyz.ToFloatPtr() );
722  }
723  }
724  qglEnd();
725 }
726 
727 
728 /*
729 =====================
730 RB_ShowTris
731 
732 Debugging tool
733 =====================
734 */
735 static void RB_ShowTris( drawSurf_t **drawSurfs, int numDrawSurfs ) {
736  modelTrace_t mt;
737  idVec3 end;
738 
739  if ( !r_showTris.GetInteger() ) {
740  return;
741  }
742 
743  qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
745  qglDisable( GL_TEXTURE_2D );
746  qglDisable( GL_STENCIL_TEST );
747 
748  qglColor3f( 1, 1, 1 );
749 
750 
752 
753  switch ( r_showTris.GetInteger() ) {
754  case 1: // only draw visible ones
755  qglPolygonOffset( -1, -2 );
756  qglEnable( GL_POLYGON_OFFSET_LINE );
757  break;
758  default:
759  case 2: // draw all front facing
761  qglDisable( GL_DEPTH_TEST );
762  break;
763  case 3: // draw all
765  qglDisable( GL_DEPTH_TEST );
766  break;
767  }
768 
770 
771  qglEnable( GL_DEPTH_TEST );
772  qglDisable( GL_POLYGON_OFFSET_LINE );
773 
774  qglDepthRange( 0, 1 );
777 }
778 
779 
780 /*
781 =====================
782 RB_ShowSurfaceInfo
783 
784 Debugging tool
785 =====================
786 */
787 static void RB_ShowSurfaceInfo( drawSurf_t **drawSurfs, int numDrawSurfs ) {
788  modelTrace_t mt;
789  idVec3 start, end;
790 
791  if ( !r_showSurfaceInfo.GetBool() ) {
792  return;
793  }
794 
795  // start far enough away that we don't hit the player model
797  end = start + tr.primaryView->renderView.viewaxis[0] * 1000.0f;
798  if ( !tr.primaryWorld->Trace( mt, start, end, 0.0f, false ) ) {
799  return;
800  }
801 
802  qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
804  qglDisable( GL_TEXTURE_2D );
805  qglDisable( GL_STENCIL_TEST );
806 
807  qglColor3f( 1, 1, 1 );
808 
810 
811  qglPolygonOffset( -1, -2 );
812  qglEnable( GL_POLYGON_OFFSET_LINE );
813 
814  idVec3 trans[3];
815  float matrix[16];
816 
817  // transform the object verts into global space
818  R_AxisToModelMatrix( mt.entity->axis, mt.entity->origin, matrix );
819 
824 
825  qglEnable( GL_DEPTH_TEST );
826  qglDisable( GL_POLYGON_OFFSET_LINE );
827 
828  qglDepthRange( 0, 1 );
831 }
832 
833 
834 /*
835 =====================
836 RB_ShowViewEntitys
837 
838 Debugging tool
839 =====================
840 */
841 static void RB_ShowViewEntitys( viewEntity_t *vModels ) {
842  if ( !r_showViewEntitys.GetBool() ) {
843  return;
844  }
845  if ( r_showViewEntitys.GetInteger() == 2 ) {
846  common->Printf( "view entities: " );
847  for ( ; vModels ; vModels = vModels->next ) {
848  common->Printf( "%i ", vModels->entityDef->index );
849  }
850  common->Printf( "\n" );
851  return;
852  }
853 
854  qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
856  qglDisable( GL_TEXTURE_2D );
857  qglDisable( GL_STENCIL_TEST );
858 
859  qglColor3f( 1, 1, 1 );
860 
861 
863 
865  qglDisable( GL_DEPTH_TEST );
866  qglDisable( GL_SCISSOR_TEST );
867 
868  for ( ; vModels ; vModels = vModels->next ) {
869  idBounds b;
870 
871  qglLoadMatrixf( vModels->modelViewMatrix );
872 
873  if ( !vModels->entityDef ) {
874  continue;
875  }
876 
877  // draw the reference bounds in yellow
878  qglColor3f( 1, 1, 0 );
880 
881 
882  // draw the model bounds in white
883  qglColor3f( 1, 1, 1 );
884 
885  idRenderModel *model = R_EntityDefDynamicModel( vModels->entityDef );
886  if ( !model ) {
887  continue; // particles won't instantiate without a current view
888  }
889  b = model->Bounds( &vModels->entityDef->parms );
890  RB_DrawBounds( b );
891  }
892 
893  qglEnable( GL_DEPTH_TEST );
894  qglDisable( GL_POLYGON_OFFSET_LINE );
895 
896  qglDepthRange( 0, 1 );
899 }
900 
901 /*
902 =====================
903 RB_ShowTexturePolarity
904 
905 Shade triangle red if they have a positive texture area
906 green if they have a negative texture area, or blue if degenerate area
907 =====================
908 */
909 static void RB_ShowTexturePolarity( drawSurf_t **drawSurfs, int numDrawSurfs ) {
910  int i, j;
911  drawSurf_t *drawSurf;
912  const srfTriangles_t *tri;
913 
914  if ( !r_showTexturePolarity.GetBool() ) {
915  return;
916  }
917  qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
919  qglDisable( GL_STENCIL_TEST );
920 
922 
923  qglColor3f( 1, 1, 1 );
924 
925  for ( i = 0 ; i < numDrawSurfs ; i++ ) {
926  drawSurf = drawSurfs[i];
927  tri = drawSurf->geo;
928  if ( !tri->verts ) {
929  continue;
930  }
931 
932  RB_SimpleSurfaceSetup( drawSurf );
933 
934  qglBegin( GL_TRIANGLES );
935  for ( j = 0 ; j < tri->numIndexes ; j+=3 ) {
936  idDrawVert *a, *b, *c;
937  float d0[5], d1[5];
938  float area;
939 
940  a = tri->verts + tri->indexes[j];
941  b = tri->verts + tri->indexes[j+1];
942  c = tri->verts + tri->indexes[j+2];
943 
944  // VectorSubtract( b->xyz, a->xyz, d0 );
945  d0[3] = b->st[0] - a->st[0];
946  d0[4] = b->st[1] - a->st[1];
947  // VectorSubtract( c->xyz, a->xyz, d1 );
948  d1[3] = c->st[0] - a->st[0];
949  d1[4] = c->st[1] - a->st[1];
950 
951  area = d0[3] * d1[4] - d0[4] * d1[3];
952 
953  if ( idMath::Fabs( area ) < 0.0001 ) {
954  qglColor4f( 0, 0, 1, 0.5 );
955  } else if ( area < 0 ) {
956  qglColor4f( 1, 0, 0, 0.5 );
957  } else {
958  qglColor4f( 0, 1, 0, 0.5 );
959  }
960  qglVertex3fv( a->xyz.ToFloatPtr() );
961  qglVertex3fv( b->xyz.ToFloatPtr() );
962  qglVertex3fv( c->xyz.ToFloatPtr() );
963  }
964  qglEnd();
965  }
966 
968 }
969 
970 
971 /*
972 =====================
973 RB_ShowUnsmoothedTangents
974 
975 Shade materials that are using unsmoothed tangents
976 =====================
977 */
978 static void RB_ShowUnsmoothedTangents( drawSurf_t **drawSurfs, int numDrawSurfs ) {
979  int i, j;
980  drawSurf_t *drawSurf;
981  const srfTriangles_t *tri;
982 
984  return;
985  }
986  qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
988  qglDisable( GL_STENCIL_TEST );
989 
991 
992  qglColor4f( 0, 1, 0, 0.5 );
993 
994  for ( i = 0 ; i < numDrawSurfs ; i++ ) {
995  drawSurf = drawSurfs[i];
996 
997  if ( !drawSurf->material->UseUnsmoothedTangents() ) {
998  continue;
999  }
1000 
1001  RB_SimpleSurfaceSetup( drawSurf );
1002 
1003  tri = drawSurf->geo;
1004  qglBegin( GL_TRIANGLES );
1005  for ( j = 0 ; j < tri->numIndexes ; j+=3 ) {
1006  idDrawVert *a, *b, *c;
1007 
1008  a = tri->verts + tri->indexes[j];
1009  b = tri->verts + tri->indexes[j+1];
1010  c = tri->verts + tri->indexes[j+2];
1011 
1012  qglVertex3fv( a->xyz.ToFloatPtr() );
1013  qglVertex3fv( b->xyz.ToFloatPtr() );
1014  qglVertex3fv( c->xyz.ToFloatPtr() );
1015  }
1016  qglEnd();
1017  }
1018 
1019  GL_State( GLS_DEFAULT );
1020 }
1021 
1022 
1023 /*
1024 =====================
1025 RB_ShowTangentSpace
1026 
1027 Shade a triangle by the RGB colors of its tangent space
1028 1 = tangents[0]
1029 2 = tangents[1]
1030 3 = normal
1031 =====================
1032 */
1033 static void RB_ShowTangentSpace( drawSurf_t **drawSurfs, int numDrawSurfs ) {
1034  int i, j;
1035  drawSurf_t *drawSurf;
1036  const srfTriangles_t *tri;
1037 
1038  if ( !r_showTangentSpace.GetInteger() ) {
1039  return;
1040  }
1041  qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
1043  qglDisable( GL_STENCIL_TEST );
1044 
1046 
1047  for ( i = 0 ; i < numDrawSurfs ; i++ ) {
1048  drawSurf = drawSurfs[i];
1049 
1050  RB_SimpleSurfaceSetup( drawSurf );
1051 
1052  tri = drawSurf->geo;
1053  if ( !tri->verts ) {
1054  continue;
1055  }
1056  qglBegin( GL_TRIANGLES );
1057  for ( j = 0 ; j < tri->numIndexes ; j++ ) {
1058  const idDrawVert *v;
1059 
1060  v = &tri->verts[tri->indexes[j]];
1061 
1062  if ( r_showTangentSpace.GetInteger() == 1 ) {
1063  qglColor4f( 0.5 + 0.5 * v->tangents[0][0], 0.5 + 0.5 * v->tangents[0][1],
1064  0.5 + 0.5 * v->tangents[0][2], 0.5 );
1065  } else if ( r_showTangentSpace.GetInteger() == 2 ) {
1066  qglColor4f( 0.5 + 0.5 * v->tangents[1][0], 0.5 + 0.5 * v->tangents[1][1],
1067  0.5 + 0.5 * v->tangents[1][2], 0.5 );
1068  } else {
1069  qglColor4f( 0.5 + 0.5 * v->normal[0], 0.5 + 0.5 * v->normal[1],
1070  0.5 + 0.5 * v->normal[2], 0.5 );
1071  }
1072  qglVertex3fv( v->xyz.ToFloatPtr() );
1073  }
1074  qglEnd();
1075  }
1076 
1077  GL_State( GLS_DEFAULT );
1078 }
1079 
1080 /*
1081 =====================
1082 RB_ShowVertexColor
1083 
1084 Draw each triangle with the solid vertex colors
1085 =====================
1086 */
1087 static void RB_ShowVertexColor( drawSurf_t **drawSurfs, int numDrawSurfs ) {
1088  int i, j;
1089  drawSurf_t *drawSurf;
1090  const srfTriangles_t *tri;
1091 
1092  if ( !r_showVertexColor.GetBool() ) {
1093  return;
1094  }
1095  qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
1097  qglDisable( GL_STENCIL_TEST );
1098 
1100 
1101  for ( i = 0 ; i < numDrawSurfs ; i++ ) {
1102  drawSurf = drawSurfs[i];
1103 
1104  RB_SimpleSurfaceSetup( drawSurf );
1105 
1106  tri = drawSurf->geo;
1107  if ( !tri->verts ) {
1108  continue;
1109  }
1110  qglBegin( GL_TRIANGLES );
1111  for ( j = 0 ; j < tri->numIndexes ; j++ ) {
1112  const idDrawVert *v;
1113 
1114  v = &tri->verts[tri->indexes[j]];
1115  qglColor4ubv( v->color );
1116  qglVertex3fv( v->xyz.ToFloatPtr() );
1117  }
1118  qglEnd();
1119  }
1120 
1121  GL_State( GLS_DEFAULT );
1122 }
1123 
1124 
1125 /*
1126 =====================
1127 RB_ShowNormals
1128 
1129 Debugging tool
1130 =====================
1131 */
1132 static void RB_ShowNormals( drawSurf_t **drawSurfs, int numDrawSurfs ) {
1133  int i, j;
1134  drawSurf_t *drawSurf;
1135  idVec3 end;
1136  const srfTriangles_t *tri;
1137  float size;
1138  bool showNumbers;
1139  idVec3 pos;
1140 
1141  if ( r_showNormals.GetFloat() == 0.0f ) {
1142  return;
1143  }
1144 
1146  qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
1147 
1149  qglDisable( GL_STENCIL_TEST );
1150  if ( !r_debugLineDepthTest.GetBool() ) {
1151  qglDisable( GL_DEPTH_TEST );
1152  } else {
1153  qglEnable( GL_DEPTH_TEST );
1154  }
1155 
1156  size = r_showNormals.GetFloat();
1157  if ( size < 0.0f ) {
1158  size = -size;
1159  showNumbers = true;
1160  } else {
1161  showNumbers = false;
1162  }
1163 
1164  for ( i = 0 ; i < numDrawSurfs ; i++ ) {
1165  drawSurf = drawSurfs[i];
1166 
1167  RB_SimpleSurfaceSetup( drawSurf );
1168 
1169  tri = drawSurf->geo;
1170  if ( !tri->verts ) {
1171  continue;
1172  }
1173 
1174  qglBegin( GL_LINES );
1175  for ( j = 0 ; j < tri->numVerts ; j++ ) {
1176  qglColor3f( 0, 0, 1 );
1177  qglVertex3fv( tri->verts[j].xyz.ToFloatPtr() );
1178  VectorMA( tri->verts[j].xyz, size, tri->verts[j].normal, end );
1179  qglVertex3fv( end.ToFloatPtr() );
1180 
1181  qglColor3f( 1, 0, 0 );
1182  qglVertex3fv( tri->verts[j].xyz.ToFloatPtr() );
1183  VectorMA( tri->verts[j].xyz, size, tri->verts[j].tangents[0], end );
1184  qglVertex3fv( end.ToFloatPtr() );
1185 
1186  qglColor3f( 0, 1, 0 );
1187  qglVertex3fv( tri->verts[j].xyz.ToFloatPtr() );
1188  VectorMA( tri->verts[j].xyz, size, tri->verts[j].tangents[1], end );
1189  qglVertex3fv( end.ToFloatPtr() );
1190  }
1191  qglEnd();
1192  }
1193 
1194  if ( showNumbers ) {
1196  for ( i = 0 ; i < numDrawSurfs ; i++ ) {
1197  drawSurf = drawSurfs[i];
1198  tri = drawSurf->geo;
1199  if ( !tri->verts ) {
1200  continue;
1201  }
1202 
1203  for ( j = 0 ; j < tri->numVerts ; j++ ) {
1204  R_LocalPointToGlobal( drawSurf->space->modelMatrix, tri->verts[j].xyz + tri->verts[j].tangents[0] + tri->verts[j].normal * 0.2f, pos );
1205  RB_DrawText( va( "%d", j ), pos, 0.01f, colorWhite, backEnd.viewDef->renderView.viewaxis, 1 );
1206  }
1207 
1208  for ( j = 0 ; j < tri->numIndexes; j += 3 ) {
1209  R_LocalPointToGlobal( drawSurf->space->modelMatrix, ( tri->verts[ tri->indexes[ j + 0 ] ].xyz + tri->verts[ tri->indexes[ j + 1 ] ].xyz + tri->verts[ tri->indexes[ j + 2 ] ].xyz ) * ( 1.0f / 3.0f ) + tri->verts[ tri->indexes[ j + 0 ] ].normal * 0.2f, pos );
1210  RB_DrawText( va( "%d", j / 3 ), pos, 0.01f, colorCyan, backEnd.viewDef->renderView.viewaxis, 1 );
1211  }
1212  }
1213  }
1214 
1215  qglEnable( GL_STENCIL_TEST );
1216 }
1217 
1218 
1219 /*
1220 =====================
1221 RB_ShowNormals
1222 
1223 Debugging tool
1224 =====================
1225 */
1226 static void RB_AltShowNormals( drawSurf_t **drawSurfs, int numDrawSurfs ) {
1227  int i, j, k;
1228  drawSurf_t *drawSurf;
1229  idVec3 end;
1230  const srfTriangles_t *tri;
1231 
1232  if ( r_showNormals.GetFloat() == 0.0f ) {
1233  return;
1234  }
1235 
1236  GL_State( GLS_DEFAULT );
1237  qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
1238 
1240  qglDisable( GL_STENCIL_TEST );
1241  qglDisable( GL_DEPTH_TEST );
1242 
1243  for ( i = 0 ; i < numDrawSurfs ; i++ ) {
1244  drawSurf = drawSurfs[i];
1245 
1246  RB_SimpleSurfaceSetup( drawSurf );
1247 
1248  tri = drawSurf->geo;
1249  qglBegin( GL_LINES );
1250  for ( j = 0 ; j < tri->numIndexes ; j += 3 ) {
1251  const idDrawVert *v[3];
1252  idVec3 mid;
1253 
1254  v[0] = &tri->verts[tri->indexes[j+0]];
1255  v[1] = &tri->verts[tri->indexes[j+1]];
1256  v[2] = &tri->verts[tri->indexes[j+2]];
1257 
1258  // make the midpoint slightly above the triangle
1259  mid = ( v[0]->xyz + v[1]->xyz + v[2]->xyz ) * ( 1.0f / 3.0f );
1260  mid += 0.1f * tri->facePlanes[ j / 3 ].Normal();
1261 
1262  for ( k = 0 ; k < 3 ; k++ ) {
1263  idVec3 pos;
1264 
1265  pos = ( mid + v[k]->xyz * 3.0f ) * 0.25f;
1266 
1267  qglColor3f( 0, 0, 1 );
1268  qglVertex3fv( pos.ToFloatPtr() );
1269  VectorMA( pos, r_showNormals.GetFloat(), v[k]->normal, end );
1270  qglVertex3fv( end.ToFloatPtr() );
1271 
1272  qglColor3f( 1, 0, 0 );
1273  qglVertex3fv( pos.ToFloatPtr() );
1274  VectorMA( pos, r_showNormals.GetFloat(), v[k]->tangents[0], end );
1275  qglVertex3fv( end.ToFloatPtr() );
1276 
1277  qglColor3f( 0, 1, 0 );
1278  qglVertex3fv( pos.ToFloatPtr() );
1279  VectorMA( pos, r_showNormals.GetFloat(), v[k]->tangents[1], end );
1280  qglVertex3fv( end.ToFloatPtr() );
1281 
1282  qglColor3f( 1, 1, 1 );
1283  qglVertex3fv( pos.ToFloatPtr() );
1284  qglVertex3fv( v[k]->xyz.ToFloatPtr() );
1285  }
1286  }
1287  qglEnd();
1288  }
1289 
1290  qglEnable( GL_DEPTH_TEST );
1291  qglEnable( GL_STENCIL_TEST );
1292 }
1293 
1294 
1295 
1296 /*
1297 =====================
1298 RB_ShowTextureVectors
1299 
1300 Draw texture vectors in the center of each triangle
1301 =====================
1302 */
1303 static void RB_ShowTextureVectors( drawSurf_t **drawSurfs, int numDrawSurfs ) {
1304  int i, j;
1305  drawSurf_t *drawSurf;
1306  const srfTriangles_t *tri;
1307 
1308  if ( r_showTextureVectors.GetFloat() == 0.0f ) {
1309  return;
1310  }
1311 
1313  qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
1314 
1316 
1317  for ( i = 0 ; i < numDrawSurfs ; i++ ) {
1318  drawSurf = drawSurfs[i];
1319 
1320  tri = drawSurf->geo;
1321 
1322  if ( !tri->verts ) {
1323  continue;
1324  }
1325  if ( !tri->facePlanes ) {
1326  continue;
1327  }
1328  RB_SimpleSurfaceSetup( drawSurf );
1329 
1330  // draw non-shared edges in yellow
1331  qglBegin( GL_LINES );
1332 
1333  for ( j = 0 ; j < tri->numIndexes ; j+= 3 ) {
1334  const idDrawVert *a, *b, *c;
1335  float area, inva;
1336  idVec3 temp;
1337  float d0[5], d1[5];
1338  idVec3 mid;
1339  idVec3 tangents[2];
1340 
1341  a = &tri->verts[tri->indexes[j+0]];
1342  b = &tri->verts[tri->indexes[j+1]];
1343  c = &tri->verts[tri->indexes[j+2]];
1344 
1345  // make the midpoint slightly above the triangle
1346  mid = ( a->xyz + b->xyz + c->xyz ) * ( 1.0f / 3.0f );
1347  mid += 0.1f * tri->facePlanes[ j / 3 ].Normal();
1348 
1349  // calculate the texture vectors
1350  VectorSubtract( b->xyz, a->xyz, d0 );
1351  d0[3] = b->st[0] - a->st[0];
1352  d0[4] = b->st[1] - a->st[1];
1353  VectorSubtract( c->xyz, a->xyz, d1 );
1354  d1[3] = c->st[0] - a->st[0];
1355  d1[4] = c->st[1] - a->st[1];
1356 
1357  area = d0[3] * d1[4] - d0[4] * d1[3];
1358  if ( area == 0 ) {
1359  continue;
1360  }
1361  inva = 1.0 / area;
1362 
1363  temp[0] = (d0[0] * d1[4] - d0[4] * d1[0]) * inva;
1364  temp[1] = (d0[1] * d1[4] - d0[4] * d1[1]) * inva;
1365  temp[2] = (d0[2] * d1[4] - d0[4] * d1[2]) * inva;
1366  temp.Normalize();
1367  tangents[0] = temp;
1368 
1369  temp[0] = (d0[3] * d1[0] - d0[0] * d1[3]) * inva;
1370  temp[1] = (d0[3] * d1[1] - d0[1] * d1[3]) * inva;
1371  temp[2] = (d0[3] * d1[2] - d0[2] * d1[3]) * inva;
1372  temp.Normalize();
1373  tangents[1] = temp;
1374 
1375  // draw the tangents
1376  tangents[0] = mid + tangents[0] * r_showTextureVectors.GetFloat();
1377  tangents[1] = mid + tangents[1] * r_showTextureVectors.GetFloat();
1378 
1379  qglColor3f( 1, 0, 0 );
1380  qglVertex3fv( mid.ToFloatPtr() );
1381  qglVertex3fv( tangents[0].ToFloatPtr() );
1382 
1383  qglColor3f( 0, 1, 0 );
1384  qglVertex3fv( mid.ToFloatPtr() );
1385  qglVertex3fv( tangents[1].ToFloatPtr() );
1386  }
1387 
1388  qglEnd();
1389  }
1390 }
1391 
1392 /*
1393 =====================
1394 RB_ShowDominantTris
1395 
1396 Draw lines from each vertex to the dominant triangle center
1397 =====================
1398 */
1399 static void RB_ShowDominantTris( drawSurf_t **drawSurfs, int numDrawSurfs ) {
1400  int i, j;
1401  drawSurf_t *drawSurf;
1402  const srfTriangles_t *tri;
1403 
1404  if ( !r_showDominantTri.GetBool() ) {
1405  return;
1406  }
1407 
1409  qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
1410 
1411  qglPolygonOffset( -1, -2 );
1412  qglEnable( GL_POLYGON_OFFSET_LINE );
1413 
1415 
1416  for ( i = 0 ; i < numDrawSurfs ; i++ ) {
1417  drawSurf = drawSurfs[i];
1418 
1419  tri = drawSurf->geo;
1420 
1421  if ( !tri->verts ) {
1422  continue;
1423  }
1424  if ( !tri->dominantTris ) {
1425  continue;
1426  }
1427  RB_SimpleSurfaceSetup( drawSurf );
1428 
1429  qglColor3f( 1, 1, 0 );
1430  qglBegin( GL_LINES );
1431 
1432  for ( j = 0 ; j < tri->numVerts ; j++ ) {
1433  const idDrawVert *a, *b, *c;
1434  idVec3 mid;
1435 
1436  // find the midpoint of the dominant tri
1437 
1438  a = &tri->verts[j];
1439  b = &tri->verts[tri->dominantTris[j].v2];
1440  c = &tri->verts[tri->dominantTris[j].v3];
1441 
1442  mid = ( a->xyz + b->xyz + c->xyz ) * ( 1.0f / 3.0f );
1443 
1444  qglVertex3fv( mid.ToFloatPtr() );
1445  qglVertex3fv( a->xyz.ToFloatPtr() );
1446  }
1447 
1448  qglEnd();
1449  }
1450  qglDisable( GL_POLYGON_OFFSET_LINE );
1451 }
1452 
1453 /*
1454 =====================
1455 RB_ShowEdges
1456 
1457 Debugging tool
1458 =====================
1459 */
1460 static void RB_ShowEdges( drawSurf_t **drawSurfs, int numDrawSurfs ) {
1461  int i, j, k, m, n, o;
1462  drawSurf_t *drawSurf;
1463  const srfTriangles_t *tri;
1464  const silEdge_t *edge;
1465  int danglePlane;
1466 
1467  if ( !r_showEdges.GetBool() ) {
1468  return;
1469  }
1470 
1471  GL_State( GLS_DEFAULT );
1472  qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
1473 
1475  qglDisable( GL_DEPTH_TEST );
1476 
1477  for ( i = 0 ; i < numDrawSurfs ; i++ ) {
1478  drawSurf = drawSurfs[i];
1479 
1480  tri = drawSurf->geo;
1481 
1482  idDrawVert *ac = (idDrawVert *)tri->verts;
1483  if ( !ac ) {
1484  continue;
1485  }
1486 
1487  RB_SimpleSurfaceSetup( drawSurf );
1488 
1489  // draw non-shared edges in yellow
1490  qglColor3f( 1, 1, 0 );
1491  qglBegin( GL_LINES );
1492 
1493  for ( j = 0 ; j < tri->numIndexes ; j+= 3 ) {
1494  for ( k = 0 ; k < 3 ; k++ ) {
1495  int l, i1, i2;
1496  l = ( k == 2 ) ? 0 : k + 1;
1497  i1 = tri->indexes[j+k];
1498  i2 = tri->indexes[j+l];
1499 
1500  // if these are used backwards, the edge is shared
1501  for ( m = 0 ; m < tri->numIndexes ; m += 3 ) {
1502  for ( n = 0 ; n < 3 ; n++ ) {
1503  o = ( n == 2 ) ? 0 : n + 1;
1504  if ( tri->indexes[m+n] == i2 && tri->indexes[m+o] == i1 ) {
1505  break;
1506  }
1507  }
1508  if ( n != 3 ) {
1509  break;
1510  }
1511  }
1512 
1513  // if we didn't find a backwards listing, draw it in yellow
1514  if ( m == tri->numIndexes ) {
1515  qglVertex3fv( ac[ i1 ].xyz.ToFloatPtr() );
1516  qglVertex3fv( ac[ i2 ].xyz.ToFloatPtr() );
1517  }
1518 
1519  }
1520  }
1521 
1522  qglEnd();
1523 
1524  // draw dangling sil edges in red
1525  if ( !tri->silEdges ) {
1526  continue;
1527  }
1528 
1529  // the plane number after all real planes
1530  // is the dangling edge
1531  danglePlane = tri->numIndexes / 3;
1532 
1533  qglColor3f( 1, 0, 0 );
1534 
1535  qglBegin( GL_LINES );
1536  for ( j = 0 ; j < tri->numSilEdges ; j++ ) {
1537  edge = tri->silEdges + j;
1538 
1539  if ( edge->p1 != danglePlane && edge->p2 != danglePlane ) {
1540  continue;
1541  }
1542 
1543  qglVertex3fv( ac[ edge->v1 ].xyz.ToFloatPtr() );
1544  qglVertex3fv( ac[ edge->v2 ].xyz.ToFloatPtr() );
1545  }
1546  qglEnd();
1547  }
1548 
1549  qglEnable( GL_DEPTH_TEST );
1550 }
1551 
1552 /*
1553 ==============
1554 RB_ShowLights
1555 
1556 Visualize all light volumes used in the current scene
1557 r_showLights 1 : just print volumes numbers, highlighting ones covering the view
1558 r_showLights 2 : also draw planes of each volume
1559 r_showLights 3 : also draw edges of each volume
1560 ==============
1561 */
1562 void RB_ShowLights( void ) {
1563  const idRenderLightLocal *light;
1564  int count;
1565  srfTriangles_t *tri;
1566  viewLight_t *vLight;
1567 
1568  if ( !r_showLights.GetInteger() ) {
1569  return;
1570  }
1571 
1572  // all volumes are expressed in world coordinates
1574 
1575  qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
1577  qglDisable( GL_STENCIL_TEST );
1578 
1579 
1580  GL_Cull( CT_TWO_SIDED );
1581  qglDisable( GL_DEPTH_TEST );
1582 
1583 
1584  common->Printf( "volumes: " ); // FIXME: not in back end!
1585 
1586  count = 0;
1587  for ( vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) {
1588  light = vLight->lightDef;
1589  count++;
1590 
1591  tri = light->frustumTris;
1592 
1593  // depth buffered planes
1594  if ( r_showLights.GetInteger() >= 2 ) {
1596  qglColor4f( 0, 0, 1, 0.25 );
1597  qglEnable( GL_DEPTH_TEST );
1598  RB_RenderTriangleSurface( tri );
1599  }
1600 
1601  // non-hidden lines
1602  if ( r_showLights.GetInteger() >= 3 ) {
1604  qglDisable( GL_DEPTH_TEST );
1605  qglColor3f( 1, 1, 1 );
1606  RB_RenderTriangleSurface( tri );
1607  }
1608 
1609  int index;
1610 
1611  index = backEnd.viewDef->renderWorld->lightDefs.FindIndex( vLight->lightDef );
1612  if ( vLight->viewInsideLight ) {
1613  // view is in this volume
1614  common->Printf( "[%i] ", index );
1615  } else {
1616  common->Printf( "%i ", index );
1617  }
1618  }
1619 
1620  qglEnable( GL_DEPTH_TEST );
1621  qglDisable( GL_POLYGON_OFFSET_LINE );
1622 
1623  qglDepthRange( 0, 1 );
1624  GL_State( GLS_DEFAULT );
1626 
1627  common->Printf( " = %i total\n", count );
1628 }
1629 
1630 /*
1631 =====================
1632 RB_ShowPortals
1633 
1634 Debugging tool, won't work correctly with SMP or when mirrors are present
1635 =====================
1636 */
1637 void RB_ShowPortals( void ) {
1638  if ( !r_showPortals.GetBool() ) {
1639  return;
1640  }
1641 
1642  // all portals are expressed in world coordinates
1644 
1646  qglDisable( GL_DEPTH_TEST );
1647 
1648  GL_State( GLS_DEFAULT );
1649 
1650  ((idRenderWorldLocal *)backEnd.viewDef->renderWorld)->ShowPortals();
1651 
1652  qglEnable( GL_DEPTH_TEST );
1653 }
1654 
1655 /*
1656 ================
1657 RB_ClearDebugText
1658 ================
1659 */
1660 void RB_ClearDebugText( int time ) {
1661  int i;
1662  int num;
1663  debugText_t *text;
1664 
1665  rb_debugTextTime = time;
1666 
1667  if ( !time ) {
1668  // free up our strings
1669  text = rb_debugText;
1670  for ( i = 0 ; i < MAX_DEBUG_TEXT; i++, text++ ) {
1671  text->text.Clear();
1672  }
1673  rb_numDebugText = 0;
1674  return;
1675  }
1676 
1677  // copy any text that still needs to be drawn
1678  num = 0;
1679  text = rb_debugText;
1680  for ( i = 0 ; i < rb_numDebugText; i++, text++ ) {
1681  if ( text->lifeTime > time ) {
1682  if ( num != i ) {
1683  rb_debugText[ num ] = *text;
1684  }
1685  num++;
1686  }
1687  }
1688  rb_numDebugText = num;
1689 }
1690 
1691 /*
1692 ================
1693 RB_AddDebugText
1694 ================
1695 */
1696 void RB_AddDebugText( const char *text, const idVec3 &origin, float scale, const idVec4 &color, const idMat3 &viewAxis, const int align, const int lifetime, const bool depthTest ) {
1697  debugText_t *debugText;
1698 
1699  if ( rb_numDebugText < MAX_DEBUG_TEXT ) {
1700  debugText = &rb_debugText[ rb_numDebugText++ ];
1701  debugText->text = text;
1702  debugText->origin = origin;
1703  debugText->scale = scale;
1704  debugText->color = color;
1705  debugText->viewAxis = viewAxis;
1706  debugText->align = align;
1707  debugText->lifeTime = rb_debugTextTime + lifetime;
1708  debugText->depthTest = depthTest;
1709  }
1710 }
1711 
1712 /*
1713 ================
1714 RB_DrawTextLength
1715 
1716  returns the length of the given text
1717 ================
1718 */
1719 float RB_DrawTextLength( const char *text, float scale, int len ) {
1720  int i, num, index, charIndex;
1721  float spacing, textLen = 0.0f;
1722 
1723  if ( text && *text ) {
1724  if ( !len ) {
1725  len = strlen(text);
1726  }
1727  for ( i = 0; i < len; i++ ) {
1728  charIndex = text[i] - 32;
1729  if ( charIndex < 0 || charIndex > NUM_SIMPLEX_CHARS ) {
1730  continue;
1731  }
1732  num = simplex[charIndex][0] * 2;
1733  spacing = simplex[charIndex][1];
1734  index = 2;
1735 
1736  while( index - 2 < num ) {
1737  if ( simplex[charIndex][index] < 0) {
1738  index++;
1739  continue;
1740  }
1741  index += 2;
1742  if ( simplex[charIndex][index] < 0) {
1743  index++;
1744  continue;
1745  }
1746  }
1747  textLen += spacing * scale;
1748  }
1749  }
1750  return textLen;
1751 }
1752 
1753 /*
1754 ================
1755 RB_DrawText
1756 
1757  oriented on the viewaxis
1758  align can be 0-left, 1-center (default), 2-right
1759 ================
1760 */
1761 static void RB_DrawText( const char *text, const idVec3 &origin, float scale, const idVec4 &color, const idMat3 &viewAxis, const int align ) {
1762  int i, j, len, num, index, charIndex, line;
1763  float textLen, spacing;
1764  idVec3 org, p1, p2;
1765 
1766  if ( text && *text ) {
1767  qglBegin( GL_LINES );
1768  qglColor3fv( color.ToFloatPtr() );
1769 
1770  if ( text[0] == '\n' ) {
1771  line = 1;
1772  } else {
1773  line = 0;
1774  }
1775 
1776  len = strlen( text );
1777  for ( i = 0; i < len; i++ ) {
1778 
1779  if ( i == 0 || text[i] == '\n' ) {
1780  org = origin - viewAxis[2] * ( line * 36.0f * scale );
1781  if ( align != 0 ) {
1782  for ( j = 1; i+j <= len; j++ ) {
1783  if ( i+j == len || text[i+j] == '\n' ) {
1784  textLen = RB_DrawTextLength( text+i, scale, j );
1785  break;
1786  }
1787  }
1788  if ( align == 2 ) {
1789  // right
1790  org += viewAxis[1] * textLen;
1791  } else {
1792  // center
1793  org += viewAxis[1] * ( textLen * 0.5f );
1794  }
1795  }
1796  line++;
1797  }
1798 
1799  charIndex = text[i] - 32;
1800  if ( charIndex < 0 || charIndex > NUM_SIMPLEX_CHARS ) {
1801  continue;
1802  }
1803  num = simplex[charIndex][0] * 2;
1804  spacing = simplex[charIndex][1];
1805  index = 2;
1806 
1807  while( index - 2 < num ) {
1808  if ( simplex[charIndex][index] < 0) {
1809  index++;
1810  continue;
1811  }
1812  p1 = org + scale * simplex[charIndex][index] * -viewAxis[1] + scale * simplex[charIndex][index+1] * viewAxis[2];
1813  index += 2;
1814  if ( simplex[charIndex][index] < 0) {
1815  index++;
1816  continue;
1817  }
1818  p2 = org + scale * simplex[charIndex][index] * -viewAxis[1] + scale * simplex[charIndex][index+1] * viewAxis[2];
1819 
1820  qglVertex3fv( p1.ToFloatPtr() );
1821  qglVertex3fv( p2.ToFloatPtr() );
1822  }
1823  org -= viewAxis[1] * ( spacing * scale );
1824  }
1825 
1826  qglEnd();
1827  }
1828 }
1829 
1830 /*
1831 ================
1832 RB_ShowDebugText
1833 ================
1834 */
1835 void RB_ShowDebugText( void ) {
1836  int i;
1837  int width;
1838  debugText_t *text;
1839 
1840  if ( !rb_numDebugText ) {
1841  return;
1842  }
1843 
1844  // all lines are expressed in world coordinates
1846 
1848 
1849  width = r_debugLineWidth.GetInteger();
1850  if ( width < 1 ) {
1851  width = 1;
1852  } else if ( width > 10 ) {
1853  width = 10;
1854  }
1855 
1856  // draw lines
1858  qglLineWidth( width );
1859 
1860  if ( !r_debugLineDepthTest.GetBool() ) {
1861  qglDisable( GL_DEPTH_TEST );
1862  }
1863 
1864  text = rb_debugText;
1865  for ( i = 0 ; i < rb_numDebugText; i++, text++ ) {
1866  if ( !text->depthTest ) {
1867  RB_DrawText( text->text, text->origin, text->scale, text->color, text->viewAxis, text->align );
1868  }
1869  }
1870 
1871  if ( !r_debugLineDepthTest.GetBool() ) {
1872  qglEnable( GL_DEPTH_TEST );
1873  }
1874 
1875  text = rb_debugText;
1876  for ( i = 0 ; i < rb_numDebugText; i++, text++ ) {
1877  if ( text->depthTest ) {
1878  RB_DrawText( text->text, text->origin, text->scale, text->color, text->viewAxis, text->align );
1879  }
1880  }
1881 
1882  qglLineWidth( 1 );
1883  GL_State( GLS_DEFAULT );
1884 }
1885 
1886 /*
1887 ================
1888 RB_ClearDebugLines
1889 ================
1890 */
1891 void RB_ClearDebugLines( int time ) {
1892  int i;
1893  int num;
1894  debugLine_t *line;
1895 
1896  rb_debugLineTime = time;
1897 
1898  if ( !time ) {
1899  rb_numDebugLines = 0;
1900  return;
1901  }
1902 
1903  // copy any lines that still need to be drawn
1904  num = 0;
1905  line = rb_debugLines;
1906  for ( i = 0 ; i < rb_numDebugLines; i++, line++ ) {
1907  if ( line->lifeTime > time ) {
1908  if ( num != i ) {
1909  rb_debugLines[ num ] = *line;
1910  }
1911  num++;
1912  }
1913  }
1914  rb_numDebugLines = num;
1915 }
1916 
1917 /*
1918 ================
1919 RB_AddDebugLine
1920 ================
1921 */
1922 void RB_AddDebugLine( const idVec4 &color, const idVec3 &start, const idVec3 &end, const int lifeTime, const bool depthTest ) {
1923  debugLine_t *line;
1924 
1926  line = &rb_debugLines[ rb_numDebugLines++ ];
1927  line->rgb = color;
1928  line->start = start;
1929  line->end = end;
1930  line->depthTest = depthTest;
1931  line->lifeTime = rb_debugLineTime + lifeTime;
1932  }
1933 }
1934 
1935 /*
1936 ================
1937 RB_ShowDebugLines
1938 ================
1939 */
1940 void RB_ShowDebugLines( void ) {
1941  int i;
1942  int width;
1943  debugLine_t *line;
1944 
1945  if ( !rb_numDebugLines ) {
1946  return;
1947  }
1948 
1949  // all lines are expressed in world coordinates
1951 
1953 
1954  width = r_debugLineWidth.GetInteger();
1955  if ( width < 1 ) {
1956  width = 1;
1957  } else if ( width > 10 ) {
1958  width = 10;
1959  }
1960 
1961  // draw lines
1962  GL_State( GLS_POLYMODE_LINE );//| GLS_DEPTHMASK ); //| GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
1963  qglLineWidth( width );
1964 
1965  if ( !r_debugLineDepthTest.GetBool() ) {
1966  qglDisable( GL_DEPTH_TEST );
1967  }
1968 
1969  qglBegin( GL_LINES );
1970 
1971  line = rb_debugLines;
1972  for ( i = 0 ; i < rb_numDebugLines; i++, line++ ) {
1973  if ( !line->depthTest ) {
1974  qglColor3fv( line->rgb.ToFloatPtr() );
1975  qglVertex3fv( line->start.ToFloatPtr() );
1976  qglVertex3fv( line->end.ToFloatPtr() );
1977  }
1978  }
1979  qglEnd();
1980 
1981  if ( !r_debugLineDepthTest.GetBool() ) {
1982  qglEnable( GL_DEPTH_TEST );
1983  }
1984 
1985  qglBegin( GL_LINES );
1986 
1987  line = rb_debugLines;
1988  for ( i = 0 ; i < rb_numDebugLines; i++, line++ ) {
1989  if ( line->depthTest ) {
1990  qglColor4fv( line->rgb.ToFloatPtr() );
1991  qglVertex3fv( line->start.ToFloatPtr() );
1992  qglVertex3fv( line->end.ToFloatPtr() );
1993  }
1994  }
1995 
1996  qglEnd();
1997 
1998  qglLineWidth( 1 );
1999  GL_State( GLS_DEFAULT );
2000 }
2001 
2002 /*
2003 ================
2004 RB_ClearDebugPolygons
2005 ================
2006 */
2007 void RB_ClearDebugPolygons( int time ) {
2008  int i;
2009  int num;
2011 
2012  rb_debugPolygonTime = time;
2013 
2014  if ( !time ) {
2015  rb_numDebugPolygons = 0;
2016  return;
2017  }
2018 
2019  // copy any polygons that still need to be drawn
2020  num = 0;
2021 
2022  poly = rb_debugPolygons;
2023  for ( i = 0 ; i < rb_numDebugPolygons; i++, poly++ ) {
2024  if ( poly->lifeTime > time ) {
2025  if ( num != i ) {
2026  rb_debugPolygons[ num ] = *poly;
2027  }
2028  num++;
2029  }
2030  }
2031  rb_numDebugPolygons = num;
2032 }
2033 
2034 /*
2035 ================
2036 RB_AddDebugPolygon
2037 ================
2038 */
2039 void RB_AddDebugPolygon( const idVec4 &color, const idWinding &winding, const int lifeTime, const bool depthTest ) {
2041 
2043  poly = &rb_debugPolygons[ rb_numDebugPolygons++ ];
2044  poly->rgb = color;
2045  poly->winding = winding;
2046  poly->depthTest = depthTest;
2047  poly->lifeTime = rb_debugPolygonTime + lifeTime;
2048  }
2049 }
2050 
2051 /*
2052 ================
2053 RB_ShowDebugPolygons
2054 ================
2055 */
2056 void RB_ShowDebugPolygons( void ) {
2057  int i, j;
2059 
2060  if ( !rb_numDebugPolygons ) {
2061  return;
2062  }
2063 
2064  // all lines are expressed in world coordinates
2066 
2068 
2069  qglDisable( GL_TEXTURE_2D );
2070  qglDisable( GL_STENCIL_TEST );
2071 
2072  qglEnable( GL_DEPTH_TEST );
2073 
2074  if ( r_debugPolygonFilled.GetBool() ) {
2076  qglPolygonOffset( -1, -2 );
2077  qglEnable( GL_POLYGON_OFFSET_FILL );
2078  } else {
2080  qglPolygonOffset( -1, -2 );
2081  qglEnable( GL_POLYGON_OFFSET_LINE );
2082  }
2083 
2084  poly = rb_debugPolygons;
2085  for ( i = 0 ; i < rb_numDebugPolygons; i++, poly++ ) {
2086 // if ( !poly->depthTest ) {
2087 
2088  qglColor4fv( poly->rgb.ToFloatPtr() );
2089 
2090  qglBegin( GL_POLYGON );
2091 
2092  for ( j = 0; j < poly->winding.GetNumPoints(); j++) {
2093  qglVertex3fv( poly->winding[j].ToFloatPtr() );
2094  }
2095 
2096  qglEnd();
2097 // }
2098  }
2099 
2100  GL_State( GLS_DEFAULT );
2101 
2102  if ( r_debugPolygonFilled.GetBool() ) {
2103  qglDisable( GL_POLYGON_OFFSET_FILL );
2104  } else {
2105  qglDisable( GL_POLYGON_OFFSET_LINE );
2106  }
2107 
2108  qglDepthRange( 0, 1 );
2109  GL_State( GLS_DEFAULT );
2110 }
2111 
2112 /*
2113 ================
2114 RB_TestGamma
2115 ================
2116 */
2117 #define G_WIDTH 512
2118 #define G_HEIGHT 512
2119 #define BAR_HEIGHT 64
2120 
2121 void RB_TestGamma( void ) {
2122  byte image[G_HEIGHT][G_WIDTH][4];
2123  int i, j;
2124  int c, comp;
2125  int v, dither;
2126  int mask, y;
2127 
2128  if ( r_testGamma.GetInteger() <= 0 ) {
2129  return;
2130  }
2131 
2132  v = r_testGamma.GetInteger();
2133  if ( v <= 1 || v >= 196 ) {
2134  v = 128;
2135  }
2136 
2137  memset( image, 0, sizeof( image ) );
2138 
2139  for ( mask = 0 ; mask < 8 ; mask++ ) {
2140  y = mask * BAR_HEIGHT;
2141  for ( c = 0 ; c < 4 ; c++ ) {
2142  v = c * 64 + 32;
2143  // solid color
2144  for ( i = 0 ; i < BAR_HEIGHT/2 ; i++ ) {
2145  for ( j = 0 ; j < G_WIDTH/4 ; j++ ) {
2146  for ( comp = 0 ; comp < 3 ; comp++ ) {
2147  if ( mask & ( 1 << comp ) ) {
2148  image[y+i][c*G_WIDTH/4+j][comp] = v;
2149  }
2150  }
2151  }
2152  // dithered color
2153  for ( j = 0 ; j < G_WIDTH/4 ; j++ ) {
2154  if ( ( i ^ j ) & 1 ) {
2155  dither = c * 64;
2156  } else {
2157  dither = c * 64 + 63;
2158  }
2159  for ( comp = 0 ; comp < 3 ; comp++ ) {
2160  if ( mask & ( 1 << comp ) ) {
2161  image[y+BAR_HEIGHT/2+i][c*G_WIDTH/4+j][comp] = dither;
2162  }
2163  }
2164  }
2165  }
2166  }
2167  }
2168 
2169  // draw geometrically increasing steps in the bottom row
2170  y = 0 * BAR_HEIGHT;
2171  float scale = 1;
2172  for ( c = 0 ; c < 4 ; c++ ) {
2173  v = (int)(64 * scale);
2174  if ( v < 0 ) {
2175  v = 0;
2176  } else if ( v > 255 ) {
2177  v = 255;
2178  }
2179  scale = scale * 1.5;
2180  for ( i = 0 ; i < BAR_HEIGHT ; i++ ) {
2181  for ( j = 0 ; j < G_WIDTH/4 ; j++ ) {
2182  image[y+i][c*G_WIDTH/4+j][0] = v;
2183  image[y+i][c*G_WIDTH/4+j][1] = v;
2184  image[y+i][c*G_WIDTH/4+j][2] = v;
2185  }
2186  }
2187  }
2188 
2189 
2190  qglLoadIdentity();
2191 
2192  qglMatrixMode( GL_PROJECTION );
2194  qglColor3f( 1, 1, 1 );
2195  qglPushMatrix();
2196  qglLoadIdentity();
2197  qglDisable( GL_TEXTURE_2D );
2198  qglOrtho( 0, 1, 0, 1, -1, 1 );
2199  qglRasterPos2f( 0.01f, 0.01f );
2200  qglDrawPixels( G_WIDTH, G_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, image );
2201  qglPopMatrix();
2202  qglEnable( GL_TEXTURE_2D );
2203  qglMatrixMode( GL_MODELVIEW );
2204 }
2205 
2206 
2207 /*
2208 ==================
2209 RB_TestGammaBias
2210 ==================
2211 */
2212 static void RB_TestGammaBias( void ) {
2213  byte image[G_HEIGHT][G_WIDTH][4];
2214 
2215  if ( r_testGammaBias.GetInteger() <= 0 ) {
2216  return;
2217  }
2218 
2219  int y = 0;
2220  for ( int bias = -40 ; bias < 40 ; bias+=10, y += BAR_HEIGHT ) {
2221  float scale = 1;
2222  for ( int c = 0 ; c < 4 ; c++ ) {
2223  int v = (int)(64 * scale + bias);
2224  scale = scale * 1.5;
2225  if ( v < 0 ) {
2226  v = 0;
2227  } else if ( v > 255 ) {
2228  v = 255;
2229  }
2230  for ( int i = 0 ; i < BAR_HEIGHT ; i++ ) {
2231  for ( int j = 0 ; j < G_WIDTH/4 ; j++ ) {
2232  image[y+i][c*G_WIDTH/4+j][0] = v;
2233  image[y+i][c*G_WIDTH/4+j][1] = v;
2234  image[y+i][c*G_WIDTH/4+j][2] = v;
2235  }
2236  }
2237  }
2238  }
2239 
2240 
2241  qglLoadIdentity();
2242  qglMatrixMode( GL_PROJECTION );
2244  qglColor3f( 1, 1, 1 );
2245  qglPushMatrix();
2246  qglLoadIdentity();
2247  qglDisable( GL_TEXTURE_2D );
2248  qglOrtho( 0, 1, 0, 1, -1, 1 );
2249  qglRasterPos2f( 0.01f, 0.01f );
2250  qglDrawPixels( G_WIDTH, G_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, image );
2251  qglPopMatrix();
2252  qglEnable( GL_TEXTURE_2D );
2253  qglMatrixMode( GL_MODELVIEW );
2254 }
2255 
2256 /*
2257 ================
2258 RB_TestImage
2259 
2260 Display a single image over most of the screen
2261 ================
2262 */
2263 void RB_TestImage( void ) {
2264  idImage *image;
2265  int max;
2266  float w, h;
2267 
2268  image = tr.testImage;
2269  if ( !image ) {
2270  return;
2271  }
2272 
2273  if ( tr.testVideo ) {
2274  cinData_t cin;
2275 
2276  cin = tr.testVideo->ImageForTime( (int)(1000 * ( backEnd.viewDef->floatTime - tr.testVideoStartTime ) ) );
2277  if ( cin.image ) {
2278  image->UploadScratch( cin.image, cin.imageWidth, cin.imageHeight );
2279  } else {
2280  tr.testImage = NULL;
2281  return;
2282  }
2283  w = 0.25;
2284  h = 0.25;
2285  } else {
2286  max = image->uploadWidth > image->uploadHeight ? image->uploadWidth : image->uploadHeight;
2287 
2288  w = 0.25 * image->uploadWidth / max;
2289  h = 0.25 * image->uploadHeight / max;
2290 
2292  }
2293 
2294  qglLoadIdentity();
2295 
2296  qglMatrixMode( GL_PROJECTION );
2298  qglColor3f( 1, 1, 1 );
2299  qglPushMatrix();
2300  qglLoadIdentity();
2301  qglOrtho( 0, 1, 0, 1, -1, 1 );
2302 
2303  tr.testImage->Bind();
2304  qglBegin( GL_QUADS );
2305 
2306  qglTexCoord2f( 0, 1 );
2307  qglVertex2f( 0.5 - w, 0 );
2308 
2309  qglTexCoord2f( 0, 0 );
2310  qglVertex2f( 0.5 - w, h*2 );
2311 
2312  qglTexCoord2f( 1, 0 );
2313  qglVertex2f( 0.5 + w, h*2 );
2314 
2315  qglTexCoord2f( 1, 1 );
2316  qglVertex2f( 0.5 + w, 0 );
2317 
2318  qglEnd();
2319 
2320  qglPopMatrix();
2321  qglMatrixMode( GL_MODELVIEW );
2322 }
2323 
2324 /*
2325 =================
2326 RB_RenderDebugTools
2327 =================
2328 */
2329 void RB_RenderDebugTools( drawSurf_t **drawSurfs, int numDrawSurfs ) {
2330  // don't do anything if this was a 2D rendering
2331  if ( !backEnd.viewDef->viewEntitys ) {
2332  return;
2333  }
2334 
2335  RB_LogComment( "---------- RB_RenderDebugTools ----------\n" );
2336 
2337  GL_State( GLS_DEFAULT );
2343 
2344 
2346  RB_ShowShadowCount();
2347  RB_ShowTexturePolarity( drawSurfs, numDrawSurfs );
2348  RB_ShowTangentSpace( drawSurfs, numDrawSurfs );
2349  RB_ShowVertexColor( drawSurfs, numDrawSurfs );
2350  RB_ShowTris( drawSurfs, numDrawSurfs );
2351  RB_ShowUnsmoothedTangents( drawSurfs, numDrawSurfs );
2352  RB_ShowSurfaceInfo( drawSurfs, numDrawSurfs );
2353  RB_ShowEdges( drawSurfs, numDrawSurfs );
2354  RB_ShowNormals( drawSurfs, numDrawSurfs );
2355  RB_ShowViewEntitys( backEnd.viewDef->viewEntitys );
2356  RB_ShowLights();
2357  RB_ShowTextureVectors( drawSurfs, numDrawSurfs );
2358  RB_ShowDominantTris( drawSurfs, numDrawSurfs );
2359  if ( r_testGamma.GetInteger() > 0 ) { // test here so stack check isn't so damn slow on debug builds
2360  RB_TestGamma();
2361  }
2362  if ( r_testGammaBias.GetInteger() > 0 ) {
2363  RB_TestGammaBias();
2364  }
2365  RB_TestImage();
2366  RB_ShowPortals();
2369  RB_ShowIntensity();
2371  RB_ShowDebugText();
2373  RB_ShowTrace( drawSurfs, numDrawSurfs );
2374 }
2375 
2376 /*
2377 =================
2378 RB_ShutdownDebugTools
2379 =================
2380 */
2382  for ( int i = 0; i < MAX_DEBUG_POLYGONS; i++ ) {
2383  rb_debugPolygons[i].winding.Clear();
2384  }
2385 }
void RB_ShowLights(void)
const int GLS_DSTBLEND_ONE
Definition: tr_local.h:1017
glIndex_t p1
Definition: Model.h:64
byte color[4]
Definition: MegaTexture.cpp:54
#define qglLoadMatrixf
Definition: qgl_linked.h:188
const srfTriangles_t * geo
Definition: tr_local.h:112
viewEntity_t worldSpace
Definition: tr_local.h:373
float Normalize(void)
Definition: Vector.h:646
Definition: Image.h:146
const int GLS_DEPTHFUNC_LESS
Definition: tr_local.h:1040
struct debugText_s debugText_t
#define qglScissor
Definition: qgl_linked.h:280
virtual void Clear(void)
Definition: Winding.h:249
const idVec3 & Normal(void) const
Definition: Plane.h:239
void RB_ClearDebugText(int time)
#define qglDisable
Definition: qgl_linked.h:92
glIndex_t * silIndexes
Definition: Model.h:104
#define qglDisableClientState
Definition: qgl_linked.h:93
idVec4 colorWhite
Definition: Lib.cpp:116
int numVerts
Definition: Model.h:98
GLenum GLint GLuint mask
Definition: glext.h:5864
const int GLS_SRCBLEND_SRC_ALPHA
Definition: tr_local.h:1009
const int GLS_POLYMODE_LINE
Definition: tr_local.h:1036
debugLine_t rb_debugLines[MAX_DEBUG_LINES]
short x2
Definition: tr_local.h:55
idVec4 xyz
Definition: Model.h:80
float GetFloat(void) const
Definition: CVarSystem.h:144
drawSurf_t ** drawSurfs
Definition: tr_local.h:411
idCVar r_showPortals("r_showPortals","0", CVAR_RENDERER|CVAR_BOOL,"draw portal outlines in color based on passed / not passed")
const GLdouble * v
Definition: glext.h:2936
GLuint GLenum matrix
Definition: glext.h:5179
#define qglClearColor
Definition: qgl_linked.h:41
const float * ToFloatPtr(void) const
Definition: Vector.h:719
idRenderModel * R_EntityDefDynamicModel(idRenderEntityLocal *def)
Definition: tr_light.cpp:1104
float floatTime
Definition: tr_local.h:377
#define VectorSubtract(a, b, c)
Definition: Vector.h:1995
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:4804
idCVar r_showTris("r_showTris","0", CVAR_RENDERER|CVAR_INTEGER,"enables wireframe rendering of the world, 1 = only draw visible ones, 2 = draw all front facing, 3 = draw all", 0, 3, idCmdSystem::ArgCompletion_Integer< 0, 3 >)
#define qglArrayElement
Definition: qgl_linked.h:32
idVec3 xyz
Definition: DrawVert.h:42
GLenum GLint GLint y
Definition: glext.h:2849
idCVar r_showTextureVectors("r_showTextureVectors","0", CVAR_RENDERER|CVAR_FLOAT," if > 0 draw each triangles texture (tangent) vectors")
const idMaterial * material
Definition: RenderWorld.h:249
GLenum GLsizei n
Definition: glext.h:3705
idCVar r_showSilhouette("r_showSilhouette","0", CVAR_RENDERER|CVAR_BOOL,"highlight edges that are casting shadow planes")
case const int
Definition: Callbacks.cpp:52
idCVar r_showVertexColor("r_showVertexColor","0", CVAR_RENDERER|CVAR_BOOL,"draws all triangles with the solid vertex color")
idVec3 tangents[2]
Definition: DrawVert.h:45
#define qglBegin
Definition: qgl_linked.h:33
idScreenRect scissorRect
Definition: tr_local.h:118
const struct drawSurf_s * localShadows
Definition: tr_local.h:332
const int GLS_DEFAULT
Definition: tr_local.h:1047
const char * GetName(void) const
Definition: DeclManager.h:140
Definition: Vector.h:316
idScreenRect viewport
Definition: tr_local.h:398
case const float
Definition: Callbacks.cpp:62
#define qglDepthRange
Definition: qgl_linked.h:91
void RB_ClearDebugPolygons(int time)
GLenum GLsizei GLenum GLenum const GLvoid * image
Definition: glext.h:2855
const int GLS_DEPTHFUNC_ALWAYS
Definition: tr_local.h:1038
#define qglVertex3fv
Definition: qgl_linked.h:350
glIndex_t p2
Definition: Model.h:64
silEdge_t * silEdges
Definition: Model.h:113
const struct drawSurf_s * globalInteractions
Definition: tr_local.h:333
idRenderWorldLocal * primaryWorld
Definition: tr_local.h:774
idPlane * facePlanes
Definition: Model.h:115
virtual const char * Name() const =0
#define qglReadPixels
Definition: qgl_linked.h:266
short x1
Definition: tr_local.h:55
float testVideoStartTime
Definition: tr_local.h:782
virtual const idMaterial * FindMaterial(const char *name, bool makeDefault=true)=0
idRenderLightLocal * lightDef
Definition: tr_local.h:302
glIndex_t v3
Definition: Model.h:70
GLenum GLsizei len
Definition: glext.h:3472
const struct viewEntity_s * space
Definition: tr_local.h:113
idCVar r_showOverDraw("r_showOverDraw","0", CVAR_RENDERER|CVAR_INTEGER,"1 = geometry overdraw, 2 = light interaction overdraw, 3 = geometry and light interaction overdraw", 0, 3, idCmdSystem::ArgCompletion_Integer< 0, 3 >)
struct vertCache_s * ambientCache
Definition: Model.h:137
virtual bool Trace(modelTrace_t &trace, const idVec3 &start, const idVec3 &end, const float radius, bool skipDynamic=true, bool skipPlayer=false) const
int i
Definition: process.py:33
const idMaterial * material
Definition: tr_local.h:114
GLuint GLuint num
Definition: glext.h:5390
#define qglEnable
Definition: qgl_linked.h:101
const viewEntity_t * currentSpace
Definition: tr_local.h:644
idCVar r_showUnsmoothedTangents("r_showUnsmoothedTangents","0", CVAR_RENDERER|CVAR_BOOL,"if 1, put all nvidia register combiner programming in display lists")
#define qglPolygonOffset
Definition: qgl_linked.h:230
idCVar r_showSurfaceInfo("r_showSurfaceInfo","0", CVAR_RENDERER|CVAR_BOOL,"show surface material name under crosshair")
void RB_ShutdownDebugTools(void)
idCVar r_showShadowCount("r_showShadowCount","0", CVAR_RENDERER|CVAR_INTEGER,"colors screen based on shadow volume depth complexity, >= 2 = print overdraw count based on stencil index values, 3 = only show turboshadows, 4 = only show static shadows", 0, 4, idCmdSystem::ArgCompletion_Integer< 0, 4 >)
list l
Definition: prepare.py:17
idList< idRenderLightLocal * > lightDefs
idVec4 colorRed
Definition: Lib.cpp:117
int rb_numDebugLines
backEndState_t backEnd
Definition: tr_backend.cpp:35
#define qglPushMatrix
Definition: qgl_linked.h:239
void GL_Cull(int cullType)
Definition: tr_backend.cpp:161
void RB_ShowDebugText(void)
const int GLS_DEPTHFUNC_EQUAL
Definition: tr_local.h:1039
idBounds referenceBounds
Definition: tr_local.h:268
int numSilEdges
Definition: Model.h:112
#define BAR_HEIGHT
struct viewLight_s * next
Definition: tr_local.h:299
void RB_RenderDrawSurfListWithFunction(drawSurf_t **drawSurfs, int numDrawSurfs, void(*triFunc_)(const drawSurf_t *))
Definition: tr_render.cpp:232
void RB_PolygonClear(void)
struct viewLight_s * viewLights
Definition: tr_local.h:415
idCVar r_showLights("r_showLights","0", CVAR_RENDERER|CVAR_INTEGER,"1 = just print volumes numbers, highlighting ones covering the view, 2 = also draw planes of each volume, 3 = also draw edges of each volume", 0, 3, idCmdSystem::ArgCompletion_Integer< 0, 3 >)
idVec2 st
Definition: DrawVert.h:43
glIndex_t v2
Definition: Model.h:65
GLfloat bias
Definition: glext.h:3681
#define qglStencilFunc
Definition: qgl_linked.h:283
virtual void DrawText(const char *text, const idVec3 &origin, float scale, const idVec4 &color, const idMat3 &viewAxis, const int align=1, const int lifetime=0, bool depthTest=false)
GLuint GLuint GLsizei count
Definition: glext.h:2845
void RB_ShowDebugPolygons(void)
#define qglStencilOp
Definition: qgl_linked.h:285
debugPolygon_t rb_debugPolygons[MAX_DEBUG_POLYGONS]
int GetNumPoints(void) const
Definition: Winding.h:238
GLuint index
Definition: glext.h:3476
const GLubyte * c
Definition: glext.h:4677
void RB_ShowOverdraw(void)
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:3454
Definition: Vector.h:808
struct viewEntity_s * next
Definition: tr_local.h:345
#define qglPushAttrib
Definition: qgl_linked.h:237
#define MAX_DEBUG_TEXT
viewDef_t * primaryView
Definition: tr_local.h:776
GLuint GLuint end
Definition: glext.h:2845
idImage * defaultImage
Definition: Image.h:392
void RB_ClearDebugLines(int time)
void UploadScratch(const byte *pic, int width, int height)
static float Fabs(float f)
Definition: Math.h:779
idCVar r_showNormals("r_showNormals","0", CVAR_RENDERER|CVAR_FLOAT,"draws wireframe normals")
idCVar r_testGammaBias("r_testGammaBias","0", CVAR_RENDERER|CVAR_FLOAT,"if > 0 draw a grid pattern to test gamma levels")
renderView_t renderView
Definition: tr_local.h:370
idCommon * common
Definition: Common.cpp:206
idCVar r_showViewEntitys("r_showViewEntitys","0", CVAR_RENDERER|CVAR_INTEGER,"1 = displays the bounding boxes of all view models, 2 = print index numbers")
idCVar r_debugLineDepthTest("r_debugLineDepthTest","0", CVAR_RENDERER|CVAR_ARCHIVE|CVAR_BOOL,"perform depth test on debug lines")
#define NULL
Definition: Lib.h:88
idCVar r_showTangentSpace("r_showTangentSpace","0", CVAR_RENDERER|CVAR_INTEGER,"shade triangles by tangent space, 1 = use 1st tangent vector, 2 = use 2nd tangent vector, 3 = use normal vector", 0, 3, idCmdSystem::ArgCompletion_Integer< 0, 3 >)
bool viewInsideLight
Definition: tr_local.h:311
void RB_TestImage(void)
void RB_SimpleWorldSetup(void)
#define qglTexCoord2f
Definition: qgl_linked.h:296
int GetInteger(void) const
Definition: CVarSystem.h:143
#define qglOrtho
Definition: qgl_linked.h:218
const int GLS_SRCBLEND_ONE
Definition: tr_local.h:1006
#define qglEnd
Definition: qgl_linked.h:103
idCVar r_debugPolygonFilled("r_debugPolygonFilled","1", CVAR_RENDERER|CVAR_BOOL,"draw a filled polygon")
idImageManager * globalImages
Definition: Image_init.cpp:74
#define qglColor3f
Definition: qgl_linked.h:50
#define qglColor4ubv
Definition: qgl_linked.h:73
void RB_AddDebugText(const char *text, const idVec3 &origin, float scale, const idVec4 &color, const idMat3 &viewAxis, const int align, const int lifetime, const bool depthTest)
int rb_debugLineTime
void RB_ShowIntensity(void)
int rb_numDebugText
void RB_T_RenderTriangleSurface(const drawSurf_t *surf)
Definition: tr_render.cpp:167
idVec3 normal
Definition: DrawVert.h:44
#define MAX_DEBUG_LINES
const byte * image
Definition: Cinematic.h:57
#define qglClearStencil
Definition: qgl_linked.h:44
void Clear(void)
Definition: Str.h:724
GLenum GLsizei width
Definition: glext.h:2846
void RB_ShowLightCount(void)
idRenderEntityLocal * entityDef
Definition: tr_local.h:348
int rb_debugTextTime
struct vertCache_s * shadowCache
Definition: Model.h:139
idRenderModel * hModel
Definition: RenderWorld.h:81
GLubyte GLubyte GLubyte a
Definition: glext.h:4662
virtual void Printf(const char *fmt,...) id_attribute((format(printf
float modelMatrix[16]
Definition: tr_local.h:360
virtual idBounds Bounds(const struct renderEntity_s *ent=NULL) const =0
void RB_DrawElementsWithCounters(const srfTriangles_t *tri)
Definition: tr_render.cpp:78
const float * ToFloatPtr(void) const
Definition: Vector.h:1051
bool UseUnsmoothedTangents(void) const
Definition: Material.h:417
const int GLS_SRCBLEND_DST_ALPHA
Definition: tr_local.h:1011
const int GLS_DSTBLEND_ZERO
Definition: tr_local.h:1016
idDeclManager * declManager
srfTriangles_t * frustumTris
Definition: tr_local.h:221
int uploadHeight
Definition: Image.h:249
GLubyte GLubyte b
Definition: glext.h:4662
idCVar r_testGamma("r_testGamma","0", CVAR_RENDERER|CVAR_FLOAT,"if > 0 draw a grid pattern to test gamma levels", 0, 195)
int numShadowIndexesNoCaps
Definition: Model.h:120
idCVar r_showDominantTri("r_showDominantTri","0", CVAR_RENDERER|CVAR_BOOL,"draw lines from vertexes to center of dominant triangles")
int uploadWidth
Definition: Image.h:249
idVec3 vieworg
Definition: RenderWorld.h:215
idVec4 colorCyan
Definition: Lib.cpp:122
#define qglPopMatrix
Definition: qgl_linked.h:234
void RB_LogComment(const char *comment,...)
Definition: tr_backend.cpp:112
void RB_ScanStencilBuffer(void)
Definition: Matrix.h:333
const int GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA
Definition: tr_local.h:1021
idVec3 point
Definition: RenderWorld.h:247
int rb_numDebugPolygons
struct viewEntity_s * viewEntitys
Definition: tr_local.h:416
glIndex_t v2
Definition: Model.h:70
bool GetBool(void) const
Definition: CVarSystem.h:142
glconfig_t glConfig
void RB_ShowDestinationAlpha(void)
const struct drawSurf_s * globalShadows
Definition: tr_local.h:330
tuple f
Definition: idal.py:89
GLint GLint i2
Definition: qgl.h:261
idCVar r_showLightCount("r_showLightCount","0", CVAR_RENDERER|CVAR_INTEGER,"1 = colors surfaces based on light count, 2 = also count everything through walls, 3 = also print overdraw", 0, 3, idCmdSystem::ArgCompletion_Integer< 0, 3 >)
glIndex_t v1
Definition: Model.h:65
bool IsCleared(void) const
Definition: Bounds.h:222
idCVar r_showIntensity("r_showIntensity","0", CVAR_RENDERER|CVAR_BOOL,"draw the screen colors based on intensity, red = 0, green = 128, blue = 255")
const struct drawSurf_s * localInteractions
Definition: tr_local.h:331
unsigned char byte
Definition: Lib.h:75
int rb_debugPolygonTime
void * R_StaticAlloc(int bytes)
Definition: tr_main.cpp:301
#define qglLineWidth
Definition: qgl_linked.h:184
void RB_SimpleSurfaceSetup(const drawSurf_t *drawSurf)
void RB_ShowTrace(drawSurf_t **drawSurfs, int numDrawSurfs)
Definition: tr_trace.cpp:353
void * Position(vertCache_t *buffer)
GLsizeiptr size
Definition: glext.h:3112
idScreenRect scissor
Definition: tr_local.h:400
const struct drawSurf_s * nextOnLight
Definition: tr_local.h:117
void RB_AddDebugPolygon(const idVec4 &color, const idWinding &winding, const int lifeTime, const bool depthTest)
#define qglClear
Definition: qgl_linked.h:39
void RB_CountStencilBuffer(void)
#define qglColor4f
Definition: qgl_linked.h:66
Definition: Str.h:116
#define qglDrawPixels
Definition: qgl_linked.h:97
#define qglVertex2f
Definition: qgl_linked.h:341
float modelViewMatrix[16]
Definition: tr_local.h:361
struct debugLine_s debugLine_t
byte color[4]
Definition: DrawVert.h:46
const int NUM_SIMPLEX_CHARS
Definition: simplex.h:28
struct debugPolygon_s debugPolygon_t
GLint i1
Definition: qgl.h:261
#define qglColor4fv
Definition: qgl_linked.h:67
int numDrawSurfs
Definition: tr_local.h:412
glIndex_t * indexes
Definition: Model.h:102
void * R_FrameAlloc(int bytes)
Definition: tr_main.cpp:365
void RB_ShowDebugLines(void)
idVertexCache vertexCache
Definition: VertexCache.cpp:41
idRenderSystemLocal tr
int FindIndex(const type &obj) const
Definition: List.h:761
idCVar r_showDepth("r_showDepth","0", CVAR_RENDERER|CVAR_BOOL,"display the contents of the depth buffer and the depth range")
void RB_ShowPortals(void)
idCVar r_showTexturePolarity("r_showTexturePolarity","0", CVAR_RENDERER|CVAR_BOOL,"shade triangles by texture area polarity")
#define qglVertex3f
Definition: qgl_linked.h:349
void GL_State(int stateBits)
Definition: tr_backend.cpp:239
idCinematic * testVideo
Definition: tr_local.h:781
const renderEntity_t * entity
Definition: RenderWorld.h:250
void RB_ShowSilhouette(void)
#define G_WIDTH
idCVar r_debugLineWidth("r_debugLineWidth","1", CVAR_RENDERER|CVAR_ARCHIVE|CVAR_BOOL,"width of debug lines")
#define qglColor3fv
Definition: qgl_linked.h:51
idCVar r_showEdges("r_showEdges","0", CVAR_RENDERER|CVAR_BOOL,"draw the sil edges")
short y1
Definition: tr_local.h:55
#define qglLoadIdentity
Definition: qgl_linked.h:186
GLint j
Definition: qgl.h:264
#define VectorMA(v, s, b, o)
Definition: Vector.h:1998
float RB_DrawTextLength(const char *text, float scale, int len)
int numIndexes
Definition: Model.h:101
idCVar r_useScissor("r_useScissor","1", CVAR_RENDERER|CVAR_BOOL,"scissor clip as portals and lights are processed")
if(!ValidDisplayID(prefInfo.prefDisplayID)) prefInfo.prefDisplayID
idRenderWorldLocal * renderWorld
Definition: tr_local.h:375
char * va(const char *fmt,...)
Definition: Str.cpp:1568
virtual cinData_t ImageForTime(int milliseconds)
Definition: Cinematic.cpp:243
void RB_T_RenderTriangleSurfaceAsLines(const drawSurf_t *surf)
void RB_ShowDepthBuffer(void)
void R_StaticFree(void *data)
Definition: tr_main.cpp:335
renderEntity_t parms
Definition: tr_local.h:251
#define max(x, y)
Definition: os.h:70
short y2
Definition: tr_local.h:55
void R_LocalPointToGlobal(const float modelMatrix[16], const idVec3 &in, idVec3 &out)
Definition: tr_main.cpp:470
void RB_TestGamma(void)
void RB_DrawBounds(const idBounds &bounds)
idMat3 viewaxis
Definition: RenderWorld.h:216
void Bind()
void RB_AddDebugLine(const idVec4 &color, const idVec3 &start, const idVec3 &end, const int lifeTime, const bool depthTest)
void RB_RenderTriangleSurface(const srfTriangles_t *tri)
Definition: tr_render.cpp:147
debugText_t rb_debugText[MAX_DEBUG_TEXT]
void R_AxisToModelMatrix(const idMat3 &axis, const idVec3 &origin, float modelMatrix[16])
Definition: tr_main.cpp:445
idScreenRect currentScissor
Definition: tr_local.h:645
void RB_RenderDebugTools(drawSurf_t **drawSurfs, int numDrawSurfs)
#define qglMatrixMode
Definition: qgl_linked.h:203
#define qglVertexPointer
Definition: qgl_linked.h:363
#define G_HEIGHT
#define MAX_DEBUG_POLYGONS
#define qglPopAttrib
Definition: qgl_linked.h:232
GLuint start
Definition: glext.h:2845
const int GLS_DEPTHMASK
Definition: tr_local.h:1029
int imageWidth
Definition: Cinematic.h:56
int imageHeight
Definition: Cinematic.h:56
idDrawVert * verts
Definition: Model.h:99
idVec4 colorBlue
Definition: Lib.cpp:119
#define qglRasterPos2f
Definition: qgl_linked.h:243
bool Equals(const idScreenRect &rect) const
Definition: tr_main.cpp:133
idImage * testImage
Definition: tr_local.h:780
const viewDef_t * viewDef
Definition: tr_local.h:641
dominantTri_t * dominantTris
Definition: Model.h:117