gl_rsurf.c (34883B)
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 25 static vec3_t modelorg; // relative to viewpoint 26 27 msurface_t *r_alpha_surfaces; 28 29 #define DYNAMIC_LIGHT_WIDTH 128 30 #define DYNAMIC_LIGHT_HEIGHT 128 31 32 #define LIGHTMAP_BYTES 4 33 34 #define BLOCK_WIDTH 128 35 #define BLOCK_HEIGHT 128 36 37 #define MAX_LIGHTMAPS 128 38 39 int c_visible_lightmaps; 40 int c_visible_textures; 41 42 #define GL_LIGHTMAP_FORMAT GL_RGBA 43 44 typedef struct 45 { 46 int internal_format; 47 int current_lightmap_texture; 48 49 msurface_t *lightmap_surfaces[MAX_LIGHTMAPS]; 50 51 int allocated[BLOCK_WIDTH]; 52 53 // the lightmap texture data needs to be kept in 54 // main memory so texsubimage can update properly 55 byte lightmap_buffer[4*BLOCK_WIDTH*BLOCK_HEIGHT]; 56 } gllightmapstate_t; 57 58 static gllightmapstate_t gl_lms; 59 60 61 static void LM_InitBlock( void ); 62 static void LM_UploadBlock( qboolean dynamic ); 63 static qboolean LM_AllocBlock (int w, int h, int *x, int *y); 64 65 extern void R_SetCacheState( msurface_t *surf ); 66 extern void R_BuildLightMap (msurface_t *surf, byte *dest, int stride); 67 68 /* 69 ============================================================= 70 71 BRUSH MODELS 72 73 ============================================================= 74 */ 75 76 /* 77 =============== 78 R_TextureAnimation 79 80 Returns the proper texture for a given time and base texture 81 =============== 82 */ 83 image_t *R_TextureAnimation (mtexinfo_t *tex) 84 { 85 int c; 86 87 if (!tex->next) 88 return tex->image; 89 90 c = currententity->frame % tex->numframes; 91 while (c) 92 { 93 tex = tex->next; 94 c--; 95 } 96 97 return tex->image; 98 } 99 100 #if 0 101 /* 102 ================= 103 WaterWarpPolyVerts 104 105 Mangles the x and y coordinates in a copy of the poly 106 so that any drawing routine can be water warped 107 ================= 108 */ 109 glpoly_t *WaterWarpPolyVerts (glpoly_t *p) 110 { 111 int i; 112 float *v, *nv; 113 static byte buffer[1024]; 114 glpoly_t *out; 115 116 out = (glpoly_t *)buffer; 117 118 out->numverts = p->numverts; 119 v = p->verts[0]; 120 nv = out->verts[0]; 121 for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE, nv+=VERTEXSIZE) 122 { 123 nv[0] = v[0] + 4*sin(v[1]*0.05+r_newrefdef.time)*sin(v[2]*0.05+r_newrefdef.time); 124 nv[1] = v[1] + 4*sin(v[0]*0.05+r_newrefdef.time)*sin(v[2]*0.05+r_newrefdef.time); 125 126 nv[2] = v[2]; 127 nv[3] = v[3]; 128 nv[4] = v[4]; 129 nv[5] = v[5]; 130 nv[6] = v[6]; 131 } 132 133 return out; 134 } 135 136 /* 137 ================ 138 DrawGLWaterPoly 139 140 Warp the vertex coordinates 141 ================ 142 */ 143 void DrawGLWaterPoly (glpoly_t *p) 144 { 145 int i; 146 float *v; 147 148 p = WaterWarpPolyVerts (p); 149 qglBegin (GL_TRIANGLE_FAN); 150 v = p->verts[0]; 151 for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE) 152 { 153 qglTexCoord2f (v[3], v[4]); 154 qglVertex3fv (v); 155 } 156 qglEnd (); 157 } 158 void DrawGLWaterPolyLightmap (glpoly_t *p) 159 { 160 int i; 161 float *v; 162 163 p = WaterWarpPolyVerts (p); 164 qglBegin (GL_TRIANGLE_FAN); 165 v = p->verts[0]; 166 for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE) 167 { 168 qglTexCoord2f (v[5], v[6]); 169 qglVertex3fv (v); 170 } 171 qglEnd (); 172 } 173 #endif 174 175 /* 176 ================ 177 DrawGLPoly 178 ================ 179 */ 180 void DrawGLPoly (glpoly_t *p) 181 { 182 int i; 183 float *v; 184 185 qglBegin (GL_POLYGON); 186 v = p->verts[0]; 187 for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE) 188 { 189 qglTexCoord2f (v[3], v[4]); 190 qglVertex3fv (v); 191 } 192 qglEnd (); 193 } 194 195 //============ 196 //PGM 197 /* 198 ================ 199 DrawGLFlowingPoly -- version of DrawGLPoly that handles scrolling texture 200 ================ 201 */ 202 void DrawGLFlowingPoly (msurface_t *fa) 203 { 204 int i; 205 float *v; 206 glpoly_t *p; 207 float scroll; 208 209 p = fa->polys; 210 211 scroll = -64 * ( (r_newrefdef.time / 40.0) - (int)(r_newrefdef.time / 40.0) ); 212 if(scroll == 0.0) 213 scroll = -64.0; 214 215 qglBegin (GL_POLYGON); 216 v = p->verts[0]; 217 for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE) 218 { 219 qglTexCoord2f ((v[3] + scroll), v[4]); 220 qglVertex3fv (v); 221 } 222 qglEnd (); 223 } 224 //PGM 225 //============ 226 227 /* 228 ** R_DrawTriangleOutlines 229 */ 230 void R_DrawTriangleOutlines (void) 231 { 232 int i, j; 233 glpoly_t *p; 234 235 if (!gl_showtris->value) 236 return; 237 238 qglDisable (GL_TEXTURE_2D); 239 qglDisable (GL_DEPTH_TEST); 240 qglColor4f (1,1,1,1); 241 242 for (i=0 ; i<MAX_LIGHTMAPS ; i++) 243 { 244 msurface_t *surf; 245 246 for ( surf = gl_lms.lightmap_surfaces[i]; surf != 0; surf = surf->lightmapchain ) 247 { 248 p = surf->polys; 249 for ( ; p ; p=p->chain) 250 { 251 for (j=2 ; j<p->numverts ; j++ ) 252 { 253 qglBegin (GL_LINE_STRIP); 254 qglVertex3fv (p->verts[0]); 255 qglVertex3fv (p->verts[j-1]); 256 qglVertex3fv (p->verts[j]); 257 qglVertex3fv (p->verts[0]); 258 qglEnd (); 259 } 260 } 261 } 262 } 263 264 qglEnable (GL_DEPTH_TEST); 265 qglEnable (GL_TEXTURE_2D); 266 } 267 268 /* 269 ** DrawGLPolyChain 270 */ 271 void DrawGLPolyChain( glpoly_t *p, float soffset, float toffset ) 272 { 273 if ( soffset == 0 && toffset == 0 ) 274 { 275 for ( ; p != 0; p = p->chain ) 276 { 277 float *v; 278 int j; 279 280 qglBegin (GL_POLYGON); 281 v = p->verts[0]; 282 for (j=0 ; j<p->numverts ; j++, v+= VERTEXSIZE) 283 { 284 qglTexCoord2f (v[5], v[6] ); 285 qglVertex3fv (v); 286 } 287 qglEnd (); 288 } 289 } 290 else 291 { 292 for ( ; p != 0; p = p->chain ) 293 { 294 float *v; 295 int j; 296 297 qglBegin (GL_POLYGON); 298 v = p->verts[0]; 299 for (j=0 ; j<p->numverts ; j++, v+= VERTEXSIZE) 300 { 301 qglTexCoord2f (v[5] - soffset, v[6] - toffset ); 302 qglVertex3fv (v); 303 } 304 qglEnd (); 305 } 306 } 307 } 308 309 /* 310 ** R_BlendLightMaps 311 ** 312 ** This routine takes all the given light mapped surfaces in the world and 313 ** blends them into the framebuffer. 314 */ 315 void R_BlendLightmaps (void) 316 { 317 int i; 318 msurface_t *surf, *newdrawsurf = 0; 319 320 // don't bother if we're set to fullbright 321 if (r_fullbright->value) 322 return; 323 if (!r_worldmodel->lightdata) 324 return; 325 326 // don't bother writing Z 327 qglDepthMask( 0 ); 328 329 /* 330 ** set the appropriate blending mode unless we're only looking at the 331 ** lightmaps. 332 */ 333 if (!gl_lightmap->value) 334 { 335 qglEnable (GL_BLEND); 336 337 if ( gl_saturatelighting->value ) 338 { 339 qglBlendFunc( GL_ONE, GL_ONE ); 340 } 341 else 342 { 343 if ( gl_monolightmap->string[0] != '0' ) 344 { 345 switch ( toupper( gl_monolightmap->string[0] ) ) 346 { 347 case 'I': 348 qglBlendFunc (GL_ZERO, GL_SRC_COLOR ); 349 break; 350 case 'L': 351 qglBlendFunc (GL_ZERO, GL_SRC_COLOR ); 352 break; 353 case 'A': 354 default: 355 qglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); 356 break; 357 } 358 } 359 else 360 { 361 qglBlendFunc (GL_ZERO, GL_SRC_COLOR ); 362 } 363 } 364 } 365 366 if ( currentmodel == r_worldmodel ) 367 c_visible_lightmaps = 0; 368 369 /* 370 ** render static lightmaps first 371 */ 372 for ( i = 1; i < MAX_LIGHTMAPS; i++ ) 373 { 374 if ( gl_lms.lightmap_surfaces[i] ) 375 { 376 if (currentmodel == r_worldmodel) 377 c_visible_lightmaps++; 378 GL_Bind( gl_state.lightmap_textures + i); 379 380 for ( surf = gl_lms.lightmap_surfaces[i]; surf != 0; surf = surf->lightmapchain ) 381 { 382 if ( surf->polys ) 383 DrawGLPolyChain( surf->polys, 0, 0 ); 384 } 385 } 386 } 387 388 /* 389 ** render dynamic lightmaps 390 */ 391 if ( gl_dynamic->value ) 392 { 393 LM_InitBlock(); 394 395 GL_Bind( gl_state.lightmap_textures+0 ); 396 397 if (currentmodel == r_worldmodel) 398 c_visible_lightmaps++; 399 400 newdrawsurf = gl_lms.lightmap_surfaces[0]; 401 402 for ( surf = gl_lms.lightmap_surfaces[0]; surf != 0; surf = surf->lightmapchain ) 403 { 404 int smax, tmax; 405 byte *base; 406 407 smax = (surf->extents[0]>>4)+1; 408 tmax = (surf->extents[1]>>4)+1; 409 410 if ( LM_AllocBlock( smax, tmax, &surf->dlight_s, &surf->dlight_t ) ) 411 { 412 base = gl_lms.lightmap_buffer; 413 base += ( surf->dlight_t * BLOCK_WIDTH + surf->dlight_s ) * LIGHTMAP_BYTES; 414 415 R_BuildLightMap (surf, base, BLOCK_WIDTH*LIGHTMAP_BYTES); 416 } 417 else 418 { 419 msurface_t *drawsurf; 420 421 // upload what we have so far 422 LM_UploadBlock( true ); 423 424 // draw all surfaces that use this lightmap 425 for ( drawsurf = newdrawsurf; drawsurf != surf; drawsurf = drawsurf->lightmapchain ) 426 { 427 if ( drawsurf->polys ) 428 DrawGLPolyChain( drawsurf->polys, 429 ( drawsurf->light_s - drawsurf->dlight_s ) * ( 1.0 / 128.0 ), 430 ( drawsurf->light_t - drawsurf->dlight_t ) * ( 1.0 / 128.0 ) ); 431 } 432 433 newdrawsurf = drawsurf; 434 435 // clear the block 436 LM_InitBlock(); 437 438 // try uploading the block now 439 if ( !LM_AllocBlock( smax, tmax, &surf->dlight_s, &surf->dlight_t ) ) 440 { 441 ri.Sys_Error( ERR_FATAL, "Consecutive calls to LM_AllocBlock(%d,%d) failed (dynamic)\n", smax, tmax ); 442 } 443 444 base = gl_lms.lightmap_buffer; 445 base += ( surf->dlight_t * BLOCK_WIDTH + surf->dlight_s ) * LIGHTMAP_BYTES; 446 447 R_BuildLightMap (surf, base, BLOCK_WIDTH*LIGHTMAP_BYTES); 448 } 449 } 450 451 /* 452 ** draw remainder of dynamic lightmaps that haven't been uploaded yet 453 */ 454 if ( newdrawsurf ) 455 LM_UploadBlock( true ); 456 457 for ( surf = newdrawsurf; surf != 0; surf = surf->lightmapchain ) 458 { 459 if ( surf->polys ) 460 DrawGLPolyChain( surf->polys, ( surf->light_s - surf->dlight_s ) * ( 1.0 / 128.0 ), ( surf->light_t - surf->dlight_t ) * ( 1.0 / 128.0 ) ); 461 } 462 } 463 464 /* 465 ** restore state 466 */ 467 qglDisable (GL_BLEND); 468 qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 469 qglDepthMask( 1 ); 470 } 471 472 /* 473 ================ 474 R_RenderBrushPoly 475 ================ 476 */ 477 void R_RenderBrushPoly (msurface_t *fa) 478 { 479 int maps; 480 image_t *image; 481 qboolean is_dynamic = false; 482 483 c_brush_polys++; 484 485 image = R_TextureAnimation (fa->texinfo); 486 487 if (fa->flags & SURF_DRAWTURB) 488 { 489 GL_Bind( image->texnum ); 490 491 // warp texture, no lightmaps 492 GL_TexEnv( GL_MODULATE ); 493 qglColor4f( gl_state.inverse_intensity, 494 gl_state.inverse_intensity, 495 gl_state.inverse_intensity, 496 1.0F ); 497 EmitWaterPolys (fa); 498 GL_TexEnv( GL_REPLACE ); 499 500 return; 501 } 502 else 503 { 504 GL_Bind( image->texnum ); 505 506 GL_TexEnv( GL_REPLACE ); 507 } 508 509 //====== 510 //PGM 511 if(fa->texinfo->flags & SURF_FLOWING) 512 DrawGLFlowingPoly (fa); 513 else 514 DrawGLPoly (fa->polys); 515 //PGM 516 //====== 517 518 /* 519 ** check for lightmap modification 520 */ 521 for ( maps = 0; maps < MAXLIGHTMAPS && fa->styles[maps] != 255; maps++ ) 522 { 523 if ( r_newrefdef.lightstyles[fa->styles[maps]].white != fa->cached_light[maps] ) 524 goto dynamic; 525 } 526 527 // dynamic this frame or dynamic previously 528 if ( ( fa->dlightframe == r_framecount ) ) 529 { 530 dynamic: 531 if ( gl_dynamic->value ) 532 { 533 if (!( fa->texinfo->flags & (SURF_SKY|SURF_TRANS33|SURF_TRANS66|SURF_WARP ) ) ) 534 { 535 is_dynamic = true; 536 } 537 } 538 } 539 540 if ( is_dynamic ) 541 { 542 if ( ( fa->styles[maps] >= 32 || fa->styles[maps] == 0 ) && ( fa->dlightframe != r_framecount ) ) 543 { 544 unsigned temp[34*34]; 545 int smax, tmax; 546 547 smax = (fa->extents[0]>>4)+1; 548 tmax = (fa->extents[1]>>4)+1; 549 550 R_BuildLightMap( fa, (void *)temp, smax*4 ); 551 R_SetCacheState( fa ); 552 553 GL_Bind( gl_state.lightmap_textures + fa->lightmaptexturenum ); 554 555 qglTexSubImage2D( GL_TEXTURE_2D, 0, 556 fa->light_s, fa->light_t, 557 smax, tmax, 558 GL_LIGHTMAP_FORMAT, 559 GL_UNSIGNED_BYTE, temp ); 560 561 fa->lightmapchain = gl_lms.lightmap_surfaces[fa->lightmaptexturenum]; 562 gl_lms.lightmap_surfaces[fa->lightmaptexturenum] = fa; 563 } 564 else 565 { 566 fa->lightmapchain = gl_lms.lightmap_surfaces[0]; 567 gl_lms.lightmap_surfaces[0] = fa; 568 } 569 } 570 else 571 { 572 fa->lightmapchain = gl_lms.lightmap_surfaces[fa->lightmaptexturenum]; 573 gl_lms.lightmap_surfaces[fa->lightmaptexturenum] = fa; 574 } 575 } 576 577 578 /* 579 ================ 580 R_DrawAlphaSurfaces 581 582 Draw water surfaces and windows. 583 The BSP tree is waled front to back, so unwinding the chain 584 of alpha_surfaces will draw back to front, giving proper ordering. 585 ================ 586 */ 587 void R_DrawAlphaSurfaces (void) 588 { 589 msurface_t *s; 590 float intens; 591 592 // 593 // go back to the world matrix 594 // 595 qglLoadMatrixf (r_world_matrix); 596 597 qglEnable (GL_BLEND); 598 GL_TexEnv( GL_MODULATE ); 599 600 // the textures are prescaled up for a better lighting range, 601 // so scale it back down 602 intens = gl_state.inverse_intensity; 603 604 for (s=r_alpha_surfaces ; s ; s=s->texturechain) 605 { 606 GL_Bind(s->texinfo->image->texnum); 607 c_brush_polys++; 608 if (s->texinfo->flags & SURF_TRANS33) 609 qglColor4f (intens,intens,intens,0.33); 610 else if (s->texinfo->flags & SURF_TRANS66) 611 qglColor4f (intens,intens,intens,0.66); 612 else 613 qglColor4f (intens,intens,intens,1); 614 if (s->flags & SURF_DRAWTURB) 615 EmitWaterPolys (s); 616 else 617 DrawGLPoly (s->polys); 618 } 619 620 GL_TexEnv( GL_REPLACE ); 621 qglColor4f (1,1,1,1); 622 qglDisable (GL_BLEND); 623 624 r_alpha_surfaces = NULL; 625 } 626 627 /* 628 ================ 629 DrawTextureChains 630 ================ 631 */ 632 void DrawTextureChains (void) 633 { 634 int i; 635 msurface_t *s; 636 image_t *image; 637 638 c_visible_textures = 0; 639 640 // GL_TexEnv( GL_REPLACE ); 641 642 if ( !qglSelectTextureSGIS ) 643 { 644 for ( i = 0, image=gltextures ; i<numgltextures ; i++,image++) 645 { 646 if (!image->registration_sequence) 647 continue; 648 s = image->texturechain; 649 if (!s) 650 continue; 651 c_visible_textures++; 652 653 for ( ; s ; s=s->texturechain) 654 R_RenderBrushPoly (s); 655 656 image->texturechain = NULL; 657 } 658 } 659 else 660 { 661 for ( i = 0, image=gltextures ; i<numgltextures ; i++,image++) 662 { 663 if (!image->registration_sequence) 664 continue; 665 if (!image->texturechain) 666 continue; 667 c_visible_textures++; 668 669 for ( s = image->texturechain; s ; s=s->texturechain) 670 { 671 if ( !( s->flags & SURF_DRAWTURB ) ) 672 R_RenderBrushPoly (s); 673 } 674 } 675 676 GL_EnableMultitexture( false ); 677 for ( i = 0, image=gltextures ; i<numgltextures ; i++,image++) 678 { 679 if (!image->registration_sequence) 680 continue; 681 s = image->texturechain; 682 if (!s) 683 continue; 684 685 for ( ; s ; s=s->texturechain) 686 { 687 if ( s->flags & SURF_DRAWTURB ) 688 R_RenderBrushPoly (s); 689 } 690 691 image->texturechain = NULL; 692 } 693 // GL_EnableMultitexture( true ); 694 } 695 696 GL_TexEnv( GL_REPLACE ); 697 } 698 699 700 static void GL_RenderLightmappedPoly( msurface_t *surf ) 701 { 702 int i, nv = surf->polys->numverts; 703 int map; 704 float *v; 705 image_t *image = R_TextureAnimation( surf->texinfo ); 706 qboolean is_dynamic = false; 707 unsigned lmtex = surf->lightmaptexturenum; 708 glpoly_t *p; 709 710 for ( map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++ ) 711 { 712 if ( r_newrefdef.lightstyles[surf->styles[map]].white != surf->cached_light[map] ) 713 goto dynamic; 714 } 715 716 // dynamic this frame or dynamic previously 717 if ( ( surf->dlightframe == r_framecount ) ) 718 { 719 dynamic: 720 if ( gl_dynamic->value ) 721 { 722 if ( !(surf->texinfo->flags & (SURF_SKY|SURF_TRANS33|SURF_TRANS66|SURF_WARP ) ) ) 723 { 724 is_dynamic = true; 725 } 726 } 727 } 728 729 if ( is_dynamic ) 730 { 731 unsigned temp[128*128]; 732 int smax, tmax; 733 734 if ( ( surf->styles[map] >= 32 || surf->styles[map] == 0 ) && ( surf->dlightframe != r_framecount ) ) 735 { 736 smax = (surf->extents[0]>>4)+1; 737 tmax = (surf->extents[1]>>4)+1; 738 739 R_BuildLightMap( surf, (void *)temp, smax*4 ); 740 R_SetCacheState( surf ); 741 742 GL_MBind( GL_TEXTURE1_SGIS, gl_state.lightmap_textures + surf->lightmaptexturenum ); 743 744 lmtex = surf->lightmaptexturenum; 745 746 qglTexSubImage2D( GL_TEXTURE_2D, 0, 747 surf->light_s, surf->light_t, 748 smax, tmax, 749 GL_LIGHTMAP_FORMAT, 750 GL_UNSIGNED_BYTE, temp ); 751 752 } 753 else 754 { 755 smax = (surf->extents[0]>>4)+1; 756 tmax = (surf->extents[1]>>4)+1; 757 758 R_BuildLightMap( surf, (void *)temp, smax*4 ); 759 760 GL_MBind( GL_TEXTURE1_SGIS, gl_state.lightmap_textures + 0 ); 761 762 lmtex = 0; 763 764 qglTexSubImage2D( GL_TEXTURE_2D, 0, 765 surf->light_s, surf->light_t, 766 smax, tmax, 767 GL_LIGHTMAP_FORMAT, 768 GL_UNSIGNED_BYTE, temp ); 769 770 } 771 772 c_brush_polys++; 773 774 GL_MBind( GL_TEXTURE0_SGIS, image->texnum ); 775 GL_MBind( GL_TEXTURE1_SGIS, gl_state.lightmap_textures + lmtex ); 776 777 //========== 778 //PGM 779 if (surf->texinfo->flags & SURF_FLOWING) 780 { 781 float scroll; 782 783 scroll = -64 * ( (r_newrefdef.time / 40.0) - (int)(r_newrefdef.time / 40.0) ); 784 if(scroll == 0.0) 785 scroll = -64.0; 786 787 for ( p = surf->polys; p; p = p->chain ) 788 { 789 v = p->verts[0]; 790 qglBegin (GL_POLYGON); 791 for (i=0 ; i< nv; i++, v+= VERTEXSIZE) 792 { 793 qglMTexCoord2fSGIS( GL_TEXTURE0_SGIS, (v[3]+scroll), v[4]); 794 qglMTexCoord2fSGIS( GL_TEXTURE1_SGIS, v[5], v[6]); 795 qglVertex3fv (v); 796 } 797 qglEnd (); 798 } 799 } 800 else 801 { 802 for ( p = surf->polys; p; p = p->chain ) 803 { 804 v = p->verts[0]; 805 qglBegin (GL_POLYGON); 806 for (i=0 ; i< nv; i++, v+= VERTEXSIZE) 807 { 808 qglMTexCoord2fSGIS( GL_TEXTURE0_SGIS, v[3], v[4]); 809 qglMTexCoord2fSGIS( GL_TEXTURE1_SGIS, v[5], v[6]); 810 qglVertex3fv (v); 811 } 812 qglEnd (); 813 } 814 } 815 //PGM 816 //========== 817 } 818 else 819 { 820 c_brush_polys++; 821 822 GL_MBind( GL_TEXTURE0_SGIS, image->texnum ); 823 GL_MBind( GL_TEXTURE1_SGIS, gl_state.lightmap_textures + lmtex ); 824 825 //========== 826 //PGM 827 if (surf->texinfo->flags & SURF_FLOWING) 828 { 829 float scroll; 830 831 scroll = -64 * ( (r_newrefdef.time / 40.0) - (int)(r_newrefdef.time / 40.0) ); 832 if(scroll == 0.0) 833 scroll = -64.0; 834 835 for ( p = surf->polys; p; p = p->chain ) 836 { 837 v = p->verts[0]; 838 qglBegin (GL_POLYGON); 839 for (i=0 ; i< nv; i++, v+= VERTEXSIZE) 840 { 841 qglMTexCoord2fSGIS( GL_TEXTURE0_SGIS, (v[3]+scroll), v[4]); 842 qglMTexCoord2fSGIS( GL_TEXTURE1_SGIS, v[5], v[6]); 843 qglVertex3fv (v); 844 } 845 qglEnd (); 846 } 847 } 848 else 849 { 850 //PGM 851 //========== 852 for ( p = surf->polys; p; p = p->chain ) 853 { 854 v = p->verts[0]; 855 qglBegin (GL_POLYGON); 856 for (i=0 ; i< nv; i++, v+= VERTEXSIZE) 857 { 858 qglMTexCoord2fSGIS( GL_TEXTURE0_SGIS, v[3], v[4]); 859 qglMTexCoord2fSGIS( GL_TEXTURE1_SGIS, v[5], v[6]); 860 qglVertex3fv (v); 861 } 862 qglEnd (); 863 } 864 //========== 865 //PGM 866 } 867 //PGM 868 //========== 869 } 870 } 871 872 /* 873 ================= 874 R_DrawInlineBModel 875 ================= 876 */ 877 void R_DrawInlineBModel (void) 878 { 879 int i, k; 880 cplane_t *pplane; 881 float dot; 882 msurface_t *psurf; 883 dlight_t *lt; 884 885 // calculate dynamic lighting for bmodel 886 if ( !gl_flashblend->value ) 887 { 888 lt = r_newrefdef.dlights; 889 for (k=0 ; k<r_newrefdef.num_dlights ; k++, lt++) 890 { 891 R_MarkLights (lt, 1<<k, currentmodel->nodes + currentmodel->firstnode); 892 } 893 } 894 895 psurf = ¤tmodel->surfaces[currentmodel->firstmodelsurface]; 896 897 if ( currententity->flags & RF_TRANSLUCENT ) 898 { 899 qglEnable (GL_BLEND); 900 qglColor4f (1,1,1,0.25); 901 GL_TexEnv( GL_MODULATE ); 902 } 903 904 // 905 // draw texture 906 // 907 for (i=0 ; i<currentmodel->nummodelsurfaces ; i++, psurf++) 908 { 909 // find which side of the node we are on 910 pplane = psurf->plane; 911 912 dot = DotProduct (modelorg, pplane->normal) - pplane->dist; 913 914 // draw the polygon 915 if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) || 916 (!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) 917 { 918 if (psurf->texinfo->flags & (SURF_TRANS33|SURF_TRANS66) ) 919 { // add to the translucent chain 920 psurf->texturechain = r_alpha_surfaces; 921 r_alpha_surfaces = psurf; 922 } 923 else if ( qglMTexCoord2fSGIS && !( psurf->flags & SURF_DRAWTURB ) ) 924 { 925 GL_RenderLightmappedPoly( psurf ); 926 } 927 else 928 { 929 GL_EnableMultitexture( false ); 930 R_RenderBrushPoly( psurf ); 931 GL_EnableMultitexture( true ); 932 } 933 } 934 } 935 936 if ( !(currententity->flags & RF_TRANSLUCENT) ) 937 { 938 if ( !qglMTexCoord2fSGIS ) 939 R_BlendLightmaps (); 940 } 941 else 942 { 943 qglDisable (GL_BLEND); 944 qglColor4f (1,1,1,1); 945 GL_TexEnv( GL_REPLACE ); 946 } 947 } 948 949 /* 950 ================= 951 R_DrawBrushModel 952 ================= 953 */ 954 void R_DrawBrushModel (entity_t *e) 955 { 956 vec3_t mins, maxs; 957 int i; 958 qboolean rotated; 959 960 if (currentmodel->nummodelsurfaces == 0) 961 return; 962 963 currententity = e; 964 gl_state.currenttextures[0] = gl_state.currenttextures[1] = -1; 965 966 if (e->angles[0] || e->angles[1] || e->angles[2]) 967 { 968 rotated = true; 969 for (i=0 ; i<3 ; i++) 970 { 971 mins[i] = e->origin[i] - currentmodel->radius; 972 maxs[i] = e->origin[i] + currentmodel->radius; 973 } 974 } 975 else 976 { 977 rotated = false; 978 VectorAdd (e->origin, currentmodel->mins, mins); 979 VectorAdd (e->origin, currentmodel->maxs, maxs); 980 } 981 982 if (R_CullBox (mins, maxs)) 983 return; 984 985 qglColor3f (1,1,1); 986 memset (gl_lms.lightmap_surfaces, 0, sizeof(gl_lms.lightmap_surfaces)); 987 988 VectorSubtract (r_newrefdef.vieworg, e->origin, modelorg); 989 if (rotated) 990 { 991 vec3_t temp; 992 vec3_t forward, right, up; 993 994 VectorCopy (modelorg, temp); 995 AngleVectors (e->angles, forward, right, up); 996 modelorg[0] = DotProduct (temp, forward); 997 modelorg[1] = -DotProduct (temp, right); 998 modelorg[2] = DotProduct (temp, up); 999 } 1000 1001 qglPushMatrix (); 1002 e->angles[0] = -e->angles[0]; // stupid quake bug 1003 e->angles[2] = -e->angles[2]; // stupid quake bug 1004 R_RotateForEntity (e); 1005 e->angles[0] = -e->angles[0]; // stupid quake bug 1006 e->angles[2] = -e->angles[2]; // stupid quake bug 1007 1008 GL_EnableMultitexture( true ); 1009 GL_SelectTexture( GL_TEXTURE0_SGIS ); 1010 GL_TexEnv( GL_REPLACE ); 1011 GL_SelectTexture( GL_TEXTURE1_SGIS ); 1012 GL_TexEnv( GL_MODULATE ); 1013 1014 R_DrawInlineBModel (); 1015 GL_EnableMultitexture( false ); 1016 1017 qglPopMatrix (); 1018 } 1019 1020 /* 1021 ============================================================= 1022 1023 WORLD MODEL 1024 1025 ============================================================= 1026 */ 1027 1028 /* 1029 ================ 1030 R_RecursiveWorldNode 1031 ================ 1032 */ 1033 void R_RecursiveWorldNode (mnode_t *node) 1034 { 1035 int c, side, sidebit; 1036 cplane_t *plane; 1037 msurface_t *surf, **mark; 1038 mleaf_t *pleaf; 1039 float dot; 1040 image_t *image; 1041 1042 if (node->contents == CONTENTS_SOLID) 1043 return; // solid 1044 1045 if (node->visframe != r_visframecount) 1046 return; 1047 if (R_CullBox (node->minmaxs, node->minmaxs+3)) 1048 return; 1049 1050 // if a leaf node, draw stuff 1051 if (node->contents != -1) 1052 { 1053 pleaf = (mleaf_t *)node; 1054 1055 // check for door connected areas 1056 if (r_newrefdef.areabits) 1057 { 1058 if (! (r_newrefdef.areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) ) 1059 return; // not visible 1060 } 1061 1062 mark = pleaf->firstmarksurface; 1063 c = pleaf->nummarksurfaces; 1064 1065 if (c) 1066 { 1067 do 1068 { 1069 (*mark)->visframe = r_framecount; 1070 mark++; 1071 } while (--c); 1072 } 1073 1074 return; 1075 } 1076 1077 // node is just a decision point, so go down the apropriate sides 1078 1079 // find which side of the node we are on 1080 plane = node->plane; 1081 1082 switch (plane->type) 1083 { 1084 case PLANE_X: 1085 dot = modelorg[0] - plane->dist; 1086 break; 1087 case PLANE_Y: 1088 dot = modelorg[1] - plane->dist; 1089 break; 1090 case PLANE_Z: 1091 dot = modelorg[2] - plane->dist; 1092 break; 1093 default: 1094 dot = DotProduct (modelorg, plane->normal) - plane->dist; 1095 break; 1096 } 1097 1098 if (dot >= 0) 1099 { 1100 side = 0; 1101 sidebit = 0; 1102 } 1103 else 1104 { 1105 side = 1; 1106 sidebit = SURF_PLANEBACK; 1107 } 1108 1109 // recurse down the children, front side first 1110 R_RecursiveWorldNode (node->children[side]); 1111 1112 // draw stuff 1113 for ( c = node->numsurfaces, surf = r_worldmodel->surfaces + node->firstsurface; c ; c--, surf++) 1114 { 1115 if (surf->visframe != r_framecount) 1116 continue; 1117 1118 if ( (surf->flags & SURF_PLANEBACK) != sidebit ) 1119 continue; // wrong side 1120 1121 if (surf->texinfo->flags & SURF_SKY) 1122 { // just adds to visible sky bounds 1123 R_AddSkySurface (surf); 1124 } 1125 else if (surf->texinfo->flags & (SURF_TRANS33|SURF_TRANS66)) 1126 { // add to the translucent chain 1127 surf->texturechain = r_alpha_surfaces; 1128 r_alpha_surfaces = surf; 1129 } 1130 else 1131 { 1132 if ( qglMTexCoord2fSGIS && !( surf->flags & SURF_DRAWTURB ) ) 1133 { 1134 GL_RenderLightmappedPoly( surf ); 1135 } 1136 else 1137 { 1138 // the polygon is visible, so add it to the texture 1139 // sorted chain 1140 // FIXME: this is a hack for animation 1141 image = R_TextureAnimation (surf->texinfo); 1142 surf->texturechain = image->texturechain; 1143 image->texturechain = surf; 1144 } 1145 } 1146 } 1147 1148 // recurse down the back side 1149 R_RecursiveWorldNode (node->children[!side]); 1150 /* 1151 for ( ; c ; c--, surf++) 1152 { 1153 if (surf->visframe != r_framecount) 1154 continue; 1155 1156 if ( (surf->flags & SURF_PLANEBACK) != sidebit ) 1157 continue; // wrong side 1158 1159 if (surf->texinfo->flags & SURF_SKY) 1160 { // just adds to visible sky bounds 1161 R_AddSkySurface (surf); 1162 } 1163 else if (surf->texinfo->flags & (SURF_TRANS33|SURF_TRANS66)) 1164 { // add to the translucent chain 1165 // surf->texturechain = alpha_surfaces; 1166 // alpha_surfaces = surf; 1167 } 1168 else 1169 { 1170 if ( qglMTexCoord2fSGIS && !( surf->flags & SURF_DRAWTURB ) ) 1171 { 1172 GL_RenderLightmappedPoly( surf ); 1173 } 1174 else 1175 { 1176 // the polygon is visible, so add it to the texture 1177 // sorted chain 1178 // FIXME: this is a hack for animation 1179 image = R_TextureAnimation (surf->texinfo); 1180 surf->texturechain = image->texturechain; 1181 image->texturechain = surf; 1182 } 1183 } 1184 } 1185 */ 1186 } 1187 1188 1189 /* 1190 ============= 1191 R_DrawWorld 1192 ============= 1193 */ 1194 void R_DrawWorld (void) 1195 { 1196 entity_t ent; 1197 1198 if (!r_drawworld->value) 1199 return; 1200 1201 if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) 1202 return; 1203 1204 currentmodel = r_worldmodel; 1205 1206 VectorCopy (r_newrefdef.vieworg, modelorg); 1207 1208 // auto cycle the world frame for texture animation 1209 memset (&ent, 0, sizeof(ent)); 1210 ent.frame = (int)(r_newrefdef.time*2); 1211 currententity = &ent; 1212 1213 gl_state.currenttextures[0] = gl_state.currenttextures[1] = -1; 1214 1215 qglColor3f (1,1,1); 1216 memset (gl_lms.lightmap_surfaces, 0, sizeof(gl_lms.lightmap_surfaces)); 1217 R_ClearSkyBox (); 1218 1219 if ( qglMTexCoord2fSGIS ) 1220 { 1221 GL_EnableMultitexture( true ); 1222 1223 GL_SelectTexture( GL_TEXTURE0_SGIS ); 1224 GL_TexEnv( GL_REPLACE ); 1225 GL_SelectTexture( GL_TEXTURE1_SGIS ); 1226 1227 if ( gl_lightmap->value ) 1228 GL_TexEnv( GL_REPLACE ); 1229 else 1230 GL_TexEnv( GL_MODULATE ); 1231 1232 R_RecursiveWorldNode (r_worldmodel->nodes); 1233 1234 GL_EnableMultitexture( false ); 1235 } 1236 else 1237 { 1238 R_RecursiveWorldNode (r_worldmodel->nodes); 1239 } 1240 1241 /* 1242 ** theoretically nothing should happen in the next two functions 1243 ** if multitexture is enabled 1244 */ 1245 DrawTextureChains (); 1246 R_BlendLightmaps (); 1247 1248 R_DrawSkyBox (); 1249 1250 R_DrawTriangleOutlines (); 1251 } 1252 1253 1254 /* 1255 =============== 1256 R_MarkLeaves 1257 1258 Mark the leaves and nodes that are in the PVS for the current 1259 cluster 1260 =============== 1261 */ 1262 void R_MarkLeaves (void) 1263 { 1264 byte *vis; 1265 byte fatvis[MAX_MAP_LEAFS/8]; 1266 mnode_t *node; 1267 int i, c; 1268 mleaf_t *leaf; 1269 int cluster; 1270 1271 if (r_oldviewcluster == r_viewcluster && r_oldviewcluster2 == r_viewcluster2 && !r_novis->value && r_viewcluster != -1) 1272 return; 1273 1274 // development aid to let you run around and see exactly where 1275 // the pvs ends 1276 if (gl_lockpvs->value) 1277 return; 1278 1279 r_visframecount++; 1280 r_oldviewcluster = r_viewcluster; 1281 r_oldviewcluster2 = r_viewcluster2; 1282 1283 if (r_novis->value || r_viewcluster == -1 || !r_worldmodel->vis) 1284 { 1285 // mark everything 1286 for (i=0 ; i<r_worldmodel->numleafs ; i++) 1287 r_worldmodel->leafs[i].visframe = r_visframecount; 1288 for (i=0 ; i<r_worldmodel->numnodes ; i++) 1289 r_worldmodel->nodes[i].visframe = r_visframecount; 1290 return; 1291 } 1292 1293 vis = Mod_ClusterPVS (r_viewcluster, r_worldmodel); 1294 // may have to combine two clusters because of solid water boundaries 1295 if (r_viewcluster2 != r_viewcluster) 1296 { 1297 memcpy (fatvis, vis, (r_worldmodel->numleafs+7)/8); 1298 vis = Mod_ClusterPVS (r_viewcluster2, r_worldmodel); 1299 c = (r_worldmodel->numleafs+31)/32; 1300 for (i=0 ; i<c ; i++) 1301 ((int *)fatvis)[i] |= ((int *)vis)[i]; 1302 vis = fatvis; 1303 } 1304 1305 for (i=0,leaf=r_worldmodel->leafs ; i<r_worldmodel->numleafs ; i++, leaf++) 1306 { 1307 cluster = leaf->cluster; 1308 if (cluster == -1) 1309 continue; 1310 if (vis[cluster>>3] & (1<<(cluster&7))) 1311 { 1312 node = (mnode_t *)leaf; 1313 do 1314 { 1315 if (node->visframe == r_visframecount) 1316 break; 1317 node->visframe = r_visframecount; 1318 node = node->parent; 1319 } while (node); 1320 } 1321 } 1322 1323 #if 0 1324 for (i=0 ; i<r_worldmodel->vis->numclusters ; i++) 1325 { 1326 if (vis[i>>3] & (1<<(i&7))) 1327 { 1328 node = (mnode_t *)&r_worldmodel->leafs[i]; // FIXME: cluster 1329 do 1330 { 1331 if (node->visframe == r_visframecount) 1332 break; 1333 node->visframe = r_visframecount; 1334 node = node->parent; 1335 } while (node); 1336 } 1337 } 1338 #endif 1339 } 1340 1341 1342 1343 /* 1344 ============================================================================= 1345 1346 LIGHTMAP ALLOCATION 1347 1348 ============================================================================= 1349 */ 1350 1351 static void LM_InitBlock( void ) 1352 { 1353 memset( gl_lms.allocated, 0, sizeof( gl_lms.allocated ) ); 1354 } 1355 1356 static void LM_UploadBlock( qboolean dynamic ) 1357 { 1358 int texture; 1359 int height = 0; 1360 1361 if ( dynamic ) 1362 { 1363 texture = 0; 1364 } 1365 else 1366 { 1367 texture = gl_lms.current_lightmap_texture; 1368 } 1369 1370 GL_Bind( gl_state.lightmap_textures + texture ); 1371 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1372 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1373 1374 if ( dynamic ) 1375 { 1376 int i; 1377 1378 for ( i = 0; i < BLOCK_WIDTH; i++ ) 1379 { 1380 if ( gl_lms.allocated[i] > height ) 1381 height = gl_lms.allocated[i]; 1382 } 1383 1384 qglTexSubImage2D( GL_TEXTURE_2D, 1385 0, 1386 0, 0, 1387 BLOCK_WIDTH, height, 1388 GL_LIGHTMAP_FORMAT, 1389 GL_UNSIGNED_BYTE, 1390 gl_lms.lightmap_buffer ); 1391 } 1392 else 1393 { 1394 qglTexImage2D( GL_TEXTURE_2D, 1395 0, 1396 gl_lms.internal_format, 1397 BLOCK_WIDTH, BLOCK_HEIGHT, 1398 0, 1399 GL_LIGHTMAP_FORMAT, 1400 GL_UNSIGNED_BYTE, 1401 gl_lms.lightmap_buffer ); 1402 if ( ++gl_lms.current_lightmap_texture == MAX_LIGHTMAPS ) 1403 ri.Sys_Error( ERR_DROP, "LM_UploadBlock() - MAX_LIGHTMAPS exceeded\n" ); 1404 } 1405 } 1406 1407 // returns a texture number and the position inside it 1408 static qboolean LM_AllocBlock (int w, int h, int *x, int *y) 1409 { 1410 int i, j; 1411 int best, best2; 1412 1413 best = BLOCK_HEIGHT; 1414 1415 for (i=0 ; i<BLOCK_WIDTH-w ; i++) 1416 { 1417 best2 = 0; 1418 1419 for (j=0 ; j<w ; j++) 1420 { 1421 if (gl_lms.allocated[i+j] >= best) 1422 break; 1423 if (gl_lms.allocated[i+j] > best2) 1424 best2 = gl_lms.allocated[i+j]; 1425 } 1426 if (j == w) 1427 { // this is a valid spot 1428 *x = i; 1429 *y = best = best2; 1430 } 1431 } 1432 1433 if (best + h > BLOCK_HEIGHT) 1434 return false; 1435 1436 for (i=0 ; i<w ; i++) 1437 gl_lms.allocated[*x + i] = best + h; 1438 1439 return true; 1440 } 1441 1442 /* 1443 ================ 1444 GL_BuildPolygonFromSurface 1445 ================ 1446 */ 1447 void GL_BuildPolygonFromSurface(msurface_t *fa) 1448 { 1449 int i, lindex, lnumverts; 1450 medge_t *pedges, *r_pedge; 1451 int vertpage; 1452 float *vec; 1453 float s, t; 1454 glpoly_t *poly; 1455 vec3_t total; 1456 1457 // reconstruct the polygon 1458 pedges = currentmodel->edges; 1459 lnumverts = fa->numedges; 1460 vertpage = 0; 1461 1462 VectorClear (total); 1463 // 1464 // draw texture 1465 // 1466 poly = Hunk_Alloc (sizeof(glpoly_t) + (lnumverts-4) * VERTEXSIZE*sizeof(float)); 1467 poly->next = fa->polys; 1468 poly->flags = fa->flags; 1469 fa->polys = poly; 1470 poly->numverts = lnumverts; 1471 1472 for (i=0 ; i<lnumverts ; i++) 1473 { 1474 lindex = currentmodel->surfedges[fa->firstedge + i]; 1475 1476 if (lindex > 0) 1477 { 1478 r_pedge = &pedges[lindex]; 1479 vec = currentmodel->vertexes[r_pedge->v[0]].position; 1480 } 1481 else 1482 { 1483 r_pedge = &pedges[-lindex]; 1484 vec = currentmodel->vertexes[r_pedge->v[1]].position; 1485 } 1486 s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3]; 1487 s /= fa->texinfo->image->width; 1488 1489 t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3]; 1490 t /= fa->texinfo->image->height; 1491 1492 VectorAdd (total, vec, total); 1493 VectorCopy (vec, poly->verts[i]); 1494 poly->verts[i][3] = s; 1495 poly->verts[i][4] = t; 1496 1497 // 1498 // lightmap texture coordinates 1499 // 1500 s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3]; 1501 s -= fa->texturemins[0]; 1502 s += fa->light_s*16; 1503 s += 8; 1504 s /= BLOCK_WIDTH*16; //fa->texinfo->texture->width; 1505 1506 t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3]; 1507 t -= fa->texturemins[1]; 1508 t += fa->light_t*16; 1509 t += 8; 1510 t /= BLOCK_HEIGHT*16; //fa->texinfo->texture->height; 1511 1512 poly->verts[i][5] = s; 1513 poly->verts[i][6] = t; 1514 } 1515 1516 poly->numverts = lnumverts; 1517 1518 } 1519 1520 /* 1521 ======================== 1522 GL_CreateSurfaceLightmap 1523 ======================== 1524 */ 1525 void GL_CreateSurfaceLightmap (msurface_t *surf) 1526 { 1527 int smax, tmax; 1528 byte *base; 1529 1530 if (surf->flags & (SURF_DRAWSKY|SURF_DRAWTURB)) 1531 return; 1532 1533 smax = (surf->extents[0]>>4)+1; 1534 tmax = (surf->extents[1]>>4)+1; 1535 1536 if ( !LM_AllocBlock( smax, tmax, &surf->light_s, &surf->light_t ) ) 1537 { 1538 LM_UploadBlock( false ); 1539 LM_InitBlock(); 1540 if ( !LM_AllocBlock( smax, tmax, &surf->light_s, &surf->light_t ) ) 1541 { 1542 ri.Sys_Error( ERR_FATAL, "Consecutive calls to LM_AllocBlock(%d,%d) failed\n", smax, tmax ); 1543 } 1544 } 1545 1546 surf->lightmaptexturenum = gl_lms.current_lightmap_texture; 1547 1548 base = gl_lms.lightmap_buffer; 1549 base += (surf->light_t * BLOCK_WIDTH + surf->light_s) * LIGHTMAP_BYTES; 1550 1551 R_SetCacheState( surf ); 1552 R_BuildLightMap (surf, base, BLOCK_WIDTH*LIGHTMAP_BYTES); 1553 } 1554 1555 1556 /* 1557 ================== 1558 GL_BeginBuildingLightmaps 1559 1560 ================== 1561 */ 1562 void GL_BeginBuildingLightmaps (model_t *m) 1563 { 1564 static lightstyle_t lightstyles[MAX_LIGHTSTYLES]; 1565 int i; 1566 unsigned dummy[128*128]; 1567 1568 memset( gl_lms.allocated, 0, sizeof(gl_lms.allocated) ); 1569 1570 r_framecount = 1; // no dlightcache 1571 1572 GL_EnableMultitexture( true ); 1573 GL_SelectTexture( GL_TEXTURE1_SGIS ); 1574 1575 /* 1576 ** setup the base lightstyles so the lightmaps won't have to be regenerated 1577 ** the first time they're seen 1578 */ 1579 for (i=0 ; i<MAX_LIGHTSTYLES ; i++) 1580 { 1581 lightstyles[i].rgb[0] = 1; 1582 lightstyles[i].rgb[1] = 1; 1583 lightstyles[i].rgb[2] = 1; 1584 lightstyles[i].white = 3; 1585 } 1586 r_newrefdef.lightstyles = lightstyles; 1587 1588 if (!gl_state.lightmap_textures) 1589 { 1590 gl_state.lightmap_textures = TEXNUM_LIGHTMAPS; 1591 // gl_state.lightmap_textures = gl_state.texture_extension_number; 1592 // gl_state.texture_extension_number = gl_state.lightmap_textures + MAX_LIGHTMAPS; 1593 } 1594 1595 gl_lms.current_lightmap_texture = 1; 1596 1597 /* 1598 ** if mono lightmaps are enabled and we want to use alpha 1599 ** blending (a,1-a) then we're likely running on a 3DLabs 1600 ** Permedia2. In a perfect world we'd use a GL_ALPHA lightmap 1601 ** in order to conserve space and maximize bandwidth, however 1602 ** this isn't a perfect world. 1603 ** 1604 ** So we have to use alpha lightmaps, but stored in GL_RGBA format, 1605 ** which means we only get 1/16th the color resolution we should when 1606 ** using alpha lightmaps. If we find another board that supports 1607 ** only alpha lightmaps but that can at least support the GL_ALPHA 1608 ** format then we should change this code to use real alpha maps. 1609 */ 1610 if ( toupper( gl_monolightmap->string[0] ) == 'A' ) 1611 { 1612 gl_lms.internal_format = gl_tex_alpha_format; 1613 } 1614 /* 1615 ** try to do hacked colored lighting with a blended texture 1616 */ 1617 else if ( toupper( gl_monolightmap->string[0] ) == 'C' ) 1618 { 1619 gl_lms.internal_format = gl_tex_alpha_format; 1620 } 1621 else if ( toupper( gl_monolightmap->string[0] ) == 'I' ) 1622 { 1623 gl_lms.internal_format = GL_INTENSITY8; 1624 } 1625 else if ( toupper( gl_monolightmap->string[0] ) == 'L' ) 1626 { 1627 gl_lms.internal_format = GL_LUMINANCE8; 1628 } 1629 else 1630 { 1631 gl_lms.internal_format = gl_tex_solid_format; 1632 } 1633 1634 /* 1635 ** initialize the dynamic lightmap texture 1636 */ 1637 GL_Bind( gl_state.lightmap_textures + 0 ); 1638 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1639 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1640 qglTexImage2D( GL_TEXTURE_2D, 1641 0, 1642 gl_lms.internal_format, 1643 BLOCK_WIDTH, BLOCK_HEIGHT, 1644 0, 1645 GL_LIGHTMAP_FORMAT, 1646 GL_UNSIGNED_BYTE, 1647 dummy ); 1648 } 1649 1650 /* 1651 ======================= 1652 GL_EndBuildingLightmaps 1653 ======================= 1654 */ 1655 void GL_EndBuildingLightmaps (void) 1656 { 1657 LM_UploadBlock( false ); 1658 GL_EnableMultitexture( false ); 1659 } 1660