1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3 Copyright (C) 2011 COR Entertainment, LLC.
4 
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 
14 See the GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 
20 */
21 // R_SURF.C: surface-related refresh code
22 
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 
27 #include <assert.h>
28 
29 #include "r_local.h"
30 
31 static vec3_t	modelorg;		// relative to viewpoint
32 
33 vec3_t	r_worldLightVec;
34 dlight_t *dynLight;
35 
36 #define LIGHTMAP_BYTES 4
37 
38 //Pretty safe bet most cards support this
39 #define	LIGHTMAP_SIZE	2048
40 #define	MAX_LIGHTMAPS	12
41 
42 int		c_visible_lightmaps;
43 int		c_visible_textures;
44 
45 // This is supposed to be faster on some older hardware.
46 #define GL_LIGHTMAP_FORMAT GL_BGRA
47 
48 typedef struct
49 {
50 	int	current_lightmap_texture;
51 
52 	// For each column, what is the last row where a pixel is used
53 	int			allocated[LIGHTMAP_SIZE];
54 
55 	// Lightmap texture data (RGBA, alpha not used)
56 	byte		lightmap_buffer[4*LIGHTMAP_SIZE*LIGHTMAP_SIZE];
57 } gllightmapstate_t;
58 
59 // TODO: dynamically allocate this so we can free it for RAM savings? It's
60 // using over 16 megs.
61 static gllightmapstate_t gl_lms;
62 
63 static void		LM_InitBlock( void );
64 static void		LM_UploadBlock( );
65 static qboolean	LM_AllocBlock (int w, int h, int *x, int *y);
66 
67 extern void R_SetCacheState( msurface_t *surf );
68 extern void R_BuildLightMap (msurface_t *surf, byte *dest, int smax, int tmax, int stride);
69 
70 /*
71 ===============
72 BSP_TextureAnimation
73 
74 Returns the proper texture for a given time and base texture
75 XXX: AFAIK this is only used for the old .wal textures, and is a bit redundant
76 with the rscript system, although it is implemented more efficiently. Maybe
77 merge the two systems somehow?
78 ===============
79 */
BSP_TextureAnimation(mtexinfo_t * tex)80 image_t *BSP_TextureAnimation (mtexinfo_t *tex)
81 {
82 	int		c;
83 
84 	if (!tex->next)
85 		return tex->image;
86 
87 	c = currententity->frame % tex->numframes;
88 	while (c)
89 	{
90 		tex = tex->next;
91 		c--;
92 	}
93 
94 	return tex->image;
95 }
96 
97 
98 
99 /*
100 =========================================
101 
102 Textureless Surface Rendering
103 Used by the shadow system
104 
105 =========================================
106 */
107 
108 /*
109 ================
110 BSP_DrawTexturelessPoly
111 ================
112 */
BSP_DrawTexturelessPoly(msurface_t * fa)113 void BSP_DrawTexturelessPoly (msurface_t *fa)
114 {
115 	R_InitVArrays(VERT_NO_TEXTURE);
116 	R_AddSurfToVArray (fa);
117 	R_KillVArrays();
118 }
119 
BSP_DrawShadowPoly(msurface_t * fa,vec3_t origin)120 void BSP_DrawShadowPoly (msurface_t *fa, vec3_t origin)
121 {
122 	R_AddShadowSurfToVArray (fa, origin);
123 }
124 
BSP_DrawTexturelessInlineBModel(entity_t * e)125 void BSP_DrawTexturelessInlineBModel (entity_t *e)
126 {
127 	int			i;
128 	msurface_t	*psurf;
129 
130 	//
131 	// draw texture
132 	//
133 	psurf = &currentmodel->surfaces[currentmodel->firstmodelsurface];
134 	for (i=0 ; i<currentmodel->nummodelsurfaces ; i++, psurf++)
135 	{
136 
137 		// draw the polygon
138 		BSP_DrawTexturelessPoly( psurf );
139 		psurf->visframe = r_framecount;
140 	}
141 
142 	qglDisable (GL_BLEND);
143 	qglColor4f (1,1,1,1);
144 	GL_TexEnv( GL_REPLACE );
145 }
146 
BSP_DrawTexturelessBrushModel(entity_t * e)147 void BSP_DrawTexturelessBrushModel (entity_t *e)
148 {
149 	vec3_t		mins, maxs;
150 	int			i;
151 	qboolean	rotated;
152 
153 	if (currentmodel->nummodelsurfaces == 0)
154 		return;
155 
156 	currententity = e;
157 
158 	if (e->angles[0] || e->angles[1] || e->angles[2])
159 	{
160 		rotated = true;
161 		for (i=0 ; i<3 ; i++)
162 		{
163 			mins[i] = e->origin[i] - currentmodel->radius;
164 			maxs[i] = e->origin[i] + currentmodel->radius;
165 		}
166 	}
167 	else
168 	{
169 		rotated = false;
170 		VectorAdd (e->origin, currentmodel->mins, mins);
171 		VectorAdd (e->origin, currentmodel->maxs, maxs);
172 	}
173 
174 	if (R_CullBox (mins, maxs)) {
175 		return;
176 	}
177 
178 	qglColor3f (1,1,1);
179 
180 	VectorSubtract (r_newrefdef.vieworg, e->origin, modelorg);
181 
182 	if (rotated)
183 	{
184 		vec3_t	temp;
185 		vec3_t	forward, right, up;
186 
187 		VectorCopy (modelorg, temp);
188 		AngleVectors (e->angles, forward, right, up);
189 		modelorg[0] = DotProduct (temp, forward);
190 		modelorg[1] = -DotProduct (temp, right);
191 		modelorg[2] = DotProduct (temp, up);
192 	}
193 
194     qglPushMatrix ();
195 	e->angles[0] = -e->angles[0];	// stupid quake bug
196 	e->angles[2] = -e->angles[2];	// stupid quake bug
197 	R_RotateForEntity (e);
198 	e->angles[0] = -e->angles[0];	// stupid quake bug
199 	e->angles[2] = -e->angles[2];	// stupid quake bug
200 
201 	BSP_DrawTexturelessInlineBModel (e);
202 
203 	qglPopMatrix ();
204 }
205 
206 
207 
208 /*
209 =========================================
210 
211 BSP Surface Rendering
212 Common between brush and world models
213 
214 =========================================
215 */
216 
217 
218 /*
219 =========================================
220 Special surfaces - Somewhat less common, require more work to render
221  - Translucent ("alpha") surfaces
222    These are special because they have to be rendered all in one pass, despite
223    consisting of several different types of surfaces, so the code can't make
224    too many assumptions about the surface.
225  - Rscript surfaces (those with material shaders)
226    Rscript surfaces are first rendered through the "ordinary" path, then
227    this one.
228  - Wavy, rippling ("warp") surfaces
229    The code to actually render these is in r_warp.c.
230 =========================================
231 */
232 
233 
234 // The "special" surfaces use these for linked lists.
235 // The reason to have linked lists for surfaces from brush model entities
236 // separate from the linked lists for world surfaces is that the world
237 // surface linked lists can be preserved between frames if r_optimize is on,
238 // whereas the entity linked lists must be cleared each time an entity is
239 // drawn.
240 msurface_t	*r_alpha_surfaces;
241 msurface_t	*r_ent_alpha_surfaces;
242 msurface_t	*r_rscript_surfaces; // no brush models can have rscript surfs
243 msurface_t	*r_warp_surfaces;
244 msurface_t	*r_ent_warp_surfaces;
245 
246 // This is a chain of surfaces that may need to have their lightmaps updated.
247 // They are not rendered in the order of this chain and will be linked into
248 // other chains for rendering.
249 msurface_t	*r_flicker_surfaces;
250 
251 
252 /*
253 ================
254 BSP_DrawWarpSurfaces
255 ================
256 */
BSP_DrawWarpSurfaces(qboolean forEnt)257 void BSP_DrawWarpSurfaces (qboolean forEnt)
258 {
259 	msurface_t	*surf;
260 	image_t		*image;
261 
262 	if (forEnt)
263 		surf = r_ent_warp_surfaces;
264 	else
265 		surf = r_warp_surfaces;
266 
267 	if (surf == NULL)
268 		return;
269 
270 	// no lightmaps rendered on these surfaces
271 	GL_EnableMultitexture( false );
272 	GL_TexEnv( GL_MODULATE );
273 	qglColor4f( gl_state.inverse_intensity,
274 		        gl_state.inverse_intensity,
275 				gl_state.inverse_intensity,
276 				1.0F );
277 	while (surf)
278 	{
279 		c_brush_polys++;
280 		image = BSP_TextureAnimation (surf->texinfo);
281 		GL_Bind (image->texnum);
282 		R_RenderWaterPolys(surf, 0, 1, 1);
283 		surf = surf->texturechain;
284 	}
285 
286 	if (forEnt)
287 		r_ent_warp_surfaces = NULL;
288 
289 	GL_EnableMultitexture( true );
290 	GL_TexEnv( GL_REPLACE );
291 	R_KillVArrays ();
292 }
293 
294 /*
295 ================
296 BSP_DrawAlphaPoly
297 ================
298 */
BSP_DrawAlphaPoly(msurface_t * fa,int flags)299 void BSP_DrawAlphaPoly (msurface_t *fa, int flags)
300 
301 {
302 	float	scroll;
303 
304 	scroll = 0;
305 	if (flags & SURF_FLOWING)
306 	{
307 
308 		scroll = -64 * ( (r_newrefdef.time / 40.0) - (int)(r_newrefdef.time / 40.0) );
309 		if (scroll == 0.0)
310 
311 			scroll = -64.0;
312 	}
313 
314 	R_InitVArrays(VERT_SINGLE_TEXTURED);
315 
316 	R_AddTexturedSurfToVArray (fa, scroll);
317 	R_KillVArrays();
318 }
319 
320 
321 /*
322 ================
323 R_DrawAlphaSurfaces
324 
325 Draw water surfaces and windows.
326 
327 Annoyingly, because alpha surfaces have to be drawn from back to front,
328 everything transparent-- water, rscripted surfs, and non-rscripted surfs-- has
329 to be drawn in a single pass. This is an inherently inefficient process.
330 
331 The BSP tree is walked front to back, so unwinding the chain of alpha surfaces
332 will draw back to front, giving proper ordering FOR BSP SURFACES!
333 
334 
335 It's a bit wrong for entity surfaces (i.e. glass doors.) Because they are in
336 separate linked lists, the entity surfaces must be either always behind or
337 always in front of the world surfaces. I chose always in front because that
338 seems to fix all rendering issues, regardless of whether the entity actually
339 is in front. Search me why. NOTE: this bug existed even when it was all one
340 linked list, although at that time entity surfaces were always behind map
341 surfaces (added to the beginning of the linked list after all the BSP
342 rendering code.)
343 ================
344 */
R_DrawAlphaSurfaces_chain(msurface_t * chain)345 void R_DrawAlphaSurfaces_chain (msurface_t *chain)
346 {
347 	msurface_t	*s;
348 	float		intens;
349 	rscript_t	*rs_shader;
350 	rs_stage_t	*stage = NULL;
351 	int			texnum = 0;
352 	float		scaleX = 1.0f, scaleY = 1.0f;
353 
354 	// the textures are prescaled up for a better lighting range,
355 	// so scale it back down
356 	intens = gl_state.inverse_intensity;
357 
358 	qglDepthMask ( GL_FALSE );
359 	qglEnable (GL_BLEND);
360 	GL_TexEnv( GL_MODULATE );
361 
362 	for (s=chain ; s ; s=s->texturechain)
363 	{
364 		GL_Bind(s->texinfo->image->texnum);
365 		c_brush_polys++;
366 
367 		if (s->texinfo->flags & SURF_TRANS33)
368 			qglColor4f (intens, intens, intens, 0.33);
369 		else if (s->texinfo->flags & SURF_TRANS66)
370 			qglColor4f (intens, intens, intens, 0.66);
371 		else
372 			qglColor4f (intens, intens, intens, 1);
373 
374 		//moving trans brushes
375 		if (s->entity)
376 		{
377 			qglLoadMatrixf (r_world_matrix); //moving trans brushes
378 			s->entity->angles[0] = -s->entity->angles[0];	// stupid quake bug
379 			s->entity->angles[2] = -s->entity->angles[2];	// stupid quake bug
380 				R_RotateForEntity (s->entity);
381 			s->entity->angles[0] = -s->entity->angles[0];	// stupid quake bug
382 			s->entity->angles[2] = -s->entity->angles[2];	// stupid quake bug
383 		}
384 
385 		rs_shader = NULL;
386 		if (r_shaders->integer)
387 			rs_shader = (rscript_t *)s->texinfo->image->script;
388 
389 		if (s->iflags & ISURF_DRAWTURB)
390 		{
391 			//water shaders
392 			scaleX = scaleY = 1.0f;
393 			if(rs_shader)
394 			{
395 				stage = rs_shader->stage;
396 				if(stage)
397 				{	//for now, just map a reflection texture
398 					texnum = stage->texture->texnum; //pass this to renderwaterpolys
399 				}
400 				if(stage->scale.scaleX != 0 && stage->scale.scaleY !=0)
401 				{
402 					scaleX = stage->scale.scaleX;
403 					scaleY = stage->scale.scaleY;
404 				}
405 			}
406 			R_RenderWaterPolys (s, texnum, scaleX, scaleY);
407 			qglEnable (GL_BLEND);
408 			GL_TexEnv( GL_MODULATE );
409 		}
410 		else if(rs_shader && !(s->texinfo->flags & SURF_FLOWING))
411 		{
412 			RS_Surface(s);
413 			qglEnable (GL_BLEND);
414 			GL_TexEnv( GL_MODULATE );
415 		}
416 		else
417 			BSP_DrawAlphaPoly (s, s->texinfo->flags);
418 	}
419 
420 	GL_TexEnv( GL_REPLACE );
421 	qglColor4f (1,1,1,1);
422 	qglDisable (GL_BLEND);
423 	qglDepthMask ( GL_TRUE );
424 }
425 
R_DrawAlphaSurfaces(void)426 void R_DrawAlphaSurfaces (void)
427 {
428 	R_DrawAlphaSurfaces_chain (r_alpha_surfaces);
429 	R_DrawAlphaSurfaces_chain (r_ent_alpha_surfaces);
430 	qglLoadMatrixf (r_world_matrix); //moving trans brushes
431 	r_ent_alpha_surfaces = NULL;
432 }
433 
434 /*
435 ================
436 R_DrawRSSurfaces
437 
438 Draw shader surfaces
439 ================
440 */
R_DrawRSSurfaces(void)441 void R_DrawRSSurfaces (void)
442 {
443 	msurface_t	*s = r_rscript_surfaces;
444 
445 	if(!s)
446 		return;
447 
448 	if (!r_shaders->integer)
449 	{
450 		r_rscript_surfaces = NULL;
451 		return;
452 	}
453 
454 	qglDepthMask(false);
455 	qglShadeModel (GL_SMOOTH);
456 
457 	qglEnable(GL_POLYGON_OFFSET_FILL);
458 	qglPolygonOffset(-3, -2);
459 
460 	for (; s; s = s->rscriptchain)
461 		RS_Surface(s);
462 
463 	qglDisable(GL_POLYGON_OFFSET_FILL);
464 
465 	GLSTATE_DISABLE_BLEND
466 	GLSTATE_DISABLE_ALPHATEST
467 
468 	qglDepthMask(true);
469 }
470 
471 
472 
473 /*
474 =========================================
475 Ordinary surfaces (fixed-function, normalmapped, and dynamically lit)
476 These are the most commonly used types of surfaces, so the rendering code path
477 for each is more optimized-- surfaces grouped by texinfo, VBOs, VBO batching,
478 etc.
479 =========================================
480 */
481 
482 // The "ordinary" surfaces do not use global variables for linked lists. The
483 // linked lists are in the texinfo struct, so the textures can be grouped by
484 // texinfo. Like the "special" surfaces, there are separate linked lists for
485 // entity surfaces and world surfaces.
486 
487 // State variables for detecting changes from one surface to the next. If any
488 // of these change, the current batch of polygons to render is flushed. This
489 // helps minimize GL state change calls and draw calls.
490 int 		r_currTex = -9999; //only bind a texture if it is not the same as previous surface
491 int 		r_currLMTex = -9999; //lightmap texture
492 mtexinfo_t	*r_currTexInfo = NULL; //texinfo struct
493 float		*r_currTangentSpaceTransform; //etc.
494 
495 // VBO batching
496 // This system allows contiguous sequences of polygons to be merged into
497 // batches, even if they are added out of order.
498 
499 // There is a linked list of these, but they are not dynamically allocated.
500 // They are allocated from a static array. This prevents us wasting CPU with
501 // lots of malloc/free calls. Keep this struct small for performance!
502 typedef struct vbobatch_s {
503 	int					first_vert, last_vert;
504 	struct vbobatch_s 	*next;
505 } vbobatch_t;
506 
507 #define MAX_VBO_BATCHES 100	// 100 ought to be enough. If we run out, we can
508 							// always just draw some prematurely.
509 
510 // use a static array and counter to avoid lots of malloc nonsense
511 int			num_vbo_batches;
512 vbobatch_t	vbobatch_buffer[MAX_VBO_BATCHES];
513 // never used directly; linked list base only
514 vbobatch_t	first_vbobatch[] = {{-1, -1, NULL}};
515 // if false, flushVBOAccum will set up the VBO GL state
516 qboolean	r_vboOn = false;
517 // for the rspeed_vbobatches HUD gauge
518 int			c_vbo_batches;
519 
520 // clear all accumulated surfaces without rendering
BSP_ClearVBOAccum(void)521 static inline void BSP_ClearVBOAccum (void)
522 {
523 	memset (vbobatch_buffer, 0, sizeof(vbobatch_buffer));
524 	num_vbo_batches = 0;
525 	first_vbobatch->next = NULL;
526 }
527 
528 // render all accumulated surfaces, then clear them
529 // XXX: assumes that global OpenGL state is correct for whatever surfaces are
530 // in the accumulator, so don't change state until you've called this!
BSP_FlushVBOAccum(void)531 static inline void BSP_FlushVBOAccum (void)
532 {
533 	vbobatch_t *batch = first_vbobatch->next;
534 
535 	if (!batch)
536 		return;
537 
538 	if (!r_vboOn)
539 	{
540 		GL_SetupWorldVBO ();
541 		r_vboOn = true;
542 	}
543 
544 	// XXX: for future reference, the glDrawRangeElements code was last seen
545 	// here at revision 3246.
546 	for (; batch; batch = batch->next)
547 	{
548 		qglDrawArrays (GL_TRIANGLES, batch->first_vert, batch->last_vert-batch->first_vert);
549 		c_vbo_batches++;
550 	}
551 
552 	BSP_ClearVBOAccum ();
553 }
554 
555 // Add a new surface to the VBO batch accumulator. If its vertex data is next
556 // to any other surfaces within the VBO, opportunistically merge the surfaces
557 // together into a larger "batch," so they can be rendered with one draw call.
558 // Whenever two batches touch each other, they are merged. Hundreds of
559 // surfaces can be rendered with a single call, which is easier on the OpenGL
560 // pipeline.
BSP_AddToVBOAccum(int first_vert,int last_vert)561 static inline void BSP_AddToVBOAccum (int first_vert, int last_vert)
562 {
563 	vbobatch_t *batch = first_vbobatch->next, *prev = first_vbobatch;
564 	vbobatch_t *new;
565 
566 	if (!batch)
567 	{
568 		batch = first_vbobatch->next = vbobatch_buffer;
569 		batch->first_vert = first_vert;
570 		batch->last_vert = last_vert;
571 		num_vbo_batches++;
572 		return;
573 	}
574 
575 	// This is optimal. Because of the way the surface linked lists are built
576 	// by BSP_AddToTextureChain, they are usually in reverse order, so it's
577 	// best to start toward the beginning of the list of VBO batches where
578 	// you're more likely to merge something.
579 
580 	while (batch->next && batch->next->first_vert < first_vert)
581 	{
582 		prev = batch;
583 		batch = batch->next;
584 	}
585 
586 	if (batch->first_vert > last_vert)
587 	{
588 		new = &vbobatch_buffer[num_vbo_batches++];
589 		new->next = batch;
590 		prev->next = new;
591 		new->first_vert = first_vert;
592 		new->last_vert = last_vert;
593 	}
594 	else if (batch->last_vert == first_vert)
595 	{
596 		batch->last_vert = last_vert;
597 		if (batch->next && batch->next->first_vert == last_vert)
598 		{
599 			// This is the special case where the new surface bridges the gap
600 			// between two existing batches, allowing us to merge them into
601 			// the first one. This is the only case where we actually remove a
602 			// batch instead of growing one or adding one.
603 			batch->last_vert = batch->next->last_vert;
604 			if (batch->next == &vbobatch_buffer[num_vbo_batches-1])
605 				num_vbo_batches--;
606 			batch->next = batch->next->next;
607 		}
608 		return; //no need to check for maximum batch count being hit
609 	}
610 	else if (batch->next && batch->next->first_vert == last_vert)
611 	{
612 		batch->next->first_vert = first_vert;
613 		return; //no need to check for maximum batch count being hit
614 	}
615 	else if (batch->first_vert == last_vert)
616 	{
617 		batch->first_vert = first_vert;
618 		return; //no need to check for maximum batch count being hit
619 	}
620 	else //if (batch->last_vert < first_vert)
621 	{
622 		new = &vbobatch_buffer[num_vbo_batches++];
623 		new->next = batch->next;
624 		batch->next = new;
625 		new->first_vert = first_vert;
626 		new->last_vert = last_vert;
627 	}
628 
629 	//running out of space
630 	if (num_vbo_batches == MAX_VBO_BATCHES)
631 	{
632 /*		Com_Printf ("MUSTFLUSH\n");*/
633 		BSP_FlushVBOAccum ();
634 	}
635 }
636 
637 /*
638 ================
639 BSP_NonGLSLTexinfoChanged
640 
641 Update GL state as needed so we can draw a new batch of surfaces for the
642 provided texinfo (version for all fixed-function standard surfaces)
643 ================
644 */
BSP_NonGLSLTexinfoChanged(mtexinfo_t * texinfo)645 static void BSP_NonGLSLTexinfoChanged (mtexinfo_t *texinfo)
646 {
647 	int			texnum;
648 
649 	BSP_FlushVBOAccum ();
650 
651 	if (TexinfoIsAlphaBlended (texinfo))
652 	{
653 		if (!r_currTexInfo || !TexinfoIsAlphaBlended(r_currTexInfo))
654 		{
655 			qglEnable( GL_ALPHA_TEST );
656 		}
657 	}
658 	else
659 	{
660 		if (!r_currTexInfo || TexinfoIsAlphaBlended(r_currTexInfo))
661 		{
662 			qglDisable( GL_ALPHA_TEST );
663 		}
664 	}
665 
666 	// do this here so only have to do it once instead of for each surface
667 	texnum = BSP_TextureAnimation( texinfo )->texnum;
668 
669 	if(texnum != r_currTex)
670 	{
671 		qglActiveTextureARB(GL_TEXTURE0);
672 		qglBindTexture(GL_TEXTURE_2D, texnum );
673 		r_currTex = texnum;
674 	}
675 
676 	r_currTexInfo = texinfo;
677 }
678 
679 /*
680 ================
681 BSP_RenderLightmappedPoly
682 
683 Main polygon rendering routine (all fixed-function standard surfaces)
684 ================
685 */
BSP_RenderLightmappedPoly(msurface_t * surf)686 static void BSP_RenderLightmappedPoly( msurface_t *surf)
687 {
688 	float	scroll;
689 	unsigned lmtex = surf->lightmaptexturenum;
690 
691 	c_brush_polys++;
692 
693 	if (lmtex != r_currLMTex)
694 	{
695 		BSP_FlushVBOAccum ();
696 		qglActiveTextureARB(GL_TEXTURE1);
697 		qglBindTexture(GL_TEXTURE_2D, gl_state.lightmap_textures + lmtex );
698 	}
699 
700 	if(gl_state.vbo && surf->has_vbo && !(surf->texinfo->flags & SURF_FLOWING))
701 	{
702 		BSP_AddToVBOAccum (surf->vbo_first_vert, surf->vbo_first_vert+surf->vbo_num_verts);
703 	}
704 	else
705 	{
706 		BSP_FlushVBOAccum ();
707 		r_vboOn = false;
708 		scroll = 0;
709 		if (surf->texinfo->flags & SURF_FLOWING)
710 		{
711 			scroll = -64 * ( (r_newrefdef.time / 40.0) - (int)(r_newrefdef.time / 40.0) );
712 			if (scroll == 0.0)
713 				scroll = -64.0;
714 		}
715 		R_InitVArrays (VERT_MULTI_TEXTURED);
716 		R_AddLightMappedSurfToVArray (surf, scroll);
717 	}
718 
719 }
720 
721 /*
722 ================
723 BSP_GLSLTexinfoChanged
724 
725 Update GL state as needed so we can draw a new batch of surfaces for the
726 provided texinfo (version for all normalmapped and/or dynamically lit standard
727 surfaces)
728 ================
729 */
BSP_GLSLTexinfoChanged(mtexinfo_t * texinfo,qboolean dynamic)730 static void BSP_GLSLTexinfoChanged (mtexinfo_t *texinfo, qboolean dynamic)
731 {
732 	int			texnum;
733 
734 	BSP_FlushVBOAccum ();
735 
736 	if (TexinfoIsAlphaBlended (texinfo))
737 	{
738 		if (!r_currTexInfo || !TexinfoIsAlphaBlended(r_currTexInfo))
739 		{
740 			qglEnable( GL_ALPHA_TEST );
741 		}
742 	}
743 	else
744 	{
745 		if (!r_currTexInfo || TexinfoIsAlphaBlended(r_currTexInfo))
746 		{
747 			qglDisable( GL_ALPHA_TEST );
748 		}
749 	}
750 
751 	// no texture animation for normalmapped surfaces, for some reason
752 	texnum = texinfo->image->texnum;
753 
754 	if(texnum != r_currTex)
755 	{
756 		r_currTex = texnum;
757 
758 		if (!r_currTexInfo)
759 		{
760 			glUniform1iARB( g_location_surfTexture, 0);
761 			glUniform1iARB( g_location_heightTexture, 1);
762 			glUniform1iARB( g_location_normalTexture, 2);
763 			glUniform1iARB( g_location_lmTexture, 3);
764 		}
765 
766 		qglActiveTextureARB(GL_TEXTURE0);
767 		qglBindTexture(GL_TEXTURE_2D, texnum);
768 
769 		qglActiveTextureARB(GL_TEXTURE1);
770 		qglBindTexture(GL_TEXTURE_2D, texinfo->heightMap->texnum);
771 
772 		qglActiveTextureARB(GL_TEXTURE2);
773 		qglBindTexture(GL_TEXTURE_2D, texinfo->normalMap->texnum);
774 		KillFlags |= KILL_TMU2_POINTER;
775 	}
776 
777 	if (dynamic)
778 	{
779 		if(gl_bspnormalmaps->integer && texinfo->has_heightmap)
780 		{
781 			if (!r_currTexInfo || !r_currTexInfo->has_heightmap)
782 			{
783 				glUniform1iARB( g_location_parallax, 1);
784 			}
785 		}
786 		else
787 		{
788 			if (!r_currTexInfo || r_currTexInfo->has_heightmap)
789 			{
790 				glUniform1iARB( g_location_parallax, 0);
791 			}
792 		}
793 	}
794 
795 	if (!gl_bspnormalmaps->integer)
796 	{
797 		if (!r_currTexInfo)
798 		{
799 			glUniform1iARB( g_location_liquid, 0 );
800 			glUniform1iARB( g_location_shiny, 0 );
801 		}
802 	}
803 	else if	(r_currTexInfo &&
804 			(texinfo->flags & (SURF_BLOOD|SURF_WATER|SURF_SHINY)) ==
805 			(r_currTexInfo->flags & (SURF_BLOOD|SURF_WATER|SURF_SHINY)))
806 	{
807 		//no change to GL state is needed
808 	}
809 	else if (texinfo->flags & SURF_BLOOD)
810 	{
811 		//need to bind the blood drop normal map, and set flag, and time
812 		glUniform1iARB( g_location_liquid, 8 ); //blood type 8, water 1
813 		glUniform1iARB( g_location_shiny, 0 );
814 		glUniform1fARB( g_location_rsTime, rs_realtime);
815 		glUniform1iARB( g_location_liquidTexture, 4); //for blood we are going to need to send a diffuse texture with it
816 		qglActiveTextureARB(GL_TEXTURE4);
817 		qglBindTexture(GL_TEXTURE_2D, r_blooddroplets->texnum);
818 		KillFlags |= KILL_TMU4_POINTER;
819 		glUniform1iARB( g_location_liquidNormTex, 5);
820 		qglActiveTextureARB(GL_TEXTURE5);
821 		qglBindTexture(GL_TEXTURE_2D, r_blooddroplets_nm->texnum);
822 		KillFlags |= KILL_TMU5_POINTER;
823 	}
824 	else if (texinfo->flags & SURF_WATER)
825 	{
826 		//need to bind the water drop normal map, and set flag, and time
827 		glUniform1iARB( g_location_liquid, 1 );
828 		glUniform1iARB( g_location_shiny, 0 );
829 		glUniform1fARB( g_location_rsTime, rs_realtime);
830 		glUniform1iARB( g_location_liquidNormTex, 4); //for blood we are going to need to send a diffuse texture with it(maybe even height!)
831 		qglActiveTextureARB(GL_TEXTURE4);
832 		qglBindTexture(GL_TEXTURE_2D, r_droplets->texnum);
833 		KillFlags |= KILL_TMU4_POINTER;
834 	}
835 	else if (texinfo->flags & SURF_SHINY)
836 	{
837 		glUniform1iARB( g_location_liquid, 0 );
838 		glUniform1iARB( g_location_shiny, 1 );
839 
840 		glUniform1iARB( g_location_chromeTex, 4);
841 		qglActiveTextureARB(GL_TEXTURE4);
842 		qglBindTexture(GL_TEXTURE_2D, r_mirrorspec->texnum);
843 		KillFlags |= KILL_TMU4_POINTER;
844 	}
845 	else if (!r_currTexInfo || r_currTexInfo->flags & (SURF_BLOOD|SURF_WATER|SURF_SHINY))
846 	{
847 		glUniform1iARB( g_location_liquid, 0 );
848 		glUniform1iARB( g_location_shiny, 0 );
849 	}
850 
851 	r_currTexInfo = texinfo;
852 }
853 
854 /*
855 ================
856 BSP_RenderGLSLLightmappedPoly
857 
858 Main polygon rendering routine (all normalmapped and/or dynamically lit
859 standard surfaces)
860 ================
861 */
BSP_RenderGLSLLightmappedPoly(msurface_t * surf)862 static void BSP_RenderGLSLLightmappedPoly( msurface_t *surf)
863 {
864 	static float	scroll;
865 	unsigned lmtex = surf->lightmaptexturenum;
866 
867 	c_brush_polys++;
868 
869 	scroll = 0;
870 
871 	if (lmtex != r_currLMTex)
872 	{
873 		BSP_FlushVBOAccum ();
874 		qglActiveTextureARB(GL_TEXTURE3);
875 		qglBindTexture(GL_TEXTURE_2D, gl_state.lightmap_textures + lmtex);
876 		KillFlags |= KILL_TMU3_POINTER;
877 	}
878 
879 	if (r_currTangentSpaceTransform != surf->tangentSpaceTransform)
880 	{
881 		BSP_FlushVBOAccum ();
882 		glUniformMatrix3fvARB( g_tangentSpaceTransform,	1, GL_FALSE, (const GLfloat *) surf->tangentSpaceTransform );
883 		r_currTangentSpaceTransform = (float *)surf->tangentSpaceTransform;
884 	}
885 
886 	if(gl_state.vbo && surf->has_vbo && !(surf->texinfo->flags & SURF_FLOWING))
887 	{
888 		BSP_AddToVBOAccum (surf->vbo_first_vert, surf->vbo_first_vert+surf->vbo_num_verts);
889 	}
890 	else
891 	{
892 		BSP_FlushVBOAccum ();
893 		r_vboOn = false;
894 		scroll = 0;
895 		if (surf->texinfo->flags & SURF_FLOWING)
896 		{
897 			scroll = -64 * ( (r_newrefdef.time / 40.0) - (int)(r_newrefdef.time / 40.0) );
898 			if (scroll == 0.0)
899 				scroll = -64.0;
900 		}
901 		R_InitVArrays (VERT_MULTI_TEXTURED);
902 		R_AddLightMappedSurfToVArray (surf, scroll);
903 	}
904 }
905 
BSP_DrawNonGLSLSurfaces(qboolean forEnt)906 void BSP_DrawNonGLSLSurfaces (qboolean forEnt)
907 {
908     int         i;
909 
910 	// reset VBO batching state
911 	r_currTex = r_currLMTex = -99999;
912 	r_currTexInfo = NULL;
913 	r_currTangentSpaceTransform = NULL;
914 
915 	BSP_FlushVBOAccum ();
916 
917 	r_vboOn = false;
918 
919 	qglEnableClientState( GL_VERTEX_ARRAY );
920 	qglClientActiveTextureARB (GL_TEXTURE0);
921 	qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
922 	qglClientActiveTextureARB (GL_TEXTURE1);
923 	qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
924 	KillFlags |= (KILL_TMU0_POINTER | KILL_TMU1_POINTER);
925 
926 	for (i = 0; i < currentmodel->num_unique_texinfos; i++)
927     {
928     	msurface_t	*s;
929     	if (forEnt)
930     	{
931     		s = currentmodel->unique_texinfo[i]->e_lightmap_surfaces;
932     		currentmodel->unique_texinfo[i]->e_lightmap_surfaces = NULL;
933     	}
934     	else
935     	{
936     		s = currentmodel->unique_texinfo[i]->w_lightmap_surfaces;
937     	}
938     	if (!s)
939     		continue;
940     	BSP_NonGLSLTexinfoChanged (s->texinfo->equiv);
941 		for (; s; s = s->texturechain) {
942 			BSP_RenderLightmappedPoly(s);
943 			r_currLMTex = s->lightmaptexturenum;
944 		}
945 	}
946 
947 	BSP_FlushVBOAccum ();
948 
949 	qglActiveTextureARB(GL_TEXTURE1);
950 	qglBindTexture(GL_TEXTURE_2D, 0 );
951 
952 	qglDisable (GL_ALPHA_TEST);
953 
954 }
955 
BSP_DrawGLSLSurfaces(qboolean forEnt)956 void BSP_DrawGLSLSurfaces (qboolean forEnt)
957 {
958     int         i;
959 
960 	// reset VBO batching state
961 	r_currTex = r_currLMTex = -99999;
962 	r_currTexInfo = NULL;
963 	r_currTangentSpaceTransform = NULL;
964 
965 	if (!gl_bspnormalmaps->integer)
966 	{
967 		return;
968 	}
969 
970 	BSP_ClearVBOAccum ();
971 
972 	if(r_shadowmapcount == 2)
973 	{
974 		//static vegetation shadow
975 		glUniform1iARB( g_location_bspShadowmapTexture2, 6);
976 		qglActiveTextureARB(GL_TEXTURE6);
977 		qglBindTexture(GL_TEXTURE_2D, r_depthtexture2->texnum);
978 
979 		glUniform1iARB( g_location_shadowmap, 1);
980 		glUniform1iARB( g_Location_statshadow, 1 );
981 
982 		glUniform1fARB( g_location_xOffs, 1.0/(viddef.width*r_shadowmapscale->value));
983         glUniform1fARB( g_location_yOffs, 1.0/(viddef.height*r_shadowmapscale->value));
984 	}
985 	else
986 	{
987 		glUniform1iARB( g_location_shadowmap, 0);
988 		glUniform1iARB( g_Location_statshadow, 0);
989 	}
990 
991 	glUniform1iARB( g_location_dynamic, 0);
992 	glUniform1iARB( g_location_parallax, 1);
993 
994 	r_vboOn = false;
995 
996 	qglEnableClientState( GL_VERTEX_ARRAY );
997 	qglClientActiveTextureARB (GL_TEXTURE0);
998 	qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
999 	qglClientActiveTextureARB (GL_TEXTURE1);
1000 	qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
1001 	KillFlags |= (KILL_TMU0_POINTER | KILL_TMU1_POINTER);
1002 
1003 	for (i = 0; i < currentmodel->num_unique_texinfos; i++)
1004     {
1005     	msurface_t	*s;
1006     	if (forEnt)
1007     	{
1008     		s = currentmodel->unique_texinfo[i]->e_glsl_surfaces;
1009     		currentmodel->unique_texinfo[i]->e_glsl_surfaces = NULL;
1010     	}
1011     	else
1012     	{
1013     		s = currentmodel->unique_texinfo[i]->w_glsl_surfaces;
1014     	}
1015     	if (!s)
1016     		continue;
1017     	BSP_GLSLTexinfoChanged (s->texinfo->equiv, false);
1018 		for (; s; s = s->texturechain) {
1019 			BSP_RenderGLSLLightmappedPoly(s);
1020 			r_currLMTex = s->lightmaptexturenum;
1021 		}
1022 	}
1023 
1024 	BSP_FlushVBOAccum ();
1025 
1026 	qglDisable (GL_ALPHA_TEST);
1027 
1028 	qglActiveTextureARB (GL_TEXTURE1);
1029 	qglDisable (GL_TEXTURE_2D);
1030 
1031 }
1032 
BSP_DrawGLSLDynamicSurfaces(qboolean forEnt)1033 void BSP_DrawGLSLDynamicSurfaces (qboolean forEnt)
1034 {
1035 	int         i;
1036 	dlight_t	*dl = NULL;
1037 	int			lnum, sv_lnum = 0;
1038 	float		add, brightest = 0;
1039 	vec3_t		lightVec;
1040 	float		lightCutoffSquared = 0.0f;
1041 	qboolean	foundLight = false;
1042 
1043 	if (gl_dynamic->integer == 0)
1044 	{
1045 		return;
1046 	}
1047 
1048 	dl = r_newrefdef.dlights;
1049 	for (lnum=0; lnum<r_newrefdef.num_dlights; lnum++, dl++)
1050 	{
1051 		VectorSubtract (r_origin, dl->origin, lightVec);
1052 		add = dl->intensity - VectorLength(lightVec)/10;
1053 		if (add > brightest) //only bother with lights close by
1054 		{
1055 			brightest = add;
1056 			sv_lnum = lnum; //remember the position of most influencial light
1057 		}
1058 	}
1059 
1060 	if(brightest > 0)
1061 	{
1062 		//we have a light
1063 		foundLight= true;
1064 		dynLight = r_newrefdef.dlights;
1065 		dynLight += sv_lnum; //our most influential light
1066 
1067 		lightCutoffSquared = ( dynLight->intensity - DLIGHT_CUTOFF );
1068 
1069 		if( lightCutoffSquared <= 0.0f )
1070 			lightCutoffSquared = 0.0f;
1071 
1072 		lightCutoffSquared *= 2.0f;
1073 		lightCutoffSquared *= lightCutoffSquared;
1074 
1075 		// reset VBO batching state
1076 		r_currTex = r_currLMTex = -99999;
1077 		r_currTexInfo = NULL;
1078 		r_currTangentSpaceTransform = NULL;
1079 
1080 		BSP_ClearVBOAccum ();
1081 
1082 		glUniform3fARB( g_location_lightPosition, dynLight->origin[0], dynLight->origin[1], dynLight->origin[2]);
1083 		glUniform3fARB( g_location_lightColour, dynLight->color[0], dynLight->color[1], dynLight->color[2]);
1084 
1085 		glUniform1fARB( g_location_lightCutoffSquared, lightCutoffSquared);
1086 
1087 		if(gl_shadowmaps->integer)
1088 		{
1089 			//dynamic shadow
1090 			glUniform1iARB( g_location_bspShadowmapTexture, 7);
1091 			qglActiveTextureARB(GL_TEXTURE7);
1092 			qglBindTexture(GL_TEXTURE_2D, r_depthtexture->texnum);
1093 
1094 			glUniform1iARB( g_location_shadowmap, 1);
1095 
1096 			glUniform1fARB( g_location_xOffs, 1.0/(viddef.width*r_shadowmapscale->value));
1097 			glUniform1fARB( g_location_yOffs, 1.0/(viddef.height*r_shadowmapscale->value));
1098 		}
1099 		else
1100 			glUniform1iARB( g_location_shadowmap, 0);
1101 	}
1102 
1103 	glUniform1iARB( g_location_dynamic, foundLight);
1104 
1105 	r_vboOn = false;
1106 
1107 	qglEnableClientState( GL_VERTEX_ARRAY );
1108 	qglClientActiveTextureARB (GL_TEXTURE0);
1109 	qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
1110 	qglClientActiveTextureARB (GL_TEXTURE1);
1111 	qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
1112 	KillFlags |= (KILL_TMU0_POINTER | KILL_TMU1_POINTER);
1113 
1114 	for (i = 0; i < currentmodel->num_unique_texinfos; i++)
1115     {
1116     	msurface_t	*s;
1117     	if (forEnt)
1118     	{
1119     		s = currentmodel->unique_texinfo[i]->e_glsl_dynamic_surfaces;
1120     		currentmodel->unique_texinfo[i]->e_glsl_dynamic_surfaces = NULL;
1121     	}
1122     	else
1123     	{
1124     		s = currentmodel->unique_texinfo[i]->w_glsl_dynamic_surfaces;
1125     	}
1126     	if (!s)
1127     		continue;
1128     	BSP_GLSLTexinfoChanged (s->texinfo->equiv, true);
1129 		for (; s; s = s->texturechain) {
1130 			BSP_RenderGLSLLightmappedPoly(s);
1131 			r_currLMTex = s->lightmaptexturenum;
1132 		}
1133 	}
1134 
1135 	BSP_FlushVBOAccum ();
1136 
1137 	qglDisable (GL_ALPHA_TEST);
1138 
1139 	qglActiveTextureARB (GL_TEXTURE1);
1140 	qglDisable (GL_TEXTURE_2D);
1141 }
1142 
1143 
1144 
1145 
1146 /*
1147 =========================================
1148 This is the "API" for the BSP surface renderer backend, hiding most of the
1149 complexity of the previous functions.
1150 =========================================
1151 */
1152 
1153 
1154 /*
1155 ================
1156 BSP_ClearWorldTextureChains
1157 
1158 Reset linked lists for the world (non-entity/non-brushmodel) surfaces. This
1159 need not be called every frame if r_optimize is on. No equivalent function is
1160 needed for entity surfaces because they are reset automatically when they are
1161 drawn.
1162 ================
1163 */
BSP_ClearWorldTextureChains(void)1164 void BSP_ClearWorldTextureChains (void)
1165 {
1166 	int i;
1167 
1168 	for (i = 0; i < currentmodel->num_unique_texinfos; i++)
1169     {
1170     	currentmodel->unique_texinfo[i]->w_lightmap_surfaces = NULL;
1171     	currentmodel->unique_texinfo[i]->w_glsl_surfaces = NULL;
1172     	currentmodel->unique_texinfo[i]->w_glsl_dynamic_surfaces = NULL;
1173     }
1174 
1175     r_warp_surfaces = NULL;
1176     r_alpha_surfaces = NULL;
1177     r_rscript_surfaces = NULL;
1178     r_flicker_surfaces = NULL;
1179 }
1180 
1181 /*
1182 ================
1183 BSP_AddToTextureChain
1184 
1185 Call this on a surface (and indicate whether it's an entity surface) and it
1186 will figure out which texture chain to add it to; this function is responsible
1187 for deciding if the surface is "ordinary" or somehow "special," whether it
1188 should be normalmapped and/or dynamically lit, etc.
1189 
1190 This function will be repeatedly called on all the surfaces in the current
1191 brushmodel entity or in the world's static geometry, followed by a single call
1192 to BSP_DrawTextureChains to render them all in one fell swoop.
1193 ================
1194 */
1195 void BSP_UpdateSurfaceLightmap (msurface_t *surf);
BSP_AddToTextureChain(msurface_t * surf,qboolean forEnt)1196 void BSP_AddToTextureChain(msurface_t *surf, qboolean forEnt)
1197 {
1198 	int			map;
1199 	rscript_t	*rs_shader;
1200 	qboolean	is_dynamic = false;
1201 
1202 	// Special surfaces that need to be handled separately
1203 
1204 	if (surf->texinfo->flags & SURF_SKY)
1205 	{	// just adds to visible sky bounds
1206 		R_AddSkySurface (surf);
1207 		return;
1208 	}
1209 
1210 	if (SurfaceIsTranslucent(surf) && !SurfaceIsAlphaBlended(surf))
1211 	{	// add to the translucent chain
1212 		if (forEnt)
1213 		{
1214 			surf->texturechain = r_ent_alpha_surfaces;
1215 			r_ent_alpha_surfaces = surf;
1216 		}
1217 		else
1218 		{
1219 			surf->texturechain = r_alpha_surfaces;
1220 			r_alpha_surfaces = surf;
1221 		}
1222 		return;
1223 	}
1224 
1225 	if (surf->iflags & ISURF_DRAWTURB)
1226 	{	// add to the warped surfaces chain
1227 		if (forEnt)
1228 		{
1229 			surf->texturechain = r_ent_warp_surfaces;
1230 			r_ent_warp_surfaces = surf;
1231 		}
1232 		else
1233 		{
1234 			surf->texturechain = r_warp_surfaces;
1235 			r_warp_surfaces = surf;
1236 		}
1237 		return;
1238 	}
1239 
1240 
1241 	// The rest of the function handles most ordinary surfaces: normalmapped,
1242 	// non-normalmapped, and dynamically lit surfaces. As these three cases
1243 	// are the most common, they are the most optimized-- grouped by texinfo,
1244 	// etc.
1245 
1246 	// XXX: we could require gl_bspnormalmaps here, but that would result in
1247 	// weird inconsistency with only meshes lighting up. Better to fall back
1248 	// on GLSL for dynamically lit surfaces, even with gl_bspnormalmaps 0.
1249 	if(r_newrefdef.num_dlights && gl_state.glsl_shaders && gl_glsl_shaders->integer && gl_dynamic->integer)
1250 	{
1251 		// dynamic this frame or dynamic previously
1252 		if ( ( surf->dlightframe == r_framecount ) )
1253 		{
1254 			if ( !SurfaceHasNoLightmap(surf) )
1255 				is_dynamic = true;
1256 		}
1257 	}
1258 
1259 	// reviving the ancient lightstyle system
1260 	if ( !SurfaceHasNoLightmap(surf) )
1261 	{
1262 		for ( map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++ )
1263 		{
1264 			// Chain of surfaces that may need to have their lightmaps updated
1265 			// in future frames (for dealing with r_optimize)
1266 			if (surf->styles[map] != 0)
1267 			{
1268 				if (!forEnt)
1269 				{
1270 					surf->flickerchain = r_flicker_surfaces;
1271 					r_flicker_surfaces = surf;
1272 					break;
1273 				}
1274 				if ( r_newrefdef.lightstyles[surf->styles[map]].white != surf->cached_light[map])
1275 				{
1276 					BSP_UpdateSurfaceLightmap (surf);
1277 					break;
1278 				}
1279 			}
1280 		}
1281 	}
1282 
1283 	if(is_dynamic && surf->texinfo->has_normalmap
1284 		&& gl_state.glsl_shaders && gl_glsl_shaders->integer) //always glsl for dynamic if it has a normalmap
1285 	{
1286 		if (forEnt)
1287 		{
1288 			surf->texturechain = surf->texinfo->equiv->e_glsl_dynamic_surfaces;
1289 			surf->texinfo->equiv->e_glsl_dynamic_surfaces = surf;
1290 		}
1291 		else
1292 		{
1293 			surf->texturechain = surf->texinfo->equiv->w_glsl_dynamic_surfaces;
1294 			surf->texinfo->equiv->w_glsl_dynamic_surfaces = surf;
1295 		}
1296 	}
1297 	else if(gl_bspnormalmaps->integer
1298 			&& surf->texinfo->has_heightmap
1299 			&& surf->texinfo->has_normalmap
1300 			&& gl_state.glsl_shaders && gl_glsl_shaders->integer)
1301 	{
1302 		if (forEnt)
1303 		{
1304 			surf->texturechain = surf->texinfo->equiv->e_glsl_surfaces;
1305 			surf->texinfo->equiv->e_glsl_surfaces = surf;
1306 		}
1307 		else
1308 		{
1309 			surf->texturechain = surf->texinfo->equiv->w_glsl_surfaces;
1310 			surf->texinfo->equiv->w_glsl_surfaces = surf;
1311 		}
1312 	}
1313 	else
1314 	{
1315 		if (forEnt)
1316 		{
1317 			surf->texturechain = surf->texinfo->equiv->e_lightmap_surfaces;
1318 			surf->texinfo->equiv->e_lightmap_surfaces = surf;
1319 		}
1320 		else
1321 		{
1322 			surf->texturechain = surf->texinfo->equiv->w_lightmap_surfaces;
1323 			surf->texinfo->equiv->w_lightmap_surfaces = surf;
1324 		}
1325 	}
1326 
1327 	// Add to the rscript chain if there is actually a shader
1328 	// TODO: investigate the possibility of doing this for brush models as
1329 	// well-- might cause problems with caustics and brush models only half
1330 	// submerged?
1331 	if(!forEnt && r_shaders->integer)
1332 	{
1333 		rs_shader = (rscript_t *)surf->texinfo->image->script;
1334 		if(rs_shader || (surf->iflags & ISURF_UNDERWATER))
1335 		{
1336 			surf->rscriptchain = r_rscript_surfaces;
1337 			r_rscript_surfaces = surf;
1338 		}
1339 	}
1340 }
1341 
1342 /*
1343 ================
1344 BSP_DrawTextureChains
1345 
1346 Draw ALL surfaces for either the current entity or the world model. If drawing
1347 entity surfaces, reset the linked lists afterward.
1348 ================
1349 */
BSP_DrawTextureChains(qboolean forEnt)1350 void BSP_DrawTextureChains (qboolean forEnt)
1351 {
1352 	msurface_t	*flickersurf;
1353 	int			map;
1354 
1355 	if (!forEnt)
1356 	{
1357 		R_KillVArrays (); // TODO: check if necessary
1358 
1359 		for (flickersurf = r_flicker_surfaces; flickersurf != NULL; flickersurf = flickersurf->flickerchain)
1360 		{
1361 			for ( map = 0; map < MAXLIGHTMAPS && flickersurf->styles[map] != 255; map++ )
1362 			{
1363 				if ( r_newrefdef.lightstyles[flickersurf->styles[map]].white != flickersurf->cached_light[map])
1364 				{
1365 					BSP_UpdateSurfaceLightmap (flickersurf);
1366 					break;
1367 				}
1368 			}
1369 		}
1370 	}
1371 
1372 	// Setup GL state for lightmap render
1373 	// (TODO: only necessary for fixed-function pipeline?)
1374 
1375 	GL_EnableMultitexture( true );
1376 
1377 	GL_SelectTexture( GL_TEXTURE0);
1378 
1379 	if ( !gl_config.mtexcombine )
1380 	{
1381 		GL_TexEnv( GL_REPLACE );
1382 			GL_SelectTexture( GL_TEXTURE1);
1383 
1384 		if ( gl_lightmap->integer )
1385 			GL_TexEnv( GL_REPLACE );
1386 		else
1387 			GL_TexEnv( GL_MODULATE );
1388 	}
1389 	else
1390 	{
1391 		GL_TexEnv ( GL_COMBINE_EXT );
1392 		qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE );
1393 		qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE );
1394 		qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE );
1395 		qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE );
1396 		GL_SelectTexture( GL_TEXTURE1 );
1397 		GL_TexEnv ( GL_COMBINE_EXT );
1398 
1399 		if ( gl_lightmap->integer )
1400 		{
1401 			qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE );
1402 			qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE );
1403 			qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE );
1404 			qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE );
1405 		}
1406 		else
1407 		{
1408 			qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE );
1409 			qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE );
1410 			qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT );
1411 			qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE );
1412 			qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE );
1413 			qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_EXT );
1414 		}
1415 
1416 		if ( r_overbrightbits->value )
1417 			qglTexEnvi ( GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, r_overbrightbits->value );
1418 	}
1419 
1420 	// render all fixed-function surfaces
1421 	BSP_DrawNonGLSLSurfaces(forEnt);
1422 
1423 	// render all GLSL surfaces, including normalmapped and dynamically lit
1424 	if(gl_state.glsl_shaders && gl_glsl_shaders->integer)
1425 	{
1426 		glUseProgramObjectARB( g_programObj );
1427 		glUniform3fARB( g_location_eyePos, r_origin[0], r_origin[1], r_origin[2] );
1428 		glUniform1iARB( g_location_fog, map_fog);
1429 		glUniform3fARB( g_location_staticLightPosition, r_worldLightVec[0], r_worldLightVec[1], r_worldLightVec[2]);
1430 		BSP_DrawGLSLSurfaces(forEnt);
1431 		BSP_DrawGLSLDynamicSurfaces(forEnt);
1432 		glUseProgramObjectARB( 0 );
1433 	}
1434 
1435 	// this has to come last because it messes with GL state
1436 	BSP_DrawWarpSurfaces (forEnt);
1437 
1438 	GL_EnableMultitexture( false );
1439 }
1440 
1441 
1442 
1443 /*
1444 =============================================================
1445 
1446 	BRUSH MODELS
1447 
1448 =============================================================
1449 */
1450 
1451 /*
1452 =================
1453 BSP_DrawInlineBModel
1454 
1455 Picks which of the current entity's surfaces face toward the camera, and calls
1456 BSP_AddToTextureChain on those.
1457 =================
1458 */
BSP_DrawInlineBModel(void)1459 void BSP_DrawInlineBModel ( void )
1460 {
1461 	int			i;
1462 	cplane_t	*pplane;
1463 	float		dot;
1464 	msurface_t	*psurf;
1465 
1466 	R_PushDlightsForBModel ( currententity );
1467 
1468 	if ( currententity->flags & RF_TRANSLUCENT )
1469 	{
1470 		qglEnable (GL_BLEND);
1471 		qglColor4f (1,1,1,0.25);
1472 		GL_TexEnv( GL_MODULATE );
1473 	}
1474 
1475 	psurf = &currentmodel->surfaces[currentmodel->firstmodelsurface];
1476 	for (i=0 ; i<currentmodel->nummodelsurfaces ; i++, psurf++)
1477 	{
1478 		if (psurf->texinfo->flags & SURF_NODRAW)
1479 			continue; //can skip dot product stuff
1480 			// TODO: remove these at load-time for inline models?
1481 
1482 		// find which side of the plane we are on
1483 		pplane = psurf->plane;
1484 		dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
1485 
1486 		// draw the polygon
1487 		if (((psurf->iflags & ISURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
1488 			(!(psurf->iflags & ISURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
1489 		{
1490 			// TODO: do this once at load time
1491 			psurf->entity = currententity;
1492 
1493 			BSP_AddToTextureChain( psurf, true );
1494 
1495 			psurf->visframe = r_framecount;
1496 		}
1497 	}
1498 
1499 	BSP_DrawTextureChains (true);
1500 
1501 	qglDisable (GL_BLEND);
1502 	qglColor4f (1,1,1,1);
1503 	GL_TexEnv( GL_REPLACE );
1504 
1505 	R_KillVArrays ();
1506 }
1507 
1508 /*
1509 =================
1510 R_DrawBrushModel
1511 =================
1512 */
R_DrawBrushModel(void)1513 void R_DrawBrushModel ( void )
1514 {
1515 	vec3_t		mins, maxs;
1516 	int			i;
1517 	qboolean	rotated;
1518 
1519 	if (currentmodel->nummodelsurfaces == 0)
1520 		return;
1521 
1522 	gl_state.currenttextures[0] = gl_state.currenttextures[1] = -1;
1523 
1524 	if (currententity->angles[0] || currententity->angles[1] || currententity->angles[2])
1525 	{
1526 		rotated = true;
1527 		for (i=0 ; i<3 ; i++)
1528 		{
1529 			mins[i] = currententity->origin[i] - currentmodel->radius;
1530 			maxs[i] = currententity->origin[i] + currentmodel->radius;
1531 		}
1532 	}
1533 	else
1534 	{
1535 		rotated = false;
1536 		VectorAdd (currententity->origin, currentmodel->mins, mins);
1537 		VectorAdd (currententity->origin, currentmodel->maxs, maxs);
1538 	}
1539 
1540 	if (R_CullBox (mins, maxs)) {
1541 		return;
1542 	}
1543 
1544 	qglColor3f (1,1,1);
1545 
1546 	VectorSubtract (r_newrefdef.vieworg, currententity->origin, modelorg);
1547 
1548 	if (rotated)
1549 	{
1550 		vec3_t	temp;
1551 		vec3_t	forward, right, up;
1552 
1553 		VectorCopy (modelorg, temp);
1554 		AngleVectors (currententity->angles, forward, right, up);
1555 		modelorg[0] = DotProduct (temp, forward);
1556 		modelorg[1] = -DotProduct (temp, right);
1557 		modelorg[2] = DotProduct (temp, up);
1558 	}
1559 
1560     qglPushMatrix ();
1561 	currententity->angles[0] = -currententity->angles[0];	// stupid quake bug
1562 	currententity->angles[2] = -currententity->angles[2];	// stupid quake bug
1563 	R_RotateForEntity (currententity);
1564 	currententity->angles[0] = -currententity->angles[0];	// stupid quake bug
1565 	currententity->angles[2] = -currententity->angles[2];	// stupid quake bug
1566 
1567 	BSP_DrawInlineBModel ();
1568 
1569 	qglPopMatrix ();
1570 }
1571 
1572 
1573 
1574 /*
1575 =============================================================
1576 
1577 	WORLD MODEL
1578 
1579 =============================================================
1580 */
1581 
1582 /*
1583 =================
1584 R_CullBox
1585 
1586 Returns true if the box is completely outside the frustum
1587 
1588 Variant: uses clipflags
1589 =================
1590 */
R_CullBox_ClipFlags(vec3_t mins,vec3_t maxs,int clipflags)1591 qboolean R_CullBox_ClipFlags (vec3_t mins, vec3_t maxs, int clipflags)
1592 {
1593 	int		i;
1594 	cplane_t *p;
1595 
1596 	for (i=0,p=frustum ; i<4; i++,p++)
1597 	{
1598 		if (!(clipflags  & (1<<i)))
1599 			continue;
1600 		switch (p->signbits)
1601 		{
1602 		case 0:
1603 			if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
1604 				return true;
1605 			break;
1606 		case 1:
1607 			if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
1608 				return true;
1609 			break;
1610 		case 2:
1611 			if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
1612 				return true;
1613 			break;
1614 		case 3:
1615 			if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
1616 				return true;
1617 			break;
1618 		case 4:
1619 			if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
1620 				return true;
1621 			break;
1622 		case 5:
1623 			if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
1624 				return true;
1625 			break;
1626 		case 6:
1627 			if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
1628 				return true;
1629 			break;
1630 		case 7:
1631 			if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
1632 				return true;
1633 			break;
1634 		default:
1635 			return false;
1636 		}
1637 	}
1638 
1639 	return false;
1640 }
1641 
1642 /*
1643 ================
1644 BSP_RecursiveWorldNode
1645 
1646 Goes through the entire world (the BSP tree,) picks out which surfaces should
1647 be drawn, and calls BSP_AddToTextureChain on each.
1648 
1649 node: the BSP node to work on
1650 clipflags: indicate which planes of the frustum may intersect the node
1651 
1652 Since each node is inside its parent in 3D space, if a frustum plane can be
1653 shown not to intersect a node at all, then it won't intersect either of its
1654 children.
1655 ================
1656 */
BSP_RecursiveWorldNode(mnode_t * node,int clipflags)1657 void BSP_RecursiveWorldNode (mnode_t *node, int clipflags)
1658 {
1659 	int			c, side;
1660 	cplane_t	*plane;
1661 	msurface_t	*surf, **mark;
1662 	mleaf_t		*pleaf;
1663 	float		dot;
1664 
1665 	if (node->contents == CONTENTS_SOLID)
1666 		return;		// solid
1667 
1668 	if (node->visframe != r_visframecount)
1669 		return;
1670 
1671 	// if a leaf node, draw stuff (pt 1)
1672 	c = 0;
1673 	if (node->contents != -1)
1674 	{
1675 		pleaf = (mleaf_t *)node;
1676 
1677 		if (! (c = pleaf->nummarksurfaces) )
1678 			return;
1679 
1680 		// check for door connected areas
1681 		if (! (r_newrefdef.areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) )
1682 			return;		// not visible
1683 
1684 		mark = pleaf->firstmarksurface;
1685 	}
1686 
1687 	if (!r_nocull->integer && clipflags)
1688 	{
1689 		int i, clipped;
1690 		cplane_t *clipplane;
1691 
1692 		for (i=0,clipplane=frustum ; i<4 ; i++,clipplane++)
1693 		{
1694 			if (!(clipflags  & (1<<i)))
1695 				continue;
1696 			clipped = BoxOnPlaneSide (node->minmaxs, node->minmaxs+3, clipplane);
1697 
1698 			if (clipped == 1)
1699 				clipflags &= ~(1<<i);	// node is entirely on screen
1700 			else if (clipped == 2)
1701 				return;					// fully clipped
1702 		}
1703 	}
1704 
1705 	//if a leaf node, draw stuff (pt 2)
1706 	if (c != 0)
1707 	{
1708 		do
1709 		{
1710 			(*mark++)->visframe = r_framecount;
1711 		} while (--c);
1712 
1713 		return;
1714 	}
1715 
1716 	// node is just a decision point, so go down the apropriate sides
1717 
1718 	// find which side of the node we are on
1719 	plane = node->plane;
1720 
1721 	switch (plane->type)
1722 	{
1723 	case PLANE_X:
1724 		dot = modelorg[0];
1725 		break;
1726 	case PLANE_Y:
1727 		dot = modelorg[1];
1728 		break;
1729 	case PLANE_Z:
1730 		dot = modelorg[2];
1731 		break;
1732 	default:
1733 		dot = DotProduct (modelorg, plane->normal);
1734 		break;
1735 	}
1736 
1737 	side = dot < plane->dist;
1738 
1739 	// recurse down the children, front side first
1740 	BSP_RecursiveWorldNode (node->children[side], clipflags);
1741 
1742 	// draw stuff
1743 	for ( c = node->numsurfaces, surf = r_worldmodel->surfaces + node->firstsurface; c ; c--, surf++)
1744 	{
1745 		if (surf->visframe != r_framecount)
1746 			continue;
1747 
1748 		/* XXX: this doesn't seem to cull any surfaces AT ALL when positioned
1749 		 * here! The surf->visframe check seems to catch any back-facing
1750 		 * surfaces, but the back-facing surface check seems to allow some
1751 		 * surfaces which are later caught by the surf->visframe check. So the
1752 		 * visframe check renders the planeback check redundant and useless.
1753 		 * I'm pretty sure it's because the map compiler structures the BSP
1754 		 * tree in such a way as to avoid back-facing surfaces being drawn.
1755 		 * -M
1756 		if ( (surf->flags & SURF_PLANEBACK) != side )
1757 			continue;		// wrong side
1758 		*/
1759 
1760 		if (clipflags != 0 && !( surf->iflags & ISURF_DRAWTURB ))
1761 		{
1762 			if (R_CullBox_ClipFlags (surf->mins, surf->maxs, clipflags))
1763 				continue;
1764 		}
1765 
1766 		// the polygon is visible, so add it to the appropriate linked list
1767 		// list
1768 		BSP_AddToTextureChain( surf, false );
1769 	}
1770 
1771 	// recurse down the back side
1772 	BSP_RecursiveWorldNode (node->children[!side], clipflags);
1773 }
1774 
1775 /*
1776 =============
1777 R_CalcWorldLights - this is the fallback for non deluxmapped bsp's
1778 =============
1779 */
R_CalcWorldLights(void)1780 void R_CalcWorldLights( void )
1781 {
1782 	int		i, j;
1783 	vec3_t	lightAdd, temp;
1784 	float	dist, weight;
1785 	int		numlights = 0;
1786 
1787 	if(gl_glsl_shaders->integer && gl_state.glsl_shaders)
1788 	{
1789 		//get light position relative to player's position
1790 		VectorClear(lightAdd);
1791 		for (i = 0; i < r_lightgroups; i++)
1792 		{
1793 			VectorSubtract(r_origin, LightGroups[i].group_origin, temp);
1794 			dist = VectorLength(temp);
1795 			if(dist == 0)
1796 				dist = 1;
1797 			dist = dist*dist;
1798 			weight = (int)250000/(dist/(LightGroups[i].avg_intensity+1.0f));
1799 			for(j = 0; j < 3; j++)
1800 				lightAdd[j] += LightGroups[i].group_origin[j]*weight;
1801 			numlights+=weight;
1802 		}
1803 
1804 		if(numlights > 0.0)
1805 		{
1806 			for(i = 0; i < 3; i++)
1807 				r_worldLightVec[i] = (lightAdd[i]/numlights + r_origin[i])/2.0;
1808 		}
1809 	}
1810 }
1811 
1812 /*
1813 =============
1814 R_DrawWorldSurfs
1815 =============
1816 */
R_DrawWorldSurfs(void)1817 void R_DrawWorldSurfs (void)
1818 {
1819 	if (!r_drawworld->integer)
1820 		return;
1821 
1822 	if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
1823 		return;
1824 
1825 	if (r_newrefdef.areabits == NULL)
1826 	{
1827 		Com_Printf ("WARN: No area bits!\n");
1828 		return;
1829 	}
1830 
1831 	qglColor3f (1,1,1);
1832 
1833 	BSP_DrawTextureChains ( false );
1834 
1835 	R_InitSun();
1836 
1837 	qglDepthMask(0);
1838 	R_DrawSkyBox();
1839 	qglDepthMask(1);
1840 
1841 	R_DrawRSSurfaces();
1842 }
1843 
1844 /*
1845 ===============
1846 R_MarkLeaves
1847 
1848 Mark the leaves and nodes that are in the PVS for the current
1849 cluster
1850 ===============
1851 */
R_MarkLeaves(void)1852 void R_MarkLeaves (void)
1853 {
1854 	static byte	*vis;
1855 	static byte	fatvis[MAX_MAP_LEAFS/8];
1856 	mnode_t	*node;
1857 	int		i, c;
1858 	mleaf_t	*leaf;
1859 	int		cluster;
1860 	static int minleaf_allareas, maxleaf_allareas;
1861 	int minleaf, maxleaf;
1862 
1863 	if	(	r_oldviewcluster == r_viewcluster &&
1864 			r_oldviewcluster2 == r_viewcluster2 &&
1865 			!r_novis->integer && r_viewcluster != -1 &&
1866 			!r_newrefdef.areabits_changed)
1867 		return;
1868 	r_newrefdef.areabits_changed = false;
1869 
1870 	// development aid to let you run around and see exactly where
1871 	// the pvs ends
1872 	if (gl_lockpvs->integer)
1873 		return;
1874 
1875 	r_oldviewcluster = r_viewcluster;
1876 	r_oldviewcluster2 = r_viewcluster2;
1877 
1878 	if (r_novis->integer || r_viewcluster == -1 || !r_worldmodel->vis)
1879 	{
1880 		r_visframecount++;
1881 		// mark everything
1882 		for (i=0 ; i<r_worldmodel->numleafs ; i++)
1883 			r_worldmodel->leafs[i].visframe = r_visframecount;
1884 		for (i=0 ; i<r_worldmodel->numnodes ; i++)
1885 			r_worldmodel->nodes[i].visframe = r_visframecount;
1886 		return;
1887 	}
1888 
1889 	vis = Mod_ClusterPVS (r_viewcluster, r_worldmodel);
1890 	minleaf_allareas = r_viewleaf->minPVSleaf;
1891 	maxleaf_allareas = r_viewleaf->maxPVSleaf;
1892 	// may have to combine two clusters because of solid water boundaries
1893 	if (r_viewcluster2 != r_viewcluster)
1894 	{
1895 		if (r_viewleaf2->minPVSleaf < minleaf_allareas)
1896 			minleaf_allareas = r_viewleaf2->minPVSleaf;
1897 		if (r_viewleaf2->maxPVSleaf > maxleaf_allareas)
1898 			maxleaf_allareas = r_viewleaf2->maxPVSleaf;
1899 		memcpy (fatvis, vis, (r_worldmodel->numleafs+7)/8);
1900 		vis = Mod_ClusterPVS (r_viewcluster2, r_worldmodel);
1901 		c = (r_worldmodel->numleafs+31)/32;
1902 		for (i=0 ; i<c ; i++)
1903 			((int *)fatvis)[i] |= ((int *)vis)[i];
1904 		vis = fatvis;
1905 	}
1906 
1907 	r_visframecount++;
1908 
1909 	minleaf = minleaf_allareas;
1910 	maxleaf = maxleaf_allareas;
1911 
1912 	//restrict leaf range further to the range leafs in connected areas.
1913 	{
1914 		int areamax = 0;
1915 		int areamin = r_worldmodel->numleafs;
1916 		for (i = 0; i < r_worldmodel->num_areas; i++)
1917 		{
1918 			if (r_newrefdef.areabits[i>>3] & (1<<(i&7)))
1919 			{
1920 				if (r_worldmodel->area_max_leaf[i] > areamax)
1921 					areamax = r_worldmodel->area_max_leaf[i];
1922 				if (r_worldmodel->area_min_leaf[i] < areamin)
1923 					areamin = r_worldmodel->area_min_leaf[i];
1924 			}
1925 		}
1926 		if (areamin < areamax)
1927 		{
1928 			if (areamin > minleaf)
1929 				minleaf = areamin;
1930 			if (areamax < maxleaf)
1931 				maxleaf = areamax;
1932 		}
1933 	}
1934 
1935 	for (i=minleaf,leaf=r_worldmodel->leafs+minleaf ; i<=maxleaf ; i++, leaf++)
1936 	{
1937 		cluster = leaf->cluster;
1938 		if (cluster == -1)
1939 			continue;
1940 		if (vis[cluster>>3] & (1<<(cluster&7)))
1941 		{
1942 			node = (mnode_t *)leaf;
1943 			do
1944 			{
1945 				if (node->visframe == r_visframecount)
1946 					break;
1947 				node->visframe = r_visframecount;
1948 				node = node->parent;
1949 			} while (node);
1950 		}
1951 	}
1952 }
1953 
1954 /*
1955 ===============
1956 R_MarkWorldSurfs
1957 
1958 Mark all surfaces that will need to be drawn this frame
1959 ===============
1960 */
R_MarkWorldSurfs(void)1961 void R_MarkWorldSurfs (void)
1962 {
1963 	static entity_t	ent;
1964 	static int		old_visframecount, old_dlightcount, last_bsp_time;
1965 	static vec3_t	old_origin, old_angle;
1966 	vec3_t			delta_origin, delta_angle;
1967 	qboolean		do_bsp;
1968 	int				cur_ms;
1969 
1970 	if (!r_drawworld->integer)
1971 		return;
1972 
1973 	if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
1974 		return;
1975 
1976 	if (r_newrefdef.areabits == NULL)
1977 	{
1978 		Com_Printf ("WARN: No area bits!\n");
1979 		return;
1980 	}
1981 
1982 	R_MarkLeaves ();
1983 
1984 	currentmodel = r_worldmodel;
1985 
1986 	VectorCopy (r_newrefdef.vieworg, modelorg);
1987 
1988 	// auto cycle the world frame for texture animation
1989 	memset (&ent, 0, sizeof(ent));
1990 	ent.frame = (int)(r_newrefdef.time*2);
1991 	currententity = &ent;
1992 
1993 	gl_state.currenttextures[0] = gl_state.currenttextures[1] = -1;
1994 
1995 	R_CalcWorldLights();
1996 
1997 	// r_optimize: only re-recurse the BSP tree if the player has moved enough
1998 	// to matter.
1999 	VectorSubtract (r_origin, old_origin, delta_origin);
2000 	VectorSubtract (r_newrefdef.viewangles, old_angle, delta_angle);
2001 	do_bsp =	old_visframecount != r_visframecount ||
2002 				VectorLength (delta_origin) > 5.0 ||
2003 				VectorLength (delta_angle) > 2.0 ||
2004 				r_newrefdef.num_dlights != 0 ||
2005 				old_dlightcount != 0 ||
2006 				!r_optimize->integer || draw_sun;
2007 
2008 	cur_ms = Sys_Milliseconds ();
2009 
2010 	// After a certain amount of time, increase the sensitivity to movement
2011 	// and angle. If we go too long without re-recursing the BSP tree, it
2012 	// means the player is either moving very slowly or not moving at all. If
2013 	// the player is moving slowly enough, it can catch the r_optimize code
2014 	// napping and cause artefacts, so we should be extra vigilant just in
2015 	// case. Something you basically have to do on purpose, but we go the
2016 	// extra mile.
2017 	if (r_optimize->integer && !do_bsp)
2018 	{
2019 		// be sure to handle integer overflow of the millisecond counter
2020 		if (cur_ms < last_bsp_time || last_bsp_time+100 < cur_ms)
2021 			do_bsp =	VectorLength (delta_origin) > 0.5 ||
2022 						VectorLength (delta_angle) > 0.2;
2023 
2024 	}
2025 
2026 	if (do_bsp)
2027 	{
2028 		R_ClearSkyBox ();
2029 		BSP_ClearWorldTextureChains ();
2030 		BSP_RecursiveWorldNode (r_worldmodel->nodes, 15);
2031 
2032 		old_visframecount = r_visframecount;
2033 		VectorCopy (r_origin, old_origin);
2034 		VectorCopy (r_newrefdef.viewangles, old_angle);
2035 		last_bsp_time = cur_ms;
2036 	}
2037 	old_dlightcount = r_newrefdef.num_dlights;
2038 }
2039 
2040 
2041 
2042 /*
2043 =============================================================================
2044 
2045   LIGHTMAP ALLOCATION
2046 
2047   TODO: move this to another file, this is load-time stuff that doesn't run
2048   every frame.
2049 
2050 =============================================================================
2051 */
2052 
LM_InitBlock(void)2053 static void LM_InitBlock (void)
2054 {
2055 	memset( gl_lms.allocated, 0, sizeof( gl_lms.allocated ) );
2056 }
2057 
2058 // Upload the current lightmap data to OpenGL, then clear it and prepare for
2059 // the next lightmap texture to be filled with data.
2060 // TODO: With HD lightmaps, are mipmaps a good idea here?
2061 // TODO: Opportunistically make lightmap texture smaller if not all is used?
2062 // Will require delaying lightmap texcoords for all surfaces until after
2063 // upload.
LM_UploadBlock(void)2064 static void LM_UploadBlock (void)
2065 {
2066 	int texture = gl_lms.current_lightmap_texture;
2067 
2068 	GL_SelectTexture (GL_TEXTURE0);
2069 	// FIXME: OH FFS this is so stupid: tell the GL_Bind batching mechanism
2070 	// that texture unit 0 has been re-bound, as it most certainly has been.
2071 	gl_state.currenttextures[gl_state.currenttmu] = -1;
2072 	GL_Bind( gl_state.lightmap_textures + texture );
2073 	qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2074 	qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2075 
2076 	qglTexImage2D( GL_TEXTURE_2D,
2077 				   0,
2078 				   GL_RGBA,
2079 				   LIGHTMAP_SIZE, LIGHTMAP_SIZE,
2080 				   0,
2081 				   GL_LIGHTMAP_FORMAT,
2082 				   GL_UNSIGNED_INT_8_8_8_8_REV,
2083 				   gl_lms.lightmap_buffer );
2084 
2085 #if 0
2086 	height = 0;
2087 	for (i = 0; i < LIGHTMAP_SIZE; i++)
2088 	{
2089 		if (gl_lms.allocated[i] > height)
2090 			height = gl_lms.allocated[i];
2091 	}
2092 
2093 	Com_Printf (" LIGHTMAP %d HEIGHT %d\n", gl_lms.current_lightmap_texture, height);
2094 #endif
2095 
2096 	if ( ++gl_lms.current_lightmap_texture == MAX_LIGHTMAPS )
2097 		Com_Error( ERR_DROP, "LM_UploadBlock() - MAX_LIGHTMAPS exceeded\n" );
2098 }
2099 
2100 // LM_AllocBlock - given a certain size rectangle, allocates space inside the
2101 // lightmap texture atlas.
2102 // Returns a texture number and the position inside it.
2103 // TODO: there are some clever tricks I can think of to pack these more
2104 // tightly: opportunistically rotating lightmap textures by 90 degrees,
2105 // wrapping the lightmap textures around the edges of the atlas, and even
2106 // recognizing that not all surfaces are rectangular.
LM_AllocBlock(int w,int h,int * x,int * y)2107 static qboolean LM_AllocBlock (int w, int h, int *x, int *y)
2108 {
2109 	int		i, j;
2110 	int		best, best2;
2111 
2112 	best = LIGHTMAP_SIZE;
2113 
2114 	for (i=0 ; i<LIGHTMAP_SIZE-w ; i++)
2115 	{
2116 		best2 = 0;
2117 
2118 		for (j=0 ; j<w ; j++)
2119 		{
2120 			if (gl_lms.allocated[i+j] >= best)
2121 				break;
2122 			if (gl_lms.allocated[i+j] > best2)
2123 				best2 = gl_lms.allocated[i+j];
2124 		}
2125 		if (j == w)
2126 		{	// this is a valid spot
2127 			*x = i;
2128 			*y = best = best2;
2129 		}
2130 	}
2131 
2132 	if (best + h > LIGHTMAP_SIZE)
2133 		return false;
2134 
2135 	for (i=0 ; i<w ; i++)
2136 		gl_lms.allocated[*x + i] = best + h;
2137 
2138 	return true;
2139 }
2140 
2141 /*
2142 ================
2143 BSP_BuildPolygonFromSurface
2144 ================
2145 */
BSP_BuildPolygonFromSurface(msurface_t * fa,float xscale,float yscale,int light_s,int light_t,int firstedge,int lnumverts)2146 void BSP_BuildPolygonFromSurface(msurface_t *fa, float xscale, float yscale, int light_s, int light_t, int firstedge, int lnumverts)
2147 {
2148 	int			i, lindex;
2149 	medge_t		*r_pedge;
2150 	float		*vec;
2151 	float		s, t;
2152 	glpoly_t	*poly;
2153 
2154 	vec3_t surfmaxs = {-99999999, -99999999, -99999999};
2155 	vec3_t surfmins = {99999999, 99999999, 99999999};
2156 
2157 	//
2158 	// draw texture
2159 	//
2160 	poly = Hunk_Alloc (sizeof(glpoly_t) + (lnumverts-4) * VERTEXSIZE*sizeof(float));
2161 	poly->next = fa->polys;
2162 	poly->numverts = lnumverts;
2163 	fa->polys = poly;
2164 
2165 	for (i=0 ; i<lnumverts ; i++)
2166 	{
2167 		lindex = currentmodel->surfedges[firstedge + i];
2168 
2169 		if (lindex > 0)
2170 		{
2171 			r_pedge = &currentmodel->edges[lindex];
2172 			vec = currentmodel->vertexes[r_pedge->v[0]].position;
2173 		}
2174 		else
2175 		{
2176 			r_pedge = &currentmodel->edges[-lindex];
2177 			vec = currentmodel->vertexes[r_pedge->v[1]].position;
2178 		}
2179 
2180 		s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
2181 		s /= fa->texinfo->image->width;
2182 
2183 		t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
2184 		t /= fa->texinfo->image->height;
2185 
2186 		VectorCopy (vec, poly->verts[i]);
2187 		poly->verts[i][3] = s;
2188 		poly->verts[i][4] = t;
2189 
2190 		// set bbox for the surf used for culling
2191 		if (vec[0] > surfmaxs[0]) surfmaxs[0] = vec[0];
2192 		if (vec[1] > surfmaxs[1]) surfmaxs[1] = vec[1];
2193 		if (vec[2] > surfmaxs[2]) surfmaxs[2] = vec[2];
2194 
2195 		if (vec[0] < surfmins[0]) surfmins[0] = vec[0];
2196 		if (vec[1] < surfmins[1]) surfmins[1] = vec[1];
2197 		if (vec[2] < surfmins[2]) surfmins[2] = vec[2];
2198 
2199 		//
2200 		// lightmap texture coordinates
2201 		//
2202 		s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
2203 		s -= fa->texturemins[0];
2204 		s += light_s*xscale;
2205 		s += xscale/2.0;
2206 		s /= LIGHTMAP_SIZE*xscale;
2207 
2208 		t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
2209 		t -= fa->texturemins[1];
2210 		t += light_t*yscale;
2211 		t += yscale/2.0;
2212 		t /= LIGHTMAP_SIZE*yscale;
2213 
2214 		poly->verts[i][5] = s;
2215 		poly->verts[i][6] = t;
2216 
2217 		//to do - check if needed
2218 		s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
2219 		s /= 128;
2220 
2221 		t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
2222 		t /= 128;
2223 
2224 		poly->verts[i][7] = s;
2225 		poly->verts[i][8] = t;
2226 
2227 	}
2228 #if 0 //SO PRETTY and useful for checking how much lightmap data is used up
2229 	if (lnumverts == 4)
2230 	{
2231 		poly->verts[0][5] = 1;
2232 		poly->verts[0][6] = 1;
2233 		poly->verts[1][5] = 1;
2234 		poly->verts[1][6] = 0;
2235 		poly->verts[2][5] = 0;
2236 		poly->verts[2][6] = 0;
2237 		poly->verts[3][5] = 0;
2238 		poly->verts[3][6] = 1;
2239 	}
2240 #endif
2241 
2242 	// store out the completed bbox
2243 	VectorCopy (surfmins, fa->mins);
2244 	VectorCopy (surfmaxs, fa->maxs);
2245 }
2246 
2247 /*
2248 ========================
2249 BSP_CreateSurfaceLightmap
2250 ========================
2251 */
BSP_CreateSurfaceLightmap(msurface_t * surf,int smax,int tmax,int * light_s,int * light_t)2252 void BSP_CreateSurfaceLightmap (msurface_t *surf, int smax, int tmax, int *light_s, int *light_t)
2253 {
2254 	byte	*base;
2255 
2256 	if (!surf->samples)
2257 		return;
2258 
2259 	if (surf->texinfo->flags & (SURF_SKY|SURF_WARP))
2260 		return; //may not need this?
2261 
2262 	if ( !LM_AllocBlock( smax, tmax, light_s, light_t ) )
2263 	{
2264 		LM_UploadBlock( );
2265 		LM_InitBlock();
2266 		if ( !LM_AllocBlock( smax, tmax, light_s, light_t ) )
2267 		{
2268 			Com_Error( ERR_FATAL, "Consecutive calls to LM_AllocBlock(%d,%d) failed\n", smax, tmax );
2269 		}
2270 	}
2271 
2272 	surf->lightmaptexturenum = gl_lms.current_lightmap_texture;
2273 
2274 	surf->lightmins[0] = *light_s;
2275 	surf->lightmins[1] = *light_t;
2276 	surf->lightmaxs[0] = smax;
2277 	surf->lightmaxs[1] = tmax;
2278 
2279 	base = gl_lms.lightmap_buffer;
2280 	base += ((*light_t) * LIGHTMAP_SIZE + *light_s) * LIGHTMAP_BYTES;
2281 
2282 	R_SetCacheState( surf );
2283 	R_BuildLightMap (surf, base, smax, tmax, LIGHTMAP_SIZE*LIGHTMAP_BYTES);
2284 }
2285 
BSP_UpdateSurfaceLightmap(msurface_t * surf)2286 void BSP_UpdateSurfaceLightmap (msurface_t *surf)
2287 {
2288 	R_SetCacheState (surf);
2289 	R_BuildLightMap (surf, gl_lms.lightmap_buffer, surf->lightmaxs[0], surf->lightmaxs[1], surf->lightmaxs[0]*LIGHTMAP_BYTES);
2290 
2291 	GL_SelectTexture (GL_TEXTURE0);
2292 	// FIXME: OH FFS this is so stupid: tell the GL_Bind batching mechanism
2293 	// that texture unit 0 has been re-bound, as it most certainly has been.
2294 	gl_state.currenttextures[gl_state.currenttmu] = -1;
2295 	GL_Bind( gl_state.lightmap_textures + surf->lightmaptexturenum );
2296 	qglTexSubImage2D( GL_TEXTURE_2D,
2297 					  0,
2298 					  surf->lightmins[0], surf->lightmins[1],
2299 					  surf->lightmaxs[0], surf->lightmaxs[1],
2300 					  GL_LIGHTMAP_FORMAT,
2301 					  GL_UNSIGNED_INT_8_8_8_8_REV,
2302 					  gl_lms.lightmap_buffer );
2303 }
2304 
2305 /*
2306 ==================
2307 BSP_BeginBuildingLightmaps
2308 ==================
2309 */
BSP_BeginBuildingLightmaps(model_t * m)2310 void BSP_BeginBuildingLightmaps (model_t *m)
2311 {
2312 	static lightstyle_t	lightstyles[MAX_LIGHTSTYLES];
2313 	int				i;
2314 
2315 	memset( gl_lms.allocated, 0, sizeof(gl_lms.allocated) );
2316 
2317 	r_framecount = 1;		// no dlightcache
2318 
2319 	GL_EnableMultitexture( true );
2320 	GL_SelectTexture( GL_TEXTURE1);
2321 
2322 	/*
2323 	** setup the base lightstyles so the lightmaps won't have to be regenerated
2324 	** the first time they're seen
2325 	*/
2326 	for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
2327 	{
2328 		lightstyles[i].rgb[0] = 1;
2329 		lightstyles[i].rgb[1] = 1;
2330 		lightstyles[i].rgb[2] = 1;
2331 		lightstyles[i].white = 3;
2332 	}
2333 	r_newrefdef.lightstyles = lightstyles;
2334 
2335 	if (!gl_state.lightmap_textures)
2336 		gl_state.lightmap_textures	= TEXNUM_LIGHTMAPS;
2337 
2338 	gl_lms.current_lightmap_texture = 1;
2339 
2340 }
2341 
2342 /*
2343 =======================
2344 BSP_EndBuildingLightmaps
2345 =======================
2346 */
BSP_EndBuildingLightmaps(void)2347 void BSP_EndBuildingLightmaps (void)
2348 {
2349 	LM_UploadBlock( );
2350 	GL_EnableMultitexture( false );
2351 }
2352 
2353 
2354 
2355 /*
2356 =============================================================================
2357 
2358   MINI MAP
2359 
2360   Draws a little 2D map in the corner of the HUD.
2361   TODO: do a bit more calculation at load time, right now this is a huge FPS
2362   hit.
2363 
2364 =============================================================================
2365 */
2366 
R_RecursiveRadarNode(mnode_t * node)2367 void R_RecursiveRadarNode (mnode_t *node)
2368 {
2369 	int			c, side;
2370 	cplane_t	*plane;
2371 	msurface_t	*surf, **mark;
2372 	mleaf_t		*pleaf;
2373 	float		dot,distance;
2374 	glpoly_t	*p;
2375 	float		*v;
2376 	int			i;
2377 
2378 	if (node->contents == CONTENTS_SOLID)	return;		// solid
2379 
2380 	if(r_minimap_zoom->value>=0.1) {
2381 		distance = 1024.0/r_minimap_zoom->value;
2382 	} else {
2383 		distance = 1024.0;
2384 	}
2385 
2386 
2387 	if ( r_origin[0]+distance < node->minmaxs[0] ||
2388 		 r_origin[0]-distance > node->minmaxs[3] ||
2389 		 r_origin[1]+distance < node->minmaxs[1] ||
2390 		 r_origin[1]-distance > node->minmaxs[4] ||
2391 		 r_origin[2]+256 < node->minmaxs[2] ||
2392 		 r_origin[2]-256 > node->minmaxs[5]) return;
2393 
2394 	// if a leaf node, draw stuff
2395 	if (node->contents != -1) {
2396 		pleaf = (mleaf_t *)node;
2397 		// check for door connected areas
2398 		if (! (r_newrefdef.areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) )
2399 			return; // not visible
2400 		mark = pleaf->firstmarksurface;
2401 		c = pleaf->nummarksurfaces;
2402 
2403 		if (c) {
2404 			do {
2405 				(*mark)->visframe = r_framecount;
2406 				mark++;
2407 			} while (--c);
2408 		}
2409 		return;
2410 	}
2411 
2412 // node is just a decision point, so go down the apropriate sides
2413 // find which side of the node we are on
2414 	plane = node->plane;
2415 
2416 	switch (plane->type) {
2417 	case PLANE_X:
2418 		dot = modelorg[0] - plane->dist;
2419 		break;
2420 	case PLANE_Y:
2421 		dot = modelorg[1] - plane->dist;
2422 		break;
2423 	case PLANE_Z:
2424 		dot = modelorg[2] - plane->dist;
2425 		break;
2426 	default:
2427 		dot = DotProduct (modelorg, plane->normal) - plane->dist;
2428 		break;
2429 	}
2430 
2431 	if (dot >= 0) {
2432 		side = 0;
2433 	} else {
2434 		side = 1;
2435 	}
2436 
2437 // recurse down the children, front side first
2438 	R_RecursiveRadarNode (node->children[side]);
2439 
2440   if(plane->normal[2]) {
2441 		// draw stuff
2442 		if(plane->normal[2]>0) for ( c = node->numsurfaces, surf = r_worldmodel->surfaces + node->firstsurface; c ; c--, surf++)
2443 		{
2444 			if (surf->texinfo->flags & SURF_SKY){
2445 				continue;
2446 			}
2447 
2448 
2449 		}
2450 	} else {
2451 			qglDisable(GL_TEXTURE_2D);
2452 		for ( c = node->numsurfaces, surf = r_worldmodel->surfaces + node->firstsurface; c ; c--, surf++) {
2453 			float sColor,C[4];
2454 			if (surf->texinfo->flags & SURF_SKY) continue;
2455 
2456 			if (surf->texinfo->flags & (SURF_WARP|SURF_FLOWING|SURF_TRANS33|SURF_TRANS66)) {
2457 				sColor=0.5;
2458 			} else {
2459 				sColor=0;
2460 			}
2461 
2462 			for ( p = surf->polys; p; p = p->chain ) {
2463 				v = p->verts[0];
2464 				qglBegin(GL_LINE_STRIP);
2465 				for (i=0 ; i< p->numverts; i++, v+= VERTEXSIZE) {
2466 					C[3]= (v[2]-r_origin[2])/512.0;
2467 					if (C[3]>0) {
2468 
2469 						C[0]=0.5;
2470 						C[1]=0.5+sColor;
2471 						C[2]=0.5;
2472 						C[3]=1-C[3];
2473 
2474 					}
2475 					   else
2476 					{
2477 						C[0]=0.5;
2478 						C[1]=sColor;
2479 						C[2]=0;
2480 						C[3]+=1;
2481 
2482 					}
2483 
2484 					if(C[3]<0) {
2485 						C[3]=0;
2486 
2487 					}
2488 					qglColor4fv(C);
2489 					qglVertex3fv (v);
2490 				}
2491 
2492 				qglEnd();
2493 			}
2494 		}
2495 		qglEnable(GL_TEXTURE_2D);
2496 
2497   }
2498 	// recurse down the back side
2499 	R_RecursiveRadarNode (node->children[!side]);
2500 
2501 
2502 }
2503 
2504 int			numRadarEnts=0;
2505 RadarEnt_t	RadarEnts[MAX_RADAR_ENTS];
2506 
R_DrawRadar(void)2507 void R_DrawRadar(void)
2508 {
2509 	int		i;
2510 	float	fS[4]={0,0,-1.0/512.0,0};
2511 
2512 	if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) return;
2513 	if(!r_minimap->integer) return;
2514 
2515 	if (!r_newrefdef.areabits) return;
2516 
2517 	qglViewport	(	r_newrefdef.x+r_newrefdef.width-r_minimap_size->value,
2518 					vid.height-r_newrefdef.y-r_newrefdef.height,
2519 					r_minimap_size->value, r_minimap_size->value);
2520 
2521 	qglDisable(GL_DEPTH_TEST);
2522   	qglMatrixMode(GL_PROJECTION);
2523 	qglPushMatrix();
2524 	qglLoadIdentity ();
2525 
2526 
2527 	if (r_minimap_style->integer) {
2528 		qglOrtho(-1024,1024,-1024,1024,-256,256);
2529 	} else {
2530 		qglOrtho(-1024,1024,-512,1536,-256,256);
2531 	}
2532 
2533 	qglMatrixMode(GL_MODELVIEW);
2534 	qglPushMatrix();
2535 	qglLoadIdentity ();
2536 
2537 
2538 		{
2539 		qglStencilMask(255);
2540 		qglClear(GL_STENCIL_BUFFER_BIT);
2541 		qglEnable(GL_STENCIL_TEST);
2542 		qglStencilFunc(GL_ALWAYS,4,4);
2543 		qglStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE);
2544 
2545 
2546 		GLSTATE_ENABLE_ALPHATEST;
2547 		qglAlphaFunc(GL_LESS,0.1);
2548 		qglColorMask(0,0,0,0);
2549 
2550 		qglColor4f(1,1,1,1);
2551 		if(r_around)
2552 			GL_Bind(r_around->texnum);
2553 		qglBegin(GL_TRIANGLE_FAN);
2554 		if (r_minimap_style->integer){
2555 			qglTexCoord2f(0,1); qglVertex3f(1024,-1024,1);
2556 			qglTexCoord2f(1,1); qglVertex3f(-1024,-1024,1);
2557 			qglTexCoord2f(1,0); qglVertex3f(-1024,1024,1);
2558 			qglTexCoord2f(0,0); qglVertex3f(1024,1024,1);
2559 		} else {
2560 			qglTexCoord2f(0,1); qglVertex3f(1024,-512,1);
2561 			qglTexCoord2f(1,1); qglVertex3f(-1024,-512,1);
2562 			qglTexCoord2f(1,0); qglVertex3f(-1024,1536,1);
2563 			qglTexCoord2f(0,0); qglVertex3f(1024,1536,1);
2564 		}
2565 		qglEnd();
2566 
2567 		qglColorMask(1,1,1,1);
2568 		GLSTATE_DISABLE_ALPHATEST;
2569 		qglAlphaFunc(GL_GREATER, 0.5);
2570 		qglStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE);
2571 		qglStencilFunc(GL_NOTEQUAL,4,4);
2572 
2573 	}
2574 
2575 	if(r_minimap_zoom->value>=0.1) {
2576 		qglScalef(r_minimap_zoom->value,r_minimap_zoom->value,r_minimap_zoom->value);
2577 	}
2578 
2579 	if (r_minimap_style->integer) {
2580 		qglPushMatrix();
2581 		qglRotatef (90-r_newrefdef.viewangles[1],  0, 0, -1);
2582 
2583 		qglDisable(GL_TEXTURE_2D);
2584 		qglBegin(GL_TRIANGLES);
2585 		qglColor4f(1,1,1,0.5);
2586 		qglVertex3f(0,32,0);
2587 		qglColor4f(1,1,0,0.5);
2588 		qglVertex3f(24,-32,0);
2589 		qglVertex3f(-24,-32,0);
2590 		qglEnd();
2591 
2592 		qglPopMatrix();
2593 	} else {
2594 		qglDisable(GL_TEXTURE_2D);
2595 		qglBegin(GL_TRIANGLES);
2596 		qglColor4f(1,1,1,0.5);
2597 		qglVertex3f(0,32,0);
2598 		qglColor4f(1,1,0,0.5);
2599 		qglVertex3f(24,-32,0);
2600 		qglVertex3f(-24,-32,0);
2601 		qglEnd();
2602 
2603 		qglRotatef (90-r_newrefdef.viewangles[1],  0, 0, 1);
2604 	}
2605 	qglTranslatef (-r_newrefdef.vieworg[0],  -r_newrefdef.vieworg[1],  -r_newrefdef.vieworg[2]);
2606 
2607 	qglBegin(GL_QUADS);
2608 	for(i=0;i<numRadarEnts;i++){
2609 		float x=RadarEnts[i].org[0];
2610 		float y=RadarEnts[i].org[1];
2611 		float z=RadarEnts[i].org[2];
2612 		qglColor4fv(RadarEnts[i].color);
2613 
2614 		qglVertex3f(x+9, y+9, z);
2615 		qglVertex3f(x+9, y-9, z);
2616 		qglVertex3f(x-9, y-9, z);
2617 		qglVertex3f(x-9, y+9, z);
2618 	}
2619 	qglEnd();
2620 
2621 	qglEnable(GL_TEXTURE_2D);
2622 
2623 	if(r_radarmap)
2624 		GL_Bind(r_radarmap->texnum);
2625 	qglBlendFunc(GL_SRC_ALPHA, GL_ONE);
2626 	GLSTATE_ENABLE_BLEND;
2627 	qglColor3f(1,1,1);
2628 
2629 	fS[3]=0.5+ r_newrefdef.vieworg[2]/512.0;
2630 	qglTexGenf(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
2631 
2632 	GLSTATE_ENABLE_TEXGEN;
2633 	qglTexGenfv(GL_S,GL_OBJECT_PLANE,fS);
2634 
2635 	// draw the stuff
2636 	R_RecursiveRadarNode (r_worldmodel->nodes);
2637 
2638 	qglBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
2639 	GLSTATE_DISABLE_TEXGEN;
2640 
2641 	qglPopMatrix();
2642 
2643 	qglViewport(0,0,vid.width,vid.height);
2644 
2645 	qglMatrixMode(GL_PROJECTION);
2646 	qglPopMatrix();
2647 	qglMatrixMode(GL_MODELVIEW);
2648 	qglDisable(GL_STENCIL_TEST);
2649 	GL_TexEnv( GL_REPLACE );
2650 	GLSTATE_DISABLE_BLEND;
2651 	qglEnable(GL_DEPTH_TEST);
2652     qglColor4f(1,1,1,1);
2653 
2654 }
2655