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