1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13 See the GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 
19 */
20 // r_main.c
21 #include "gl_local.h"
22 #include "vlights.h"
23 
24 void R_Clear (void);
25 
26 #define random()	((rand () & 0x7fff) / ((float)0x7fff))
27 #define crandom()	(2.0 * (random() - 0.5))
28 
29 viddef_t	vid;
30 
31 refimport_t	ri;
32 
33 int GL_TEXTURE0, GL_TEXTURE1;
34 
35 model_t		*r_worldmodel;
36 
37 float		gldepthmin, gldepthmax;
38 
39 glconfig_t gl_config;
40 glstate_t  gl_state;
41 
42 image_t		*r_particletextures[PARTICLE_TYPES]; //list for particles
43 image_t		*r_particlebeam;//used for beam ents
44 image_t		*r_celtexture;//used for cel shading
45 image_t		*r_notexture;		// use for bad textures
46 image_t		*r_dynamicimage;
47 image_t		*r_lblendimage;
48 image_t		*r_motionblurimage;
49 image_t		*r_motionblurscreenimage;
50 
51 particle_t	*currentparticle;
52 entity_t	*currententity;
53 rscript_t	*currententityscript;
54 model_t		*currentmodel;
55 
56 cplane_t	frustum[4];
57 
58 int			r_viewport[4];
59 
60 int			r_visframecount;	// bumped when going to a new PVS
61 int			r_framecount;		// used for dlight push checking
62 
63 int			c_brush_polys, c_alias_polys;
64 
65 float		v_blend[4];			// final blending color
66 
67 void GL_Strings_f( void );
68 
69 //
70 // view origin
71 //
72 vec3_t	vup;
73 vec3_t	vpn;
74 vec3_t	vright;
75 vec3_t	r_origin;
76 
77 float	r_world_matrix[16];
78 float	r_base_world_matrix[16];
79 
80 //
81 // screen size info
82 //
83 refdef_t	r_newrefdef;
84 
85 int		r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2;
86 
87 cvar_t *skydistance; // DMP - skybox size change
88 
89 cvar_t *gl_transrendersort;
90 cvar_t *gl_particle_lighting;
91 cvar_t *gl_particle_min;
92 cvar_t *gl_particle_max;
93 
94 cvar_t	*r_norefresh;
95 cvar_t	*r_drawentities;
96 cvar_t	*r_drawworld;
97 cvar_t	*r_speeds;
98 cvar_t	*r_fullbright;
99 cvar_t	*r_novis;
100 cvar_t	*r_nocull;
101 cvar_t	*r_lerpmodels;
102 cvar_t	*r_lefthand;
103 
104 cvar_t *r_dlights_normal;
105 
106 cvar_t *r_shaders;
107 
108 cvar_t *rs_glares;
109 cvar_t *rs_glares_sky;
110 cvar_t *rs_glares_size;
111 cvar_t *rs_glares_shell;
112 cvar_t *rs_glares_particles;
113 cvar_t *rs_dynamic_time;
114 cvar_t *rs_dynamic_size;
115 cvar_t *rs_dynamic_particles;
116 cvar_t *rs_dynamic_entities;
117 
118 cvar_t *gl_motionblur;
119 cvar_t *gl_motionblur_size;
120 
121 cvar_t *rs_detail;
122 
123 cvar_t *r_model_lightlerp;
124 cvar_t *r_model_dlights;
125 
126 cvar_t	*r_lightlevel;	// FIXME: This is a HACK to get the client's light level
127 
128 cvar_t	*gl_nosubimage;
129 cvar_t	*gl_allow_software;
130 
131 cvar_t	*gl_vertex_arrays;
132 
133 cvar_t	*gl_ext_texture_compression; // Heffo - ARB Texture Compression
134 // Vic - begin
135 cvar_t	*gl_ext_mtexcombine;
136 cvar_t	*r_overbrightbits;
137 // Vic - end
138 
139 cvar_t	*r_celshading;
140 cvar_t	*r_celshading_width;
141 
142 cvar_t	*con_font;
143 cvar_t	*con_font_size;
144 
145 cvar_t	*cl_3dcam;
146 cvar_t	*cl_3dcam_angle;
147 cvar_t	*cl_3dcam_chase;
148 cvar_t	*cl_3dcam_dist;
149 cvar_t	*cl_3dcam_alpha;
150 cvar_t	*cl_3dcam_adjust;
151 
152 cvar_t	*gl_ext_swapinterval;
153 cvar_t	*gl_ext_multitexture;
154 cvar_t	*gl_ext_pointparameters;
155 cvar_t	*gl_ext_compiled_vertex_array;
156 
157 cvar_t	*gl_stencil;
158 
159 cvar_t	*gl_screenshot_quality;
160 
161 cvar_t	*gl_surftrans_light;
162 cvar_t	*gl_log;
163 cvar_t	*gl_bitdepth;
164 cvar_t	*gl_drawbuffer;
165 cvar_t  *gl_driver;
166 cvar_t	*gl_lightmap;
167 cvar_t	*gl_shadows;
168 cvar_t	*gl_mode;
169 cvar_t	*gl_dynamic;
170 cvar_t  *gl_monolightmap;
171 cvar_t	*gl_modulate;
172 cvar_t	*gl_nobind;
173 cvar_t	*gl_round_down;
174 cvar_t	*gl_picmip;
175 cvar_t	*gl_skymip;
176 cvar_t	*gl_showtris;
177 cvar_t	*gl_ztrick;
178 cvar_t	*gl_finish;
179 cvar_t	*gl_clear;
180 cvar_t	*gl_cull;
181 cvar_t	*gl_polyblend;
182 cvar_t	*gl_flashblend;
183 cvar_t	*gl_playermip;
184 cvar_t  *gl_saturatelighting;
185 cvar_t	*gl_swapinterval;
186 cvar_t	*gl_texturemode;
187 cvar_t	*gl_anisotropic;
188 cvar_t	*gl_texturealphamode;
189 cvar_t	*gl_texturesolidmode;
190 cvar_t	*gl_lockpvs;
191 
192 cvar_t	*gl_3dlabs_broken;
193 
194 cvar_t	*vid_fullscreen;
195 cvar_t	*vid_gamma;
196 cvar_t	*vid_ref;
197 
198 /*
199 =================
200 GL_Stencil
201 
202 setting stencil buffer
203 =================
204 */
205 extern qboolean have_stencil;
GL_Stencil(qboolean enable)206 void GL_Stencil (qboolean enable)
207 {
208 	if (!have_stencil || !gl_stencil->value)
209 		return;
210 
211 	if (enable)
212 	{
213 		qglEnable(GL_STENCIL_TEST);
214 		qglStencilFunc(GL_EQUAL, 1, 2);
215 		qglStencilOp(GL_KEEP,GL_KEEP,GL_INCR);
216 	}
217 	else
218 	{
219 		qglDisable(GL_STENCIL_TEST);
220 	}
221 }
GL_HasStencil(void)222 qboolean GL_HasStencil (void)
223 {
224 	return (have_stencil && gl_stencil->value);
225 }
226 
227 /*
228 =================
229 GL_Spheremap
230 
231 setting up spheremap
232 =================
233 */
234 
GL_Spheremap(qboolean enable)235 void GL_Spheremap (qboolean enable)
236 {
237 
238 	if (enable)
239 	{
240 		qglTexGenf(GL_S, GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
241 		qglTexGenf(GL_T, GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
242 		GLSTATE_ENABLE_TEXGEN
243 	}
244 	else
245 	{
246 		GLSTATE_DISABLE_TEXGEN
247 	}
248 }
249 
250 /*
251 =================
252 R_CullBox
253 
254 Returns true if the box is completely outside the frustom
255 =================
256 */
R_CullBox(vec3_t mins,vec3_t maxs)257 qboolean R_CullBox (vec3_t mins, vec3_t maxs)
258 {
259 	int		i;
260 
261 	if (r_nocull->value)
262 		return false;
263 
264 	for (i=0 ; i<4 ; i++)
265 		if ( BOX_ON_PLANE_SIDE(mins, maxs, &frustum[i]) == 2)
266 			return true;
267 	return false;
268 }
269 
R_CullSphere(const vec3_t origin,float radius)270 qboolean R_CullSphere (const vec3_t origin, float radius)
271 {
272  	int i;
273 	cplane_t *p;
274 
275 	if (r_nocull->value)
276 		return false;
277 
278 	for (i = 0, p = frustum; i < 4; i++, p++)
279 		if (DotProduct(origin, p->normal) - p->dist <= -radius)
280 			return true;
281 
282 	return false;
283 }
284 
R_RotateForEntity(entity_t * e,qboolean full)285 void R_RotateForEntity (entity_t *e, qboolean full)
286 {
287     qglTranslatef (e->origin[0],  e->origin[1],  e->origin[2]);
288 
289     qglRotatef (e->angles[1],  0, 0, 1);
290 	if (full==true)
291 	{
292 		qglRotatef (-e->angles[0],  0, 1, 0);
293 		qglRotatef (-e->angles[2],  1, 0, 0);
294 	}
295 }
296 
297 /*
298 =============================================================
299 
300   SPRITE MODELS
301 
302 =============================================================
303 */
304 
305 
306 /*
307 =================
308 R_DrawSpriteModel
309 
310 =================
311 */
R_DrawSpriteModel(entity_t * e)312 void R_DrawSpriteModel (entity_t *e)
313 {
314 	float alpha = 1.0F;
315 	vec3_t	point, up, right;
316 	dsprframe_t	*frame;
317 	dsprite_t		*psprite;
318 
319 	// don't even bother culling, because it's just a single
320 	// polygon without a surface cache
321 
322 	psprite = (dsprite_t *)currentmodel->extradata;
323 
324 	e->frame %= psprite->numframes;
325 
326 	frame = &psprite->frames[e->frame];
327 
328 	if (!frame)
329 		return;
330 
331 	// normal sprite
332 	VectorCopy(vup, up);
333 	VectorCopy(vright, right);
334 
335 
336 	if ( e->flags & RF_TRANSLUCENT )
337 		alpha = e->alpha;
338 
339 	if (!currentmodel->skins[e->frame])
340 		return;
341 
342 	GL_Bind(currentmodel->skins[e->frame]->texnum);
343 
344 	if ((currententity->flags&RF_TRANS_ADDITIVE) && (alpha != 1.0F))
345 	{
346 		GLSTATE_ENABLE_BLEND
347 		GL_TexEnv( GL_MODULATE );
348 
349 		GLSTATE_DISABLE_ALPHATEST
350 		GL_BlendFunction (GL_SRC_ALPHA, GL_ONE);
351 
352 		qglColor4ub(255, 255, 255, alpha*254);
353 	}
354 	else
355 	{
356 		if ( alpha != 1.0F )
357 			GLSTATE_ENABLE_BLEND
358 
359 		GL_TexEnv( GL_MODULATE );
360 
361 		if ( alpha == 1.0 )
362 			GLSTATE_ENABLE_ALPHATEST
363 		else
364 			GLSTATE_DISABLE_ALPHATEST
365 
366 		qglColor4f( 1, 1, 1, alpha );
367 	}
368 
369 	qglBegin (GL_QUADS);
370 
371 	qglTexCoord2f (0, 1);
372 	VectorMA (e->origin, -frame->origin_y, up, point);
373 	VectorMA (point, -frame->origin_x, right, point);
374 	qglVertex3fv (point);
375 
376 	qglTexCoord2f (0, 0);
377 	VectorMA (e->origin, frame->height - frame->origin_y, up, point);
378 	VectorMA (point, -frame->origin_x, right, point);
379 	qglVertex3fv (point);
380 
381 	qglTexCoord2f (1, 0);
382 	VectorMA (e->origin, frame->height - frame->origin_y, up, point);
383 	VectorMA (point, frame->width - frame->origin_x, right, point);
384 	qglVertex3fv (point);
385 
386 	qglTexCoord2f (1, 1);
387 	VectorMA (e->origin, -frame->origin_y, up, point);
388 	VectorMA (point, frame->width - frame->origin_x, right, point);
389 	qglVertex3fv (point);
390 
391 	qglEnd ();
392 
393 
394 	GL_BlendFunction (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
395 	GLSTATE_DISABLE_ALPHATEST
396 
397 	GL_TexEnv( GL_REPLACE );
398 
399 	if ( alpha != 1.0F )
400 		GLSTATE_DISABLE_BLEND
401 
402 	qglColor4f( 1, 1, 1, 1 );
403 }
404 
405 //==================================================================================
406 
407 /*
408 =============
409 R_DrawNullModel
410 =============
411 */
R_DrawNullModel(void)412 void R_DrawNullModel (void)
413 {
414 	vec3_t	shadelight;
415 	int		i;
416 
417 	if ( currententity->flags & RF_FULLBRIGHT )
418 		shadelight[0] = shadelight[1] = shadelight[2] = 1.0F;
419 	else
420 		R_LightPoint (currententity->origin, shadelight);
421 
422     qglPushMatrix ();
423 	R_RotateForEntity (currententity, true);
424 
425 	qglDisable (GL_TEXTURE_2D);
426 	qglColor3fv (shadelight);
427 
428 	qglBegin (GL_TRIANGLE_FAN);
429 	qglVertex3f (0, 0, -16);
430 	for (i=0 ; i<=4 ; i++)
431 		qglVertex3f (16*cos(i*M_PI/2), 16*sin(i*M_PI/2), 0);
432 	qglEnd ();
433 
434 	qglBegin (GL_TRIANGLE_FAN);
435 	qglVertex3f (0, 0, 16);
436 	for (i=4 ; i>=0 ; i--)
437 		qglVertex3f (16*cos(i*M_PI/2), 16*sin(i*M_PI/2), 0);
438 	qglEnd ();
439 
440 	qglColor3f (1,1,1);
441 	qglPopMatrix ();
442 	qglEnable (GL_TEXTURE_2D);
443 }
444 /*
445 =============
446 R_DrawEntitiesOnList
447 =============
448 */
449 
450 // STRUCTURE STUFF
451 
452 typedef struct sortedelement_s
453 {
454 	void *data;
455 	vec_t len;
456 	vec3_t org;
457 	void *left, *right, *next;
458 }
459 sortedelement_t;
460 
461 int entstosort;
462 sortedelement_t theents[MAX_ENTITIES];
463 sortedelement_t *ents_viewweaps;
464 sortedelement_t *ents_viewweaps_trans;
465 sortedelement_t *ents_prerender;
466 sortedelement_t *ents_last;
467 
468 
resetSortList(void)469 void resetSortList (void)
470 {
471 	entstosort = 0;
472 	ents_last = NULL;
473 	ents_prerender = NULL;
474 	ents_viewweaps = NULL;
475 	ents_viewweaps_trans = NULL;
476 }
477 
NewSortEnt(entity_t * ent)478 sortedelement_t *NewSortEnt (entity_t *ent)
479 {
480 	qboolean entinwater, is_weapmodel = false;
481 	vec3_t distance;
482 	sortedelement_t *element;
483 	mleaf_t *point_in;
484 
485 	element = &theents[entstosort];
486 
487 	VectorSubtract(ent->origin, r_origin, distance);
488 	VectorCopy(ent->origin, element->org);
489 
490 	element->data = (entity_t *)ent;
491 	element->len = (vec_t)VectorLength(distance);
492 	element->left = NULL;
493 	element->right = NULL;
494 	element->next = NULL;
495 
496 	return element;
497 }
498 
499 // TREE BUILDING AND USAGE
500 
ElementAddNode(sortedelement_t * base,sortedelement_t * thisElement)501 void ElementAddNode ( sortedelement_t *base, sortedelement_t *thisElement )
502 {
503 	if (thisElement->len > base->len)
504 	{
505 		if (base->left)
506 			ElementAddNode(base->left, thisElement);
507 		else
508 			base->left = thisElement;
509 	}
510 	else
511 	{
512 		if (base->right)
513 			ElementAddNode(base->right, thisElement);
514 		else
515 			base->right = thisElement;
516 	}
517 }
518 
AddEntViewWeapTree(entity_t * ent,qboolean trans)519 void AddEntViewWeapTree( entity_t *ent, qboolean trans)
520 {
521 	int closer = 0;
522 	sortedelement_t *thisEnt;
523 
524 
525 	thisEnt = NewSortEnt(ent);
526 
527 	if (!thisEnt)
528 		return;
529 
530 	if (!trans)
531 	{
532 		if (ents_viewweaps)
533 			ElementAddNode(ents_viewweaps, thisEnt);
534 		else
535 			ents_viewweaps = thisEnt;
536 	}
537 	else
538 	{
539 		if (ents_viewweaps_trans)
540 			ElementAddNode(ents_viewweaps_trans, thisEnt);
541 		else
542 			ents_viewweaps_trans = thisEnt;
543 	}
544 
545 	entstosort++;
546 }
547 
AddEntTransTree(entity_t * ent)548 void AddEntTransTree( entity_t *ent )
549 {
550 	int closer = 0;
551 	sortedelement_t *thisEnt;
552 
553 
554 	thisEnt = NewSortEnt(ent);
555 
556 	if (!thisEnt)
557 		return;
558 
559 	if (ents_prerender)
560 		ElementAddNode(ents_prerender, thisEnt);
561 	else
562 		ents_prerender = thisEnt;
563 
564 	ents_last = thisEnt;
565 
566 	entstosort++;
567 }
568 
ParseRenderEntity(entity_t * ent)569 void ParseRenderEntity (entity_t *ent)
570 {
571 	currententity = ent;
572 
573 	if ( currententity->flags & RF_BEAM )
574 	{
575 		R_DrawBeam( currententity );
576 	}
577 	else
578 	{
579 		currentmodel = currententity->model;
580 		if (!currentmodel)
581 		{
582 			R_DrawNullModel ();
583 			return;
584 		}
585 		if (currententity->model && r_shaders->value)
586 		{
587 			currententityscript=(rscript_t *)currententity->model->script[currententity->skinnum];
588 			if (currententity->skin)
589 				currententityscript = currententity->skin->script;
590 		}
591 
592 		switch (currentmodel->type)
593 		{
594 		case mod_alias:
595 			R_DrawAliasModel (currententity);
596 			break;
597 		case mod_brush:
598 			R_DrawBrushModel (currententity);
599 			break;
600 		case mod_sprite:
601 			R_DrawSpriteModel (currententity);
602 			break;
603 		default:
604 			ri.Sys_Error (ERR_DROP, "Bad modeltype");
605 			break;
606 		}
607 	}
608 }
609 
transBrushModel(entity_t * ent)610 qboolean transBrushModel (entity_t *ent)
611 {
612 	int i;
613 	msurface_t *surf;
614 
615 	if (ent && ent->model && ent->model->type==mod_brush)
616 	{
617 		surf = &ent->model->surfaces[ent->model->firstmodelsurface];
618 		for (i=0 ; i<ent->model->nummodelsurfaces ; i++, surf++)
619 			if (surf && surf->texinfo->flags & (SURF_TRANS33|SURF_TRANS66))
620 				return true;
621 	}
622 
623 	return false;
624 }
625 
RenderEntTree(sortedelement_t * element)626 void RenderEntTree (sortedelement_t *element)
627 {
628 	if (!element)
629 		return;
630 
631 	RenderEntTree(element->left);
632 
633 	if (element->data)
634 		ParseRenderEntity(element->data);
635 
636 
637 	RenderEntTree(element->right);
638 }
639 
640 // ACTUAL RENDERING FUNCTIONS
641 
642 void R_DrawAliasShadow (entity_t *ent);
R_DrawAllEntityShadows(void)643 void R_DrawAllEntityShadows (void)
644 {
645 	qboolean	alpha;
646 	rscript_t	*rs = NULL;
647 	int i;
648 
649 	if(!gl_shadows->value)
650 		return;
651 
652 	for (i=0;i<r_newrefdef.num_entities; i++)
653 	{
654 		currententity = &r_newrefdef.entities[i];
655 
656 		if ( currententity->flags & RF_BEAM )
657 			continue;
658 		currentmodel = currententity->model;
659 		if (!currentmodel)
660 			continue;
661 		if (currentmodel->type!=mod_alias)
662 			continue;
663 
664 
665 		if ( currententity->flags & ( RF_TRANSLUCENT | RF_WEAPONMODEL | RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) )
666 			continue;
667 		if	(currententity->renderfx & RF2_NOSHADOW)
668 			continue;
669 		if (currententity->flags&RF_TRANSLUCENT)
670 			continue;
671 //		if (transBrushModel(currententity)) //crashy
672 //			continue;
673 
674 		alpha = false;
675 		if (currententity->model && r_shaders->value)
676 		{
677 			rs=(rscript_t *)currententity->model->script[currententity->skinnum];
678 			if (!rs && currententity->skin)
679 				rs = currententity->skin->script;
680 			if (rs)
681 			{
682 				RS_ReadyScript(rs);
683 				currententityscript = rs;
684 				if (rs->stage && rs->stage->has_alpha)
685 					continue;
686 			}
687 			else
688 				currententityscript = NULL;
689 		}
690 
691 		R_DrawAliasShadow (currententity);
692 	}
693 }
694 
R_DrawAllEntities(qboolean addViewWeaps)695 void R_DrawAllEntities (qboolean addViewWeaps)
696 {
697 	qboolean alpha;
698 	rscript_t	*rs = NULL;
699 	int i;
700 
701 	if (!r_drawentities->value)
702 		return;
703 
704 	resetSortList();
705 
706 	for (i=0;i<r_newrefdef.num_entities; i++)
707 	{
708 		currententity = &r_newrefdef.entities[i];
709 
710 		alpha = false;
711 		if (currententity->flags&RF_TRANSLUCENT)
712 			alpha = true;
713 		if (currententity->model && r_shaders->value)
714 		{
715 			rs=(rscript_t *)currententity->model->script[currententity->skinnum];
716 			if (currententity->skin)
717 				rs = currententity->skin->script;
718 			if (rs)
719 			{
720 				RS_ReadyScript(rs);
721 				currententityscript = rs;
722 				if (rs->stage && rs->stage->has_alpha)
723 					alpha = true;
724 			}
725 			else
726 				currententityscript = NULL;
727 		}
728 
729 		if (alpha)
730 			continue;
731 
732 		if (currententity->flags & RF_WEAPONMODEL)
733 			if (!addViewWeaps)
734 				continue;
735 
736 		ParseRenderEntity(currententity);
737 	}
738 
739 	qglDepthMask (0);
740 	for (i=0;i<r_newrefdef.num_entities; i++)
741 	{
742 		currententity = &r_newrefdef.entities[i];
743 
744 		alpha = false;
745 		if (currententity->flags&RF_TRANSLUCENT)
746 			alpha = true;
747 		if (currententity->model && r_shaders->value)
748 		{
749 			rs=(rscript_t *)currententity->model->script[currententity->skinnum];
750 			if (currententity->skin)
751 				rs = currententity->skin->script;
752 
753 			if (rs)
754 			{
755 				RS_ReadyScript(rs);
756 				currententityscript = rs;
757 				if (rs->stage && rs->stage->has_alpha)
758 					alpha = true;
759 			}
760 			else
761 				currententityscript = NULL;
762 		}
763 
764 		if (currententity->flags & RF_WEAPONMODEL)
765 			if (!addViewWeaps)
766 				continue;
767 
768 		if (!alpha)
769 			continue;
770 
771 		ParseRenderEntity(currententity);
772 	}
773 	qglDepthMask (1);
774 }
775 
776 void setRenderMotionBlur (void);
R_DrawMotionBlurEntities(void)777 void R_DrawMotionBlurEntities (void)
778 {
779 	qboolean alpha;
780 	int		i;
781 	rscript_t *rs = NULL;
782 
783 	if (!r_drawentities->value)
784 		return;
785 
786 	for (i=0;i<r_newrefdef.num_entities; i++)
787 	{
788 		currententity = &r_newrefdef.entities[i];
789 		if (currententity->flags & RF_TRANSLUCENT)
790 			continue;
791 		if (currententity->renderfx & RF2_MOTIONBLUR)
792 			ParseRenderEntity(currententity);
793 	}
794 }
795 
796 
R_DrawSolidEntities(void)797 void R_DrawSolidEntities (void)
798 {
799 	qboolean alpha;
800 	int		i;
801 	rscript_t *rs = NULL;
802 
803 	if (!r_drawentities->value)
804 		return;
805 
806 	resetSortList();
807 
808 	for (i=0;i<r_newrefdef.num_entities; i++)
809 	{
810 		currententity = &r_newrefdef.entities[i];
811 		alpha = false;
812 
813 		//find alpha and script...
814 		if (currententity->model && r_shaders->value)
815 		{
816 			rs=(rscript_t *)currententity->model->script[currententity->skinnum];
817 			if (currententity->skin)
818 				rs = currententity->skin->script;
819 			if (rs)
820 			{
821 				RS_ReadyScript(rs);
822 				currententityscript = rs;
823 				//only add to list if base layer is alpha
824 				if (rs->stage && rs->stage->has_alpha)
825 					alpha = true;
826 			}
827 			else
828 				currententityscript = NULL;
829 		}
830 		if (currententity->flags&RF_TRANSLUCENT)
831 			alpha = true;
832 //		if (transBrushModel(currententity))
833 //			alpha = true;
834 
835 		if (currententity->flags & RF_WEAPONMODEL)
836 		{
837 			AddEntViewWeapTree(currententity, alpha);
838 			continue;
839 		}
840 
841 		if (alpha)
842 		{
843 			AddEntTransTree(currententity);
844 			continue;
845 		}
846 
847 		ParseRenderEntity(currententity);
848 	}
849 }
850 
R_DrawEntitiesOnList(void * list)851 void R_DrawEntitiesOnList (void *list)
852 {
853 	if (!r_drawentities->value)
854 		return;
855 
856 	RenderEntTree(list);
857 }
858 
859 /*
860 ** GL_DrawParticles
861 **
862 */
863 
864 int partstosort;
865 sortedelement_t theparts[MAX_PARTICLES];
866 sortedelement_t *parts_prerender;
867 sortedelement_t *parts_decals;
868 sortedelement_t *parts_last;
869 void renderParticle (particle_t *p);
870 void renderDecal (particle_t *p);
871 
NewSortPart(particle_t * p)872 sortedelement_t *NewSortPart ( particle_t *p)
873 {
874 	qboolean partinwater;
875 	vec3_t distance;
876 	sortedelement_t *element;
877 
878 	element = &theparts[partstosort];
879 
880 	VectorSubtract(p->origin, r_origin, distance);
881 	VectorCopy(p->origin, element->org);
882 
883 	element->data	= p;
884 	element->len	= VectorLength(distance);
885 	element->left	= NULL;
886 	element->right	= NULL;
887 
888 	return element;
889 }
890 
resetPartSortList(void)891 void resetPartSortList (void)
892 {
893 	partstosort = 0;
894 	parts_prerender = NULL;
895 	parts_decals = NULL;
896 	parts_last = NULL;
897 }
898 
particleClip(float len)899 qboolean particleClip( float len )
900 {
901 	if (gl_particle_min->value>0)
902 	{
903 		if (len < gl_particle_min->value)
904 			return true;
905 	}
906 	if (gl_particle_max->value>0)
907 	{
908 		if (len > gl_particle_max->value)
909 			return true;
910 	}
911 
912 	return false;
913 }
914 
915 
DecalElementAddNode(sortedelement_t * base,sortedelement_t * thisElement)916 void DecalElementAddNode ( sortedelement_t *base, sortedelement_t *thisElement )
917 {
918 	particle_t	*pBase = thisElement->data,
919 				*pThis = base->data;
920 
921 	if (pBase->flags & PART_DECAL_SUB)
922 	{
923 		if (pThis->flags & PART_DECAL_SUB)
924 		{
925 			if (base->right)
926 				ElementAddNode(base->right, thisElement);
927 			else
928 				base->right = thisElement;
929 		}
930 		else
931 		{
932 			if (base->left)
933 				ElementAddNode(base->left, thisElement);
934 			else
935 				base->left = thisElement;
936 		}
937 		return;
938 	}
939 	else if (pThis->flags & PART_DECAL_ADD)
940 	{
941 		if (pThis->flags & PART_DECAL_SUB)
942 		{
943 			if (base->left)
944 				ElementAddNode(base->left, thisElement);
945 			else
946 				base->left = thisElement;
947 		}
948 		else
949 		{
950 			if (base->right)
951 				ElementAddNode(base->right, thisElement);
952 			else
953 				base->right = thisElement;
954 		}
955 		return;
956 	}
957 
958 	if (thisElement->len > base->len)
959 	{
960 		if (base->left)
961 			ElementAddNode(base->left, thisElement);
962 		else
963 			base->left = thisElement;
964 	}
965 	else
966 	{
967 		if (base->right)
968 			ElementAddNode(base->right, thisElement);
969 		else
970 			base->right = thisElement;
971 	}
972 }
973 
AddPartTransTree(particle_t * p)974 void AddPartTransTree( particle_t *p )
975 {
976 	sortedelement_t *thisPart;
977 
978 	thisPart = NewSortPart(p);
979 
980 	//decals are sorted by render type, then depth
981 	if (p->flags&PART_DECAL)
982 	{
983 		if (parts_decals)
984 			DecalElementAddNode(parts_decals, thisPart);
985 		else
986 			parts_decals = thisPart;
987 	}
988 	else
989 	{
990 		if (particleClip(thisPart->len))
991 			return;
992 
993 		if (parts_prerender)
994 			ElementAddNode(parts_prerender, thisPart);
995 		else
996 			parts_prerender = thisPart;
997 
998 		parts_last = thisPart;
999 	}
1000 
1001 	partstosort++;
1002 }
1003 
GL_BuildParticleList()1004 void GL_BuildParticleList()
1005 {
1006 	int		i;
1007 	resetPartSortList();
1008 
1009 	for ( i=0 ; i < r_newrefdef.num_particles ; i++)
1010 	{
1011 		currentparticle = &r_newrefdef.particles[i];
1012 		AddPartTransTree(currentparticle);
1013 	}
1014 }
1015 
RenderParticleTree(sortedelement_t * element)1016 void RenderParticleTree (sortedelement_t *element)
1017 {
1018 	if (!element)
1019 		return;
1020 
1021 	RenderParticleTree(element->left);
1022 
1023 	if (element->data)
1024 		renderParticle((particle_t *)element->data);
1025 
1026 	RenderParticleTree(element->right);
1027 }
1028 
RenderDecalTree(sortedelement_t * element)1029 void RenderDecalTree (sortedelement_t *element)
1030 {
1031 	if (!element)
1032 		return;
1033 
1034 	RenderDecalTree(element->left);
1035 
1036 	if (element->data)
1037 		renderDecal((particle_t *)element->data);
1038 
1039 	RenderDecalTree(element->right);
1040 }
1041 
1042 /*
1043 ===============
1044 R_DrawParticles
1045 ===============
1046 */
1047 
1048 vec3_t particle_coord[4];
R_DrawDecals(void)1049 void R_DrawDecals (void)
1050 {
1051 	vec3_t		up		= {vup[0]    * 0.75f, vup[1]    * 0.75f, vup[2]    * 0.75f};
1052 	vec3_t		right	= {vright[0] * 0.75f, vright[1] * 0.75f, vright[2] * 0.75f};
1053 
1054 	VectorAdd      (up, right, particle_coord[0]);
1055 	VectorSubtract (right, up, particle_coord[1]);
1056 	VectorNegate   (particle_coord[0], particle_coord[2]);
1057 	VectorNegate   (particle_coord[1], particle_coord[3]);
1058 
1059 	qglEnable (GL_TEXTURE_2D);
1060 	GL_TexEnv( GL_MODULATE );
1061 	qglDepthMask   (false);
1062 	GLSTATE_ENABLE_BLEND
1063 	GL_ShadeModel (GL_SMOOTH);
1064 	GLSTATE_DISABLE_ALPHATEST
1065 
1066 	RenderDecalTree(parts_decals);
1067 
1068 	qglDepthRange (gldepthmin, gldepthmax);
1069 	GL_BlendFunction (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1070 	GL_TexEnv( GL_MODULATE );
1071 	qglDepthMask (true);
1072 	GLSTATE_DISABLE_BLEND
1073 	qglColor4f   (1,1,1,1);
1074 }
1075 
1076 
R_DrawAllAddGlareParticles(void)1077 void R_DrawAllAddGlareParticles (void)
1078 {
1079 	vec3_t		up		= {vup[0]    * 0.75f, vup[1]    * 0.75f, vup[2]    * 0.75f};
1080 	vec3_t		right	= {vright[0] * 0.75f, vright[1] * 0.75f, vright[2] * 0.75f};
1081 	int		i;
1082 
1083 	VectorAdd      (up, right, particle_coord[0]);
1084 	VectorSubtract (right, up, particle_coord[1]);
1085 	VectorNegate   (particle_coord[0], particle_coord[2]);
1086 	VectorNegate   (particle_coord[1], particle_coord[3]);
1087 
1088 	qglEnable (GL_TEXTURE_2D);
1089 	GL_TexEnv( GL_MODULATE );
1090 	qglDepthMask   (false);
1091 	GLSTATE_ENABLE_BLEND
1092 	GL_ShadeModel (GL_SMOOTH);
1093 	GLSTATE_DISABLE_ALPHATEST
1094 
1095 	for ( i=0 ; i < r_newrefdef.num_particles ; i++)
1096 		if (r_newrefdef.particles[i].flags&PART_GLARE)
1097 		{
1098 			if (r_newrefdef.particles[i].flags&PART_DECAL)
1099 				renderDecal(&r_newrefdef.particles[i]);
1100 			else
1101 				renderParticle(&r_newrefdef.particles[i]);
1102 		}
1103 
1104 	qglDepthRange (gldepthmin, gldepthmax);
1105 	GL_BlendFunction (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1106 	GL_TexEnv( GL_MODULATE );
1107 	qglDepthMask (true);
1108 	GLSTATE_DISABLE_BLEND
1109 	qglColor4f   (1,1,1,1);
1110 }
1111 
R_DrawAllSubDecals(void)1112 void R_DrawAllSubDecals (void)
1113 {
1114 	vec3_t		up		= {vup[0]    * 0.75f, vup[1]    * 0.75f, vup[2]    * 0.75f};
1115 	vec3_t		right	= {vright[0] * 0.75f, vright[1] * 0.75f, vright[2] * 0.75f};
1116 	int		i;
1117 
1118 	VectorAdd      (up, right, particle_coord[0]);
1119 	VectorSubtract (right, up, particle_coord[1]);
1120 	VectorNegate   (particle_coord[0], particle_coord[2]);
1121 	VectorNegate   (particle_coord[1], particle_coord[3]);
1122 
1123 	qglEnable (GL_TEXTURE_2D);
1124 	GL_TexEnv( GL_MODULATE );
1125 	qglDepthMask   (false);
1126 	GLSTATE_ENABLE_BLEND
1127 	GL_ShadeModel (GL_SMOOTH);
1128 	GLSTATE_DISABLE_ALPHATEST
1129 
1130 	for ( i=0 ; i < r_newrefdef.num_particles ; i++)
1131 		if (r_newrefdef.particles[i].flags&PART_DECAL && r_newrefdef.particles[i].flags&PART_DECAL_SUB)
1132 			renderDecal(&r_newrefdef.particles[i]);
1133 
1134 	qglDepthRange (gldepthmin, gldepthmax);
1135 	GL_BlendFunction (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1136 	GL_TexEnv( GL_MODULATE );
1137 	qglDepthMask (true);
1138 	GLSTATE_DISABLE_BLEND
1139 	qglColor4f   (1,1,1,1);
1140 }
1141 
R_DrawAllDecals(void)1142 void R_DrawAllDecals (void)
1143 {
1144 	vec3_t		up		= {vup[0]    * 0.75f, vup[1]    * 0.75f, vup[2]    * 0.75f};
1145 	vec3_t		right	= {vright[0] * 0.75f, vright[1] * 0.75f, vright[2] * 0.75f};
1146 	int		i;
1147 
1148 	VectorAdd      (up, right, particle_coord[0]);
1149 	VectorSubtract (right, up, particle_coord[1]);
1150 	VectorNegate   (particle_coord[0], particle_coord[2]);
1151 	VectorNegate   (particle_coord[1], particle_coord[3]);
1152 
1153 	qglEnable (GL_TEXTURE_2D);
1154 	GL_TexEnv( GL_MODULATE );
1155 	qglDepthMask   (false);
1156 	GLSTATE_ENABLE_BLEND
1157 	GL_ShadeModel (GL_SMOOTH);
1158 	GLSTATE_DISABLE_ALPHATEST
1159 
1160 	for ( i=0 ; i < r_newrefdef.num_particles ; i++)
1161 		if (r_newrefdef.particles[i].flags&PART_DECAL)
1162 			renderDecal(&r_newrefdef.particles[i]);
1163 
1164 	qglDepthRange (gldepthmin, gldepthmax);
1165 	GL_BlendFunction (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1166 	GL_TexEnv( GL_MODULATE );
1167 	qglDepthMask (true);
1168 	GLSTATE_DISABLE_BLEND
1169 	qglColor4f   (1,1,1,1);
1170 }
1171 
1172 void SetVertexOverbrights(qboolean);
1173 
1174 qboolean ParticleOverbright;
SetParticleOverbright(qboolean toggle)1175 void SetParticleOverbright(qboolean toggle)
1176 {
1177 	if ( (toggle && !ParticleOverbright) || (!toggle && ParticleOverbright) )
1178 	{
1179 		SetVertexOverbrights(toggle);
1180 		ParticleOverbright = toggle;
1181 	}
1182 }
1183 
R_DrawParticles(void * list)1184 void R_DrawParticles (void *list)
1185 {
1186 	vec3_t		up		= {vup[0]    * 0.75f, vup[1]    * 0.75f, vup[2]    * 0.75f};
1187 	vec3_t		right	= {vright[0] * 0.75f, vright[1] * 0.75f, vright[2] * 0.75f};
1188 
1189 	VectorAdd      (up, right, particle_coord[0]);
1190 	VectorSubtract (right, up, particle_coord[1]);
1191 	VectorNegate   (particle_coord[0], particle_coord[2]);
1192 	VectorNegate   (particle_coord[1], particle_coord[3]);
1193 
1194 	qglEnable (GL_TEXTURE_2D);
1195 	GL_TexEnv( GL_MODULATE );
1196 	qglDepthMask   (false);
1197 	GLSTATE_ENABLE_BLEND
1198 	GL_ShadeModel (GL_SMOOTH);
1199 	GLSTATE_DISABLE_ALPHATEST
1200 	ParticleOverbright = false;
1201 
1202 	RenderParticleTree(list);
1203 
1204 	qglDepthRange (gldepthmin, gldepthmax);
1205 	GL_BlendFunction (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1206 	GL_TexEnv( GL_MODULATE );
1207 	qglDepthMask (true);
1208 	GLSTATE_DISABLE_BLEND
1209 	qglColor4f   (1,1,1,1);
1210 }
1211 
R_DrawAllParticles(void)1212 void R_DrawAllParticles (void)
1213 {
1214 	vec3_t		up		= {vup[0]    * 0.75f, vup[1]    * 0.75f, vup[2]    * 0.75f};
1215 	vec3_t		right	= {vright[0] * 0.75f, vright[1] * 0.75f, vright[2] * 0.75f};
1216 
1217 	int		i;
1218 
1219 	VectorAdd      (up, right, particle_coord[0]);
1220 	VectorSubtract (right, up, particle_coord[1]);
1221 	VectorNegate   (particle_coord[0], particle_coord[2]);
1222 	VectorNegate   (particle_coord[1], particle_coord[3]);
1223 
1224 	qglEnable (GL_TEXTURE_2D);
1225 	GL_TexEnv( GL_MODULATE );
1226 	qglDepthMask   (false);
1227 	GLSTATE_ENABLE_BLEND
1228 	GL_ShadeModel (GL_SMOOTH);
1229 	GLSTATE_DISABLE_ALPHATEST
1230 	ParticleOverbright = false;
1231 
1232 	for ( i=0 ; i < r_newrefdef.num_particles ; i++)
1233 		if (!(r_newrefdef.particles[i].flags&PART_DECAL))
1234 			renderParticle(&r_newrefdef.particles[i]);
1235 
1236 	qglDepthRange (gldepthmin, gldepthmax);
1237 	GL_BlendFunction (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1238 	GL_TexEnv( GL_MODULATE );
1239 	qglDepthMask (true);
1240 	GLSTATE_DISABLE_BLEND
1241 	qglColor4f   (1,1,1,1);
1242 }
1243 
1244 /**********************************************************
1245 				renderParticle
1246 **********************************************************/
1247 
texParticle(int type)1248 int texParticle (int type)
1249 {
1250 	image_t		*part_img;
1251 
1252 	part_img = r_particletextures [type];
1253 
1254 	return part_img->texnum;
1255 }
1256 
vectoanglerolled(vec3_t value1,float angleyaw,vec3_t angles)1257 void vectoanglerolled (vec3_t value1, float angleyaw, vec3_t angles)
1258 {
1259 	float	forward, yaw, pitch;
1260 
1261 	yaw = (int) (atan2(value1[1], value1[0]) * 180 / M_PI);
1262 	forward = sqrt (value1[0]*value1[0] + value1[1]*value1[1]);
1263 	pitch = (int) (atan2(value1[2], forward) * 180 / M_PI);
1264 
1265 	if (pitch < 0)
1266 		pitch += 360;
1267 
1268 	angles[PITCH] = -pitch;
1269 	angles[YAW] =  yaw;
1270 	angles[ROLL] = - angleyaw;
1271 }
1272 
AngleFind(float input)1273 float AngleFind(float input)
1274 {
1275 	return 180.0/input;
1276 }
1277 
setBeamAngles(vec3_t start,vec3_t end,vec3_t up,vec3_t right)1278 void setBeamAngles (vec3_t start, vec3_t end, vec3_t up, vec3_t right)
1279 {
1280 	vec3_t move, delta;
1281 
1282 	VectorSubtract(end, start, move);
1283 	VectorNormalize(move);
1284 
1285 	VectorCopy(move, up);
1286 	VectorSubtract(r_newrefdef.vieworg, start, delta);
1287 	CrossProduct(up, delta, right);
1288 //	if(!VectorCompare(right, vec3_origin))
1289 		VectorNormalize(right);
1290 }
1291 
getParticleLight(particle_t * p,vec3_t pos,float lighting,vec3_t shadelight)1292 void getParticleLight (particle_t *p, vec3_t pos, float lighting, vec3_t shadelight)
1293 {
1294 	int j;
1295 	float lightest = 0;
1296 
1297 	if (!lighting)
1298 	{
1299 		VectorSet(shadelight, p->red, p->green, p->blue);
1300 		return;
1301 	}
1302 
1303 	R_LightPoint (pos, shadelight);
1304 
1305 	shadelight[0]= (lighting*shadelight[0]+(1-lighting)) * p->red;
1306 	shadelight[1]= (lighting*shadelight[1]+(1-lighting)) * p->green;
1307 	shadelight[2]= (lighting*shadelight[2]+(1-lighting)) * p->blue;
1308 
1309 	//this cleans up the lighting
1310 	{
1311 		for (j=0;j<3;j++)
1312 			if (shadelight[j]>lightest)
1313 				lightest= shadelight[j];
1314 		if (lightest>255)
1315 			for (j=0;j<3;j++)
1316 			{
1317 				shadelight[j]*= 255/lightest;
1318 				if (shadelight[j]>255)
1319 					shadelight[j] = 255;
1320 			}
1321 
1322 		for (j=0;j<3;j++)
1323 		{
1324 			if (shadelight[j]<0)
1325 				shadelight[j] = 0;
1326 		}
1327 	}
1328 }
1329 
1330 //id move this somewhere less dirty, but im too damn lazy - psychospaz
1331 #define DEPTHHACK_RANGE_SHORT	0.999f
1332 #define DEPTHHACK_RANGE_MID		0.99f
1333 #define DEPTHHACK_RANGE_LONG	0.975f
1334 
1335 vec3_t ParticleVec[4];
1336 vec3_t shadelight;
1337 
shaderParticle(int type)1338 rscript_t *shaderParticle (int type)
1339 {
1340 	image_t		*part_img;
1341 	part_img = r_particletextures[type];
1342 
1343 	return part_img->script;
1344 }
1345 
renderParticleShader(particle_t * p,vec3_t origin,float size,qboolean translate)1346 void renderParticleShader (particle_t *p, vec3_t origin, float size, qboolean translate)
1347 {
1348 	rscript_t *rs = NULL;
1349 	float	txm,tym, alpha,s,t;
1350 	rs_stage_t *stage;
1351 	char scriptname [MAX_QPATH];
1352 	vec3_t color;
1353 
1354 	if (r_shaders->value)
1355 		rs=shaderParticle(p->image);
1356 
1357 	if (rs)
1358 	{
1359 		RS_ReadyScript(rs);
1360 
1361 		stage=rs->stage;
1362 		while (stage)
1363 		{
1364 			if (stage->colormap.enabled)
1365 				qglDisable (GL_TEXTURE_2D);
1366 			else if (stage->anim_count)
1367 				GL_Bind(RS_Animate(stage));
1368 			else
1369 				GL_Bind (stage->texture->texnum);
1370 
1371 			if (stage->blendfunc.blend)
1372 				GL_BlendFunction(stage->blendfunc.source,stage->blendfunc.dest);
1373 			else
1374 				GL_BlendFunction (p->blendfunc_src, p->blendfunc_dst);
1375 
1376 			alpha=1.0f;
1377 			if (stage->alphashift.min || stage->alphashift.speed)
1378 			{
1379 				if (!stage->alphashift.speed && stage->alphashift.min > 0)
1380 				{
1381 					alpha=stage->alphashift.min;
1382 				}
1383 				else if (stage->alphashift.speed)
1384 				{
1385 					alpha=sin(rs_realtime * stage->alphashift.speed);
1386 					alpha=(alpha+1)*0.5f;
1387 					if (alpha > stage->alphashift.max) alpha=stage->alphashift.max;
1388 					if (alpha < stage->alphashift.min) alpha=stage->alphashift.min;
1389 				}
1390 			}
1391 			alpha *= p->alpha;
1392 
1393 			if (stage->alphamask)
1394 			{
1395 				GLSTATE_ENABLE_ALPHATEST
1396 			}
1397 			else
1398 			{
1399 				GLSTATE_DISABLE_ALPHATEST
1400 			}
1401 
1402 			if (stage->colormap.enabled)
1403 			{
1404 				float red = 1, green = 1, blue = 1;
1405 
1406 				red = stage->colormap.red/255.0;
1407 				green = stage->colormap.green/255.0;
1408 				blue = stage->colormap.blue/255.0;
1409 
1410 				VectorSet(color, red,green,blue);
1411 			}
1412 			else if (stage->lightmap && p->flags&PART_SHADED)
1413 				VectorSet(color, shadelight[0]/255.0, shadelight[1]/255.0, shadelight[2]/255.0);
1414 			else
1415 				VectorSet(color, p->red/255.0, p->green/255.0, p->blue/255.0);
1416 
1417 
1418 			if (p->flags&PART_ALPHACOLOR)
1419 				qglColor4f(color[0]*alpha,color[1]*alpha,color[2]*alpha, alpha);
1420 			else
1421 				qglColor4f(color[0],color[1],color[2], alpha);
1422 
1423 			qglPushMatrix();
1424 			{
1425 				if (translate)
1426 				{
1427 					qglTranslatef( origin[0], origin[1], origin[2] );
1428 					qglScalef(size, size, size );
1429 				}
1430 				if (p->decal)
1431 				{
1432 					qglEnable(GL_POLYGON_OFFSET_FILL);
1433 					qglPolygonOffset(-2, -1);
1434 
1435 					qglBegin (GL_TRIANGLE_FAN);
1436 					{
1437 						int i;
1438 						float s, t;
1439 						vec3_t point;
1440 						decalpolys_t *decal = p->decal;
1441 
1442 						for (i = 0; i < p->decal->numpolys; i++)
1443 						{
1444 							s = p->decal->coords[i][0];
1445 							t = p->decal->coords[i][1];
1446 							VectorCopy(decal->polys[i], point);
1447 
1448 							RS_SetTexcoords2D (stage, &s, &t);
1449 							qglTexCoord2f (s, t);
1450 							qglVertex3fv  (point);
1451 						}
1452 					}
1453 					qglEnd ();
1454 
1455 					qglDisable(GL_POLYGON_OFFSET_FILL);
1456 				}
1457 				else
1458 				{
1459 					qglBegin (GL_QUADS);
1460 					{
1461 						float s, t;
1462 
1463 						s = 0;
1464 						t = 1;
1465 						RS_SetTexcoords2D (stage, &s, &t);
1466 						qglTexCoord2f (s, t);
1467 						qglVertex3fv  (ParticleVec[0]);
1468 						s = 0;
1469 						t = 0;
1470 						RS_SetTexcoords2D (stage, &s, &t);
1471 						qglTexCoord2f (s, t);
1472 						qglVertex3fv  (ParticleVec[1]);
1473 						s = 1;
1474 						t = 0;
1475 						RS_SetTexcoords2D (stage, &s, &t);
1476 						qglTexCoord2f (s, t);
1477 						qglVertex3fv  (ParticleVec[2]);
1478 						s = 1;
1479 						t = 1;
1480 						RS_SetTexcoords2D (stage, &s, &t);
1481 						qglTexCoord2f (s, t);
1482 						qglVertex3fv  (ParticleVec[3]);
1483 					}
1484 					qglEnd ();
1485 				}
1486 			}
1487 			qglPopMatrix ();
1488 
1489 			if (stage->colormap.enabled)
1490 				qglEnable (GL_TEXTURE_2D);
1491 
1492 			stage=stage->next;
1493 		}
1494 	}
1495 	else
1496 	{
1497 		qglPushMatrix();
1498 		{
1499 			if (translate)
1500 			{
1501 				qglTranslatef( origin[0], origin[1], origin[2] );
1502 				qglScalef(size, size, size );
1503 			}
1504 			if (p->decal)
1505 			{
1506 				qglEnable(GL_POLYGON_OFFSET_FILL);
1507 				qglPolygonOffset(-2, -1);
1508 
1509 				qglBegin (GL_TRIANGLE_FAN);
1510 				{
1511 					int i;
1512 					for (i = 0; i < p->decal->numpolys; i++)
1513 					{
1514 						qglTexCoord2f (p->decal->coords[i][0], p->decal->coords[i][1]);
1515 						qglVertex3fv  (p->decal->polys[i]);
1516 					}
1517 				}
1518 				qglEnd ();
1519 
1520 				qglDisable(GL_POLYGON_OFFSET_FILL);
1521 			}
1522 			else
1523 			{
1524 				qglBegin (GL_QUADS);
1525 				{
1526 					qglTexCoord2f (0, 1);
1527 					qglVertex3fv  (ParticleVec[0]);
1528 					qglTexCoord2f (0, 0);
1529 					qglVertex3fv  (ParticleVec[1]);
1530 					qglTexCoord2f (1, 0);
1531 					qglVertex3fv  (ParticleVec[2]);
1532 					qglTexCoord2f (1, 1);
1533 					qglVertex3fv  (ParticleVec[3]);
1534 				}
1535 				qglEnd ();
1536 			}
1537 		}
1538 		qglPopMatrix ();
1539 	}
1540 }
1541 
renderDecal(particle_t * p)1542 void renderDecal (particle_t *p)
1543 {
1544 	float size, alpha;
1545 	vec3_t angl_coord[4];
1546 	vec3_t ang_up, ang_right, ang_forward, color;
1547 	rscript_t *rs = NULL;
1548 
1549 	size = (p->size>0.1) ? p->size : 0.1;
1550 	alpha = p->alpha;
1551 
1552 
1553 	if (p->flags&PART_SHADED)
1554 	{
1555 		getParticleLight (p, p->origin, gl_particle_lighting->value, shadelight);
1556 		VectorSet(color, shadelight[0]/255.0, shadelight[1]/255.0, shadelight[2]/255.0);
1557 	}
1558 	else
1559 	{
1560 		VectorSet(shadelight, p->red, p->green, p->blue);
1561 		VectorSet(color, p->red/255.0, p->green/255.0, p->blue/255.0);
1562 	}
1563 
1564 	if (!r_shaders->value || !shaderParticle(p->image))
1565 	{
1566 		GL_BlendFunction (p->blendfunc_src, p->blendfunc_dst);
1567 		GL_Bind(texParticle(p->image));
1568 
1569 		if (p->flags&PART_ALPHACOLOR)
1570 			qglColor4f(color[0]*alpha,color[1]*alpha,color[2]*alpha, alpha);
1571 		else
1572 			qglColor4f(color[0],color[1],color[2], alpha);
1573 	}
1574 
1575 	if (!p->decal)
1576 	{
1577 		AngleVectors(p->angle, ang_forward, ang_right, ang_up);
1578 
1579 		VectorScale (ang_right, 0.75f, ang_right);
1580 		VectorScale (ang_up, 0.75f, ang_up);
1581 
1582 		VectorAdd      (ang_up, ang_right, angl_coord[0]);
1583 		VectorSubtract (ang_right, ang_up, angl_coord[1]);
1584 		VectorNegate   (angl_coord[0], angl_coord[2]);
1585 		VectorNegate   (angl_coord[1], angl_coord[3]);
1586 
1587 		VectorMA(p->origin, size, angl_coord[0], ParticleVec[0]);
1588 		VectorMA(p->origin, size, angl_coord[1], ParticleVec[1]);
1589 		VectorMA(p->origin, size, angl_coord[2], ParticleVec[2]);
1590 		VectorMA(p->origin, size, angl_coord[3], ParticleVec[3]);
1591 	}
1592 
1593 	renderParticleShader(p, NULL, 0, false);
1594 }
1595 
renderParticle(particle_t * p)1596 void renderParticle (particle_t *p)
1597 {
1598 	float		size, lighting = gl_particle_lighting->value;
1599 	vec3_t		up		= {vup[0]    * 0.75f, vup[1]    * 0.75f, vup[2]    * 0.75f};
1600 	vec3_t		right	= {vright[0] * 0.75f, vright[1] * 0.75f, vright[2] * 0.75f};
1601 	vec3_t		shadelight;
1602 	float		alpha;
1603 	vec3_t		coord[4], color;
1604 	rscript_t *rs = NULL;
1605 
1606 	VectorCopy(particle_coord[0], coord[0]);
1607 	VectorCopy(particle_coord[1], coord[1]);
1608 	VectorCopy(particle_coord[2], coord[2]);
1609 	VectorCopy(particle_coord[3], coord[3]);
1610 
1611 	size = (p->size>0.1) ? p->size : 0.1;
1612 	alpha = p->alpha;
1613 
1614 	if (p->flags&PART_DEPTHHACK_SHORT) //nice little poly-peeking - psychospaz
1615 		qglDepthRange (gldepthmin, gldepthmin + DEPTHHACK_RANGE_SHORT*(gldepthmax-gldepthmin));
1616 	if (p->flags&PART_DEPTHHACK_MID)
1617 		qglDepthRange (gldepthmin, gldepthmin + DEPTHHACK_RANGE_MID*(gldepthmax-gldepthmin));
1618 	if (p->flags&PART_DEPTHHACK_LONG)
1619 		qglDepthRange (gldepthmin, gldepthmin + DEPTHHACK_RANGE_LONG*(gldepthmax-gldepthmin));
1620 
1621 	if (p->flags&PART_OVERBRIGHT)
1622 		SetParticleOverbright(true);
1623 
1624 	if (p->flags&PART_SHADED)
1625 	{
1626 		getParticleLight (p, p->origin, lighting, shadelight);
1627 		VectorSet(color, shadelight[0]/255.0, shadelight[1]/255.0, shadelight[2]/255.0);
1628 	}
1629 	else
1630 	{
1631 		VectorSet(shadelight, p->red, p->green, p->blue);
1632 		VectorSet(color, p->red/255.0, p->green/255.0, p->blue/255.0);
1633 	}
1634 
1635 	if (!r_shaders->value || !shaderParticle(p->image))
1636 	{
1637 		GL_BlendFunction (p->blendfunc_src, p->blendfunc_dst);
1638 
1639 		GL_Bind(texParticle(p->image));
1640 
1641 		if (p->flags&PART_ALPHACOLOR)
1642 			qglColor4f(color[0]*alpha,color[1]*alpha,color[2]*alpha, alpha);
1643 		else
1644 			qglColor4f(color[0],color[1],color[2], alpha);
1645 	}
1646 
1647 	if (p->flags&PART_BEAM) //given start and end positions, will have fun here :)
1648 	{	//p->angle = start
1649 		//p->origin= end
1650 		vec3_t	angl_coord[4];
1651 		vec3_t	ang_up, ang_right;
1652 
1653 		setBeamAngles(p->angle, p->origin, ang_up, ang_right);
1654 		VectorScale(ang_right, size, ang_right);
1655 
1656 		VectorAdd(p->origin, ang_right, ParticleVec[0]);
1657 		VectorAdd(p->angle, ang_right, ParticleVec[1]);
1658 		VectorSubtract(p->angle, ang_right, ParticleVec[2]);
1659 		VectorSubtract(p->origin, ang_right, ParticleVec[3]);
1660 
1661 		renderParticleShader(p, NULL, 0, false);
1662 	}
1663 	else if (p->flags&PART_LIGHTNING) //given start and end positions, will have fun here :)
1664 	{	//p->angle = start
1665 		//p->origin= end
1666 		int k = 0;
1667 		float	len, dec, angdot;
1668 		vec3_t	move, lastvec, thisvec, tempvec;
1669 		vec3_t	angl_coord[4], old_coord[2];
1670 		vec3_t	ang_up, ang_right, last_right, abs_up, abs_right;
1671 		float	width, scale_up, scale_right;
1672 
1673 		scale_up = scale_right = 0;
1674 		dec = size*5.0;
1675 		width = size;
1676 
1677 		VectorSubtract(p->origin, p->angle, move);
1678 		len = VectorNormalize(move);
1679 
1680 		setBeamAngles(p->angle, p->origin, abs_up, abs_right);
1681 		VectorScale(move, dec, move);
1682 		VectorCopy(p->angle, thisvec);
1683 		VectorSubtract(thisvec, move, lastvec);
1684 		VectorCopy(thisvec, tempvec);
1685 		len+=dec;
1686 
1687 		setBeamAngles(lastvec, thisvec, ang_up, ang_right);
1688 		VectorScale (ang_right, width, ang_right);
1689 
1690 		while (len>dec)
1691 		{
1692 			VectorCopy(ang_right, last_right);
1693 
1694 			setBeamAngles(lastvec, thisvec, ang_up, ang_right);
1695 			VectorScale (ang_right, width, ang_right);
1696 
1697 			angdot = DotProduct(ang_right, last_right);
1698 			{
1699 				VectorAdd(lastvec, ang_right, ParticleVec[1]);
1700 				VectorSubtract(lastvec, ang_right, ParticleVec[2]);
1701 
1702 				VectorAdd(thisvec, ang_right, ParticleVec[0]);
1703 				VectorSubtract(thisvec, ang_right, ParticleVec[3]);
1704 
1705 				VectorCopy(ParticleVec[0], old_coord[0]);
1706 				VectorCopy(ParticleVec[3], old_coord[1]);
1707 			}
1708 			if (k>0)
1709 				renderParticleShader(p, NULL, 0, false);
1710 
1711 			k++;
1712 
1713 			len-=dec;
1714 
1715 			VectorCopy(thisvec, lastvec);
1716 
1717 			//now modify stuff
1718 			{
1719 				float diff = lastvec[0] + lastvec[1] + lastvec[2];
1720 				//scale_up += crandom() * size;
1721 				//scale_right -= crandom() * size;
1722 
1723 				scale_up = size*( cos(diff*0.1+rs_realtime*15.0) );
1724 				scale_right = size*( sin( diff*0.1+rs_realtime*15.0) );
1725 			}
1726 			if (scale_right > size) scale_right = size;
1727 			if (scale_right < -size) scale_right = -size;
1728 			if (scale_up > size) scale_up = size;
1729 			if (scale_up < -size) scale_up = -size;
1730 
1731 
1732 			VectorAdd(tempvec, move, tempvec);
1733 			thisvec[0] = tempvec[0] + abs_up[0]*scale_up + abs_right[0]*scale_right;
1734 			thisvec[1] = tempvec[1] + abs_up[1]*scale_up + abs_right[1]*scale_right;
1735 			thisvec[2] = tempvec[2] + abs_up[2]*scale_up + abs_right[2]*scale_right;
1736 		}
1737 
1738 		//one more time
1739 		if (len>0)
1740 		{
1741 			VectorCopy(p->origin, thisvec);
1742 			VectorCopy(ang_right, last_right);
1743 
1744 			setBeamAngles(lastvec, thisvec, ang_up, ang_right);
1745 			VectorScale (ang_right, width, ang_right);
1746 
1747 			angdot = DotProduct(ang_right, last_right);
1748 			{
1749 				VectorAdd(lastvec, ang_right, ParticleVec[1]);
1750 				VectorSubtract(lastvec, ang_right, ParticleVec[2]);
1751 
1752 				VectorAdd(thisvec, ang_right, ParticleVec[0]);
1753 				VectorSubtract(thisvec, ang_right, ParticleVec[3]);
1754 
1755 				VectorCopy(ParticleVec[0], old_coord[0]);
1756 				VectorCopy(ParticleVec[3], old_coord[1]);
1757 			}
1758 			renderParticleShader(p, NULL, 0, false);
1759 		}
1760 	}
1761 	else if (p->flags&PART_DIRECTION) //streched out in direction...tracers etc...
1762 		//never dissapears because of angle like other engines :D
1763 	{
1764 		vec3_t angl_coord[4];
1765 		vec3_t ang_up, ang_right, vdelta;
1766 
1767 		VectorAdd(p->angle, p->origin, vdelta);
1768 		setBeamAngles(vdelta, p->origin, ang_up, ang_right);
1769 
1770 		VectorScale (ang_right, 0.75f, ang_right);
1771 		VectorScale (ang_up, 0.75f * VectorLength(p->angle), ang_up);
1772 
1773 		VectorAdd      (ang_up, ang_right, ParticleVec[0]);
1774 		VectorSubtract (ang_right, ang_up, ParticleVec[1]);
1775 		VectorNegate   (ParticleVec[0], ParticleVec[2]);
1776 		VectorNegate   (ParticleVec[1], ParticleVec[3]);
1777 
1778 		renderParticleShader(p, p->origin, size, true);
1779 	}
1780 	else if (p->flags&PART_ANGLED) //facing direction... (decal wannabes)
1781 	{
1782 		vec3_t angl_coord[4];
1783 		vec3_t ang_up, ang_right, ang_forward;
1784 
1785 		AngleVectors(p->angle, ang_forward, ang_right, ang_up);
1786 
1787 		VectorScale (ang_right, 0.75f, ang_right);
1788 		VectorScale (ang_up, 0.75f, ang_up);
1789 
1790 		VectorAdd      (ang_up, ang_right, ParticleVec[0]);
1791 		VectorSubtract (ang_right, ang_up, ParticleVec[1]);
1792 		VectorNegate   (ParticleVec[0], ParticleVec[2]);
1793 		VectorNegate   (ParticleVec[1], ParticleVec[3]);
1794 
1795 		qglDisable (GL_CULL_FACE);
1796 
1797 		renderParticleShader(p, p->origin, size, true);
1798 
1799 		qglEnable (GL_CULL_FACE);
1800 
1801 	}
1802 	else //normal sprites
1803 	{
1804 		if (p->angle[2]) //if we have roll, we do calcs
1805 		{
1806 			vec3_t angl_coord[4];
1807 			vec3_t ang_up, ang_right, ang_forward;
1808 
1809 			VectorSubtract(p->origin, r_newrefdef.vieworg, angl_coord[0]);
1810 
1811 			vectoanglerolled(angl_coord[0], p->angle[2], angl_coord[1]);
1812 			AngleVectors(angl_coord[1], ang_forward, ang_right, ang_up);
1813 
1814 			VectorScale (ang_forward, 0.75f, ang_forward);
1815 			VectorScale (ang_right, 0.75f, ang_right);
1816 			VectorScale (ang_up, 0.75f, ang_up);
1817 
1818 			VectorAdd      (ang_up, ang_right, ParticleVec[0]);
1819 			VectorSubtract (ang_right, ang_up, ParticleVec[1]);
1820 			VectorNegate   (ParticleVec[0], ParticleVec[2]);
1821 			VectorNegate   (ParticleVec[1], ParticleVec[3]);
1822 		}
1823 		else
1824 		{
1825 			VectorCopy(coord[0], ParticleVec[0]);
1826 			VectorCopy(coord[1], ParticleVec[1]);
1827 			VectorCopy(coord[2], ParticleVec[2]);
1828 			VectorCopy(coord[3], ParticleVec[3]);
1829 		}
1830 		renderParticleShader(p, p->origin, size, true);
1831 	}
1832 
1833 	if (p->flags&PART_OVERBRIGHT)
1834 		SetParticleOverbright(false);
1835 
1836 	if (p->flags&PART_DEPTHHACK)
1837 		qglDepthRange (gldepthmin, gldepthmax);
1838 }
1839 
1840 
1841 /*
1842 ============
1843 R_PolyBlend
1844 ============
1845 */
1846 
R_MotionBlurBlend(void)1847 void R_MotionBlurBlend (void)
1848 {
1849 	if (!gl_motionblur->value)
1850 		return;
1851 
1852 	GLSTATE_DISABLE_ALPHATEST
1853 	GLSTATE_ENABLE_BLEND
1854 	qglDisable (GL_DEPTH_TEST);
1855 	qglEnable (GL_TEXTURE_2D);
1856 	GL_TexEnv( GL_MODULATE );
1857 
1858     qglLoadIdentity ();
1859 
1860 	// FIXME: get rid of these
1861     qglRotatef (-90,  1, 0, 0);	    // put Z going up
1862     qglRotatef (90,  0, 0, 1);	    // put Z going up
1863 
1864 	GL_Bind(r_motionblurimage->texnum);
1865 	GL_BlendFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR);
1866 
1867 	qglColor4ub(255, 255, 255, 250);
1868 
1869 	qglBegin (GL_QUADS);
1870 		qglTexCoord2f (0, 0);
1871 			qglVertex3f (100, 100, 100);
1872 		qglTexCoord2f (1, 0);
1873 			qglVertex3f (100, -100, 100);
1874 		qglTexCoord2f (1, -1);
1875 			qglVertex3f (100, -100, -100);
1876 		qglTexCoord2f (0, -1);
1877 			qglVertex3f (100, 100, -100);
1878 	qglEnd ();
1879 
1880 	GLSTATE_DISABLE_BLEND
1881 	GLSTATE_ENABLE_ALPHATEST
1882 	GL_TexEnv( GL_REPLACE );
1883 
1884 	qglColor4f(1,1,1,1);
1885 }
1886 
R_PolyBlend(void)1887 void R_PolyBlend (void)
1888 {
1889 	if (!gl_polyblend->value)
1890 		return;
1891 	if (!v_blend[3])
1892 		return;
1893 
1894 	GLSTATE_DISABLE_ALPHATEST
1895 	GLSTATE_ENABLE_BLEND
1896 	qglDisable (GL_DEPTH_TEST);
1897 	qglDisable (GL_TEXTURE_2D);
1898 	GL_BlendFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1899 
1900     qglLoadIdentity ();
1901 
1902 	// FIXME: get rid of these
1903     qglRotatef (-90,  1, 0, 0);	    // put Z going up
1904     qglRotatef (90,  0, 0, 1);	    // put Z going up
1905 
1906 	qglColor4fv (v_blend);
1907 
1908 	qglBegin (GL_QUADS);
1909 
1910 	qglVertex3f (10, 100, 100);
1911 	qglVertex3f (10, -100, 100);
1912 	qglVertex3f (10, -100, -100);
1913 	qglVertex3f (10, 100, -100);
1914 	qglEnd ();
1915 
1916 	GLSTATE_DISABLE_BLEND
1917 	qglEnable (GL_TEXTURE_2D);
1918 	GLSTATE_ENABLE_ALPHATEST
1919 
1920 	qglColor4f(1,1,1,1);
1921 }
1922 
R_StencilBlend(void)1923 void R_StencilBlend (void)
1924 {
1925 
1926 	GLSTATE_DISABLE_ALPHATEST
1927 	GLSTATE_ENABLE_BLEND
1928 	qglDisable (GL_DEPTH_TEST);
1929 	qglDisable (GL_TEXTURE_2D);
1930 
1931     qglLoadIdentity ();
1932 
1933 	// FIXME: get rid of these
1934     qglRotatef (-90,  1, 0, 0);	    // put Z going up
1935     qglRotatef (90,  0, 0, 1);	    // put Z going up
1936 
1937 	qglColor4f(0,0,0,0.3);
1938 	qglStencilFunc( GL_NOTEQUAL, 0, 0xFFFFFFFFL );
1939 	qglStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
1940 	qglEnable(GL_STENCIL_TEST);
1941 
1942 	qglBegin (GL_QUADS);
1943 	qglVertex3f (10, 100, 100);
1944 	qglVertex3f (10, -100, 100);
1945 	qglVertex3f (10, -100, -100);
1946 	qglVertex3f (10, 100, -100);
1947 	qglEnd ();
1948 
1949 	qglDisable(GL_STENCIL_TEST);
1950 
1951 
1952 	GLSTATE_DISABLE_BLEND
1953 	qglEnable (GL_TEXTURE_2D);
1954 	GLSTATE_ENABLE_ALPHATEST
1955 
1956 	qglColor4f(1,1,1,1);
1957 }
1958 
1959 //=======================================================================
1960 
SignbitsForPlane(cplane_t * out)1961 int SignbitsForPlane (cplane_t *out)
1962 {
1963 	int	bits, j;
1964 
1965 	// for fast box on planeside test
1966 
1967 	bits = 0;
1968 	for (j=0 ; j<3 ; j++)
1969 	{
1970 		if (out->normal[j] < 0)
1971 			bits |= 1<<j;
1972 	}
1973 	return bits;
1974 }
1975 
1976 
R_SetFrustum(void)1977 void R_SetFrustum (void)
1978 {
1979 	int		i;
1980 
1981 #if 0
1982 	/*
1983 	** this code is wrong, since it presume a 90 degree FOV both in the
1984 	** horizontal and vertical plane
1985 	*/
1986 	// front side is visible
1987 	VectorAdd (vpn, vright, frustum[0].normal);
1988 	VectorSubtract (vpn, vright, frustum[1].normal);
1989 	VectorAdd (vpn, vup, frustum[2].normal);
1990 	VectorSubtract (vpn, vup, frustum[3].normal);
1991 
1992 	// we theoretically don't need to normalize these vectors, but I do it
1993 	// anyway so that debugging is a little easier
1994 	VectorNormalize( frustum[0].normal );
1995 	VectorNormalize( frustum[1].normal );
1996 	VectorNormalize( frustum[2].normal );
1997 	VectorNormalize( frustum[3].normal );
1998 #else
1999 	// rotate VPN right by FOV_X/2 degrees
2000 	RotatePointAroundVector( frustum[0].normal, vup, vpn, -(90-r_newrefdef.fov_x / 2 ) );
2001 	// rotate VPN left by FOV_X/2 degrees
2002 	RotatePointAroundVector( frustum[1].normal, vup, vpn, 90-r_newrefdef.fov_x / 2 );
2003 	// rotate VPN up by FOV_X/2 degrees
2004 	RotatePointAroundVector( frustum[2].normal, vright, vpn, 90-r_newrefdef.fov_y / 2 );
2005 	// rotate VPN down by FOV_X/2 degrees
2006 	RotatePointAroundVector( frustum[3].normal, vright, vpn, -( 90 - r_newrefdef.fov_y / 2 ) );
2007 #endif
2008 
2009 	for (i=0 ; i<4 ; i++)
2010 	{
2011 		frustum[i].type = PLANE_ANYZ;
2012 		frustum[i].dist = DotProduct (r_origin, frustum[i].normal);
2013 		frustum[i].signbits = SignbitsForPlane (&frustum[i]);
2014 	}
2015 }
2016 
2017 //=======================================================================
2018 
2019 /*
2020 ===============
2021 R_SetupFrame
2022 ===============
2023 */
R_SetupFrame(void)2024 void R_SetupFrame (void)
2025 {
2026 	int i;
2027 	mleaf_t	*leaf;
2028 
2029 	r_framecount++;
2030 
2031 // build the transformation matrix for the given view angles
2032 	VectorCopy (r_newrefdef.vieworg, r_origin);
2033 
2034 	AngleVectors (r_newrefdef.viewangles, vpn, vright, vup);
2035 
2036 // current viewcluster
2037 	if ( !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
2038 	{
2039 		r_oldviewcluster = r_viewcluster;
2040 		r_oldviewcluster2 = r_viewcluster2;
2041 		leaf = Mod_PointInLeaf (r_origin, r_worldmodel);
2042 		r_viewcluster = r_viewcluster2 = leaf->cluster;
2043 
2044 		// check above and below so crossing solid water doesn't draw wrong
2045 		if (!leaf->contents)
2046 		{	// look down a bit
2047 			vec3_t	temp;
2048 
2049 			VectorCopy (r_origin, temp);
2050 			temp[2] -= 16;
2051 			leaf = Mod_PointInLeaf (temp, r_worldmodel);
2052 			if ( !(leaf->contents & CONTENTS_SOLID) &&
2053 				(leaf->cluster != r_viewcluster2) )
2054 				r_viewcluster2 = leaf->cluster;
2055 		}
2056 		else
2057 		{	// look up a bit
2058 			vec3_t	temp;
2059 
2060 			VectorCopy (r_origin, temp);
2061 			temp[2] += 16;
2062 			leaf = Mod_PointInLeaf (temp, r_worldmodel);
2063 			if ( !(leaf->contents & CONTENTS_SOLID) &&
2064 				(leaf->cluster != r_viewcluster2) )
2065 				r_viewcluster2 = leaf->cluster;
2066 		}
2067 	}
2068 
2069 	for (i=0 ; i<4 ; i++)
2070 		v_blend[i] = r_newrefdef.blend[i];
2071 
2072 	c_brush_polys = 0;
2073 	c_alias_polys = 0;
2074 
2075 	// clear out the portion of the screen that the NOWORLDMODEL defines
2076 /*	if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
2077 	{
2078 		qglEnable( GL_SCISSOR_TEST );
2079 		qglClearColor( 0.3, 0.3, 0.3, 1 );
2080 		qglScissor( r_newrefdef.x, vid.height - r_newrefdef.height - r_newrefdef.y, r_newrefdef.width, r_newrefdef.height );
2081 		qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
2082 		qglClearColor( 1, 0, 0.5, 0.5 );
2083 		qglDisable( GL_SCISSOR_TEST );
2084 	}*/
2085 }
2086 
2087 
MYgluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear,GLdouble zFar)2088 void MYgluPerspective( GLdouble fovy, GLdouble aspect,
2089 		     GLdouble zNear, GLdouble zFar )
2090 {
2091    GLdouble xmin, xmax, ymin, ymax;
2092 
2093    ymax = zNear * tan( fovy * M_PI / 360.0 );
2094    ymin = -ymax;
2095 
2096    xmin = ymin * aspect;
2097    xmax = ymax * aspect;
2098 
2099    xmin += -( 2 * gl_state.camera_separation ) / zNear;
2100    xmax += -( 2 * gl_state.camera_separation ) / zNear;
2101 
2102    qglFrustum( xmin, xmax, ymin, ymax, zNear, zFar );
2103 }
2104 
2105 
2106 /*
2107 =============
2108 R_SetupGL
2109 =============
2110 */
R_SetupGL(void)2111 void R_SetupGL (void)
2112 {
2113 	static GLdouble farz; // DMP skybox size change
2114 	GLdouble boxsize;  // DMP skybox size change
2115 
2116 	float	screenaspect;
2117 //	float	yfov;
2118 	int		x, x2, y2, y, w, h;
2119 
2120 	//
2121 	// set up viewport
2122 	//
2123 	x = floor(r_newrefdef.x * vid.width / vid.width);
2124 	x2 = ceil((r_newrefdef.x + r_newrefdef.width) * vid.width / vid.width);
2125 	y = floor(vid.height - r_newrefdef.y * vid.height / vid.height);
2126 	y2 = ceil(vid.height - (r_newrefdef.y + r_newrefdef.height) * vid.height / vid.height);
2127 
2128 	w = x2 - x;
2129 	h = y - y2;
2130 
2131 	qglViewport (x, y2, w, h);
2132 
2133 	if (skydistance->modified)
2134 	{
2135 		skydistance->modified = false;
2136 		boxsize = skydistance->value;
2137 		boxsize -= 252 * ceil(boxsize / 2300);
2138 		farz = 1.0;
2139 		while (farz < boxsize)  // DMP: make this value a power-of-2
2140 		{
2141 			farz *= 2.0;
2142 			if (farz >= 65536.0)  // DMP: don't make it larger than this
2143 				break;
2144   		}
2145 		farz *= 2.0;	// DMP: double since boxsize is distance from camera to
2146 				// edge of skybox - not total size of skybox
2147 		ri.Con_Printf(PRINT_DEVELOPER, "farz now set to %g\n", farz);
2148 	}
2149 
2150 
2151 	//
2152 	// set up projection matrix
2153 	//
2154     screenaspect = (float)r_newrefdef.width/r_newrefdef.height;
2155 //	yfov = 2*atan((float)r_newrefdef.height/r_newrefdef.width)*180/M_PI;
2156 	qglMatrixMode(GL_PROJECTION);
2157     qglLoadIdentity ();
2158 
2159 //    MYgluPerspective (r_newrefdef.fov_y,  screenaspect,  4,  4096);
2160 	MYgluPerspective (r_newrefdef.fov_y,  screenaspect, 4, farz); // DMP skybox
2161 
2162 
2163 	qglCullFace(GL_FRONT);
2164 
2165 	qglMatrixMode(GL_MODELVIEW);
2166     qglLoadIdentity ();
2167 
2168     qglRotatef (-90,  1, 0, 0);	    // put Z going up
2169     qglRotatef (90,  0, 0, 1);	    // put Z going up
2170     qglRotatef (-r_newrefdef.viewangles[2],  1, 0, 0);
2171     qglRotatef (-r_newrefdef.viewangles[0],  0, 1, 0);
2172     qglRotatef (-r_newrefdef.viewangles[1],  0, 0, 1);
2173     qglTranslatef (-r_newrefdef.vieworg[0],  -r_newrefdef.vieworg[1],  -r_newrefdef.vieworg[2]);
2174 
2175 //	if ( gl_state.camera_separation != 0 && gl_state.stereo_enabled )
2176 //		qglTranslatef ( gl_state.camera_separation, 0, 0 );
2177 
2178 	qglGetFloatv (GL_MODELVIEW_MATRIX, r_world_matrix);
2179 
2180 	qglGetIntegerv (GL_VIEWPORT, r_viewport);
2181 
2182 	//
2183 	// set drawing parms
2184 	//
2185 	if (gl_cull->value)
2186 		qglEnable(GL_CULL_FACE);
2187 	else
2188 		qglDisable(GL_CULL_FACE);
2189 
2190 	GLSTATE_DISABLE_BLEND
2191 	GLSTATE_DISABLE_ALPHATEST
2192 	qglEnable(GL_DEPTH_TEST);
2193 }
2194 
2195 /*
2196 =============
2197 R_Clear
2198 =============
2199 */
R_Clear(void)2200 void R_Clear (void)
2201 {
2202 
2203 	if (gl_ztrick->value)
2204 	{
2205 		static int trickframe;
2206 
2207 		if (gl_clear->value)
2208 			qglClear (GL_COLOR_BUFFER_BIT);
2209 
2210 		trickframe++;
2211 		if (trickframe & 1)
2212 		{
2213 			gldepthmin = 0;
2214 			gldepthmax = 0.49999;
2215 			qglDepthFunc (GL_LEQUAL);
2216 		}
2217 		else
2218 		{
2219 			gldepthmin = 1;
2220 			gldepthmax = 0.5;
2221 			qglDepthFunc (GL_GEQUAL);
2222 		}
2223 	}
2224 	else
2225 	{
2226 		if (gl_clear->value)
2227 			qglClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2228 		else
2229 			qglClear (GL_DEPTH_BUFFER_BIT);
2230 		gldepthmin = 0;
2231 		gldepthmax = 1;
2232 		qglDepthFunc (GL_LEQUAL);
2233 	}
2234 
2235 	if (have_stencil)
2236 	{
2237 		qglClearStencil(0);
2238 		qglClear(GL_STENCIL_BUFFER_BIT);
2239 	}
2240 
2241 	//this is for spheremapping...
2242 	qglTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
2243 	qglTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
2244 
2245 	qglDepthRange (gldepthmin, gldepthmax);
2246 
2247 }
2248 
R_ShadowBlend()2249 void R_ShadowBlend()
2250 {
2251 	if (!gl_shadows->value)
2252 		return;
2253 
2254     qglLoadIdentity ();
2255 
2256 	// FIXME: get rid of these
2257     qglRotatef (-90,  1, 0, 0);	    // put Z going up
2258     qglRotatef (90,  0, 0, 1);	    // put Z going up
2259 
2260 	qglColor4f (0,0,0,0.4f);
2261 
2262 	GLSTATE_DISABLE_ALPHATEST
2263 	GLSTATE_ENABLE_BLEND
2264 	qglDisable (GL_DEPTH_TEST);
2265 	qglDisable (GL_TEXTURE_2D);
2266 
2267 	qglEnable(GL_STENCIL_TEST);
2268 	qglStencilFunc( GL_NOTEQUAL, 0, 0xFF);
2269 	qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2270 
2271 	qglBegin (GL_QUADS);
2272 
2273 	qglVertex3f (10, 100, 100);
2274 	qglVertex3f (10, -100, 100);
2275 	qglVertex3f (10, -100, -100);
2276 	qglVertex3f (10, 100, -100);
2277 	qglEnd ();
2278 
2279 	GLSTATE_DISABLE_BLEND
2280 	qglEnable (GL_TEXTURE_2D);
2281 	GLSTATE_ENABLE_ALPHATEST
2282 	qglDisable(GL_STENCIL_TEST);
2283 
2284 	qglColor4f(1,1,1,1);
2285 }
2286 
R_Flash(void)2287 void R_Flash( void )
2288 {
2289 	R_PolyBlend ();
2290 	R_ShadowBlend ();
2291 }
2292 /*
2293 ================
2294 R_RenderView
2295 
2296 r_newrefdef must be set before the first call
2297 ================
2298 */
2299 
2300 void R_DrawSkyBox_Models (void);
2301 void R_DrawSpecialSurfaces(void);
2302 
R_RenderMotionBlurView(refdef_t * fd)2303 void R_RenderMotionBlurView (refdef_t *fd)
2304 {
2305 	if (r_norefresh->value)
2306 		return;
2307 
2308 	r_newrefdef = *fd;
2309 
2310 	if (!r_worldmodel && !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
2311 		ri.Sys_Error (ERR_DROP, "R_RenderView: NULL worldmodel");
2312 
2313 	if (r_speeds->value)
2314 	{
2315 		c_brush_polys = 0;
2316 		c_alias_polys = 0;
2317 	}
2318 
2319 	R_PushDlights ();
2320 
2321 	if (gl_finish->value)
2322 		qglFinish ();
2323 
2324 	R_SetupFrame ();
2325 	R_SetFrustum ();
2326 	R_SetupGL ();
2327 	R_MarkLeaves ();	// done here so we know if we're in water
2328 	R_DrawWorld ();
2329 
2330 	GLSTATE_DISABLE_ALPHATEST
2331 
2332 	R_DrawMotionBlurEntities();
2333 	R_MotionBlurBlend();
2334 }
2335 
R_RenderDynamicView(refdef_t * fd)2336 void R_RenderDynamicView (refdef_t *fd)
2337 {
2338 	if (r_norefresh->value)
2339 		return;
2340 
2341 	r_newrefdef = *fd;
2342 
2343 	if (!r_worldmodel && !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
2344 		ri.Sys_Error (ERR_DROP, "R_RenderView: NULL worldmodel");
2345 
2346 	if (r_speeds->value)
2347 	{
2348 		c_brush_polys = 0;
2349 		c_alias_polys = 0;
2350 	}
2351 
2352 	R_PushDlights ();
2353 
2354 	if (gl_finish->value)
2355 		qglFinish ();
2356 
2357 	R_SetupFrame ();
2358 	R_SetFrustum ();
2359 	R_SetupGL ();
2360 	R_MarkLeaves ();	// done here so we know if we're in water
2361 	R_DrawWorld ();
2362 
2363 	GLSTATE_DISABLE_ALPHATEST
2364 
2365 	R_RenderDlights ();
2366 
2367 	//never sort - could get too messy!
2368 	R_DrawSpecialSurfaces();
2369 	if (rs_dynamic_particles->value)
2370 	{
2371 		R_DrawAllDecals();
2372 		R_DrawAllParticles();
2373 	}
2374 	if (rs_dynamic_entities->value)
2375 		R_DrawAllEntities(false);
2376 	R_DrawAlphaSurfaces (false);
2377 }
2378 
R_RenderGlareView(refdef_t * fd)2379 void R_RenderGlareView (refdef_t *fd)
2380 {
2381 
2382 	if (r_norefresh->value)
2383 		return;
2384 
2385 	r_newrefdef = *fd;
2386 
2387 	if (!r_worldmodel && !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
2388 		ri.Sys_Error (ERR_DROP, "R_RenderView: NULL worldmodel");
2389 
2390 	if (r_speeds->value)
2391 	{
2392 		c_brush_polys = 0;
2393 		c_alias_polys = 0;
2394 	}
2395 
2396 	R_PushDlights ();
2397 
2398 	if (gl_finish->value)
2399 		qglFinish ();
2400 
2401 	R_SetupFrame ();
2402 	R_SetFrustum ();
2403 	R_SetupGL ();
2404 	R_MarkLeaves ();	// done here so we know if we're in water
2405 	R_DrawWorld ();
2406 
2407 	GLSTATE_DISABLE_ALPHATEST
2408 
2409 	R_DrawAllSubDecals();
2410 	R_DrawAllEntities(true);
2411 	if (rs_glares_particles->value)
2412 		R_DrawAllAddGlareParticles();
2413 }
2414 
2415 
checkSurfaceTrace(msurface_t * surf,vec3_t end,vec3_t start)2416 qboolean checkSurfaceTrace (msurface_t *surf, vec3_t end, vec3_t start)
2417 {
2418 	float front, back, side, dist;
2419 	vec3_t normal;
2420 	cplane_t *plane;
2421 
2422 	plane = surf->plane;
2423 
2424 	if (!plane)
2425 		return false;
2426 
2427 	dist = plane->dist;
2428 	VectorCopy(plane->normal, normal);
2429 
2430 	front = DotProduct (start, normal) - dist;
2431 	back = DotProduct (end, normal) - dist;
2432 	side = front < 0;
2433 
2434 	if ( (back < 0) == side)
2435 		return false;
2436 
2437 	return true;
2438 }
2439 
TracePoints(vec3_t start,vec3_t end,void * surface)2440 qboolean TracePoints (vec3_t start, vec3_t end, void *surface)
2441 {
2442 	int i;
2443 	msurface_t	*surf = r_worldmodel->surfaces;
2444 	for (i=0; i<r_worldmodel->numsurfaces; i++, surf++)
2445 	{
2446 		if (surf == surface)
2447 			continue;
2448 		if (surf->texinfo->flags & (SURF_TRANS33 | SURF_TRANS66))
2449 			continue;
2450 		if (checkSurfaceTrace(surf, start, end))
2451 			return true;
2452 	}
2453 	return false;
2454 }
2455 
2456 
checkElementSurfaceScan(msurface_t * surf,vec3_t start)2457 qboolean checkElementSurfaceScan (msurface_t *surf, vec3_t start)
2458 {
2459 	float front, back, side, dist;
2460 	vec3_t end, normal;
2461 	cplane_t *plane;
2462 
2463 	plane = surf->plane;
2464 
2465 	if (!plane)
2466 		return false;
2467 
2468 	dist = plane->dist;
2469 	VectorCopy(plane->normal, normal);
2470 	VectorCopy(r_newrefdef.vieworg, end);
2471 
2472 	front = DotProduct (start, normal) - dist;
2473 	back = DotProduct (end, normal) - dist;
2474 	side = front < 0;
2475 
2476 	if ( (back < 0) == side)
2477 		return false;
2478 
2479 	return true;
2480 }
2481 
2482 sortedelement_t *listswap[2];
ElementChecker(sortedelement_t * element,msurface_t * surf)2483 void ElementChecker (sortedelement_t *element, msurface_t *surf)
2484 {
2485 	if (!element)
2486 		return;
2487 
2488 	ElementChecker(element->right, surf);
2489 	ElementChecker(element->left, surf);
2490 	element->left = element->right = NULL;
2491 
2492 	if (checkElementSurfaceScan(surf, element->org))
2493 	{
2494 		if (!listswap[0])
2495 			listswap[0] = element;
2496 		else
2497 			ElementAddNode(listswap[0], element);
2498 	}
2499 	else
2500 	{
2501 		if (!listswap[1])
2502 			listswap[1] = element;
2503 		else
2504 			ElementAddNode(listswap[1], element);
2505 	}
2506 }
2507 
surf_ElementList(msurface_t * surf,qboolean ents)2508 void surf_ElementList(msurface_t *surf, qboolean ents)
2509 {
2510 	sortedelement_t *temp, *element, *last = NULL, *found = NULL;
2511 
2512 	listswap[0] = listswap[1] = NULL;
2513 
2514 	if (ents)
2515 		ElementChecker(ents_prerender, surf);
2516 	else
2517 		ElementChecker(parts_prerender, surf);
2518 
2519 	if (ents)
2520 	{
2521 		ents_prerender = listswap[1];
2522 		RenderEntTree(listswap[0]);
2523 	}
2524 	else
2525 	{
2526 		parts_prerender = listswap[1];
2527 		R_DrawParticles(listswap[0]);
2528 	}
2529 }
2530 
R_DrawLastElements(void)2531 void R_DrawLastElements (void)
2532 {
2533 	if (parts_prerender)
2534 		R_DrawParticles(parts_prerender);
2535 	if (ents_prerender)
2536 		RenderEntTree(ents_prerender);
2537 }
2538 
R_RenderView(refdef_t * fd)2539 void R_RenderView (refdef_t *fd)
2540 {
2541 	qboolean mBlur = fd->rdflags & RDF_MOTIONBLUR;
2542 
2543 	if (mBlur)
2544 			fd->rdflags &= ~RDF_MOTIONBLUR;
2545 
2546 	if (r_norefresh->value)
2547 		return;
2548 
2549 	r_newrefdef = *fd;
2550 
2551 	if (!r_worldmodel && !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
2552 		ri.Sys_Error (ERR_DROP, "R_RenderView: NULL worldmodel");
2553 
2554 	if (r_speeds->value)
2555 	{
2556 		c_brush_polys = 0;
2557 		c_alias_polys = 0;
2558 	}
2559 
2560 	R_PushDlights ();
2561 
2562 	if (gl_finish->value)
2563 		qglFinish ();
2564 
2565 	R_SetupFrame ();
2566 
2567 	R_SetFrustum ();
2568 
2569 	R_SetupGL ();
2570 
2571 	R_MarkLeaves ();	// done here so we know if we're in water
2572 
2573 	R_DrawWorld ();
2574 
2575 	if (r_newrefdef.rdflags & RDF_NOWORLDMODEL) //options menu
2576 	{
2577 		R_DrawAllDecals();
2578 		R_DrawAllEntities(false);
2579 		R_DrawAllParticles();
2580 	}
2581 	else
2582 	{
2583 		R_DrawSpecialSurfaces();
2584 
2585 		GLSTATE_DISABLE_ALPHATEST
2586 
2587 		R_RenderDlights ();
2588 
2589 		//spaz -> my nice trees
2590 		if (gl_transrendersort->value)
2591 		{
2592 			GL_BuildParticleList();
2593 			R_DrawSolidEntities();
2594 	//		R_DrawAllEntityShadows();
2595 			R_DrawDecals ();
2596 
2597 			if (gl_transrendersort->value==1)
2598 			{
2599 				R_DrawLastElements();
2600 				R_DrawAlphaSurfaces (false);
2601 			}
2602 			else
2603 			{
2604 				R_DrawAlphaSurfaces (true);
2605 				R_DrawLastElements();
2606 			}
2607 		}
2608 		//nonsorted routines
2609 		else
2610 		{
2611 			R_DrawAllDecals();
2612 
2613 			R_DrawAllEntities(true);
2614 	//		R_DrawAllEntityShadows();
2615 
2616 			R_DrawAllParticles();
2617 			R_DrawAlphaSurfaces (false);
2618 		}
2619 
2620 		//always draw vwep last...
2621 		R_DrawEntitiesOnList(ents_viewweaps);
2622 		R_DrawEntitiesOnList(ents_viewweaps_trans);
2623 
2624 		R_DrawAllEntityShadows();
2625 
2626 		R_Flash();
2627 
2628 		if (r_speeds->value)
2629 		{
2630 			ri.Con_Printf (PRINT_ALL, "%4i wpoly %4i epoly %i tex %i lmaps\n",
2631 				c_brush_polys,
2632 				c_alias_polys,
2633 				c_visible_textures,
2634 				c_visible_lightmaps);
2635 		}
2636 	}
2637 
2638 	if (mBlur)
2639 	{
2640 		R_MotionBlurBlend();
2641 		fd->rdflags |= RDF_MOTIONBLUR;
2642 	}
2643 }
2644 
mulc(int i1,const float mult)2645 byte mulc(int i1, const float mult)
2646 {
2647 	//amplify colors a bit
2648 	int r = i1 * mult;
2649 
2650 	if (r > 255) return 255;
2651 	else return r;
2652 }
2653 
ProcessGlare(byte glarepixels[][4],int width,int height,const float mult)2654 void ProcessGlare(byte glarepixels[][4], int width, int height, const float mult)
2655 {
2656 	int i;
2657 
2658 	for (i=0; i<width*height; i++)
2659 	{
2660 
2661 		if ( (glarepixels[i][0] != 0) ||
2662 			 (glarepixels[i][1] != 0) ||
2663 			 (glarepixels[i][2] != 0) )
2664 		{
2665 
2666 			glarepixels[i][0] = mulc(glarepixels[i][0], mult);
2667 			glarepixels[i][1] = mulc(glarepixels[i][1], mult);
2668 			glarepixels[i][2] = mulc(glarepixels[i][2], mult);
2669 		}
2670 		else
2671 		{
2672 			glarepixels[i][0] = 0;
2673 			glarepixels[i][1] = 0;
2674 			glarepixels[i][2] = 0;
2675 		}
2676 	}
2677 }
2678 
2679 /*
2680 Fast Idea Blurring from
2681 http://www.gamasutra.com/features/20010209/evans_01.htm
2682 */
2683 typedef struct bytecolor_s
2684 {
2685 	byte r,g,b,a;
2686 } bytecolor_t;
2687 typedef struct longcolor_s
2688 {
2689 	unsigned long r,g,b,a;
2690 } longcolor_t;
2691 
DoPreComputation(bytecolor_t * src,int src_w,int src_h,longcolor_t * dst)2692 void DoPreComputation(bytecolor_t *src, int src_w, int src_h, longcolor_t *dst)
2693 {
2694 	longcolor_t tot;
2695 	int y,x;
2696 
2697 	for (y=0;y<src_h;y++)
2698 	{
2699 		for (x=0;x<src_w;x++)
2700 		{
2701 			tot.r = src[0].r;
2702 			tot.g = src[0].g;
2703 			tot.b = src[0].b;
2704 			tot.a = 255;
2705 
2706 			if (x>0)
2707 			{
2708 				tot.r+=dst[-1].r;
2709 				tot.g+=dst[-1].g;
2710 				tot.b+=dst[-1].b;
2711 			}
2712 			if (y>0)
2713 			{
2714 				tot.r+=dst[-src_w].r;
2715 				tot.g+=dst[-src_w].g;
2716 				tot.b+=dst[-src_w].b;
2717 			}
2718 			if (x>0 && y>0)
2719 			{
2720 				tot.r-=dst[-src_w-1].r;
2721 				tot.g-=dst[-src_w-1].g;
2722 				tot.b-=dst[-src_w-1].b;
2723 			}
2724 			dst->r=tot.r;
2725 			dst->g=tot.g;
2726 			dst->b=tot.b;
2727 			dst->a=255;
2728 			dst++;
2729 			src++;
2730 		}
2731 	}
2732 }
2733 
2734 // this is a utility function used by DoBoxBlur below
ReadP(longcolor_t * p,int w,int h,int x,int y)2735 longcolor_t *ReadP(longcolor_t *p, int w, int h, int x, int y)
2736 {
2737 	if (x<0) x=0; else if (x>=w) x=w-1;
2738 	if (y<0) y=0; else if (y>=h) y=h-1;
2739 	return &p[x+y*w];
2740 }
2741 
2742 // the main meat of the algorithm lies here
DoBoxBlur(bytecolor_t * src,int src_w,int src_h,bytecolor_t * dst,longcolor_t * p,int boxw,int boxh)2743 void DoBoxBlur(bytecolor_t *src, int src_w, int src_h, bytecolor_t *dst, longcolor_t *p, int boxw, int boxh)
2744 {
2745 	longcolor_t *to1, *to2, *to3, *to4;
2746 	int y,x;
2747 	float mul;
2748 
2749 	if (boxw<0 || boxh<0)
2750 	{
2751 		memcpy(dst,src,src_w*src_h*4); // deal with degenerate kernel sizes
2752 		return;
2753 	}
2754 	mul=1.f/((boxw*2+1)*(boxh*2+1));
2755 	for (y=0;y<src_h;y++)
2756 	{
2757 		for (x=0;x<src_w;x++)
2758 		{
2759 			to1 = ReadP(p, src_w, src_h, x+boxw, y+boxh);
2760 			to2 = ReadP(p, src_w, src_h, x-boxw, y-boxh);
2761 			to3 = ReadP(p, src_w, src_h, x-boxw, y+boxh);
2762 			to4 = ReadP(p, src_w, src_h, x+boxw, y-boxh);
2763 
2764 			dst->r= (to1->r + to2->r - to3->r - to4->r)*mul;
2765 			dst->g= (to1->g + to2->g - to3->g - to4->g)*mul;
2766 			dst->b= (to1->b + to2->b - to3->b - to4->b)*mul;
2767 
2768 			dst->a= 255;
2769 
2770 			dst++;
2771 			src++;
2772 		}
2773 	}
2774 }
2775 
2776 qboolean screenMotionBlurRender = false;
ProcessBlur(bytecolor_t * src,int src_w,int src_h)2777 void ProcessBlur (bytecolor_t *src, int src_w, int src_h)
2778 {
2779 	int x, y, alpha, r ,g ,b, noalpha= true;
2780 
2781 	for (y=0;y<src_h;y++)
2782 		for (x=0;x<src_w;x++, src++)
2783 		{
2784 			r = src->r;
2785 			g = src->g;
2786 			b = src->b;
2787 
2788 			alpha = (r + g + b);
2789 			src->r = r*r * DIV255;
2790 			src->g = g*g * DIV255;
2791 			src->b = b*b * DIV255;
2792 
2793 			if (alpha > 254)
2794 				alpha = 254;
2795 
2796 			if (alpha > 0)
2797 				noalpha = false;
2798 
2799 			src->a = alpha;
2800 		}
2801 
2802 	if (noalpha)
2803 		screenMotionBlurRender = false;
2804 }
2805 
2806 byte imagepixels[256*256][4];
2807 byte glareblurpixels[256*256][4];
2808 long glaresum[256*256][4];
2809 
2810 const int powerof2s[] = { 8, 16, 32, 64 , 128, 256 };
checkResolution(int check)2811 int checkResolution (int check)
2812 {
2813 	int i;
2814 
2815 	for (i=5; i>0; i--)
2816 		if (check>=powerof2s[i])
2817 			return powerof2s[i];
2818 
2819 	return powerof2s[0];
2820 }
2821 
2822 float CalcFov (float fov_x, float width, float height);
2823 int lastcapture = 0;
2824 qboolean renderDynamic = false;
2825 qboolean renderMotionBlur = false;
2826 
setRenderDynamic(void)2827 void setRenderDynamic (void)
2828 {
2829 	renderDynamic = true;
2830 }
setRenderMotionBlur(void)2831 void setRenderMotionBlur (void)
2832 {
2833 	renderMotionBlur = true;
2834 }
2835 
R_PreRenderDynamic(refdef_t * fd)2836 void R_PreRenderDynamic (refdef_t *fd)
2837 {
2838 	int i;
2839 	msurface_t *surf;
2840 	refdef_t refdef;
2841 	qboolean motionBlurScreen = fd->rdflags & RDF_MOTIONBLUR;
2842 
2843 	if (fd->rdflags & RDF_NOWORLDMODEL)
2844 		return;
2845 
2846 	if (r_shaders->value && lastcapture++ > rs_dynamic_time->value && renderDynamic)
2847 	{
2848 		int width = checkResolution(rs_dynamic_size->value);
2849 		int height = checkResolution(rs_dynamic_size->value);
2850 
2851 		//lower res wont get messed up
2852 		if (vid.width < width || vid.height < height)
2853 			width = height = 128;
2854 
2855 		renderDynamic = false;
2856 		lastcapture = 0;
2857 
2858 		memcpy (&refdef, fd, sizeof( refdef ));
2859 
2860 		refdef.x = 0;
2861 		refdef.y = vid.height - height;
2862 		refdef.width = width;
2863 		refdef.height = height;
2864 		refdef.fov_x = 150;
2865 		refdef.fov_y = CalcFov (refdef.fov_x, refdef.width, refdef.height);
2866 		refdef.viewangles[1] += (refdef.viewangles[1]>180)? -180: 180;
2867 		if (motionBlurScreen)
2868 			refdef.rdflags &= ~RDF_MOTIONBLUR;
2869 
2870 		R_Clear();
2871 		R_RenderDynamicView ( &refdef );
2872 		GL_Bind(r_dynamicimage->texnum);
2873 
2874 		qglReadPixels (0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, imagepixels);
2875 		qglTexImage2D (GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imagepixels);
2876 
2877 		r_dynamicimage->upload_width = width;
2878 		r_dynamicimage->upload_height = height;
2879 	}
2880 
2881 	if (rs_glares->value)
2882 	{
2883 		int width = checkResolution(rs_glares_size->value);
2884 		int height = checkResolution(rs_glares_size->value);
2885 
2886 		//lower res wont get messed up
2887 		if (vid.width < width || vid.height < height)
2888 			width = height = 128;
2889 
2890 		memcpy (&refdef, fd, sizeof( refdef ));
2891 
2892 		refdef.x = 0;
2893 		refdef.y = vid.height - height;
2894 		refdef.width = width;
2895 		refdef.height = height;
2896 		refdef.fov_y = CalcFov (refdef.fov_x, refdef.width, refdef.height);
2897 		refdef.rdflags |= RDF_LIGHTBLEND;
2898 		if (motionBlurScreen)
2899 			refdef.rdflags &= ~RDF_MOTIONBLUR;
2900 
2901 		R_Clear();
2902 		R_RenderGlareView ( &refdef );
2903 		GL_Bind(r_lblendimage->texnum);
2904 
2905 		qglReadPixels (0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, imagepixels);
2906 
2907 		ProcessGlare(imagepixels, width, height, 1 + rs_glares->value*.5);
2908 		DoPreComputation((bytecolor_t *)imagepixels, width, height, (longcolor_t *)glaresum);
2909 		DoBoxBlur((bytecolor_t *)imagepixels, width, height,
2910 				(bytecolor_t *)glareblurpixels, (longcolor_t *)glaresum, rs_glares->value*3, rs_glares->value*3);
2911 		if (rs_glares->value != 1)
2912 			ProcessGlare(glareblurpixels, width, height, 1 + rs_glares->value/3);
2913 		qglTexImage2D (GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, glareblurpixels);
2914 
2915 		r_lblendimage->upload_width = width;
2916 		r_lblendimage->upload_height = height;
2917 	}
2918 
2919 	if (gl_motionblur->value && (motionBlurScreen || renderMotionBlur || screenMotionBlurRender))
2920 	{
2921 		int width = checkResolution(gl_motionblur_size->value);
2922 		int height = checkResolution(gl_motionblur_size->value);
2923 
2924 		//lower res wont get messed up
2925 		if (vid.width < width || vid.height < height)
2926 			width = height = 128;
2927 
2928 		renderMotionBlur = false;
2929 		screenMotionBlurRender = true;
2930 
2931 		memcpy (&refdef, fd, sizeof( refdef ));
2932 
2933 		refdef.x = 0;
2934 		refdef.y = vid.height - height;
2935 		refdef.width = width;
2936 		refdef.height = height;
2937 		refdef.fov_y = CalcFov (refdef.fov_x, refdef.width, refdef.height);
2938 
2939 		R_Clear();
2940 
2941 		if (motionBlurScreen)
2942 		{
2943 			R_RenderView( &refdef );
2944 		}
2945 		else
2946 		{
2947 			refdef.rdflags |= RDF_MOTIONBLUR;
2948 			R_RenderMotionBlurView ( &refdef );
2949 		}
2950 
2951 		qglReadPixels (0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, imagepixels);
2952 
2953 		GL_Bind(r_motionblurimage->texnum);
2954 		qglTexImage2D (GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imagepixels);
2955 
2956 		GL_Bind(r_motionblurscreenimage->texnum);
2957 		ProcessBlur((void *)imagepixels, width, height);
2958 		qglTexImage2D (GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imagepixels);
2959 
2960 
2961 		r_motionblurscreenimage->upload_width = width;
2962 		r_motionblurscreenimage->upload_height = height;
2963 		r_motionblurimage->upload_width = width;
2964 		r_motionblurimage->upload_height = height;
2965 	}
2966 
2967 	R_Clear();
2968 }
2969 
R_RenderPic(int x,int y,int w,int h)2970 void R_RenderPic(int x, int y, int w, int h)
2971 {
2972 	qglTexCoord2f (0, 0);
2973 		qglVertex2f (x, y);
2974 	qglTexCoord2f (1, 0);
2975 		qglVertex2f (x+w, y);
2976 	qglTexCoord2f (1, -1);
2977 		qglVertex2f (x+w, y+h);
2978 	qglTexCoord2f (0, -1);
2979 		qglVertex2f (x, y+h);
2980 }
2981 
2982 
2983 
R_RenderMotionBlur(refdef_t * fd)2984 void R_RenderMotionBlur (refdef_t *fd)
2985 {
2986 	int x, y, w, h;
2987 
2988 	if (fd->rdflags & RDF_NOWORLDMODEL)
2989 		return;
2990 	if (!gl_motionblur->value)
2991 		return;
2992 	if (!screenMotionBlurRender)
2993 		return;
2994 
2995 	w = fd->width;
2996 	h = fd->width;
2997 	x = 0;
2998 	y = (fd->width-fd->height)*-0.5;
2999 
3000 	GL_Bind (r_motionblurscreenimage->texnum);
3001 	GL_BlendFunction(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
3002 
3003 	GLSTATE_DISABLE_ALPHATEST
3004 	GLSTATE_ENABLE_BLEND
3005 	GL_TexEnv( GL_MODULATE );
3006 	qglColor4ub(255, 255, 255, 255);
3007 
3008 	qglBegin (GL_QUADS);
3009 	R_RenderPic(x, y, w, h);
3010 	qglEnd ();
3011 
3012 	GLSTATE_ENABLE_ALPHATEST
3013 	GLSTATE_DISABLE_BLEND
3014 	GL_TexEnv( GL_REPLACE );
3015 	GL_BlendFunction(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
3016 }
R_RenderGlares(refdef_t * fd)3017 void R_RenderGlares (refdef_t *fd)
3018 {
3019 	int x, y, w, h;
3020 
3021 	if (fd->rdflags & RDF_NOWORLDMODEL)
3022 		return;
3023 	if (!rs_glares->value)
3024 		return;
3025 
3026 	w = fd->width;
3027 	h = fd->width;
3028 	x = 0;
3029 	y = (fd->width-fd->height)*-0.5;
3030 
3031 	GL_Bind (r_lblendimage->texnum);
3032 	GL_BlendFunction(GL_ONE,GL_ONE);
3033 
3034 	GLSTATE_DISABLE_ALPHATEST
3035 	GLSTATE_ENABLE_BLEND
3036 	GL_TexEnv( GL_MODULATE );
3037 	qglColor4f(1,1,1,1);
3038 
3039 	qglBegin (GL_QUADS);
3040 	R_RenderPic(x, y, w, h);
3041 	qglEnd ();
3042 
3043 	GLSTATE_ENABLE_ALPHATEST
3044 	GLSTATE_DISABLE_BLEND
3045 	GL_TexEnv( GL_REPLACE );
3046 	GL_BlendFunction(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
3047 }
3048 
R_SetGL2D(void)3049 void	R_SetGL2D (void)
3050 {
3051 	// set 2D virtual screen size
3052 	qglViewport (0,0, vid.width, vid.height);
3053 	qglMatrixMode(GL_PROJECTION);
3054     qglLoadIdentity ();
3055 	qglOrtho  (0, vid.width, vid.height, 0, -99999, 99999);
3056 	qglMatrixMode(GL_MODELVIEW);
3057     qglLoadIdentity ();
3058 	qglDisable (GL_DEPTH_TEST);
3059 	qglDisable (GL_CULL_FACE);
3060 	GLSTATE_DISABLE_BLEND
3061 	GLSTATE_ENABLE_ALPHATEST
3062 	GLSTATE_DISABLE_TEXGEN
3063 	qglColor4f (1,1,1,1);
3064 	GL_BlendFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
3065 }
3066 
GL_DrawColoredStereoLinePair(float r,float g,float b,float y)3067 static void GL_DrawColoredStereoLinePair( float r, float g, float b, float y )
3068 {
3069 	qglColor3f( r, g, b );
3070 	qglVertex2f( 0, y );
3071 	qglVertex2f( vid.width, y );
3072 	qglColor3f( 0, 0, 0 );
3073 	qglVertex2f( 0, y + 1 );
3074 	qglVertex2f( vid.width, y + 1 );
3075 }
3076 
GL_DrawStereoPattern(void)3077 static void GL_DrawStereoPattern( void )
3078 {
3079 	int i;
3080 
3081 	if ( !( gl_config.renderer & GL_RENDERER_INTERGRAPH ) )
3082 		return;
3083 
3084 	if ( !gl_state.stereo_enabled )
3085 		return;
3086 
3087 	R_SetGL2D();
3088 
3089 	qglDrawBuffer( GL_BACK_LEFT );
3090 
3091 	for ( i = 0; i < 20; i++ )
3092 	{
3093 		qglBegin( GL_LINES );
3094 			GL_DrawColoredStereoLinePair( 1, 0, 0, 0 );
3095 			GL_DrawColoredStereoLinePair( 1, 0, 0, 2 );
3096 			GL_DrawColoredStereoLinePair( 1, 0, 0, 4 );
3097 			GL_DrawColoredStereoLinePair( 1, 0, 0, 6 );
3098 			GL_DrawColoredStereoLinePair( 0, 1, 0, 8 );
3099 			GL_DrawColoredStereoLinePair( 1, 1, 0, 10);
3100 			GL_DrawColoredStereoLinePair( 1, 1, 0, 12);
3101 			GL_DrawColoredStereoLinePair( 0, 1, 0, 14);
3102 		qglEnd();
3103 
3104 		GLimp_EndFrame();
3105 	}
3106 }
3107 
3108 
3109 /*
3110 ====================
3111 R_SetLightLevel
3112 
3113 ====================
3114 */
R_SetLightLevel(void)3115 void R_SetLightLevel (void)
3116 {
3117 	vec3_t		shadelight;
3118 
3119 	if (r_newrefdef.rdflags & RDF_NOWORLDMODEL)
3120 		return;
3121 
3122 	// save off light value for server to look at (BIG HACK!)
3123 
3124 	R_LightPoint (r_newrefdef.vieworg, shadelight);
3125 
3126 	// pick the greatest component, which should be the same
3127 	// as the mono value returned by software
3128 	if (shadelight[0] > shadelight[1])
3129 	{
3130 		if (shadelight[0] > shadelight[2])
3131 			r_lightlevel->value = 150*shadelight[0];
3132 		else
3133 			r_lightlevel->value = 150*shadelight[2];
3134 	}
3135 	else
3136 	{
3137 		if (shadelight[1] > shadelight[2])
3138 			r_lightlevel->value = 150*shadelight[1];
3139 		else
3140 			r_lightlevel->value = 150*shadelight[2];
3141 	}
3142 
3143 }
3144 
3145 /*
3146 @@@@@@@@@@@@@@@@@@@@@
3147 R_RenderFrame
3148 
3149 @@@@@@@@@@@@@@@@@@@@@
3150 */
R_RenderFrame(refdef_t * fd)3151 void R_RenderFrame (refdef_t *fd)
3152 {
3153 	R_PreRenderDynamic( fd );
3154 
3155 	R_RenderView( fd );
3156 	R_SetLightLevel ();
3157 	R_SetGL2D ();
3158 
3159 	R_RenderGlares(fd);
3160 	R_RenderMotionBlur(fd);
3161 }
3162 
3163 
R_Register(void)3164 void R_Register( void )
3165 {
3166 	con_font = ri.Cvar_Get ("con_font", "default", CVAR_ARCHIVE);
3167 	con_font_size = ri.Cvar_Get ("con_font_size", "8", CVAR_ARCHIVE);
3168 
3169 	r_dlights_normal = ri.Cvar_Get("r_dlights_normal", "1", CVAR_ARCHIVE);
3170 
3171 	skydistance = ri.Cvar_Get("r_skydistance", "10000", CVAR_ARCHIVE); // DMP - skybox size change
3172 	gl_transrendersort = ri.Cvar_Get ("gl_transrendersort", "1", CVAR_ARCHIVE );
3173 	gl_particle_lighting = ri.Cvar_Get ("gl_particle_lighting", "0.75", CVAR_ARCHIVE );
3174 	gl_particle_min = ri.Cvar_Get ("gl_particle_min", "0", CVAR_ARCHIVE );
3175 	gl_particle_max = ri.Cvar_Get ("gl_particle_max", "0", CVAR_ARCHIVE );
3176 	gl_surftrans_light = ri.Cvar_Get ("gl_surftrans_light", "1", CVAR_ARCHIVE );
3177 
3178 	gl_stencil = ri.Cvar_Get ("gl_stencil", "1", CVAR_ARCHIVE );
3179 
3180 	gl_screenshot_quality = ri.Cvar_Get ("gl_screenshot_quality", "85", CVAR_ARCHIVE );
3181 
3182 	r_lefthand = ri.Cvar_Get( "hand", "0", CVAR_USERINFO | CVAR_ARCHIVE );
3183 	r_norefresh = ri.Cvar_Get ("r_norefresh", "0", 0);
3184 	r_fullbright = ri.Cvar_Get ("r_fullbright", "0", 0);
3185 	r_drawentities = ri.Cvar_Get ("r_drawentities", "1", 0);
3186 	r_drawworld = ri.Cvar_Get ("r_drawworld", "1", 0);
3187 	r_novis = ri.Cvar_Get ("r_novis", "0", 0);
3188 	r_nocull = ri.Cvar_Get ("r_nocull", "0", 0);
3189 	r_lerpmodels = ri.Cvar_Get ("r_lerpmodels", "1", 0);
3190 	r_speeds = ri.Cvar_Get ("r_speeds", "0", 0);
3191 
3192 	r_lightlevel = ri.Cvar_Get ("r_lightlevel", "0", 0);
3193 
3194 	r_shaders = ri.Cvar_Get ("r_shaders", "1", CVAR_ARCHIVE);
3195 
3196 	rs_dynamic_time = ri.Cvar_Get("rs_dynamic_time", "2", CVAR_ARCHIVE);
3197 	rs_dynamic_size = ri.Cvar_Get("rs_dynamic_size", "64", CVAR_ARCHIVE);
3198 	rs_dynamic_particles = ri.Cvar_Get("rs_dynamic_particles", "1", CVAR_ARCHIVE);
3199 	rs_dynamic_entities = ri.Cvar_Get("rs_dynamic_entities", "1", CVAR_ARCHIVE);
3200 
3201 	gl_motionblur = ri.Cvar_Get("gl_motionblur", "1", CVAR_ARCHIVE);
3202 	gl_motionblur_size  = ri.Cvar_Get("gl_motionblur_size", "128", CVAR_ARCHIVE);
3203 
3204 	rs_detail = ri.Cvar_Get("rs_detail", "1", CVAR_ARCHIVE);
3205 
3206 	rs_glares = ri.Cvar_Get("rs_glares", "0", CVAR_ARCHIVE);
3207 	rs_glares_sky = ri.Cvar_Get("rs_glares_sky", "0", CVAR_ARCHIVE);
3208 	rs_glares_size = ri.Cvar_Get("rs_glares_size", "128", CVAR_ARCHIVE);
3209 	rs_glares_shell = ri.Cvar_Get("rs_glares_shell", "1", CVAR_ARCHIVE);
3210 	rs_glares_particles = ri.Cvar_Get("rs_glares_particles", "1", CVAR_ARCHIVE);
3211 
3212 	r_model_lightlerp = ri.Cvar_Get( "r_model_lightlerp", "1", CVAR_ARCHIVE );
3213 	r_model_dlights = ri.Cvar_Get( "r_model_dlights", "3", CVAR_ARCHIVE );
3214 
3215 	gl_nosubimage = ri.Cvar_Get( "gl_nosubimage", "0", 0 );
3216 	gl_allow_software = ri.Cvar_Get( "gl_allow_software", "0", 0 );
3217 
3218 // Vic - begin
3219 	r_overbrightbits = ri.Cvar_Get( "r_overbrightbits", "2", CVAR_ARCHIVE );
3220 	gl_ext_mtexcombine = ri.Cvar_Get( "gl_ext_mtexcombine", "1", CVAR_ARCHIVE );
3221 // Vic - end
3222 	gl_ext_texture_compression = ri.Cvar_Get( "gl_ext_texture_compression", "0", CVAR_ARCHIVE ); // Heffo - ARB Texture Compression
3223 
3224 	gl_modulate = ri.Cvar_Get ("gl_modulate", "1", CVAR_ARCHIVE );
3225 	gl_log = ri.Cvar_Get( "gl_log", "0", 0 );
3226 	gl_bitdepth = ri.Cvar_Get( "gl_bitdepth", "0", 0 );
3227 	gl_mode = ri.Cvar_Get( "gl_mode", "3", CVAR_ARCHIVE );
3228 	gl_lightmap = ri.Cvar_Get ("gl_lightmap", "0", 0);
3229 	gl_shadows = ri.Cvar_Get ("gl_shadows", "0", CVAR_ARCHIVE );
3230 	gl_dynamic = ri.Cvar_Get ("gl_dynamic", "1", 0);
3231 	gl_nobind = ri.Cvar_Get ("gl_nobind", "0", 0);
3232 	gl_round_down = ri.Cvar_Get ("gl_round_down", "1", 0);
3233 	gl_picmip = ri.Cvar_Get ("gl_picmip", "0", 0);
3234 	gl_skymip = ri.Cvar_Get ("gl_skymip", "0", 0);
3235 	gl_showtris = ri.Cvar_Get ("gl_showtris", "0", 0);
3236 	gl_ztrick = ri.Cvar_Get ("gl_ztrick", "0", 0);
3237 	gl_finish = ri.Cvar_Get ("gl_finish", "0", CVAR_ARCHIVE);
3238 	gl_clear = ri.Cvar_Get ("gl_clear", "0", 0);
3239 	gl_cull = ri.Cvar_Get ("gl_cull", "1", 0);
3240 	gl_polyblend = ri.Cvar_Get ("gl_polyblend", "1", 0);
3241 	gl_flashblend = ri.Cvar_Get ("gl_flashblend", "0", 0);
3242 	gl_playermip = ri.Cvar_Get ("gl_playermip", "0", 0);
3243 	gl_monolightmap = ri.Cvar_Get( "gl_monolightmap", "0", 0 );
3244 	gl_driver = ri.Cvar_Get( "gl_driver", "libGL.so", CVAR_ARCHIVE );
3245 	gl_texturemode = ri.Cvar_Get( "gl_texturemode", "GL_LINEAR_MIPMAP_NEAREST", CVAR_ARCHIVE );
3246 	gl_anisotropic = ri.Cvar_Get( "gl_anisotropic", "0", CVAR_ARCHIVE );
3247 	gl_texturealphamode = ri.Cvar_Get( "gl_texturealphamode", "default", CVAR_ARCHIVE );
3248 	gl_texturesolidmode = ri.Cvar_Get( "gl_texturesolidmode", "default", CVAR_ARCHIVE );
3249 	gl_lockpvs = ri.Cvar_Get( "gl_lockpvs", "0", 0 );
3250 
3251 
3252 	gl_vertex_arrays = ri.Cvar_Get( "gl_vertex_arrays", "0", CVAR_ARCHIVE );
3253 
3254 	r_celshading = ri.Cvar_Get( "r_celshading", "0", CVAR_ARCHIVE );
3255 	r_celshading_width = ri.Cvar_Get( "r_celshading_width", "4", CVAR_ARCHIVE );
3256 
3257 	cl_3dcam = ri.Cvar_Get ("cl_3dcam", "0", CVAR_ARCHIVE);
3258 	cl_3dcam_angle = ri.Cvar_Get ("cl_3dcam_angle", "0", CVAR_ARCHIVE);
3259 	cl_3dcam_dist = ri.Cvar_Get ("cl_3dcam_dist", "50", CVAR_ARCHIVE);
3260 	cl_3dcam_alpha = ri.Cvar_Get ("cl_3dcam_alpha", "1", CVAR_ARCHIVE);
3261 	cl_3dcam_chase = ri.Cvar_Get ("cl_3dcam_chase", "1", CVAR_ARCHIVE);
3262 	cl_3dcam_adjust = ri.Cvar_Get ("cl_3dcam_adjust", "1", CVAR_ARCHIVE);
3263 
3264 	gl_ext_swapinterval = ri.Cvar_Get( "gl_ext_swapinterval", "1", CVAR_ARCHIVE );
3265 	gl_ext_multitexture = ri.Cvar_Get( "gl_ext_multitexture", "1", CVAR_ARCHIVE );
3266 	gl_ext_pointparameters = ri.Cvar_Get( "gl_ext_pointparameters", "1", CVAR_ARCHIVE );
3267 	gl_ext_compiled_vertex_array = ri.Cvar_Get( "gl_ext_compiled_vertex_array", "1", CVAR_ARCHIVE );
3268 
3269 	gl_drawbuffer = ri.Cvar_Get( "gl_drawbuffer", "GL_BACK", 0 );
3270 	gl_swapinterval = ri.Cvar_Get( "gl_swapinterval", "0", CVAR_ARCHIVE );
3271 
3272 	gl_saturatelighting = ri.Cvar_Get( "gl_saturatelighting", "0", 0 );
3273 
3274 	gl_3dlabs_broken = ri.Cvar_Get( "gl_3dlabs_broken", "1", CVAR_ARCHIVE );
3275 
3276 	vid_fullscreen = ri.Cvar_Get( "vid_fullscreen", "0", CVAR_ARCHIVE );
3277 	vid_gamma = ri.Cvar_Get( "vid_gamma", "1.0", CVAR_ARCHIVE );
3278 	vid_ref = ri.Cvar_Get( "vid_ref", "glx", CVAR_ARCHIVE );
3279 
3280 	ri.Cmd_AddCommand( "imagelist", GL_ImageList_f );
3281 	ri.Cmd_AddCommand( "screenshot", GL_ScreenShot_f );
3282 	ri.Cmd_AddCommand( "modellist", Mod_Modellist_f );
3283 	ri.Cmd_AddCommand( "gl_strings", GL_Strings_f );
3284 }
3285 
3286 /*
3287 ==================
3288 R_SetMode
3289 ==================
3290 */
R_SetMode(void)3291 qboolean R_SetMode (void)
3292 {
3293 	rserr_t err;
3294 	qboolean fullscreen;
3295 
3296 	if ( vid_fullscreen->modified && !gl_config.allow_cds )
3297 	{
3298 		ri.Con_Printf( PRINT_ALL, "R_SetMode() - CDS not allowed with this driver\n" );
3299 		ri.Cvar_SetValue( "vid_fullscreen", !vid_fullscreen->value );
3300 		vid_fullscreen->modified = false;
3301 	}
3302 
3303 	fullscreen = vid_fullscreen->value;
3304 
3305 	skydistance->modified = true; // DMP skybox size change
3306 	vid_fullscreen->modified = false;
3307 	gl_mode->modified = false;
3308 
3309 	if ( ( err = GLimp_SetMode( &vid.width, &vid.height, gl_mode->value, fullscreen ) ) == rserr_ok )
3310 	{
3311 		gl_state.prev_mode = gl_mode->value;
3312 	}
3313 	else
3314 	{
3315 		if ( err == rserr_invalid_fullscreen )
3316 		{
3317 			ri.Cvar_SetValue( "vid_fullscreen", 0);
3318 			vid_fullscreen->modified = false;
3319 			ri.Con_Printf( PRINT_ALL, "rfx_gl::R_SetMode() - fullscreen unavailable in this mode\n" );
3320 			if ( ( err = GLimp_SetMode( &vid.width, &vid.height, gl_mode->value, false ) ) == rserr_ok )
3321 				return true;
3322 		}
3323 		else if ( err == rserr_invalid_mode )
3324 		{
3325 			ri.Cvar_SetValue( "gl_mode", gl_state.prev_mode );
3326 			gl_mode->modified = false;
3327 			ri.Con_Printf( PRINT_ALL, "rfx_gl::R_SetMode() - invalid mode\n" );
3328 		}
3329 
3330 		// try setting it back to something safe
3331 		if ( ( err = GLimp_SetMode( &vid.width, &vid.height, gl_state.prev_mode, false ) ) != rserr_ok )
3332 		{
3333 			ri.Con_Printf( PRINT_ALL, "rfx_gl::R_SetMode() - could not revert to safe mode\n" );
3334 			return false;
3335 		}
3336 	}
3337 	return true;
3338 }
3339 
3340 /*
3341 ===============
3342 R_Init
3343 ===============
3344 */
R_Init(void * hinstance,void * hWnd)3345 int R_Init( void *hinstance, void *hWnd )
3346 {
3347 	char renderer_buffer[1000];
3348 	char vendor_buffer[1000];
3349 	int		err;
3350 	int		j;
3351 	extern float r_turbsin[256];
3352 
3353 	for ( j = 0; j < 256; j++ )
3354 	{
3355 		r_turbsin[j] *= 0.5;
3356 	}
3357 
3358 	ri.Con_Printf (PRINT_ALL, "rfx_gl version: "REF_VERSION"\n");
3359 
3360 	Draw_GetPalette ();
3361 
3362 	R_Register();
3363 
3364 	VLight_Init();
3365 
3366 	// initialize our QGL dynamic bindings
3367 	if ( !QGL_Init( gl_driver->string ) )
3368 	{
3369 		QGL_Shutdown();
3370         ri.Con_Printf (PRINT_ALL, "rfx_gl::R_Init() - could not load \"%s\"\n", gl_driver->string );
3371 		return -1;
3372 	}
3373 
3374 	// initialize OS-specific parts of OpenGL
3375 	if ( !GLimp_Init( hinstance, hWnd ) )
3376 	{
3377 		QGL_Shutdown();
3378 		return -1;
3379 	}
3380 
3381 	// set our "safe" modes
3382 	gl_state.prev_mode = 3;
3383 
3384 	// create the window and set up the context
3385 	if ( !R_SetMode () )
3386 	{
3387 		QGL_Shutdown();
3388         ri.Con_Printf (PRINT_ALL, "rfx_gl::R_Init() - could not R_SetMode()\n" );
3389 		return -1;
3390 	}
3391 
3392 	ri.Vid_MenuInit();
3393 
3394 	/*
3395 	** get our various GL strings
3396 	*/
3397 	gl_config.vendor_string = qglGetString (GL_VENDOR);
3398 	ri.Con_Printf (PRINT_ALL, "GL_VENDOR: %s\n", gl_config.vendor_string );
3399 	gl_config.renderer_string = qglGetString (GL_RENDERER);
3400 	ri.Con_Printf (PRINT_ALL, "GL_RENDERER: %s\n", gl_config.renderer_string );
3401 	gl_config.version_string = qglGetString (GL_VERSION);
3402 	ri.Con_Printf (PRINT_ALL, "GL_VERSION: %s\n", gl_config.version_string );
3403 	gl_config.extensions_string = qglGetString (GL_EXTENSIONS);
3404 	ri.Con_Printf (PRINT_ALL, "GL_EXTENSIONS: %s\n", gl_config.extensions_string );
3405 
3406 	strcpy( renderer_buffer, gl_config.renderer_string );
3407 	strlwr( renderer_buffer );
3408 
3409 	strcpy( vendor_buffer, gl_config.vendor_string );
3410 	strlwr( vendor_buffer );
3411 
3412 	if ( strstr( renderer_buffer, "voodoo" ) )
3413 	{
3414 		if ( !strstr( renderer_buffer, "rush" ) )
3415 			gl_config.renderer = GL_RENDERER_VOODOO;
3416 		else
3417 			gl_config.renderer = GL_RENDERER_VOODOO_RUSH;
3418 	}
3419 	else if ( strstr( vendor_buffer, "sgi" ) )
3420 		gl_config.renderer = GL_RENDERER_SGI;
3421 	else if ( strstr( renderer_buffer, "permedia" ) )
3422 		gl_config.renderer = GL_RENDERER_PERMEDIA2;
3423 	else if ( strstr( renderer_buffer, "glint" ) )
3424 		gl_config.renderer = GL_RENDERER_GLINT_MX;
3425 	else if ( strstr( renderer_buffer, "glzicd" ) )
3426 		gl_config.renderer = GL_RENDERER_REALIZM;
3427 	else if ( strstr( renderer_buffer, "gdi" ) )
3428 		gl_config.renderer = GL_RENDERER_MCD;
3429 	else if ( strstr( renderer_buffer, "pcx2" ) )
3430 		gl_config.renderer = GL_RENDERER_PCX2;
3431 	else if ( strstr( renderer_buffer, "verite" ) )
3432 		gl_config.renderer = GL_RENDERER_RENDITION;
3433 	else
3434 		gl_config.renderer = GL_RENDERER_OTHER;
3435 
3436 	if ( toupper( gl_monolightmap->string[1] ) != 'F' )
3437 	{
3438 		if ( gl_config.renderer == GL_RENDERER_PERMEDIA2 )
3439 		{
3440 			ri.Cvar_Set( "gl_monolightmap", "A" );
3441 			ri.Con_Printf( PRINT_ALL, "...using gl_monolightmap 'a'\n" );
3442 		}
3443 		else if ( gl_config.renderer & GL_RENDERER_POWERVR )
3444 		{
3445 			ri.Cvar_Set( "gl_monolightmap", "0" );
3446 		}
3447 		else
3448 		{
3449 			ri.Cvar_Set( "gl_monolightmap", "0" );
3450 		}
3451 	}
3452 
3453 	// power vr can't have anything stay in the framebuffer, so
3454 	// the screen needs to redraw the tiled background every frame
3455 	if ( gl_config.renderer & GL_RENDERER_POWERVR )
3456 	{
3457 		ri.Cvar_Set( "scr_drawall", "1" );
3458 	}
3459 	else
3460 	{
3461 		ri.Cvar_Set( "scr_drawall", "0" );
3462 	}
3463 
3464 #ifdef __unix__
3465 	ri.Cvar_SetValue( "gl_finish", 1 );
3466 #endif
3467 
3468 	// MCD has buffering issues
3469 	if ( gl_config.renderer == GL_RENDERER_MCD )
3470 	{
3471 		ri.Cvar_SetValue( "gl_finish", 1 );
3472 	}
3473 
3474 	if ( gl_config.renderer & GL_RENDERER_3DLABS )
3475 	{
3476 		if ( gl_3dlabs_broken->value )
3477 			gl_config.allow_cds = false;
3478 		else
3479 			gl_config.allow_cds = true;
3480 	}
3481 	else
3482 	{
3483 		gl_config.allow_cds = true;
3484 	}
3485 
3486 	if ( gl_config.allow_cds )
3487 		ri.Con_Printf( PRINT_ALL, "...allowing CDS\n" );
3488 	else
3489 		ri.Con_Printf( PRINT_ALL, "...disabling CDS\n" );
3490 
3491 	/*
3492 	** grab extensions
3493 	*/
3494 	if ( strstr( gl_config.extensions_string, "GL_EXT_compiled_vertex_array" ) ||
3495 		 strstr( gl_config.extensions_string, "GL_SGI_compiled_vertex_array" ) )
3496 	{
3497 		ri.Con_Printf( PRINT_ALL, "...enabling GL_EXT_compiled_vertex_array\n" );
3498 		qglLockArraysEXT = ( void * ) qwglGetProcAddress( "glLockArraysEXT" );
3499 		qglUnlockArraysEXT = ( void * ) qwglGetProcAddress( "glUnlockArraysEXT" );
3500 	}
3501 	else
3502 	{
3503 		ri.Con_Printf( PRINT_ALL, "...GL_EXT_compiled_vertex_array not found\n" );
3504 	}
3505 
3506 #ifdef _WIN32
3507 	if ( strstr( gl_config.extensions_string, "WGL_EXT_swap_control" ) )
3508 	{
3509 		qwglSwapIntervalEXT = ( BOOL (WINAPI *)(int)) qwglGetProcAddress( "wglSwapIntervalEXT" );
3510 		ri.Con_Printf( PRINT_ALL, "...enabling WGL_EXT_swap_control\n" );
3511 	}
3512 	else
3513 	{
3514 		ri.Con_Printf( PRINT_ALL, "...WGL_EXT_swap_control not found\n" );
3515 	}
3516 #endif
3517 
3518 	if ( strstr( gl_config.extensions_string, "GL_EXT_point_parameters" ) )
3519 	{
3520 		if ( gl_ext_pointparameters->value )
3521 		{
3522 			qglPointParameterfEXT = ( void (APIENTRY *)( GLenum, GLfloat ) ) qwglGetProcAddress( "glPointParameterfEXT" );
3523 			qglPointParameterfvEXT = ( void (APIENTRY *)( GLenum, const GLfloat * ) ) qwglGetProcAddress( "glPointParameterfvEXT" );
3524 			ri.Con_Printf( PRINT_ALL, "...using GL_EXT_point_parameters\n" );
3525 		}
3526 		else
3527 		{
3528 			ri.Con_Printf( PRINT_ALL, "...ignoring GL_EXT_point_parameters\n" );
3529 		}
3530 	}
3531 	else
3532 	{
3533 		ri.Con_Printf( PRINT_ALL, "...GL_EXT_point_parameters not found\n" );
3534 	}
3535 
3536 	if ( strstr( gl_config.extensions_string, "GL_ARB_multitexture" ) )
3537 	{
3538 		if ( gl_ext_multitexture->value )
3539 		{
3540 			ri.Con_Printf( PRINT_ALL, "...using GL_ARB_multitexture\n" );
3541 			qglMTexCoord2fSGIS = ( void * ) qwglGetProcAddress( "glMultiTexCoord2fARB" );
3542 			qglActiveTextureARB = ( void * ) qwglGetProcAddress( "glActiveTextureARB" );
3543 			qglClientActiveTextureARB = ( void * ) qwglGetProcAddress( "glClientActiveTextureARB" );
3544 			GL_TEXTURE0 = GL_TEXTURE0_ARB;
3545 			GL_TEXTURE1 = GL_TEXTURE1_ARB;
3546 		}
3547 		else
3548 		{
3549 			ri.Con_Printf( PRINT_ALL, "...ignoring GL_ARB_multitexture\n" );
3550 		}
3551 	}
3552 	else
3553 	{
3554 		ri.Con_Printf( PRINT_ALL, "...GL_ARB_multitexture not found\n" );
3555 	}
3556 
3557 	if ( strstr( gl_config.extensions_string, "GL_SGIS_multitexture" ) )
3558 	{
3559 		if ( qglActiveTextureARB )
3560 		{
3561 			ri.Con_Printf( PRINT_ALL, "...GL_SGIS_multitexture deprecated in favor of ARB_multitexture\n" );
3562 		}
3563 		else if ( gl_ext_multitexture->value )
3564 		{
3565 			ri.Con_Printf( PRINT_ALL, "...using GL_SGIS_multitexture\n" );
3566 			qglMTexCoord2fSGIS = ( void * ) qwglGetProcAddress( "glMTexCoord2fSGIS" );
3567 			qglSelectTextureSGIS = ( void * ) qwglGetProcAddress( "glSelectTextureSGIS" );
3568 			GL_TEXTURE0 = GL_TEXTURE0_SGIS;
3569 			GL_TEXTURE1 = GL_TEXTURE1_SGIS;
3570 		}
3571 		else
3572 		{
3573 			ri.Con_Printf( PRINT_ALL, "...ignoring GL_SGIS_multitexture\n" );
3574 		}
3575 	}
3576 	else
3577 	{
3578 		ri.Con_Printf( PRINT_ALL, "...GL_SGIS_multitexture not found\n" );
3579 	}
3580 
3581 // Vic - begin
3582 	gl_config.mtexcombine = false;
3583 
3584 	if ( strstr( gl_config.extensions_string, "GL_ARB_texture_env_combine" ) )
3585 	{
3586 		if ( gl_ext_mtexcombine->value )
3587 		{
3588 			Com_Printf( "...using GL_ARB_texture_env_combine\n" );
3589 			gl_config.mtexcombine = true;
3590 		}
3591 		else
3592 		{
3593 			Com_Printf( "...ignoring GL_ARB_texture_env_combine\n" );
3594 		}
3595 	}
3596 	else
3597 	{
3598 		Com_Printf( "...GL_ARB_texture_env_combine not found\n" );
3599 	}
3600 
3601 	if ( !gl_config.mtexcombine )
3602 	{
3603 		if ( strstr( gl_config.extensions_string, "GL_EXT_texture_env_combine" ) )
3604 		{
3605 			if ( gl_ext_mtexcombine->value )
3606 			{
3607 				Com_Printf( "...using GL_EXT_texture_env_combine\n" );
3608 				gl_config.mtexcombine = true;
3609 			}
3610 			else
3611 			{
3612 				Com_Printf( "...ignoring GL_EXT_texture_env_combine\n" );
3613 			}
3614 		}
3615 		else
3616 		{
3617 			Com_Printf( "...GL_EXT_texture_env_combine not found\n" );
3618 		}
3619 	}
3620 // Vic - end
3621 
3622 	// Texture Shader support - MrG
3623 	if ( strstr( gl_config.extensions_string, "GL_NV_texture_shader" ) )
3624 	{
3625 		ri.Con_Printf(PRINT_ALL, "...using GL_NV_texture_shader\n");
3626 		gl_state.texshaders=true;
3627 	}
3628 	else
3629 	{
3630 		ri.Con_Printf(PRINT_ALL, "...GL_NV_texture_shader not found\n");
3631 		gl_state.texshaders=false;
3632 	}
3633 
3634 	if ( strstr( gl_config.extensions_string, "GL_SGIS_generate_mipmap" ) )
3635 	{
3636 		ri.Con_Printf(PRINT_ALL, "...using GL_SGIS_generate_mipmap\n");
3637 		gl_state.sgis_mipmap=true;
3638 	} else {
3639 		ri.Con_Printf(PRINT_ALL, "...GL_SGIS_generate_mipmap not found\n");
3640 		gl_state.sgis_mipmap=false;
3641 	}
3642 
3643 	// Heffo - ARB Texture Compression
3644 	if ( strstr( gl_config.extensions_string, "GL_ARB_texture_compression" ) )
3645 	{
3646 		if(!gl_ext_texture_compression->value)
3647 		{
3648 			ri.Con_Printf(PRINT_ALL, "...ignoring GL_ARB_texture_compression\n");
3649 			gl_state.texture_compression = false;
3650 		}
3651 		else
3652 		{
3653 			ri.Con_Printf(PRINT_ALL, "...using GL_ARB_texture_compression\n");
3654 			gl_state.texture_compression = true;
3655 		}
3656 	}
3657 	else
3658 	{
3659 		ri.Con_Printf(PRINT_ALL, "...GL_ARB_texture_compression not found\n");
3660 		gl_state.texture_compression = false;
3661 		ri.Cvar_Set("gl_ext_texture_compression", "0");
3662 	}
3663 
3664 	GL_SetDefaultState();
3665 
3666 	/*
3667 	** draw our stereo patterns
3668 	*/
3669 #if 0 // commented out until H3D pays us the money they owe us
3670 	GL_DrawStereoPattern();
3671 #endif
3672 
3673 	gl_swapinterval->modified = true;
3674 
3675 	GL_InitImages ();
3676 	Mod_Init ();
3677 	R_InitParticleTexture ();
3678 	Draw_InitLocal ();
3679 
3680 	if(gl_texturemode)
3681 		GL_TextureMode( gl_texturemode->string );
3682 
3683 	err = qglGetError();
3684 	if ( err != GL_NO_ERROR )
3685 		ri.Con_Printf (PRINT_ALL, "glGetError() = 0x%x\n", err);
3686 }
3687 
3688 /*
3689 ===============
3690 R_Shutdown
3691 ===============
3692 */
R_Shutdown(void)3693 void R_Shutdown (void)
3694 {
3695 	ri.Cmd_RemoveCommand ("modellist");
3696 	ri.Cmd_RemoveCommand ("screenshot");
3697 	ri.Cmd_RemoveCommand ("imagelist");
3698 	ri.Cmd_RemoveCommand ("gl_strings");
3699 
3700 	Mod_FreeAll ();
3701 
3702 	GL_ShutdownImages ();
3703 
3704 	/*
3705 	** shut down OS specific OpenGL stuff like contexts, etc.
3706 	*/
3707 	GLimp_Shutdown();
3708 
3709 	/*
3710 	** shutdown our QGL subsystem
3711 	*/
3712 	QGL_Shutdown();
3713 }
3714 
3715 
3716 
3717 /*
3718 @@@@@@@@@@@@@@@@@@@@@
3719 R_BeginFrame
3720 @@@@@@@@@@@@@@@@@@@@@
3721 */
3722 
3723 #ifdef _WIN32
3724 void UpdateGammaRamp();
3725 #endif
3726 void RefreshFont (void);
R_BeginFrame(float camera_separation)3727 void R_BeginFrame( float camera_separation )
3728 {
3729 	gl_state.camera_separation = camera_separation;
3730 
3731 	if (con_font->modified)
3732 		RefreshFont ();
3733 
3734 	if (con_font_size->modified)
3735 	{
3736 		if (con_font_size->value<4)
3737 			ri.Cvar_Set( "con_font_size", "4" );
3738 		else if (con_font_size->value>32)
3739 			ri.Cvar_Set( "con_font_size", "32" );
3740 
3741 		con_font_size->modified = false;
3742 	}
3743 
3744 	if (r_overbrightbits->modified)
3745 	{
3746 		if (r_overbrightbits->value<1)
3747 			ri.Cvar_Set( "r_overbrightbits", "1" );
3748 		else if (r_overbrightbits->value>2 && r_overbrightbits->value!=4)
3749 			ri.Cvar_Set( "r_overbrightbits", "4" );
3750 
3751 		r_overbrightbits->modified = false;
3752 	}
3753 	if (gl_modulate->modified)
3754 	{
3755 		if (gl_modulate->value<0.5)
3756 			ri.Cvar_Set( "gl_modulate", "0.5");
3757 		else if (gl_modulate->value>3)
3758 			ri.Cvar_Set( "gl_modulate", "3" );
3759 
3760 		gl_modulate->modified = false;
3761 	}
3762 
3763 	/*
3764 	** change modes if necessary
3765 	*/
3766 	if ( gl_mode->modified || vid_fullscreen->modified )
3767 	{	// FIXME: only restart if CDS is required
3768 		cvar_t	*ref;
3769 
3770 		ref = ri.Cvar_Get ("vid_ref", "glx", 0);
3771 		ref->modified = true;
3772 	}
3773 
3774 	if ( gl_log->modified )
3775 	{
3776 		GLimp_EnableLogging( gl_log->value );
3777 		gl_log->modified = false;
3778 	}
3779 
3780 	if ( gl_log->value )
3781 	{
3782 		GLimp_LogNewFrame();
3783 	}
3784 
3785 	/*
3786 	** update 3Dfx gamma -- it is expected that a user will do a vid_restart
3787 	** after tweaking this value
3788 	*/
3789 	if ( vid_gamma->modified )
3790 	{
3791 		vid_gamma->modified = false;
3792 
3793 #ifdef _WIN32
3794 		if (gl_state.gammaramp)
3795 			UpdateGammaRamp();
3796 #else
3797 		if ( gl_state.hwgamma )
3798 			UpdateHardwareGamma();
3799 #endif
3800 		else if ( gl_config.renderer & ( GL_RENDERER_VOODOO ) )
3801 		{
3802 			char envbuffer[1024];
3803 			float g;
3804 
3805 			g = 2.00 * ( 0.8 - ( vid_gamma->value - 0.5 ) ) + 1.0F;
3806 			Com_sprintf( envbuffer, sizeof(envbuffer), "SSTV2_GAMMA=%f", g );
3807 			putenv( envbuffer );
3808 			Com_sprintf( envbuffer, sizeof(envbuffer), "SST_GAMMA=%f", g );
3809 			putenv( envbuffer );
3810 		}
3811 	}
3812 
3813 	if (gl_particle_lighting->modified)
3814 	{
3815 		gl_particle_lighting->modified = false;
3816 		if (gl_particle_lighting->value<0)
3817 			gl_particle_lighting->value=0;
3818 		if (gl_particle_lighting->value>1)
3819 			gl_particle_lighting->value=1;
3820 	}
3821 
3822 	GLimp_BeginFrame( camera_separation );
3823 
3824 	/*
3825 	** go into 2D mode
3826 	*/
3827 	qglViewport (0,0, vid.width, vid.height);
3828 	qglMatrixMode(GL_PROJECTION);
3829     qglLoadIdentity ();
3830 	qglOrtho  (0, vid.width, vid.height, 0, -99999, 99999);
3831 	qglMatrixMode(GL_MODELVIEW);
3832     qglLoadIdentity ();
3833 	qglDisable (GL_DEPTH_TEST);
3834 	qglDisable (GL_CULL_FACE);
3835 	GLSTATE_DISABLE_BLEND
3836 	GLSTATE_ENABLE_ALPHATEST
3837 	qglColor4f (1,1,1,1);
3838 
3839 	/*
3840 	** draw buffer stuff
3841 	*/
3842 	if ( gl_drawbuffer->modified )
3843 	{
3844 		gl_drawbuffer->modified = false;
3845 
3846 		if ( gl_state.camera_separation == 0 || !gl_state.stereo_enabled )
3847 		{
3848 			if ( Q_stricmp( gl_drawbuffer->string, "GL_FRONT" ) == 0 )
3849 				qglDrawBuffer( GL_FRONT );
3850 			else
3851 				qglDrawBuffer( GL_BACK );
3852 		}
3853 	}
3854 
3855 	/*
3856 	** texturemode stuff
3857 	*/
3858 	if ( gl_texturemode->modified )
3859 	{
3860 		GL_TextureMode( gl_texturemode->string );
3861 		gl_texturemode->modified = false;
3862 	}
3863 
3864 	if ( gl_texturealphamode->modified )
3865 	{
3866 		GL_TextureAlphaMode( gl_texturealphamode->string );
3867 		gl_texturealphamode->modified = false;
3868 	}
3869 
3870 	if ( gl_texturesolidmode->modified )
3871 	{
3872 		GL_TextureSolidMode( gl_texturesolidmode->string );
3873 		gl_texturesolidmode->modified = false;
3874 	}
3875 
3876 	/*
3877 	** swapinterval stuff
3878 	*/
3879 	GL_UpdateSwapInterval();
3880 
3881 	//
3882 	// clear screen if desired
3883 	//
3884 	R_Clear ();
3885 }
3886 
3887 /*
3888 =============
3889 R_SetPalette
3890 =============
3891 */
3892 unsigned r_rawpalette[256];
3893 
R_SetPalette(const unsigned char * palette)3894 void R_SetPalette ( const unsigned char *palette)
3895 {
3896 	int		i;
3897 
3898 	byte *rp = ( byte * ) r_rawpalette;
3899 
3900 	if ( palette )
3901 	{
3902 		for ( i = 0; i < 256; i++ )
3903 		{
3904 			rp[i*4+0] = palette[i*3+0];
3905 			rp[i*4+1] = palette[i*3+1];
3906 			rp[i*4+2] = palette[i*3+2];
3907 			rp[i*4+3] = 0xff;
3908 		}
3909 	}
3910 	else
3911 	{
3912 		for ( i = 0; i < 256; i++ )
3913 		{
3914 			rp[i*4+0] = d_8to24table[i] & 0xff;
3915 			rp[i*4+1] = ( d_8to24table[i] >> 8 ) & 0xff;
3916 			rp[i*4+2] = ( d_8to24table[i] >> 16 ) & 0xff;
3917 			rp[i*4+3] = 0xff;
3918 		}
3919 	}
3920 //	GL_SetTexturePalette( r_rawpalette );
3921 
3922 	qglClearColor (0,0,0,0);
3923 	qglClear (GL_COLOR_BUFFER_BIT);
3924 	qglClearColor (1,0, 0.5 , 0.5);
3925 
3926 }
3927 
3928 /*
3929 ** R_DrawBeam
3930 */
3931 void R_RenderBeam( vec3_t start, vec3_t end, float size, float red, float green, float blue, float alpha );
3932 
R_DrawBeam(entity_t * e)3933 void R_DrawBeam( entity_t *e )
3934 {
3935 
3936 	R_RenderBeam( e->origin, e->oldorigin, e->frame,
3937 		( d_8to24table[e->skinnum & 0xFF] ) & 0xFF,
3938 		( d_8to24table[e->skinnum & 0xFF] >> 8 ) & 0xFF,
3939 		( d_8to24table[e->skinnum & 0xFF] >> 16 ) & 0xFF,
3940 		e->alpha*254 );
3941 
3942 	//OLD BEAM RENDERING CODE ...
3943 	/*
3944 #define NUM_BEAM_SEGS 12
3945 
3946 	int	i;
3947 	float r, g, b;
3948 
3949 	vec3_t perpvec;
3950 	vec3_t direction, normalized_direction;
3951 	vec3_t	start_points[NUM_BEAM_SEGS], end_points[NUM_BEAM_SEGS];
3952 	vec3_t oldorigin, origin;
3953 
3954 	oldorigin[0] = e->oldorigin[0];
3955 	oldorigin[1] = e->oldorigin[1];
3956 	oldorigin[2] = e->oldorigin[2];
3957 
3958 	origin[0] = e->origin[0];
3959 	origin[1] = e->origin[1];
3960 	origin[2] = e->origin[2];
3961 
3962 	normalized_direction[0] = direction[0] = oldorigin[0] - origin[0];
3963 	normalized_direction[1] = direction[1] = oldorigin[1] - origin[1];
3964 	normalized_direction[2] = direction[2] = oldorigin[2] - origin[2];
3965 
3966 	if ( VectorNormalize( normalized_direction ) == 0 )
3967 		return;
3968 
3969 	PerpendicularVector( perpvec, normalized_direction );
3970 	VectorScale( perpvec, e->frame / 2, perpvec );
3971 
3972 	for ( i = 0; i < NUM_BEAM_SEGS; i++ )
3973 	{
3974 		RotatePointAroundVector( start_points[i], normalized_direction, perpvec, (360.0/NUM_BEAM_SEGS)*i );
3975 		VectorAdd( start_points[i], origin, start_points[i] );
3976 		VectorAdd( start_points[i], direction, end_points[i] );
3977 	}
3978 
3979 	qglDisable( GL_TEXTURE_2D );
3980 	GLSTATE_ENABLE_BLEND
3981 	qglDepthMask( GL_FALSE );
3982 
3983 	r = ( d_8to24table[e->skinnum & 0xFF] ) & 0xFF;
3984 	g = ( d_8to24table[e->skinnum & 0xFF] >> 8 ) & 0xFF;
3985 	b = ( d_8to24table[e->skinnum & 0xFF] >> 16 ) & 0xFF;
3986 
3987 	r *= DIV255;
3988 	g *= DIV255;
3989 	b *= DIV255;
3990 
3991 	qglColor4f( r, g, b, e->alpha );
3992 
3993 	qglBegin( GL_TRIANGLE_STRIP );
3994 	for ( i = 0; i < NUM_BEAM_SEGS; i++ )
3995 	{
3996 		qglVertex3fv( start_points[i] );
3997 		qglVertex3fv( end_points[i] );
3998 		qglVertex3fv( start_points[(i+1)%NUM_BEAM_SEGS] );
3999 		qglVertex3fv( end_points[(i+1)%NUM_BEAM_SEGS] );
4000 	}
4001 	qglEnd();
4002 
4003 	qglEnable( GL_TEXTURE_2D );
4004 	GLSTATE_DISABLE_BLEND
4005 	qglDepthMask( GL_TRUE );
4006 	*/
4007 }
4008 
4009 
R_RenderBeam(vec3_t start,vec3_t end,float size,float red,float green,float blue,float alpha)4010 void R_RenderBeam( vec3_t start, vec3_t end, float size, float red, float green, float blue, float alpha )
4011 {
4012 	particle_t beam;
4013 	vec3_t		up		= {vup[0]    * 0.75f, vup[1]    * 0.75f, vup[2]    * 0.75f};
4014 	vec3_t		right	= {vright[0] * 0.75f, vright[1] * 0.75f, vright[2] * 0.75f};
4015 
4016 	VectorAdd      (up, right, particle_coord[0]);
4017 	VectorSubtract (right, up, particle_coord[1]);
4018 	VectorNegate   (particle_coord[0], particle_coord[2]);
4019 	VectorNegate   (particle_coord[1], particle_coord[3]);
4020 
4021 	qglEnable (GL_TEXTURE_2D);
4022 	GL_TexEnv( GL_MODULATE );
4023 	qglDepthMask   (false);
4024 	GLSTATE_ENABLE_BLEND
4025 	GL_ShadeModel (GL_SMOOTH);
4026 	GLSTATE_DISABLE_ALPHATEST
4027 	ParticleOverbright = false;
4028 
4029 	beam.alpha = alpha*DIV255*2.5;
4030 	beam.blendfunc_src = GL_SRC_ALPHA;
4031 	beam.blendfunc_dst = GL_ONE;
4032 	beam.blue	= blue*255;
4033 	beam.red	= red*255;
4034 	beam.green	= green*255;
4035 	beam.decal = NULL;
4036 	beam.flags = PART_BEAM;
4037 	beam.image = 0;
4038 	VectorCopy(start, beam.angle);
4039 	VectorCopy(end, beam.origin);
4040 	beam.size = size*2;
4041 
4042 	renderParticle (&beam);
4043 
4044 	qglDepthRange (gldepthmin, gldepthmax);
4045 	GL_BlendFunction (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
4046 	GL_TexEnv( GL_MODULATE );
4047 	qglDepthMask (true);
4048 	GLSTATE_DISABLE_BLEND
4049 	qglColor4f   (1,1,1,1);
4050 }
4051 
4052 /*
4053 void R_RenderBeam( vec3_t start, vec3_t end, float size, float red, float green, float blue, float alpha )
4054 {
4055 	float	len;
4056 	vec3_t coord[4], ang_up, ang_right, vdelta;
4057 	particle_t beam;
4058 
4059 	GL_TexEnv( GL_MODULATE );
4060 
4061 	qglDepthMask   (false);
4062 	GL_BlendFunction   (GL_SRC_ALPHA, GL_ONE);
4063 	GLSTATE_ENABLE_BLEND
4064 	GL_ShadeModel (GL_SMOOTH);
4065 	GL_Bind(r_particlebeam->texnum);
4066 	qglColor4ub(red, green, blue, alpha);
4067 
4068 	VectorSubtract(start, end, ang_up);
4069 	len = VectorNormalize(ang_up);
4070 
4071 	VectorSubtract(r_newrefdef.vieworg, start, vdelta);
4072 	CrossProduct(ang_up, vdelta, ang_right);
4073 	if(!VectorCompare(ang_right, vec3_origin))
4074 		VectorNormalize(ang_right);
4075 
4076 	VectorScale (ang_right, size*3.0, ang_right);
4077 
4078 	VectorAdd(start, ang_right, coord[0]);
4079 	VectorAdd(end, ang_right, coord[1]);
4080 	VectorSubtract(end, ang_right, coord[2]);
4081 	VectorSubtract(start, ang_right, coord[3]);
4082 
4083 	qglPushMatrix();
4084 	{
4085 		qglBegin (GL_QUADS);
4086 		{
4087 			qglTexCoord2f (0, 1);
4088 			qglVertex3fv  (coord[0]);
4089 			qglTexCoord2f (0, 0);
4090 			qglVertex3fv  (coord[1]);
4091 			qglTexCoord2f (1, 0);
4092 			qglVertex3fv  (coord[2]);
4093 			qglTexCoord2f (1, 1);
4094 			qglVertex3fv  (coord[3]);
4095 		}
4096 		qglEnd ();
4097 	}
4098 	qglPopMatrix ();
4099 
4100 	GL_BlendFunction (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
4101 	GL_TexEnv( GL_MODULATE );
4102 	qglDepthMask (true);
4103 	GLSTATE_DISABLE_BLEND
4104 	qglColor4f   (1,1,1,1);
4105 }
4106 */
4107 //===================================================================
4108 
4109 
4110 void	R_BeginRegistration (char *map);
4111 struct model_s	*R_RegisterModel (char *name);
4112 struct image_s	*R_RegisterSkin (char *name);
4113 void R_SetSky (char *name, float rotate, vec3_t axis);
4114 void	R_EndRegistration (void);
4115 
4116 void	R_RenderFrame (refdef_t *fd);
4117 
4118 struct image_s	*Draw_FindPic (char *name);
4119 
4120 void	Draw_ScaledPic (int x, int y, float scale, char *pic);
4121 void	Draw_Pic (int x, int y, char *name);
4122 void 	Draw_Char (float x, float y, int num, int alpha);
4123 void 	Draw_ScaledChar (float x, float y, int num, float scale,
4124 	 int red, int green, int blue, int alpha, qboolean italic);
4125 void	Draw_TileClear (int x, int y, int w, int h, char *name);
4126 void	Draw_Fill (int x, int y, int w, int h, int c);
4127 void 	Draw_FadeBox (int x, int y, int w, int h, float r, float g, float b, float alpha);
4128 
4129 float	CharMapScale (void);
4130 void	SetParticlePicture (int num, char *name);
4131 int Mod_MarkFragments (const vec3_t origin,  vec3_t axis[3], float radius, int maxPoints, vec3_t *points, vec2_t *tcoords, int maxFragments, markFragment_t *fragments);
4132 
4133 /*
4134 @@@@@@@@@@@@@@@@@@@@@
4135 GetRefAPI
4136 
4137 @@@@@@@@@@@@@@@@@@@@@
4138 */
GetRefAPI(refimport_t rimp)4139 refexport_t GetRefAPI (refimport_t rimp )
4140 {
4141 	refexport_t	re;
4142 
4143 	ri = rimp;
4144 
4145 	re.api_version = API_VERSION;
4146 
4147 	re.BeginRegistration = R_BeginRegistration;
4148 	re.RegisterModel = R_RegisterModel;
4149 	re.RegisterSkin = R_RegisterSkin;
4150 	re.RegisterPic = Draw_FindPic;
4151 	re.SetSky = R_SetSky;
4152 	re.EndRegistration = R_EndRegistration;
4153 
4154 	re.RenderFrame = R_RenderFrame;
4155 
4156 	re.SetParticlePicture = SetParticlePicture;
4157 
4158 	re.DrawGetPicSize = Draw_GetPicSize;
4159 	re.DrawScaledPic = Draw_ScaledPic;
4160 	re.DrawPic = Draw_Pic;
4161 	re.DrawStretchPic = Draw_StretchPic;
4162 	re.DrawScaledChar = Draw_ScaledChar;
4163 	re.DrawChar = Draw_Char;
4164 	re.DrawTileClear = Draw_TileClear;
4165 	re.DrawFill = Draw_Fill;
4166 	re.DrawFadeBox= Draw_FadeBox;
4167 	re.CharMap_Scale = CharMapScale;
4168 
4169 	re.DrawStretchRaw = Draw_StretchRaw;
4170 
4171 	re.MarkFragments = Mod_MarkFragments;
4172 
4173 	re.Init = R_Init;
4174 	re.Shutdown = R_Shutdown;
4175 
4176 	re.CinematicSetPalette = R_SetPalette;
4177 	re.BeginFrame = R_BeginFrame;
4178 	re.EndFrame = GLimp_EndFrame;
4179 
4180 	re.AppActivate = GLimp_AppActivate;
4181 
4182 	Swap_Init ();
4183 
4184 	return re;
4185 }
4186 
4187 
4188 #ifndef REF_HARD_LINKED
4189 // this is only here so the functions in q_shared.c and q_shwin.c can link
Sys_Error(char * error,...)4190 void Sys_Error (char *error, ...)
4191 {
4192 	va_list		argptr;
4193 	char		text[1024];
4194 
4195 	va_start (argptr, error);
4196 	vsprintf (text, error, argptr);
4197 	va_end (argptr);
4198 
4199 	ri.Sys_Error (ERR_FATAL, "%s", text);
4200 }
4201 
Com_Printf(char * fmt,...)4202 void Com_Printf (char *fmt, ...)
4203 {
4204 	va_list		argptr;
4205 	char		text[1024];
4206 
4207 	va_start (argptr, fmt);
4208 	vsprintf (text, fmt, argptr);
4209 	va_end (argptr);
4210 
4211 	ri.Con_Printf (PRINT_ALL, "%s", text);
4212 }
4213 
4214 #endif
4215