tr_init.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake III Arena source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Foobar; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. // tr_init.c -- functions that are not called every frame
  19. #include "tr_local.h"
  20. glconfig_t glConfig;
  21. glstate_t glState;
  22. static void GfxInfo_f( void );
  23. cvar_t *r_flareSize;
  24. cvar_t *r_flareFade;
  25. cvar_t *r_railWidth;
  26. cvar_t *r_railCoreWidth;
  27. cvar_t *r_railSegmentLength;
  28. cvar_t *r_ignoreFastPath;
  29. cvar_t *r_verbose;
  30. cvar_t *r_ignore;
  31. cvar_t *r_displayRefresh;
  32. cvar_t *r_detailTextures;
  33. cvar_t *r_znear;
  34. cvar_t *r_smp;
  35. cvar_t *r_showSmp;
  36. cvar_t *r_skipBackEnd;
  37. cvar_t *r_ignorehwgamma;
  38. cvar_t *r_measureOverdraw;
  39. cvar_t *r_inGameVideo;
  40. cvar_t *r_fastsky;
  41. cvar_t *r_drawSun;
  42. cvar_t *r_dynamiclight;
  43. cvar_t *r_dlightBacks;
  44. cvar_t *r_lodbias;
  45. cvar_t *r_lodscale;
  46. cvar_t *r_norefresh;
  47. cvar_t *r_drawentities;
  48. cvar_t *r_drawworld;
  49. cvar_t *r_speeds;
  50. cvar_t *r_fullbright;
  51. cvar_t *r_novis;
  52. cvar_t *r_nocull;
  53. cvar_t *r_facePlaneCull;
  54. cvar_t *r_showcluster;
  55. cvar_t *r_nocurves;
  56. cvar_t *r_allowExtensions;
  57. cvar_t *r_ext_compressed_textures;
  58. cvar_t *r_ext_gamma_control;
  59. cvar_t *r_ext_multitexture;
  60. cvar_t *r_ext_compiled_vertex_array;
  61. cvar_t *r_ext_texture_env_add;
  62. cvar_t *r_ignoreGLErrors;
  63. cvar_t *r_logFile;
  64. cvar_t *r_stencilbits;
  65. cvar_t *r_depthbits;
  66. cvar_t *r_colorbits;
  67. cvar_t *r_stereo;
  68. cvar_t *r_primitives;
  69. cvar_t *r_texturebits;
  70. cvar_t *r_drawBuffer;
  71. cvar_t *r_glDriver;
  72. cvar_t *r_lightmap;
  73. cvar_t *r_vertexLight;
  74. cvar_t *r_uiFullScreen;
  75. cvar_t *r_shadows;
  76. cvar_t *r_flares;
  77. cvar_t *r_mode;
  78. cvar_t *r_nobind;
  79. cvar_t *r_singleShader;
  80. cvar_t *r_roundImagesDown;
  81. cvar_t *r_colorMipLevels;
  82. cvar_t *r_picmip;
  83. cvar_t *r_showtris;
  84. cvar_t *r_showsky;
  85. cvar_t *r_shownormals;
  86. cvar_t *r_finish;
  87. cvar_t *r_clear;
  88. cvar_t *r_swapInterval;
  89. cvar_t *r_textureMode;
  90. cvar_t *r_offsetFactor;
  91. cvar_t *r_offsetUnits;
  92. cvar_t *r_gamma;
  93. cvar_t *r_intensity;
  94. cvar_t *r_lockpvs;
  95. cvar_t *r_noportals;
  96. cvar_t *r_portalOnly;
  97. cvar_t *r_subdivisions;
  98. cvar_t *r_lodCurveError;
  99. cvar_t *r_fullscreen;
  100. cvar_t *r_customwidth;
  101. cvar_t *r_customheight;
  102. cvar_t *r_customaspect;
  103. cvar_t *r_overBrightBits;
  104. cvar_t *r_mapOverBrightBits;
  105. cvar_t *r_debugSurface;
  106. cvar_t *r_simpleMipMaps;
  107. cvar_t *r_showImages;
  108. cvar_t *r_ambientScale;
  109. cvar_t *r_directedScale;
  110. cvar_t *r_debugLight;
  111. cvar_t *r_debugSort;
  112. cvar_t *r_printShaders;
  113. cvar_t *r_saveFontData;
  114. cvar_t *r_maxpolys;
  115. int max_polys;
  116. cvar_t *r_maxpolyverts;
  117. int max_polyverts;
  118. void ( APIENTRY * qglMultiTexCoord2fARB )( GLenum texture, GLfloat s, GLfloat t );
  119. void ( APIENTRY * qglActiveTextureARB )( GLenum texture );
  120. void ( APIENTRY * qglClientActiveTextureARB )( GLenum texture );
  121. void ( APIENTRY * qglLockArraysEXT)( GLint, GLint);
  122. void ( APIENTRY * qglUnlockArraysEXT) ( void );
  123. static void AssertCvarRange( cvar_t *cv, float minVal, float maxVal, qboolean shouldBeIntegral )
  124. {
  125. if ( shouldBeIntegral )
  126. {
  127. if ( ( int ) cv->value != cv->integer )
  128. {
  129. ri.Printf( PRINT_WARNING, "WARNING: cvar '%s' must be integral (%f)\n", cv->name, cv->value );
  130. ri.Cvar_Set( cv->name, va( "%d", cv->integer ) );
  131. }
  132. }
  133. if ( cv->value < minVal )
  134. {
  135. ri.Printf( PRINT_WARNING, "WARNING: cvar '%s' out of range (%f < %f)\n", cv->name, cv->value, minVal );
  136. ri.Cvar_Set( cv->name, va( "%f", minVal ) );
  137. }
  138. else if ( cv->value > maxVal )
  139. {
  140. ri.Printf( PRINT_WARNING, "WARNING: cvar '%s' out of range (%f > %f)\n", cv->name, cv->value, maxVal );
  141. ri.Cvar_Set( cv->name, va( "%f", maxVal ) );
  142. }
  143. }
  144. /*
  145. ** InitOpenGL
  146. **
  147. ** This function is responsible for initializing a valid OpenGL subsystem. This
  148. ** is done by calling GLimp_Init (which gives us a working OGL subsystem) then
  149. ** setting variables, checking GL constants, and reporting the gfx system config
  150. ** to the user.
  151. */
  152. static void InitOpenGL( void )
  153. {
  154. char renderer_buffer[1024];
  155. //
  156. // initialize OS specific portions of the renderer
  157. //
  158. // GLimp_Init directly or indirectly references the following cvars:
  159. // - r_fullscreen
  160. // - r_glDriver
  161. // - r_mode
  162. // - r_(color|depth|stencil)bits
  163. // - r_ignorehwgamma
  164. // - r_gamma
  165. //
  166. if ( glConfig.vidWidth == 0 )
  167. {
  168. GLint temp;
  169. GLimp_Init();
  170. strcpy( renderer_buffer, glConfig.renderer_string );
  171. Q_strlwr( renderer_buffer );
  172. // OpenGL driver constants
  173. qglGetIntegerv( GL_MAX_TEXTURE_SIZE, &temp );
  174. glConfig.maxTextureSize = temp;
  175. // stubbed or broken drivers may have reported 0...
  176. if ( glConfig.maxTextureSize <= 0 )
  177. {
  178. glConfig.maxTextureSize = 0;
  179. }
  180. }
  181. // init command buffers and SMP
  182. R_InitCommandBuffers();
  183. // print info
  184. GfxInfo_f();
  185. // set default state
  186. GL_SetDefaultState();
  187. }
  188. /*
  189. ==================
  190. GL_CheckErrors
  191. ==================
  192. */
  193. void GL_CheckErrors( void ) {
  194. int err;
  195. char s[64];
  196. err = qglGetError();
  197. if ( err == GL_NO_ERROR ) {
  198. return;
  199. }
  200. if ( r_ignoreGLErrors->integer ) {
  201. return;
  202. }
  203. switch( err ) {
  204. case GL_INVALID_ENUM:
  205. strcpy( s, "GL_INVALID_ENUM" );
  206. break;
  207. case GL_INVALID_VALUE:
  208. strcpy( s, "GL_INVALID_VALUE" );
  209. break;
  210. case GL_INVALID_OPERATION:
  211. strcpy( s, "GL_INVALID_OPERATION" );
  212. break;
  213. case GL_STACK_OVERFLOW:
  214. strcpy( s, "GL_STACK_OVERFLOW" );
  215. break;
  216. case GL_STACK_UNDERFLOW:
  217. strcpy( s, "GL_STACK_UNDERFLOW" );
  218. break;
  219. case GL_OUT_OF_MEMORY:
  220. strcpy( s, "GL_OUT_OF_MEMORY" );
  221. break;
  222. default:
  223. Com_sprintf( s, sizeof(s), "%i", err);
  224. break;
  225. }
  226. ri.Error( ERR_FATAL, "GL_CheckErrors: %s", s );
  227. }
  228. /*
  229. ** R_GetModeInfo
  230. */
  231. typedef struct vidmode_s
  232. {
  233. const char *description;
  234. int width, height;
  235. float pixelAspect; // pixel width / height
  236. } vidmode_t;
  237. vidmode_t r_vidModes[] =
  238. {
  239. { "Mode 0: 320x240", 320, 240, 1 },
  240. { "Mode 1: 400x300", 400, 300, 1 },
  241. { "Mode 2: 512x384", 512, 384, 1 },
  242. { "Mode 3: 640x480", 640, 480, 1 },
  243. { "Mode 4: 800x600", 800, 600, 1 },
  244. { "Mode 5: 960x720", 960, 720, 1 },
  245. { "Mode 6: 1024x768", 1024, 768, 1 },
  246. { "Mode 7: 1152x864", 1152, 864, 1 },
  247. { "Mode 8: 1280x1024", 1280, 1024, 1 },
  248. { "Mode 9: 1600x1200", 1600, 1200, 1 },
  249. { "Mode 10: 2048x1536", 2048, 1536, 1 },
  250. { "Mode 11: 856x480 (wide)",856, 480, 1 }
  251. };
  252. static int s_numVidModes = ( sizeof( r_vidModes ) / sizeof( r_vidModes[0] ) );
  253. qboolean R_GetModeInfo( int *width, int *height, float *windowAspect, int mode ) {
  254. vidmode_t *vm;
  255. if ( mode < -1 ) {
  256. return qfalse;
  257. }
  258. if ( mode >= s_numVidModes ) {
  259. return qfalse;
  260. }
  261. if ( mode == -1 ) {
  262. *width = r_customwidth->integer;
  263. *height = r_customheight->integer;
  264. *windowAspect = r_customaspect->value;
  265. return qtrue;
  266. }
  267. vm = &r_vidModes[mode];
  268. *width = vm->width;
  269. *height = vm->height;
  270. *windowAspect = (float)vm->width / ( vm->height * vm->pixelAspect );
  271. return qtrue;
  272. }
  273. /*
  274. ** R_ModeList_f
  275. */
  276. static void R_ModeList_f( void )
  277. {
  278. int i;
  279. ri.Printf( PRINT_ALL, "\n" );
  280. for ( i = 0; i < s_numVidModes; i++ )
  281. {
  282. ri.Printf( PRINT_ALL, "%s\n", r_vidModes[i].description );
  283. }
  284. ri.Printf( PRINT_ALL, "\n" );
  285. }
  286. /*
  287. ==============================================================================
  288. SCREEN SHOTS
  289. NOTE TTimo
  290. some thoughts about the screenshots system:
  291. screenshots get written in fs_homepath + fs_gamedir
  292. vanilla q3 .. baseq3/screenshots/ *.tga
  293. team arena .. missionpack/screenshots/ *.tga
  294. two commands: "screenshot" and "screenshotJPEG"
  295. we use statics to store a count and start writing the first screenshot/screenshot????.tga (.jpg) available
  296. (with FS_FileExists / FS_FOpenFileWrite calls)
  297. FIXME: the statics don't get a reinit between fs_game changes
  298. ==============================================================================
  299. */
  300. /*
  301. ==================
  302. RB_TakeScreenshot
  303. ==================
  304. */
  305. void RB_TakeScreenshot( int x, int y, int width, int height, char *fileName ) {
  306. byte *buffer;
  307. int i, c, temp;
  308. buffer = ri.Hunk_AllocateTempMemory(glConfig.vidWidth*glConfig.vidHeight*3+18);
  309. Com_Memset (buffer, 0, 18);
  310. buffer[2] = 2; // uncompressed type
  311. buffer[12] = width & 255;
  312. buffer[13] = width >> 8;
  313. buffer[14] = height & 255;
  314. buffer[15] = height >> 8;
  315. buffer[16] = 24; // pixel size
  316. qglReadPixels( x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer+18 );
  317. // swap rgb to bgr
  318. c = 18 + width * height * 3;
  319. for (i=18 ; i<c ; i+=3) {
  320. temp = buffer[i];
  321. buffer[i] = buffer[i+2];
  322. buffer[i+2] = temp;
  323. }
  324. // gamma correct
  325. if ( ( tr.overbrightBits > 0 ) && glConfig.deviceSupportsGamma ) {
  326. R_GammaCorrect( buffer + 18, glConfig.vidWidth * glConfig.vidHeight * 3 );
  327. }
  328. ri.FS_WriteFile( fileName, buffer, c );
  329. ri.Hunk_FreeTempMemory( buffer );
  330. }
  331. /*
  332. ==================
  333. RB_TakeScreenshotJPEG
  334. ==================
  335. */
  336. void RB_TakeScreenshotJPEG( int x, int y, int width, int height, char *fileName ) {
  337. byte *buffer;
  338. buffer = ri.Hunk_AllocateTempMemory(glConfig.vidWidth*glConfig.vidHeight*4);
  339. qglReadPixels( x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer );
  340. // gamma correct
  341. if ( ( tr.overbrightBits > 0 ) && glConfig.deviceSupportsGamma ) {
  342. R_GammaCorrect( buffer, glConfig.vidWidth * glConfig.vidHeight * 4 );
  343. }
  344. ri.FS_WriteFile( fileName, buffer, 1 ); // create path
  345. SaveJPG( fileName, 95, glConfig.vidWidth, glConfig.vidHeight, buffer);
  346. ri.Hunk_FreeTempMemory( buffer );
  347. }
  348. /*
  349. ==================
  350. RB_TakeScreenshotCmd
  351. ==================
  352. */
  353. const void *RB_TakeScreenshotCmd( const void *data ) {
  354. const screenshotCommand_t *cmd;
  355. cmd = (const screenshotCommand_t *)data;
  356. if (cmd->jpeg)
  357. RB_TakeScreenshotJPEG( cmd->x, cmd->y, cmd->width, cmd->height, cmd->fileName);
  358. else
  359. RB_TakeScreenshot( cmd->x, cmd->y, cmd->width, cmd->height, cmd->fileName);
  360. return (const void *)(cmd + 1);
  361. }
  362. /*
  363. ==================
  364. R_TakeScreenshot
  365. ==================
  366. */
  367. void R_TakeScreenshot( int x, int y, int width, int height, char *name, qboolean jpeg ) {
  368. static char fileName[MAX_OSPATH]; // bad things if two screenshots per frame?
  369. screenshotCommand_t *cmd;
  370. cmd = R_GetCommandBuffer( sizeof( *cmd ) );
  371. if ( !cmd ) {
  372. return;
  373. }
  374. cmd->commandId = RC_SCREENSHOT;
  375. cmd->x = x;
  376. cmd->y = y;
  377. cmd->width = width;
  378. cmd->height = height;
  379. Q_strncpyz( fileName, name, sizeof(fileName) );
  380. cmd->fileName = fileName;
  381. cmd->jpeg = jpeg;
  382. }
  383. /*
  384. ==================
  385. R_ScreenshotFilename
  386. ==================
  387. */
  388. void R_ScreenshotFilename( int lastNumber, char *fileName ) {
  389. int a,b,c,d;
  390. if ( lastNumber < 0 || lastNumber > 9999 ) {
  391. Com_sprintf( fileName, MAX_OSPATH, "screenshots/shot9999.tga" );
  392. return;
  393. }
  394. a = lastNumber / 1000;
  395. lastNumber -= a*1000;
  396. b = lastNumber / 100;
  397. lastNumber -= b*100;
  398. c = lastNumber / 10;
  399. lastNumber -= c*10;
  400. d = lastNumber;
  401. Com_sprintf( fileName, MAX_OSPATH, "screenshots/shot%i%i%i%i.tga"
  402. , a, b, c, d );
  403. }
  404. /*
  405. ==================
  406. R_ScreenshotFilename
  407. ==================
  408. */
  409. void R_ScreenshotFilenameJPEG( int lastNumber, char *fileName ) {
  410. int a,b,c,d;
  411. if ( lastNumber < 0 || lastNumber > 9999 ) {
  412. Com_sprintf( fileName, MAX_OSPATH, "screenshots/shot9999.jpg" );
  413. return;
  414. }
  415. a = lastNumber / 1000;
  416. lastNumber -= a*1000;
  417. b = lastNumber / 100;
  418. lastNumber -= b*100;
  419. c = lastNumber / 10;
  420. lastNumber -= c*10;
  421. d = lastNumber;
  422. Com_sprintf( fileName, MAX_OSPATH, "screenshots/shot%i%i%i%i.jpg"
  423. , a, b, c, d );
  424. }
  425. /*
  426. ====================
  427. R_LevelShot
  428. levelshots are specialized 128*128 thumbnails for
  429. the menu system, sampled down from full screen distorted images
  430. ====================
  431. */
  432. void R_LevelShot( void ) {
  433. char checkname[MAX_OSPATH];
  434. byte *buffer;
  435. byte *source;
  436. byte *src, *dst;
  437. int x, y;
  438. int r, g, b;
  439. float xScale, yScale;
  440. int xx, yy;
  441. sprintf( checkname, "levelshots/%s.tga", tr.world->baseName );
  442. source = ri.Hunk_AllocateTempMemory( glConfig.vidWidth * glConfig.vidHeight * 3 );
  443. buffer = ri.Hunk_AllocateTempMemory( 128 * 128*3 + 18);
  444. Com_Memset (buffer, 0, 18);
  445. buffer[2] = 2; // uncompressed type
  446. buffer[12] = 128;
  447. buffer[14] = 128;
  448. buffer[16] = 24; // pixel size
  449. qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_RGB, GL_UNSIGNED_BYTE, source );
  450. // resample from source
  451. xScale = glConfig.vidWidth / 512.0f;
  452. yScale = glConfig.vidHeight / 384.0f;
  453. for ( y = 0 ; y < 128 ; y++ ) {
  454. for ( x = 0 ; x < 128 ; x++ ) {
  455. r = g = b = 0;
  456. for ( yy = 0 ; yy < 3 ; yy++ ) {
  457. for ( xx = 0 ; xx < 4 ; xx++ ) {
  458. src = source + 3 * ( glConfig.vidWidth * (int)( (y*3+yy)*yScale ) + (int)( (x*4+xx)*xScale ) );
  459. r += src[0];
  460. g += src[1];
  461. b += src[2];
  462. }
  463. }
  464. dst = buffer + 18 + 3 * ( y * 128 + x );
  465. dst[0] = b / 12;
  466. dst[1] = g / 12;
  467. dst[2] = r / 12;
  468. }
  469. }
  470. // gamma correct
  471. if ( ( tr.overbrightBits > 0 ) && glConfig.deviceSupportsGamma ) {
  472. R_GammaCorrect( buffer + 18, 128 * 128 * 3 );
  473. }
  474. ri.FS_WriteFile( checkname, buffer, 128 * 128*3 + 18 );
  475. ri.Hunk_FreeTempMemory( buffer );
  476. ri.Hunk_FreeTempMemory( source );
  477. ri.Printf( PRINT_ALL, "Wrote %s\n", checkname );
  478. }
  479. /*
  480. ==================
  481. R_ScreenShot_f
  482. screenshot
  483. screenshot [silent]
  484. screenshot [levelshot]
  485. screenshot [filename]
  486. Doesn't print the pacifier message if there is a second arg
  487. ==================
  488. */
  489. void R_ScreenShot_f (void) {
  490. char checkname[MAX_OSPATH];
  491. static int lastNumber = -1;
  492. qboolean silent;
  493. if ( !strcmp( ri.Cmd_Argv(1), "levelshot" ) ) {
  494. R_LevelShot();
  495. return;
  496. }
  497. if ( !strcmp( ri.Cmd_Argv(1), "silent" ) ) {
  498. silent = qtrue;
  499. } else {
  500. silent = qfalse;
  501. }
  502. if ( ri.Cmd_Argc() == 2 && !silent ) {
  503. // explicit filename
  504. Com_sprintf( checkname, MAX_OSPATH, "screenshots/%s.tga", ri.Cmd_Argv( 1 ) );
  505. } else {
  506. // scan for a free filename
  507. // if we have saved a previous screenshot, don't scan
  508. // again, because recording demo avis can involve
  509. // thousands of shots
  510. if ( lastNumber == -1 ) {
  511. lastNumber = 0;
  512. }
  513. // scan for a free number
  514. for ( ; lastNumber <= 9999 ; lastNumber++ ) {
  515. R_ScreenshotFilename( lastNumber, checkname );
  516. if (!ri.FS_FileExists( checkname ))
  517. {
  518. break; // file doesn't exist
  519. }
  520. }
  521. if ( lastNumber >= 9999 ) {
  522. ri.Printf (PRINT_ALL, "ScreenShot: Couldn't create a file\n");
  523. return;
  524. }
  525. lastNumber++;
  526. }
  527. R_TakeScreenshot( 0, 0, glConfig.vidWidth, glConfig.vidHeight, checkname, qfalse );
  528. if ( !silent ) {
  529. ri.Printf (PRINT_ALL, "Wrote %s\n", checkname);
  530. }
  531. }
  532. void R_ScreenShotJPEG_f (void) {
  533. char checkname[MAX_OSPATH];
  534. static int lastNumber = -1;
  535. qboolean silent;
  536. if ( !strcmp( ri.Cmd_Argv(1), "levelshot" ) ) {
  537. R_LevelShot();
  538. return;
  539. }
  540. if ( !strcmp( ri.Cmd_Argv(1), "silent" ) ) {
  541. silent = qtrue;
  542. } else {
  543. silent = qfalse;
  544. }
  545. if ( ri.Cmd_Argc() == 2 && !silent ) {
  546. // explicit filename
  547. Com_sprintf( checkname, MAX_OSPATH, "screenshots/%s.jpg", ri.Cmd_Argv( 1 ) );
  548. } else {
  549. // scan for a free filename
  550. // if we have saved a previous screenshot, don't scan
  551. // again, because recording demo avis can involve
  552. // thousands of shots
  553. if ( lastNumber == -1 ) {
  554. lastNumber = 0;
  555. }
  556. // scan for a free number
  557. for ( ; lastNumber <= 9999 ; lastNumber++ ) {
  558. R_ScreenshotFilenameJPEG( lastNumber, checkname );
  559. if (!ri.FS_FileExists( checkname ))
  560. {
  561. break; // file doesn't exist
  562. }
  563. }
  564. if ( lastNumber == 10000 ) {
  565. ri.Printf (PRINT_ALL, "ScreenShot: Couldn't create a file\n");
  566. return;
  567. }
  568. lastNumber++;
  569. }
  570. R_TakeScreenshot( 0, 0, glConfig.vidWidth, glConfig.vidHeight, checkname, qtrue );
  571. if ( !silent ) {
  572. ri.Printf (PRINT_ALL, "Wrote %s\n", checkname);
  573. }
  574. }
  575. //============================================================================
  576. /*
  577. ** GL_SetDefaultState
  578. */
  579. void GL_SetDefaultState( void )
  580. {
  581. qglClearDepth( 1.0f );
  582. qglCullFace(GL_FRONT);
  583. qglColor4f (1,1,1,1);
  584. // initialize downstream texture unit if we're running
  585. // in a multitexture environment
  586. if ( qglActiveTextureARB ) {
  587. GL_SelectTexture( 1 );
  588. GL_TextureMode( r_textureMode->string );
  589. GL_TexEnv( GL_MODULATE );
  590. qglDisable( GL_TEXTURE_2D );
  591. GL_SelectTexture( 0 );
  592. }
  593. qglEnable(GL_TEXTURE_2D);
  594. GL_TextureMode( r_textureMode->string );
  595. GL_TexEnv( GL_MODULATE );
  596. qglShadeModel( GL_SMOOTH );
  597. qglDepthFunc( GL_LEQUAL );
  598. // the vertex array is always enabled, but the color and texture
  599. // arrays are enabled and disabled around the compiled vertex array call
  600. qglEnableClientState (GL_VERTEX_ARRAY);
  601. //
  602. // make sure our GL state vector is set correctly
  603. //
  604. glState.glStateBits = GLS_DEPTHTEST_DISABLE | GLS_DEPTHMASK_TRUE;
  605. qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
  606. qglDepthMask( GL_TRUE );
  607. qglDisable( GL_DEPTH_TEST );
  608. qglEnable( GL_SCISSOR_TEST );
  609. qglDisable( GL_CULL_FACE );
  610. qglDisable( GL_BLEND );
  611. }
  612. /*
  613. ================
  614. GfxInfo_f
  615. ================
  616. */
  617. void GfxInfo_f( void )
  618. {
  619. cvar_t *sys_cpustring = ri.Cvar_Get( "sys_cpustring", "", 0 );
  620. const char *enablestrings[] =
  621. {
  622. "disabled",
  623. "enabled"
  624. };
  625. const char *fsstrings[] =
  626. {
  627. "windowed",
  628. "fullscreen"
  629. };
  630. ri.Printf( PRINT_ALL, "\nGL_VENDOR: %s\n", glConfig.vendor_string );
  631. ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glConfig.renderer_string );
  632. ri.Printf( PRINT_ALL, "GL_VERSION: %s\n", glConfig.version_string );
  633. ri.Printf( PRINT_ALL, "GL_EXTENSIONS: %s\n", glConfig.extensions_string );
  634. ri.Printf( PRINT_ALL, "GL_MAX_TEXTURE_SIZE: %d\n", glConfig.maxTextureSize );
  635. ri.Printf( PRINT_ALL, "GL_MAX_ACTIVE_TEXTURES_ARB: %d\n", glConfig.maxActiveTextures );
  636. ri.Printf( PRINT_ALL, "\nPIXELFORMAT: color(%d-bits) Z(%d-bit) stencil(%d-bits)\n", glConfig.colorBits, glConfig.depthBits, glConfig.stencilBits );
  637. ri.Printf( PRINT_ALL, "MODE: %d, %d x %d %s hz:", r_mode->integer, glConfig.vidWidth, glConfig.vidHeight, fsstrings[r_fullscreen->integer == 1] );
  638. if ( glConfig.displayFrequency )
  639. {
  640. ri.Printf( PRINT_ALL, "%d\n", glConfig.displayFrequency );
  641. }
  642. else
  643. {
  644. ri.Printf( PRINT_ALL, "N/A\n" );
  645. }
  646. if ( glConfig.deviceSupportsGamma )
  647. {
  648. ri.Printf( PRINT_ALL, "GAMMA: hardware w/ %d overbright bits\n", tr.overbrightBits );
  649. }
  650. else
  651. {
  652. ri.Printf( PRINT_ALL, "GAMMA: software w/ %d overbright bits\n", tr.overbrightBits );
  653. }
  654. ri.Printf( PRINT_ALL, "CPU: %s\n", sys_cpustring->string );
  655. // rendering primitives
  656. {
  657. int primitives;
  658. // default is to use triangles if compiled vertex arrays are present
  659. ri.Printf( PRINT_ALL, "rendering primitives: " );
  660. primitives = r_primitives->integer;
  661. if ( primitives == 0 ) {
  662. if ( qglLockArraysEXT ) {
  663. primitives = 2;
  664. } else {
  665. primitives = 1;
  666. }
  667. }
  668. if ( primitives == -1 ) {
  669. ri.Printf( PRINT_ALL, "none\n" );
  670. } else if ( primitives == 2 ) {
  671. ri.Printf( PRINT_ALL, "single glDrawElements\n" );
  672. } else if ( primitives == 1 ) {
  673. ri.Printf( PRINT_ALL, "multiple glArrayElement\n" );
  674. } else if ( primitives == 3 ) {
  675. ri.Printf( PRINT_ALL, "multiple glColor4ubv + glTexCoord2fv + glVertex3fv\n" );
  676. }
  677. }
  678. ri.Printf( PRINT_ALL, "texturemode: %s\n", r_textureMode->string );
  679. ri.Printf( PRINT_ALL, "picmip: %d\n", r_picmip->integer );
  680. ri.Printf( PRINT_ALL, "texture bits: %d\n", r_texturebits->integer );
  681. ri.Printf( PRINT_ALL, "multitexture: %s\n", enablestrings[qglActiveTextureARB != 0] );
  682. ri.Printf( PRINT_ALL, "compiled vertex arrays: %s\n", enablestrings[qglLockArraysEXT != 0 ] );
  683. ri.Printf( PRINT_ALL, "texenv add: %s\n", enablestrings[glConfig.textureEnvAddAvailable != 0] );
  684. ri.Printf( PRINT_ALL, "compressed textures: %s\n", enablestrings[glConfig.textureCompression!=TC_NONE] );
  685. if ( r_vertexLight->integer || glConfig.hardwareType == GLHW_PERMEDIA2 )
  686. {
  687. ri.Printf( PRINT_ALL, "HACK: using vertex lightmap approximation\n" );
  688. }
  689. if ( glConfig.hardwareType == GLHW_RAGEPRO )
  690. {
  691. ri.Printf( PRINT_ALL, "HACK: ragePro approximations\n" );
  692. }
  693. if ( glConfig.hardwareType == GLHW_RIVA128 )
  694. {
  695. ri.Printf( PRINT_ALL, "HACK: riva128 approximations\n" );
  696. }
  697. if ( glConfig.smpActive ) {
  698. ri.Printf( PRINT_ALL, "Using dual processor acceleration\n" );
  699. }
  700. if ( r_finish->integer ) {
  701. ri.Printf( PRINT_ALL, "Forcing glFinish\n" );
  702. }
  703. }
  704. /*
  705. ===============
  706. R_Register
  707. ===============
  708. */
  709. void R_Register( void )
  710. {
  711. //
  712. // latched and archived variables
  713. //
  714. r_glDriver = ri.Cvar_Get( "r_glDriver", OPENGL_DRIVER_NAME, CVAR_ARCHIVE | CVAR_LATCH );
  715. r_allowExtensions = ri.Cvar_Get( "r_allowExtensions", "1", CVAR_ARCHIVE | CVAR_LATCH );
  716. r_ext_compressed_textures = ri.Cvar_Get( "r_ext_compressed_textures", "0", CVAR_ARCHIVE | CVAR_LATCH );
  717. r_ext_gamma_control = ri.Cvar_Get( "r_ext_gamma_control", "1", CVAR_ARCHIVE | CVAR_LATCH );
  718. r_ext_multitexture = ri.Cvar_Get( "r_ext_multitexture", "1", CVAR_ARCHIVE | CVAR_LATCH );
  719. r_ext_compiled_vertex_array = ri.Cvar_Get( "r_ext_compiled_vertex_array", "1", CVAR_ARCHIVE | CVAR_LATCH);
  720. #ifdef __linux__ // broken on linux
  721. r_ext_texture_env_add = ri.Cvar_Get( "r_ext_texture_env_add", "0", CVAR_ARCHIVE | CVAR_LATCH);
  722. #else
  723. r_ext_texture_env_add = ri.Cvar_Get( "r_ext_texture_env_add", "1", CVAR_ARCHIVE | CVAR_LATCH);
  724. #endif
  725. r_picmip = ri.Cvar_Get ("r_picmip", "1", CVAR_ARCHIVE | CVAR_LATCH );
  726. r_roundImagesDown = ri.Cvar_Get ("r_roundImagesDown", "1", CVAR_ARCHIVE | CVAR_LATCH );
  727. r_colorMipLevels = ri.Cvar_Get ("r_colorMipLevels", "0", CVAR_LATCH );
  728. AssertCvarRange( r_picmip, 0, 16, qtrue );
  729. r_detailTextures = ri.Cvar_Get( "r_detailtextures", "1", CVAR_ARCHIVE | CVAR_LATCH );
  730. r_texturebits = ri.Cvar_Get( "r_texturebits", "0", CVAR_ARCHIVE | CVAR_LATCH );
  731. r_colorbits = ri.Cvar_Get( "r_colorbits", "0", CVAR_ARCHIVE | CVAR_LATCH );
  732. r_stereo = ri.Cvar_Get( "r_stereo", "0", CVAR_ARCHIVE | CVAR_LATCH );
  733. #ifdef __linux__
  734. r_stencilbits = ri.Cvar_Get( "r_stencilbits", "0", CVAR_ARCHIVE | CVAR_LATCH );
  735. #else
  736. r_stencilbits = ri.Cvar_Get( "r_stencilbits", "8", CVAR_ARCHIVE | CVAR_LATCH );
  737. #endif
  738. r_depthbits = ri.Cvar_Get( "r_depthbits", "0", CVAR_ARCHIVE | CVAR_LATCH );
  739. r_overBrightBits = ri.Cvar_Get ("r_overBrightBits", "1", CVAR_ARCHIVE | CVAR_LATCH );
  740. r_ignorehwgamma = ri.Cvar_Get( "r_ignorehwgamma", "0", CVAR_ARCHIVE | CVAR_LATCH);
  741. r_mode = ri.Cvar_Get( "r_mode", "3", CVAR_ARCHIVE | CVAR_LATCH );
  742. r_fullscreen = ri.Cvar_Get( "r_fullscreen", "1", CVAR_ARCHIVE | CVAR_LATCH );
  743. r_customwidth = ri.Cvar_Get( "r_customwidth", "1600", CVAR_ARCHIVE | CVAR_LATCH );
  744. r_customheight = ri.Cvar_Get( "r_customheight", "1024", CVAR_ARCHIVE | CVAR_LATCH );
  745. r_customaspect = ri.Cvar_Get( "r_customaspect", "1", CVAR_ARCHIVE | CVAR_LATCH );
  746. r_simpleMipMaps = ri.Cvar_Get( "r_simpleMipMaps", "1", CVAR_ARCHIVE | CVAR_LATCH );
  747. r_vertexLight = ri.Cvar_Get( "r_vertexLight", "0", CVAR_ARCHIVE | CVAR_LATCH );
  748. r_uiFullScreen = ri.Cvar_Get( "r_uifullscreen", "0", 0);
  749. r_subdivisions = ri.Cvar_Get ("r_subdivisions", "4", CVAR_ARCHIVE | CVAR_LATCH);
  750. #if (defined(MACOS_X) || defined(__linux__)) && defined(SMP)
  751. // Default to using SMP on Mac OS X or Linux if we have multiple processors
  752. r_smp = ri.Cvar_Get( "r_smp", Sys_ProcessorCount() > 1 ? "1" : "0", CVAR_ARCHIVE | CVAR_LATCH);
  753. #else
  754. r_smp = ri.Cvar_Get( "r_smp", "0", CVAR_ARCHIVE | CVAR_LATCH);
  755. #endif
  756. r_ignoreFastPath = ri.Cvar_Get( "r_ignoreFastPath", "1", CVAR_ARCHIVE | CVAR_LATCH );
  757. //
  758. // temporary latched variables that can only change over a restart
  759. //
  760. r_displayRefresh = ri.Cvar_Get( "r_displayRefresh", "0", CVAR_LATCH );
  761. AssertCvarRange( r_displayRefresh, 0, 200, qtrue );
  762. r_fullbright = ri.Cvar_Get ("r_fullbright", "0", CVAR_LATCH|CVAR_CHEAT );
  763. r_mapOverBrightBits = ri.Cvar_Get ("r_mapOverBrightBits", "2", CVAR_LATCH );
  764. r_intensity = ri.Cvar_Get ("r_intensity", "1", CVAR_LATCH );
  765. r_singleShader = ri.Cvar_Get ("r_singleShader", "0", CVAR_CHEAT | CVAR_LATCH );
  766. //
  767. // archived variables that can change at any time
  768. //
  769. r_lodCurveError = ri.Cvar_Get( "r_lodCurveError", "250", CVAR_ARCHIVE|CVAR_CHEAT );
  770. r_lodbias = ri.Cvar_Get( "r_lodbias", "0", CVAR_ARCHIVE );
  771. r_flares = ri.Cvar_Get ("r_flares", "0", CVAR_ARCHIVE );
  772. r_znear = ri.Cvar_Get( "r_znear", "4", CVAR_CHEAT );
  773. AssertCvarRange( r_znear, 0.001f, 200, qtrue );
  774. r_ignoreGLErrors = ri.Cvar_Get( "r_ignoreGLErrors", "1", CVAR_ARCHIVE );
  775. r_fastsky = ri.Cvar_Get( "r_fastsky", "0", CVAR_ARCHIVE );
  776. r_inGameVideo = ri.Cvar_Get( "r_inGameVideo", "1", CVAR_ARCHIVE );
  777. r_drawSun = ri.Cvar_Get( "r_drawSun", "0", CVAR_ARCHIVE );
  778. r_dynamiclight = ri.Cvar_Get( "r_dynamiclight", "1", CVAR_ARCHIVE );
  779. r_dlightBacks = ri.Cvar_Get( "r_dlightBacks", "1", CVAR_ARCHIVE );
  780. r_finish = ri.Cvar_Get ("r_finish", "0", CVAR_ARCHIVE);
  781. r_textureMode = ri.Cvar_Get( "r_textureMode", "GL_LINEAR_MIPMAP_NEAREST", CVAR_ARCHIVE );
  782. r_swapInterval = ri.Cvar_Get( "r_swapInterval", "0", CVAR_ARCHIVE );
  783. #ifdef __MACOS__
  784. r_gamma = ri.Cvar_Get( "r_gamma", "1.2", CVAR_ARCHIVE );
  785. #else
  786. r_gamma = ri.Cvar_Get( "r_gamma", "1", CVAR_ARCHIVE );
  787. #endif
  788. r_facePlaneCull = ri.Cvar_Get ("r_facePlaneCull", "1", CVAR_ARCHIVE );
  789. r_railWidth = ri.Cvar_Get( "r_railWidth", "16", CVAR_ARCHIVE );
  790. r_railCoreWidth = ri.Cvar_Get( "r_railCoreWidth", "6", CVAR_ARCHIVE );
  791. r_railSegmentLength = ri.Cvar_Get( "r_railSegmentLength", "32", CVAR_ARCHIVE );
  792. r_primitives = ri.Cvar_Get( "r_primitives", "0", CVAR_ARCHIVE );
  793. r_ambientScale = ri.Cvar_Get( "r_ambientScale", "0.6", CVAR_CHEAT );
  794. r_directedScale = ri.Cvar_Get( "r_directedScale", "1", CVAR_CHEAT );
  795. //
  796. // temporary variables that can change at any time
  797. //
  798. r_showImages = ri.Cvar_Get( "r_showImages", "0", CVAR_TEMP );
  799. r_debugLight = ri.Cvar_Get( "r_debuglight", "0", CVAR_TEMP );
  800. r_debugSort = ri.Cvar_Get( "r_debugSort", "0", CVAR_CHEAT );
  801. r_printShaders = ri.Cvar_Get( "r_printShaders", "0", 0 );
  802. r_saveFontData = ri.Cvar_Get( "r_saveFontData", "0", 0 );
  803. r_nocurves = ri.Cvar_Get ("r_nocurves", "0", CVAR_CHEAT );
  804. r_drawworld = ri.Cvar_Get ("r_drawworld", "1", CVAR_CHEAT );
  805. r_lightmap = ri.Cvar_Get ("r_lightmap", "0", 0 );
  806. r_portalOnly = ri.Cvar_Get ("r_portalOnly", "0", CVAR_CHEAT );
  807. r_flareSize = ri.Cvar_Get ("r_flareSize", "40", CVAR_CHEAT);
  808. r_flareFade = ri.Cvar_Get ("r_flareFade", "7", CVAR_CHEAT);
  809. r_showSmp = ri.Cvar_Get ("r_showSmp", "0", CVAR_CHEAT);
  810. r_skipBackEnd = ri.Cvar_Get ("r_skipBackEnd", "0", CVAR_CHEAT);
  811. r_measureOverdraw = ri.Cvar_Get( "r_measureOverdraw", "0", CVAR_CHEAT );
  812. r_lodscale = ri.Cvar_Get( "r_lodscale", "5", CVAR_CHEAT );
  813. r_norefresh = ri.Cvar_Get ("r_norefresh", "0", CVAR_CHEAT);
  814. r_drawentities = ri.Cvar_Get ("r_drawentities", "1", CVAR_CHEAT );
  815. r_ignore = ri.Cvar_Get( "r_ignore", "1", CVAR_CHEAT );
  816. r_nocull = ri.Cvar_Get ("r_nocull", "0", CVAR_CHEAT);
  817. r_novis = ri.Cvar_Get ("r_novis", "0", CVAR_CHEAT);
  818. r_showcluster = ri.Cvar_Get ("r_showcluster", "0", CVAR_CHEAT);
  819. r_speeds = ri.Cvar_Get ("r_speeds", "0", CVAR_CHEAT);
  820. r_verbose = ri.Cvar_Get( "r_verbose", "0", CVAR_CHEAT );
  821. r_logFile = ri.Cvar_Get( "r_logFile", "0", CVAR_CHEAT );
  822. r_debugSurface = ri.Cvar_Get ("r_debugSurface", "0", CVAR_CHEAT);
  823. r_nobind = ri.Cvar_Get ("r_nobind", "0", CVAR_CHEAT);
  824. r_showtris = ri.Cvar_Get ("r_showtris", "0", CVAR_CHEAT);
  825. r_showsky = ri.Cvar_Get ("r_showsky", "0", CVAR_CHEAT);
  826. r_shownormals = ri.Cvar_Get ("r_shownormals", "0", CVAR_CHEAT);
  827. r_clear = ri.Cvar_Get ("r_clear", "0", CVAR_CHEAT);
  828. r_offsetFactor = ri.Cvar_Get( "r_offsetfactor", "-1", CVAR_CHEAT );
  829. r_offsetUnits = ri.Cvar_Get( "r_offsetunits", "-2", CVAR_CHEAT );
  830. r_drawBuffer = ri.Cvar_Get( "r_drawBuffer", "GL_BACK", CVAR_CHEAT );
  831. r_lockpvs = ri.Cvar_Get ("r_lockpvs", "0", CVAR_CHEAT);
  832. r_noportals = ri.Cvar_Get ("r_noportals", "0", CVAR_CHEAT);
  833. r_shadows = ri.Cvar_Get( "cg_shadows", "1", 0 );
  834. r_maxpolys = ri.Cvar_Get( "r_maxpolys", va("%d", MAX_POLYS), 0);
  835. r_maxpolyverts = ri.Cvar_Get( "r_maxpolyverts", va("%d", MAX_POLYVERTS), 0);
  836. // make sure all the commands added here are also
  837. // removed in R_Shutdown
  838. ri.Cmd_AddCommand( "imagelist", R_ImageList_f );
  839. ri.Cmd_AddCommand( "shaderlist", R_ShaderList_f );
  840. ri.Cmd_AddCommand( "skinlist", R_SkinList_f );
  841. ri.Cmd_AddCommand( "modellist", R_Modellist_f );
  842. ri.Cmd_AddCommand( "modelist", R_ModeList_f );
  843. ri.Cmd_AddCommand( "screenshot", R_ScreenShot_f );
  844. ri.Cmd_AddCommand( "screenshotJPEG", R_ScreenShotJPEG_f );
  845. ri.Cmd_AddCommand( "gfxinfo", GfxInfo_f );
  846. }
  847. /*
  848. ===============
  849. R_Init
  850. ===============
  851. */
  852. void R_Init( void ) {
  853. int err;
  854. int i;
  855. byte *ptr;
  856. ri.Printf( PRINT_ALL, "----- R_Init -----\n" );
  857. // clear all our internal state
  858. Com_Memset( &tr, 0, sizeof( tr ) );
  859. Com_Memset( &backEnd, 0, sizeof( backEnd ) );
  860. Com_Memset( &tess, 0, sizeof( tess ) );
  861. // Swap_Init();
  862. if ( (int)tess.xyz & 15 ) {
  863. Com_Printf( "WARNING: tess.xyz not 16 byte aligned\n" );
  864. }
  865. Com_Memset( tess.constantColor255, 255, sizeof( tess.constantColor255 ) );
  866. //
  867. // init function tables
  868. //
  869. for ( i = 0; i < FUNCTABLE_SIZE; i++ )
  870. {
  871. tr.sinTable[i] = sin( DEG2RAD( i * 360.0f / ( ( float ) ( FUNCTABLE_SIZE - 1 ) ) ) );
  872. tr.squareTable[i] = ( i < FUNCTABLE_SIZE/2 ) ? 1.0f : -1.0f;
  873. tr.sawToothTable[i] = (float)i / FUNCTABLE_SIZE;
  874. tr.inverseSawToothTable[i] = 1.0f - tr.sawToothTable[i];
  875. if ( i < FUNCTABLE_SIZE / 2 )
  876. {
  877. if ( i < FUNCTABLE_SIZE / 4 )
  878. {
  879. tr.triangleTable[i] = ( float ) i / ( FUNCTABLE_SIZE / 4 );
  880. }
  881. else
  882. {
  883. tr.triangleTable[i] = 1.0f - tr.triangleTable[i-FUNCTABLE_SIZE / 4];
  884. }
  885. }
  886. else
  887. {
  888. tr.triangleTable[i] = -tr.triangleTable[i-FUNCTABLE_SIZE/2];
  889. }
  890. }
  891. R_InitFogTable();
  892. R_NoiseInit();
  893. R_Register();
  894. max_polys = r_maxpolys->integer;
  895. if (max_polys < MAX_POLYS)
  896. max_polys = MAX_POLYS;
  897. max_polyverts = r_maxpolyverts->integer;
  898. if (max_polyverts < MAX_POLYVERTS)
  899. max_polyverts = MAX_POLYVERTS;
  900. ptr = ri.Hunk_Alloc( sizeof( *backEndData[0] ) + sizeof(srfPoly_t) * max_polys + sizeof(polyVert_t) * max_polyverts, h_low);
  901. backEndData[0] = (backEndData_t *) ptr;
  902. backEndData[0]->polys = (srfPoly_t *) ((char *) ptr + sizeof( *backEndData[0] ));
  903. backEndData[0]->polyVerts = (polyVert_t *) ((char *) ptr + sizeof( *backEndData[0] ) + sizeof(srfPoly_t) * max_polys);
  904. if ( r_smp->integer ) {
  905. ptr = ri.Hunk_Alloc( sizeof( *backEndData[1] ) + sizeof(srfPoly_t) * max_polys + sizeof(polyVert_t) * max_polyverts, h_low);
  906. backEndData[1] = (backEndData_t *) ptr;
  907. backEndData[1]->polys = (srfPoly_t *) ((char *) ptr + sizeof( *backEndData[1] ));
  908. backEndData[1]->polyVerts = (polyVert_t *) ((char *) ptr + sizeof( *backEndData[1] ) + sizeof(srfPoly_t) * max_polys);
  909. } else {
  910. backEndData[1] = NULL;
  911. }
  912. R_ToggleSmpFrame();
  913. InitOpenGL();
  914. R_InitImages();
  915. R_InitShaders();
  916. R_InitSkins();
  917. R_ModelInit();
  918. R_InitFreeType();
  919. err = qglGetError();
  920. if ( err != GL_NO_ERROR )
  921. ri.Printf (PRINT_ALL, "glGetError() = 0x%x\n", err);
  922. ri.Printf( PRINT_ALL, "----- finished R_Init -----\n" );
  923. }
  924. /*
  925. ===============
  926. RE_Shutdown
  927. ===============
  928. */
  929. void RE_Shutdown( qboolean destroyWindow ) {
  930. ri.Printf( PRINT_ALL, "RE_Shutdown( %i )\n", destroyWindow );
  931. ri.Cmd_RemoveCommand ("modellist");
  932. ri.Cmd_RemoveCommand ("screenshotJPEG");
  933. ri.Cmd_RemoveCommand ("screenshot");
  934. ri.Cmd_RemoveCommand ("imagelist");
  935. ri.Cmd_RemoveCommand ("shaderlist");
  936. ri.Cmd_RemoveCommand ("skinlist");
  937. ri.Cmd_RemoveCommand ("gfxinfo");
  938. ri.Cmd_RemoveCommand( "modelist" );
  939. ri.Cmd_RemoveCommand( "shaderstate" );
  940. if ( tr.registered ) {
  941. R_SyncRenderThread();
  942. R_ShutdownCommandBuffers();
  943. R_DeleteTextures();
  944. }
  945. R_DoneFreeType();
  946. // shut down platform specific OpenGL stuff
  947. if ( destroyWindow ) {
  948. GLimp_Shutdown();
  949. }
  950. tr.registered = qfalse;
  951. }
  952. /*
  953. =============
  954. RE_EndRegistration
  955. Touch all images to make sure they are resident
  956. =============
  957. */
  958. void RE_EndRegistration( void ) {
  959. R_SyncRenderThread();
  960. if (!Sys_LowPhysicalMemory()) {
  961. RB_ShowImages();
  962. }
  963. }
  964. /*
  965. @@@@@@@@@@@@@@@@@@@@@
  966. GetRefAPI
  967. @@@@@@@@@@@@@@@@@@@@@
  968. */
  969. refexport_t *GetRefAPI ( int apiVersion, refimport_t *rimp ) {
  970. static refexport_t re;
  971. ri = *rimp;
  972. Com_Memset( &re, 0, sizeof( re ) );
  973. if ( apiVersion != REF_API_VERSION ) {
  974. ri.Printf(PRINT_ALL, "Mismatched REF_API_VERSION: expected %i, got %i\n",
  975. REF_API_VERSION, apiVersion );
  976. return NULL;
  977. }
  978. // the RE_ functions are Renderer Entry points
  979. re.Shutdown = RE_Shutdown;
  980. re.BeginRegistration = RE_BeginRegistration;
  981. re.RegisterModel = RE_RegisterModel;
  982. re.RegisterSkin = RE_RegisterSkin;
  983. re.RegisterShader = RE_RegisterShader;
  984. re.RegisterShaderNoMip = RE_RegisterShaderNoMip;
  985. re.LoadWorld = RE_LoadWorldMap;
  986. re.SetWorldVisData = RE_SetWorldVisData;
  987. re.EndRegistration = RE_EndRegistration;
  988. re.BeginFrame = RE_BeginFrame;
  989. re.EndFrame = RE_EndFrame;
  990. re.MarkFragments = R_MarkFragments;
  991. re.LerpTag = R_LerpTag;
  992. re.ModelBounds = R_ModelBounds;
  993. re.ClearScene = RE_ClearScene;
  994. re.AddRefEntityToScene = RE_AddRefEntityToScene;
  995. re.AddPolyToScene = RE_AddPolyToScene;
  996. re.LightForPoint = R_LightForPoint;
  997. re.AddLightToScene = RE_AddLightToScene;
  998. re.AddAdditiveLightToScene = RE_AddAdditiveLightToScene;
  999. re.RenderScene = RE_RenderScene;
  1000. re.SetColor = RE_SetColor;
  1001. re.DrawStretchPic = RE_StretchPic;
  1002. re.DrawStretchRaw = RE_StretchRaw;
  1003. re.UploadCinematic = RE_UploadCinematic;
  1004. re.RegisterFont = RE_RegisterFont;
  1005. re.RemapShader = R_RemapShader;
  1006. re.GetEntityToken = R_GetEntityToken;
  1007. re.inPVS = R_inPVS;
  1008. return &re;
  1009. }