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 = ¤tmodel->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