tr_init.c 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418
  1. /*
  2. ===========================================================================
  3. Return to Castle Wolfenstein single player GPL Source Code
  4. Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Return to Castle Wolfenstein single player GPL Source Code (“RTCW SP Source Code”).
  6. RTCW SP Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. RTCW SP Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the RTCW SP 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 RTCW SP Source Code. If not, please request a copy in writing from id Software at the address below.
  17. 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.
  18. ===========================================================================
  19. */
  20. // tr_init.c -- functions that are not called every frame
  21. #include "tr_local.h"
  22. //#ifdef __USEA3D
  23. //// Defined in snd_a3dg_refcommon.c
  24. //void RE_A3D_RenderGeometry (void *pVoidA3D, void *pVoidGeom, void *pVoidMat, void *pVoidGeomStatus);
  25. //#endif
  26. glconfig_t glConfig;
  27. glstate_t glState;
  28. static void GfxInfo_f( void );
  29. cvar_t *r_flareSize;
  30. cvar_t *r_flareFade;
  31. cvar_t *r_railWidth;
  32. cvar_t *r_railCoreWidth;
  33. cvar_t *r_railSegmentLength;
  34. cvar_t *r_ignoreFastPath;
  35. cvar_t *r_verbose;
  36. cvar_t *r_ignore;
  37. cvar_t *r_displayRefresh;
  38. cvar_t *r_detailTextures;
  39. cvar_t *r_znear;
  40. cvar_t *r_zfar;
  41. cvar_t *r_smp;
  42. cvar_t *r_showSmp;
  43. cvar_t *r_skipBackEnd;
  44. cvar_t *r_ignorehwgamma;
  45. cvar_t *r_measureOverdraw;
  46. cvar_t *r_inGameVideo;
  47. cvar_t *r_fastsky;
  48. cvar_t *r_drawSun;
  49. cvar_t *r_dynamiclight;
  50. cvar_t *r_dlightBacks;
  51. cvar_t *r_dlightScale; //----(SA) added
  52. cvar_t *r_waterFogColor; //----(SA) added
  53. cvar_t *r_mapFogColor;
  54. cvar_t *r_savegameFogColor; //----(SA) added
  55. cvar_t *r_lodbias;
  56. cvar_t *r_lodscale;
  57. cvar_t *r_norefresh;
  58. cvar_t *r_drawentities;
  59. cvar_t *r_drawworld;
  60. cvar_t *r_speeds;
  61. cvar_t *r_fullbright;
  62. cvar_t *r_novis;
  63. cvar_t *r_nocull;
  64. cvar_t *r_facePlaneCull;
  65. cvar_t *r_showcluster;
  66. cvar_t *r_nocurves;
  67. cvar_t *r_allowExtensions;
  68. cvar_t *r_ext_compressed_textures;
  69. cvar_t *r_ext_gamma_control;
  70. cvar_t *r_ext_multitexture;
  71. cvar_t *r_ext_compiled_vertex_array;
  72. cvar_t *r_ext_texture_env_add;
  73. //----(SA) added
  74. cvar_t *r_ext_texture_filter_anisotropic;
  75. cvar_t *r_ext_NV_fog_dist;
  76. cvar_t *r_nv_fogdist_mode;
  77. cvar_t *r_ext_ATI_pntriangles;
  78. cvar_t *r_ati_truform_tess; //
  79. cvar_t *r_ati_truform_normalmode; // linear/quadratic
  80. cvar_t *r_ati_truform_pointmode; // linear/cubic
  81. //----(SA) end
  82. cvar_t *r_ati_fsaa_samples; //DAJ valids are 1, 2, 4
  83. cvar_t *r_ignoreGLErrors;
  84. cvar_t *r_logFile;
  85. cvar_t *r_stencilbits;
  86. cvar_t *r_depthbits;
  87. cvar_t *r_colorbits;
  88. cvar_t *r_stereo;
  89. cvar_t *r_primitives;
  90. cvar_t *r_texturebits;
  91. cvar_t *r_drawBuffer;
  92. cvar_t *r_glDriver;
  93. cvar_t *r_glIgnoreWicked3D;
  94. cvar_t *r_lightmap;
  95. cvar_t *r_vertexLight;
  96. cvar_t *r_uiFullScreen;
  97. cvar_t *r_shadows;
  98. cvar_t *r_portalsky; //----(SA) added
  99. cvar_t *r_flares;
  100. cvar_t *r_mode;
  101. cvar_t *r_nobind;
  102. cvar_t *r_singleShader;
  103. cvar_t *r_roundImagesDown;
  104. cvar_t *r_lowMemTextureSize;
  105. cvar_t *r_lowMemTextureThreshold;
  106. cvar_t *r_colorMipLevels;
  107. cvar_t *r_picmip;
  108. cvar_t *r_picmip2;
  109. cvar_t *r_showtris;
  110. cvar_t *r_showsky;
  111. cvar_t *r_shownormals;
  112. cvar_t *r_finish;
  113. cvar_t *r_clear;
  114. cvar_t *r_swapInterval;
  115. cvar_t *r_textureMode;
  116. cvar_t *r_offsetFactor;
  117. cvar_t *r_offsetUnits;
  118. cvar_t *r_gamma;
  119. cvar_t *r_intensity;
  120. cvar_t *r_lockpvs;
  121. cvar_t *r_noportals;
  122. cvar_t *r_portalOnly;
  123. cvar_t *r_subdivisions;
  124. cvar_t *r_lodCurveError;
  125. cvar_t *r_fullscreen;
  126. cvar_t *r_customwidth;
  127. cvar_t *r_customheight;
  128. cvar_t *r_customaspect;
  129. cvar_t *r_overBrightBits;
  130. cvar_t *r_mapOverBrightBits;
  131. cvar_t *r_debugSurface;
  132. cvar_t *r_simpleMipMaps;
  133. cvar_t *r_showImages;
  134. cvar_t *r_ambientScale;
  135. cvar_t *r_directedScale;
  136. cvar_t *r_debugLight;
  137. cvar_t *r_debugSort;
  138. cvar_t *r_printShaders;
  139. cvar_t *r_saveFontData;
  140. // Ridah
  141. cvar_t *r_cache;
  142. cvar_t *r_cacheShaders;
  143. cvar_t *r_cacheModels;
  144. cvar_t *r_compressModels;
  145. cvar_t *r_exportCompressedModels;
  146. cvar_t *r_cacheGathering;
  147. cvar_t *r_buildScript;
  148. cvar_t *r_bonesDebug;
  149. // done.
  150. // Rafael - wolf fog
  151. cvar_t *r_wolffog;
  152. // done
  153. cvar_t *r_highQualityVideo;
  154. cvar_t *r_rmse;
  155. cvar_t *r_maxpolys;
  156. int max_polys;
  157. cvar_t *r_maxpolyverts;
  158. int max_polyverts;
  159. void ( APIENTRY * qglMultiTexCoord2fARB )( GLenum texture, GLfloat s, GLfloat t );
  160. void ( APIENTRY * qglActiveTextureARB )( GLenum texture );
  161. void ( APIENTRY * qglClientActiveTextureARB )( GLenum texture );
  162. void ( APIENTRY * qglLockArraysEXT )( GLint, GLint );
  163. void ( APIENTRY * qglUnlockArraysEXT )( void );
  164. //----(SA) added
  165. void ( APIENTRY * qglPNTrianglesiATI )( GLenum pname, GLint param );
  166. void ( APIENTRY * qglPNTrianglesfATI )( GLenum pname, GLfloat param );
  167. /*
  168. The tessellation level and normal generation mode are specified with:
  169. void qglPNTriangles{if}ATI(enum pname, T param)
  170. If <pname> is:
  171. GL_PN_TRIANGLES_NORMAL_MODE_ATI -
  172. <param> must be one of the symbolic constants:
  173. - GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI or
  174. - GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI
  175. which will select linear or quadratic normal interpolation respectively.
  176. GL_PN_TRIANGLES_POINT_MODE_ATI -
  177. <param> must be one of the symbolic constants:
  178. - GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI or
  179. - GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI
  180. which will select linear or cubic interpolation respectively.
  181. GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI -
  182. <param> should be a value specifying the number of evaluation points on each edge. This value must be
  183. greater than 0 and less than or equal to the value given by GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI.
  184. An INVALID_VALUE error will be generated if the value for <param> is less than zero or greater than the max value.
  185. Associated 'gets':
  186. Get Value Get Command Type Minimum Value Attribute
  187. --------- ----------- ---- ------------ ---------
  188. PN_TRIANGLES_ATI IsEnabled B False PN Triangles/enable
  189. PN_TRIANGLES_NORMAL_MODE_ATI GetIntegerv Z2 PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI PN Triangles
  190. PN_TRIANGLES_POINT_MODE_ATI GetIntegerv Z2 PN_TRIANGLES_POINT_MODE_CUBIC_ATI PN Triangles
  191. PN_TRIANGLES_TESSELATION_LEVEL_ATI GetIntegerv Z+ 1 PN Triangles
  192. MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI GetIntegerv Z+ 1 -
  193. */
  194. //----(SA) end
  195. static void AssertCvarRange( cvar_t *cv, float minVal, float maxVal, qboolean shouldBeIntegral ) {
  196. if ( shouldBeIntegral ) {
  197. if ( ( int ) cv->value != cv->integer ) {
  198. ri.Printf( PRINT_WARNING, "WARNING: cvar '%s' must be integral (%f)\n", cv->name, cv->value );
  199. ri.Cvar_Set( cv->name, va( "%d", cv->integer ) );
  200. }
  201. }
  202. if ( cv->value < minVal ) {
  203. ri.Printf( PRINT_WARNING, "WARNING: cvar '%s' out of range (%f < %f)\n", cv->name, cv->value, minVal );
  204. ri.Cvar_Set( cv->name, va( "%f", minVal ) );
  205. } else if ( cv->value > maxVal ) {
  206. ri.Printf( PRINT_WARNING, "WARNING: cvar '%s' out of range (%f > %f)\n", cv->name, cv->value, maxVal );
  207. ri.Cvar_Set( cv->name, va( "%f", maxVal ) );
  208. }
  209. }
  210. /*
  211. ** InitOpenGL
  212. **
  213. ** This function is responsible for initializing a valid OpenGL subsystem. This
  214. ** is done by calling GLimp_Init (which gives us a working OGL subsystem) then
  215. ** setting variables, checking GL constants, and reporting the gfx system config
  216. ** to the user.
  217. */
  218. static void InitOpenGL( void ) {
  219. char renderer_buffer[1024];
  220. //
  221. // initialize OS specific portions of the renderer
  222. //
  223. // GLimp_Init directly or indirectly references the following cvars:
  224. // - r_fullscreen
  225. // - r_glDriver
  226. // - r_mode
  227. // - r_(color|depth|stencil)bits
  228. // - r_ignorehwgamma
  229. // - r_gamma
  230. //
  231. if ( glConfig.vidWidth == 0 ) {
  232. GLint temp;
  233. GLimp_Init();
  234. strcpy( renderer_buffer, glConfig.renderer_string );
  235. Q_strlwr( renderer_buffer );
  236. // OpenGL driver constants
  237. qglGetIntegerv( GL_MAX_TEXTURE_SIZE, &temp );
  238. glConfig.maxTextureSize = temp;
  239. // stubbed or broken drivers may have reported 0...
  240. if ( glConfig.maxTextureSize <= 0 ) {
  241. glConfig.maxTextureSize = 0;
  242. }
  243. }
  244. // init command buffers and SMP
  245. R_InitCommandBuffers();
  246. // print info
  247. GfxInfo_f();
  248. // set default state
  249. GL_SetDefaultState();
  250. }
  251. /*
  252. ==================
  253. GL_CheckErrors
  254. ==================
  255. */
  256. void GL_CheckErrors( void ) {
  257. int err;
  258. char s[64];
  259. err = qglGetError();
  260. if ( err == GL_NO_ERROR ) {
  261. return;
  262. }
  263. if ( r_ignoreGLErrors->integer ) {
  264. return;
  265. }
  266. switch ( err ) {
  267. case GL_INVALID_ENUM:
  268. strcpy( s, "GL_INVALID_ENUM" );
  269. break;
  270. case GL_INVALID_VALUE:
  271. strcpy( s, "GL_INVALID_VALUE" );
  272. break;
  273. case GL_INVALID_OPERATION:
  274. strcpy( s, "GL_INVALID_OPERATION" );
  275. break;
  276. case GL_STACK_OVERFLOW:
  277. strcpy( s, "GL_STACK_OVERFLOW" );
  278. break;
  279. case GL_STACK_UNDERFLOW:
  280. strcpy( s, "GL_STACK_UNDERFLOW" );
  281. break;
  282. case GL_OUT_OF_MEMORY:
  283. strcpy( s, "GL_OUT_OF_MEMORY" );
  284. break;
  285. default:
  286. Com_sprintf( s, sizeof( s ), "%i", err );
  287. break;
  288. }
  289. ri.Error( ERR_FATAL, "GL_CheckErrors: %s", s );
  290. }
  291. /*
  292. ** R_GetModeInfo
  293. */
  294. typedef struct vidmode_s
  295. {
  296. const char *description;
  297. int width, height;
  298. float pixelAspect; // pixel width / height
  299. } vidmode_t;
  300. vidmode_t r_vidModes[] =
  301. {
  302. { "Mode 0: 320x240", 320, 240, 1 },
  303. { "Mode 1: 400x300", 400, 300, 1 },
  304. { "Mode 2: 512x384", 512, 384, 1 },
  305. { "Mode 3: 640x480", 640, 480, 1 },
  306. { "Mode 4: 800x600", 800, 600, 1 },
  307. { "Mode 5: 960x720", 960, 720, 1 },
  308. { "Mode 6: 1024x768", 1024, 768, 1 },
  309. { "Mode 7: 1152x864", 1152, 864, 1 },
  310. { "Mode 8: 1280x1024", 1280, 1024, 1 },
  311. { "Mode 9: 1600x1200", 1600, 1200, 1 },
  312. { "Mode 10: 2048x1536", 2048, 1536, 1 },
  313. { "Mode 11: 856x480 (wide)",856, 480, 1 },
  314. { "Mode 12: 1920x1200 (wide)",1920, 1200, 1 } //----(SA) added
  315. };
  316. static int s_numVidModes = ( sizeof( r_vidModes ) / sizeof( r_vidModes[0] ) );
  317. qboolean R_GetModeInfo( int *width, int *height, float *windowAspect, int mode ) {
  318. vidmode_t *vm;
  319. if ( mode < -1 ) {
  320. return qfalse;
  321. }
  322. if ( mode >= s_numVidModes ) {
  323. return qfalse;
  324. }
  325. if ( mode == -1 ) {
  326. *width = r_customwidth->integer;
  327. *height = r_customheight->integer;
  328. *windowAspect = r_customaspect->value;
  329. return qtrue;
  330. }
  331. vm = &r_vidModes[mode];
  332. *width = vm->width;
  333. *height = vm->height;
  334. *windowAspect = (float)vm->width / ( vm->height * vm->pixelAspect );
  335. return qtrue;
  336. }
  337. /*
  338. ** R_ModeList_f
  339. */
  340. static void R_ModeList_f( void ) {
  341. int i;
  342. ri.Printf( PRINT_ALL, "\n" );
  343. for ( i = 0; i < s_numVidModes; i++ )
  344. {
  345. ri.Printf( PRINT_ALL, "%s\n", r_vidModes[i].description );
  346. }
  347. ri.Printf( PRINT_ALL, "\n" );
  348. }
  349. /*
  350. ==============================================================================
  351. SCREEN SHOTS
  352. ==============================================================================
  353. */
  354. /*
  355. ==================
  356. R_TakeScreenshot
  357. ==================
  358. */
  359. void R_TakeScreenshot( int x, int y, int width, int height, char *fileName ) {
  360. byte *buffer;
  361. int i, c, temp;
  362. buffer = ri.Hunk_AllocateTempMemory( glConfig.vidWidth * glConfig.vidHeight * 3 + 18 );
  363. memset( buffer, 0, 18 );
  364. buffer[2] = 2; // uncompressed type
  365. buffer[12] = width & 255;
  366. buffer[13] = width >> 8;
  367. buffer[14] = height & 255;
  368. buffer[15] = height >> 8;
  369. buffer[16] = 24; // pixel size
  370. qglReadPixels( x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer + 18 );
  371. // swap rgb to bgr
  372. c = 18 + width * height * 3;
  373. for ( i = 18 ; i < c ; i += 3 ) {
  374. temp = buffer[i];
  375. buffer[i] = buffer[i + 2];
  376. buffer[i + 2] = temp;
  377. }
  378. // gamma correct
  379. if ( ( tr.overbrightBits > 0 ) && glConfig.deviceSupportsGamma ) {
  380. R_GammaCorrect( buffer + 18, glConfig.vidWidth * glConfig.vidHeight * 3 );
  381. }
  382. ri.FS_WriteFile( fileName, buffer, c );
  383. ri.Hunk_FreeTempMemory( buffer );
  384. }
  385. /*
  386. ==============
  387. R_TakeScreenshotJPEG
  388. ==============
  389. */
  390. void R_TakeScreenshotJPEG( int x, int y, int width, int height, char *fileName ) {
  391. byte *buffer;
  392. buffer = ri.Hunk_AllocateTempMemory( glConfig.vidWidth * glConfig.vidHeight * 4 );
  393. qglReadPixels( x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer );
  394. // gamma correct
  395. if ( ( tr.overbrightBits > 0 ) && glConfig.deviceSupportsGamma ) {
  396. R_GammaCorrect( buffer, glConfig.vidWidth * glConfig.vidHeight * 4 );
  397. }
  398. ri.FS_WriteFile( fileName, buffer, 1 ); // create path
  399. SaveJPG( fileName, 95, glConfig.vidWidth, glConfig.vidHeight, buffer );
  400. ri.Hunk_FreeTempMemory( buffer );
  401. }
  402. /*
  403. ==================
  404. R_ScreenshotFilename
  405. ==================
  406. */
  407. void R_ScreenshotFilename( int lastNumber, char *fileName ) {
  408. int a,b,c,d;
  409. if ( lastNumber < 0 || lastNumber > 9999 ) {
  410. Com_sprintf( fileName, MAX_OSPATH, "screenshots/shot9999.tga" );
  411. return;
  412. }
  413. a = lastNumber / 1000;
  414. lastNumber -= a * 1000;
  415. b = lastNumber / 100;
  416. lastNumber -= b * 100;
  417. c = lastNumber / 10;
  418. lastNumber -= c * 10;
  419. d = lastNumber;
  420. Com_sprintf( fileName, MAX_OSPATH, "screenshots/shot%i%i%i%i.tga"
  421. , a, b, c, d );
  422. }
  423. /*
  424. ==============
  425. R_ScreenshotFilenameJPEG
  426. ==============
  427. */
  428. void R_ScreenshotFilenameJPEG( int lastNumber, char *fileName ) {
  429. int a,b,c,d;
  430. if ( lastNumber < 0 || lastNumber > 9999 ) {
  431. Com_sprintf( fileName, MAX_OSPATH, "screenshots/shot9999.jpg" );
  432. return;
  433. }
  434. a = lastNumber / 1000;
  435. lastNumber -= a * 1000;
  436. b = lastNumber / 100;
  437. lastNumber -= b * 100;
  438. c = lastNumber / 10;
  439. lastNumber -= c * 10;
  440. d = lastNumber;
  441. Com_sprintf( fileName, MAX_OSPATH, "screenshots/shot%i%i%i%i.jpg"
  442. , a, b, c, d );
  443. }
  444. /*
  445. ====================
  446. R_LevelShot
  447. levelshots are specialized 128*128 thumbnails for
  448. the menu system, sampled down from full screen distorted images
  449. ====================
  450. */
  451. void R_LevelShot( void ) {
  452. char checkname[MAX_OSPATH];
  453. byte *buffer;
  454. byte *source;
  455. byte *src, *dst;
  456. int x, y;
  457. int r, g, b;
  458. float xScale, yScale;
  459. int xx, yy;
  460. sprintf( checkname, "levelshots/%s.tga", tr.world->baseName );
  461. source = ri.Hunk_AllocateTempMemory( glConfig.vidWidth * glConfig.vidHeight * 3 );
  462. buffer = ri.Hunk_AllocateTempMemory( 128 * 128 * 3 + 18 );
  463. memset( buffer, 0, 18 );
  464. buffer[2] = 2; // uncompressed type
  465. buffer[12] = 128;
  466. buffer[14] = 128;
  467. buffer[16] = 24; // pixel size
  468. qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_RGB, GL_UNSIGNED_BYTE, source );
  469. // resample from source
  470. xScale = glConfig.vidWidth / 512.0f;
  471. yScale = glConfig.vidHeight / 384.0f;
  472. for ( y = 0 ; y < 128 ; y++ ) {
  473. for ( x = 0 ; x < 128 ; x++ ) {
  474. r = g = b = 0;
  475. for ( yy = 0 ; yy < 3 ; yy++ ) {
  476. for ( xx = 0 ; xx < 4 ; xx++ ) {
  477. src = source + 3 * ( glConfig.vidWidth * (int)( ( y * 3 + yy ) * yScale ) + (int)( ( x * 4 + xx ) * xScale ) );
  478. r += src[0];
  479. g += src[1];
  480. b += src[2];
  481. }
  482. }
  483. dst = buffer + 18 + 3 * ( y * 128 + x );
  484. dst[0] = b / 12;
  485. dst[1] = g / 12;
  486. dst[2] = r / 12;
  487. }
  488. }
  489. // gamma correct
  490. if ( ( tr.overbrightBits > 0 ) && glConfig.deviceSupportsGamma ) {
  491. R_GammaCorrect( buffer + 18, 128 * 128 * 3 );
  492. }
  493. ri.FS_WriteFile( checkname, buffer, 128 * 128 * 3 + 18 );
  494. ri.Hunk_FreeTempMemory( buffer );
  495. ri.Hunk_FreeTempMemory( source );
  496. ri.Printf( PRINT_ALL, "Wrote %s\n", checkname );
  497. }
  498. /*
  499. ==================
  500. R_ScreenShot_f
  501. screenshot
  502. screenshot [silent]
  503. screenshot [levelshot]
  504. screenshot [filename]
  505. Doesn't print the pacifier message if there is a second arg
  506. ==================
  507. */
  508. void R_ScreenShot_f( void ) {
  509. char checkname[MAX_OSPATH];
  510. int len;
  511. static int lastNumber = -1;
  512. qboolean silent;
  513. if ( !strcmp( ri.Cmd_Argv( 1 ), "levelshot" ) ) {
  514. R_LevelShot();
  515. return;
  516. }
  517. if ( !strcmp( ri.Cmd_Argv( 1 ), "silent" ) ) {
  518. silent = qtrue;
  519. } else {
  520. silent = qfalse;
  521. }
  522. if ( ri.Cmd_Argc() == 2 && !silent ) {
  523. // explicit filename
  524. Com_sprintf( checkname, MAX_OSPATH, "screenshots/%s.tga", ri.Cmd_Argv( 1 ) );
  525. } else {
  526. // scan for a free filename
  527. // if we have saved a previous screenshot, don't scan
  528. // again, because recording demo avis can involve
  529. // thousands of shots
  530. if ( lastNumber == -1 ) {
  531. lastNumber = 0;
  532. }
  533. // scan for a free number
  534. for ( ; lastNumber <= 9999 ; lastNumber++ ) {
  535. R_ScreenshotFilename( lastNumber, checkname );
  536. len = ri.FS_ReadFile( checkname, NULL );
  537. if ( len <= 0 ) {
  538. break; // file doesn't exist
  539. }
  540. }
  541. if ( lastNumber >= 9999 ) {
  542. ri.Printf( PRINT_ALL, "ScreenShot: Couldn't create a file\n" );
  543. return;
  544. }
  545. lastNumber++;
  546. }
  547. R_TakeScreenshot( 0, 0, glConfig.vidWidth, glConfig.vidHeight, checkname );
  548. if ( !silent ) {
  549. ri.Printf( PRINT_ALL, "Wrote %s\n", checkname );
  550. }
  551. }
  552. void R_ScreenShotJPEG_f( void ) {
  553. char checkname[MAX_OSPATH];
  554. int len;
  555. static int lastNumber = -1;
  556. qboolean silent;
  557. if ( !strcmp( ri.Cmd_Argv( 1 ), "levelshot" ) ) {
  558. R_LevelShot();
  559. return;
  560. }
  561. if ( !strcmp( ri.Cmd_Argv( 1 ), "silent" ) ) {
  562. silent = qtrue;
  563. } else {
  564. silent = qfalse;
  565. }
  566. if ( ri.Cmd_Argc() == 2 && !silent ) {
  567. // explicit filename
  568. Com_sprintf( checkname, MAX_OSPATH, "screenshots/%s.jpg", ri.Cmd_Argv( 1 ) );
  569. } else {
  570. // scan for a free filename
  571. // if we have saved a previous screenshot, don't scan
  572. // again, because recording demo avis can involve
  573. // thousands of shots
  574. if ( lastNumber == -1 ) {
  575. lastNumber = 0;
  576. }
  577. // scan for a free number
  578. for ( ; lastNumber <= 9999 ; lastNumber++ ) {
  579. R_ScreenshotFilenameJPEG( lastNumber, checkname );
  580. len = ri.FS_ReadFile( checkname, NULL );
  581. if ( len <= 0 ) {
  582. break; // file doesn't exist
  583. }
  584. }
  585. if ( lastNumber == 10000 ) {
  586. ri.Printf( PRINT_ALL, "ScreenShot: Couldn't create a file\n" );
  587. return;
  588. }
  589. lastNumber++;
  590. }
  591. R_TakeScreenshotJPEG( 0, 0, glConfig.vidWidth, glConfig.vidHeight, checkname );
  592. if ( !silent ) {
  593. ri.Printf( PRINT_ALL, "Wrote %s\n", checkname );
  594. }
  595. }
  596. //============================================================================
  597. /*
  598. ** GL_SetDefaultState
  599. */
  600. void GL_SetDefaultState( void ) {
  601. qglClearDepth( 1.0f );
  602. qglCullFace( GL_FRONT );
  603. qglColor4f( 1,1,1,1 );
  604. // initialize downstream texture unit if we're running
  605. // in a multitexture environment
  606. if ( qglActiveTextureARB ) {
  607. GL_SelectTexture( 1 );
  608. GL_TextureMode( r_textureMode->string );
  609. GL_TexEnv( GL_MODULATE );
  610. qglDisable( GL_TEXTURE_2D );
  611. GL_SelectTexture( 0 );
  612. }
  613. qglEnable( GL_TEXTURE_2D );
  614. GL_TextureMode( r_textureMode->string );
  615. GL_TexEnv( GL_MODULATE );
  616. qglShadeModel( GL_SMOOTH );
  617. qglDepthFunc( GL_LEQUAL );
  618. // the vertex array is always enabled, but the color and texture
  619. // arrays are enabled and disabled around the compiled vertex array call
  620. qglEnableClientState( GL_VERTEX_ARRAY );
  621. //
  622. // make sure our GL state vector is set correctly
  623. //
  624. glState.glStateBits = GLS_DEPTHTEST_DISABLE | GLS_DEPTHMASK_TRUE;
  625. qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
  626. qglDepthMask( GL_TRUE );
  627. qglDisable( GL_DEPTH_TEST );
  628. qglEnable( GL_SCISSOR_TEST );
  629. qglDisable( GL_CULL_FACE );
  630. qglDisable( GL_BLEND );
  631. //----(SA) added.
  632. // ATI pn_triangles
  633. if ( qglPNTrianglesiATI ) {
  634. int maxtess;
  635. // get max supported tesselation
  636. qglGetIntegerv( GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI, (GLint*)&maxtess );
  637. #ifdef __MACOS__
  638. glConfig.ATIMaxTruformTess = 7;
  639. #else
  640. glConfig.ATIMaxTruformTess = maxtess;
  641. #endif
  642. // cap if necessary
  643. if ( r_ati_truform_tess->value > maxtess ) {
  644. ri.Cvar_Set( "r_ati_truform_tess", va( "%d", maxtess ) );
  645. }
  646. // set Wolf defaults
  647. qglPNTrianglesiATI( GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI, r_ati_truform_tess->value );
  648. }
  649. if ( glConfig.anisotropicAvailable ) {
  650. float maxAnisotropy;
  651. qglGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy );
  652. glConfig.maxAnisotropy = maxAnisotropy;
  653. // set when rendering
  654. // qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, glConfig.maxAnisotropy);
  655. }
  656. //----(SA) end
  657. }
  658. /*
  659. ================
  660. GfxInfo_f
  661. ================
  662. */
  663. void GfxInfo_f( void ) {
  664. cvar_t *sys_cpustring = ri.Cvar_Get( "sys_cpustring", "", 0 );
  665. const char *enablestrings[] =
  666. {
  667. "disabled",
  668. "enabled"
  669. };
  670. const char *fsstrings[] =
  671. {
  672. "windowed",
  673. "fullscreen"
  674. };
  675. ri.Printf( PRINT_ALL, "\nGL_VENDOR: %s\n", glConfig.vendor_string );
  676. ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glConfig.renderer_string );
  677. ri.Printf( PRINT_ALL, "GL_VERSION: %s\n", glConfig.version_string );
  678. ri.Printf( PRINT_ALL, "GL_EXTENSIONS: %s\n", glConfig.extensions_string );
  679. ri.Printf( PRINT_ALL, "GL_MAX_TEXTURE_SIZE: %d\n", glConfig.maxTextureSize );
  680. ri.Printf( PRINT_ALL, "GL_MAX_ACTIVE_TEXTURES_ARB: %d\n", glConfig.maxActiveTextures );
  681. ri.Printf( PRINT_ALL, "\nPIXELFORMAT: color(%d-bits) Z(%d-bit) stencil(%d-bits)\n", glConfig.colorBits, glConfig.depthBits, glConfig.stencilBits );
  682. ri.Printf( PRINT_ALL, "MODE: %d, %d x %d %s hz:", r_mode->integer, glConfig.vidWidth, glConfig.vidHeight, fsstrings[r_fullscreen->integer == 1] );
  683. if ( glConfig.displayFrequency ) {
  684. ri.Printf( PRINT_ALL, "%d\n", glConfig.displayFrequency );
  685. } else
  686. {
  687. ri.Printf( PRINT_ALL, "N/A\n" );
  688. }
  689. if ( glConfig.deviceSupportsGamma ) {
  690. ri.Printf( PRINT_ALL, "GAMMA: hardware w/ %d overbright bits\n", tr.overbrightBits );
  691. } else
  692. {
  693. ri.Printf( PRINT_ALL, "GAMMA: software w/ %d overbright bits\n", tr.overbrightBits );
  694. }
  695. ri.Printf( PRINT_ALL, "CPU: %s\n", sys_cpustring->string );
  696. // rendering primitives
  697. {
  698. int primitives;
  699. // default is to use triangles if compiled vertex arrays are present
  700. ri.Printf( PRINT_ALL, "rendering primitives: " );
  701. primitives = r_primitives->integer;
  702. if ( primitives == 0 ) {
  703. if ( qglLockArraysEXT ) {
  704. primitives = 2;
  705. } else {
  706. primitives = 1;
  707. }
  708. }
  709. if ( primitives == -1 ) {
  710. ri.Printf( PRINT_ALL, "none\n" );
  711. } else if ( primitives == 2 ) {
  712. ri.Printf( PRINT_ALL, "single glDrawElements\n" );
  713. } else if ( primitives == 1 ) {
  714. ri.Printf( PRINT_ALL, "multiple glArrayElement\n" );
  715. } else if ( primitives == 3 ) {
  716. ri.Printf( PRINT_ALL, "multiple glColor4ubv + glTexCoord2fv + glVertex3fv\n" );
  717. }
  718. }
  719. ri.Printf( PRINT_ALL, "texturemode: %s\n", r_textureMode->string );
  720. ri.Printf( PRINT_ALL, "picmip: %d\n", r_picmip->integer );
  721. ri.Printf( PRINT_ALL, "picmip2: %d\n", r_picmip2->integer );
  722. ri.Printf( PRINT_ALL, "texture bits: %d\n", r_texturebits->integer );
  723. ri.Printf( PRINT_ALL, "multitexture: %s\n", enablestrings[qglActiveTextureARB != 0] );
  724. ri.Printf( PRINT_ALL, "compiled vertex arrays: %s\n", enablestrings[qglLockArraysEXT != 0 ] );
  725. ri.Printf( PRINT_ALL, "texenv add: %s\n", enablestrings[glConfig.textureEnvAddAvailable != 0] );
  726. ri.Printf( PRINT_ALL, "compressed textures: %s\n", enablestrings[glConfig.textureCompression != TC_NONE] );
  727. ri.Printf( PRINT_ALL, "ATI truform: %s\n", enablestrings[qglPNTrianglesiATI != 0] );
  728. if ( qglPNTrianglesiATI ) {
  729. //DAJ bogus at this point ri.Printf( PRINT_ALL, "MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI: %d\n", glConfig.ATIMaxTruformTess );
  730. ri.Printf( PRINT_ALL, "Truform Tess: %d\n", r_ati_truform_tess->integer );
  731. ri.Printf( PRINT_ALL, "Truform Point Mode: %s\n", r_ati_truform_pointmode->string );
  732. ri.Printf( PRINT_ALL, "Truform Normal Mode: %s\n", r_ati_truform_normalmode->string );
  733. }
  734. ri.Printf( PRINT_ALL, "NV distance fog: %s\n", enablestrings[glConfig.NVFogAvailable != 0] );
  735. if ( glConfig.NVFogAvailable ) {
  736. ri.Printf( PRINT_ALL, "Fog Mode: %s\n", r_nv_fogdist_mode->string );
  737. }
  738. if ( r_vertexLight->integer || glConfig.hardwareType == GLHW_PERMEDIA2 ) {
  739. ri.Printf( PRINT_ALL, "HACK: using vertex lightmap approximation\n" );
  740. }
  741. if ( glConfig.hardwareType == GLHW_RAGEPRO ) {
  742. ri.Printf( PRINT_ALL, "HACK: ragePro approximations\n" );
  743. }
  744. if ( glConfig.hardwareType == GLHW_RIVA128 ) {
  745. ri.Printf( PRINT_ALL, "HACK: riva128 approximations\n" );
  746. }
  747. if ( glConfig.smpActive ) {
  748. ri.Printf( PRINT_ALL, "Using dual processor acceleration\n" );
  749. }
  750. if ( r_finish->integer ) {
  751. ri.Printf( PRINT_ALL, "Forcing glFinish\n" );
  752. }
  753. }
  754. // RF
  755. extern void R_CropImages_f( void );
  756. /*
  757. ===============
  758. R_Register
  759. ===============
  760. */
  761. void R_Register( void ) {
  762. //
  763. // latched and archived variables
  764. //
  765. r_glDriver = ri.Cvar_Get( "r_glDriver", OPENGL_DRIVER_NAME, CVAR_ARCHIVE | CVAR_LATCH );
  766. r_allowExtensions = ri.Cvar_Get( "r_allowExtensions", "1", CVAR_ARCHIVE | CVAR_LATCH );
  767. r_ext_compressed_textures = ri.Cvar_Get( "r_ext_compressed_textures", "1", CVAR_ARCHIVE | CVAR_LATCH ); // (SA) ew, a spelling change I missed from the missionpack
  768. r_ext_gamma_control = ri.Cvar_Get( "r_ext_gamma_control", "1", CVAR_ARCHIVE | CVAR_LATCH );
  769. r_ext_multitexture = ri.Cvar_Get( "r_ext_multitexture", "1", CVAR_ARCHIVE | CVAR_LATCH );
  770. r_ext_compiled_vertex_array = ri.Cvar_Get( "r_ext_compiled_vertex_array", "1", CVAR_ARCHIVE | CVAR_LATCH );
  771. r_glIgnoreWicked3D = ri.Cvar_Get( "r_glIgnoreWicked3D", "0", CVAR_ARCHIVE | CVAR_LATCH );
  772. //----(SA) added
  773. r_ext_ATI_pntriangles = ri.Cvar_Get( "r_ext_ATI_pntriangles", "0", CVAR_ARCHIVE | CVAR_LATCH ); //----(SA) default to '0'
  774. r_ati_truform_tess = ri.Cvar_Get( "r_ati_truform_tess", "1", CVAR_ARCHIVE );
  775. // GR - Change default mode -- linear doesn't do much...
  776. r_ati_truform_normalmode = ri.Cvar_Get( "r_ati_truform_normalmode", "QUADRATIC", CVAR_ARCHIVE );
  777. r_ati_truform_pointmode = ri.Cvar_Get( "r_ati_truform_pointmode", "CUBIC", CVAR_ARCHIVE );
  778. r_ati_fsaa_samples = ri.Cvar_Get( "r_ati_fsaa_samples", "1", CVAR_ARCHIVE ); //DAJ valids are 1, 2, 4
  779. r_ext_texture_filter_anisotropic = ri.Cvar_Get( "r_ext_texture_filter_anisotropic", "0", CVAR_ARCHIVE );
  780. r_ext_NV_fog_dist = ri.Cvar_Get( "r_ext_NV_fog_dist", "1", CVAR_ARCHIVE | CVAR_LATCH );
  781. r_nv_fogdist_mode = ri.Cvar_Get( "r_nv_fogdist_mode", "GL_EYE_RADIAL_NV", CVAR_ARCHIVE ); // default to 'looking good'
  782. //----(SA) end
  783. #ifdef __linux__ // broken on linux
  784. r_ext_texture_env_add = ri.Cvar_Get( "r_ext_texture_env_add", "0", CVAR_ARCHIVE | CVAR_LATCH );
  785. #else
  786. r_ext_texture_env_add = ri.Cvar_Get( "r_ext_texture_env_add", "1", CVAR_ARCHIVE | CVAR_LATCH );
  787. #endif
  788. r_picmip = ri.Cvar_Get( "r_picmip", "1", CVAR_ARCHIVE | CVAR_LATCH );
  789. r_picmip2 = ri.Cvar_Get( "r_picmip2", "2", CVAR_ARCHIVE | CVAR_LATCH ); // used for character skins picmipping at a different level from the rest of the game
  790. r_roundImagesDown = ri.Cvar_Get( "r_roundImagesDown", "1", CVAR_ARCHIVE | CVAR_LATCH );
  791. r_lowMemTextureSize = ri.Cvar_Get( "r_lowMemTextureSize", "0", CVAR_ARCHIVE | CVAR_LATCH );
  792. r_lowMemTextureThreshold = ri.Cvar_Get( "r_lowMemTextureThreshold", "15.0", CVAR_ARCHIVE | CVAR_LATCH );
  793. r_rmse = ri.Cvar_Get( "r_rmse", "0.0", CVAR_ARCHIVE | CVAR_LATCH );
  794. r_colorMipLevels = ri.Cvar_Get( "r_colorMipLevels", "0", CVAR_LATCH );
  795. AssertCvarRange( r_picmip, 0, 16, qtrue );
  796. AssertCvarRange( r_picmip2, 0, 16, qtrue );
  797. r_detailTextures = ri.Cvar_Get( "r_detailtextures", "1", CVAR_ARCHIVE | CVAR_LATCH );
  798. r_texturebits = ri.Cvar_Get( "r_texturebits", "0", CVAR_ARCHIVE | CVAR_LATCH );
  799. r_colorbits = ri.Cvar_Get( "r_colorbits", "0", CVAR_ARCHIVE | CVAR_LATCH );
  800. r_stereo = ri.Cvar_Get( "r_stereo", "0", CVAR_ARCHIVE | CVAR_LATCH );
  801. #if defined ( __linux__ )
  802. r_stencilbits = ri.Cvar_Get( "r_stencilbits", "0", CVAR_ARCHIVE | CVAR_LATCH );
  803. #elif defined ( __MACOS__ )
  804. {
  805. // extern long gSystemVersion;
  806. // if(gSystemVersion >= 0x1000)
  807. // r_stencilbits = ri.Cvar_Get( "r_stencilbits", "8", CVAR_ARCHIVE | CVAR_LATCH );
  808. // else
  809. r_stencilbits = ri.Cvar_Get( "r_stencilbits", "0", CVAR_ARCHIVE | CVAR_LATCH );
  810. }
  811. #else
  812. r_stencilbits = ri.Cvar_Get( "r_stencilbits", "8", CVAR_ARCHIVE | CVAR_LATCH );
  813. #endif
  814. r_depthbits = ri.Cvar_Get( "r_depthbits", "0", CVAR_ARCHIVE | CVAR_LATCH );
  815. r_overBrightBits = ri.Cvar_Get( "r_overBrightBits", "1", CVAR_ARCHIVE | CVAR_LATCH );
  816. r_ignorehwgamma = ri.Cvar_Get( "r_ignorehwgamma", "1", CVAR_ARCHIVE | CVAR_LATCH ); //----(SA) changed this to default to '1' for Drew
  817. r_mode = ri.Cvar_Get( "r_mode", "3", CVAR_ARCHIVE | CVAR_LATCH );
  818. r_fullscreen = ri.Cvar_Get( "r_fullscreen", "1", CVAR_ARCHIVE | CVAR_LATCH );
  819. r_customwidth = ri.Cvar_Get( "r_customwidth", "1600", CVAR_ARCHIVE | CVAR_LATCH );
  820. r_customheight = ri.Cvar_Get( "r_customheight", "1024", CVAR_ARCHIVE | CVAR_LATCH );
  821. r_customaspect = ri.Cvar_Get( "r_customaspect", "1", CVAR_ARCHIVE | CVAR_LATCH );
  822. r_simpleMipMaps = ri.Cvar_Get( "r_simpleMipMaps", "1", CVAR_ARCHIVE | CVAR_LATCH );
  823. r_vertexLight = ri.Cvar_Get( "r_vertexLight", "0", CVAR_ARCHIVE | CVAR_LATCH );
  824. r_uiFullScreen = ri.Cvar_Get( "r_uifullscreen", "0", 0 );
  825. r_subdivisions = ri.Cvar_Get( "r_subdivisions", "4", CVAR_ARCHIVE | CVAR_LATCH );
  826. #ifdef MACOS_X
  827. // Default to using SMP on Mac OS X if we have multiple processors
  828. r_smp = ri.Cvar_Get( "r_smp", Sys_ProcessorCount() > 1 ? "1" : "0", CVAR_ARCHIVE | CVAR_LATCH );
  829. #else
  830. r_smp = ri.Cvar_Get( "r_smp", "0", CVAR_ARCHIVE | CVAR_LATCH );
  831. #endif
  832. r_ignoreFastPath = ri.Cvar_Get( "r_ignoreFastPath", "1", CVAR_ARCHIVE | CVAR_LATCH );
  833. //
  834. // temporary latched variables that can only change over a restart
  835. //
  836. r_displayRefresh = ri.Cvar_Get( "r_displayRefresh", "0", CVAR_LATCH );
  837. AssertCvarRange( r_displayRefresh, 0, 200, qtrue );
  838. r_fullbright = ri.Cvar_Get( "r_fullbright", "0", CVAR_LATCH | CVAR_CHEAT );
  839. r_mapOverBrightBits = ri.Cvar_Get( "r_mapOverBrightBits", "2", CVAR_LATCH );
  840. r_intensity = ri.Cvar_Get( "r_intensity", "1", CVAR_LATCH );
  841. r_singleShader = ri.Cvar_Get( "r_singleShader", "0", CVAR_CHEAT | CVAR_LATCH );
  842. //
  843. // archived variables that can change at any time
  844. //
  845. r_lodCurveError = ri.Cvar_Get( "r_lodCurveError", "250", CVAR_ARCHIVE );
  846. r_lodbias = ri.Cvar_Get( "r_lodbias", "0", CVAR_ARCHIVE );
  847. r_flares = ri.Cvar_Get( "r_flares", "1", CVAR_ARCHIVE );
  848. r_znear = ri.Cvar_Get( "r_znear", "4", CVAR_CHEAT );
  849. AssertCvarRange( r_znear, 0.001f, 200, qtrue );
  850. //----(SA) added
  851. r_zfar = ri.Cvar_Get( "r_zfar", "0", CVAR_CHEAT );
  852. //----(SA) end
  853. r_ignoreGLErrors = ri.Cvar_Get( "r_ignoreGLErrors", "1", CVAR_ARCHIVE );
  854. r_fastsky = ri.Cvar_Get( "r_fastsky", "0", CVAR_ARCHIVE );
  855. r_inGameVideo = ri.Cvar_Get( "r_inGameVideo", "1", CVAR_ARCHIVE );
  856. r_drawSun = ri.Cvar_Get( "r_drawSun", "1", CVAR_ARCHIVE );
  857. r_dynamiclight = ri.Cvar_Get( "r_dynamiclight", "1", CVAR_ARCHIVE );
  858. r_dlightScale = ri.Cvar_Get( "r_dlightScale", "1.0", CVAR_ARCHIVE ); //----(SA) added
  859. r_dlightBacks = ri.Cvar_Get( "r_dlightBacks", "1", CVAR_ARCHIVE );
  860. r_finish = ri.Cvar_Get( "r_finish", "0", CVAR_ARCHIVE );
  861. r_textureMode = ri.Cvar_Get( "r_textureMode", "GL_LINEAR_MIPMAP_NEAREST", CVAR_ARCHIVE );
  862. r_swapInterval = ri.Cvar_Get( "r_swapInterval", "0", CVAR_ARCHIVE );
  863. #ifdef __MACOS__
  864. r_gamma = ri.Cvar_Get( "r_gamma", "1.2", CVAR_ARCHIVE );
  865. #else
  866. r_gamma = ri.Cvar_Get( "r_gamma", "1.3", CVAR_ARCHIVE );
  867. #endif
  868. r_facePlaneCull = ri.Cvar_Get( "r_facePlaneCull", "1", CVAR_ARCHIVE );
  869. r_railWidth = ri.Cvar_Get( "r_railWidth", "16", CVAR_ARCHIVE );
  870. r_railCoreWidth = ri.Cvar_Get( "r_railCoreWidth", "1", CVAR_ARCHIVE );
  871. r_railSegmentLength = ri.Cvar_Get( "r_railSegmentLength", "32", CVAR_ARCHIVE );
  872. r_waterFogColor = ri.Cvar_Get( "r_waterFogColor", "0", CVAR_ROM ); //----(SA) added
  873. r_mapFogColor = ri.Cvar_Get( "r_mapFogColor", "0", CVAR_ROM ); //----(SA) added
  874. r_savegameFogColor = ri.Cvar_Get( "r_savegameFogColor", "0", CVAR_ROM ); //----(SA) added
  875. r_primitives = ri.Cvar_Get( "r_primitives", "0", CVAR_ARCHIVE );
  876. r_ambientScale = ri.Cvar_Get( "r_ambientScale", "0.5", CVAR_CHEAT );
  877. r_directedScale = ri.Cvar_Get( "r_directedScale", "1", CVAR_CHEAT );
  878. //
  879. // temporary variables that can change at any time
  880. //
  881. r_showImages = ri.Cvar_Get( "r_showImages", "0", CVAR_TEMP );
  882. r_debugLight = ri.Cvar_Get( "r_debuglight", "0", CVAR_TEMP );
  883. r_debugSort = ri.Cvar_Get( "r_debugSort", "0", CVAR_CHEAT );
  884. r_printShaders = ri.Cvar_Get( "r_printShaders", "0", 0 );
  885. r_saveFontData = ri.Cvar_Get( "r_saveFontData", "0", 0 );
  886. // Ridah
  887. // show_bug.cgi?id=440
  888. // NOTE TTimo: r_cache is disabled by default in SP
  889. ri.Cvar_Set( "r_cache", "0" );
  890. r_cache = ri.Cvar_Get( "r_cache", "1", CVAR_LATCH ); // leaving it as this for backwards compability. but it caches models and shaders also
  891. // (SA) disabling cacheshaders
  892. ri.Cvar_Set( "r_cacheShaders", "0" );
  893. r_cacheShaders = ri.Cvar_Get( "r_cacheShaders", "0", CVAR_LATCH );
  894. //----(SA) end
  895. r_cacheModels = ri.Cvar_Get( "r_cacheModels", "1", CVAR_LATCH );
  896. r_compressModels = ri.Cvar_Get( "r_compressModels", "0", 0 ); // converts MD3 -> MDC at run-time
  897. r_exportCompressedModels = ri.Cvar_Get( "r_exportCompressedModels", "0", 0 ); // saves compressed models
  898. r_cacheGathering = ri.Cvar_Get( "cl_cacheGathering", "0", 0 );
  899. r_buildScript = ri.Cvar_Get( "com_buildscript", "0", 0 );
  900. r_bonesDebug = ri.Cvar_Get( "r_bonesDebug", "0", CVAR_CHEAT );
  901. // done.
  902. // Rafael - wolf fog
  903. r_wolffog = ri.Cvar_Get( "r_wolffog", "1", 0 );
  904. // done
  905. r_nocurves = ri.Cvar_Get( "r_nocurves", "0", CVAR_CHEAT );
  906. r_drawworld = ri.Cvar_Get( "r_drawworld", "1", CVAR_CHEAT );
  907. r_lightmap = ri.Cvar_Get( "r_lightmap", "0", CVAR_CHEAT );
  908. r_portalOnly = ri.Cvar_Get( "r_portalOnly", "0", CVAR_CHEAT );
  909. r_flareSize = ri.Cvar_Get( "r_flareSize", "40", CVAR_CHEAT );
  910. r_flareFade = ri.Cvar_Get( "r_flareFade", "5", CVAR_CHEAT );
  911. r_showSmp = ri.Cvar_Get( "r_showSmp", "0", CVAR_CHEAT );
  912. r_skipBackEnd = ri.Cvar_Get( "r_skipBackEnd", "0", CVAR_CHEAT );
  913. r_measureOverdraw = ri.Cvar_Get( "r_measureOverdraw", "0", CVAR_CHEAT );
  914. r_lodscale = ri.Cvar_Get( "r_lodscale", "5", CVAR_CHEAT );
  915. r_norefresh = ri.Cvar_Get( "r_norefresh", "0", CVAR_CHEAT );
  916. r_drawentities = ri.Cvar_Get( "r_drawentities", "1", CVAR_CHEAT );
  917. r_ignore = ri.Cvar_Get( "r_ignore", "1", CVAR_CHEAT );
  918. r_nocull = ri.Cvar_Get( "r_nocull", "0", CVAR_CHEAT );
  919. r_novis = ri.Cvar_Get( "r_novis", "0", CVAR_CHEAT );
  920. r_showcluster = ri.Cvar_Get( "r_showcluster", "0", CVAR_CHEAT );
  921. r_speeds = ri.Cvar_Get( "r_speeds", "0", CVAR_CHEAT );
  922. r_verbose = ri.Cvar_Get( "r_verbose", "0", CVAR_CHEAT );
  923. r_logFile = ri.Cvar_Get( "r_logFile", "0", CVAR_CHEAT );
  924. r_debugSurface = ri.Cvar_Get( "r_debugSurface", "0", CVAR_CHEAT );
  925. r_nobind = ri.Cvar_Get( "r_nobind", "0", CVAR_CHEAT );
  926. r_showtris = ri.Cvar_Get( "r_showtris", "0", CVAR_CHEAT );
  927. r_showsky = ri.Cvar_Get( "r_showsky", "0", CVAR_CHEAT );
  928. r_shownormals = ri.Cvar_Get( "r_shownormals", "0", CVAR_CHEAT );
  929. r_clear = ri.Cvar_Get( "r_clear", "0", CVAR_CHEAT );
  930. r_offsetFactor = ri.Cvar_Get( "r_offsetfactor", "-1", CVAR_CHEAT );
  931. r_offsetUnits = ri.Cvar_Get( "r_offsetunits", "-2", CVAR_CHEAT );
  932. r_drawBuffer = ri.Cvar_Get( "r_drawBuffer", "GL_BACK", CVAR_CHEAT );
  933. r_lockpvs = ri.Cvar_Get( "r_lockpvs", "0", CVAR_CHEAT );
  934. r_noportals = ri.Cvar_Get( "r_noportals", "0", CVAR_CHEAT );
  935. r_shadows = ri.Cvar_Get( "cg_shadows", "1", 0 );
  936. r_shadows = ri.Cvar_Get( "cg_shadows", "1", 0 );
  937. r_portalsky = ri.Cvar_Get( "cg_skybox", "1", 0 );
  938. r_maxpolys = ri.Cvar_Get( "r_maxpolys", va( "%d", MAX_POLYS ), 0 );
  939. r_maxpolyverts = ri.Cvar_Get( "r_maxpolyverts", va( "%d", MAX_POLYVERTS ), 0 );
  940. r_highQualityVideo = ri.Cvar_Get( "r_highQualityVideo", "1", CVAR_ARCHIVE );
  941. // make sure all the commands added here are also
  942. // removed in R_Shutdown
  943. ri.Cmd_AddCommand( "imagelist", R_ImageList_f );
  944. ri.Cmd_AddCommand( "shaderlist", R_ShaderList_f );
  945. ri.Cmd_AddCommand( "skinlist", R_SkinList_f );
  946. ri.Cmd_AddCommand( "modellist", R_Modellist_f );
  947. ri.Cmd_AddCommand( "modelist", R_ModeList_f );
  948. ri.Cmd_AddCommand( "screenshot", R_ScreenShot_f );
  949. ri.Cmd_AddCommand( "screenshotJPEG", R_ScreenShotJPEG_f );
  950. ri.Cmd_AddCommand( "gfxinfo", GfxInfo_f );
  951. ri.Cmd_AddCommand( "taginfo", R_TagInfo_f );
  952. // Ridah
  953. ri.Cmd_AddCommand( "cropimages", R_CropImages_f );
  954. // done.
  955. }
  956. /*
  957. ===============
  958. R_Init
  959. ===============
  960. */
  961. void R_Init( void ) {
  962. int err;
  963. int i;
  964. ri.Printf( PRINT_ALL, "----- R_Init -----\n" );
  965. // clear all our internal state
  966. memset( &tr, 0, sizeof( tr ) );
  967. memset( &backEnd, 0, sizeof( backEnd ) );
  968. memset( &tess, 0, sizeof( tess ) );
  969. Swap_Init();
  970. if ( (int)tess.xyz & 15 ) {
  971. Com_Printf( "WARNING: tess.xyz not 16 byte aligned\n" );
  972. }
  973. memset( tess.constantColor255, 255, sizeof( tess.constantColor255 ) );
  974. //
  975. // init function tables
  976. //
  977. for ( i = 0; i < FUNCTABLE_SIZE; i++ )
  978. {
  979. tr.sinTable[i] = sin( DEG2RAD( i * 360.0f / ( ( float ) ( FUNCTABLE_SIZE - 1 ) ) ) );
  980. tr.squareTable[i] = ( i < FUNCTABLE_SIZE / 2 ) ? 1.0f : -1.0f;
  981. tr.sawToothTable[i] = (float)i / FUNCTABLE_SIZE;
  982. tr.inverseSawToothTable[i] = 1.0f - tr.sawToothTable[i];
  983. if ( i < FUNCTABLE_SIZE / 2 ) {
  984. if ( i < FUNCTABLE_SIZE / 4 ) {
  985. tr.triangleTable[i] = ( float ) i / ( FUNCTABLE_SIZE / 4 );
  986. } else
  987. {
  988. tr.triangleTable[i] = 1.0f - tr.triangleTable[i - FUNCTABLE_SIZE / 4];
  989. }
  990. } else
  991. {
  992. tr.triangleTable[i] = -tr.triangleTable[i - FUNCTABLE_SIZE / 2];
  993. }
  994. }
  995. R_InitFogTable();
  996. R_NoiseInit();
  997. R_Register();
  998. // Ridah, init the virtual memory
  999. R_Hunk_Begin();
  1000. max_polys = r_maxpolys->integer;
  1001. if ( max_polys < MAX_POLYS ) {
  1002. max_polys = MAX_POLYS;
  1003. }
  1004. max_polyverts = r_maxpolyverts->integer;
  1005. if ( max_polyverts < MAX_POLYVERTS ) {
  1006. max_polyverts = MAX_POLYVERTS;
  1007. }
  1008. // backEndData[0] = ri.Hunk_Alloc( sizeof( *backEndData[0] ), h_low );
  1009. backEndData[0] = ri.Hunk_Alloc( sizeof( *backEndData[0] ) + sizeof( srfPoly_t ) * max_polys + sizeof( polyVert_t ) * max_polyverts, h_low );
  1010. if ( r_smp->integer ) {
  1011. // backEndData[1] = ri.Hunk_Alloc( sizeof( *backEndData[1] ), h_low );
  1012. backEndData[1] = ri.Hunk_Alloc( sizeof( *backEndData[1] ) + sizeof( srfPoly_t ) * max_polys + sizeof( polyVert_t ) * max_polyverts, h_low );
  1013. } else {
  1014. backEndData[1] = NULL;
  1015. }
  1016. R_ToggleSmpFrame();
  1017. InitOpenGL();
  1018. R_InitImages();
  1019. R_InitShaders();
  1020. R_InitSkins();
  1021. R_ModelInit();
  1022. R_InitFreeType();
  1023. RB_ZombieFXInit();
  1024. err = qglGetError();
  1025. if ( err != GL_NO_ERROR ) {
  1026. ri.Printf( PRINT_ALL, "glGetError() = 0x%x\n", err );
  1027. }
  1028. ri.Printf( PRINT_ALL, "----- finished R_Init -----\n" );
  1029. }
  1030. /*
  1031. ===============
  1032. RE_Shutdown
  1033. ===============
  1034. */
  1035. void RE_Shutdown( qboolean destroyWindow ) {
  1036. ri.Printf( PRINT_ALL, "RE_Shutdown( %i )\n", destroyWindow );
  1037. ri.Cmd_RemoveCommand( "modellist" );
  1038. ri.Cmd_RemoveCommand( "screenshotJPEG" );
  1039. ri.Cmd_RemoveCommand( "screenshot" );
  1040. ri.Cmd_RemoveCommand( "imagelist" );
  1041. ri.Cmd_RemoveCommand( "shaderlist" );
  1042. ri.Cmd_RemoveCommand( "skinlist" );
  1043. ri.Cmd_RemoveCommand( "gfxinfo" );
  1044. ri.Cmd_RemoveCommand( "modelist" );
  1045. ri.Cmd_RemoveCommand( "shaderstate" );
  1046. ri.Cmd_RemoveCommand( "taginfo" );
  1047. // Ridah
  1048. ri.Cmd_RemoveCommand( "cropimages" );
  1049. // done.
  1050. R_ShutdownCommandBuffers();
  1051. // Ridah, keep a backup of the current images if possible
  1052. // clean out any remaining unused media from the last backup
  1053. R_PurgeShaders( 9999999 );
  1054. R_PurgeBackupImages( 9999999 );
  1055. R_PurgeModels( 9999999 );
  1056. if ( r_cache->integer ) {
  1057. if ( tr.registered ) {
  1058. if ( destroyWindow ) {
  1059. R_SyncRenderThread();
  1060. R_ShutdownCommandBuffers();
  1061. R_DeleteTextures();
  1062. } else {
  1063. // backup the current media
  1064. R_ShutdownCommandBuffers();
  1065. R_BackupModels();
  1066. R_BackupShaders();
  1067. R_BackupImages();
  1068. }
  1069. }
  1070. } else if ( tr.registered ) {
  1071. R_SyncRenderThread();
  1072. R_ShutdownCommandBuffers();
  1073. R_DeleteTextures();
  1074. }
  1075. R_DoneFreeType();
  1076. // shut down platform specific OpenGL stuff
  1077. if ( destroyWindow ) {
  1078. GLimp_Shutdown();
  1079. // Ridah, release the virtual memory
  1080. R_Hunk_End();
  1081. R_FreeImageBuffer();
  1082. //ri.Tag_Free(); // wipe all render alloc'd zone memory
  1083. }
  1084. tr.registered = qfalse;
  1085. }
  1086. /*
  1087. =============
  1088. RE_EndRegistration
  1089. Touch all images to make sure they are resident
  1090. =============
  1091. */
  1092. void RE_EndRegistration( void ) {
  1093. R_SyncRenderThread();
  1094. if ( !Sys_LowPhysicalMemory() ) {
  1095. RB_ShowImages();
  1096. }
  1097. }
  1098. /*
  1099. @@@@@@@@@@@@@@@@@@@@@
  1100. GetRefAPI
  1101. @@@@@@@@@@@@@@@@@@@@@
  1102. */
  1103. refexport_t *GetRefAPI( int apiVersion, refimport_t *rimp ) {
  1104. static refexport_t re;
  1105. ri = *rimp;
  1106. memset( &re, 0, sizeof( re ) );
  1107. if ( apiVersion != REF_API_VERSION ) {
  1108. ri.Printf( PRINT_ALL, "Mismatched REF_API_VERSION: expected %i, got %i\n",
  1109. REF_API_VERSION, apiVersion );
  1110. return NULL;
  1111. }
  1112. // the RE_ functions are Renderer Entry points
  1113. re.Shutdown = RE_Shutdown;
  1114. re.BeginRegistration = RE_BeginRegistration;
  1115. re.RegisterModel = RE_RegisterModel;
  1116. re.RegisterSkin = RE_RegisterSkin;
  1117. //----(SA) added
  1118. re.GetSkinModel = RE_GetSkinModel;
  1119. re.GetShaderFromModel = RE_GetShaderFromModel;
  1120. //----(SA) end
  1121. re.RegisterShader = RE_RegisterShader;
  1122. re.RegisterShaderNoMip = RE_RegisterShaderNoMip;
  1123. re.LoadWorld = RE_LoadWorldMap;
  1124. re.SetWorldVisData = RE_SetWorldVisData;
  1125. re.EndRegistration = RE_EndRegistration;
  1126. re.BeginFrame = RE_BeginFrame;
  1127. re.EndFrame = RE_EndFrame;
  1128. re.MarkFragments = R_MarkFragments;
  1129. re.LerpTag = R_LerpTag;
  1130. re.ModelBounds = R_ModelBounds;
  1131. re.ClearScene = RE_ClearScene;
  1132. re.AddRefEntityToScene = RE_AddRefEntityToScene;
  1133. re.AddPolyToScene = RE_AddPolyToScene;
  1134. // Ridah
  1135. re.AddPolysToScene = RE_AddPolysToScene;
  1136. // done.
  1137. re.AddLightToScene = RE_AddLightToScene;
  1138. //----(SA)
  1139. re.AddCoronaToScene = RE_AddCoronaToScene;
  1140. re.SetFog = R_SetFog;
  1141. //----(SA)
  1142. re.RenderScene = RE_RenderScene;
  1143. re.SetColor = RE_SetColor;
  1144. re.DrawStretchPic = RE_StretchPic;
  1145. re.DrawStretchPicGradient = RE_StretchPicGradient;
  1146. re.DrawStretchRaw = RE_StretchRaw;
  1147. re.UploadCinematic = RE_UploadCinematic;
  1148. re.RegisterFont = RE_RegisterFont;
  1149. re.RemapShader = R_RemapShader;
  1150. re.GetEntityToken = R_GetEntityToken;
  1151. #ifdef BLAH // MrE __USEA3D
  1152. re.A3D_RenderGeometry = RE_A3D_RenderGeometry;
  1153. #endif
  1154. // RF
  1155. re.ZombieFXAddNewHit = RB_ZombieFXAddNewHit;
  1156. return &re;
  1157. }