gl_mesh.c (19224B)
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_mesh.c: triangle model functions 21 22 #include "gl_local.h" 23 24 /* 25 ============================================================= 26 27 ALIAS MODELS 28 29 ============================================================= 30 */ 31 32 #define NUMVERTEXNORMALS 162 33 34 float r_avertexnormals[NUMVERTEXNORMALS][3] = { 35 #include "anorms.h" 36 }; 37 38 typedef float vec4_t[4]; 39 40 static vec4_t s_lerped[MAX_VERTS]; 41 //static vec3_t lerped[MAX_VERTS]; 42 43 vec3_t shadevector; 44 float shadelight[3]; 45 46 // precalculated dot products for quantized angles 47 #define SHADEDOT_QUANT 16 48 float r_avertexnormal_dots[SHADEDOT_QUANT][256] = 49 #include "anormtab.h" 50 ; 51 52 float *shadedots = r_avertexnormal_dots[0]; 53 54 void GL_LerpVerts( int nverts, dtrivertx_t *v, dtrivertx_t *ov, dtrivertx_t *verts, float *lerp, float move[3], float frontv[3], float backv[3] ) 55 { 56 int i; 57 58 //PMM -- added RF_SHELL_DOUBLE, RF_SHELL_HALF_DAM 59 if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) ) 60 { 61 for (i=0 ; i < nverts; i++, v++, ov++, lerp+=4 ) 62 { 63 float *normal = r_avertexnormals[verts[i].lightnormalindex]; 64 65 lerp[0] = move[0] + ov->v[0]*backv[0] + v->v[0]*frontv[0] + normal[0] * POWERSUIT_SCALE; 66 lerp[1] = move[1] + ov->v[1]*backv[1] + v->v[1]*frontv[1] + normal[1] * POWERSUIT_SCALE; 67 lerp[2] = move[2] + ov->v[2]*backv[2] + v->v[2]*frontv[2] + normal[2] * POWERSUIT_SCALE; 68 } 69 } 70 else 71 { 72 for (i=0 ; i < nverts; i++, v++, ov++, lerp+=4) 73 { 74 lerp[0] = move[0] + ov->v[0]*backv[0] + v->v[0]*frontv[0]; 75 lerp[1] = move[1] + ov->v[1]*backv[1] + v->v[1]*frontv[1]; 76 lerp[2] = move[2] + ov->v[2]*backv[2] + v->v[2]*frontv[2]; 77 } 78 } 79 80 } 81 82 /* 83 ============= 84 GL_DrawAliasFrameLerp 85 86 interpolates between two frames and origins 87 FIXME: batch lerp all vertexes 88 ============= 89 */ 90 void GL_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp) 91 { 92 float l; 93 daliasframe_t *frame, *oldframe; 94 dtrivertx_t *v, *ov, *verts; 95 int *order; 96 int count; 97 float frontlerp; 98 float alpha; 99 vec3_t move, delta, vectors[3]; 100 vec3_t frontv, backv; 101 int i; 102 int index_xyz; 103 float *lerp; 104 105 frame = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames 106 + currententity->frame * paliashdr->framesize); 107 verts = v = frame->verts; 108 109 oldframe = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames 110 + currententity->oldframe * paliashdr->framesize); 111 ov = oldframe->verts; 112 113 order = (int *)((byte *)paliashdr + paliashdr->ofs_glcmds); 114 115 // glTranslatef (frame->translate[0], frame->translate[1], frame->translate[2]); 116 // glScalef (frame->scale[0], frame->scale[1], frame->scale[2]); 117 118 if (currententity->flags & RF_TRANSLUCENT) 119 alpha = currententity->alpha; 120 else 121 alpha = 1.0; 122 123 // PMM - added double shell 124 if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) ) 125 qglDisable( GL_TEXTURE_2D ); 126 127 frontlerp = 1.0 - backlerp; 128 129 // move should be the delta back to the previous frame * backlerp 130 VectorSubtract (currententity->oldorigin, currententity->origin, delta); 131 AngleVectors (currententity->angles, vectors[0], vectors[1], vectors[2]); 132 133 move[0] = DotProduct (delta, vectors[0]); // forward 134 move[1] = -DotProduct (delta, vectors[1]); // left 135 move[2] = DotProduct (delta, vectors[2]); // up 136 137 VectorAdd (move, oldframe->translate, move); 138 139 for (i=0 ; i<3 ; i++) 140 { 141 move[i] = backlerp*move[i] + frontlerp*frame->translate[i]; 142 } 143 144 for (i=0 ; i<3 ; i++) 145 { 146 frontv[i] = frontlerp*frame->scale[i]; 147 backv[i] = backlerp*oldframe->scale[i]; 148 } 149 150 lerp = s_lerped[0]; 151 152 GL_LerpVerts( paliashdr->num_xyz, v, ov, verts, lerp, move, frontv, backv ); 153 154 if ( gl_vertex_arrays->value ) 155 { 156 float colorArray[MAX_VERTS*4]; 157 158 qglEnableClientState( GL_VERTEX_ARRAY ); 159 qglVertexPointer( 3, GL_FLOAT, 16, s_lerped ); // padded for SIMD 160 161 // if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE ) ) 162 // PMM - added double damage shell 163 if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) ) 164 { 165 qglColor4f( shadelight[0], shadelight[1], shadelight[2], alpha ); 166 } 167 else 168 { 169 qglEnableClientState( GL_COLOR_ARRAY ); 170 qglColorPointer( 3, GL_FLOAT, 0, colorArray ); 171 172 // 173 // pre light everything 174 // 175 for ( i = 0; i < paliashdr->num_xyz; i++ ) 176 { 177 float l = shadedots[verts[i].lightnormalindex]; 178 179 colorArray[i*3+0] = l * shadelight[0]; 180 colorArray[i*3+1] = l * shadelight[1]; 181 colorArray[i*3+2] = l * shadelight[2]; 182 } 183 } 184 185 if ( qglLockArraysEXT != 0 ) 186 qglLockArraysEXT( 0, paliashdr->num_xyz ); 187 188 while (1) 189 { 190 // get the vertex count and primitive type 191 count = *order++; 192 if (!count) 193 break; // done 194 if (count < 0) 195 { 196 count = -count; 197 qglBegin (GL_TRIANGLE_FAN); 198 } 199 else 200 { 201 qglBegin (GL_TRIANGLE_STRIP); 202 } 203 204 // PMM - added double damage shell 205 if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) ) 206 { 207 do 208 { 209 index_xyz = order[2]; 210 order += 3; 211 212 qglVertex3fv( s_lerped[index_xyz] ); 213 214 } while (--count); 215 } 216 else 217 { 218 do 219 { 220 // texture coordinates come from the draw list 221 qglTexCoord2f (((float *)order)[0], ((float *)order)[1]); 222 index_xyz = order[2]; 223 224 order += 3; 225 226 // normals and vertexes come from the frame list 227 // l = shadedots[verts[index_xyz].lightnormalindex]; 228 229 // qglColor4f (l* shadelight[0], l*shadelight[1], l*shadelight[2], alpha); 230 qglArrayElement( index_xyz ); 231 232 } while (--count); 233 } 234 qglEnd (); 235 } 236 237 if ( qglUnlockArraysEXT != 0 ) 238 qglUnlockArraysEXT(); 239 } 240 else 241 { 242 while (1) 243 { 244 // get the vertex count and primitive type 245 count = *order++; 246 if (!count) 247 break; // done 248 if (count < 0) 249 { 250 count = -count; 251 qglBegin (GL_TRIANGLE_FAN); 252 } 253 else 254 { 255 qglBegin (GL_TRIANGLE_STRIP); 256 } 257 258 if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE ) ) 259 { 260 do 261 { 262 index_xyz = order[2]; 263 order += 3; 264 265 qglColor4f( shadelight[0], shadelight[1], shadelight[2], alpha); 266 qglVertex3fv (s_lerped[index_xyz]); 267 268 } while (--count); 269 } 270 else 271 { 272 do 273 { 274 // texture coordinates come from the draw list 275 qglTexCoord2f (((float *)order)[0], ((float *)order)[1]); 276 index_xyz = order[2]; 277 order += 3; 278 279 // normals and vertexes come from the frame list 280 l = shadedots[verts[index_xyz].lightnormalindex]; 281 282 qglColor4f (l* shadelight[0], l*shadelight[1], l*shadelight[2], alpha); 283 qglVertex3fv (s_lerped[index_xyz]); 284 } while (--count); 285 } 286 287 qglEnd (); 288 } 289 } 290 291 // if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE ) ) 292 // PMM - added double damage shell 293 if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) ) 294 qglEnable( GL_TEXTURE_2D ); 295 } 296 297 298 #if 1 299 /* 300 ============= 301 GL_DrawAliasShadow 302 ============= 303 */ 304 extern vec3_t lightspot; 305 306 void GL_DrawAliasShadow (dmdl_t *paliashdr, int posenum) 307 { 308 dtrivertx_t *verts; 309 int *order; 310 vec3_t point; 311 float height, lheight; 312 int count; 313 daliasframe_t *frame; 314 315 lheight = currententity->origin[2] - lightspot[2]; 316 317 frame = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames 318 + currententity->frame * paliashdr->framesize); 319 verts = frame->verts; 320 321 height = 0; 322 323 order = (int *)((byte *)paliashdr + paliashdr->ofs_glcmds); 324 325 height = -lheight + 1.0; 326 327 while (1) 328 { 329 // get the vertex count and primitive type 330 count = *order++; 331 if (!count) 332 break; // done 333 if (count < 0) 334 { 335 count = -count; 336 qglBegin (GL_TRIANGLE_FAN); 337 } 338 else 339 qglBegin (GL_TRIANGLE_STRIP); 340 341 do 342 { 343 // normals and vertexes come from the frame list 344 /* 345 point[0] = verts[order[2]].v[0] * frame->scale[0] + frame->translate[0]; 346 point[1] = verts[order[2]].v[1] * frame->scale[1] + frame->translate[1]; 347 point[2] = verts[order[2]].v[2] * frame->scale[2] + frame->translate[2]; 348 */ 349 350 memcpy( point, s_lerped[order[2]], sizeof( point ) ); 351 352 point[0] -= shadevector[0]*(point[2]+lheight); 353 point[1] -= shadevector[1]*(point[2]+lheight); 354 point[2] = height; 355 // height -= 0.001; 356 qglVertex3fv (point); 357 358 order += 3; 359 360 // verts++; 361 362 } while (--count); 363 364 qglEnd (); 365 } 366 } 367 368 #endif 369 370 /* 371 ** R_CullAliasModel 372 */ 373 static qboolean R_CullAliasModel( vec3_t bbox[8], entity_t *e ) 374 { 375 int i; 376 vec3_t mins, maxs; 377 dmdl_t *paliashdr; 378 vec3_t vectors[3]; 379 vec3_t thismins, oldmins, thismaxs, oldmaxs; 380 daliasframe_t *pframe, *poldframe; 381 vec3_t angles; 382 383 paliashdr = (dmdl_t *)currentmodel->extradata; 384 385 if ( ( e->frame >= paliashdr->num_frames ) || ( e->frame < 0 ) ) 386 { 387 ri.Con_Printf (PRINT_ALL, "R_CullAliasModel %s: no such frame %d\n", 388 currentmodel->name, e->frame); 389 e->frame = 0; 390 } 391 if ( ( e->oldframe >= paliashdr->num_frames ) || ( e->oldframe < 0 ) ) 392 { 393 ri.Con_Printf (PRINT_ALL, "R_CullAliasModel %s: no such oldframe %d\n", 394 currentmodel->name, e->oldframe); 395 e->oldframe = 0; 396 } 397 398 pframe = ( daliasframe_t * ) ( ( byte * ) paliashdr + 399 paliashdr->ofs_frames + 400 e->frame * paliashdr->framesize); 401 402 poldframe = ( daliasframe_t * ) ( ( byte * ) paliashdr + 403 paliashdr->ofs_frames + 404 e->oldframe * paliashdr->framesize); 405 406 /* 407 ** compute axially aligned mins and maxs 408 */ 409 if ( pframe == poldframe ) 410 { 411 for ( i = 0; i < 3; i++ ) 412 { 413 mins[i] = pframe->translate[i]; 414 maxs[i] = mins[i] + pframe->scale[i]*255; 415 } 416 } 417 else 418 { 419 for ( i = 0; i < 3; i++ ) 420 { 421 thismins[i] = pframe->translate[i]; 422 thismaxs[i] = thismins[i] + pframe->scale[i]*255; 423 424 oldmins[i] = poldframe->translate[i]; 425 oldmaxs[i] = oldmins[i] + poldframe->scale[i]*255; 426 427 if ( thismins[i] < oldmins[i] ) 428 mins[i] = thismins[i]; 429 else 430 mins[i] = oldmins[i]; 431 432 if ( thismaxs[i] > oldmaxs[i] ) 433 maxs[i] = thismaxs[i]; 434 else 435 maxs[i] = oldmaxs[i]; 436 } 437 } 438 439 /* 440 ** compute a full bounding box 441 */ 442 for ( i = 0; i < 8; i++ ) 443 { 444 vec3_t tmp; 445 446 if ( i & 1 ) 447 tmp[0] = mins[0]; 448 else 449 tmp[0] = maxs[0]; 450 451 if ( i & 2 ) 452 tmp[1] = mins[1]; 453 else 454 tmp[1] = maxs[1]; 455 456 if ( i & 4 ) 457 tmp[2] = mins[2]; 458 else 459 tmp[2] = maxs[2]; 460 461 VectorCopy( tmp, bbox[i] ); 462 } 463 464 /* 465 ** rotate the bounding box 466 */ 467 VectorCopy( e->angles, angles ); 468 angles[YAW] = -angles[YAW]; 469 AngleVectors( angles, vectors[0], vectors[1], vectors[2] ); 470 471 for ( i = 0; i < 8; i++ ) 472 { 473 vec3_t tmp; 474 475 VectorCopy( bbox[i], tmp ); 476 477 bbox[i][0] = DotProduct( vectors[0], tmp ); 478 bbox[i][1] = -DotProduct( vectors[1], tmp ); 479 bbox[i][2] = DotProduct( vectors[2], tmp ); 480 481 VectorAdd( e->origin, bbox[i], bbox[i] ); 482 } 483 484 { 485 int p, f, aggregatemask = ~0; 486 487 for ( p = 0; p < 8; p++ ) 488 { 489 int mask = 0; 490 491 for ( f = 0; f < 4; f++ ) 492 { 493 float dp = DotProduct( frustum[f].normal, bbox[p] ); 494 495 if ( ( dp - frustum[f].dist ) < 0 ) 496 { 497 mask |= ( 1 << f ); 498 } 499 } 500 501 aggregatemask &= mask; 502 } 503 504 if ( aggregatemask ) 505 { 506 return true; 507 } 508 509 return false; 510 } 511 } 512 513 /* 514 ================= 515 R_DrawAliasModel 516 517 ================= 518 */ 519 void R_DrawAliasModel (entity_t *e) 520 { 521 int i; 522 dmdl_t *paliashdr; 523 float an; 524 vec3_t bbox[8]; 525 image_t *skin; 526 527 if ( !( e->flags & RF_WEAPONMODEL ) ) 528 { 529 if ( R_CullAliasModel( bbox, e ) ) 530 return; 531 } 532 533 if ( e->flags & RF_WEAPONMODEL ) 534 { 535 if ( r_lefthand->value == 2 ) 536 return; 537 } 538 539 paliashdr = (dmdl_t *)currentmodel->extradata; 540 541 // 542 // get lighting information 543 // 544 // PMM - rewrote, reordered to handle new shells & mixing 545 // 546 if ( currententity->flags & ( RF_SHELL_HALF_DAM | RF_SHELL_GREEN | RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_DOUBLE ) ) 547 { 548 // PMM -special case for godmode 549 if ( (currententity->flags & RF_SHELL_RED) && 550 (currententity->flags & RF_SHELL_BLUE) && 551 (currententity->flags & RF_SHELL_GREEN) ) 552 { 553 for (i=0 ; i<3 ; i++) 554 shadelight[i] = 1.0; 555 } 556 else if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_DOUBLE ) ) 557 { 558 VectorClear (shadelight); 559 560 if ( currententity->flags & RF_SHELL_RED ) 561 { 562 shadelight[0] = 1.0; 563 if (currententity->flags & (RF_SHELL_BLUE|RF_SHELL_DOUBLE) ) 564 shadelight[2] = 1.0; 565 } 566 else if ( currententity->flags & RF_SHELL_BLUE ) 567 { 568 if ( currententity->flags & RF_SHELL_DOUBLE ) 569 { 570 shadelight[1] = 1.0; 571 shadelight[2] = 1.0; 572 } 573 else 574 { 575 shadelight[2] = 1.0; 576 } 577 } 578 else if ( currententity->flags & RF_SHELL_DOUBLE ) 579 { 580 shadelight[0] = 0.9; 581 shadelight[1] = 0.7; 582 } 583 } 584 else if ( currententity->flags & ( RF_SHELL_HALF_DAM | RF_SHELL_GREEN ) ) 585 { 586 VectorClear (shadelight); 587 // PMM - new colors 588 if ( currententity->flags & RF_SHELL_HALF_DAM ) 589 { 590 shadelight[0] = 0.56; 591 shadelight[1] = 0.59; 592 shadelight[2] = 0.45; 593 } 594 if ( currententity->flags & RF_SHELL_GREEN ) 595 { 596 shadelight[1] = 1.0; 597 } 598 } 599 } 600 //PMM - ok, now flatten these down to range from 0 to 1.0. 601 // max_shell_val = max(shadelight[0], max(shadelight[1], shadelight[2])); 602 // if (max_shell_val > 0) 603 // { 604 // for (i=0; i<3; i++) 605 // { 606 // shadelight[i] = shadelight[i] / max_shell_val; 607 // } 608 // } 609 // pmm 610 else if ( currententity->flags & RF_FULLBRIGHT ) 611 { 612 for (i=0 ; i<3 ; i++) 613 shadelight[i] = 1.0; 614 } 615 else 616 { 617 R_LightPoint (currententity->origin, shadelight); 618 619 // player lighting hack for communication back to server 620 // big hack! 621 if ( currententity->flags & RF_WEAPONMODEL ) 622 { 623 // pick the greatest component, which should be the same 624 // as the mono value returned by software 625 if (shadelight[0] > shadelight[1]) 626 { 627 if (shadelight[0] > shadelight[2]) 628 r_lightlevel->value = 150*shadelight[0]; 629 else 630 r_lightlevel->value = 150*shadelight[2]; 631 } 632 else 633 { 634 if (shadelight[1] > shadelight[2]) 635 r_lightlevel->value = 150*shadelight[1]; 636 else 637 r_lightlevel->value = 150*shadelight[2]; 638 } 639 640 } 641 642 if ( gl_monolightmap->string[0] != '0' ) 643 { 644 float s = shadelight[0]; 645 646 if ( s < shadelight[1] ) 647 s = shadelight[1]; 648 if ( s < shadelight[2] ) 649 s = shadelight[2]; 650 651 shadelight[0] = s; 652 shadelight[1] = s; 653 shadelight[2] = s; 654 } 655 } 656 657 if ( currententity->flags & RF_MINLIGHT ) 658 { 659 for (i=0 ; i<3 ; i++) 660 if (shadelight[i] > 0.1) 661 break; 662 if (i == 3) 663 { 664 shadelight[0] = 0.1; 665 shadelight[1] = 0.1; 666 shadelight[2] = 0.1; 667 } 668 } 669 670 if ( currententity->flags & RF_GLOW ) 671 { // bonus items will pulse with time 672 float scale; 673 float min; 674 675 scale = 0.1 * sin(r_newrefdef.time*7); 676 for (i=0 ; i<3 ; i++) 677 { 678 min = shadelight[i] * 0.8; 679 shadelight[i] += scale; 680 if (shadelight[i] < min) 681 shadelight[i] = min; 682 } 683 } 684 685 // ================= 686 // PGM ir goggles color override 687 if ( r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & RF_IR_VISIBLE) 688 { 689 shadelight[0] = 1.0; 690 shadelight[1] = 0.0; 691 shadelight[2] = 0.0; 692 } 693 // PGM 694 // ================= 695 696 shadedots = r_avertexnormal_dots[((int)(currententity->angles[1] * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)]; 697 698 an = currententity->angles[1]/180*M_PI; 699 shadevector[0] = cos(-an); 700 shadevector[1] = sin(-an); 701 shadevector[2] = 1; 702 VectorNormalize (shadevector); 703 704 // 705 // locate the proper data 706 // 707 708 c_alias_polys += paliashdr->num_tris; 709 710 // 711 // draw all the triangles 712 // 713 if (currententity->flags & RF_DEPTHHACK) // hack the depth range to prevent view model from poking into walls 714 qglDepthRange (gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin)); 715 716 if ( ( currententity->flags & RF_WEAPONMODEL ) && ( r_lefthand->value == 1.0F ) ) 717 { 718 extern void MYgluPerspective( GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar ); 719 720 qglMatrixMode( GL_PROJECTION ); 721 qglPushMatrix(); 722 qglLoadIdentity(); 723 qglScalef( -1, 1, 1 ); 724 MYgluPerspective( r_newrefdef.fov_y, ( float ) r_newrefdef.width / r_newrefdef.height, 4, 4096); 725 qglMatrixMode( GL_MODELVIEW ); 726 727 qglCullFace( GL_BACK ); 728 } 729 730 qglPushMatrix (); 731 e->angles[PITCH] = -e->angles[PITCH]; // sigh. 732 R_RotateForEntity (e); 733 e->angles[PITCH] = -e->angles[PITCH]; // sigh. 734 735 // select skin 736 if (currententity->skin) 737 skin = currententity->skin; // custom player skin 738 else 739 { 740 if (currententity->skinnum >= MAX_MD2SKINS) 741 skin = currentmodel->skins[0]; 742 else 743 { 744 skin = currentmodel->skins[currententity->skinnum]; 745 if (!skin) 746 skin = currentmodel->skins[0]; 747 } 748 } 749 if (!skin) 750 skin = r_notexture; // fallback... 751 GL_Bind(skin->texnum); 752 753 // draw it 754 755 qglShadeModel (GL_SMOOTH); 756 757 GL_TexEnv( GL_MODULATE ); 758 if ( currententity->flags & RF_TRANSLUCENT ) 759 { 760 qglEnable (GL_BLEND); 761 } 762 763 764 if ( (currententity->frame >= paliashdr->num_frames) 765 || (currententity->frame < 0) ) 766 { 767 ri.Con_Printf (PRINT_ALL, "R_DrawAliasModel %s: no such frame %d\n", 768 currentmodel->name, currententity->frame); 769 currententity->frame = 0; 770 currententity->oldframe = 0; 771 } 772 773 if ( (currententity->oldframe >= paliashdr->num_frames) 774 || (currententity->oldframe < 0)) 775 { 776 ri.Con_Printf (PRINT_ALL, "R_DrawAliasModel %s: no such oldframe %d\n", 777 currentmodel->name, currententity->oldframe); 778 currententity->frame = 0; 779 currententity->oldframe = 0; 780 } 781 782 if ( !r_lerpmodels->value ) 783 currententity->backlerp = 0; 784 GL_DrawAliasFrameLerp (paliashdr, currententity->backlerp); 785 786 GL_TexEnv( GL_REPLACE ); 787 qglShadeModel (GL_FLAT); 788 789 qglPopMatrix (); 790 791 #if 0 792 qglDisable( GL_CULL_FACE ); 793 qglPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); 794 qglDisable( GL_TEXTURE_2D ); 795 qglBegin( GL_TRIANGLE_STRIP ); 796 for ( i = 0; i < 8; i++ ) 797 { 798 qglVertex3fv( bbox[i] ); 799 } 800 qglEnd(); 801 qglEnable( GL_TEXTURE_2D ); 802 qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); 803 qglEnable( GL_CULL_FACE ); 804 #endif 805 806 if ( ( currententity->flags & RF_WEAPONMODEL ) && ( r_lefthand->value == 1.0F ) ) 807 { 808 qglMatrixMode( GL_PROJECTION ); 809 qglPopMatrix(); 810 qglMatrixMode( GL_MODELVIEW ); 811 qglCullFace( GL_FRONT ); 812 } 813 814 if ( currententity->flags & RF_TRANSLUCENT ) 815 { 816 qglDisable (GL_BLEND); 817 } 818 819 if (currententity->flags & RF_DEPTHHACK) 820 qglDepthRange (gldepthmin, gldepthmax); 821 822 #if 1 823 if (gl_shadows->value && !(currententity->flags & (RF_TRANSLUCENT | RF_WEAPONMODEL))) 824 { 825 qglPushMatrix (); 826 R_RotateForEntity (e); 827 qglDisable (GL_TEXTURE_2D); 828 qglEnable (GL_BLEND); 829 qglColor4f (0,0,0,0.5); 830 GL_DrawAliasShadow (paliashdr, currententity->frame ); 831 qglEnable (GL_TEXTURE_2D); 832 qglDisable (GL_BLEND); 833 qglPopMatrix (); 834 } 835 #endif 836 qglColor4f (1,1,1,1); 837 } 838 839