doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RenderSystem.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 #include "../idlib/precompiled.h"
29 #pragma hdrstop
30 
31 #include "tr_local.h"
32 
35 
36 
37 /*
38 =====================
39 R_PerformanceCounters
40 
41 This prints both front and back end counters, so it should
42 only be called when the back end thread is idle.
43 =====================
44 */
45 static void R_PerformanceCounters( void ) {
46  if ( r_showPrimitives.GetInteger() != 0 ) {
47 
48  float megaBytes = globalImages->SumOfUsedImages() / ( 1024*1024.0 );
49 
50  if ( r_showPrimitives.GetInteger() > 1 ) {
51  common->Printf( "v:%i ds:%i t:%i/%i v:%i/%i st:%i sv:%i image:%5.1f MB\n",
52  tr.pc.c_numViews,
60  megaBytes
61  );
62  } else {
63  common->Printf( "views:%i draws:%i tris:%i (shdw:%i) (vbo:%i) image:%5.1f MB\n",
64  tr.pc.c_numViews,
69  megaBytes
70  );
71  }
72  }
73 
74  if ( r_showDynamic.GetBool() ) {
75  common->Printf( "callback:%i md5:%i dfrmVerts:%i dfrmTris:%i tangTris:%i guis:%i\n",
77  tr.pc.c_generateMd5,
79  tr.pc.c_deformedIndexes/3,
80  tr.pc.c_tangentIndexes/3,
81  tr.pc.c_guiSurfs
82  );
83  }
84 
85  if ( r_showCull.GetBool() ) {
86  common->Printf( "%i sin %i sclip %i sout %i bin %i bout\n",
89  }
90 
91  if ( r_showAlloc.GetBool() ) {
92  common->Printf( "alloc:%i free:%i\n", tr.pc.c_alloc, tr.pc.c_free );
93  }
94 
95  if ( r_showInteractions.GetBool() ) {
96  common->Printf( "createInteractions:%i createLightTris:%i createShadowVolumes:%i\n",
98  }
99  if ( r_showDefs.GetBool() ) {
100  common->Printf( "viewEntities:%i shadowEntities:%i viewLights:%i\n", tr.pc.c_visibleViewEntities,
102  }
103  if ( r_showUpdates.GetBool() ) {
104  common->Printf( "entityUpdates:%i entityRefs:%i lightUpdates:%i lightRefs:%i\n",
107  }
108  if ( r_showMemory.GetBool() ) {
109  int m1 = frameData ? frameData->memoryHighwater : 0;
110  common->Printf( "frameData: %i (%i)\n", R_CountFrameData(), m1 );
111  }
112  if ( r_showLightScale.GetBool() ) {
113  common->Printf( "lightScale: %f\n", backEnd.pc.maxLightValue );
114  }
115 
116  memset( &tr.pc, 0, sizeof( tr.pc ) );
117  memset( &backEnd.pc, 0, sizeof( backEnd.pc ) );
118 }
119 
120 
121 
122 /*
123 ====================
124 R_IssueRenderCommands
125 
126 Called by R_EndFrame each frame
127 ====================
128 */
129 static void R_IssueRenderCommands( void ) {
131  && !frameData->cmdHead->next ) {
132  // nothing to issue
133  return;
134  }
135 
136  // r_skipBackEnd allows the entire time of the back end
137  // to be removed from performance measurements, although
138  // nothing will be drawn to the screen. If the prints
139  // are going to a file, or r_skipBackEnd is later disabled,
140  // usefull data can be received.
141 
142  // r_skipRender is usually more usefull, because it will still
143  // draw 2D graphics
144  if ( !r_skipBackEnd.GetBool() ) {
146  }
147 
149 }
150 
151 /*
152 ============
153 R_GetCommandBuffer
154 
155 Returns memory for a command buffer (stretchPicCommand_t,
156 drawSurfsCommand_t, etc) and links it to the end of the
157 current command chain.
158 ============
159 */
160 void *R_GetCommandBuffer( int bytes ) {
161  emptyCommand_t *cmd;
162 
163  cmd = (emptyCommand_t *)R_FrameAlloc( bytes );
164  cmd->next = NULL;
165  frameData->cmdTail->next = &cmd->commandId;
166  frameData->cmdTail = cmd;
167 
168  return (void *)cmd;
169 }
170 
171 
172 /*
173 ====================
174 R_ClearCommandChain
175 
176 Called after every buffer submission
177 and by R_ToggleSmpFrame
178 ====================
179 */
180 void R_ClearCommandChain( void ) {
181  // clear the command chain
185 }
186 
187 /*
188 =================
189 R_ViewStatistics
190 =================
191 */
192 static void R_ViewStatistics( viewDef_t *parms ) {
193  // report statistics about this view
194  if ( !r_showSurfaces.GetBool() ) {
195  return;
196  }
197  common->Printf( "view:%p surfs:%i\n", parms, parms->numDrawSurfs );
198 }
199 
200 /*
201 =============
202 R_AddDrawViewCmd
203 
204 This is the main 3D rendering command. A single scene may
205 have multiple views if a mirror, portal, or dynamic texture is present.
206 =============
207 */
208 void R_AddDrawViewCmd( viewDef_t *parms ) {
209  drawSurfsCommand_t *cmd;
210 
211  cmd = (drawSurfsCommand_t *)R_GetCommandBuffer( sizeof( *cmd ) );
212  cmd->commandId = RC_DRAW_VIEW;
213 
214  cmd->viewDef = parms;
215 
216  if ( parms->viewEntitys ) {
217  // save the command for r_lockSurfaces debugging
218  tr.lockSurfacesCmd = *cmd;
219  }
220 
221  tr.pc.c_numViews++;
222 
223  R_ViewStatistics( parms );
224 }
225 
226 
227 //=================================================================================
228 
229 
230 /*
231 ======================
232 R_LockSurfaceScene
233 
234 r_lockSurfaces allows a developer to move around
235 without changing the composition of the scene, including
236 culling. The only thing that is modified is the
237 view position and axis, no front end work is done at all
238 
239 
240 Add the stored off command again, so the new rendering will use EXACTLY
241 the same surfaces, including all the culling, even though the transformation
242 matricies have been changed. This allow the culling tightness to be
243 evaluated interactively.
244 ======================
245 */
247  drawSurfsCommand_t *cmd;
248  viewEntity_t *vModel;
249 
250  // set the matrix for world space to eye space
251  R_SetViewMatrix( parms );
253 
254  // update the view origin and axis, and all
255  // the entity matricies
256  for( vModel = tr.lockSurfacesCmd.viewDef->viewEntitys ; vModel ; vModel = vModel->next ) {
257  myGlMultMatrix( vModel->modelMatrix,
259  vModel->modelViewMatrix );
260  }
261 
262  // add the stored off surface commands again
263  cmd = (drawSurfsCommand_t *)R_GetCommandBuffer( sizeof( *cmd ) );
264  *cmd = tr.lockSurfacesCmd;
265 }
266 
267 /*
268 =============
269 R_CheckCvars
270 
271 See if some cvars that we watch have changed
272 =============
273 */
274 static void R_CheckCvars( void ) {
276 
277  // gamma stuff
278  if ( r_gamma.IsModified() || r_brightness.IsModified() ) {
282  }
283 
284  // check for changes to logging state
286 }
287 
288 /*
289 =============
290 idRenderSystemLocal::idRenderSystemLocal
291 =============
292 */
294  Clear();
295 }
296 
297 /*
298 =============
299 idRenderSystemLocal::~idRenderSystemLocal
300 =============
301 */
303 }
304 
305 /*
306 =============
307 SetColor
308 
309 This can be used to pass general information to the current material, not
310 just colors
311 =============
312 */
314  guiModel->SetColor( rgba[0], rgba[1], rgba[2], rgba[3] );
315 }
316 
317 
318 /*
319 =============
320 SetColor4
321 =============
322 */
323 void idRenderSystemLocal::SetColor4( float r, float g, float b, float a ) {
324  guiModel->SetColor( r, g, b, a );
325 }
326 
327 /*
328 =============
329 DrawStretchPic
330 =============
331 */
332 void idRenderSystemLocal::DrawStretchPic( const idDrawVert *verts, const glIndex_t *indexes, int vertCount, int indexCount, const idMaterial *material,
333  bool clip, float min_x, float min_y, float max_x, float max_y ) {
334  guiModel->DrawStretchPic( verts, indexes, vertCount, indexCount, material,
335  clip, min_x, min_y, max_x, max_y );
336 }
337 
338 /*
339 =============
340 DrawStretchPic
341 
342 x/y/w/h are in the 0,0 to 640,480 range
343 =============
344 */
345 void idRenderSystemLocal::DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, const idMaterial *material ) {
346  guiModel->DrawStretchPic( x, y, w, h, s1, t1, s2, t2, material );
347 }
348 
349 /*
350 =============
351 DrawStretchTri
352 
353 x/y/w/h are in the 0,0 to 640,480 range
354 =============
355 */
356 void idRenderSystemLocal::DrawStretchTri( idVec2 p1, idVec2 p2, idVec2 p3, idVec2 t1, idVec2 t2, idVec2 t3, const idMaterial *material ) {
357  tr.guiModel->DrawStretchTri( p1, p2, p3, t1, t2, t3, material );
358 }
359 
360 /*
361 =============
362 GlobalToNormalizedDeviceCoordinates
363 =============
364 */
367 }
368 
369 /*
370 =============
371 GlobalToNormalizedDeviceCoordinates
372 =============
373 */
375  width = glConfig.vidWidth;
376  height = glConfig.vidHeight;
377 }
378 
379 /*
380 =====================
381 idRenderSystemLocal::DrawSmallChar
382 
383 small chars are drawn at native screen resolution
384 =====================
385 */
386 void idRenderSystemLocal::DrawSmallChar( int x, int y, int ch, const idMaterial *material ) {
387  int row, col;
388  float frow, fcol;
389  float size;
390 
391  ch &= 255;
392 
393  if ( ch == ' ' ) {
394  return;
395  }
396 
397  if ( y < -SMALLCHAR_HEIGHT ) {
398  return;
399  }
400 
401  row = ch >> 4;
402  col = ch & 15;
403 
404  frow = row * 0.0625f;
405  fcol = col * 0.0625f;
406  size = 0.0625f;
407 
409  fcol, frow,
410  fcol + size, frow + size,
411  material );
412 }
413 
414 /*
415 ==================
416 idRenderSystemLocal::DrawSmallString[Color]
417 
418 Draws a multi-colored string with a drop shadow, optionally forcing
419 to a fixed color.
420 
421 Coordinates are at 640 by 480 virtual resolution
422 ==================
423 */
424 void idRenderSystemLocal::DrawSmallStringExt( int x, int y, const char *string, const idVec4 &setColor, bool forceColor, const idMaterial *material ) {
425  idVec4 color;
426  const unsigned char *s;
427  int xx;
428 
429  // draw the colored text
430  s = (const unsigned char*)string;
431  xx = x;
432  SetColor( setColor );
433  while ( *s ) {
434  if ( idStr::IsColor( (const char*)s ) ) {
435  if ( !forceColor ) {
436  if ( *(s+1) == C_COLOR_DEFAULT ) {
437  SetColor( setColor );
438  } else {
439  color = idStr::ColorForIndex( *(s+1) );
440  color[3] = setColor[3];
441  SetColor( color );
442  }
443  }
444  s += 2;
445  continue;
446  }
447  DrawSmallChar( xx, y, *s, material );
448  xx += SMALLCHAR_WIDTH;
449  s++;
450  }
451  SetColor( colorWhite );
452 }
453 
454 /*
455 =====================
456 idRenderSystemLocal::DrawBigChar
457 =====================
458 */
459 void idRenderSystemLocal::DrawBigChar( int x, int y, int ch, const idMaterial *material ) {
460  int row, col;
461  float frow, fcol;
462  float size;
463 
464  ch &= 255;
465 
466  if ( ch == ' ' ) {
467  return;
468  }
469 
470  if ( y < -BIGCHAR_HEIGHT ) {
471  return;
472  }
473 
474  row = ch >> 4;
475  col = ch & 15;
476 
477  frow = row * 0.0625f;
478  fcol = col * 0.0625f;
479  size = 0.0625f;
480 
482  fcol, frow,
483  fcol + size, frow + size,
484  material );
485 }
486 
487 /*
488 ==================
489 idRenderSystemLocal::DrawBigString[Color]
490 
491 Draws a multi-colored string with a drop shadow, optionally forcing
492 to a fixed color.
493 
494 Coordinates are at 640 by 480 virtual resolution
495 ==================
496 */
497 void idRenderSystemLocal::DrawBigStringExt( int x, int y, const char *string, const idVec4 &setColor, bool forceColor, const idMaterial *material ) {
498  idVec4 color;
499  const char *s;
500  int xx;
501 
502  // draw the colored text
503  s = string;
504  xx = x;
505  SetColor( setColor );
506  while ( *s ) {
507  if ( idStr::IsColor( s ) ) {
508  if ( !forceColor ) {
509  if ( *(s+1) == C_COLOR_DEFAULT ) {
510  SetColor( setColor );
511  } else {
512  color = idStr::ColorForIndex( *(s+1) );
513  color[3] = setColor[3];
514  SetColor( color );
515  }
516  }
517  s += 2;
518  continue;
519  }
520  DrawBigChar( xx, y, *s, material );
521  xx += BIGCHAR_WIDTH;
522  s++;
523  }
524  SetColor( colorWhite );
525 }
526 
527 //======================================================================================
528 
529 /*
530 ==================
531 SetBackEndRenderer
532 
533 Check for changes in the back end renderSystem, possibly invalidating cached data
534 ==================
535 */
537  if ( !r_renderer.IsModified() ) {
538  return;
539  }
540 
541  bool oldVPstate = backEndRendererHasVertexPrograms;
542 
544 
545  if ( idStr::Icmp( r_renderer.GetString(), "arb" ) == 0 ) {
547  } else if ( idStr::Icmp( r_renderer.GetString(), "arb2" ) == 0 ) {
548  if ( glConfig.allowARB2Path ) {
550  }
551  } else if ( idStr::Icmp( r_renderer.GetString(), "nv10" ) == 0 ) {
552  if ( glConfig.allowNV10Path ) {
554  }
555  } else if ( idStr::Icmp( r_renderer.GetString(), "nv20" ) == 0 ) {
556  if ( glConfig.allowNV20Path ) {
558  }
559  } else if ( idStr::Icmp( r_renderer.GetString(), "r200" ) == 0 ) {
560  if ( glConfig.allowR200Path ) {
562  }
563  }
564 
565  // fallback
566  if ( backEndRenderer == BE_BAD ) {
567  // choose the best
568  if ( glConfig.allowARB2Path ) {
570  } else if ( glConfig.allowR200Path ) {
572  } else if ( glConfig.allowNV20Path ) {
574  } else if ( glConfig.allowNV10Path ) {
576  } else {
577  // the others are considered experimental
579  }
580  }
581 
584 
585  switch( backEndRenderer ) {
586  case BE_ARB:
587  common->Printf( "using ARB renderSystem\n" );
588  break;
589  case BE_NV10:
590  common->Printf( "using NV10 renderSystem\n" );
591  break;
592  case BE_NV20:
593  common->Printf( "using NV20 renderSystem\n" );
595  break;
596  case BE_R200:
597  common->Printf( "using R200 renderSystem\n" );
599  break;
600  case BE_ARB2:
601  common->Printf( "using ARB2 renderSystem\n" );
604  break;
605  default:
606  common->FatalError( "SetbackEndRenderer: bad back end" );
607  }
608 
609  // clear the vertex cache if we are changing between
610  // using vertex programs and not, because specular and
611  // shadows will be different data
612  if ( oldVPstate != backEndRendererHasVertexPrograms ) {
614  if ( primaryWorld ) {
616  }
617  }
618 
620 }
621 
622 /*
623 ====================
624 BeginFrame
625 ====================
626 */
627 void idRenderSystemLocal::BeginFrame( int windowWidth, int windowHeight ) {
628  setBufferCommand_t *cmd;
629 
630  if ( !glConfig.isInitialized ) {
631  return;
632  }
633 
634  // determine which back end we will use
636 
637  guiModel->Clear();
638 
639  // for the larger-than-window tiled rendering screenshots
640  if ( tiledViewport[0] ) {
641  windowWidth = tiledViewport[0];
642  windowHeight = tiledViewport[1];
643  }
644 
645  glConfig.vidWidth = windowWidth;
646  glConfig.vidHeight = windowHeight;
647 
648  renderCrops[0].x = 0;
649  renderCrops[0].y = 0;
650  renderCrops[0].width = windowWidth;
651  renderCrops[0].height = windowHeight;
652  currentRenderCrop = 0;
653 
654  // screenFraction is just for quickly testing fill rate limitations
655  if ( r_screenFraction.GetInteger() != 100 ) {
656  int w = SCREEN_WIDTH * r_screenFraction.GetInteger() / 100.0f;
657  int h = SCREEN_HEIGHT * r_screenFraction.GetInteger() / 100.0f;
658  CropRenderSize( w, h );
659  }
660 
661 
662  // this is the ONLY place this is modified
663  frameCount++;
664 
665  // just in case we did a common->Error while this
666  // was set
667  guiRecursionLevel = 0;
668 
669  // the first rendering will be used for commands like
670  // screenshot, rather than a possible subsequent remote
671  // or mirror render
672 // primaryWorld = NULL;
673 
674  // set the time for shader effects in 2D rendering
676 
677  //
678  // draw buffer stuff
679  //
680  cmd = (setBufferCommand_t *)R_GetCommandBuffer( sizeof( *cmd ) );
681  cmd->commandId = RC_SET_BUFFER;
682  cmd->frameCount = frameCount;
683 
684  if ( r_frontBuffer.GetBool() ) {
685  cmd->buffer = (int)GL_FRONT;
686  } else {
687  cmd->buffer = (int)GL_BACK;
688  }
689 }
690 
695 }
696 
699 }
700 
701 /*
702 =============
703 EndFrame
704 
705 Returns the number of msec spent in the back end
706 =============
707 */
708 void idRenderSystemLocal::EndFrame( int *frontEndMsec, int *backEndMsec ) {
709  emptyCommand_t *cmd;
710 
711  if ( !glConfig.isInitialized ) {
712  return;
713  }
714 
715  // close any gui drawing
717  guiModel->Clear();
718 
719  // save out timing information
720  if ( frontEndMsec ) {
721  *frontEndMsec = pc.frontEndMsec;
722  }
723  if ( backEndMsec ) {
724  *backEndMsec = backEnd.pc.msec;
725  }
726 
727  // print any other statistics and clear all of them
728  R_PerformanceCounters();
729 
730  // check for dynamic changes that require some initialization
731  R_CheckCvars();
732 
733  // check for errors
734  GL_CheckErrors();
735 
736  // add the swapbuffers command
737  cmd = (emptyCommand_t *)R_GetCommandBuffer( sizeof( *cmd ) );
738  cmd->commandId = RC_SWAP_BUFFERS;
739 
740  // start the back end up again with the new command list
741  R_IssueRenderCommands();
742 
743  // use the other buffers next frame, because another CPU
744  // may still be rendering into the current buffers
746 
747  // we can now release the vertexes used this frame
749 
750  if ( session->writeDemo ) {
753  if ( r_showDemo.GetBool() ) {
754  common->Printf( "write DC_END_FRAME\n" );
755  }
756  }
757 
758 }
759 
760 /*
761 =====================
762 RenderViewToViewport
763 
764 Converts from SCREEN_WIDTH / SCREEN_HEIGHT coordinates to current cropped pixel coordinates
765 =====================
766 */
769 
770  float wRatio = (float)rc->width / SCREEN_WIDTH;
771  float hRatio = (float)rc->height / SCREEN_HEIGHT;
772 
773  viewport->x1 = idMath::Ftoi( rc->x + renderView->x * wRatio );
774  viewport->x2 = idMath::Ftoi( rc->x + floor( ( renderView->x + renderView->width ) * wRatio + 0.5f ) - 1 );
775  viewport->y1 = idMath::Ftoi( ( rc->y + rc->height ) - floor( ( renderView->y + renderView->height ) * hRatio + 0.5f ) );
776  viewport->y2 = idMath::Ftoi( ( rc->y + rc->height ) - floor( renderView->y * hRatio + 0.5f ) - 1 );
777 }
778 
779 static int RoundDownToPowerOfTwo( int v ) {
780  int i;
781 
782  for ( i = 0 ; i < 20 ; i++ ) {
783  if ( ( 1 << i ) == v ) {
784  return v;
785  }
786  if ( ( 1 << i ) > v ) {
787  return 1 << ( i-1 );
788  }
789  }
790  return 1<<i;
791 }
792 
793 /*
794 ================
795 CropRenderSize
796 
797 This automatically halves sizes until it fits in the current window size,
798 so if you specify a power of two size for a texture copy, it may be shrunk
799 down, but still valid.
800 ================
801 */
802 void idRenderSystemLocal::CropRenderSize( int width, int height, bool makePowerOfTwo, bool forceDimensions ) {
803  if ( !glConfig.isInitialized ) {
804  return;
805  }
806 
807  // close any gui drawing before changing the size
809  guiModel->Clear();
810 
811  if ( width < 1 || height < 1 ) {
812  common->Error( "CropRenderSize: bad sizes" );
813  }
814 
815  if ( session->writeDemo ) {
818  session->writeDemo->WriteInt( width );
819  session->writeDemo->WriteInt( height );
820  session->writeDemo->WriteInt( makePowerOfTwo );
821 
822  if ( r_showDemo.GetBool() ) {
823  common->Printf( "write DC_CROP_RENDER\n" );
824  }
825  }
826 
827  // convert from virtual SCREEN_WIDTH/SCREEN_HEIGHT coordinates to physical OpenGL pixels
828  renderView_t renderView;
829  renderView.x = 0;
830  renderView.y = 0;
831  renderView.width = width;
832  renderView.height = height;
833 
834  idScreenRect r;
835  RenderViewToViewport( &renderView, &r );
836 
837  width = r.x2 - r.x1 + 1;
838  height = r.y2 - r.y1 + 1;
839 
840  if ( forceDimensions ) {
841  // just give exactly what we ask for
842  width = renderView.width;
843  height = renderView.height;
844  }
845 
846  // if makePowerOfTwo, drop to next lower power of two after scaling to physical pixels
847  if ( makePowerOfTwo ) {
848  width = RoundDownToPowerOfTwo( width );
849  height = RoundDownToPowerOfTwo( height );
850  // FIXME: megascreenshots with offset viewports don't work right with this yet
851  }
852 
854 
855  // we might want to clip these to the crop window instead
856  while ( width > glConfig.vidWidth ) {
857  width >>= 1;
858  }
859  while ( height > glConfig.vidHeight ) {
860  height >>= 1;
861  }
862 
863  if ( currentRenderCrop == MAX_RENDER_CROPS ) {
864  common->Error( "idRenderSystemLocal::CropRenderSize: currentRenderCrop == MAX_RENDER_CROPS" );
865  }
866 
868 
870 
871  rc->x = 0;
872  rc->y = 0;
873  rc->width = width;
874  rc->height = height;
875 }
876 
877 /*
878 ================
879 UnCrop
880 ================
881 */
883  if ( !glConfig.isInitialized ) {
884  return;
885  }
886 
887  if ( currentRenderCrop < 1 ) {
888  common->Error( "idRenderSystemLocal::UnCrop: currentRenderCrop < 1" );
889  }
890 
891  // close any gui drawing
893  guiModel->Clear();
894 
896 
897  if ( session->writeDemo ) {
900 
901  if ( r_showDemo.GetBool() ) {
902  common->Printf( "write DC_UNCROP\n" );
903  }
904  }
905 }
906 
907 /*
908 ================
909 CaptureRenderToImage
910 ================
911 */
912 void idRenderSystemLocal::CaptureRenderToImage( const char *imageName ) {
913  if ( !glConfig.isInitialized ) {
914  return;
915  }
917  guiModel->Clear();
918 
919  if ( session->writeDemo ) {
922  session->writeDemo->WriteHashString( imageName );
923 
924  if ( r_showDemo.GetBool() ) {
925  common->Printf( "write DC_CAPTURE_RENDER: %s\n", imageName );
926  }
927  }
928 
929  // look up the image before we create the render command, because it
930  // may need to sync to create the image
932 
934 
935  copyRenderCommand_t *cmd = (copyRenderCommand_t *)R_GetCommandBuffer( sizeof( *cmd ) );
936  cmd->commandId = RC_COPY_RENDER;
937  cmd->x = rc->x;
938  cmd->y = rc->y;
939  cmd->imageWidth = rc->width;
940  cmd->imageHeight = rc->height;
941  cmd->image = image;
942 
943  guiModel->Clear();
944 }
945 
946 /*
947 ==============
948 CaptureRenderToFile
949 
950 ==============
951 */
952 void idRenderSystemLocal::CaptureRenderToFile( const char *fileName, bool fixAlpha ) {
953  if ( !glConfig.isInitialized ) {
954  return;
955  }
956 
958 
960  guiModel->Clear();
961  R_IssueRenderCommands();
962 
963  qglReadBuffer( GL_BACK );
964 
965  // include extra space for OpenGL padding to word boundaries
966  int c = ( rc->width + 3 ) * rc->height;
967  byte *data = (byte *)R_StaticAlloc( c * 3 );
968 
969  qglReadPixels( rc->x, rc->y, rc->width, rc->height, GL_RGB, GL_UNSIGNED_BYTE, data );
970 
971  byte *data2 = (byte *)R_StaticAlloc( c * 4 );
972 
973  for ( int i = 0 ; i < c ; i++ ) {
974  data2[ i * 4 ] = data[ i * 3 ];
975  data2[ i * 4 + 1 ] = data[ i * 3 + 1 ];
976  data2[ i * 4 + 2 ] = data[ i * 3 + 2 ];
977  data2[ i * 4 + 3 ] = 0xff;
978  }
979 
980  R_WriteTGA( fileName, data2, rc->width, rc->height, true );
981 
982  R_StaticFree( data );
983  R_StaticFree( data2 );
984 }
985 
986 
987 /*
988 ==============
989 AllocRenderWorld
990 ==============
991 */
993  idRenderWorldLocal *rw;
994  rw = new idRenderWorldLocal;
995  worlds.Append( rw );
996  return rw;
997 }
998 
999 /*
1000 ==============
1001 FreeRenderWorld
1002 ==============
1003 */
1005  if ( primaryWorld == rw ) {
1006  primaryWorld = NULL;
1007  }
1008  worlds.Remove( static_cast<idRenderWorldLocal *>(rw) );
1009  delete rw;
1010 }
1011 
1012 /*
1013 ==============
1014 PrintMemInfo
1015 ==============
1016 */
1018  // sum up image totals
1019  globalImages->PrintMemInfo( mi );
1020 
1021  // sum up model totals
1023 
1024  // compute render totals
1025 
1026 }
1027 
1028 /*
1029 ===============
1030 idRenderSystemLocal::UploadImage
1031 ===============
1032 */
1033 bool idRenderSystemLocal::UploadImage( const char *imageName, const byte *data, int width, int height ) {
1034  idImage *image = globalImages->GetImage( imageName );
1035  if ( !image ) {
1036  return false;
1037  }
1038  image->UploadScratch( data, width, height );
1039  image->SetImageFilterAndRepeat();
1040  return true;
1041 }
virtual void FreeRenderWorld(idRenderWorld *rw)
GLubyte g
Definition: glext.h:4662
byte color[4]
Definition: MegaTexture.cpp:54
void R_ClearCommandChain(void)
void R_LockSurfaceScene(viewDef_t *parms)
viewEntity_t worldSpace
Definition: tr_local.h:373
Definition: Image.h:146
const int C_COLOR_DEFAULT
Definition: Str.h:83
idCVar r_frontBuffer("r_frontBuffer","0", CVAR_RENDERER|CVAR_BOOL,"draw to front buffer for debugging")
void EmitFullScreen()
Definition: GuiModel.cpp:226
idCVar r_gamma("r_gamma","1", CVAR_RENDERER|CVAR_ARCHIVE|CVAR_FLOAT,"changes gamma tables", 0.5f, 3.0f)
renderCommand_t commandId
Definition: tr_local.h:492
virtual void WriteDemoPics()
idVec4 colorWhite
Definition: Lib.cpp:116
void GL_CheckErrors(void)
virtual bool UploadImage(const char *imageName, const byte *data, int width, int height)
short x2
Definition: tr_local.h:55
const GLdouble * v
Definition: glext.h:2936
backEndCounters_t pc
Definition: tr_local.h:642
class idGuiModel * guiModel
Definition: tr_local.h:802
bool allowR200Path
Definition: RenderSystem.h:95
bool allowARB2Path
Definition: RenderSystem.h:96
virtual void SetColor4(float r, float g, float b, float a)
float maxLightValue
Definition: tr_local.h:633
idCVar r_brightness("r_brightness","1", CVAR_RENDERER|CVAR_ARCHIVE|CVAR_FLOAT,"changes gamma tables", 0.5f, 2.0f)
GLenum GLint GLint y
Definition: glext.h:2849
emptyCommand_t * cmdHead
Definition: tr_local.h:542
const int SCREEN_HEIGHT
Definition: RenderSystem.h:154
drawSurfsCommand_t lockSurfacesCmd
Definition: tr_local.h:790
idRenderSystem * renderSystem
virtual void CaptureRenderToImage(const char *imageName)
case const int
Definition: Callbacks.cpp:52
virtual void PrintMemInfo(MemInfo_t *mi)=0
idCVar r_screenFraction("r_screenFraction","100", CVAR_RENDERER|CVAR_INTEGER,"for testing fill rate, the resolution of the entire screen can be changed")
idImage * GetImage(const char *name) const
Definition: Vector.h:316
case const float
Definition: Callbacks.cpp:62
idCVar r_renderer("r_renderer","best", CVAR_RENDERER|CVAR_ARCHIVE,"hardware specific renderer path to use", r_rendererArgs, idCmdSystem::ArgCompletion_String< r_rendererArgs >)
GLenum GLsizei GLenum GLenum const GLvoid * image
Definition: glext.h:2855
performanceCounters_t pc
Definition: tr_local.h:788
GLenum GLsizei const GLvoid * string
Definition: glext.h:3472
idRenderWorldLocal * primaryWorld
Definition: tr_local.h:774
#define qglReadPixels
Definition: qgl_linked.h:266
short x1
Definition: tr_local.h:55
int tiledViewport[2]
Definition: tr_local.h:759
void PrintMemInfo(MemInfo_t *mi)
frameData_t * frameData
Definition: tr_backend.cpp:34
class idGuiModel * demoGuiModel
Definition: tr_local.h:803
GLdouble s
Definition: glext.h:2935
idList< idRenderWorldLocal * > worlds
Definition: tr_local.h:772
renderCommand_t commandId
Definition: tr_local.h:486
bool allowNV20Path
Definition: RenderSystem.h:93
GLenum GLint x
Definition: glext.h:2849
int i
Definition: process.py:33
static idVec4 & ColorForIndex(int i)
Definition: Str.cpp:71
const int BIGCHAR_WIDTH
Definition: RenderSystem.h:148
renderCommand_t commandId
Definition: tr_local.h:497
idCVar r_skipBackEnd("r_skipBackEnd","0", CVAR_RENDERER|CVAR_BOOL,"don't draw anything")
int Icmp(const char *text) const
Definition: Str.h:667
idDemoFile * writeDemo
Definition: Session.h:159
static int Ftoi(float f)
Definition: Math.h:797
backEndState_t backEnd
Definition: tr_backend.cpp:35
idCVar r_showDemo("r_showDemo","0", CVAR_RENDERER|CVAR_BOOL,"report reads and writes to the demo file")
idCVar r_showAlloc("r_showAlloc","0", CVAR_RENDERER|CVAR_BOOL,"report alloc/free counts")
virtual void CropRenderSize(int width, int height, bool makePowerOfTwo=false, bool forceDimensions=false)
backEndName_t backEndRenderer
Definition: tr_local.h:762
void * R_GetCommandBuffer(int bytes)
virtual void DrawStretchPic(const idDrawVert *verts, const glIndex_t *indexes, int vertCount, int indexCount, const idMaterial *material, bool clip=true, float x=0.0f, float y=0.0f, float w=640.0f, float h=0.0f)
viewDef_t * viewDef
Definition: tr_local.h:493
void DrawStretchTri(idVec2 p1, idVec2 p2, idVec2 p3, idVec2 t1, idVec2 t2, idVec2 t3, const idMaterial *material)
Definition: GuiModel.cpp:568
void R_AddDrawViewCmd(viewDef_t *parms)
renderCommand_t * next
Definition: tr_local.h:482
virtual void BeginFrame(int windowWidth, int windowHeight)
const int SMALLCHAR_WIDTH
Definition: RenderSystem.h:146
bool backEndRendererHasVertexPrograms
Definition: tr_local.h:763
virtual void DrawBigChar(int x, int y, int ch, const idMaterial *material)
Definition: Vector.h:52
virtual int WriteInt(const int value)
Definition: File.cpp:468
virtual void PrintMemInfo(MemInfo_t *mi)
void R_SetColorMappings(void)
const GLubyte * c
Definition: glext.h:4677
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:3454
Definition: Vector.h:808
struct viewEntity_s * next
Definition: tr_local.h:345
#define qglReadBuffer
Definition: qgl_linked.h:265
void Clear()
Definition: GuiModel.cpp:52
void UploadScratch(const byte *pic, int width, int height)
idCVar r_showUpdates("r_showUpdates","0", CVAR_RENDERER|CVAR_BOOL,"report entity and light updates and ref counts")
idCommon * common
Definition: Common.cpp:206
idCVar r_showCull("r_showCull","0", CVAR_RENDERER|CVAR_BOOL,"report sphere and box culling stats")
#define NULL
Definition: Lib.h:88
int memoryHighwater
Definition: tr_local.h:537
int glIndex_t
Definition: Model.h:52
GLsizei GLsizei GLenum GLenum const GLvoid * data
Definition: glext.h:2853
int GetInteger(void) const
Definition: CVarSystem.h:143
virtual void GetGLSettings(int &width, int &height)
idImageManager * globalImages
Definition: Image_init.cpp:74
virtual void virtual void FatalError(const char *fmt,...) id_attribute((format(printf
virtual void CaptureRenderToFile(const char *fileName, bool fixAlpha)
idCVar r_logFile("r_logFile","0", CVAR_RENDERER|CVAR_INTEGER,"number of frames to emit GL logs")
virtual void EndFrame(int *frontEndMsec, int *backEndMsec)
void R_WriteTGA(const char *filename, const byte *data, int width, int height, bool flipVertical=false)
Definition: Image_files.cpp:85
void SetImageFilterAndRepeat() const
Definition: Image_load.cpp:370
float backEndRendererMaxLight
Definition: tr_local.h:764
void R_GlobalToNormalizedDeviceCoordinates(const idVec3 &global, idVec3 &ndc)
Definition: tr_main.cpp:714
virtual void DrawBigStringExt(int x, int y, const char *string, const idVec4 &setColor, bool forceColor, const idMaterial *material)
GLenum GLsizei width
Definition: glext.h:2846
void RenderViewToViewport(const renderView_t *renderView, idScreenRect *viewport)
emptyCommand_t * cmdTail
Definition: tr_local.h:542
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
void WriteToDemo(idDemoFile *demo)
Definition: GuiModel.cpp:64
idCVar r_showDefs("r_showDefs","0", CVAR_RENDERER|CVAR_BOOL,"report the number of modeDefs and lightDefs in view")
void R_SetViewMatrix(viewDef_t *viewDef)
Definition: tr_main.cpp:838
void GLimp_EnableLogging(bool enable)
Definition: dedicated.cpp:75
GLenum GLsizei GLsizei height
Definition: glext.h:2856
bool allowNV10Path
Definition: RenderSystem.h:94
idEventLoop * eventLoop
Definition: EventLoop.cpp:35
const int BIGCHAR_HEIGHT
Definition: RenderSystem.h:149
GLubyte GLubyte b
Definition: glext.h:4662
virtual void SetColor(const idVec4 &rgba)
void RB_ExecuteBackEndCommands(const emptyCommand_t *cmds)
Definition: tr_backend.cpp:600
idImage * ImageFromFile(const char *name, textureFilter_t filter, bool allowDownSize, textureRepeat_t repeat, textureDepth_t depth, cubeFiles_t cubeMap=CF_2D)
renderCrop_t renderCrops[MAX_RENDER_CROPS]
Definition: tr_local.h:797
void myGlMultMatrix(const float *a, const float *b, float *out)
const char * GetString(void) const
Definition: CVarSystem.h:141
int Append(const type &obj)
Definition: List.h:646
GLdouble GLdouble GLdouble r
Definition: glext.h:2951
idRenderModelManager * renderModelManager
const int SCREEN_WIDTH
Definition: RenderSystem.h:153
struct viewEntity_s * viewEntitys
Definition: tr_local.h:416
GLenum GLenum GLvoid * row
Definition: glext.h:2866
bool GetBool(void) const
Definition: CVarSystem.h:142
glconfig_t glConfig
idImage * image
Definition: tr_local.h:499
void ClearModified(void)
Definition: CVarSystem.h:139
void DrawStretchPic(const idDrawVert *verts, const glIndex_t *indexes, int vertCount, int indexCount, const idMaterial *hShader, bool clip=true, float min_x=0.0f, float min_y=0.0f, float max_x=640.0f, float max_y=480.0f)
Definition: GuiModel.cpp:359
unsigned char byte
Definition: Lib.h:75
void * R_StaticAlloc(int bytes)
Definition: tr_main.cpp:301
renderCommand_t commandId
Definition: tr_local.h:482
GLsizeiptr size
Definition: glext.h:3112
int R_CountFrameData(void)
Definition: tr_main.cpp:274
virtual void DrawDemoPics()
virtual void DrawSmallStringExt(int x, int y, const char *string, const idVec4 &setColor, bool forceColor, const idMaterial *material)
bool IsModified(void) const
Definition: CVarSystem.h:137
idCVar r_showInteractions("r_showInteractions","0", CVAR_RENDERER|CVAR_BOOL,"report interaction generation activity")
const int SMALLCHAR_HEIGHT
Definition: RenderSystem.h:147
virtual void UnCrop()
float modelViewMatrix[16]
Definition: tr_local.h:361
int numDrawSurfs
Definition: tr_local.h:412
void * R_FrameAlloc(int bytes)
Definition: tr_main.cpp:365
idVertexCache vertexCache
Definition: VertexCache.cpp:41
idCVar r_showPrimitives("r_showPrimitives","0", CVAR_RENDERER|CVAR_INTEGER,"report drawsurf/index/vertex counts")
idRenderSystemLocal tr
void SetColor(float r, float g, float b, float a)
Definition: GuiModel.cpp:334
idCVar r_showMemory("r_showMemory","0", CVAR_RENDERER|CVAR_BOOL,"print frame memory utilization")
virtual void DrawSmallChar(int x, int y, int ch, const idMaterial *material)
short y1
Definition: tr_local.h:55
idCVar r_showLightScale("r_showLightScale","0", CVAR_RENDERER|CVAR_BOOL,"report the scale factor applied to drawing for overbrights")
bool isInitialized
Definition: RenderSystem.h:98
virtual idRenderWorld * AllocRenderWorld(void)
idSession * session
Definition: Session.cpp:48
void R_StaticFree(void *data)
Definition: tr_main.cpp:335
int RoundDownToPowerOfTwo(int num)
Definition: MegaTexture.cpp:45
short y2
Definition: tr_local.h:55
void R_ToggleSmpFrame(void)
Definition: tr_main.cpp:184
virtual void Error(const char *fmt,...) id_attribute((format(printf
idCVar r_showSurfaces("r_showSurfaces","0", CVAR_RENDERER|CVAR_BOOL,"report surface/light/shadow counts")
idCVar r_showDynamic("r_showDynamic","0", CVAR_RENDERER|CVAR_BOOL,"report stats on dynamic surface generation")
virtual void GlobalToNormalizedDeviceCoordinates(const idVec3 &global, idVec3 &ndc)
bool Remove(const type &obj)
Definition: List.h:878
bool IsColor(void) const
Definition: Str.h:837
int Milliseconds(void)
Definition: EventLoop.cpp:248
virtual void DrawStretchTri(idVec2 p1, idVec2 p2, idVec2 p3, idVec2 t1, idVec2 t2, idVec2 t3, const idMaterial *material)
void WriteHashString(const char *str)
Definition: DemoFile.cpp:248