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 // GL_RSURF.C: surface-related refresh code
21 #include <assert.h>
22 
23 #include "gl_local.h"
24 #include "gl_refl.h" /** MPO **/
25 
26 static vec3_t	modelorg;		// relative to viewpoint
27 
28 msurface_t	*r_alpha_surfaces;
29 
30 #define LIGHTMAP_BYTES 4
31 
32 #define	BLOCK_WIDTH		128
33 #define	BLOCK_HEIGHT	128
34 
35 #define	MAX_LIGHTMAPS	128
36 
37 int		c_visible_lightmaps;
38 int		c_visible_textures;
39 
40 #define GL_LIGHTMAP_FORMAT GL_RGBA
41 
42 typedef struct
43 {
44 	int internal_format;
45 	int	current_lightmap_texture;
46 
47 	msurface_t	*lightmap_surfaces[MAX_LIGHTMAPS];
48 
49 	int			allocated[BLOCK_WIDTH];
50 
51 	// the lightmap texture data needs to be kept in
52 	// main memory so texsubimage can update properly
53 	byte		lightmap_buffer[4*BLOCK_WIDTH*BLOCK_HEIGHT];
54 } gllightmapstate_t;
55 
56 static gllightmapstate_t gl_lms;
57 
58 
59 static void		LM_InitBlock( void );
60 static void		LM_UploadBlock( qboolean dynamic );
61 static qboolean	LM_AllocBlock (int w, int h, int *x, int *y);
62 
63 extern void R_SetCacheState( msurface_t *surf );
64 extern void R_BuildLightMap (msurface_t *surf, byte *dest, int stride);
65 
66 // MH - detail textures
67 static msurface_t *r_detailsurfaces;
68 
69 /*
70 =============================================================
71 
72 	BRUSH MODELS
73 
74 =============================================================
75 */
76 
77 /*
78 ===============
79 R_TextureAnimation
80 
81 Returns the proper texture for a given time and base texture
82 ===============
83 */
R_TextureAnimation(mtexinfo_t * tex)84 image_t *R_TextureAnimation (mtexinfo_t *tex)
85 {
86 	int		c;
87 
88 	if (!tex->next)
89 		return tex->image;
90 
91 	c = currententity->frame % tex->numframes;
92 	while (c)
93 	{
94 		tex = tex->next;
95 		c--;
96 	}
97 
98 	return tex->image;
99 }
100 
101 /*
102 ================
103 DrawGLPoly
104 ================
105 */
DrawGLPoly(glpoly_t * p)106 void DrawGLPoly (glpoly_t *p)
107 {
108 	int		i;
109 	float	*v;
110 
111 	qglBegin (GL_POLYGON);
112 	v = p->verts[0];
113 	for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
114 	{
115 		qglTexCoord2f (v[3], v[4]);
116 		qglVertex3fv (v);
117 	}
118 	qglEnd ();
119 }
120 
121 //============
122 //PGM
123 /*
124 ================
125 DrawGLFlowingPoly -- version of DrawGLPoly that handles scrolling texture
126 ================
127 */
DrawGLFlowingPoly(msurface_t * fa)128 void DrawGLFlowingPoly (msurface_t *fa)
129 {
130 	int		i;
131 	float	*v;
132 	glpoly_t *p;
133 	float	scroll;
134 
135 	p = fa->polys;
136 
137 	scroll = -64 * ( (r_newrefdef.time / 40.0) - (int)(r_newrefdef.time / 40.0) );
138 	if(scroll == 0.0)
139 		scroll = -64.0;
140 
141 	qglBegin (GL_POLYGON);
142 	v = p->verts[0];
143 	for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
144 	{
145 		qglTexCoord2f ((v[3] + scroll), v[4]);
146 		qglVertex3fv (v);
147 	}
148 	qglEnd ();
149 }
150 //PGM
151 //============
152 
153 /*
154 ** R_DrawTriangleOutlines
155 */
R_DrawTriangleOutlines(msurface_t * surf)156 void R_DrawTriangleOutlines(msurface_t *surf)	//** Guy
157 {
158 	int i, j;
159 	glpoly_t *p;
160 
161 	if (!gl_showtris->value)
162 		return;
163 
164 	//** Guy: *\/\/\/ gl_showtris fix begin \/\/\/*
165 	qglDisable(GL_DEPTH_TEST);
166 
167 	if (!surf)	//** Guy: Called from non-multitexture mode; need to loop through surfaces defined by non-mtex functions
168 	{
169 		qglDisable(GL_TEXTURE_2D);
170 
171 		for (i=0; i < MAX_LIGHTMAPS; i++)
172 		{
173 			for (surf=gl_lms.lightmap_surfaces[i]; surf!=0; surf=surf->lightmapchain)
174 			{
175 				for (p=surf->polys; p; p=p->chain)
176 				{
177 					for (j=2; j<p->numverts; j++)
178 					{
179 						qglBegin(GL_LINE_STRIP);
180 						qglColor4f(.5, 1, 1, 1);
181 						qglVertex3fv(p->verts[0]);
182 						qglVertex3fv(p->verts[j-1]);
183 						qglVertex3fv(p->verts[j]);
184 						qglVertex3fv(p->verts[0]);
185 						qglEnd();
186 					}
187 				}
188 			}
189 		}
190 
191 		qglEnable(GL_TEXTURE_2D);
192 	}
193 	else	//** Guy: Called from multitexture mode; surface to be rendered in wireframe already passed in
194 	{
195 		float tex_state0, tex_state1;
196 
197 		GL_SelectTexture(GL_TEXTURE0);
198 		qglGetTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &tex_state0);
199 
200 		GL_SelectTexture(GL_TEXTURE1);
201 		qglGetTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &tex_state1);
202 
203 		GL_EnableMultitexture(false);
204 		qglDisable(GL_TEXTURE_2D);
205 
206 		for (p=surf->polys; p; p=p->chain)
207 		{
208 			for (i=2; i<p->numverts; i++)
209 			{
210 				qglBegin(GL_LINE_STRIP);
211 				qglColor4f(.5, 1, 1, 1);
212 				qglVertex3fv(p->verts[0]);
213 				qglVertex3fv(p->verts[i - 1]);
214 				qglVertex3fv(p->verts[i]);
215 				qglVertex3fv(p->verts[0]);
216 				qglEnd();
217 			}
218 		}
219 
220 		qglEnable(GL_TEXTURE_2D);
221 		GL_EnableMultitexture(true);
222 
223 		GL_SelectTexture(GL_TEXTURE0);
224 		GL_TexEnv(tex_state0);
225 
226 		GL_SelectTexture(GL_TEXTURE1);
227 		GL_TexEnv(tex_state1);
228 	}
229 
230 	qglEnable(GL_DEPTH_TEST);
231 	//** Guy: */\/\/\ gl_showtris fix end /\/\/\*
232 	/* thanks guy who ever you are .. ;) */
233 }
234 
235 /*
236 ** DrawGLPolyChain
237 */
DrawGLPolyChain(glpoly_t * p,float soffset,float toffset)238 void DrawGLPolyChain( glpoly_t *p, float soffset, float toffset )
239 {
240 	if ( soffset == 0 && toffset == 0 )
241 	{
242 		for ( ; p != 0; p = p->chain )
243 		{
244 			float *v;
245 			int j;
246 
247 			qglBegin (GL_POLYGON);
248 			v = p->verts[0];
249 			for (j=0 ; j<p->numverts ; j++, v+= VERTEXSIZE)
250 			{
251 				qglTexCoord2f (v[5], v[6] );
252 				qglVertex3fv (v);
253 			}
254 			qglEnd ();
255 		}
256 	}
257 	else
258 	{
259 		for ( ; p != 0; p = p->chain )
260 		{
261 			float *v;
262 			int j;
263 
264 			qglBegin (GL_POLYGON);
265 			v = p->verts[0];
266 			for (j=0 ; j<p->numverts ; j++, v+= VERTEXSIZE)
267 			{
268 				qglTexCoord2f (v[5] - soffset, v[6] - toffset );
269 				qglVertex3fv (v);
270 			}
271 			qglEnd ();
272 		}
273 	}
274 }
275 
276 /*
277 ** R_BlendLightMaps
278 **
279 ** This routine takes all the given light mapped surfaces in the world and
280 ** blends them into the framebuffer.
281 */
R_BlendLightmaps(void)282 void R_BlendLightmaps (void)
283 {
284 	int			i;
285 	msurface_t	*surf, *newdrawsurf = 0;
286 
287 	// don't bother if we're set to fullbright
288 	if (r_fullbright->value)
289 		return;
290 	if (!r_worldmodel->lightdata)
291 		return;
292 
293 	// don't bother writing Z
294 	qglDepthMask( 0 );
295 
296 	/*
297 	** set the appropriate blending mode unless we're only looking at the
298 	** lightmaps.
299 	*/
300 	if (!gl_lightmap->value)
301 	{
302 		qglEnable (GL_BLEND);
303 
304 		if ( gl_saturatelighting->value )
305 		{
306 			qglBlendFunc( GL_ONE, GL_ONE );
307 		}
308 		else
309 		{
310 			if ( gl_monolightmap->string[0] != '0' )
311 			{
312 				switch ( toupper( gl_monolightmap->string[0] ) )
313 				{
314 				case 'I':
315 					qglBlendFunc (GL_ZERO, GL_SRC_COLOR );
316 					break;
317 				case 'L':
318 					qglBlendFunc (GL_ZERO, GL_SRC_COLOR );
319 					break;
320 				case 'A':
321 				default:
322 					qglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
323 					break;
324 				}
325 			}
326 			else
327 			{
328 				qglBlendFunc (GL_ZERO, GL_SRC_COLOR );
329 			}
330 		}
331 	}
332 
333 	if ( currentmodel == r_worldmodel )
334 		c_visible_lightmaps = 0;
335 
336 	/*
337 	** render static lightmaps first
338 	*/
339 	for ( i = 1; i < MAX_LIGHTMAPS; i++ )
340 	{
341 		if ( gl_lms.lightmap_surfaces[i] )
342 		{
343 			if (currentmodel == r_worldmodel)
344 				c_visible_lightmaps++;
345 			GL_Bind( gl_state.lightmap_textures + i);
346 
347 			for ( surf = gl_lms.lightmap_surfaces[i]; surf != 0; surf = surf->lightmapchain )
348 			{
349 				if ( surf->polys )
350 					DrawGLPolyChain( surf->polys, 0, 0 );
351 			}
352 		}
353 	}
354 
355 	/*
356 	** render dynamic lightmaps
357 	*/
358 	if ( gl_dynamic->value )
359 	{
360 		LM_InitBlock();
361 
362 		GL_Bind( gl_state.lightmap_textures+0 );
363 
364 		if (currentmodel == r_worldmodel)
365 			c_visible_lightmaps++;
366 
367 		newdrawsurf = gl_lms.lightmap_surfaces[0];
368 
369 		for ( surf = gl_lms.lightmap_surfaces[0]; surf != 0; surf = surf->lightmapchain )
370 		{
371 			int		smax, tmax;
372 			byte	*base;
373 
374 			smax = (surf->extents[0]>>4)+1;
375 			tmax = (surf->extents[1]>>4)+1;
376 
377 			if ( LM_AllocBlock( smax, tmax, &surf->dlight_s, &surf->dlight_t ) )
378 			{
379 				base = gl_lms.lightmap_buffer;
380 				base += ( surf->dlight_t * BLOCK_WIDTH + surf->dlight_s ) * LIGHTMAP_BYTES;
381 
382 				R_BuildLightMap (surf, base, BLOCK_WIDTH*LIGHTMAP_BYTES);
383 			}
384 			else
385 			{
386 				msurface_t *drawsurf;
387 
388 				// upload what we have so far
389 				LM_UploadBlock( true );
390 
391 				// draw all surfaces that use this lightmap
392 				for ( drawsurf = newdrawsurf; drawsurf != surf; drawsurf = drawsurf->lightmapchain )
393 				{
394 					if ( drawsurf->polys )
395 						DrawGLPolyChain( drawsurf->polys,
396 							              ( drawsurf->light_s - drawsurf->dlight_s ) * ( 1.0 / 128.0 ),
397 										( drawsurf->light_t - drawsurf->dlight_t ) * ( 1.0 / 128.0 ) );
398 				}
399 
400 				newdrawsurf = drawsurf;
401 
402 				// clear the block
403 				LM_InitBlock();
404 
405 				// try uploading the block now
406 				if ( !LM_AllocBlock( smax, tmax, &surf->dlight_s, &surf->dlight_t ) )
407 				{
408 					ri.Sys_Error( ERR_FATAL, "Consecutive calls to LM_AllocBlock(%d,%d) failed (dynamic)\n", smax, tmax );
409 				}
410 
411 				base = gl_lms.lightmap_buffer;
412 				base += ( surf->dlight_t * BLOCK_WIDTH + surf->dlight_s ) * LIGHTMAP_BYTES;
413 
414 				R_BuildLightMap (surf, base, BLOCK_WIDTH*LIGHTMAP_BYTES);
415 			}
416 		}
417 
418 		/*
419 		** draw remainder of dynamic lightmaps that haven't been uploaded yet
420 		*/
421 		if ( newdrawsurf )
422 			LM_UploadBlock( true );
423 
424 		for ( surf = newdrawsurf; surf != 0; surf = surf->lightmapchain )
425 		{
426 			if ( surf->polys )
427 				DrawGLPolyChain( surf->polys, ( surf->light_s - surf->dlight_s ) * ( 1.0 / 128.0 ), ( surf->light_t - surf->dlight_t ) * ( 1.0 / 128.0 ) );
428 		}
429 	}
430 
431 	/*
432 	** restore state
433 	*/
434 	qglDisable (GL_BLEND);
435 	qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
436 	qglDepthMask( 1 );
437 }
438 
439 /*
440 ================
441 R_RenderBrushPoly
442 ================
443 */
R_RenderBrushPoly(msurface_t * fa)444 void R_RenderBrushPoly (msurface_t *fa)
445 {
446 	int			maps;
447 	image_t		*image;
448 	qboolean is_dynamic = false;
449 
450 	c_brush_polys++;
451 
452 	image = R_TextureAnimation (fa->texinfo);
453 
454 	if (fa->flags & SURF_DRAWTURB)
455 	{
456 		GL_Bind( image->texnum );
457 
458 		// warp texture, no lightmaps
459 		GL_TexEnv( GL_MODULATE );
460 		qglColor4f( gl_state.inverse_intensity,
461 			        gl_state.inverse_intensity,
462 					gl_state.inverse_intensity,
463 					1.0F );
464 		EmitWaterPolys (fa);
465 		GL_TexEnv( GL_REPLACE );
466 
467 		return;
468 	}
469 	else
470 	{
471 		GL_Bind( image->texnum );
472 
473 		GL_TexEnv( GL_REPLACE );
474 	}
475 	// MH - detail textures begin
476 	// accumulate the detail chain
477 	// wait until we get here so that we don't get any detail texturing on DRAWTURB polys
478 	if((maxTextureUnits<3) && (gl_detailtextures->value)) {
479 		fa->detailchain = r_detailsurfaces;
480 		r_detailsurfaces = fa;
481 	}
482 	// MH - detail textures end
483 
484 //======
485 //PGM
486 	if(fa->texinfo->flags & SURF_FLOWING)
487 		DrawGLFlowingPoly (fa);
488 	else
489 		DrawGLPoly (fa->polys);
490 //PGM
491 //======
492 
493 	/*
494 	** check for lightmap modification
495 	*/
496 	for ( maps = 0; maps < MAXLIGHTMAPS && fa->styles[maps] != 255; maps++ )
497 	{
498 		if ( r_newrefdef.lightstyles[fa->styles[maps]].white != fa->cached_light[maps] )
499 			goto dynamic;
500 	}
501 
502 	// dynamic this frame or dynamic previously
503 	if ( ( fa->dlightframe == r_framecount ) )
504 	{
505 dynamic:
506 		if ( gl_dynamic->value )
507 		{
508 			if (!( fa->texinfo->flags & (SURF_SKY|SURF_TRANS33|SURF_TRANS66|SURF_WARP ) ) )
509 			{
510 				is_dynamic = true;
511 			}
512 		}
513 	}
514 
515 	if ( is_dynamic )
516 	{
517 		if ( ( fa->styles[maps] >= 32 || fa->styles[maps] == 0 ) && ( fa->dlightframe != r_framecount ) )
518 		{
519 			unsigned	temp[34*34];
520 			int			smax, tmax;
521 
522 			smax = (fa->extents[0]>>4)+1;
523 			tmax = (fa->extents[1]>>4)+1;
524 
525 			R_BuildLightMap( fa, (void *)temp, smax*4 );
526 			R_SetCacheState( fa );
527 
528 			GL_Bind( gl_state.lightmap_textures + fa->lightmaptexturenum );
529 
530 			qglTexSubImage2D( GL_TEXTURE_2D, 0,
531 							  fa->light_s, fa->light_t,
532 							  smax, tmax,
533 							  GL_LIGHTMAP_FORMAT,
534 							  GL_UNSIGNED_BYTE, temp );
535 
536 			fa->lightmapchain = gl_lms.lightmap_surfaces[fa->lightmaptexturenum];
537 			gl_lms.lightmap_surfaces[fa->lightmaptexturenum] = fa;
538 		}
539 		else
540 		{
541 			fa->lightmapchain = gl_lms.lightmap_surfaces[0];
542 			gl_lms.lightmap_surfaces[0] = fa;
543 		}
544 	}
545 	else
546 	{
547 		fa->lightmapchain = gl_lms.lightmap_surfaces[fa->lightmaptexturenum];
548 		gl_lms.lightmap_surfaces[fa->lightmaptexturenum] = fa;
549 	}
550 }
551 
552 
553 /*
554 ================
555 R_DrawAlphaSurfaces
556 
557 Draw water surfaces and windows.
558 The BSP tree is waled front to back, so unwinding the chain
559 of alpha_surfaces will draw back to front, giving proper ordering.
560 ================
561 */
R_DrawAlphaSurfaces(void)562 void R_DrawAlphaSurfaces (void)
563 {
564 	msurface_t	*s;
565 	float		intens;
566 
567 	//
568 	// go back to the world matrix
569 	//
570     qglLoadMatrixf (r_world_matrix);
571 
572 	qglEnable (GL_BLEND);
573 	GL_TexEnv( GL_MODULATE );
574 
575 	// the textures are prescaled up for a better lighting range,
576 	// so scale it back down
577 	intens = gl_state.inverse_intensity;
578 
579 	for (s=r_alpha_surfaces ; s ; s=s->texturechain)
580 	{
581 		GL_Bind(s->texinfo->image->texnum);
582 		c_brush_polys++;
583 		if (s->texinfo->flags & SURF_TRANS33)
584 			qglColor4f (intens,intens,intens,0.33);
585 		else if (s->texinfo->flags & SURF_TRANS66)
586 			qglColor4f (intens,intens,intens,0.66);
587 		else
588 			qglColor4f (intens,intens,intens,1);
589 		if (s->flags & SURF_DRAWTURB)
590 			EmitWaterPolys (s);
591 		else if(s->texinfo->flags & SURF_FLOWING)			// PGM	9/16/98
592 			DrawGLFlowingPoly (s);							// PGM
593 		else
594 			DrawGLPoly (s->polys);
595 	}
596 
597 	GL_TexEnv( GL_REPLACE );
598 	qglColor4f (1,1,1,1);
599 	qglDisable (GL_BLEND);
600 
601 	r_alpha_surfaces = NULL;
602 }
603 
604 /*
605 ================
606 DrawTextureChains
607 ================
608 */
DrawTextureChains(void)609 void DrawTextureChains (void)
610 {
611 	int		i;
612 	msurface_t	*s;
613 	image_t		*image;
614 
615 	c_visible_textures = 0;
616 
617 //	GL_TexEnv( GL_REPLACE );
618 
619 	if ( !qglSelectTextureSGIS && !qglActiveTextureARB )
620 	{
621 		for ( i = 0, image=gltextures ; i<numgltextures ; i++,image++)
622 		{
623 			if (!image->registration_sequence)
624 				continue;
625 			s = image->texturechain;
626 			if (!s)
627 				continue;
628 			c_visible_textures++;
629 
630 			for ( ; s ; s=s->texturechain)
631 				R_RenderBrushPoly (s);
632 
633 			image->texturechain = NULL;
634 		}
635 	}
636 	else
637 	{
638 		for ( i = 0, image=gltextures ; i<numgltextures ; i++,image++)
639 		{
640 			if (!image->registration_sequence)
641 				continue;
642 			if (!image->texturechain)
643 				continue;
644 			c_visible_textures++;
645 
646 			for ( s = image->texturechain; s ; s=s->texturechain)
647 			{
648 				if ( !( s->flags & SURF_DRAWTURB ) )
649 					R_RenderBrushPoly (s);
650 			}
651 		}
652 
653 		GL_EnableMultitexture( false );
654 		for ( i = 0, image=gltextures ; i<numgltextures ; i++,image++)
655 		{
656 			if (!image->registration_sequence)
657 				continue;
658 			s = image->texturechain;
659 			if (!s)
660 				continue;
661 
662 			for ( ; s ; s=s->texturechain)
663 			{
664 				if ( s->flags & SURF_DRAWTURB )
665 					R_RenderBrushPoly (s);
666 			}
667 
668 			image->texturechain = NULL;
669 		}
670 //		GL_EnableMultitexture( true );
671 	}
672 
673 	GL_TexEnv( GL_REPLACE );
674 }
675 
676 void
EmitCausticPolys(msurface_t * fa)677 EmitCausticPolys(msurface_t * fa)
678 {
679 	glpoly_t       *p;
680 	float          *v;
681 	int		i;
682 	float		scroll;
683 
684 	scroll = -64 * ((r_newrefdef.time / 40.0) - (int)(r_newrefdef.time / 40.0));
685 	if (scroll == 0.0)
686 		scroll = -64.0;
687 
688 	if (/* !gl_fogenable->value || */!gl_fogunderwater->value)
689 		qglDisable(GL_FOG);
690 
691 	GL_SelectTexture(GL_TEXTURE1);
692 	qglDisable(GL_TEXTURE_2D);
693 	GL_SelectTexture(GL_TEXTURE0);
694 
695 	GL_Bind(r_caustictexture->texnum);
696 
697 	qglBlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
698 
699 	qglColor4f(1, 1, 1, 0.275);
700 	qglEnable(GL_BLEND);
701 
702 	for (p = fa->polys; p; p = p->chain) {
703 
704 		qglBegin(GL_POLYGON);
705 		for (i = 0, v = p->verts[0]; i < p->numverts; i++, v += VERTEXSIZE) {
706 			qglTexCoord2f(v[3] + (scroll / 30), v[4] + (scroll / 30));
707 			qglVertex3fv(v);
708 		}
709 		qglEnd();
710 	}
711 
712 
713 	qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
714 
715 	qglColor4f(1, 1, 1, 1);
716 	qglDisable(GL_BLEND);
717 	GL_SelectTexture(GL_TEXTURE1);
718 	qglEnable(GL_TEXTURE_2D);
719 	GL_SelectTexture(GL_TEXTURE0);
720 
721 	if (gl_fogenable->value)
722 		qglEnable(GL_FOG);
723 
724 }
725 
GL_RenderLightmappedPoly(msurface_t * surf)726 void GL_RenderLightmappedPoly( msurface_t *surf )
727 {
728 	int		i, nv = surf->polys->numverts;
729 	int		map;
730 	float	*v;
731 	image_t *image = R_TextureAnimation( surf->texinfo );
732 	qboolean is_dynamic = false;
733 	unsigned lmtex = surf->lightmaptexturenum;
734 	glpoly_t *p;
735 
736 	// MH - detail textures begin
737 	if((gl_detailtextures->value) && (maxTextureUnits >2) && (!surf->texinfo->flags & SURF_LIGHT) ) {
738 
739 		GL_Enable3dTextureUnit ( true );
740 		GL_MBind ( GL_TEXTURE2, r_detailtexture->texnum );	//bind detail texture
741 		GL_TexEnv ( GL_COMBINE_ARB );				//set blending mode
742 		qglTexEnvi ( GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 2 );	//bump up lighting a little
743 	}
744 
745 	else if((gl_detailtextures->value) && (maxTextureUnits < 3) && (!surf->texinfo->flags & SURF_LIGHT)) {
746 		// accumulate the detail texture chain - this is used if we have 2 or less texture units
747 		surf->detailchain = r_detailsurfaces;
748 		r_detailsurfaces = surf;
749 
750 	}
751 	// MH - detail textures end
752 
753 	for ( map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++ )
754 	{
755 		if ( r_newrefdef.lightstyles[surf->styles[map]].white != surf->cached_light[map] )
756 			goto dynamic;
757 	}
758 
759 	// dynamic this frame or dynamic previously
760 	if ( ( surf->dlightframe == r_framecount ) )
761 	{
762 dynamic:
763 		if ( gl_dynamic->value )
764 		{
765 			if ( !(surf->texinfo->flags & (SURF_SKY|SURF_TRANS33|SURF_TRANS66|SURF_WARP ) ) )
766 			{
767 				is_dynamic = true;
768 			}
769 		}
770 	}
771 
772 	if ( is_dynamic )
773 	{
774 		unsigned	temp[128*128];
775 		int			smax, tmax;
776 
777 		if ( ( surf->styles[map] >= 32 || surf->styles[map] == 0 ) && ( surf->dlightframe != r_framecount ) )
778 		{
779 			smax = (surf->extents[0]>>4)+1;
780 			tmax = (surf->extents[1]>>4)+1;
781 
782 			R_BuildLightMap( surf, (void *)temp, smax*4 );
783 			R_SetCacheState( surf );
784 
785 			GL_MBind( GL_TEXTURE1, gl_state.lightmap_textures + surf->lightmaptexturenum );
786 
787 			lmtex = surf->lightmaptexturenum;
788 
789 			qglTexSubImage2D( GL_TEXTURE_2D, 0,
790 							  surf->light_s, surf->light_t,
791 							  smax, tmax,
792 							  GL_LIGHTMAP_FORMAT,
793 							  GL_UNSIGNED_BYTE, temp );
794 
795 		}
796 		else
797 		{
798 			smax = (surf->extents[0]>>4)+1;
799 			tmax = (surf->extents[1]>>4)+1;
800 
801 			R_BuildLightMap( surf, (void *)temp, smax*4 );
802 
803 			GL_MBind( GL_TEXTURE1, gl_state.lightmap_textures + 0 );
804 
805 			lmtex = 0;
806 
807 			qglTexSubImage2D( GL_TEXTURE_2D, 0,
808 							  surf->light_s, surf->light_t,
809 							  smax, tmax,
810 							  GL_LIGHTMAP_FORMAT,
811 							  GL_UNSIGNED_BYTE, temp );
812 
813 		}
814 
815 		c_brush_polys++;
816 
817 		GL_MBind( GL_TEXTURE0, image->texnum );
818 		GL_MBind( GL_TEXTURE1, gl_state.lightmap_textures + lmtex );
819 
820 //==========
821 //PGM
822 		if (surf->texinfo->flags & SURF_FLOWING)
823 		{
824 			float scroll;
825 
826 			scroll = -64 * ( (r_newrefdef.time / 40.0) - (int)(r_newrefdef.time / 40.0) );
827 			if(scroll == 0.0)
828 				scroll = -64.0;
829 
830 			for ( p = surf->polys; p; p = p->chain )
831 			{
832 				v = p->verts[0];
833 				qglBegin (GL_POLYGON);
834 				for (i=0 ; i< nv; i++, v+= VERTEXSIZE)
835 				{
836 					qglMTexCoord2fSGIS( GL_TEXTURE0, (v[3]+scroll), v[4]);
837 					qglMTexCoord2fSGIS( GL_TEXTURE1, v[5], v[6]);
838 					qglVertex3fv (v);
839 				}
840 				qglEnd ();
841 			}
842 		}
843 		else
844 		{
845 			for ( p = surf->polys; p; p = p->chain )
846 			{
847 				v = p->verts[0];
848 				qglBegin (GL_POLYGON);
849 				for (i=0 ; i< nv; i++, v+= VERTEXSIZE)
850 				{
851 					qglMTexCoord2fSGIS( GL_TEXTURE0, v[3], v[4]);
852 					qglMTexCoord2fSGIS( GL_TEXTURE1, v[5], v[6]);
853 					if( (gl_detailtextures->value>0) && (maxTextureUnits>2) ){
854 						qglMTexCoord2fSGIS( GL_TEXTURE2, v[7] * gl_detailtextures->value,
855 						                    v[8] * gl_detailtextures->value);
856 					}
857 					qglVertex3fv (v);
858 				}
859 				qglEnd ();
860 			}
861 		}
862 //PGM
863 //==========
864 	}
865 	else
866 	{
867 		c_brush_polys++;
868 
869 		GL_MBind( GL_TEXTURE0, image->texnum );
870 		GL_MBind( GL_TEXTURE1, gl_state.lightmap_textures + lmtex );
871 
872 //==========
873 //PGM
874 		if (surf->texinfo->flags & SURF_FLOWING)
875 		{
876 			float scroll;
877 
878 			scroll = -64 * ( (r_newrefdef.time / 40.0) - (int)(r_newrefdef.time / 40.0) );
879 			if(scroll == 0.0)
880 				scroll = -64.0;
881 
882 			for ( p = surf->polys; p; p = p->chain )
883 			{
884 				v = p->verts[0];
885 				qglBegin (GL_POLYGON);
886 				for (i=0 ; i< nv; i++, v+= VERTEXSIZE)
887 				{
888 					qglMTexCoord2fSGIS( GL_TEXTURE0, (v[3]+scroll), v[4]);
889 					qglMTexCoord2fSGIS( GL_TEXTURE1, v[5], v[6]);
890 					qglVertex3fv (v);
891 				}
892 				qglEnd ();
893 			}
894 		}
895 		else
896 		{
897 //PGM
898 //==========
899 			for ( p = surf->polys; p; p = p->chain )
900 			{
901 				v = p->verts[0];
902 				qglBegin (GL_POLYGON);
903 				for (i=0 ; i< nv; i++, v+= VERTEXSIZE)
904 				{
905 					qglMTexCoord2fSGIS( GL_TEXTURE0, v[3], v[4]);
906 					qglMTexCoord2fSGIS( GL_TEXTURE1, v[5], v[6]);
907 					if( (gl_detailtextures->value>0) && (maxTextureUnits>2) ) {
908 						qglMTexCoord2fSGIS( GL_TEXTURE2, v[7] * gl_detailtextures->value,
909 						                    v[8] * gl_detailtextures->value);
910 					}
911 					qglVertex3fv (v);
912 				}
913 				qglEnd ();
914 			}
915 //==========
916 //PGM
917 		}
918 //PGM
919 //==========
920 	}
921 
922 	if((gl_detailtextures->value) && (maxTextureUnits >2) ) {
923 		GL_Enable3dTextureUnit ( false );
924 	}
925 
926 	if ((surf->flags & SURF_UNDERWATER) && !image->has_alpha) {
927 
928 		if (gl_water_caustics->value) {
929 			EmitCausticPolys(surf);
930 		} else
931 			return;
932 	}
933 }
934 
935 // MH - detail textures begin
936 // here we draw the detail textures!
937 // we could do this as a multitextured render along with the other stuff, but my own tests
938 // have indicated that for something like this there's no real benefit to be had from doing
939 // so.  the difference is in the order of 1 or 2 FPS - the real hit from detail texturing
940 // comes from scrunching large images into small spaces
R_DrawDetailSurfaces(void)941 static void R_DrawDetailSurfaces (void)
942 {
943 	msurface_t	*surf = r_detailsurfaces;
944 	int			i;
945 	float		*v;
946 	glpoly_t	*p;
947 
948 	// nothing to draw!
949 	if (!surf)
950 		return;
951 
952 	// we do this rather than checking for 0 (checking for 0 is always bad with floats)
953 	// standard 6 decimal place precision
954 	if (gl_detailtextures->value < 0.00001)
955 		return;
956 
957 
958 	qglEnable (GL_POLYGON_OFFSET_FILL); //to stop z buffer fighting
959 	qglPolygonOffset(-1, -2);
960 
961 	// we *could* use the standard glBindTexture here as we don't need to do any bind checking
962 	// but again we'll maintain consistency
963 	GL_Bind (r_detailtexture->texnum);
964 
965 	// set the correct blending mode
966 	qglTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
967 	qglBlendFunc (GL_DST_COLOR, GL_SRC_COLOR);
968 	qglEnable (GL_BLEND);
969 
970 	// here we get clever and do our texture scaling in the texture matrix.  this saves
971 	// us from more runtime calculations in software
972 	qglMatrixMode (GL_TEXTURE);
973 	qglLoadIdentity ();
974 
975 	// we only need to scale the X and Y co-ords, correcponding to texture s and t.
976 	// everyone will have their own favourite scaling amount, so i did a cvar
977 	qglScalef (gl_detailtextures->value, gl_detailtextures->value, 1.0);
978 
979 	// we can safely leave the texture matrix as the active mode while we're doing the draw
980 	for (; surf; surf = surf->detailchain)
981 	{
982 		for (p = surf->polys; p; p = p->chain)
983 		{
984 			// using GL_TRIANGLE_FAN is theoretically more efficient than GL_POLYGON as
985 			// the GL implementation can know something about what we are going to draw
986 			// in advance, and set things up accordingly.  the visual result is identical.
987 			qglBegin (GL_TRIANGLE_FAN);
988 
989 			for (v = p->verts[0], i = 0 ; i < p->numverts; i++, v += VERTEXSIZE)
990 			{
991 				// take the 128 * 128 version of the s and t co-ords
992 				qglTexCoord2f (v[7], v[8]);
993 				qglVertex3fv (v);
994 			}
995 
996 			qglEnd ();
997 		}
998 	}
999 
1000 	// restore original texture matrix
1001 	qglLoadIdentity ();
1002 	qglMatrixMode (GL_MODELVIEW);
1003 
1004 	// restore original blend
1005 	qglTexEnvf ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE) ;
1006 	qglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
1007 	qglDisable ( GL_BLEND );
1008 	qglDisable ( GL_POLYGON_OFFSET_FILL );
1009 }
1010 // MH - detail textures end
1011 
1012 /*
1013 =================
1014 R_DrawInlineBModel
1015 =================
1016 */
R_DrawInlineBModel(void)1017 void R_DrawInlineBModel (void)
1018 {
1019 	int			i, k;
1020 	cplane_t	*pplane;
1021 	float		dot;
1022 	msurface_t	*psurf;
1023 	dlight_t	*lt;
1024 
1025 	// calculate dynamic lighting for bmodel
1026 	if ( !gl_flashblend->value )
1027 	{
1028 		lt = r_newrefdef.dlights;
1029 		for (k=0 ; k<r_newrefdef.num_dlights ; k++, lt++)
1030 		{
1031 			R_MarkLights (lt, 1<<k, currentmodel->nodes + currentmodel->firstnode);
1032 		}
1033 	}
1034 
1035 	psurf = &currentmodel->surfaces[currentmodel->firstmodelsurface];
1036 
1037 	if ( currententity->flags & RF_TRANSLUCENT )
1038 	{
1039 		qglEnable (GL_BLEND);
1040 		qglColor4f (1,1,1,0.25);
1041 		GL_TexEnv( GL_MODULATE );
1042 	}
1043 
1044 	// MH - detail textures begin
1045 	// null the detail chain again
1046 	r_detailsurfaces = NULL;
1047 	// MH - detail textures end
1048 
1049 	//
1050 	// draw texture
1051 	//
1052 	for (i=0 ; i<currentmodel->nummodelsurfaces ; i++, psurf++)
1053 	{
1054 	// find which side of the node we are on
1055 		pplane = psurf->plane;
1056 
1057 		dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
1058 
1059 	// draw the polygon
1060 		if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
1061 			(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
1062 		{
1063 			if (psurf->texinfo->flags & (SURF_TRANS33|SURF_TRANS66) )
1064 			{	// add to the translucent chain
1065 				psurf->texturechain = r_alpha_surfaces;
1066 				r_alpha_surfaces = psurf;
1067 			}
1068 			else if ( qglMTexCoord2fSGIS && !( psurf->flags & SURF_DRAWTURB ) )
1069 			{
1070 				GL_RenderLightmappedPoly( psurf );
1071 			}
1072 			else
1073 			{
1074 				GL_EnableMultitexture( false );
1075 				R_RenderBrushPoly( psurf );
1076 				GL_EnableMultitexture( true );
1077 			}
1078 		}
1079 	}
1080 
1081 	if ( !(currententity->flags & RF_TRANSLUCENT) )
1082 	{
1083 		if ( !qglMTexCoord2fSGIS )
1084 			R_BlendLightmaps ();
1085 
1086 		// MH - detail textures begin
1087 		// shut down multitexturing (we can't do this in R_DrawDetailSurfaces cos then it
1088 		// messes things up for the world)
1089 		GL_EnableMultitexture (false);
1090 
1091 		// don't put them on translucent surfs
1092 		if(maxTextureUnits<3)	R_DrawDetailSurfaces ();	// slow old school method
1093 
1094 		// bring multitexturing back up
1095 		GL_EnableMultitexture (true);
1096 		// MH - detail textures end
1097 	}
1098 	else
1099 	{
1100 		qglDisable (GL_BLEND);
1101 		qglColor4f (1,1,1,1);
1102 		GL_TexEnv( GL_REPLACE );
1103 	}
1104 }
1105 
1106 /*
1107 =================
1108 R_DrawBrushModel
1109 =================
1110 */
R_DrawBrushModel(entity_t * e)1111 void R_DrawBrushModel (entity_t *e)
1112 {
1113 	vec3_t		mins, maxs;
1114 	int			i;
1115 	qboolean	rotated;
1116 
1117 	if (currentmodel->nummodelsurfaces == 0)
1118 		return;
1119 
1120 	currententity = e;
1121 	gl_state.currenttextures[0] = gl_state.currenttextures[1] = -1;
1122 
1123 	if (e->angles[0] || e->angles[1] || e->angles[2])
1124 	{
1125 		rotated = true;
1126 		for (i=0 ; i<3 ; i++)
1127 		{
1128 			mins[i] = e->origin[i] - currentmodel->radius;
1129 			maxs[i] = e->origin[i] + currentmodel->radius;
1130 		}
1131 	}
1132 	else
1133 	{
1134 		rotated = false;
1135 		VectorAdd (e->origin, currentmodel->mins, mins);
1136 		VectorAdd (e->origin, currentmodel->maxs, maxs);
1137 	}
1138 
1139 	if (R_CullBox (mins, maxs))
1140 		return;
1141 
1142 	qglColor3f (1,1,1);
1143 	memset (gl_lms.lightmap_surfaces, 0, sizeof(gl_lms.lightmap_surfaces));
1144 
1145 	// start MPO
1146 	// if this is a reflection we're drawing we need to flip the vertical position across the water
1147 	if (g_drawing_refl) {
1148 
1149 		float distance;
1150 
1151 		distance = DotProduct(modelorg, waterNormals[g_active_refl]) - g_waterDistance2[g_active_refl];
1152 		VectorMA(r_newrefdef.vieworg, distance*-2, waterNormals[g_active_refl], modelorg);
1153 	}
1154 	// stop MPO
1155 
1156 	VectorSubtract (r_newrefdef.vieworg, e->origin, modelorg);
1157 	if (rotated)
1158 	{
1159 		vec3_t	temp;
1160 		vec3_t	forward, right, up;
1161 
1162 		VectorCopy (modelorg, temp);
1163 		AngleVectors (e->angles, forward, right, up);
1164 		modelorg[0] = DotProduct (temp, forward);
1165 		modelorg[1] = -DotProduct (temp, right);
1166 		modelorg[2] = DotProduct (temp, up);
1167 	}
1168 
1169     qglPushMatrix ();
1170 e->angles[0] = -e->angles[0];	// stupid quake bug
1171 e->angles[2] = -e->angles[2];	// stupid quake bug
1172 	R_RotateForEntity (e);
1173 e->angles[0] = -e->angles[0];	// stupid quake bug
1174 e->angles[2] = -e->angles[2];	// stupid quake bug
1175 
1176 	GL_EnableMultitexture( true );
1177 	GL_SelectTexture( GL_TEXTURE0);
1178 	/* Vic */
1179 #if 0
1180 	GL_TexEnv( GL_REPLACE );
1181 	GL_SelectTexture( GL_TEXTURE1);
1182 	GL_TexEnv( GL_MODULATE );
1183 #else
1184 	if (!gl_config.mtexcombine) {
1185 		GL_TexEnv(GL_REPLACE);
1186 		GL_SelectTexture(GL_TEXTURE1);
1187 
1188 		if (gl_lightmap->value)
1189 			GL_TexEnv(GL_REPLACE);
1190 		else
1191 			GL_TexEnv(GL_MODULATE);
1192 	} else {
1193 		GL_TexEnv(GL_COMBINE_EXT);
1194 		qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);
1195 		qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
1196 		qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
1197 		qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
1198 
1199 		GL_SelectTexture(GL_TEXTURE1);
1200 		GL_TexEnv(GL_COMBINE_EXT);
1201 		if (gl_lightmap->value) {
1202 			qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);
1203 			qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
1204 			qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
1205 			qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
1206 		} else {
1207 			qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
1208 			qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
1209 			qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
1210 
1211 			qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE);
1212 			qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
1213 			qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_EXT);
1214 		}
1215 
1216 		if (gl_overbrightbits->value) {
1217 			qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, gl_overbrightbits->value);
1218 		}
1219 	}
1220 #endif
1221 	/* Vic */
1222 
1223 	R_DrawInlineBModel ();
1224 	GL_EnableMultitexture( false );
1225 
1226 	qglPopMatrix ();
1227 }
1228 
1229 /*
1230 =============================================================
1231 
1232 	WORLD MODEL
1233 
1234 =============================================================
1235 */
1236 
1237 /*
1238 ================
1239 R_RecursiveWorldNode
1240 ================
1241 */
R_RecursiveWorldNode(mnode_t * node)1242 void R_RecursiveWorldNode (mnode_t *node)
1243 {
1244 	int			c, side, sidebit;
1245 	cplane_t	*plane;
1246 	msurface_t	*surf, **mark;
1247 	mleaf_t		*pleaf;
1248 	float		dot;
1249 	image_t		*image;
1250 
1251 	if (node->contents == CONTENTS_SOLID)
1252 		return;		// solid
1253 
1254 	if (node->visframe != r_visframecount)
1255 		return;
1256 	if (R_CullBox (node->minmaxs, node->minmaxs+3))
1257 		return;
1258 
1259 // if a leaf node, draw stuff
1260 	if (node->contents != -1)
1261 	{
1262 		pleaf = (mleaf_t *)node;
1263 
1264 		// check for door connected areas
1265 		if (r_newrefdef.areabits)
1266 		{
1267 			if (! (r_newrefdef.areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) )
1268 				return;		// not visible
1269 		}
1270 
1271 		mark = pleaf->firstmarksurface;
1272 		c = pleaf->nummarksurfaces;
1273 
1274 		if (c)
1275 		{
1276 			do
1277 			{
1278 				(*mark)->visframe = r_framecount;
1279 				mark++;
1280 			} while (--c);
1281 		}
1282 
1283 		return;
1284 	}
1285 
1286 // node is just a decision point, so go down the apropriate sides
1287 
1288 // find which side of the node we are on
1289 	plane = node->plane;
1290 
1291 	switch (plane->type)
1292 	{
1293 	case PLANE_X:
1294 		dot = modelorg[0] - plane->dist;
1295 		break;
1296 	case PLANE_Y:
1297 		dot = modelorg[1] - plane->dist;
1298 		break;
1299 	case PLANE_Z:
1300 		dot = modelorg[2] - plane->dist;
1301 		break;
1302 	default:
1303 		dot = DotProduct (modelorg, plane->normal) - plane->dist;
1304 		break;
1305 	}
1306 
1307 	if (dot >= 0)
1308 	{
1309 		side = 0;
1310 		sidebit = 0;
1311 	}
1312 	else
1313 	{
1314 		side = 1;
1315 		sidebit = SURF_PLANEBACK;
1316 	}
1317 
1318 // recurse down the children, front side first
1319 	R_RecursiveWorldNode (node->children[side]);
1320 
1321 	// draw stuff
1322 	for ( c = node->numsurfaces, surf = r_worldmodel->surfaces + node->firstsurface; c ; c--, surf++)
1323 	{
1324 		if (surf->visframe != r_framecount)
1325 			continue;
1326 
1327 		if ( (surf->flags & SURF_PLANEBACK) != sidebit )
1328 			continue;		// wrong side
1329 
1330 		if (surf->texinfo->flags & SURF_SKY)
1331 		{	// just adds to visible sky bounds
1332 			R_AddSkySurface (surf);
1333 		}
1334 		else if (surf->texinfo->flags & (SURF_TRANS33|SURF_TRANS66))
1335 		{	// add to the translucent chain
1336 			surf->texturechain = r_alpha_surfaces;
1337 			r_alpha_surfaces = surf;
1338 		}
1339 		else
1340 		{
1341 			if ( qglMTexCoord2fSGIS && !( surf->flags & SURF_DRAWTURB ) )
1342 			{
1343 				GL_RenderLightmappedPoly( surf );
1344 			}
1345 			else
1346 			{
1347 				// the polygon is visible, so add it to the texture
1348 				// sorted chain
1349 				// FIXME: this is a hack for animation
1350 				image = R_TextureAnimation (surf->texinfo);
1351 				surf->texturechain = image->texturechain;
1352 				image->texturechain = surf;
1353 			}
1354 		}
1355 		if (gl_showtris->value  &&  qglMTexCoord2fSGIS)	//** DMP added extra check to avoid func call overhead in this inner loop
1356 			R_DrawTriangleOutlines(surf);
1357 	}
1358 
1359 	// recurse down the back side
1360 	R_RecursiveWorldNode (node->children[!side]);
1361 /*
1362 	for ( ; c ; c--, surf++)
1363 	{
1364 		if (surf->visframe != r_framecount)
1365 			continue;
1366 
1367 		if ( (surf->flags & SURF_PLANEBACK) != sidebit )
1368 			continue;		// wrong side
1369 
1370 		if (surf->texinfo->flags & SURF_SKY)
1371 		{	// just adds to visible sky bounds
1372 			R_AddSkySurface (surf);
1373 		}
1374 		else if (surf->texinfo->flags & (SURF_TRANS33|SURF_TRANS66))
1375 		{	// add to the translucent chain
1376 //			surf->texturechain = alpha_surfaces;
1377 //			alpha_surfaces = surf;
1378 		}
1379 		else
1380 		{
1381 			if ( qglMTexCoord2fSGIS && !( surf->flags & SURF_DRAWTURB ) )
1382 			{
1383 				GL_RenderLightmappedPoly( surf );
1384 			}
1385 			else
1386 			{
1387 				// the polygon is visible, so add it to the texture
1388 				// sorted chain
1389 				// FIXME: this is a hack for animation
1390 				image = R_TextureAnimation (surf->texinfo);
1391 				surf->texturechain = image->texturechain;
1392 				image->texturechain = surf;
1393 			}
1394 		}
1395 	}
1396 */
1397 }
1398 
1399 
1400 /*
1401 =============
1402 R_DrawWorld
1403 =============
1404 */
R_DrawWorld(void)1405 void R_DrawWorld (void)
1406 {
1407 	entity_t	ent;
1408 
1409 	if (!r_drawworld->value)
1410 		return;
1411 
1412 	if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
1413 		return;
1414 
1415 	currentmodel = r_worldmodel;
1416 
1417 	VectorCopy (r_newrefdef.vieworg, modelorg);
1418 
1419 	// start MPO
1420 	// if this is a reflection we're drawing, we need to flip vertically across the water
1421 	if (g_drawing_refl)
1422 	{
1423 		float distance;
1424 
1425 		distance = DotProduct(modelorg, waterNormals[g_active_refl]) - g_waterDistance2[g_active_refl];
1426 		VectorMA(r_newrefdef.vieworg, distance*-2, waterNormals[g_active_refl], modelorg);
1427 	}
1428 	// stop MPO
1429 
1430 	// auto cycle the world frame for texture animation
1431 	memset (&ent, 0, sizeof(ent));
1432 	ent.frame = (int)(r_newrefdef.time*2);
1433 	currententity = &ent;
1434 
1435 	gl_state.currenttextures[0] = gl_state.currenttextures[1] = -1;
1436 
1437 	qglColor3f (1,1,1);
1438 	memset (gl_lms.lightmap_surfaces, 0, sizeof(gl_lms.lightmap_surfaces));
1439 	R_ClearSkyBox ();
1440 	// MH - detail textures begin
1441 	r_detailsurfaces = NULL;
1442 	// MH - detail textures end
1443 
1444 	if ( qglMTexCoord2fSGIS )
1445 	{
1446 		GL_EnableMultitexture( true );
1447 
1448 		GL_SelectTexture( GL_TEXTURE0);
1449 		/* Vic */
1450 #if 0
1451 		GL_TexEnv( GL_REPLACE );
1452 		GL_SelectTexture( GL_TEXTURE1);
1453 
1454 		if ( gl_lightmap->value )
1455 			GL_TexEnv( GL_REPLACE );
1456 		else
1457 			GL_TexEnv( GL_MODULATE );
1458 #else
1459 		if (!gl_config.mtexcombine) {
1460 			GL_TexEnv(GL_REPLACE);
1461 			GL_SelectTexture(GL_TEXTURE1);
1462 
1463 			if (gl_lightmap->value)
1464 				GL_TexEnv(GL_REPLACE);
1465 			else
1466 				GL_TexEnv(GL_MODULATE);
1467 		} else {
1468 			GL_TexEnv(GL_COMBINE_EXT);
1469 			qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);
1470 			qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
1471 			qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
1472 			qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
1473 
1474 			GL_SelectTexture(GL_TEXTURE1);
1475 			GL_TexEnv(GL_COMBINE_EXT);
1476 			if (gl_lightmap->value) {
1477 				qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);
1478 				qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
1479 				qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
1480 				qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
1481 			} else {
1482 				qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
1483 				qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
1484 				qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
1485 
1486 				qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE);
1487 				qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
1488 				qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_EXT);
1489 			}
1490 
1491 			if (gl_overbrightbits->value) {
1492 				qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, gl_overbrightbits->value);
1493 			}
1494 		}
1495 #endif
1496 		R_RecursiveWorldNode (r_worldmodel->nodes);
1497 
1498 		GL_EnableMultitexture( false );
1499 	}
1500 	else
1501 	{
1502 		R_RecursiveWorldNode (r_worldmodel->nodes);
1503 	}
1504 
1505 	/*
1506 	** theoretically nothing should happen in the next two functions
1507 	** if multitexture is enabled
1508 	*/
1509 	DrawTextureChains ();
1510 	R_BlendLightmaps ();
1511 
1512 	// MH - detail textures begin
1513 	if(maxTextureUnits<3)
1514 		R_DrawDetailSurfaces ();
1515 	// MH - detail textures end
1516 
1517 	if (gl_fogunderwater->value && (r_newrefdef.rdflags & RDF_UNDERWATER)) {
1518 		if (gl_fogenable->value) {
1519 			qglDisable(GL_FOG);
1520 		}
1521 		R_DrawSkyBox();
1522 	}
1523 	else
1524 		R_DrawSkyBox ();
1525 
1526 	R_DrawTriangleOutlines (NULL);
1527 }
1528 
1529 
1530 /*
1531 ===============
1532 R_MarkLeaves
1533 
1534 Mark the leaves and nodes that are in the PVS for the current
1535 cluster
1536 ===============
1537 */
R_MarkLeaves(void)1538 void R_MarkLeaves (void)
1539 {
1540 	byte	*vis;
1541 	byte	fatvis[MAX_MAP_LEAFS/8];
1542 	mnode_t	*node;
1543 	int		i, c;
1544 	mleaf_t	*leaf;
1545 	int		cluster;
1546 
1547 	if (r_oldviewcluster == r_viewcluster && r_oldviewcluster2 == r_viewcluster2 && !r_novis->value && r_viewcluster != -1)
1548 		return;
1549 
1550 	// development aid to let you run around and see exactly where
1551 	// the pvs ends
1552 	if (gl_lockpvs->value)
1553 		return;
1554 
1555 	r_visframecount++;
1556 	r_oldviewcluster = r_viewcluster;
1557 	r_oldviewcluster2 = r_viewcluster2;
1558 
1559 	if (r_novis->value || r_viewcluster == -1 || !r_worldmodel->vis)
1560 	{
1561 		// mark everything
1562 		for (i=0 ; i<r_worldmodel->numleafs ; i++)
1563 			r_worldmodel->leafs[i].visframe = r_visframecount;
1564 		for (i=0 ; i<r_worldmodel->numnodes ; i++)
1565 			r_worldmodel->nodes[i].visframe = r_visframecount;
1566 		return;
1567 	}
1568 
1569 	vis = Mod_ClusterPVS (r_viewcluster, r_worldmodel);
1570 	// may have to combine two clusters because of solid water boundaries
1571 	if (r_viewcluster2 != r_viewcluster)
1572 	{
1573 		memcpy (fatvis, vis, (r_worldmodel->numleafs+7)/8);
1574 		vis = Mod_ClusterPVS (r_viewcluster2, r_worldmodel);
1575 		c = (r_worldmodel->numleafs+31)/32;
1576 		for (i=0 ; i<c ; i++)
1577 			((int *)fatvis)[i] |= ((int *)vis)[i];
1578 		vis = fatvis;
1579 	}
1580 
1581 	for (i=0,leaf=r_worldmodel->leafs ; i<r_worldmodel->numleafs ; i++, leaf++)
1582 	{
1583 		cluster = leaf->cluster;
1584 		if (cluster == -1)
1585 			continue;
1586 		if (vis[cluster>>3] & (1<<(cluster&7)))
1587 		{
1588 			node = (mnode_t *)leaf;
1589 			do
1590 			{
1591 				if (node->visframe == r_visframecount)
1592 					break;
1593 				node->visframe = r_visframecount;
1594 				node = node->parent;
1595 			} while (node);
1596 		}
1597 	}
1598 }
1599 
1600 
1601 
1602 /*
1603 =============================================================================
1604 
1605   LIGHTMAP ALLOCATION
1606 
1607 =============================================================================
1608 */
1609 
LM_InitBlock(void)1610 static void LM_InitBlock( void )
1611 {
1612 	memset( gl_lms.allocated, 0, sizeof( gl_lms.allocated ) );
1613 }
1614 
LM_UploadBlock(qboolean dynamic)1615 static void LM_UploadBlock( qboolean dynamic )
1616 {
1617 	int texture;
1618 	int height = 0;
1619 
1620 	if ( dynamic )
1621 	{
1622 		texture = 0;
1623 	}
1624 	else
1625 	{
1626 		texture = gl_lms.current_lightmap_texture;
1627 	}
1628 
1629 	GL_Bind( gl_state.lightmap_textures + texture );
1630 	qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1631 	qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1632 
1633 	if ( dynamic )
1634 	{
1635 		int i;
1636 
1637 		for ( i = 0; i < BLOCK_WIDTH; i++ )
1638 		{
1639 			if ( gl_lms.allocated[i] > height )
1640 				height = gl_lms.allocated[i];
1641 		}
1642 
1643 		qglTexSubImage2D( GL_TEXTURE_2D,
1644 						  0,
1645 						  0, 0,
1646 						  BLOCK_WIDTH, height,
1647 						  GL_LIGHTMAP_FORMAT,
1648 						  GL_UNSIGNED_BYTE,
1649 						  gl_lms.lightmap_buffer );
1650 	}
1651 	else
1652 	{
1653 		qglTexImage2D( GL_TEXTURE_2D,
1654 					   0,
1655 					   gl_lms.internal_format,
1656 					   BLOCK_WIDTH, BLOCK_HEIGHT,
1657 					   0,
1658 					   GL_LIGHTMAP_FORMAT,
1659 					   GL_UNSIGNED_BYTE,
1660 					   gl_lms.lightmap_buffer );
1661 		if ( ++gl_lms.current_lightmap_texture == MAX_LIGHTMAPS )
1662 			ri.Sys_Error( ERR_DROP, "LM_UploadBlock() - MAX_LIGHTMAPS exceeded\n" );
1663 	}
1664 }
1665 
1666 // returns a texture number and the position inside it
LM_AllocBlock(int w,int h,int * x,int * y)1667 static qboolean LM_AllocBlock (int w, int h, int *x, int *y)
1668 {
1669 	int		i, j;
1670 	int		best, best2;
1671 
1672 	best = BLOCK_HEIGHT;
1673 
1674 	for (i=0 ; i<BLOCK_WIDTH-w ; i++)
1675 	{
1676 		best2 = 0;
1677 
1678 		for (j=0 ; j<w ; j++)
1679 		{
1680 			if (gl_lms.allocated[i+j] >= best)
1681 				break;
1682 			if (gl_lms.allocated[i+j] > best2)
1683 				best2 = gl_lms.allocated[i+j];
1684 		}
1685 		if (j == w)
1686 		{	// this is a valid spot
1687 			*x = i;
1688 			*y = best = best2;
1689 		}
1690 	}
1691 
1692 	if (best + h > BLOCK_HEIGHT)
1693 		return false;
1694 
1695 	for (i=0 ; i<w ; i++)
1696 		gl_lms.allocated[*x + i] = best + h;
1697 
1698 	return true;
1699 }
1700 
1701 /*
1702 ================
1703 GL_BuildPolygonFromSurface
1704 ================
1705 */
GL_BuildPolygonFromSurface(msurface_t * fa)1706 void GL_BuildPolygonFromSurface(msurface_t *fa)
1707 {
1708 	int			i, lindex, lnumverts;
1709 	medge_t		*pedges, *r_pedge;
1710 	int			vertpage;
1711 	float		*vec;
1712 	float		s, t;
1713 	glpoly_t	*poly;
1714 	vec3_t		total;
1715 
1716 // reconstruct the polygon
1717 	pedges = currentmodel->edges;
1718 	lnumverts = fa->numedges;
1719 	vertpage = 0;
1720 
1721 	VectorClear (total);
1722 	//
1723 	// draw texture
1724 	//
1725 	poly = Hunk_Alloc (sizeof(glpoly_t) + (lnumverts-4) * VERTEXSIZE*sizeof(float));
1726 	poly->next = fa->polys;
1727 	poly->flags = fa->flags;
1728 	fa->polys = poly;
1729 	poly->numverts = lnumverts;
1730 
1731 	for (i=0 ; i<lnumverts ; i++)
1732 	{
1733 		lindex = currentmodel->surfedges[fa->firstedge + i];
1734 
1735 		if (lindex > 0)
1736 		{
1737 			r_pedge = &pedges[lindex];
1738 			vec = currentmodel->vertexes[r_pedge->v[0]].position;
1739 		}
1740 		else
1741 		{
1742 			r_pedge = &pedges[-lindex];
1743 			vec = currentmodel->vertexes[r_pedge->v[1]].position;
1744 		}
1745 		s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
1746 		s /= fa->texinfo->image->width;
1747 
1748 		t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
1749 		t /= fa->texinfo->image->height;
1750 
1751 		VectorAdd (total, vec, total);
1752 		VectorCopy (vec, poly->verts[i]);
1753 		poly->verts[i][3] = s;
1754 		poly->verts[i][4] = t;
1755 
1756 		//
1757 		// lightmap texture coordinates
1758 		//
1759 		s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
1760 		s -= fa->texturemins[0];
1761 		s += fa->light_s*16;
1762 		s += 8;
1763 		s /= BLOCK_WIDTH*16; //fa->texinfo->texture->width;
1764 
1765 		t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
1766 		t -= fa->texturemins[1];
1767 		t += fa->light_t*16;
1768 		t += 8;
1769 		t /= BLOCK_HEIGHT*16; //fa->texinfo->texture->height;
1770 
1771 		poly->verts[i][5] = s;
1772 		poly->verts[i][6] = t;
1773 
1774 		// MH - detail textures begin
1775 		// here we build a set of texture s and t co-ords suitable for a 128 * 128 version
1776 		// of the texture.  this is necessary because using the original texture s and t
1777 		// will cause the detail texture (and anything else we may ever consider adding)
1778 		// to rescale itself to the same aspect ratio as the original texture, which looks
1779 		// bad.  NOTE - to enable this we *must* increase the define of VERTEXSIZE to 9.
1780 
1781 			s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
1782 			s /= 128;
1783 
1784 			t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
1785 			t /= 128;
1786 
1787 			// and load them in
1788 			poly->verts[i][7] = s;
1789 			poly->verts[i][8] = t;
1790 		// MH - detail textures end
1791 	}
1792 
1793 	poly->numverts = lnumverts;
1794 
1795 }
1796 
1797 /*
1798 ========================
1799 GL_CreateSurfaceLightmap
1800 ========================
1801 */
GL_CreateSurfaceLightmap(msurface_t * surf)1802 void GL_CreateSurfaceLightmap (msurface_t *surf)
1803 {
1804 	int		smax, tmax;
1805 	byte	*base;
1806 
1807 	if (surf->flags & (SURF_DRAWSKY|SURF_DRAWTURB))
1808 		return;
1809 
1810 	smax = (surf->extents[0]>>4)+1;
1811 	tmax = (surf->extents[1]>>4)+1;
1812 
1813 	if ( !LM_AllocBlock( smax, tmax, &surf->light_s, &surf->light_t ) )
1814 	{
1815 		LM_UploadBlock( false );
1816 		LM_InitBlock();
1817 		if ( !LM_AllocBlock( smax, tmax, &surf->light_s, &surf->light_t ) )
1818 		{
1819 			ri.Sys_Error( ERR_FATAL, "Consecutive calls to LM_AllocBlock(%d,%d) failed\n", smax, tmax );
1820 		}
1821 	}
1822 
1823 	surf->lightmaptexturenum = gl_lms.current_lightmap_texture;
1824 
1825 	base = gl_lms.lightmap_buffer;
1826 	base += (surf->light_t * BLOCK_WIDTH + surf->light_s) * LIGHTMAP_BYTES;
1827 
1828 	R_SetCacheState( surf );
1829 	R_BuildLightMap (surf, base, BLOCK_WIDTH*LIGHTMAP_BYTES);
1830 }
1831 
1832 
1833 /*
1834 ==================
1835 GL_BeginBuildingLightmaps
1836 
1837 ==================
1838 */
GL_BeginBuildingLightmaps(model_t * m)1839 void GL_BeginBuildingLightmaps (model_t *m)
1840 {
1841 	static lightstyle_t	lightstyles[MAX_LIGHTSTYLES];
1842 	int				i;
1843 	unsigned		dummy[128*128];
1844 
1845 	memset( gl_lms.allocated, 0, sizeof(gl_lms.allocated) );
1846 
1847 	r_framecount = 1;		// no dlightcache
1848 
1849 	GL_EnableMultitexture( true );
1850 	GL_SelectTexture( GL_TEXTURE1);
1851 
1852 	/*
1853 	** setup the base lightstyles so the lightmaps won't have to be regenerated
1854 	** the first time they're seen
1855 	*/
1856 	for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
1857 	{
1858 		lightstyles[i].rgb[0] = 1;
1859 		lightstyles[i].rgb[1] = 1;
1860 		lightstyles[i].rgb[2] = 1;
1861 		lightstyles[i].white = 3;
1862 	}
1863 	r_newrefdef.lightstyles = lightstyles;
1864 
1865 	if (!gl_state.lightmap_textures)
1866 	{
1867 		gl_state.lightmap_textures	= TEXNUM_LIGHTMAPS;
1868 //		gl_state.lightmap_textures	= gl_state.texture_extension_number;
1869 //		gl_state.texture_extension_number = gl_state.lightmap_textures + MAX_LIGHTMAPS;
1870 	}
1871 
1872 	gl_lms.current_lightmap_texture = 1;
1873 
1874 	/*
1875 	** if mono lightmaps are enabled and we want to use alpha
1876 	** blending (a,1-a) then we're likely running on a 3DLabs
1877 	** Permedia2.  In a perfect world we'd use a GL_ALPHA lightmap
1878 	** in order to conserve space and maximize bandwidth, however
1879 	** this isn't a perfect world.
1880 	**
1881 	** So we have to use alpha lightmaps, but stored in GL_RGBA format,
1882 	** which means we only get 1/16th the color resolution we should when
1883 	** using alpha lightmaps.  If we find another board that supports
1884 	** only alpha lightmaps but that can at least support the GL_ALPHA
1885 	** format then we should change this code to use real alpha maps.
1886 	*/
1887 	if ( toupper( gl_monolightmap->string[0] ) == 'A' )
1888 	{
1889 		gl_lms.internal_format = gl_tex_alpha_format;
1890 	}
1891 	/*
1892 	** try to do hacked colored lighting with a blended texture
1893 	*/
1894 	else if ( toupper( gl_monolightmap->string[0] ) == 'C' )
1895 	{
1896 		gl_lms.internal_format = gl_tex_alpha_format;
1897 	}
1898 	else if ( toupper( gl_monolightmap->string[0] ) == 'I' )
1899 	{
1900 		gl_lms.internal_format = GL_INTENSITY8;
1901 	}
1902 	else if ( toupper( gl_monolightmap->string[0] ) == 'L' )
1903 	{
1904 		gl_lms.internal_format = GL_LUMINANCE8;
1905 	}
1906 	else
1907 	{
1908 		gl_lms.internal_format = gl_tex_solid_format;
1909 	}
1910 
1911 	/*
1912 	** initialize the dynamic lightmap texture
1913 	*/
1914 	GL_Bind( gl_state.lightmap_textures + 0 );
1915 	qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1916 	qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1917 	qglTexImage2D( GL_TEXTURE_2D,
1918 				   0,
1919 				   gl_lms.internal_format,
1920 				   BLOCK_WIDTH, BLOCK_HEIGHT,
1921 				   0,
1922 				   GL_LIGHTMAP_FORMAT,
1923 				   GL_UNSIGNED_BYTE,
1924 				   dummy );
1925 }
1926 
1927 /*
1928 =======================
1929 GL_EndBuildingLightmaps
1930 =======================
1931 */
GL_EndBuildingLightmaps(void)1932 void GL_EndBuildingLightmaps (void)
1933 {
1934 	LM_UploadBlock( false );
1935 	GL_EnableMultitexture( false );
1936 }
1937 
1938 
1939 /* sul's minimap thing */
1940 void
R_RecursiveRadarNode(mnode_t * node)1941 R_RecursiveRadarNode(mnode_t * node)
1942 {
1943 	int		c, side, sidebit;
1944 	cplane_t       *plane;
1945 	msurface_t     *surf, **mark;
1946 	mleaf_t        *pleaf;
1947 	float		dot, distance;
1948 	glpoly_t       *p;
1949 	float          *v;
1950 	int		i;
1951 
1952 	if (node->contents == CONTENTS_SOLID)
1953 		return;		/* solid */
1954 
1955 	if (gl_minimap_zoom->value >= 0.1)
1956 		distance = 1024.0 / gl_minimap_zoom->value;
1957 	else
1958 		distance = 1024.0;
1959 
1960 	if (r_origin[0] + distance < node->minmaxs[0] ||
1961 	    r_origin[0] - distance > node->minmaxs[3] ||
1962 
1963 	    r_origin[1] + distance < node->minmaxs[1] ||
1964 	    r_origin[1] - distance > node->minmaxs[4] ||
1965 
1966 	    r_origin[2] + 256 < node->minmaxs[2] ||
1967 	    r_origin[2] - 256 > node->minmaxs[5])
1968 		return;
1969 
1970 	/* if a leaf node, draw stuff */
1971 	if (node->contents != -1) {
1972 		pleaf = (mleaf_t *) node;
1973 		/* check for door connected areas */
1974 		if (r_newrefdef.areabits) {
1975 			if (!(r_newrefdef.areabits[pleaf->area >> 3] & (1 << (pleaf->area & 7))))
1976 				return;	/* not visible */
1977 		}
1978 		mark = pleaf->firstmarksurface;
1979 		c = pleaf->nummarksurfaces;
1980 		if (c) {
1981 			do {
1982 				(*mark)->visframe = r_framecount;
1983 				mark++;
1984 			} while (--c);
1985 		}
1986 		return;
1987 	}
1988 	/* node is just a decision point, so go down the apropriate sides */
1989 	/* find which side of the node we are on */
1990 	plane = node->plane;
1991 
1992 	switch (plane->type) {
1993 	case PLANE_X:
1994 		dot = modelorg[0] - plane->dist;
1995 		break;
1996 	case PLANE_Y:
1997 		dot = modelorg[1] - plane->dist;
1998 		break;
1999 	case PLANE_Z:
2000 		dot = modelorg[2] - plane->dist;
2001 		break;
2002 	default:
2003 		dot = DotProduct(modelorg, plane->normal) - plane->dist;
2004 		break;
2005 	}
2006 
2007 	if (dot >= 0) {
2008 		side = 0;
2009 		sidebit = 0;
2010 	} else {
2011 		side = 1;
2012 		sidebit = SURF_PLANEBACK;
2013 	}
2014 
2015 	/* recurse down the children, front side first */
2016 	R_RecursiveRadarNode(node->children[side]);
2017 
2018 	if (plane->normal[2]) {
2019 		/* draw stuff     */
2020 		if (plane->normal[2] > 0)
2021 			for (c = node->numsurfaces, surf = r_worldmodel->surfaces + node->firstsurface; c; c--, surf++) {
2022 
2023 				if (surf->texinfo->flags & SURF_SKY) {
2024 					continue;
2025 				}
2026 				if (surf->texinfo->flags & (SURF_TRANS33 | SURF_TRANS66))
2027 					qglColor4f(0, 1, 0, 0.5);
2028 				else if (surf->texinfo->flags & (SURF_WARP | SURF_FLOWING))
2029 					qglColor4f(0, 0, 1, 0.5);
2030 				else
2031 					qglColor4f(1, 1, 1, 1);
2032 
2033 				for (p = surf->polys; p; p = p->chain) {
2034 					v = p->verts[0];
2035 
2036 					qglBegin(GL_TRIANGLE_FAN);
2037 					for (i = 0; i < p->numverts; i++, v += VERTEXSIZE)
2038 						qglVertex3fv(v);
2039 					qglEnd();
2040 				}
2041 
2042 			}
2043 	} else {
2044 		qglDisable(GL_TEXTURE_2D);
2045 
2046 		for (c = node->numsurfaces, surf = r_worldmodel->surfaces + node->firstsurface; c; c--, surf++) {
2047 			float		sColor  , C[4];
2048 
2049 			if (surf->texinfo->flags & SURF_SKY) {
2050 				continue;
2051 			}
2052 			if (surf->texinfo->flags & (SURF_WARP | SURF_FLOWING | SURF_TRANS33 | SURF_TRANS66)) {
2053 				sColor = 0.5;
2054 			} else {
2055 				sColor = 0;
2056 			}
2057 
2058 			for (p = surf->polys; p; p = p->chain) {
2059 				v = p->verts[0];
2060 
2061 				qglBegin(GL_LINE_STRIP);
2062 				for (i = 0; i < p->numverts; i++, v += VERTEXSIZE) {
2063 					C[3] = (v[2] - r_origin[2]) / 256.0;
2064 					if (C[3] > 0) {
2065 						C[0] = 0.5;
2066 						C[1] = 0.5 + sColor;
2067 						C[2] = 0.5;
2068 						C[3] = 1 - C[3];
2069 					} else {
2070 						C[0] = 0.5;
2071 						C[1] = sColor;
2072 						C[2] = 0;
2073 						C[3] += 1;
2074 					}
2075 					if (C[3] < 0)
2076 						C[3] = 0;
2077 					qglColor4fv(C);
2078 					qglVertex3fv(v);
2079 				}
2080 				qglEnd();
2081 			}
2082 
2083 		}
2084 		qglEnable(GL_TEXTURE_2D);
2085 	}
2086 	/* recurse down the back side */
2087 	R_RecursiveRadarNode(node->children[!side]);
2088 }
2089 
2090 extern qboolean	have_stencil;
2091 void
GL_DrawRadar(void)2092 GL_DrawRadar(void)
2093 {
2094 
2095 	int		i;
2096 	float		fS[4] = {0, 0, -1.0 / 512.0, 0};
2097 
2098 	if (r_newrefdef.rdflags & RDF_NOWORLDMODEL)
2099 		return;
2100 
2101 	if (!gl_minimap->value)
2102 		return;
2103 
2104 	qglViewport(gl_minimap_x->value - gl_minimap_size->value,
2105                     gl_minimap_y->value - gl_minimap_size->value,
2106                     gl_minimap_size->value, gl_minimap_size->value);
2107 
2108 	GL_TexEnv(GL_MODULATE);
2109 	qglMatrixMode(GL_PROJECTION);
2110 	qglPushMatrix();
2111 	qglLoadIdentity();
2112 
2113 	if (gl_minimap_style->value) {
2114 		qglOrtho(-1024, 1024, -1024, 1024, -256, 256);
2115 	} else {
2116 		qglOrtho(-1024, 1024, -512, 1536, -256, 256);
2117 	}
2118 
2119 	qglMatrixMode(GL_MODELVIEW);
2120 	qglPushMatrix();
2121 	qglLoadIdentity();
2122 
2123 	qglDisable(GL_DEPTH_TEST);
2124 
2125 	if (have_stencil) {
2126 		qglClearStencil(0);
2127 		qglClear(GL_STENCIL_BUFFER_BIT);
2128 		qglEnable(GL_STENCIL_TEST);
2129 		qglStencilFunc(GL_ALWAYS, 4, 4);
2130 		qglStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
2131 
2132 		qglEnable(GL_ALPHA_TEST);
2133 		qglAlphaFunc(GL_LESS, 0.1);
2134 		qglColorMask(0, 0, 0, 0);
2135 		qglColor4f(1, 1, 1, 1);
2136 
2137 		GL_Bind(r_around->texnum);
2138 		qglBegin(GL_TRIANGLE_FAN);
2139 
2140 		if (gl_minimap_style->value) {
2141 			qglTexCoord2f(0, 1);
2142 			qglVertex3f(1024, -1024, 1);
2143 			qglTexCoord2f(1, 1);
2144 			qglVertex3f(-1024, -1024, 1);
2145 			qglTexCoord2f(1, 0);
2146 			qglVertex3f(-1024, 1024, 1);
2147 			qglTexCoord2f(0, 0);
2148 			qglVertex3f(1024, 1024, 1);
2149 		} else {
2150 			qglTexCoord2f(0, 1);
2151 			qglVertex3f(1024, -512, 1);
2152 			qglTexCoord2f(1, 1);
2153 			qglVertex3f(-1024, -512, 1);
2154 			qglTexCoord2f(1, 0);
2155 			qglVertex3f(-1024, 1536, 1);
2156 			qglTexCoord2f(0, 0);
2157 			qglVertex3f(1024, 1536, 1);
2158 		}
2159 
2160 		qglEnd();
2161 
2162 		qglColorMask(1, 1, 1, 1);
2163 		qglDisable(GL_ALPHA_TEST);
2164 		qglAlphaFunc(GL_GREATER, 0.666);
2165 		qglStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
2166 		qglStencilFunc(GL_NOTEQUAL, 4, 4);
2167 	}
2168 	if (gl_minimap_zoom->value >= 0.1)
2169 		qglScalef(gl_minimap_zoom->value, gl_minimap_zoom->value, gl_minimap_zoom->value);
2170 
2171 	if (gl_minimap_style->value) {
2172 		qglPushMatrix();
2173 		qglRotatef(90 - r_newrefdef.viewangles[1], 0, 0, -1);
2174 		qglDisable(GL_TEXTURE_2D);
2175 		qglBegin(GL_TRIANGLES);
2176 		qglColor4f(1, 1, 0, 0.5);
2177 		qglVertex3f(0, 32, 0);
2178 		qglColor4f(1, 1, 0, 0.5);
2179 		qglVertex3f(24, -32, 0);
2180 		qglVertex3f(-24, -32, 0);
2181 		qglEnd();
2182 		qglPopMatrix();
2183 	} else {
2184 		qglDisable(GL_TEXTURE_2D);
2185 		qglBegin(GL_TRIANGLES);
2186 		qglColor4f(1, 1, 0, 0.5);
2187 		qglVertex3f(0, 32, 0);
2188 		qglColor4f(1, 1, 0, 0.5);
2189 		qglVertex3f(24, -32, 0);
2190 		qglVertex3f(-24, -32, 0);
2191 		qglEnd();
2192 		qglRotatef(90 - r_newrefdef.viewangles[1], 0, 0, 1);
2193 	}
2194 
2195 	qglTranslatef(-r_newrefdef.vieworg[0], -r_newrefdef.vieworg[1], -r_newrefdef.vieworg[2]);
2196 
2197 	if (gl_minimap->value == 2) {
2198 		qglBegin(GL_QUADS);
2199 	} else {
2200 		qglBegin(GL_TRIANGLES);
2201 	}
2202 
2203 	for (i = 0; i < numRadarEnts; i++) {
2204 		float		x = RadarEnts[i].org[0];
2205 		float		y = RadarEnts[i].org[1];
2206 		float		z = RadarEnts[i].org[2];
2207 
2208 		qglColor4fv(RadarEnts[i].color);
2209 
2210 		if (gl_minimap->value == 2) {
2211 			qglVertex3f(x + 9, y + 9, z);
2212 			qglVertex3f(x + 9, y - 9, z);
2213 			qglVertex3f(x - 9, y - 9, z);
2214 			qglVertex3f(x - 9, y + 9, z);
2215 		} else {
2216 			qglVertex3f(x, y + 32, z);
2217 			qglVertex3f(x + 27.7128, y - 16, z);
2218 			qglVertex3f(x - 27.7128, y - 16, z);
2219 
2220 			qglVertex3f(x, y - 32, z);
2221 			qglVertex3f(x - 27.7128, y + 16, z);
2222 			qglVertex3f(x + 27.7128, y + 16, z);
2223 		}
2224 	}
2225 
2226 	qglEnd();
2227 
2228 	qglEnable(GL_TEXTURE_2D);
2229 
2230 	GL_Bind(r_radarmap->texnum);
2231 	qglBlendFunc(GL_SRC_ALPHA, GL_ONE);
2232 	qglEnable(GL_BLEND);
2233 	qglColor3f(1, 1, 1);
2234 
2235 	fS[3] = 0.5 + r_newrefdef.vieworg[2] / 512.0;
2236 	qglTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
2237 
2238 	GLSTATE_ENABLE_TEXGEN;
2239 	qglTexGenfv(GL_S, GL_OBJECT_PLANE, fS);
2240 
2241 	/* draw the stuff */
2242 	R_RecursiveRadarNode(r_worldmodel->nodes);
2243 
2244 	qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2245 	GLSTATE_DISABLE_TEXGEN;
2246 
2247 	qglPopMatrix();
2248 
2249 	if (have_stencil)
2250 		qglDisable(GL_STENCIL_TEST);
2251 
2252 	qglViewport(gl_minimap_x->value, gl_minimap_y->value, vid.width, vid.height);
2253 
2254 	GL_TexEnv(GL_REPLACE);
2255 
2256 	qglMatrixMode(GL_PROJECTION);
2257 	qglPopMatrix();
2258 	qglMatrixMode(GL_MODELVIEW);
2259 
2260 }
2261 
2262 
2263 
2264 
2265 
2266 
2267 
2268