|
|
1.1.1.3 ! root 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: */ 1.1 root 20: // r_main.c 21: #include "gl_local.h" 22: 23: void R_Clear (void); 24: 25: viddef_t vid; 26: 27: refimport_t ri; 28: 1.1.1.3 ! root 29: int GL_TEXTURE0, GL_TEXTURE1; ! 30: 1.1 root 31: model_t *r_worldmodel; 32: 33: float gldepthmin, gldepthmax; 34: 35: glconfig_t gl_config; 36: glstate_t gl_state; 37: 38: image_t *r_notexture; // use for bad textures 39: image_t *r_particletexture; // little dot for particles 40: 41: entity_t *currententity; 42: model_t *currentmodel; 43: 44: cplane_t frustum[4]; 45: 46: int r_visframecount; // bumped when going to a new PVS 47: int r_framecount; // used for dlight push checking 48: 49: int c_brush_polys, c_alias_polys; 50: 51: float v_blend[4]; // final blending color 52: 53: void GL_Strings_f( void ); 54: 55: // 56: // view origin 57: // 58: vec3_t vup; 59: vec3_t vpn; 60: vec3_t vright; 61: vec3_t r_origin; 62: 63: float r_world_matrix[16]; 64: float r_base_world_matrix[16]; 65: 66: // 67: // screen size info 68: // 69: refdef_t r_newrefdef; 70: 71: int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2; 72: 73: cvar_t *r_norefresh; 74: cvar_t *r_drawentities; 75: cvar_t *r_drawworld; 76: cvar_t *r_speeds; 77: cvar_t *r_fullbright; 78: cvar_t *r_novis; 79: cvar_t *r_nocull; 80: cvar_t *r_lerpmodels; 81: cvar_t *r_lefthand; 82: 83: cvar_t *r_lightlevel; // FIXME: This is a HACK to get the client's light level 84: 85: cvar_t *gl_nosubimage; 86: cvar_t *gl_allow_software; 87: 1.1.1.2 root 88: cvar_t *gl_vertex_arrays; 89: 1.1 root 90: cvar_t *gl_particle_min_size; 91: cvar_t *gl_particle_max_size; 92: cvar_t *gl_particle_size; 93: cvar_t *gl_particle_att_a; 94: cvar_t *gl_particle_att_b; 95: cvar_t *gl_particle_att_c; 96: 97: cvar_t *gl_ext_swapinterval; 98: cvar_t *gl_ext_palettedtexture; 99: cvar_t *gl_ext_multitexture; 100: cvar_t *gl_ext_pointparameters; 1.1.1.2 root 101: cvar_t *gl_ext_compiled_vertex_array; 1.1 root 102: 103: cvar_t *gl_log; 104: cvar_t *gl_bitdepth; 105: cvar_t *gl_drawbuffer; 106: cvar_t *gl_driver; 107: cvar_t *gl_lightmap; 108: cvar_t *gl_shadows; 109: cvar_t *gl_mode; 110: cvar_t *gl_dynamic; 111: cvar_t *gl_monolightmap; 112: cvar_t *gl_modulate; 113: cvar_t *gl_nobind; 114: cvar_t *gl_round_down; 115: cvar_t *gl_picmip; 116: cvar_t *gl_skymip; 117: cvar_t *gl_showtris; 118: cvar_t *gl_ztrick; 119: cvar_t *gl_finish; 120: cvar_t *gl_clear; 121: cvar_t *gl_cull; 122: cvar_t *gl_polyblend; 123: cvar_t *gl_flashblend; 124: cvar_t *gl_playermip; 125: cvar_t *gl_saturatelighting; 126: cvar_t *gl_swapinterval; 127: cvar_t *gl_texturemode; 1.1.1.2 root 128: cvar_t *gl_texturealphamode; 129: cvar_t *gl_texturesolidmode; 1.1 root 130: cvar_t *gl_lockpvs; 131: 132: cvar_t *gl_3dlabs_broken; 133: 134: cvar_t *vid_fullscreen; 135: cvar_t *vid_gamma; 136: cvar_t *vid_ref; 137: 138: /* 139: ================= 140: R_CullBox 141: 142: Returns true if the box is completely outside the frustom 143: ================= 144: */ 145: qboolean R_CullBox (vec3_t mins, vec3_t maxs) 146: { 147: int i; 148: 149: if (r_nocull->value) 150: return false; 151: 152: for (i=0 ; i<4 ; i++) 153: if ( BOX_ON_PLANE_SIDE(mins, maxs, &frustum[i]) == 2) 154: return true; 155: return false; 156: } 157: 158: 159: void R_RotateForEntity (entity_t *e) 160: { 161: qglTranslatef (e->origin[0], e->origin[1], e->origin[2]); 162: 163: qglRotatef (e->angles[1], 0, 0, 1); 164: qglRotatef (-e->angles[0], 0, 1, 0); 165: qglRotatef (-e->angles[2], 1, 0, 0); 166: } 167: 168: /* 169: ============================================================= 170: 171: SPRITE MODELS 172: 173: ============================================================= 174: */ 175: 176: 177: /* 178: ================= 179: R_DrawSpriteModel 180: 181: ================= 182: */ 183: void R_DrawSpriteModel (entity_t *e) 184: { 185: float alpha = 1.0F; 186: vec3_t point; 187: dsprframe_t *frame; 188: float *up, *right; 189: dsprite_t *psprite; 190: 191: // don't even bother culling, because it's just a single 192: // polygon without a surface cache 193: 194: psprite = (dsprite_t *)currentmodel->extradata; 195: 196: #if 0 197: if (e->frame < 0 || e->frame >= psprite->numframes) 198: { 199: ri.Con_Printf (PRINT_ALL, "no such sprite frame %i\n", e->frame); 200: e->frame = 0; 201: } 202: #endif 203: e->frame %= psprite->numframes; 204: 205: frame = &psprite->frames[e->frame]; 206: 207: #if 0 208: if (psprite->type == SPR_ORIENTED) 209: { // bullet marks on walls 210: vec3_t v_forward, v_right, v_up; 211: 212: AngleVectors (currententity->angles, v_forward, v_right, v_up); 213: up = v_up; 214: right = v_right; 215: } 216: else 217: #endif 218: { // normal sprite 219: up = vup; 220: right = vright; 221: } 222: 223: if ( e->flags & RF_TRANSLUCENT ) 224: alpha = e->alpha; 225: 226: if ( alpha != 1.0F ) 227: qglEnable( GL_BLEND ); 228: 229: qglColor4f( 1, 1, 1, alpha ); 230: 231: GL_Bind(currentmodel->skins[e->frame]->texnum); 232: 233: GL_TexEnv( GL_MODULATE ); 234: 235: if ( alpha == 1.0 ) 236: qglEnable (GL_ALPHA_TEST); 237: else 238: qglDisable( GL_ALPHA_TEST ); 239: 240: qglBegin (GL_QUADS); 241: 242: qglTexCoord2f (0, 1); 243: VectorMA (e->origin, -frame->origin_y, up, point); 244: VectorMA (point, -frame->origin_x, right, point); 245: qglVertex3fv (point); 246: 247: qglTexCoord2f (0, 0); 248: VectorMA (e->origin, frame->height - frame->origin_y, up, point); 249: VectorMA (point, -frame->origin_x, right, point); 250: qglVertex3fv (point); 251: 252: qglTexCoord2f (1, 0); 253: VectorMA (e->origin, frame->height - frame->origin_y, up, point); 254: VectorMA (point, frame->width - frame->origin_x, right, point); 255: qglVertex3fv (point); 256: 257: qglTexCoord2f (1, 1); 258: VectorMA (e->origin, -frame->origin_y, up, point); 259: VectorMA (point, frame->width - frame->origin_x, right, point); 260: qglVertex3fv (point); 261: 262: qglEnd (); 263: 264: qglDisable (GL_ALPHA_TEST); 265: GL_TexEnv( GL_REPLACE ); 266: 267: if ( alpha != 1.0F ) 268: qglDisable( GL_BLEND ); 269: 270: qglColor4f( 1, 1, 1, 1 ); 271: } 272: 273: //================================================================================== 274: 275: /* 276: ============= 277: R_DrawNullModel 278: ============= 279: */ 280: void R_DrawNullModel (void) 281: { 282: vec3_t shadelight; 283: int i; 284: 285: if ( currententity->flags & RF_FULLBRIGHT ) 286: shadelight[0] = shadelight[1] = shadelight[2] = 1.0F; 287: else 288: R_LightPoint (currententity->origin, shadelight); 289: 290: qglPushMatrix (); 291: R_RotateForEntity (currententity); 292: 293: qglDisable (GL_TEXTURE_2D); 294: qglColor3fv (shadelight); 295: 296: qglBegin (GL_TRIANGLE_FAN); 297: qglVertex3f (0, 0, -16); 298: for (i=0 ; i<=4 ; i++) 299: qglVertex3f (16*cos(i*M_PI/2), 16*sin(i*M_PI/2), 0); 300: qglEnd (); 301: 302: qglBegin (GL_TRIANGLE_FAN); 303: qglVertex3f (0, 0, 16); 304: for (i=4 ; i>=0 ; i--) 305: qglVertex3f (16*cos(i*M_PI/2), 16*sin(i*M_PI/2), 0); 306: qglEnd (); 307: 308: qglColor3f (1,1,1); 309: qglPopMatrix (); 310: qglEnable (GL_TEXTURE_2D); 311: } 312: 313: /* 314: ============= 315: R_DrawEntitiesOnList 316: ============= 317: */ 318: void R_DrawEntitiesOnList (void) 319: { 320: int i; 321: 322: if (!r_drawentities->value) 323: return; 324: 325: // draw non-transparent first 326: for (i=0 ; i<r_newrefdef.num_entities ; i++) 327: { 328: currententity = &r_newrefdef.entities[i]; 329: if (currententity->flags & RF_TRANSLUCENT) 330: continue; // solid 331: 332: if ( currententity->flags & RF_BEAM ) 333: { 334: R_DrawBeam( currententity ); 335: } 336: else 337: { 338: currentmodel = currententity->model; 339: if (!currentmodel) 340: { 341: R_DrawNullModel (); 342: continue; 343: } 344: switch (currentmodel->type) 345: { 346: case mod_alias: 347: R_DrawAliasModel (currententity); 348: break; 349: case mod_brush: 350: R_DrawBrushModel (currententity); 351: break; 352: case mod_sprite: 353: R_DrawSpriteModel (currententity); 354: break; 355: default: 356: ri.Sys_Error (ERR_DROP, "Bad modeltype"); 357: break; 358: } 359: } 360: } 361: 362: // draw transparent entities 363: // we could sort these if it ever becomes a problem... 364: qglDepthMask (0); // no z writes 365: for (i=0 ; i<r_newrefdef.num_entities ; i++) 366: { 367: currententity = &r_newrefdef.entities[i]; 368: if (!(currententity->flags & RF_TRANSLUCENT)) 369: continue; // solid 370: 371: if ( currententity->flags & RF_BEAM ) 372: { 373: R_DrawBeam( currententity ); 374: } 375: else 376: { 377: currentmodel = currententity->model; 378: 379: if (!currentmodel) 380: { 381: R_DrawNullModel (); 382: continue; 383: } 384: switch (currentmodel->type) 385: { 386: case mod_alias: 387: R_DrawAliasModel (currententity); 388: break; 389: case mod_brush: 390: R_DrawBrushModel (currententity); 391: break; 392: case mod_sprite: 393: R_DrawSpriteModel (currententity); 394: break; 395: default: 396: ri.Sys_Error (ERR_DROP, "Bad modeltype"); 397: break; 398: } 399: } 400: } 401: qglDepthMask (1); // back to writing 402: 403: } 404: 405: /* 406: ** GL_DrawParticles 407: ** 408: */ 409: void GL_DrawParticles( int num_particles, const particle_t particles[], const unsigned colortable[768] ) 410: { 411: const particle_t *p; 412: int i; 413: vec3_t up, right; 414: float scale; 415: byte color[4]; 416: 417: GL_Bind(r_particletexture->texnum); 418: qglDepthMask( GL_FALSE ); // no z buffering 419: qglEnable( GL_BLEND ); 420: GL_TexEnv( GL_MODULATE ); 421: qglBegin( GL_TRIANGLES ); 422: 423: VectorScale (vup, 1.5, up); 424: VectorScale (vright, 1.5, right); 425: 426: for ( p = particles, i=0 ; i < num_particles ; i++,p++) 427: { 428: // hack a scale up to keep particles from disapearing 429: scale = ( p->origin[0] - r_origin[0] ) * vpn[0] + 430: ( p->origin[1] - r_origin[1] ) * vpn[1] + 431: ( p->origin[2] - r_origin[2] ) * vpn[2]; 432: 433: if (scale < 20) 434: scale = 1; 435: else 436: scale = 1 + scale * 0.004; 437: 438: *(int *)color = colortable[p->color]; 439: color[3] = p->alpha*255; 440: 441: qglColor4ubv( color ); 442: 443: qglTexCoord2f( 0.0625, 0.0625 ); 444: qglVertex3fv( p->origin ); 445: 446: qglTexCoord2f( 1.0625, 0.0625 ); 447: qglVertex3f( p->origin[0] + up[0]*scale, 448: p->origin[1] + up[1]*scale, 449: p->origin[2] + up[2]*scale); 450: 451: qglTexCoord2f( 0.0625, 1.0625 ); 452: qglVertex3f( p->origin[0] + right[0]*scale, 453: p->origin[1] + right[1]*scale, 454: p->origin[2] + right[2]*scale); 455: } 456: 457: qglEnd (); 458: qglDisable( GL_BLEND ); 459: qglColor4f( 1,1,1,1 ); 460: qglDepthMask( 1 ); // back to normal Z buffering 461: GL_TexEnv( GL_REPLACE ); 462: } 463: 464: /* 465: =============== 466: R_DrawParticles 467: =============== 468: */ 469: void R_DrawParticles (void) 470: { 471: if ( gl_ext_pointparameters->value && qglPointParameterfEXT ) 472: { 473: int i; 474: unsigned char color[4]; 475: const particle_t *p; 476: 477: qglDepthMask( GL_FALSE ); 478: qglEnable( GL_BLEND ); 479: qglDisable( GL_TEXTURE_2D ); 480: 481: qglPointSize( gl_particle_size->value ); 482: 483: qglBegin( GL_POINTS ); 484: for ( i = 0, p = r_newrefdef.particles; i < r_newrefdef.num_particles; i++, p++ ) 485: { 486: *(int *)color = d_8to24table[p->color]; 487: color[3] = p->alpha*255; 488: 489: qglColor4ubv( color ); 490: 491: qglVertex3fv( p->origin ); 492: } 493: qglEnd(); 494: 495: qglDisable( GL_BLEND ); 496: qglColor4f( 1.0F, 1.0F, 1.0F, 1.0F ); 497: qglDepthMask( GL_TRUE ); 498: qglEnable( GL_TEXTURE_2D ); 499: 500: } 501: else 502: { 503: GL_DrawParticles( r_newrefdef.num_particles, r_newrefdef.particles, d_8to24table ); 504: } 505: } 506: 507: /* 508: ============ 509: R_PolyBlend 510: ============ 511: */ 512: void R_PolyBlend (void) 513: { 514: if (!gl_polyblend->value) 515: return; 516: if (!v_blend[3]) 517: return; 518: 519: qglDisable (GL_ALPHA_TEST); 520: qglEnable (GL_BLEND); 521: qglDisable (GL_DEPTH_TEST); 522: qglDisable (GL_TEXTURE_2D); 523: 524: qglLoadIdentity (); 525: 526: // FIXME: get rid of these 527: qglRotatef (-90, 1, 0, 0); // put Z going up 528: qglRotatef (90, 0, 0, 1); // put Z going up 529: 530: qglColor4fv (v_blend); 531: 532: qglBegin (GL_QUADS); 533: 534: qglVertex3f (10, 100, 100); 535: qglVertex3f (10, -100, 100); 536: qglVertex3f (10, -100, -100); 537: qglVertex3f (10, 100, -100); 538: qglEnd (); 539: 540: qglDisable (GL_BLEND); 541: qglEnable (GL_TEXTURE_2D); 542: qglEnable (GL_ALPHA_TEST); 543: 544: qglColor4f(1,1,1,1); 545: } 546: 547: //======================================================================= 548: 549: int SignbitsForPlane (cplane_t *out) 550: { 551: int bits, j; 552: 553: // for fast box on planeside test 554: 555: bits = 0; 556: for (j=0 ; j<3 ; j++) 557: { 558: if (out->normal[j] < 0) 559: bits |= 1<<j; 560: } 561: return bits; 562: } 563: 564: 565: void R_SetFrustum (void) 566: { 567: int i; 568: 569: #if 0 570: /* 571: ** this code is wrong, since it presume a 90 degree FOV both in the 572: ** horizontal and vertical plane 573: */ 574: // front side is visible 575: VectorAdd (vpn, vright, frustum[0].normal); 576: VectorSubtract (vpn, vright, frustum[1].normal); 577: VectorAdd (vpn, vup, frustum[2].normal); 578: VectorSubtract (vpn, vup, frustum[3].normal); 579: 580: // we theoretically don't need to normalize these vectors, but I do it 581: // anyway so that debugging is a little easier 582: VectorNormalize( frustum[0].normal ); 583: VectorNormalize( frustum[1].normal ); 584: VectorNormalize( frustum[2].normal ); 585: VectorNormalize( frustum[3].normal ); 586: #else 587: // rotate VPN right by FOV_X/2 degrees 588: RotatePointAroundVector( frustum[0].normal, vup, vpn, -(90-r_newrefdef.fov_x / 2 ) ); 589: // rotate VPN left by FOV_X/2 degrees 590: RotatePointAroundVector( frustum[1].normal, vup, vpn, 90-r_newrefdef.fov_x / 2 ); 591: // rotate VPN up by FOV_X/2 degrees 592: RotatePointAroundVector( frustum[2].normal, vright, vpn, 90-r_newrefdef.fov_y / 2 ); 593: // rotate VPN down by FOV_X/2 degrees 594: RotatePointAroundVector( frustum[3].normal, vright, vpn, -( 90 - r_newrefdef.fov_y / 2 ) ); 595: #endif 596: 597: for (i=0 ; i<4 ; i++) 598: { 599: frustum[i].type = PLANE_ANYZ; 600: frustum[i].dist = DotProduct (r_origin, frustum[i].normal); 601: frustum[i].signbits = SignbitsForPlane (&frustum[i]); 602: } 603: } 604: 605: //======================================================================= 606: 607: /* 608: =============== 609: R_SetupFrame 610: =============== 611: */ 612: void R_SetupFrame (void) 613: { 614: int i; 615: mleaf_t *leaf; 616: 617: r_framecount++; 618: 619: // build the transformation matrix for the given view angles 620: VectorCopy (r_newrefdef.vieworg, r_origin); 621: 622: AngleVectors (r_newrefdef.viewangles, vpn, vright, vup); 623: 624: // current viewcluster 625: if ( !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) ) 626: { 627: r_oldviewcluster = r_viewcluster; 628: r_oldviewcluster2 = r_viewcluster2; 629: leaf = Mod_PointInLeaf (r_origin, r_worldmodel); 630: r_viewcluster = r_viewcluster2 = leaf->cluster; 631: 632: // check above and below so crossing solid water doesn't draw wrong 633: if (!leaf->contents) 634: { // look down a bit 635: vec3_t temp; 636: 637: VectorCopy (r_origin, temp); 638: temp[2] -= 16; 639: leaf = Mod_PointInLeaf (temp, r_worldmodel); 640: if ( !(leaf->contents & CONTENTS_SOLID) && 641: (leaf->cluster != r_viewcluster2) ) 642: r_viewcluster2 = leaf->cluster; 643: } 644: else 645: { // look up a bit 646: vec3_t temp; 647: 648: VectorCopy (r_origin, temp); 649: temp[2] += 16; 650: leaf = Mod_PointInLeaf (temp, r_worldmodel); 651: if ( !(leaf->contents & CONTENTS_SOLID) && 652: (leaf->cluster != r_viewcluster2) ) 653: r_viewcluster2 = leaf->cluster; 654: } 655: } 656: 657: for (i=0 ; i<4 ; i++) 658: v_blend[i] = r_newrefdef.blend[i]; 659: 660: c_brush_polys = 0; 661: c_alias_polys = 0; 662: 663: // clear out the portion of the screen that the NOWORLDMODEL defines 664: if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) 665: { 666: qglEnable( GL_SCISSOR_TEST ); 667: qglClearColor( 0.3, 0.3, 0.3, 1 ); 668: qglScissor( r_newrefdef.x, vid.height - r_newrefdef.height - r_newrefdef.y, r_newrefdef.width, r_newrefdef.height ); 669: qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 670: qglClearColor( 1, 0, 0.5, 0.5 ); 671: qglDisable( GL_SCISSOR_TEST ); 672: } 673: } 674: 675: 676: void MYgluPerspective( GLdouble fovy, GLdouble aspect, 677: GLdouble zNear, GLdouble zFar ) 678: { 679: GLdouble xmin, xmax, ymin, ymax; 680: 681: ymax = zNear * tan( fovy * M_PI / 360.0 ); 682: ymin = -ymax; 683: 684: xmin = ymin * aspect; 685: xmax = ymax * aspect; 686: 687: xmin += -( 2 * gl_state.camera_separation ) / zNear; 688: xmax += -( 2 * gl_state.camera_separation ) / zNear; 689: 690: qglFrustum( xmin, xmax, ymin, ymax, zNear, zFar ); 691: } 692: 693: 694: /* 695: ============= 696: R_SetupGL 697: ============= 698: */ 699: void R_SetupGL (void) 700: { 701: float screenaspect; 702: // float yfov; 703: int x, x2, y2, y, w, h; 704: 705: // 706: // set up viewport 707: // 708: x = floor(r_newrefdef.x * vid.width / vid.width); 709: x2 = ceil((r_newrefdef.x + r_newrefdef.width) * vid.width / vid.width); 710: y = floor(vid.height - r_newrefdef.y * vid.height / vid.height); 711: y2 = ceil(vid.height - (r_newrefdef.y + r_newrefdef.height) * vid.height / vid.height); 712: 713: w = x2 - x; 714: h = y - y2; 715: 716: qglViewport (x, y2, w, h); 717: 718: // 719: // set up projection matrix 720: // 721: screenaspect = (float)r_newrefdef.width/r_newrefdef.height; 722: // yfov = 2*atan((float)r_newrefdef.height/r_newrefdef.width)*180/M_PI; 723: qglMatrixMode(GL_PROJECTION); 724: qglLoadIdentity (); 725: MYgluPerspective (r_newrefdef.fov_y, screenaspect, 4, 4096); 726: 727: qglCullFace(GL_FRONT); 728: 729: qglMatrixMode(GL_MODELVIEW); 730: qglLoadIdentity (); 731: 732: qglRotatef (-90, 1, 0, 0); // put Z going up 733: qglRotatef (90, 0, 0, 1); // put Z going up 734: qglRotatef (-r_newrefdef.viewangles[2], 1, 0, 0); 735: qglRotatef (-r_newrefdef.viewangles[0], 0, 1, 0); 736: qglRotatef (-r_newrefdef.viewangles[1], 0, 0, 1); 737: qglTranslatef (-r_newrefdef.vieworg[0], -r_newrefdef.vieworg[1], -r_newrefdef.vieworg[2]); 738: 739: // if ( gl_state.camera_separation != 0 && gl_state.stereo_enabled ) 740: // qglTranslatef ( gl_state.camera_separation, 0, 0 ); 741: 742: qglGetFloatv (GL_MODELVIEW_MATRIX, r_world_matrix); 743: 744: // 745: // set drawing parms 746: // 747: if (gl_cull->value) 748: qglEnable(GL_CULL_FACE); 749: else 750: qglDisable(GL_CULL_FACE); 751: 752: qglDisable(GL_BLEND); 753: qglDisable(GL_ALPHA_TEST); 754: qglEnable(GL_DEPTH_TEST); 755: } 756: 757: /* 758: ============= 759: R_Clear 760: ============= 761: */ 762: void R_Clear (void) 763: { 764: if (gl_ztrick->value) 765: { 766: static int trickframe; 767: 768: if (gl_clear->value) 769: qglClear (GL_COLOR_BUFFER_BIT); 770: 771: trickframe++; 772: if (trickframe & 1) 773: { 774: gldepthmin = 0; 775: gldepthmax = 0.49999; 776: qglDepthFunc (GL_LEQUAL); 777: } 778: else 779: { 780: gldepthmin = 1; 781: gldepthmax = 0.5; 782: qglDepthFunc (GL_GEQUAL); 783: } 784: } 785: else 786: { 787: if (gl_clear->value) 788: qglClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 789: else 790: qglClear (GL_DEPTH_BUFFER_BIT); 791: gldepthmin = 0; 792: gldepthmax = 1; 793: qglDepthFunc (GL_LEQUAL); 794: } 795: 796: qglDepthRange (gldepthmin, gldepthmax); 797: 798: } 799: 800: void R_Flash( void ) 801: { 1.1.1.2 root 802: R_PolyBlend (); 1.1 root 803: } 804: 805: /* 806: ================ 807: R_RenderView 808: 809: r_newrefdef must be set before the first call 810: ================ 811: */ 812: void R_RenderView (refdef_t *fd) 813: { 814: if (r_norefresh->value) 815: return; 816: 817: r_newrefdef = *fd; 818: 819: if (!r_worldmodel && !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) ) 820: ri.Sys_Error (ERR_DROP, "R_RenderView: NULL worldmodel"); 821: 822: if (r_speeds->value) 823: { 824: c_brush_polys = 0; 825: c_alias_polys = 0; 826: } 827: 828: R_PushDlights (); 829: 830: if (gl_finish->value) 831: qglFinish (); 832: 833: R_SetupFrame (); 834: 835: R_SetFrustum (); 836: 837: R_SetupGL (); 838: 839: R_MarkLeaves (); // done here so we know if we're in water 840: 841: R_DrawWorld (); 842: 843: R_DrawEntitiesOnList (); 844: 845: R_RenderDlights (); 846: 847: R_DrawParticles (); 848: 849: R_DrawAlphaSurfaces (); 850: 851: R_Flash(); 852: 853: if (r_speeds->value) 854: { 855: ri.Con_Printf (PRINT_ALL, "%4i wpoly %4i epoly %i tex %i lmaps\n", 856: c_brush_polys, 857: c_alias_polys, 858: c_visible_textures, 859: c_visible_lightmaps); 860: } 861: } 862: 863: 864: void R_SetGL2D (void) 865: { 866: // set 2D virtual screen size 867: qglViewport (0,0, vid.width, vid.height); 868: qglMatrixMode(GL_PROJECTION); 869: qglLoadIdentity (); 870: qglOrtho (0, vid.width, vid.height, 0, -99999, 99999); 871: qglMatrixMode(GL_MODELVIEW); 872: qglLoadIdentity (); 873: qglDisable (GL_DEPTH_TEST); 874: qglDisable (GL_CULL_FACE); 875: qglDisable (GL_BLEND); 876: qglEnable (GL_ALPHA_TEST); 877: qglColor4f (1,1,1,1); 878: } 879: 880: static void GL_DrawColoredStereoLinePair( float r, float g, float b, float y ) 881: { 882: qglColor3f( r, g, b ); 883: qglVertex2f( 0, y ); 884: qglVertex2f( vid.width, y ); 885: qglColor3f( 0, 0, 0 ); 886: qglVertex2f( 0, y + 1 ); 887: qglVertex2f( vid.width, y + 1 ); 888: } 889: 890: static void GL_DrawStereoPattern( void ) 891: { 892: int i; 893: 894: if ( !( gl_config.renderer & GL_RENDERER_INTERGRAPH ) ) 895: return; 896: 897: if ( !gl_state.stereo_enabled ) 898: return; 899: 900: R_SetGL2D(); 901: 902: qglDrawBuffer( GL_BACK_LEFT ); 903: 904: for ( i = 0; i < 20; i++ ) 905: { 906: qglBegin( GL_LINES ); 907: GL_DrawColoredStereoLinePair( 1, 0, 0, 0 ); 908: GL_DrawColoredStereoLinePair( 1, 0, 0, 2 ); 909: GL_DrawColoredStereoLinePair( 1, 0, 0, 4 ); 910: GL_DrawColoredStereoLinePair( 1, 0, 0, 6 ); 911: GL_DrawColoredStereoLinePair( 0, 1, 0, 8 ); 912: GL_DrawColoredStereoLinePair( 1, 1, 0, 10); 913: GL_DrawColoredStereoLinePair( 1, 1, 0, 12); 914: GL_DrawColoredStereoLinePair( 0, 1, 0, 14); 915: qglEnd(); 916: 917: GLimp_EndFrame(); 918: } 919: } 920: 921: 922: /* 923: ==================== 924: R_SetLightLevel 925: 926: ==================== 927: */ 928: void R_SetLightLevel (void) 929: { 930: vec3_t shadelight; 931: 932: if (r_newrefdef.rdflags & RDF_NOWORLDMODEL) 933: return; 934: 935: // save off light value for server to look at (BIG HACK!) 936: 937: R_LightPoint (r_newrefdef.vieworg, shadelight); 938: 939: // pick the greatest component, which should be the same 940: // as the mono value returned by software 941: if (shadelight[0] > shadelight[1]) 942: { 943: if (shadelight[0] > shadelight[2]) 944: r_lightlevel->value = 150*shadelight[0]; 945: else 946: r_lightlevel->value = 150*shadelight[2]; 947: } 948: else 949: { 950: if (shadelight[1] > shadelight[2]) 951: r_lightlevel->value = 150*shadelight[1]; 952: else 953: r_lightlevel->value = 150*shadelight[2]; 954: } 955: 956: } 957: 958: /* 959: @@@@@@@@@@@@@@@@@@@@@ 960: R_RenderFrame 961: 962: @@@@@@@@@@@@@@@@@@@@@ 963: */ 964: void R_RenderFrame (refdef_t *fd) 965: { 966: R_RenderView( fd ); 967: R_SetLightLevel (); 968: R_SetGL2D (); 969: } 970: 971: 972: void R_Register( void ) 973: { 974: r_lefthand = ri.Cvar_Get( "hand", "0", CVAR_USERINFO | CVAR_ARCHIVE ); 975: r_norefresh = ri.Cvar_Get ("r_norefresh", "0", 0); 976: r_fullbright = ri.Cvar_Get ("r_fullbright", "0", 0); 977: r_drawentities = ri.Cvar_Get ("r_drawentities", "1", 0); 978: r_drawworld = ri.Cvar_Get ("r_drawworld", "1", 0); 979: r_novis = ri.Cvar_Get ("r_novis", "0", 0); 980: r_nocull = ri.Cvar_Get ("r_nocull", "0", 0); 981: r_lerpmodels = ri.Cvar_Get ("r_lerpmodels", "1", 0); 982: r_speeds = ri.Cvar_Get ("r_speeds", "0", 0); 983: 984: r_lightlevel = ri.Cvar_Get ("r_lightlevel", "0", 0); 985: 986: gl_nosubimage = ri.Cvar_Get( "gl_nosubimage", "0", 0 ); 987: gl_allow_software = ri.Cvar_Get( "gl_allow_software", "0", 0 ); 988: 989: gl_particle_min_size = ri.Cvar_Get( "gl_particle_min_size", "2", CVAR_ARCHIVE ); 990: gl_particle_max_size = ri.Cvar_Get( "gl_particle_max_size", "40", CVAR_ARCHIVE ); 991: gl_particle_size = ri.Cvar_Get( "gl_particle_size", "40", CVAR_ARCHIVE ); 992: gl_particle_att_a = ri.Cvar_Get( "gl_particle_att_a", "0.01", CVAR_ARCHIVE ); 993: gl_particle_att_b = ri.Cvar_Get( "gl_particle_att_b", "0.0", CVAR_ARCHIVE ); 994: gl_particle_att_c = ri.Cvar_Get( "gl_particle_att_c", "0.01", CVAR_ARCHIVE ); 995: 996: gl_modulate = ri.Cvar_Get ("gl_modulate", "1", CVAR_ARCHIVE ); 997: gl_log = ri.Cvar_Get( "gl_log", "0", 0 ); 998: gl_bitdepth = ri.Cvar_Get( "gl_bitdepth", "0", 0 ); 999: gl_mode = ri.Cvar_Get( "gl_mode", "3", CVAR_ARCHIVE ); 1000: gl_lightmap = ri.Cvar_Get ("gl_lightmap", "0", 0); 1001: gl_shadows = ri.Cvar_Get ("gl_shadows", "0", CVAR_ARCHIVE ); 1002: gl_dynamic = ri.Cvar_Get ("gl_dynamic", "1", 0); 1003: gl_nobind = ri.Cvar_Get ("gl_nobind", "0", 0); 1004: gl_round_down = ri.Cvar_Get ("gl_round_down", "1", 0); 1005: gl_picmip = ri.Cvar_Get ("gl_picmip", "0", 0); 1006: gl_skymip = ri.Cvar_Get ("gl_skymip", "0", 0); 1007: gl_showtris = ri.Cvar_Get ("gl_showtris", "0", 0); 1008: gl_ztrick = ri.Cvar_Get ("gl_ztrick", "0", 0); 1.1.1.2 root 1009: gl_finish = ri.Cvar_Get ("gl_finish", "0", CVAR_ARCHIVE); 1.1 root 1010: gl_clear = ri.Cvar_Get ("gl_clear", "0", 0); 1011: gl_cull = ri.Cvar_Get ("gl_cull", "1", 0); 1012: gl_polyblend = ri.Cvar_Get ("gl_polyblend", "1", 0); 1013: gl_flashblend = ri.Cvar_Get ("gl_flashblend", "0", 0); 1014: gl_playermip = ri.Cvar_Get ("gl_playermip", "0", 0); 1015: gl_monolightmap = ri.Cvar_Get( "gl_monolightmap", "0", 0 ); 1016: gl_driver = ri.Cvar_Get( "gl_driver", "opengl32", CVAR_ARCHIVE ); 1017: gl_texturemode = ri.Cvar_Get( "gl_texturemode", "GL_LINEAR_MIPMAP_NEAREST", CVAR_ARCHIVE ); 1.1.1.2 root 1018: gl_texturealphamode = ri.Cvar_Get( "gl_texturealphamode", "default", CVAR_ARCHIVE ); 1019: gl_texturesolidmode = ri.Cvar_Get( "gl_texturesolidmode", "default", CVAR_ARCHIVE ); 1.1 root 1020: gl_lockpvs = ri.Cvar_Get( "gl_lockpvs", "0", 0 ); 1021: 1.1.1.2 root 1022: gl_vertex_arrays = ri.Cvar_Get( "gl_vertex_arrays", "0", CVAR_ARCHIVE ); 1023: 1.1 root 1024: gl_ext_swapinterval = ri.Cvar_Get( "gl_ext_swapinterval", "1", CVAR_ARCHIVE ); 1025: gl_ext_palettedtexture = ri.Cvar_Get( "gl_ext_palettedtexture", "1", CVAR_ARCHIVE ); 1026: gl_ext_multitexture = ri.Cvar_Get( "gl_ext_multitexture", "1", CVAR_ARCHIVE ); 1027: gl_ext_pointparameters = ri.Cvar_Get( "gl_ext_pointparameters", "1", CVAR_ARCHIVE ); 1.1.1.2 root 1028: gl_ext_compiled_vertex_array = ri.Cvar_Get( "gl_ext_compiled_vertex_array", "1", CVAR_ARCHIVE ); 1.1 root 1029: 1030: gl_drawbuffer = ri.Cvar_Get( "gl_drawbuffer", "GL_BACK", 0 ); 1031: gl_swapinterval = ri.Cvar_Get( "gl_swapinterval", "1", CVAR_ARCHIVE ); 1032: 1033: gl_saturatelighting = ri.Cvar_Get( "gl_saturatelighting", "0", 0 ); 1034: 1035: gl_3dlabs_broken = ri.Cvar_Get( "gl_3dlabs_broken", "1", CVAR_ARCHIVE ); 1036: 1037: vid_fullscreen = ri.Cvar_Get( "vid_fullscreen", "0", CVAR_ARCHIVE ); 1038: vid_gamma = ri.Cvar_Get( "vid_gamma", "1.0", CVAR_ARCHIVE ); 1039: vid_ref = ri.Cvar_Get( "vid_ref", "soft", CVAR_ARCHIVE ); 1040: 1041: ri.Cmd_AddCommand( "imagelist", GL_ImageList_f ); 1042: ri.Cmd_AddCommand( "screenshot", GL_ScreenShot_f ); 1043: ri.Cmd_AddCommand( "modellist", Mod_Modellist_f ); 1044: ri.Cmd_AddCommand( "gl_strings", GL_Strings_f ); 1045: } 1046: 1047: /* 1048: ================== 1049: R_SetMode 1050: ================== 1051: */ 1052: qboolean R_SetMode (void) 1053: { 1054: rserr_t err; 1055: qboolean fullscreen; 1056: 1057: if ( vid_fullscreen->modified && !gl_config.allow_cds ) 1058: { 1059: ri.Con_Printf( PRINT_ALL, "R_SetMode() - CDS not allowed with this driver\n" ); 1060: ri.Cvar_SetValue( "vid_fullscreen", !vid_fullscreen->value ); 1061: vid_fullscreen->modified = false; 1062: } 1063: 1064: fullscreen = vid_fullscreen->value; 1065: 1066: vid_fullscreen->modified = false; 1067: gl_mode->modified = false; 1068: 1069: if ( ( err = GLimp_SetMode( &vid.width, &vid.height, gl_mode->value, fullscreen ) ) == rserr_ok ) 1070: { 1071: gl_state.prev_mode = gl_mode->value; 1072: } 1073: else 1074: { 1075: if ( err == rserr_invalid_fullscreen ) 1076: { 1077: ri.Cvar_SetValue( "vid_fullscreen", 0); 1078: vid_fullscreen->modified = false; 1079: ri.Con_Printf( PRINT_ALL, "ref_gl::R_SetMode() - fullscreen unavailable in this mode\n" ); 1080: if ( ( err = GLimp_SetMode( &vid.width, &vid.height, gl_mode->value, false ) ) == rserr_ok ) 1081: return true; 1082: } 1083: else if ( err == rserr_invalid_mode ) 1084: { 1085: ri.Cvar_SetValue( "gl_mode", gl_state.prev_mode ); 1086: gl_mode->modified = false; 1087: ri.Con_Printf( PRINT_ALL, "ref_gl::R_SetMode() - invalid mode\n" ); 1088: } 1089: 1090: // try setting it back to something safe 1091: if ( ( err = GLimp_SetMode( &vid.width, &vid.height, gl_state.prev_mode, false ) ) != rserr_ok ) 1092: { 1093: ri.Con_Printf( PRINT_ALL, "ref_gl::R_SetMode() - could not revert to safe mode\n" ); 1094: return false; 1095: } 1096: } 1097: return true; 1098: } 1099: 1100: /* 1101: =============== 1102: R_Init 1103: =============== 1104: */ 1105: int R_Init( void *hinstance, void *hWnd ) 1106: { 1107: char renderer_buffer[1000]; 1.1.1.2 root 1108: char vendor_buffer[1000]; 1.1 root 1109: int err; 1110: int j; 1111: extern float r_turbsin[256]; 1112: 1113: for ( j = 0; j < 256; j++ ) 1114: { 1115: r_turbsin[j] *= 0.5; 1116: } 1117: 1118: ri.Con_Printf (PRINT_ALL, "ref_gl version: "REF_VERSION"\n"); 1119: 1120: Draw_GetPalette (); 1121: 1122: R_Register(); 1123: 1124: // initialize our QGL dynamic bindings 1125: if ( !QGL_Init( gl_driver->string ) ) 1126: { 1127: QGL_Shutdown(); 1128: ri.Con_Printf (PRINT_ALL, "ref_gl::R_Init() - could not load \"%s\"\n", gl_driver->string ); 1129: return -1; 1130: } 1131: 1132: // initialize OS-specific parts of OpenGL 1133: if ( !GLimp_Init( hinstance, hWnd ) ) 1134: { 1135: QGL_Shutdown(); 1136: return -1; 1137: } 1138: 1139: // set our "safe" modes 1140: gl_state.prev_mode = 3; 1141: 1142: // create the window and set up the context 1143: if ( !R_SetMode () ) 1144: { 1145: QGL_Shutdown(); 1146: ri.Con_Printf (PRINT_ALL, "ref_gl::R_Init() - could not R_SetMode()\n" ); 1147: return -1; 1148: } 1149: 1150: ri.Vid_MenuInit(); 1151: 1152: /* 1153: ** get our various GL strings 1154: */ 1155: gl_config.vendor_string = qglGetString (GL_VENDOR); 1156: ri.Con_Printf (PRINT_ALL, "GL_VENDOR: %s\n", gl_config.vendor_string ); 1157: gl_config.renderer_string = qglGetString (GL_RENDERER); 1158: ri.Con_Printf (PRINT_ALL, "GL_RENDERER: %s\n", gl_config.renderer_string ); 1159: gl_config.version_string = qglGetString (GL_VERSION); 1160: ri.Con_Printf (PRINT_ALL, "GL_VERSION: %s\n", gl_config.version_string ); 1161: gl_config.extensions_string = qglGetString (GL_EXTENSIONS); 1162: ri.Con_Printf (PRINT_ALL, "GL_EXTENSIONS: %s\n", gl_config.extensions_string ); 1163: 1164: strcpy( renderer_buffer, gl_config.renderer_string ); 1165: strlwr( renderer_buffer ); 1166: 1.1.1.2 root 1167: strcpy( vendor_buffer, gl_config.vendor_string ); 1168: strlwr( vendor_buffer ); 1169: 1.1 root 1170: if ( strstr( renderer_buffer, "voodoo" ) ) 1171: { 1172: if ( !strstr( renderer_buffer, "rush" ) ) 1173: gl_config.renderer = GL_RENDERER_VOODOO; 1174: else 1175: gl_config.renderer = GL_RENDERER_VOODOO_RUSH; 1176: } 1.1.1.2 root 1177: else if ( strstr( vendor_buffer, "sgi" ) ) 1178: gl_config.renderer = GL_RENDERER_SGI; 1.1 root 1179: else if ( strstr( renderer_buffer, "permedia" ) ) 1180: gl_config.renderer = GL_RENDERER_PERMEDIA2; 1181: else if ( strstr( renderer_buffer, "glint" ) ) 1182: gl_config.renderer = GL_RENDERER_GLINT_MX; 1183: else if ( strstr( renderer_buffer, "glzicd" ) ) 1184: gl_config.renderer = GL_RENDERER_REALIZM; 1185: else if ( strstr( renderer_buffer, "gdi" ) ) 1186: gl_config.renderer = GL_RENDERER_MCD; 1187: else if ( strstr( renderer_buffer, "pcx2" ) ) 1188: gl_config.renderer = GL_RENDERER_PCX2; 1189: else if ( strstr( renderer_buffer, "verite" ) ) 1190: gl_config.renderer = GL_RENDERER_RENDITION; 1191: else 1192: gl_config.renderer = GL_RENDERER_OTHER; 1193: 1194: if ( toupper( gl_monolightmap->string[1] ) != 'F' ) 1195: { 1196: if ( gl_config.renderer == GL_RENDERER_PERMEDIA2 ) 1197: { 1198: ri.Cvar_Set( "gl_monolightmap", "A" ); 1199: ri.Con_Printf( PRINT_ALL, "...using gl_monolightmap 'a'\n" ); 1200: } 1201: else if ( gl_config.renderer & GL_RENDERER_POWERVR ) 1202: { 1203: ri.Cvar_Set( "gl_monolightmap", "0" ); 1204: } 1205: else 1206: { 1207: ri.Cvar_Set( "gl_monolightmap", "0" ); 1208: } 1209: } 1210: 1211: // power vr can't have anything stay in the framebuffer, so 1212: // the screen needs to redraw the tiled background every frame 1213: if ( gl_config.renderer & GL_RENDERER_POWERVR ) 1214: { 1215: ri.Cvar_Set( "scr_drawall", "1" ); 1216: } 1217: else 1218: { 1219: ri.Cvar_Set( "scr_drawall", "0" ); 1220: } 1221: 1.1.1.3 ! root 1222: #ifdef __linux__ ! 1223: ri.Cvar_SetValue( "gl_finish", 1 ); ! 1224: #endif ! 1225: 1.1 root 1226: // MCD has buffering issues 1227: if ( gl_config.renderer == GL_RENDERER_MCD ) 1228: { 1229: ri.Cvar_SetValue( "gl_finish", 1 ); 1230: } 1231: 1232: if ( gl_config.renderer & GL_RENDERER_3DLABS ) 1233: { 1234: if ( gl_3dlabs_broken->value ) 1235: gl_config.allow_cds = false; 1236: else 1237: gl_config.allow_cds = true; 1238: } 1239: else 1240: { 1241: gl_config.allow_cds = true; 1242: } 1243: 1244: if ( gl_config.allow_cds ) 1245: ri.Con_Printf( PRINT_ALL, "...allowing CDS\n" ); 1246: else 1247: ri.Con_Printf( PRINT_ALL, "...disabling CDS\n" ); 1248: 1249: /* 1250: ** grab extensions 1251: */ 1.1.1.2 root 1252: if ( strstr( gl_config.extensions_string, "GL_EXT_compiled_vertex_array" ) || 1253: strstr( gl_config.extensions_string, "GL_SGI_compiled_vertex_array" ) ) 1.1 root 1254: { 1.1.1.2 root 1255: ri.Con_Printf( PRINT_ALL, "...enabling GL_EXT_compiled_vertex_array\n" ); 1256: qglLockArraysEXT = ( void * ) qwglGetProcAddress( "glLockArraysEXT" ); 1257: qglUnlockArraysEXT = ( void * ) qwglGetProcAddress( "glUnlockArraysEXT" ); 1.1 root 1258: } 1259: else 1260: { 1.1.1.2 root 1261: ri.Con_Printf( PRINT_ALL, "...GL_EXT_compiled_vertex_array not found\n" ); 1.1 root 1262: } 1263: 1.1.1.3 ! root 1264: #ifdef _WIN32 1.1.1.2 root 1265: if ( strstr( gl_config.extensions_string, "WGL_EXT_swap_control" ) ) 1.1 root 1266: { 1.1.1.2 root 1267: qwglSwapIntervalEXT = ( BOOL (WINAPI *)(int)) qwglGetProcAddress( "wglSwapIntervalEXT" ); 1268: ri.Con_Printf( PRINT_ALL, "...enabling WGL_EXT_swap_control\n" ); 1.1 root 1269: } 1270: else 1271: { 1.1.1.2 root 1272: ri.Con_Printf( PRINT_ALL, "...WGL_EXT_swap_control not found\n" ); 1.1 root 1273: } 1.1.1.3 ! root 1274: #endif 1.1 root 1275: 1276: if ( strstr( gl_config.extensions_string, "GL_EXT_point_parameters" ) ) 1277: { 1278: if ( gl_ext_pointparameters->value ) 1279: { 1280: qglPointParameterfEXT = ( void (APIENTRY *)( GLenum, GLfloat ) ) qwglGetProcAddress( "glPointParameterfEXT" ); 1281: qglPointParameterfvEXT = ( void (APIENTRY *)( GLenum, const GLfloat * ) ) qwglGetProcAddress( "glPointParameterfvEXT" ); 1282: ri.Con_Printf( PRINT_ALL, "...using GL_EXT_point_parameters\n" ); 1283: } 1284: else 1285: { 1286: ri.Con_Printf( PRINT_ALL, "...ignoring GL_EXT_point_parameters\n" ); 1287: } 1288: } 1289: else 1290: { 1291: ri.Con_Printf( PRINT_ALL, "...GL_EXT_point_parameters not found\n" ); 1292: } 1293: 1.1.1.3 ! root 1294: #ifdef __linux__ ! 1295: if ( strstr( gl_config.extensions_string, "3DFX_set_global_palette" )) ! 1296: { ! 1297: if ( gl_ext_palettedtexture->value ) ! 1298: { ! 1299: ri.Con_Printf( PRINT_ALL, "...using 3DFX_set_global_palette\n" ); ! 1300: qgl3DfxSetPaletteEXT = ( void ( APIENTRY * ) (GLuint *) )qwglGetProcAddress( "gl3DfxSetPaletteEXT" ); ! 1301: qglColorTableEXT = Fake_glColorTableEXT; ! 1302: } ! 1303: else ! 1304: { ! 1305: ri.Con_Printf( PRINT_ALL, "...ignoring 3DFX_set_global_palette\n" ); ! 1306: } ! 1307: } ! 1308: else ! 1309: { ! 1310: ri.Con_Printf( PRINT_ALL, "...3DFX_set_global_palette not found\n" ); ! 1311: } ! 1312: #endif ! 1313: ! 1314: if ( !qglColorTableEXT && ! 1315: strstr( gl_config.extensions_string, "GL_EXT_paletted_texture" ) && ! 1316: strstr( gl_config.extensions_string, "GL_EXT_shared_texture_palette" ) ) 1.1 root 1317: { 1318: if ( gl_ext_palettedtexture->value ) 1319: { 1320: ri.Con_Printf( PRINT_ALL, "...using GL_EXT_shared_texture_palette\n" ); 1321: qglColorTableEXT = ( void ( APIENTRY * ) ( int, int, int, int, int, const void * ) ) qwglGetProcAddress( "glColorTableEXT" ); 1322: } 1323: else 1324: { 1325: ri.Con_Printf( PRINT_ALL, "...ignoring GL_EXT_shared_texture_palette\n" ); 1326: } 1327: } 1328: else 1329: { 1330: ri.Con_Printf( PRINT_ALL, "...GL_EXT_shared_texture_palette not found\n" ); 1331: } 1332: 1.1.1.3 ! root 1333: if ( strstr( gl_config.extensions_string, "GL_ARB_multitexture" ) ) 1.1 root 1334: { 1335: if ( gl_ext_multitexture->value ) 1336: { 1.1.1.3 ! root 1337: ri.Con_Printf( PRINT_ALL, "...using GL_ARB_multitexture\n" ); ! 1338: qglMTexCoord2fSGIS = ( void * ) qwglGetProcAddress( "glMultiTexCoord2fARB" ); ! 1339: qglActiveTextureARB = ( void * ) qwglGetProcAddress( "glActiveTextureARB" ); ! 1340: qglClientActiveTextureARB = ( void * ) qwglGetProcAddress( "glClientActiveTextureARB" ); ! 1341: GL_TEXTURE0 = GL_TEXTURE0_ARB; ! 1342: GL_TEXTURE1 = GL_TEXTURE1_ARB; ! 1343: } ! 1344: else ! 1345: { ! 1346: ri.Con_Printf( PRINT_ALL, "...ignoring GL_ARB_multitexture\n" ); ! 1347: } ! 1348: } ! 1349: else ! 1350: { ! 1351: ri.Con_Printf( PRINT_ALL, "...GL_ARB_multitexture not found\n" ); ! 1352: } ! 1353: ! 1354: if ( strstr( gl_config.extensions_string, "GL_SGIS_multitexture" ) ) ! 1355: { ! 1356: if ( qglActiveTextureARB ) ! 1357: { ! 1358: ri.Con_Printf( PRINT_ALL, "...GL_SGIS_multitexture deprecated in favor of ARB_multitexture\n" ); ! 1359: } ! 1360: else if ( gl_ext_multitexture->value ) ! 1361: { 1.1 root 1362: ri.Con_Printf( PRINT_ALL, "...using GL_SGIS_multitexture\n" ); 1363: qglMTexCoord2fSGIS = ( void * ) qwglGetProcAddress( "glMTexCoord2fSGIS" ); 1364: qglSelectTextureSGIS = ( void * ) qwglGetProcAddress( "glSelectTextureSGIS" ); 1.1.1.3 ! root 1365: GL_TEXTURE0 = GL_TEXTURE0_SGIS; ! 1366: GL_TEXTURE1 = GL_TEXTURE1_SGIS; 1.1 root 1367: } 1368: else 1369: { 1370: ri.Con_Printf( PRINT_ALL, "...ignoring GL_SGIS_multitexture\n" ); 1371: } 1372: } 1373: else 1374: { 1375: ri.Con_Printf( PRINT_ALL, "...GL_SGIS_multitexture not found\n" ); 1376: } 1377: 1378: GL_SetDefaultState(); 1379: 1380: /* 1381: ** draw our stereo patterns 1382: */ 1383: #if 0 // commented out until H3D pays us the money they owe us 1384: GL_DrawStereoPattern(); 1385: #endif 1386: 1387: GL_InitImages (); 1388: Mod_Init (); 1389: R_InitParticleTexture (); 1390: Draw_InitLocal (); 1391: 1392: err = qglGetError(); 1393: if ( err != GL_NO_ERROR ) 1394: ri.Con_Printf (PRINT_ALL, "glGetError() = 0x%x\n", err); 1395: } 1396: 1397: /* 1398: =============== 1399: R_Shutdown 1400: =============== 1401: */ 1402: void R_Shutdown (void) 1403: { 1404: ri.Cmd_RemoveCommand ("modellist"); 1405: ri.Cmd_RemoveCommand ("screenshot"); 1406: ri.Cmd_RemoveCommand ("imagelist"); 1407: ri.Cmd_RemoveCommand ("gl_strings"); 1408: 1409: Mod_FreeAll (); 1410: 1411: GL_ShutdownImages (); 1412: 1413: /* 1414: ** shut down OS specific OpenGL stuff like contexts, etc. 1415: */ 1416: GLimp_Shutdown(); 1417: 1418: /* 1419: ** shutdown our QGL subsystem 1420: */ 1421: QGL_Shutdown(); 1422: } 1423: 1424: 1425: 1426: /* 1427: @@@@@@@@@@@@@@@@@@@@@ 1428: R_BeginFrame 1429: @@@@@@@@@@@@@@@@@@@@@ 1430: */ 1431: void R_BeginFrame( float camera_separation ) 1432: { 1433: 1434: gl_state.camera_separation = camera_separation; 1435: 1436: /* 1437: ** change modes if necessary 1438: */ 1439: if ( gl_mode->modified || vid_fullscreen->modified ) 1440: { // FIXME: only restart if CDS is required 1441: cvar_t *ref; 1442: 1443: ref = ri.Cvar_Get ("vid_ref", "gl", 0); 1444: ref->modified = true; 1445: } 1446: 1447: if ( gl_log->modified ) 1448: { 1449: GLimp_EnableLogging( gl_log->value ); 1450: gl_log->modified = false; 1451: } 1452: 1453: if ( gl_log->value ) 1454: { 1455: GLimp_LogNewFrame(); 1456: } 1457: 1458: /* 1459: ** update 3Dfx gamma -- it is expected that a user will do a vid_restart 1460: ** after tweaking this value 1461: */ 1462: if ( vid_gamma->modified ) 1463: { 1464: vid_gamma->modified = false; 1465: 1.1.1.2 root 1466: if ( gl_config.renderer & ( GL_RENDERER_VOODOO ) ) 1.1 root 1467: { 1468: char envbuffer[1024]; 1469: float g; 1470: 1471: g = 2.00 * ( 0.8 - ( vid_gamma->value - 0.5 ) ) + 1.0F; 1472: Com_sprintf( envbuffer, sizeof(envbuffer), "SSTV2_GAMMA=%f", g ); 1473: putenv( envbuffer ); 1474: Com_sprintf( envbuffer, sizeof(envbuffer), "SST_GAMMA=%f", g ); 1475: putenv( envbuffer ); 1476: } 1477: } 1478: 1479: GLimp_BeginFrame( camera_separation ); 1480: 1481: /* 1482: ** go into 2D mode 1483: */ 1484: qglViewport (0,0, vid.width, vid.height); 1485: qglMatrixMode(GL_PROJECTION); 1486: qglLoadIdentity (); 1487: qglOrtho (0, vid.width, vid.height, 0, -99999, 99999); 1488: qglMatrixMode(GL_MODELVIEW); 1489: qglLoadIdentity (); 1490: qglDisable (GL_DEPTH_TEST); 1491: qglDisable (GL_CULL_FACE); 1492: qglDisable (GL_BLEND); 1493: qglEnable (GL_ALPHA_TEST); 1494: qglColor4f (1,1,1,1); 1495: 1496: /* 1497: ** draw buffer stuff 1498: */ 1499: if ( gl_drawbuffer->modified ) 1500: { 1501: gl_drawbuffer->modified = false; 1502: 1503: if ( gl_state.camera_separation == 0 || !gl_state.stereo_enabled ) 1504: { 1.1.1.2 root 1505: if ( Q_stricmp( gl_drawbuffer->string, "GL_FRONT" ) == 0 ) 1.1 root 1506: qglDrawBuffer( GL_FRONT ); 1507: else 1508: qglDrawBuffer( GL_BACK ); 1509: } 1510: } 1511: 1512: /* 1513: ** texturemode stuff 1514: */ 1515: if ( gl_texturemode->modified ) 1516: { 1517: GL_TextureMode( gl_texturemode->string ); 1518: gl_texturemode->modified = false; 1519: } 1520: 1.1.1.2 root 1521: if ( gl_texturealphamode->modified ) 1522: { 1523: GL_TextureAlphaMode( gl_texturealphamode->string ); 1524: gl_texturealphamode->modified = false; 1525: } 1526: 1527: if ( gl_texturesolidmode->modified ) 1528: { 1529: GL_TextureSolidMode( gl_texturesolidmode->string ); 1530: gl_texturesolidmode->modified = false; 1531: } 1532: 1.1 root 1533: /* 1534: ** swapinterval stuff 1535: */ 1536: GL_UpdateSwapInterval(); 1537: 1538: // 1539: // clear screen if desired 1540: // 1541: R_Clear (); 1542: } 1543: 1544: /* 1545: ============= 1546: R_SetPalette 1547: ============= 1548: */ 1549: unsigned r_rawpalette[256]; 1550: 1551: void R_SetPalette ( const unsigned char *palette) 1552: { 1553: int i; 1554: 1555: byte *rp = ( byte * ) r_rawpalette; 1556: 1557: if ( palette ) 1558: { 1559: for ( i = 0; i < 256; i++ ) 1560: { 1561: rp[i*4+0] = palette[i*3+0]; 1562: rp[i*4+1] = palette[i*3+1]; 1563: rp[i*4+2] = palette[i*3+2]; 1564: rp[i*4+3] = 0xff; 1565: } 1566: } 1567: else 1568: { 1569: for ( i = 0; i < 256; i++ ) 1570: { 1571: rp[i*4+0] = d_8to24table[i] & 0xff; 1572: rp[i*4+1] = ( d_8to24table[i] >> 8 ) & 0xff; 1573: rp[i*4+2] = ( d_8to24table[i] >> 16 ) & 0xff; 1574: rp[i*4+3] = 0xff; 1575: } 1576: } 1577: GL_SetTexturePalette( r_rawpalette ); 1578: 1579: qglClearColor (0,0,0,0); 1580: qglClear (GL_COLOR_BUFFER_BIT); 1581: qglClearColor (1,0, 0.5 , 0.5); 1582: } 1583: 1584: /* 1585: ** R_DrawBeam 1586: */ 1587: void R_DrawBeam( entity_t *e ) 1588: { 1589: #define NUM_BEAM_SEGS 6 1590: 1591: int i; 1592: float r, g, b; 1593: 1594: vec3_t perpvec; 1595: vec3_t direction, normalized_direction; 1596: vec3_t start_points[NUM_BEAM_SEGS], end_points[NUM_BEAM_SEGS]; 1597: vec3_t oldorigin, origin; 1598: 1599: oldorigin[0] = e->oldorigin[0]; 1600: oldorigin[1] = e->oldorigin[1]; 1601: oldorigin[2] = e->oldorigin[2]; 1602: 1603: origin[0] = e->origin[0]; 1604: origin[1] = e->origin[1]; 1605: origin[2] = e->origin[2]; 1606: 1607: normalized_direction[0] = direction[0] = oldorigin[0] - origin[0]; 1608: normalized_direction[1] = direction[1] = oldorigin[1] - origin[1]; 1609: normalized_direction[2] = direction[2] = oldorigin[2] - origin[2]; 1610: 1611: if ( VectorNormalize( normalized_direction ) == 0 ) 1612: return; 1613: 1614: PerpendicularVector( perpvec, normalized_direction ); 1615: VectorScale( perpvec, e->frame / 2, perpvec ); 1616: 1617: for ( i = 0; i < 6; i++ ) 1618: { 1619: RotatePointAroundVector( start_points[i], normalized_direction, perpvec, (360.0/NUM_BEAM_SEGS)*i ); 1620: VectorAdd( start_points[i], origin, start_points[i] ); 1621: VectorAdd( start_points[i], direction, end_points[i] ); 1622: } 1623: 1624: qglDisable( GL_TEXTURE_2D ); 1625: qglEnable( GL_BLEND ); 1626: qglDepthMask( GL_FALSE ); 1627: 1628: r = ( d_8to24table[e->skinnum & 0xFF] ) & 0xFF; 1629: g = ( d_8to24table[e->skinnum & 0xFF] >> 8 ) & 0xFF; 1630: b = ( d_8to24table[e->skinnum & 0xFF] >> 16 ) & 0xFF; 1631: 1632: r *= 1/255.0F; 1633: g *= 1/255.0F; 1634: b *= 1/255.0F; 1635: 1636: qglColor4f( r, g, b, e->alpha ); 1637: 1638: qglBegin( GL_TRIANGLE_STRIP ); 1639: for ( i = 0; i < NUM_BEAM_SEGS; i++ ) 1640: { 1641: qglVertex3fv( start_points[i] ); 1642: qglVertex3fv( end_points[i] ); 1643: qglVertex3fv( start_points[(i+1)%NUM_BEAM_SEGS] ); 1644: qglVertex3fv( end_points[(i+1)%NUM_BEAM_SEGS] ); 1645: } 1646: qglEnd(); 1647: 1648: qglEnable( GL_TEXTURE_2D ); 1649: qglDisable( GL_BLEND ); 1650: qglDepthMask( GL_TRUE ); 1651: } 1652: 1653: //=================================================================== 1654: 1655: 1656: void R_BeginRegistration (char *map); 1657: struct model_s *R_RegisterModel (char *name); 1658: struct image_s *R_RegisterSkin (char *name); 1659: void R_SetSky (char *name, float rotate, vec3_t axis); 1660: void R_EndRegistration (void); 1661: 1662: void R_RenderFrame (refdef_t *fd); 1663: 1664: struct image_s *Draw_FindPic (char *name); 1665: 1666: void Draw_Pic (int x, int y, char *name); 1667: void Draw_Char (int x, int y, int c); 1668: void Draw_TileClear (int x, int y, int w, int h, char *name); 1669: void Draw_Fill (int x, int y, int w, int h, int c); 1670: void Draw_FadeScreen (void); 1671: 1672: /* 1673: @@@@@@@@@@@@@@@@@@@@@ 1674: GetRefAPI 1675: 1676: @@@@@@@@@@@@@@@@@@@@@ 1677: */ 1678: refexport_t GetRefAPI (refimport_t rimp ) 1679: { 1680: refexport_t re; 1681: 1682: ri = rimp; 1683: 1684: re.api_version = API_VERSION; 1685: 1686: re.BeginRegistration = R_BeginRegistration; 1687: re.RegisterModel = R_RegisterModel; 1688: re.RegisterSkin = R_RegisterSkin; 1689: re.RegisterPic = Draw_FindPic; 1690: re.SetSky = R_SetSky; 1691: re.EndRegistration = R_EndRegistration; 1692: 1693: re.RenderFrame = R_RenderFrame; 1694: 1695: re.DrawGetPicSize = Draw_GetPicSize; 1696: re.DrawPic = Draw_Pic; 1697: re.DrawStretchPic = Draw_StretchPic; 1698: re.DrawChar = Draw_Char; 1699: re.DrawTileClear = Draw_TileClear; 1700: re.DrawFill = Draw_Fill; 1701: re.DrawFadeScreen= Draw_FadeScreen; 1702: 1703: re.DrawStretchRaw = Draw_StretchRaw; 1704: 1705: re.Init = R_Init; 1706: re.Shutdown = R_Shutdown; 1707: 1708: re.CinematicSetPalette = R_SetPalette; 1709: re.BeginFrame = R_BeginFrame; 1710: re.EndFrame = GLimp_EndFrame; 1711: 1712: re.AppActivate = GLimp_AppActivate; 1713: 1714: Swap_Init (); 1715: 1716: return re; 1717: } 1718: 1719: 1720: #ifndef REF_HARD_LINKED 1721: // this is only here so the functions in q_shared.c and q_shwin.c can link 1722: void Sys_Error (char *error, ...) 1723: { 1724: va_list argptr; 1725: char text[1024]; 1726: 1727: va_start (argptr, error); 1728: vsprintf (text, error, argptr); 1729: va_end (argptr); 1730: 1731: ri.Sys_Error (ERR_FATAL, "%s", text); 1732: } 1733: 1734: void Com_Printf (char *fmt, ...) 1735: { 1736: va_list argptr; 1737: char text[1024]; 1738: 1739: va_start (argptr, fmt); 1740: vsprintf (text, fmt, argptr); 1741: va_end (argptr); 1742: 1743: ri.Con_Printf (PRINT_ALL, "%s", text); 1744: } 1745: 1746: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.