1 /*
2 ===========================================================================
3 Copyright (C) 1999-2005 Id Software, Inc.
4 Copyright (C) 2006 Robert Beckebans <trebor_7@users.sourceforge.net>
5 
6 This file is part of XreaL source code.
7 
8 XreaL source code is free software; you can redistribute it
9 and/or modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of the License,
11 or (at your option) any later version.
12 
13 XreaL source code is distributed in the hope that it will be
14 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with XreaL source code; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21 ===========================================================================
22 */
23 // tr_init.c -- functions that are not called every frame
24 
25 #include "tr_local.h"
26 
27 glConfig_t      glConfig;
28 glConfig2_t     glConfig2;
29 glstate_t       glState;
30 float			displayAspect = 0.0f;
31 
32 static void     GfxInfo_f(void);
33 
34 cvar_t         *r_flareSize;
35 cvar_t         *r_flareFade;
36 cvar_t		   *r_flareCoeff;
37 
38 cvar_t         *r_railWidth;
39 cvar_t         *r_railCoreWidth;
40 cvar_t         *r_railSegmentLength;
41 
42 cvar_t         *r_verbose;
43 cvar_t         *r_ignore;
44 
45 cvar_t         *r_displayRefresh;
46 
47 cvar_t         *r_detailTextures;
48 
49 cvar_t         *r_znear;
50 cvar_t         *r_zfar;
51 
52 cvar_t         *r_smp;
53 cvar_t         *r_showSmp;
54 cvar_t         *r_skipBackEnd;
55 
56 cvar_t         *r_ignorehwgamma;
57 cvar_t         *r_measureOverdraw;
58 
59 cvar_t         *r_inGameVideo;
60 cvar_t         *r_fastsky;
61 cvar_t         *r_drawSun;
62 cvar_t         *r_drawBloom;
63 cvar_t         *r_bloomBlur;
64 cvar_t         *r_lighting;
65 cvar_t         *r_dynamicLighting;
66 
67 cvar_t         *r_lodbias;
68 cvar_t         *r_lodscale;
69 
70 cvar_t         *r_norefresh;
71 cvar_t         *r_drawentities;
72 cvar_t         *r_drawworld;
73 cvar_t         *r_speeds;
74 cvar_t         *r_fullbright;
75 cvar_t         *r_novis;
76 cvar_t         *r_nocull;
77 cvar_t         *r_showcluster;
78 cvar_t         *r_nocurves;
79 cvar_t         *r_nobatching;
80 cvar_t         *r_noLightScissors;
81 cvar_t         *r_noLightVisCull;
82 cvar_t         *r_noInteractionSort;
83 
84 cvar_t         *r_allowExtensions;
85 
86 cvar_t         *r_ext_compressed_textures;
87 cvar_t         *r_ext_multitexture;
88 cvar_t         *r_ext_compiled_vertex_array;
89 cvar_t         *r_ext_texture_env_add;
90 cvar_t         *r_ext_multisample;
91 cvar_t         *r_ext_texture_non_power_of_two;
92 cvar_t         *r_ext_texture_cube_map;
93 cvar_t         *r_ext_depth_texture;
94 cvar_t         *r_ext_vertex_program;
95 cvar_t         *r_ext_vertex_buffer_object;
96 cvar_t         *r_ext_occlusion_query;
97 cvar_t         *r_ext_shading_language_100;
98 cvar_t         *r_ext_stencil_wrap;
99 cvar_t         *r_ext_texture_filter_anisotropic;
100 cvar_t         *r_ext_stencil_two_side;
101 cvar_t         *r_ext_depth_bounds_test;
102 cvar_t         *r_ext_framebuffer_object;
103 cvar_t         *r_ext_generate_mipmap;
104 
105 cvar_t         *r_ignoreGLErrors;
106 cvar_t         *r_logFile;
107 
108 cvar_t         *r_stencilbits;
109 cvar_t         *r_depthbits;
110 cvar_t         *r_colorbits;
111 cvar_t         *r_stereo;
112 cvar_t         *r_texturebits;
113 
114 cvar_t         *r_drawBuffer;
115 cvar_t         *r_uiFullScreen;
116 cvar_t         *r_shadows;
117 cvar_t         *r_shadowOffsetFactor;
118 cvar_t         *r_shadowOffsetUnits;
119 cvar_t         *r_drawFlares;
120 cvar_t         *r_noLightFrustums;
121 cvar_t         *r_mode;
122 cvar_t         *r_collapseStages;
123 cvar_t         *r_nobind;
124 cvar_t         *r_singleShader;
125 cvar_t         *r_roundImagesDown;
126 cvar_t         *r_colorMipLevels;
127 cvar_t         *r_picmip;
128 cvar_t         *r_showtris;
129 cvar_t         *r_showsky;
130 cvar_t         *r_shownormals;
131 cvar_t         *r_showTangentSpaces;
132 cvar_t         *r_finish;
133 cvar_t         *r_clear;
134 cvar_t         *r_swapInterval;
135 cvar_t         *r_textureMode;
136 cvar_t         *r_offsetFactor;
137 cvar_t         *r_offsetUnits;
138 cvar_t         *r_specularExponent;
139 cvar_t         *r_gamma;
140 cvar_t         *r_intensity;
141 cvar_t         *r_lockpvs;
142 cvar_t         *r_noportals;
143 cvar_t         *r_portalOnly;
144 
145 cvar_t         *r_subdivisions;
146 
147 cvar_t         *r_fullscreen;
148 
149 cvar_t         *r_customwidth;
150 cvar_t         *r_customheight;
151 cvar_t         *r_customaspect;
152 
153 cvar_t         *r_overBrightBits;
154 cvar_t         *r_mapOverBrightBits;
155 
156 cvar_t         *r_simpleMipMaps;
157 
158 cvar_t         *r_showImages;
159 
160 cvar_t         *r_ambientScale;
161 cvar_t         *r_directedScale;
162 cvar_t         *r_lightScale;
163 cvar_t         *r_debugLight;
164 cvar_t         *r_debugSort;
165 
166 cvar_t         *r_maxpolys;
167 int             max_polys;
168 cvar_t         *r_maxpolyverts;
169 int             max_polyverts;
170 
171 cvar_t         *r_showLightMaps;
172 cvar_t         *r_showDeluxeMaps;
173 cvar_t         *r_showNormalMaps;
174 cvar_t         *r_showShadowVolumes;
175 cvar_t         *r_showSkeleton;
176 cvar_t         *r_showEntityTransforms;
177 cvar_t         *r_showLightTransforms;
178 cvar_t         *r_showLightInteractions;
179 cvar_t         *r_showLightScissors;
180 cvar_t         *r_showOcclusionQueries;
181 
182 cvar_t         *r_vboFaces;
183 cvar_t         *r_vboCurves;
184 cvar_t         *r_vboTriangles;
185 
AssertCvarRange(cvar_t * cv,float minVal,float maxVal,qboolean shouldBeIntegral)186 static void AssertCvarRange(cvar_t * cv, float minVal, float maxVal, qboolean shouldBeIntegral)
187 {
188 	if(shouldBeIntegral)
189 	{
190 		if((int)cv->value != cv->integer)
191 		{
192 			ri.Printf(PRINT_WARNING, "WARNING: cvar '%s' must be integral (%f)\n", cv->name, cv->value);
193 			ri.Cvar_Set(cv->name, va("%d", cv->integer));
194 		}
195 	}
196 
197 	if(cv->value < minVal)
198 	{
199 		ri.Printf(PRINT_WARNING, "WARNING: cvar '%s' out of range (%f < %f)\n", cv->name, cv->value, minVal);
200 		ri.Cvar_Set(cv->name, va("%f", minVal));
201 	}
202 	else if(cv->value > maxVal)
203 	{
204 		ri.Printf(PRINT_WARNING, "WARNING: cvar '%s' out of range (%f > %f)\n", cv->name, cv->value, maxVal);
205 		ri.Cvar_Set(cv->name, va("%f", maxVal));
206 	}
207 }
208 
209 
210 
211 /*
212 ** InitOpenGL
213 **
214 ** This function is responsible for initializing a valid OpenGL subsystem.  This
215 ** is done by calling GLimp_Init (which gives us a working OGL subsystem) then
216 ** setting variables, checking GL constants, and reporting the gfx system config
217 ** to the user.
218 */
InitOpenGL(void)219 static void InitOpenGL(void)
220 {
221 	char            renderer_buffer[1024];
222 
223 	//
224 	// initialize OS specific portions of the renderer
225 	//
226 	// GLimp_Init directly or indirectly references the following cvars:
227 	//      - r_fullscreen
228 	//      - r_mode
229 	//      - r_(color|depth|stencil)bits
230 	//      - r_ignorehwgamma
231 	//      - r_gamma
232 	//
233 
234 	if(glConfig.vidWidth == 0)
235 	{
236 		GLint           temp;
237 
238 		GLimp_Init();
239 
240 		strcpy(renderer_buffer, glConfig.renderer_string);
241 		Q_strlwr(renderer_buffer);
242 
243 		// OpenGL driver constants
244 		qglGetIntegerv(GL_MAX_TEXTURE_SIZE, &temp);
245 		glConfig.maxTextureSize = temp;
246 
247 		// stubbed or broken drivers may have reported 0...
248 		if(glConfig.maxTextureSize <= 0)
249 		{
250 			glConfig.maxTextureSize = 0;
251 		}
252 	}
253 
254 	// init command buffers and SMP
255 	R_InitCommandBuffers();
256 
257 	// print info
258 	GfxInfo_f();
259 
260 	// set default state
261 	GL_SetDefaultState();
262 }
263 
264 /*
265 ==================
266 GL_CheckErrors
267 ==================
268 */
GL_CheckErrors_(const char * filename,int line)269 void GL_CheckErrors_(const char *filename, int line)
270 {
271 	int             err;
272 	char            s[128];
273 
274 	if(glConfig.smpActive)
275 	{
276 		// we can't print onto the console while rendering in another thread
277 		return;
278 	}
279 
280 	if(r_ignoreGLErrors->integer)
281 	{
282 		return;
283 	}
284 
285 	err = qglGetError();
286 	if(err == GL_NO_ERROR)
287 	{
288 		return;
289 	}
290 
291 	switch (err)
292 	{
293 		case GL_INVALID_ENUM:
294 			strcpy(s, "GL_INVALID_ENUM");
295 			break;
296 		case GL_INVALID_VALUE:
297 			strcpy(s, "GL_INVALID_VALUE");
298 			break;
299 		case GL_INVALID_OPERATION:
300 			strcpy(s, "GL_INVALID_OPERATION");
301 			break;
302 		case GL_STACK_OVERFLOW:
303 			strcpy(s, "GL_STACK_OVERFLOW");
304 			break;
305 		case GL_STACK_UNDERFLOW:
306 			strcpy(s, "GL_STACK_UNDERFLOW");
307 			break;
308 		case GL_OUT_OF_MEMORY:
309 			strcpy(s, "GL_OUT_OF_MEMORY");
310 			break;
311 		case GL_TABLE_TOO_LARGE:
312 			strcpy(s, "GL_TABLE_TOO_LARGE");
313 			break;
314 		case GL_INVALID_FRAMEBUFFER_OPERATION_EXT:
315 			strcpy(s, "GL_INVALID_FRAMEBUFFER_OPERATION_EXT");
316 			break;
317 		default:
318 			Com_sprintf(s, sizeof(s), "%i", err);
319 			break;
320 	}
321 
322 	ri.Error(ERR_FATAL, "caught OpenGL error: %s in file %s line %i", s, filename, line);
323 }
324 
325 
326 /*
327 ** R_GetModeInfo
328 */
329 typedef struct vidmode_s
330 {
331 	const char     *description;
332 	int             width, height;
333 	float           pixelAspect;	// pixel width / height
334 } vidmode_t;
335 
336 vidmode_t       r_vidModes[] = {
337 	{"Mode  0: 320x240", 320, 240, 1},
338 	{"Mode  1: 400x300", 400, 300, 1},
339 	{"Mode  2: 512x384", 512, 384, 1},
340 	{"Mode  3: 640x480", 640, 480, 1},
341 	{"Mode  4: 800x600", 800, 600, 1},
342 	{"Mode  5: 960x720", 960, 720, 1},
343 	{"Mode  6: 1024x768", 1024, 768, 1},
344 	{"Mode  7: 1152x864", 1152, 864, 1},
345 	{"Mode  8: 1280x1024", 1280, 1024, 1},
346 	{"Mode  9: 1600x1200", 1600, 1200, 1},
347 	{"Mode 10: 2048x1536", 2048, 1536, 1},
348 	{"Mode 11: 856x480 (wide)", 856, 480, 1}
349 };
350 static int      s_numVidModes = (sizeof(r_vidModes) / sizeof(r_vidModes[0]));
351 
R_GetModeInfo(int * width,int * height,float * windowAspect,int mode)352 qboolean R_GetModeInfo(int *width, int *height, float *windowAspect, int mode)
353 {
354 	vidmode_t      *vm;
355 
356 	if(mode < -1)
357 	{
358 		return qfalse;
359 	}
360 	if(mode >= s_numVidModes)
361 	{
362 		return qfalse;
363 	}
364 
365 	if(mode == -1)
366 	{
367 		*width = r_customwidth->integer;
368 		*height = r_customheight->integer;
369 		*windowAspect = r_customaspect->value;
370 		return qtrue;
371 	}
372 
373 	vm = &r_vidModes[mode];
374 
375 	*width = vm->width;
376 	*height = vm->height;
377 	*windowAspect = (float)vm->width / (vm->height * vm->pixelAspect);
378 
379 	return qtrue;
380 }
381 
382 /*
383 ** R_ModeList_f
384 */
R_ModeList_f(void)385 static void R_ModeList_f(void)
386 {
387 	int             i;
388 
389 	ri.Printf(PRINT_ALL, "\n");
390 	for(i = 0; i < s_numVidModes; i++)
391 	{
392 		ri.Printf(PRINT_ALL, "%s\n", r_vidModes[i].description);
393 	}
394 	ri.Printf(PRINT_ALL, "\n");
395 }
396 
397 
398 /*
399 ==============================================================================
400 
401 						SCREEN SHOTS
402 
403 NOTE TTimo
404 some thoughts about the screenshots system:
405 screenshots get written in fs_homepath + fs_gamedir
406 vanilla q3 .. baseq3/screenshots/ *.tga
407 team arena .. missionpack/screenshots/ *.tga
408 
409 two commands: "screenshot" and "screenshotJPEG"
410 we use statics to store a count and start writing the first screenshot/screenshot????.tga (.jpg) available
411 (with FS_FileExists / FS_FOpenFileWrite calls)
412 FIXME: the statics don't get a reinit between fs_game changes
413 
414 ==============================================================================
415 */
416 
417 /*
418 ==================
419 RB_TakeScreenshot
420 ==================
421 */
RB_TakeScreenshot(int x,int y,int width,int height,char * fileName)422 void RB_TakeScreenshot(int x, int y, int width, int height, char *fileName)
423 {
424 	byte           *buffer;
425 	int             i, c, temp;
426 
427 	buffer = ri.Hunk_AllocateTempMemory(glConfig.vidWidth * glConfig.vidHeight * 3 + 18);
428 
429 	Com_Memset(buffer, 0, 18);
430 	buffer[2] = 2;				// uncompressed type
431 	buffer[12] = width & 255;
432 	buffer[13] = width >> 8;
433 	buffer[14] = height & 255;
434 	buffer[15] = height >> 8;
435 	buffer[16] = 24;			// pixel size
436 
437 	qglReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer + 18);
438 
439 	// swap rgb to bgr
440 	c = 18 + width * height * 3;
441 	for(i = 18; i < c; i += 3)
442 	{
443 		temp = buffer[i];
444 		buffer[i] = buffer[i + 2];
445 		buffer[i + 2] = temp;
446 	}
447 
448 	// gamma correct
449 	if((tr.overbrightBits > 0) && glConfig.deviceSupportsGamma)
450 	{
451 		R_GammaCorrect(buffer + 18, glConfig.vidWidth * glConfig.vidHeight * 3);
452 	}
453 
454 	ri.FS_WriteFile(fileName, buffer, c);
455 
456 	ri.Hunk_FreeTempMemory(buffer);
457 }
458 
459 /*
460 ==================
461 RB_TakeScreenshotJPEG
462 ==================
463 */
RB_TakeScreenshotJPEG(int x,int y,int width,int height,char * fileName)464 void RB_TakeScreenshotJPEG(int x, int y, int width, int height, char *fileName)
465 {
466 	byte           *buffer;
467 
468 	buffer = ri.Hunk_AllocateTempMemory(glConfig.vidWidth * glConfig.vidHeight * 4);
469 
470 	qglReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
471 
472 	// gamma correct
473 	if((tr.overbrightBits > 0) && glConfig.deviceSupportsGamma)
474 	{
475 		R_GammaCorrect(buffer, glConfig.vidWidth * glConfig.vidHeight * 4);
476 	}
477 
478 	ri.FS_WriteFile(fileName, buffer, 1);	// create path
479 //	SaveJPG(fileName, 95, glConfig.vidWidth, glConfig.vidHeight, buffer);
480 
481 	ri.Hunk_FreeTempMemory(buffer);
482 }
483 
484 /*
485 ==================
486 RB_TakeScreenshotCmd
487 ==================
488 */
RB_TakeScreenshotCmd(const void * data)489 const void     *RB_TakeScreenshotCmd(const void *data)
490 {
491 	const screenshotCommand_t *cmd;
492 
493 	cmd = (const screenshotCommand_t *)data;
494 
495 	if(cmd->jpeg)
496 		RB_TakeScreenshotJPEG(cmd->x, cmd->y, cmd->width, cmd->height, cmd->fileName);
497 	else
498 		RB_TakeScreenshot(cmd->x, cmd->y, cmd->width, cmd->height, cmd->fileName);
499 
500 	return (const void *)(cmd + 1);
501 }
502 
503 /*
504 ==================
505 R_TakeScreenshot
506 ==================
507 */
R_TakeScreenshot(int x,int y,int width,int height,char * name,qboolean jpeg)508 void R_TakeScreenshot(int x, int y, int width, int height, char *name, qboolean jpeg)
509 {
510 	static char     fileName[MAX_OSPATH];	// bad things if two screenshots per frame?
511 	screenshotCommand_t *cmd;
512 
513 	cmd = R_GetCommandBuffer(sizeof(*cmd));
514 	if(!cmd)
515 	{
516 		return;
517 	}
518 	cmd->commandId = RC_SCREENSHOT;
519 
520 	cmd->x = x;
521 	cmd->y = y;
522 	cmd->width = width;
523 	cmd->height = height;
524 	Q_strncpyz(fileName, name, sizeof(fileName));
525 	cmd->fileName = fileName;
526 	cmd->jpeg = jpeg;
527 }
528 
529 
530 /*
531 ==================
532 R_ScreenshotFilename
533 ==================
534 */
R_ScreenshotFilename(int lastNumber,char * fileName)535 void R_ScreenshotFilename(int lastNumber, char *fileName)
536 {
537 	int             a, b, c, d;
538 
539 	if(lastNumber < 0 || lastNumber > 9999)
540 	{
541 		Com_sprintf(fileName, MAX_OSPATH, "screenshots/shot9999.tga");
542 		return;
543 	}
544 
545 	a = lastNumber / 1000;
546 	lastNumber -= a * 1000;
547 	b = lastNumber / 100;
548 	lastNumber -= b * 100;
549 	c = lastNumber / 10;
550 	lastNumber -= c * 10;
551 	d = lastNumber;
552 
553 	Com_sprintf(fileName, MAX_OSPATH, "screenshots/shot%i%i%i%i.tga", a, b, c, d);
554 }
555 
556 
557 /*
558 ==================
559 R_ScreenshotFilename
560 ==================
561 */
R_ScreenshotFilenameJPEG(int lastNumber,char * fileName)562 void R_ScreenshotFilenameJPEG(int lastNumber, char *fileName)
563 {
564 	int             a, b, c, d;
565 
566 	if(lastNumber < 0 || lastNumber > 9999)
567 	{
568 		Com_sprintf(fileName, MAX_OSPATH, "screenshots/shot9999.jpg");
569 		return;
570 	}
571 
572 	a = lastNumber / 1000;
573 	lastNumber -= a * 1000;
574 	b = lastNumber / 100;
575 	lastNumber -= b * 100;
576 	c = lastNumber / 10;
577 	lastNumber -= c * 10;
578 	d = lastNumber;
579 
580 	Com_sprintf(fileName, MAX_OSPATH, "screenshots/shot%i%i%i%i.jpg", a, b, c, d);
581 }
582 
583 
584 /*
585 ====================
586 R_LevelShot
587 
588 levelshots are specialized 128*128 thumbnails for
589 the menu system, sampled down from full screen distorted images
590 ====================
591 */
R_LevelShot(void)592 void R_LevelShot(void)
593 {
594 	char            checkname[MAX_OSPATH];
595 	byte           *buffer;
596 	byte           *source;
597 	byte           *src, *dst;
598 	int             x, y;
599 	int             r, g, b;
600 	float           xScale, yScale;
601 	int             xx, yy;
602 
603 	sprintf(checkname, "levelshots/%s.tga", tr.world->baseName);
604 
605 	source = ri.Hunk_AllocateTempMemory(glConfig.vidWidth * glConfig.vidHeight * 3);
606 
607 	buffer = ri.Hunk_AllocateTempMemory(128 * 128 * 3 + 18);
608 	Com_Memset(buffer, 0, 18);
609 	buffer[2] = 2;				// uncompressed type
610 	buffer[12] = 128;
611 	buffer[14] = 128;
612 	buffer[16] = 24;			// pixel size
613 
614 	qglReadPixels(0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_RGB, GL_UNSIGNED_BYTE, source);
615 
616 	// resample from source
617 	xScale = glConfig.vidWidth / 512.0f;
618 	yScale = glConfig.vidHeight / 384.0f;
619 	for(y = 0; y < 128; y++)
620 	{
621 		for(x = 0; x < 128; x++)
622 		{
623 			r = g = b = 0;
624 			for(yy = 0; yy < 3; yy++)
625 			{
626 				for(xx = 0; xx < 4; xx++)
627 				{
628 					src = source + 3 * (glConfig.vidWidth * (int)((y * 3 + yy) * yScale) + (int)((x * 4 + xx) * xScale));
629 					r += src[0];
630 					g += src[1];
631 					b += src[2];
632 				}
633 			}
634 			dst = buffer + 18 + 3 * (y * 128 + x);
635 			dst[0] = b / 12;
636 			dst[1] = g / 12;
637 			dst[2] = r / 12;
638 		}
639 	}
640 
641 	// gamma correct
642 	if((tr.overbrightBits > 0) && glConfig.deviceSupportsGamma)
643 	{
644 		R_GammaCorrect(buffer + 18, 128 * 128 * 3);
645 	}
646 
647 	ri.FS_WriteFile(checkname, buffer, 128 * 128 * 3 + 18);
648 
649 	ri.Hunk_FreeTempMemory(buffer);
650 	ri.Hunk_FreeTempMemory(source);
651 
652 	ri.Printf(PRINT_ALL, "Wrote %s\n", checkname);
653 }
654 
655 
656 /*
657 ==================
658 R_ScreenShot_f
659 
660 screenshot
661 screenshot [silent]
662 screenshot [levelshot]
663 screenshot [filename]
664 
665 Doesn't print the pacifier message if there is a second arg
666 ==================
667 */
R_ScreenShot_f(void)668 void R_ScreenShot_f(void)
669 {
670 	char            checkname[MAX_OSPATH];
671 	static int      lastNumber = -1;
672 	qboolean        silent;
673 
674 	if(!strcmp(ri.Cmd_Argv(1), "levelshot"))
675 	{
676 		R_LevelShot();
677 		return;
678 	}
679 
680 	if(!strcmp(ri.Cmd_Argv(1), "silent"))
681 	{
682 		silent = qtrue;
683 	}
684 	else
685 	{
686 		silent = qfalse;
687 	}
688 
689 	if(ri.Cmd_Argc() == 2 && !silent)
690 	{
691 		// explicit filename
692 		Com_sprintf(checkname, MAX_OSPATH, "screenshots/%s.tga", ri.Cmd_Argv(1));
693 	}
694 	else
695 	{
696 		// scan for a free filename
697 
698 		// if we have saved a previous screenshot, don't scan
699 		// again, because recording demo avis can involve
700 		// thousands of shots
701 		if(lastNumber == -1)
702 		{
703 			lastNumber = 0;
704 		}
705 		// scan for a free number
706 		for(; lastNumber <= 9999; lastNumber++)
707 		{
708 			R_ScreenshotFilename(lastNumber, checkname);
709 
710 			if(!ri.FS_FileExists(checkname))
711 			{
712 				break;			// file doesn't exist
713 			}
714 		}
715 
716 		if(lastNumber >= 9999)
717 		{
718 			ri.Printf(PRINT_ALL, "ScreenShot: Couldn't create a file\n");
719 			return;
720 		}
721 
722 		lastNumber++;
723 	}
724 
725 	R_TakeScreenshot(0, 0, glConfig.vidWidth, glConfig.vidHeight, checkname, qfalse);
726 
727 	if(!silent)
728 	{
729 		ri.Printf(PRINT_ALL, "Wrote %s\n", checkname);
730 	}
731 }
732 
733 
R_ScreenShotJPEG_f(void)734 void R_ScreenShotJPEG_f(void)
735 {
736 	char            checkname[MAX_OSPATH];
737 	static int      lastNumber = -1;
738 	qboolean        silent;
739 
740 	if(!strcmp(ri.Cmd_Argv(1), "levelshot"))
741 	{
742 		R_LevelShot();
743 		return;
744 	}
745 
746 	if(!strcmp(ri.Cmd_Argv(1), "silent"))
747 	{
748 		silent = qtrue;
749 	}
750 	else
751 	{
752 		silent = qfalse;
753 	}
754 
755 	if(ri.Cmd_Argc() == 2 && !silent)
756 	{
757 		// explicit filename
758 		Com_sprintf(checkname, MAX_OSPATH, "screenshots/%s.jpg", ri.Cmd_Argv(1));
759 	}
760 	else
761 	{
762 		// scan for a free filename
763 
764 		// if we have saved a previous screenshot, don't scan
765 		// again, because recording demo avis can involve
766 		// thousands of shots
767 		if(lastNumber == -1)
768 		{
769 			lastNumber = 0;
770 		}
771 		// scan for a free number
772 		for(; lastNumber <= 9999; lastNumber++)
773 		{
774 			R_ScreenshotFilenameJPEG(lastNumber, checkname);
775 
776 			if(!ri.FS_FileExists(checkname))
777 			{
778 				break;			// file doesn't exist
779 			}
780 		}
781 
782 		if(lastNumber == 10000)
783 		{
784 			ri.Printf(PRINT_ALL, "ScreenShot: Couldn't create a file\n");
785 			return;
786 		}
787 
788 		lastNumber++;
789 	}
790 
791 	R_TakeScreenshot(0, 0, glConfig.vidWidth, glConfig.vidHeight, checkname, qtrue);
792 
793 	if(!silent)
794 	{
795 		ri.Printf(PRINT_ALL, "Wrote %s\n", checkname);
796 	}
797 }
798 
799 //============================================================================
800 
801 /*
802 ** GL_SetDefaultState
803 */
GL_SetDefaultState(void)804 void GL_SetDefaultState(void)
805 {
806 	int             i;
807 
808 	GLimp_LogComment("--- GL_SetDefaultState ---\n");
809 
810 	qglClearDepth(1.0f);
811 
812 	if(glConfig.stencilBits >= 4)
813 	{
814 		qglClearStencil(128);
815 	}
816 
817 	qglFrontFace(GL_CCW);
818 	qglCullFace(GL_FRONT);
819 
820 	qglColor4f(1, 1, 1, 1);
821 
822 	// initialize downstream texture units if we're running
823 	// in a multitexture environment
824 	if(qglActiveTextureARB)
825 	{
826 		for(i = glConfig.maxTextureUnits - 1; i >= 0; i--)
827 		{
828 			GL_SelectTexture(i);
829 			GL_TextureMode(r_textureMode->string);
830 			GL_TexEnv(GL_MODULATE);
831 
832 			if(i != 0)
833 				qglDisable(GL_TEXTURE_2D);
834 			else
835 				qglEnable(GL_TEXTURE_2D);
836 		}
837 	}
838 
839 	qglShadeModel(GL_SMOOTH);
840 	qglDepthFunc(GL_LEQUAL);
841 
842 	// the vertex array is always enabled, but the color and texture
843 	// arrays are enabled and disabled around the compiled vertex array call
844 	qglEnableClientState(GL_VERTEX_ARRAY);
845 
846 	// make sure our GL state vector is set correctly
847 	glState.glStateBits = GLS_DEPTHTEST_DISABLE | GLS_DEPTHMASK_TRUE;
848 	glState.glClientStateBits = GLCS_DEFAULT;
849 	glState.currentProgram = 0;
850 
851 	qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
852 	qglDepthMask(GL_TRUE);
853 	qglDisable(GL_DEPTH_TEST);
854 	qglEnable(GL_SCISSOR_TEST);
855 	qglDisable(GL_CULL_FACE);
856 	qglDisable(GL_BLEND);
857 }
858 
859 
860 
861 /*
862 ================
863 GfxInfo_f
864 ================
865 */
GfxInfo_f(void)866 void GfxInfo_f(void)
867 {
868 	const char     *enablestrings[] = {
869 		"disabled",
870 		"enabled"
871 	};
872 	const char     *fsstrings[] = {
873 		"windowed",
874 		"fullscreen"
875 	};
876 
877 	ri.Printf(PRINT_ALL, "\nGL_VENDOR: %s\n", glConfig.vendor_string);
878 	ri.Printf(PRINT_ALL, "GL_RENDERER: %s\n", glConfig.renderer_string);
879 	ri.Printf(PRINT_ALL, "GL_VERSION: %s\n", glConfig.version_string);
880 	ri.Printf(PRINT_ALL, "GL_EXTENSIONS: %s\n", glConfig.extensions_string);
881 	ri.Printf(PRINT_ALL, "GL_MAX_TEXTURE_SIZE: %d\n", glConfig.maxTextureSize);
882 	ri.Printf(PRINT_ALL, "GL_MAX_TEXTURE_UNITS_ARB: %d\n", glConfig.maxTextureUnits);
883 
884 	if(glConfig2.textureAnisotropyAvailable)
885 	{
886 		ri.Printf(PRINT_ALL, "GL_TEXTURE_MAX_ANISOTROPY_EXT: %f\n", glConfig2.maxTextureAnisotropy);
887 	}
888 
889 	if(glConfig2.occlusionQueryAvailable)
890 	{
891 		ri.Printf(PRINT_ALL, "%d occlusion query bits\n", glConfig2.occlusionQueryBits);
892 	}
893 
894 	if(glConfig2.framebufferObjectAvailable)
895 	{
896 		ri.Printf(PRINT_ALL, "GL_MAX_RENDERBUFFER_SIZE_EXT: %d\n", glConfig2.maxRenderbufferSize);
897 		ri.Printf(PRINT_ALL, "GL_MAX_COLOR_ATTACHMENTS_EXT: %d\n", glConfig2.maxColorAttachments);
898 	}
899 
900 	ri.Printf(PRINT_ALL, "\nPIXELFORMAT: color(%d-bits) Z(%d-bit) stencil(%d-bits)\n", glConfig.colorBits,
901 			  glConfig.depthBits, glConfig.stencilBits);
902 	ri.Printf(PRINT_ALL, "MODE: %d, %d x %d %s hz:", r_mode->integer, glConfig.vidWidth, glConfig.vidHeight,
903 			  fsstrings[r_fullscreen->integer == 1]);
904 
905 	if(glConfig.displayFrequency)
906 	{
907 		ri.Printf(PRINT_ALL, "%d\n", glConfig.displayFrequency);
908 	}
909 	else
910 	{
911 		ri.Printf(PRINT_ALL, "N/A\n");
912 	}
913 
914 	if(glConfig.deviceSupportsGamma)
915 	{
916 		ri.Printf(PRINT_ALL, "GAMMA: hardware w/ %d overbright bits\n", tr.overbrightBits);
917 	}
918 	else
919 	{
920 		ri.Printf(PRINT_ALL, "GAMMA: software w/ %d overbright bits\n", tr.overbrightBits);
921 	}
922 
923 	ri.Printf(PRINT_ALL, "texturemode: %s\n", r_textureMode->string);
924 	ri.Printf(PRINT_ALL, "picmip: %d\n", r_picmip->integer);
925 	ri.Printf(PRINT_ALL, "texture bits: %d\n", r_texturebits->integer);
926 	ri.Printf(PRINT_ALL, "multitexture: %s\n", enablestrings[qglActiveTextureARB != 0]);
927 	ri.Printf(PRINT_ALL, "compiled vertex arrays: %s\n", enablestrings[qglLockArraysEXT != 0]);
928 	ri.Printf(PRINT_ALL, "texenv add: %s\n", enablestrings[glConfig.textureEnvAddAvailable != 0]);
929 	ri.Printf(PRINT_ALL, "compressed textures: %s\n", enablestrings[glConfig.textureCompression != TC_NONE]);
930 
931 	if(glConfig.hardwareType == GLHW_RAGEPRO)
932 	{
933 		ri.Printf(PRINT_ALL, "HACK: ragePro approximations\n");
934 	}
935 
936 	if(glConfig.hardwareType == GLHW_RIVA128)
937 	{
938 		ri.Printf(PRINT_ALL, "HACK: riva128 approximations\n");
939 	}
940 
941 	if(glConfig.hardwareType == GLHW_ATI)
942 	{
943 		ri.Printf(PRINT_ALL, "HACK: ATI approximations\n");
944 	}
945 
946 	if(glConfig.smpActive)
947 	{
948 		ri.Printf(PRINT_ALL, "Using dual processor acceleration\n");
949 	}
950 
951 	if(r_finish->integer)
952 	{
953 		ri.Printf(PRINT_ALL, "Forcing glFinish\n");
954 	}
955 }
956 
957 /*
958 ===============
959 R_Register
960 ===============
961 */
R_Register(void)962 void R_Register(void)
963 {
964 	//
965 	// latched and archived variables
966 	//
967 	r_allowExtensions = ri.Cvar_Get("r_allowExtensions", "1", CVAR_ARCHIVE | CVAR_LATCH);
968 	r_ext_compressed_textures = ri.Cvar_Get("r_ext_compressed_textures", "0", CVAR_ARCHIVE | CVAR_LATCH);
969 	r_ext_multitexture = ri.Cvar_Get("r_ext_multitexture", "1", CVAR_ARCHIVE | CVAR_LATCH);
970 	r_ext_compiled_vertex_array = ri.Cvar_Get("r_ext_compiled_vertex_array", "1", CVAR_ARCHIVE | CVAR_LATCH);
971 	r_ext_texture_env_add = ri.Cvar_Get("r_ext_texture_env_add", "1", CVAR_ARCHIVE | CVAR_LATCH);
972 	r_ext_multisample = ri.Cvar_Get("r_ext_multisample", "0", CVAR_ARCHIVE | CVAR_LATCH);
973 	r_ext_texture_non_power_of_two = ri.Cvar_Get("r_ext_texture_non_power_of_two", "1", CVAR_CHEAT | CVAR_LATCH);
974 	r_ext_texture_cube_map = ri.Cvar_Get("r_ext_texture_cube_map", "1", CVAR_ARCHIVE | CVAR_LATCH);
975 	r_ext_depth_texture = ri.Cvar_Get("r_ext_depth_texture", "1", CVAR_ARCHIVE | CVAR_LATCH);
976 	r_ext_vertex_program = ri.Cvar_Get("r_ext_vertex_program", "1", CVAR_ARCHIVE | CVAR_LATCH);
977 	r_ext_vertex_buffer_object = ri.Cvar_Get("r_ext_vertex_buffer_object", "0", CVAR_ARCHIVE | CVAR_LATCH);
978 	r_ext_occlusion_query = ri.Cvar_Get("r_ext_occlusion_query", "0", CVAR_ARCHIVE | CVAR_LATCH);
979 	r_ext_stencil_wrap = ri.Cvar_Get("r_ext_stencil_wrap", "1", CVAR_ARCHIVE | CVAR_LATCH);
980 	r_ext_shading_language_100 = ri.Cvar_Get("r_ext_shading_language_100", "1", CVAR_ARCHIVE | CVAR_LATCH);
981 	r_ext_texture_filter_anisotropic = ri.Cvar_Get("r_ext_texture_filter_anisotropic", "16", CVAR_ARCHIVE | CVAR_LATCH);
982 	r_ext_stencil_two_side = ri.Cvar_Get("r_ext_stencil_two_side", "1", CVAR_ARCHIVE | CVAR_LATCH);
983 	r_ext_depth_bounds_test = ri.Cvar_Get("r_ext_depth_bounds_test", "1", CVAR_ARCHIVE | CVAR_LATCH);
984 	r_ext_framebuffer_object = ri.Cvar_Get("r_ext_framebuffer_object", "1", CVAR_ARCHIVE | CVAR_LATCH);
985 	r_ext_generate_mipmap = ri.Cvar_Get("r_ext_generate_mipmap", "1", CVAR_CHEAT | CVAR_LATCH);
986 
987 	r_collapseStages = ri.Cvar_Get("r_collapseStages", "1", CVAR_LATCH | CVAR_CHEAT);
988 	r_picmip = ri.Cvar_Get("r_picmip", "0", CVAR_ARCHIVE | CVAR_LATCH);
989 	AssertCvarRange(r_picmip, 0, 16, qtrue);
990 	r_roundImagesDown = ri.Cvar_Get("r_roundImagesDown", "1", CVAR_ARCHIVE | CVAR_LATCH);
991 	r_colorMipLevels = ri.Cvar_Get("r_colorMipLevels", "0", CVAR_LATCH);
992 	r_detailTextures = ri.Cvar_Get("r_detailtextures", "1", CVAR_ARCHIVE | CVAR_LATCH);
993 	r_texturebits = ri.Cvar_Get("r_texturebits", "0", CVAR_ARCHIVE | CVAR_LATCH);
994 	r_colorbits = ri.Cvar_Get("r_colorbits", "0", CVAR_ARCHIVE | CVAR_LATCH);
995 	r_stereo = ri.Cvar_Get("r_stereo", "0", CVAR_ARCHIVE | CVAR_LATCH);
996 	r_stencilbits = ri.Cvar_Get("r_stencilbits", "8", CVAR_ARCHIVE | CVAR_LATCH);
997 	r_depthbits = ri.Cvar_Get("r_depthbits", "0", CVAR_ARCHIVE | CVAR_LATCH);
998 	r_overBrightBits = ri.Cvar_Get("r_overBrightBits", "1", CVAR_ARCHIVE | CVAR_LATCH);
999 	r_ignorehwgamma = ri.Cvar_Get("r_ignorehwgamma", "0", CVAR_ARCHIVE | CVAR_LATCH);
1000 	r_mode = ri.Cvar_Get("r_mode", "3", CVAR_ARCHIVE | CVAR_LATCH);
1001 	r_fullscreen = ri.Cvar_Get("r_fullscreen", "1", CVAR_ARCHIVE | CVAR_LATCH);
1002 	r_customwidth = ri.Cvar_Get("r_customwidth", "1600", CVAR_ARCHIVE | CVAR_LATCH);
1003 	r_customheight = ri.Cvar_Get("r_customheight", "1024", CVAR_ARCHIVE | CVAR_LATCH);
1004 	r_customaspect = ri.Cvar_Get("r_customaspect", "1", CVAR_ARCHIVE | CVAR_LATCH);
1005 	r_simpleMipMaps = ri.Cvar_Get("r_simpleMipMaps", "1", CVAR_ARCHIVE | CVAR_LATCH);
1006 	r_uiFullScreen = ri.Cvar_Get("r_uifullscreen", "0", 0);
1007 	r_subdivisions = ri.Cvar_Get("r_subdivisions", "4", CVAR_ARCHIVE | CVAR_LATCH);
1008 	r_smp = ri.Cvar_Get("r_smp", "0", CVAR_ARCHIVE | CVAR_LATCH);
1009 
1010 	//
1011 	// temporary latched variables that can only change over a restart
1012 	//
1013 	r_displayRefresh = ri.Cvar_Get("r_displayRefresh", "0", CVAR_LATCH);
1014 	AssertCvarRange(r_displayRefresh, 0, 200, qtrue);
1015 	r_fullbright = ri.Cvar_Get("r_fullbright", "0", CVAR_LATCH | CVAR_CHEAT);
1016 	r_mapOverBrightBits = ri.Cvar_Get("r_mapOverBrightBits", "2", CVAR_LATCH);
1017 	r_intensity = ri.Cvar_Get("r_intensity", "1", CVAR_LATCH);
1018 	r_singleShader = ri.Cvar_Get("r_singleShader", "0", CVAR_CHEAT | CVAR_LATCH);
1019 
1020 	//
1021 	// archived variables that can change at any time
1022 	//
1023 	r_lodbias = ri.Cvar_Get("r_lodbias", "0", CVAR_ARCHIVE);
1024 	r_drawFlares = ri.Cvar_Get("r_drawFlares", "1", CVAR_ARCHIVE);
1025 	r_znear = ri.Cvar_Get("r_znear", "4", CVAR_CHEAT);
1026 	r_zfar = ri.Cvar_Get("r_zfar", "0", CVAR_CHEAT);
1027 	AssertCvarRange(r_znear, 0.001f, 200, qtrue);
1028 	r_ignoreGLErrors = ri.Cvar_Get("r_ignoreGLErrors", "1", CVAR_ARCHIVE);
1029 	r_fastsky = ri.Cvar_Get("r_fastsky", "0", CVAR_ARCHIVE);
1030 	r_inGameVideo = ri.Cvar_Get("r_inGameVideo", "1", CVAR_ARCHIVE);
1031 	r_drawSun = ri.Cvar_Get("r_drawSun", "0", CVAR_ARCHIVE);
1032 	r_drawBloom = ri.Cvar_Get("r_drawBloom", "0", CVAR_ARCHIVE);
1033 	r_bloomBlur = ri.Cvar_Get("r_bloomBlur", "1.2", CVAR_ARCHIVE);
1034 	r_lighting = ri.Cvar_Get("r_lighting", "2", CVAR_ARCHIVE);
1035 	AssertCvarRange(r_lighting, 0, 3, qtrue);
1036 	r_dynamicLighting = ri.Cvar_Get("r_dynamicLighting", "1", CVAR_CHEAT);
1037 	r_finish = ri.Cvar_Get("r_finish", "0", CVAR_ARCHIVE);
1038 	r_textureMode = ri.Cvar_Get("r_textureMode", "GL_LINEAR_MIPMAP_LINEAR", CVAR_ARCHIVE);
1039 	r_swapInterval = ri.Cvar_Get("r_swapInterval", "0", CVAR_ARCHIVE);
1040 	r_gamma = ri.Cvar_Get("r_gamma", "1", CVAR_ARCHIVE);
1041 
1042 	r_railWidth = ri.Cvar_Get("r_railWidth", "128", CVAR_ARCHIVE);
1043 	r_railCoreWidth = ri.Cvar_Get("r_railCoreWidth", "16", CVAR_ARCHIVE);
1044 	r_railSegmentLength = ri.Cvar_Get("r_railSegmentLength", "64", CVAR_ARCHIVE);
1045 
1046 	r_ambientScale = ri.Cvar_Get("r_ambientScale", "0.6", CVAR_CHEAT);
1047 	r_directedScale = ri.Cvar_Get("r_directedScale", "1", CVAR_CHEAT);
1048 	r_lightScale = ri.Cvar_Get("r_lightScale", "2", CVAR_CHEAT);
1049 
1050 	r_vboFaces = ri.Cvar_Get("r_vboFaces", "0", CVAR_ARCHIVE);
1051 	r_vboCurves = ri.Cvar_Get("r_vboCurves", "0", CVAR_ARCHIVE);
1052 	r_vboTriangles = ri.Cvar_Get("r_vboTriangles", "1", CVAR_ARCHIVE);
1053 
1054 	//
1055 	// temporary variables that can change at any time
1056 	//
1057 	r_showImages = ri.Cvar_Get("r_showImages", "0", CVAR_TEMP);
1058 
1059 	r_debugLight = ri.Cvar_Get("r_debuglight", "0", CVAR_TEMP);
1060 	r_debugSort = ri.Cvar_Get("r_debugSort", "0", CVAR_CHEAT);
1061 
1062 	r_nocurves = ri.Cvar_Get("r_nocurves", "0", CVAR_CHEAT);
1063 	r_nobatching = ri.Cvar_Get("r_nobatching", "0", CVAR_CHEAT);
1064 	r_noLightScissors = ri.Cvar_Get("r_noLightScissors", "0", CVAR_CHEAT);
1065 	r_noLightVisCull = ri.Cvar_Get("r_noLightVisCull", "0", CVAR_CHEAT);
1066 	r_noInteractionSort = ri.Cvar_Get("r_noInteractionSort", "0", CVAR_CHEAT);
1067 	r_drawworld = ri.Cvar_Get("r_drawworld", "1", CVAR_CHEAT);
1068 	r_portalOnly = ri.Cvar_Get("r_portalOnly", "0", CVAR_CHEAT);
1069 
1070 	r_flareSize = ri.Cvar_Get("r_flareSize", "40", CVAR_CHEAT);
1071 	r_flareFade = ri.Cvar_Get("r_flareFade", "7", CVAR_CHEAT);
1072 	r_flareCoeff = ri.Cvar_Get ("r_flareCoeff", "150", CVAR_CHEAT);
1073 
1074 	r_showSmp = ri.Cvar_Get("r_showSmp", "0", CVAR_CHEAT);
1075 	r_skipBackEnd = ri.Cvar_Get("r_skipBackEnd", "0", CVAR_CHEAT);
1076 
1077 	r_measureOverdraw = ri.Cvar_Get("r_measureOverdraw", "0", CVAR_CHEAT);
1078 	r_lodscale = ri.Cvar_Get("r_lodscale", "5", CVAR_CHEAT);
1079 	r_norefresh = ri.Cvar_Get("r_norefresh", "0", CVAR_CHEAT);
1080 	r_drawentities = ri.Cvar_Get("r_drawentities", "1", CVAR_CHEAT);
1081 	r_ignore = ri.Cvar_Get("r_ignore", "1", CVAR_CHEAT);
1082 	r_nocull = ri.Cvar_Get("r_nocull", "0", CVAR_CHEAT);
1083 	r_novis = ri.Cvar_Get("r_novis", "0", CVAR_CHEAT);
1084 	r_showcluster = ri.Cvar_Get("r_showcluster", "0", CVAR_CHEAT);
1085 	r_speeds = ri.Cvar_Get("r_speeds", "0", CVAR_CHEAT);
1086 	r_verbose = ri.Cvar_Get("r_verbose", "0", CVAR_CHEAT);
1087 	r_logFile = ri.Cvar_Get("r_logFile", "0", CVAR_CHEAT);
1088 	r_nobind = ri.Cvar_Get("r_nobind", "0", CVAR_CHEAT);
1089 	r_showtris = ri.Cvar_Get("r_showtris", "0", CVAR_CHEAT);
1090 	r_showsky = ri.Cvar_Get("r_showsky", "0", CVAR_CHEAT);
1091 	r_shownormals = ri.Cvar_Get("r_shownormals", "0", CVAR_CHEAT);
1092 	r_showTangentSpaces = ri.Cvar_Get("r_showTangentSpaces", "0", CVAR_CHEAT);
1093 	r_clear = ri.Cvar_Get("r_clear", "1", CVAR_CHEAT);
1094 	r_offsetFactor = ri.Cvar_Get("r_offsetFactor", "-1", CVAR_CHEAT);
1095 	r_offsetUnits = ri.Cvar_Get("r_offsetUnits", "-2", CVAR_CHEAT);
1096 	r_specularExponent = ri.Cvar_Get("r_specularExponent", "16", CVAR_CHEAT);
1097 	r_drawBuffer = ri.Cvar_Get("r_drawBuffer", "GL_BACK", CVAR_CHEAT);
1098 	r_lockpvs = ri.Cvar_Get("r_lockpvs", "0", CVAR_CHEAT);
1099 	r_noportals = ri.Cvar_Get("r_noportals", "0", CVAR_CHEAT);
1100 	r_shadows = ri.Cvar_Get("cg_shadows", "1", 0);
1101 	AssertCvarRange(r_shadows, 0, 3, qtrue);
1102 	r_shadowOffsetFactor = ri.Cvar_Get("r_shadowOffsetFactor", "0", CVAR_CHEAT);
1103 	r_shadowOffsetUnits = ri.Cvar_Get("r_shadowOffsetUnits", "0", CVAR_CHEAT);
1104 	r_noLightFrustums = ri.Cvar_Get("r_noLightFrustums", "0", CVAR_CHEAT);
1105 
1106 	r_maxpolys = ri.Cvar_Get("r_maxpolys", va("%d", MAX_POLYS), 0);
1107 	r_maxpolyverts = ri.Cvar_Get("r_maxpolyverts", va("%d", MAX_POLYVERTS), 0);
1108 
1109 	r_showLightMaps = ri.Cvar_Get("r_showLightMaps", "0", CVAR_CHEAT);
1110 	r_showDeluxeMaps = ri.Cvar_Get("r_showDeluxeMaps", "0", CVAR_CHEAT);
1111 	r_showNormalMaps = ri.Cvar_Get("r_showNormalMaps", "0", CVAR_CHEAT);
1112 	r_showShadowVolumes = ri.Cvar_Get("r_showShadowVolumes", "0", CVAR_CHEAT);
1113 	r_showSkeleton = ri.Cvar_Get("r_showSkeleton", "0", CVAR_CHEAT);
1114 	r_showEntityTransforms = ri.Cvar_Get("r_showEntityTransforms", "0", CVAR_CHEAT);
1115 	r_showLightTransforms = ri.Cvar_Get("r_showLightTransforms", "0", CVAR_CHEAT);
1116 	r_showLightInteractions = ri.Cvar_Get("r_showLightInteractions", "0", CVAR_CHEAT);
1117 	r_showLightScissors = ri.Cvar_Get("r_showLightScissors", "0", CVAR_CHEAT);
1118 	r_showOcclusionQueries = ri.Cvar_Get("r_showOcclusionQueries", "0", CVAR_CHEAT);
1119 
1120 	// make sure all the commands added here are also removed in R_Shutdown
1121 	ri.Cmd_AddCommand("imagelist", R_ImageList_f);
1122 	ri.Cmd_AddCommand("shaderlist", R_ShaderList_f);
1123 	ri.Cmd_AddCommand("shaderexp", R_ShaderExp_f);
1124 	ri.Cmd_AddCommand("skinlist", R_SkinList_f);
1125 	ri.Cmd_AddCommand("modellist", R_Modellist_f);
1126 	ri.Cmd_AddCommand("modelist", R_ModeList_f);
1127 	ri.Cmd_AddCommand("animationlist", R_AnimationList_f);
1128 	ri.Cmd_AddCommand("fbolist", R_FBOList_f);
1129 	ri.Cmd_AddCommand("screenshot", R_ScreenShot_f);
1130 	ri.Cmd_AddCommand("screenshotJPEG", R_ScreenShotJPEG_f);
1131 	ri.Cmd_AddCommand("gfxinfo", GfxInfo_f);
1132 }
1133 
1134 /*
1135 ===============
1136 R_Init
1137 ===============
1138 */
R_Init(void)1139 void R_Init(void)
1140 {
1141 	int             err;
1142 	int             i;
1143 	byte           *ptr;
1144 
1145 	ri.Printf(PRINT_ALL, "----- R_Init -----\n");
1146 
1147 	// clear all our internal state
1148 	Com_Memset(&tr, 0, sizeof(tr));
1149 	Com_Memset(&backEnd, 0, sizeof(backEnd));
1150 	Com_Memset(&tess, 0, sizeof(tess));
1151 
1152 	if(sizeof(glConfig_t) != 11332)
1153 		ri.Error(ERR_FATAL, "Mod ABI incompatible: sizeof(glconfig_t) == %zd != 11332", sizeof(glConfig_t));
1154 
1155 //  Swap_Init();
1156 
1157 	if ( (intptr_t)tess.xyz & 15 )
1158 		ri.Printf(PRINT_ALL, "WARNING: tess.xyz not 16 byte aligned\n");
1159 
1160 	Com_Memset(tess.constantColor255, 255, sizeof(tess.constantColor255));
1161 
1162 	//
1163 	// init function tables
1164 	//
1165 	for(i = 0; i < FUNCTABLE_SIZE; i++)
1166 	{
1167 		tr.sinTable[i] = sin(DEG2RAD(i * 360.0f / ((float)(FUNCTABLE_SIZE - 1))));
1168 		tr.squareTable[i] = (i < FUNCTABLE_SIZE / 2) ? 1.0f : -1.0f;
1169 		tr.sawToothTable[i] = (float)i / FUNCTABLE_SIZE;
1170 		tr.inverseSawToothTable[i] = 1.0f - tr.sawToothTable[i];
1171 
1172 		if(i < FUNCTABLE_SIZE / 2)
1173 		{
1174 			if(i < FUNCTABLE_SIZE / 4)
1175 			{
1176 				tr.triangleTable[i] = (float)i / (FUNCTABLE_SIZE / 4);
1177 			}
1178 			else
1179 			{
1180 				tr.triangleTable[i] = 1.0f - tr.triangleTable[i - FUNCTABLE_SIZE / 4];
1181 			}
1182 		}
1183 		else
1184 		{
1185 			tr.triangleTable[i] = -tr.triangleTable[i - FUNCTABLE_SIZE / 2];
1186 		}
1187 	}
1188 
1189 	R_InitFogTable();
1190 
1191 	R_NoiseInit();
1192 
1193 	R_Register();
1194 
1195 	max_polys = r_maxpolys->integer;
1196 	if(max_polys < MAX_POLYS)
1197 		max_polys = MAX_POLYS;
1198 
1199 	max_polyverts = r_maxpolyverts->integer;
1200 	if(max_polyverts < MAX_POLYVERTS)
1201 		max_polyverts = MAX_POLYVERTS;
1202 
1203 	ptr = ri.Hunk_Alloc(sizeof(*backEndData[0]) + sizeof(srfPoly_t) * max_polys + sizeof(polyVert_t) * max_polyverts, h_low);
1204 	backEndData[0] = (backEndData_t *) ptr;
1205 	backEndData[0]->polys = (srfPoly_t *) ((char *)ptr + sizeof(*backEndData[0]));
1206 	backEndData[0]->polyVerts = (polyVert_t *) ((char *)ptr + sizeof(*backEndData[0]) + sizeof(srfPoly_t) * max_polys);
1207 	if(r_smp->integer)
1208 	{
1209 		ptr = ri.Hunk_Alloc(sizeof(*backEndData[1]) + sizeof(srfPoly_t) * max_polys + sizeof(polyVert_t) * max_polyverts, h_low);
1210 		backEndData[1] = (backEndData_t *) ptr;
1211 		backEndData[1]->polys = (srfPoly_t *) ((char *)ptr + sizeof(*backEndData[1]));
1212 		backEndData[1]->polyVerts = (polyVert_t *) ((char *)ptr + sizeof(*backEndData[1]) + sizeof(srfPoly_t) * max_polys);
1213 	}
1214 	else
1215 	{
1216 		backEndData[1] = NULL;
1217 	}
1218 	R_ToggleSmpFrame();
1219 
1220 	InitOpenGL();
1221 
1222 	RB_InitGPUShaders();
1223 
1224 	R_InitImages();
1225 
1226 	R_InitFBOs();
1227 
1228 	R_InitShaders();
1229 
1230 	R_InitSkins();
1231 
1232 	R_ModelInit();
1233 
1234 	R_InitAnimations();
1235 
1236 	R_InitFreeType();
1237 
1238 	if(glConfig2.textureAnisotropyAvailable)
1239 	{
1240 		AssertCvarRange(r_ext_texture_filter_anisotropic, 0, glConfig2.maxTextureAnisotropy, qfalse);
1241 	}
1242 
1243 	if(glConfig2.occlusionQueryBits)
1244 	{
1245 		qglGenQueriesARB(MAX_OCCLUSION_QUERIES, tr.occlusionQueryObjects);
1246 	}
1247 
1248 	err = qglGetError();
1249 	if(err != GL_NO_ERROR)
1250 		ri.Printf(PRINT_ALL, "glGetError() = 0x%x\n", err);
1251 
1252 	ri.Printf(PRINT_ALL, "----- finished R_Init -----\n");
1253 }
1254 
1255 /*
1256 ===============
1257 RE_Shutdown
1258 ===============
1259 */
RE_Shutdown(qboolean destroyWindow)1260 void RE_Shutdown(qboolean destroyWindow)
1261 {
1262 	ri.Printf(PRINT_ALL, "RE_Shutdown( %i )\n", destroyWindow);
1263 
1264 	ri.Cmd_RemoveCommand("modellist");
1265 	ri.Cmd_RemoveCommand("screenshotJPEG");
1266 	ri.Cmd_RemoveCommand("screenshot");
1267 	ri.Cmd_RemoveCommand("imagelist");
1268 	ri.Cmd_RemoveCommand("shaderlist");
1269 	ri.Cmd_RemoveCommand("shaderexp");
1270 	ri.Cmd_RemoveCommand("skinlist");
1271 	ri.Cmd_RemoveCommand("gfxinfo");
1272 	ri.Cmd_RemoveCommand("modelist");
1273 	ri.Cmd_RemoveCommand("shaderstate");
1274 	ri.Cmd_RemoveCommand("animationlist");
1275 	ri.Cmd_RemoveCommand("fbolist");
1276 
1277 	if(tr.registered)
1278 	{
1279 		R_SyncRenderThread();
1280 		R_ShutdownCommandBuffers();
1281 		R_ShutdownImages();
1282 		R_ShutdownVBOs();
1283 		R_ShutdownFBOs();
1284 
1285 		if(glConfig2.occlusionQueryBits)
1286 		{
1287 			qglDeleteQueriesARB(MAX_OCCLUSION_QUERIES, tr.occlusionQueryObjects);
1288 		}
1289 
1290 		RB_ShutdownGPUShaders();
1291 	}
1292 
1293 	R_DoneFreeType();
1294 
1295 	// shut down platform specific OpenGL stuff
1296 	if ( destroyWindow )
1297 		GLimp_Shutdown();
1298 
1299 	tr.registered = qfalse;
1300 }
1301 
1302 
1303 /*
1304 =============
1305 RE_EndRegistration
1306 
1307 Touch all images to make sure they are resident
1308 =============
1309 */
RE_EndRegistration(void)1310 void RE_EndRegistration(void)
1311 {
1312 	R_SyncRenderThread();
1313 	if(!Sys_LowPhysicalMemory())
1314 	{
1315 		RB_ShowImages();
1316 	}
1317 }
1318 
1319 
1320 /*
1321 @@@@@@@@@@@@@@@@@@@@@
1322 GetRefAPI
1323 @@@@@@@@@@@@@@@@@@@@@
1324 */
GetRefAPI(int apiVersion,refimport_t * rimp)1325 refexport_t    *GetRefAPI(int apiVersion, refimport_t * rimp)
1326 {
1327 	static refexport_t re;
1328 
1329 	ri = *rimp;
1330 
1331 	Com_Memset(&re, 0, sizeof(re));
1332 
1333 	if(apiVersion != REF_API_VERSION)
1334 	{
1335 		ri.Printf(PRINT_ALL, "Mismatched REF_API_VERSION: expected %i, got %i\n", REF_API_VERSION, apiVersion);
1336 		return NULL;
1337 	}
1338 
1339 	// the RE_ functions are Renderer Entry points
1340 	re.Shutdown = RE_Shutdown;
1341 
1342 	re.BeginRegistration = RE_BeginRegistration;
1343 	re.RegisterModel = RE_RegisterModel;
1344 	re.RegisterAnimation = RE_RegisterAnimation;
1345 	re.RegisterSkin = RE_RegisterSkin;
1346 	re.RegisterShader = RE_RegisterShader;
1347 	re.RegisterShaderNoMip = RE_RegisterShaderNoMip;
1348 	re.RegisterShaderLightAttenuation = RE_RegisterShaderLightAttenuation;
1349 	re.LoadWorld = RE_LoadWorldMap;
1350 	re.SetWorldVisData = RE_SetWorldVisData;
1351 	re.EndRegistration = RE_EndRegistration;
1352 
1353 	re.BeginFrame = RE_BeginFrame;
1354 	re.EndFrame = RE_EndFrame;
1355 
1356 	re.MarkFragments = R_MarkFragments;
1357 	re.LerpTag = RE_LerpTag;
1358 	re.BuildSkeleton = RE_BuildSkeleton;
1359 	re.BlendSkeleton = RE_BlendSkeleton;
1360 	re.BoneIndex = RE_BoneIndex;
1361 	re.AnimNumFrames = RE_AnimNumFrames;
1362 	re.AnimFrameRate = RE_AnimFrameRate;
1363 
1364 	re.ModelBounds = R_ModelBounds;
1365 
1366 	re.ClearScene = RE_ClearScene;
1367 	re.AddRefEntityToScene = RE_AddRefEntityToScene;
1368 	re.AddRefLightToScene = RE_AddRefDlightToScene;
1369 	re.AddPolyToScene = RE_AddPolyToScene;
1370 	re.LightForPoint = R_LightForPoint;
1371 	re.AddLightToScene = RE_AddLightToScene;
1372 	re.AddAdditiveLightToScene = RE_AddAdditiveLightToScene;
1373 	re.RenderScene = RE_RenderScene;
1374 
1375 	re.SetColor = RE_SetColor;
1376 	re.DrawStretchPic = RE_StretchPic;
1377 	re.DrawStretchRaw = RE_StretchRaw;
1378 	re.UploadCinematic = RE_UploadCinematic;
1379 
1380 	re.RegisterFont = RE_RegisterFont;
1381 	re.RemapShader = R_RemapShader;
1382 	re.GetEntityToken = R_GetEntityToken;
1383 	re.inPVS = R_inPVS;
1384 
1385 	return &re;
1386 }
1387