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