1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20 // r_main.c
21 #include "gl_local.h"
22 #include "vlights.h"
23
24 void R_Clear (void);
25
26 #define random() ((rand () & 0x7fff) / ((float)0x7fff))
27 #define crandom() (2.0 * (random() - 0.5))
28
29 viddef_t vid;
30
31 refimport_t ri;
32
33 int GL_TEXTURE0, GL_TEXTURE1;
34
35 model_t *r_worldmodel;
36
37 float gldepthmin, gldepthmax;
38
39 glconfig_t gl_config;
40 glstate_t gl_state;
41
42 image_t *r_particletextures[PARTICLE_TYPES]; //list for particles
43 image_t *r_particlebeam;//used for beam ents
44 image_t *r_celtexture;//used for cel shading
45 image_t *r_notexture; // use for bad textures
46 image_t *r_dynamicimage;
47 image_t *r_lblendimage;
48 image_t *r_motionblurimage;
49 image_t *r_motionblurscreenimage;
50
51 particle_t *currentparticle;
52 entity_t *currententity;
53 rscript_t *currententityscript;
54 model_t *currentmodel;
55
56 cplane_t frustum[4];
57
58 int r_viewport[4];
59
60 int r_visframecount; // bumped when going to a new PVS
61 int r_framecount; // used for dlight push checking
62
63 int c_brush_polys, c_alias_polys;
64
65 float v_blend[4]; // final blending color
66
67 void GL_Strings_f( void );
68
69 //
70 // view origin
71 //
72 vec3_t vup;
73 vec3_t vpn;
74 vec3_t vright;
75 vec3_t r_origin;
76
77 float r_world_matrix[16];
78 float r_base_world_matrix[16];
79
80 //
81 // screen size info
82 //
83 refdef_t r_newrefdef;
84
85 int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2;
86
87 cvar_t *skydistance; // DMP - skybox size change
88
89 cvar_t *gl_transrendersort;
90 cvar_t *gl_particle_lighting;
91 cvar_t *gl_particle_min;
92 cvar_t *gl_particle_max;
93
94 cvar_t *r_norefresh;
95 cvar_t *r_drawentities;
96 cvar_t *r_drawworld;
97 cvar_t *r_speeds;
98 cvar_t *r_fullbright;
99 cvar_t *r_novis;
100 cvar_t *r_nocull;
101 cvar_t *r_lerpmodels;
102 cvar_t *r_lefthand;
103
104 cvar_t *r_dlights_normal;
105
106 cvar_t *r_shaders;
107
108 cvar_t *rs_glares;
109 cvar_t *rs_glares_sky;
110 cvar_t *rs_glares_size;
111 cvar_t *rs_glares_shell;
112 cvar_t *rs_glares_particles;
113 cvar_t *rs_dynamic_time;
114 cvar_t *rs_dynamic_size;
115 cvar_t *rs_dynamic_particles;
116 cvar_t *rs_dynamic_entities;
117
118 cvar_t *gl_motionblur;
119 cvar_t *gl_motionblur_size;
120
121 cvar_t *rs_detail;
122
123 cvar_t *r_model_lightlerp;
124 cvar_t *r_model_dlights;
125
126 cvar_t *r_lightlevel; // FIXME: This is a HACK to get the client's light level
127
128 cvar_t *gl_nosubimage;
129 cvar_t *gl_allow_software;
130
131 cvar_t *gl_vertex_arrays;
132
133 cvar_t *gl_ext_texture_compression; // Heffo - ARB Texture Compression
134 // Vic - begin
135 cvar_t *gl_ext_mtexcombine;
136 cvar_t *r_overbrightbits;
137 // Vic - end
138
139 cvar_t *r_celshading;
140 cvar_t *r_celshading_width;
141
142 cvar_t *con_font;
143 cvar_t *con_font_size;
144
145 cvar_t *cl_3dcam;
146 cvar_t *cl_3dcam_angle;
147 cvar_t *cl_3dcam_chase;
148 cvar_t *cl_3dcam_dist;
149 cvar_t *cl_3dcam_alpha;
150 cvar_t *cl_3dcam_adjust;
151
152 cvar_t *gl_ext_swapinterval;
153 cvar_t *gl_ext_multitexture;
154 cvar_t *gl_ext_pointparameters;
155 cvar_t *gl_ext_compiled_vertex_array;
156
157 cvar_t *gl_stencil;
158
159 cvar_t *gl_screenshot_quality;
160
161 cvar_t *gl_surftrans_light;
162 cvar_t *gl_log;
163 cvar_t *gl_bitdepth;
164 cvar_t *gl_drawbuffer;
165 cvar_t *gl_driver;
166 cvar_t *gl_lightmap;
167 cvar_t *gl_shadows;
168 cvar_t *gl_mode;
169 cvar_t *gl_dynamic;
170 cvar_t *gl_monolightmap;
171 cvar_t *gl_modulate;
172 cvar_t *gl_nobind;
173 cvar_t *gl_round_down;
174 cvar_t *gl_picmip;
175 cvar_t *gl_skymip;
176 cvar_t *gl_showtris;
177 cvar_t *gl_ztrick;
178 cvar_t *gl_finish;
179 cvar_t *gl_clear;
180 cvar_t *gl_cull;
181 cvar_t *gl_polyblend;
182 cvar_t *gl_flashblend;
183 cvar_t *gl_playermip;
184 cvar_t *gl_saturatelighting;
185 cvar_t *gl_swapinterval;
186 cvar_t *gl_texturemode;
187 cvar_t *gl_anisotropic;
188 cvar_t *gl_texturealphamode;
189 cvar_t *gl_texturesolidmode;
190 cvar_t *gl_lockpvs;
191
192 cvar_t *gl_3dlabs_broken;
193
194 cvar_t *vid_fullscreen;
195 cvar_t *vid_gamma;
196 cvar_t *vid_ref;
197
198 /*
199 =================
200 GL_Stencil
201
202 setting stencil buffer
203 =================
204 */
205 extern qboolean have_stencil;
GL_Stencil(qboolean enable)206 void GL_Stencil (qboolean enable)
207 {
208 if (!have_stencil || !gl_stencil->value)
209 return;
210
211 if (enable)
212 {
213 qglEnable(GL_STENCIL_TEST);
214 qglStencilFunc(GL_EQUAL, 1, 2);
215 qglStencilOp(GL_KEEP,GL_KEEP,GL_INCR);
216 }
217 else
218 {
219 qglDisable(GL_STENCIL_TEST);
220 }
221 }
GL_HasStencil(void)222 qboolean GL_HasStencil (void)
223 {
224 return (have_stencil && gl_stencil->value);
225 }
226
227 /*
228 =================
229 GL_Spheremap
230
231 setting up spheremap
232 =================
233 */
234
GL_Spheremap(qboolean enable)235 void GL_Spheremap (qboolean enable)
236 {
237
238 if (enable)
239 {
240 qglTexGenf(GL_S, GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
241 qglTexGenf(GL_T, GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
242 GLSTATE_ENABLE_TEXGEN
243 }
244 else
245 {
246 GLSTATE_DISABLE_TEXGEN
247 }
248 }
249
250 /*
251 =================
252 R_CullBox
253
254 Returns true if the box is completely outside the frustom
255 =================
256 */
R_CullBox(vec3_t mins,vec3_t maxs)257 qboolean R_CullBox (vec3_t mins, vec3_t maxs)
258 {
259 int i;
260
261 if (r_nocull->value)
262 return false;
263
264 for (i=0 ; i<4 ; i++)
265 if ( BOX_ON_PLANE_SIDE(mins, maxs, &frustum[i]) == 2)
266 return true;
267 return false;
268 }
269
R_CullSphere(const vec3_t origin,float radius)270 qboolean R_CullSphere (const vec3_t origin, float radius)
271 {
272 int i;
273 cplane_t *p;
274
275 if (r_nocull->value)
276 return false;
277
278 for (i = 0, p = frustum; i < 4; i++, p++)
279 if (DotProduct(origin, p->normal) - p->dist <= -radius)
280 return true;
281
282 return false;
283 }
284
R_RotateForEntity(entity_t * e,qboolean full)285 void R_RotateForEntity (entity_t *e, qboolean full)
286 {
287 qglTranslatef (e->origin[0], e->origin[1], e->origin[2]);
288
289 qglRotatef (e->angles[1], 0, 0, 1);
290 if (full==true)
291 {
292 qglRotatef (-e->angles[0], 0, 1, 0);
293 qglRotatef (-e->angles[2], 1, 0, 0);
294 }
295 }
296
297 /*
298 =============================================================
299
300 SPRITE MODELS
301
302 =============================================================
303 */
304
305
306 /*
307 =================
308 R_DrawSpriteModel
309
310 =================
311 */
R_DrawSpriteModel(entity_t * e)312 void R_DrawSpriteModel (entity_t *e)
313 {
314 float alpha = 1.0F;
315 vec3_t point, up, right;
316 dsprframe_t *frame;
317 dsprite_t *psprite;
318
319 // don't even bother culling, because it's just a single
320 // polygon without a surface cache
321
322 psprite = (dsprite_t *)currentmodel->extradata;
323
324 e->frame %= psprite->numframes;
325
326 frame = &psprite->frames[e->frame];
327
328 if (!frame)
329 return;
330
331 // normal sprite
332 VectorCopy(vup, up);
333 VectorCopy(vright, right);
334
335
336 if ( e->flags & RF_TRANSLUCENT )
337 alpha = e->alpha;
338
339 if (!currentmodel->skins[e->frame])
340 return;
341
342 GL_Bind(currentmodel->skins[e->frame]->texnum);
343
344 if ((currententity->flags&RF_TRANS_ADDITIVE) && (alpha != 1.0F))
345 {
346 GLSTATE_ENABLE_BLEND
347 GL_TexEnv( GL_MODULATE );
348
349 GLSTATE_DISABLE_ALPHATEST
350 GL_BlendFunction (GL_SRC_ALPHA, GL_ONE);
351
352 qglColor4ub(255, 255, 255, alpha*254);
353 }
354 else
355 {
356 if ( alpha != 1.0F )
357 GLSTATE_ENABLE_BLEND
358
359 GL_TexEnv( GL_MODULATE );
360
361 if ( alpha == 1.0 )
362 GLSTATE_ENABLE_ALPHATEST
363 else
364 GLSTATE_DISABLE_ALPHATEST
365
366 qglColor4f( 1, 1, 1, alpha );
367 }
368
369 qglBegin (GL_QUADS);
370
371 qglTexCoord2f (0, 1);
372 VectorMA (e->origin, -frame->origin_y, up, point);
373 VectorMA (point, -frame->origin_x, right, point);
374 qglVertex3fv (point);
375
376 qglTexCoord2f (0, 0);
377 VectorMA (e->origin, frame->height - frame->origin_y, up, point);
378 VectorMA (point, -frame->origin_x, right, point);
379 qglVertex3fv (point);
380
381 qglTexCoord2f (1, 0);
382 VectorMA (e->origin, frame->height - frame->origin_y, up, point);
383 VectorMA (point, frame->width - frame->origin_x, right, point);
384 qglVertex3fv (point);
385
386 qglTexCoord2f (1, 1);
387 VectorMA (e->origin, -frame->origin_y, up, point);
388 VectorMA (point, frame->width - frame->origin_x, right, point);
389 qglVertex3fv (point);
390
391 qglEnd ();
392
393
394 GL_BlendFunction (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
395 GLSTATE_DISABLE_ALPHATEST
396
397 GL_TexEnv( GL_REPLACE );
398
399 if ( alpha != 1.0F )
400 GLSTATE_DISABLE_BLEND
401
402 qglColor4f( 1, 1, 1, 1 );
403 }
404
405 //==================================================================================
406
407 /*
408 =============
409 R_DrawNullModel
410 =============
411 */
R_DrawNullModel(void)412 void R_DrawNullModel (void)
413 {
414 vec3_t shadelight;
415 int i;
416
417 if ( currententity->flags & RF_FULLBRIGHT )
418 shadelight[0] = shadelight[1] = shadelight[2] = 1.0F;
419 else
420 R_LightPoint (currententity->origin, shadelight);
421
422 qglPushMatrix ();
423 R_RotateForEntity (currententity, true);
424
425 qglDisable (GL_TEXTURE_2D);
426 qglColor3fv (shadelight);
427
428 qglBegin (GL_TRIANGLE_FAN);
429 qglVertex3f (0, 0, -16);
430 for (i=0 ; i<=4 ; i++)
431 qglVertex3f (16*cos(i*M_PI/2), 16*sin(i*M_PI/2), 0);
432 qglEnd ();
433
434 qglBegin (GL_TRIANGLE_FAN);
435 qglVertex3f (0, 0, 16);
436 for (i=4 ; i>=0 ; i--)
437 qglVertex3f (16*cos(i*M_PI/2), 16*sin(i*M_PI/2), 0);
438 qglEnd ();
439
440 qglColor3f (1,1,1);
441 qglPopMatrix ();
442 qglEnable (GL_TEXTURE_2D);
443 }
444 /*
445 =============
446 R_DrawEntitiesOnList
447 =============
448 */
449
450 // STRUCTURE STUFF
451
452 typedef struct sortedelement_s
453 {
454 void *data;
455 vec_t len;
456 vec3_t org;
457 void *left, *right, *next;
458 }
459 sortedelement_t;
460
461 int entstosort;
462 sortedelement_t theents[MAX_ENTITIES];
463 sortedelement_t *ents_viewweaps;
464 sortedelement_t *ents_viewweaps_trans;
465 sortedelement_t *ents_prerender;
466 sortedelement_t *ents_last;
467
468
resetSortList(void)469 void resetSortList (void)
470 {
471 entstosort = 0;
472 ents_last = NULL;
473 ents_prerender = NULL;
474 ents_viewweaps = NULL;
475 ents_viewweaps_trans = NULL;
476 }
477
NewSortEnt(entity_t * ent)478 sortedelement_t *NewSortEnt (entity_t *ent)
479 {
480 qboolean entinwater, is_weapmodel = false;
481 vec3_t distance;
482 sortedelement_t *element;
483 mleaf_t *point_in;
484
485 element = &theents[entstosort];
486
487 VectorSubtract(ent->origin, r_origin, distance);
488 VectorCopy(ent->origin, element->org);
489
490 element->data = (entity_t *)ent;
491 element->len = (vec_t)VectorLength(distance);
492 element->left = NULL;
493 element->right = NULL;
494 element->next = NULL;
495
496 return element;
497 }
498
499 // TREE BUILDING AND USAGE
500
ElementAddNode(sortedelement_t * base,sortedelement_t * thisElement)501 void ElementAddNode ( sortedelement_t *base, sortedelement_t *thisElement )
502 {
503 if (thisElement->len > base->len)
504 {
505 if (base->left)
506 ElementAddNode(base->left, thisElement);
507 else
508 base->left = thisElement;
509 }
510 else
511 {
512 if (base->right)
513 ElementAddNode(base->right, thisElement);
514 else
515 base->right = thisElement;
516 }
517 }
518
AddEntViewWeapTree(entity_t * ent,qboolean trans)519 void AddEntViewWeapTree( entity_t *ent, qboolean trans)
520 {
521 int closer = 0;
522 sortedelement_t *thisEnt;
523
524
525 thisEnt = NewSortEnt(ent);
526
527 if (!thisEnt)
528 return;
529
530 if (!trans)
531 {
532 if (ents_viewweaps)
533 ElementAddNode(ents_viewweaps, thisEnt);
534 else
535 ents_viewweaps = thisEnt;
536 }
537 else
538 {
539 if (ents_viewweaps_trans)
540 ElementAddNode(ents_viewweaps_trans, thisEnt);
541 else
542 ents_viewweaps_trans = thisEnt;
543 }
544
545 entstosort++;
546 }
547
AddEntTransTree(entity_t * ent)548 void AddEntTransTree( entity_t *ent )
549 {
550 int closer = 0;
551 sortedelement_t *thisEnt;
552
553
554 thisEnt = NewSortEnt(ent);
555
556 if (!thisEnt)
557 return;
558
559 if (ents_prerender)
560 ElementAddNode(ents_prerender, thisEnt);
561 else
562 ents_prerender = thisEnt;
563
564 ents_last = thisEnt;
565
566 entstosort++;
567 }
568
ParseRenderEntity(entity_t * ent)569 void ParseRenderEntity (entity_t *ent)
570 {
571 currententity = ent;
572
573 if ( currententity->flags & RF_BEAM )
574 {
575 R_DrawBeam( currententity );
576 }
577 else
578 {
579 currentmodel = currententity->model;
580 if (!currentmodel)
581 {
582 R_DrawNullModel ();
583 return;
584 }
585 if (currententity->model && r_shaders->value)
586 {
587 currententityscript=(rscript_t *)currententity->model->script[currententity->skinnum];
588 if (currententity->skin)
589 currententityscript = currententity->skin->script;
590 }
591
592 switch (currentmodel->type)
593 {
594 case mod_alias:
595 R_DrawAliasModel (currententity);
596 break;
597 case mod_brush:
598 R_DrawBrushModel (currententity);
599 break;
600 case mod_sprite:
601 R_DrawSpriteModel (currententity);
602 break;
603 default:
604 ri.Sys_Error (ERR_DROP, "Bad modeltype");
605 break;
606 }
607 }
608 }
609
transBrushModel(entity_t * ent)610 qboolean transBrushModel (entity_t *ent)
611 {
612 int i;
613 msurface_t *surf;
614
615 if (ent && ent->model && ent->model->type==mod_brush)
616 {
617 surf = &ent->model->surfaces[ent->model->firstmodelsurface];
618 for (i=0 ; i<ent->model->nummodelsurfaces ; i++, surf++)
619 if (surf && surf->texinfo->flags & (SURF_TRANS33|SURF_TRANS66))
620 return true;
621 }
622
623 return false;
624 }
625
RenderEntTree(sortedelement_t * element)626 void RenderEntTree (sortedelement_t *element)
627 {
628 if (!element)
629 return;
630
631 RenderEntTree(element->left);
632
633 if (element->data)
634 ParseRenderEntity(element->data);
635
636
637 RenderEntTree(element->right);
638 }
639
640 // ACTUAL RENDERING FUNCTIONS
641
642 void R_DrawAliasShadow (entity_t *ent);
R_DrawAllEntityShadows(void)643 void R_DrawAllEntityShadows (void)
644 {
645 qboolean alpha;
646 rscript_t *rs = NULL;
647 int i;
648
649 if(!gl_shadows->value)
650 return;
651
652 for (i=0;i<r_newrefdef.num_entities; i++)
653 {
654 currententity = &r_newrefdef.entities[i];
655
656 if ( currententity->flags & RF_BEAM )
657 continue;
658 currentmodel = currententity->model;
659 if (!currentmodel)
660 continue;
661 if (currentmodel->type!=mod_alias)
662 continue;
663
664
665 if ( currententity->flags & ( RF_TRANSLUCENT | RF_WEAPONMODEL | RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) )
666 continue;
667 if (currententity->renderfx & RF2_NOSHADOW)
668 continue;
669 if (currententity->flags&RF_TRANSLUCENT)
670 continue;
671 // if (transBrushModel(currententity)) //crashy
672 // continue;
673
674 alpha = false;
675 if (currententity->model && r_shaders->value)
676 {
677 rs=(rscript_t *)currententity->model->script[currententity->skinnum];
678 if (!rs && currententity->skin)
679 rs = currententity->skin->script;
680 if (rs)
681 {
682 RS_ReadyScript(rs);
683 currententityscript = rs;
684 if (rs->stage && rs->stage->has_alpha)
685 continue;
686 }
687 else
688 currententityscript = NULL;
689 }
690
691 R_DrawAliasShadow (currententity);
692 }
693 }
694
R_DrawAllEntities(qboolean addViewWeaps)695 void R_DrawAllEntities (qboolean addViewWeaps)
696 {
697 qboolean alpha;
698 rscript_t *rs = NULL;
699 int i;
700
701 if (!r_drawentities->value)
702 return;
703
704 resetSortList();
705
706 for (i=0;i<r_newrefdef.num_entities; i++)
707 {
708 currententity = &r_newrefdef.entities[i];
709
710 alpha = false;
711 if (currententity->flags&RF_TRANSLUCENT)
712 alpha = true;
713 if (currententity->model && r_shaders->value)
714 {
715 rs=(rscript_t *)currententity->model->script[currententity->skinnum];
716 if (currententity->skin)
717 rs = currententity->skin->script;
718 if (rs)
719 {
720 RS_ReadyScript(rs);
721 currententityscript = rs;
722 if (rs->stage && rs->stage->has_alpha)
723 alpha = true;
724 }
725 else
726 currententityscript = NULL;
727 }
728
729 if (alpha)
730 continue;
731
732 if (currententity->flags & RF_WEAPONMODEL)
733 if (!addViewWeaps)
734 continue;
735
736 ParseRenderEntity(currententity);
737 }
738
739 qglDepthMask (0);
740 for (i=0;i<r_newrefdef.num_entities; i++)
741 {
742 currententity = &r_newrefdef.entities[i];
743
744 alpha = false;
745 if (currententity->flags&RF_TRANSLUCENT)
746 alpha = true;
747 if (currententity->model && r_shaders->value)
748 {
749 rs=(rscript_t *)currententity->model->script[currententity->skinnum];
750 if (currententity->skin)
751 rs = currententity->skin->script;
752
753 if (rs)
754 {
755 RS_ReadyScript(rs);
756 currententityscript = rs;
757 if (rs->stage && rs->stage->has_alpha)
758 alpha = true;
759 }
760 else
761 currententityscript = NULL;
762 }
763
764 if (currententity->flags & RF_WEAPONMODEL)
765 if (!addViewWeaps)
766 continue;
767
768 if (!alpha)
769 continue;
770
771 ParseRenderEntity(currententity);
772 }
773 qglDepthMask (1);
774 }
775
776 void setRenderMotionBlur (void);
R_DrawMotionBlurEntities(void)777 void R_DrawMotionBlurEntities (void)
778 {
779 qboolean alpha;
780 int i;
781 rscript_t *rs = NULL;
782
783 if (!r_drawentities->value)
784 return;
785
786 for (i=0;i<r_newrefdef.num_entities; i++)
787 {
788 currententity = &r_newrefdef.entities[i];
789 if (currententity->flags & RF_TRANSLUCENT)
790 continue;
791 if (currententity->renderfx & RF2_MOTIONBLUR)
792 ParseRenderEntity(currententity);
793 }
794 }
795
796
R_DrawSolidEntities(void)797 void R_DrawSolidEntities (void)
798 {
799 qboolean alpha;
800 int i;
801 rscript_t *rs = NULL;
802
803 if (!r_drawentities->value)
804 return;
805
806 resetSortList();
807
808 for (i=0;i<r_newrefdef.num_entities; i++)
809 {
810 currententity = &r_newrefdef.entities[i];
811 alpha = false;
812
813 //find alpha and script...
814 if (currententity->model && r_shaders->value)
815 {
816 rs=(rscript_t *)currententity->model->script[currententity->skinnum];
817 if (currententity->skin)
818 rs = currententity->skin->script;
819 if (rs)
820 {
821 RS_ReadyScript(rs);
822 currententityscript = rs;
823 //only add to list if base layer is alpha
824 if (rs->stage && rs->stage->has_alpha)
825 alpha = true;
826 }
827 else
828 currententityscript = NULL;
829 }
830 if (currententity->flags&RF_TRANSLUCENT)
831 alpha = true;
832 // if (transBrushModel(currententity))
833 // alpha = true;
834
835 if (currententity->flags & RF_WEAPONMODEL)
836 {
837 AddEntViewWeapTree(currententity, alpha);
838 continue;
839 }
840
841 if (alpha)
842 {
843 AddEntTransTree(currententity);
844 continue;
845 }
846
847 ParseRenderEntity(currententity);
848 }
849 }
850
R_DrawEntitiesOnList(void * list)851 void R_DrawEntitiesOnList (void *list)
852 {
853 if (!r_drawentities->value)
854 return;
855
856 RenderEntTree(list);
857 }
858
859 /*
860 ** GL_DrawParticles
861 **
862 */
863
864 int partstosort;
865 sortedelement_t theparts[MAX_PARTICLES];
866 sortedelement_t *parts_prerender;
867 sortedelement_t *parts_decals;
868 sortedelement_t *parts_last;
869 void renderParticle (particle_t *p);
870 void renderDecal (particle_t *p);
871
NewSortPart(particle_t * p)872 sortedelement_t *NewSortPart ( particle_t *p)
873 {
874 qboolean partinwater;
875 vec3_t distance;
876 sortedelement_t *element;
877
878 element = &theparts[partstosort];
879
880 VectorSubtract(p->origin, r_origin, distance);
881 VectorCopy(p->origin, element->org);
882
883 element->data = p;
884 element->len = VectorLength(distance);
885 element->left = NULL;
886 element->right = NULL;
887
888 return element;
889 }
890
resetPartSortList(void)891 void resetPartSortList (void)
892 {
893 partstosort = 0;
894 parts_prerender = NULL;
895 parts_decals = NULL;
896 parts_last = NULL;
897 }
898
particleClip(float len)899 qboolean particleClip( float len )
900 {
901 if (gl_particle_min->value>0)
902 {
903 if (len < gl_particle_min->value)
904 return true;
905 }
906 if (gl_particle_max->value>0)
907 {
908 if (len > gl_particle_max->value)
909 return true;
910 }
911
912 return false;
913 }
914
915
DecalElementAddNode(sortedelement_t * base,sortedelement_t * thisElement)916 void DecalElementAddNode ( sortedelement_t *base, sortedelement_t *thisElement )
917 {
918 particle_t *pBase = thisElement->data,
919 *pThis = base->data;
920
921 if (pBase->flags & PART_DECAL_SUB)
922 {
923 if (pThis->flags & PART_DECAL_SUB)
924 {
925 if (base->right)
926 ElementAddNode(base->right, thisElement);
927 else
928 base->right = thisElement;
929 }
930 else
931 {
932 if (base->left)
933 ElementAddNode(base->left, thisElement);
934 else
935 base->left = thisElement;
936 }
937 return;
938 }
939 else if (pThis->flags & PART_DECAL_ADD)
940 {
941 if (pThis->flags & PART_DECAL_SUB)
942 {
943 if (base->left)
944 ElementAddNode(base->left, thisElement);
945 else
946 base->left = thisElement;
947 }
948 else
949 {
950 if (base->right)
951 ElementAddNode(base->right, thisElement);
952 else
953 base->right = thisElement;
954 }
955 return;
956 }
957
958 if (thisElement->len > base->len)
959 {
960 if (base->left)
961 ElementAddNode(base->left, thisElement);
962 else
963 base->left = thisElement;
964 }
965 else
966 {
967 if (base->right)
968 ElementAddNode(base->right, thisElement);
969 else
970 base->right = thisElement;
971 }
972 }
973
AddPartTransTree(particle_t * p)974 void AddPartTransTree( particle_t *p )
975 {
976 sortedelement_t *thisPart;
977
978 thisPart = NewSortPart(p);
979
980 //decals are sorted by render type, then depth
981 if (p->flags&PART_DECAL)
982 {
983 if (parts_decals)
984 DecalElementAddNode(parts_decals, thisPart);
985 else
986 parts_decals = thisPart;
987 }
988 else
989 {
990 if (particleClip(thisPart->len))
991 return;
992
993 if (parts_prerender)
994 ElementAddNode(parts_prerender, thisPart);
995 else
996 parts_prerender = thisPart;
997
998 parts_last = thisPart;
999 }
1000
1001 partstosort++;
1002 }
1003
GL_BuildParticleList()1004 void GL_BuildParticleList()
1005 {
1006 int i;
1007 resetPartSortList();
1008
1009 for ( i=0 ; i < r_newrefdef.num_particles ; i++)
1010 {
1011 currentparticle = &r_newrefdef.particles[i];
1012 AddPartTransTree(currentparticle);
1013 }
1014 }
1015
RenderParticleTree(sortedelement_t * element)1016 void RenderParticleTree (sortedelement_t *element)
1017 {
1018 if (!element)
1019 return;
1020
1021 RenderParticleTree(element->left);
1022
1023 if (element->data)
1024 renderParticle((particle_t *)element->data);
1025
1026 RenderParticleTree(element->right);
1027 }
1028
RenderDecalTree(sortedelement_t * element)1029 void RenderDecalTree (sortedelement_t *element)
1030 {
1031 if (!element)
1032 return;
1033
1034 RenderDecalTree(element->left);
1035
1036 if (element->data)
1037 renderDecal((particle_t *)element->data);
1038
1039 RenderDecalTree(element->right);
1040 }
1041
1042 /*
1043 ===============
1044 R_DrawParticles
1045 ===============
1046 */
1047
1048 vec3_t particle_coord[4];
R_DrawDecals(void)1049 void R_DrawDecals (void)
1050 {
1051 vec3_t up = {vup[0] * 0.75f, vup[1] * 0.75f, vup[2] * 0.75f};
1052 vec3_t right = {vright[0] * 0.75f, vright[1] * 0.75f, vright[2] * 0.75f};
1053
1054 VectorAdd (up, right, particle_coord[0]);
1055 VectorSubtract (right, up, particle_coord[1]);
1056 VectorNegate (particle_coord[0], particle_coord[2]);
1057 VectorNegate (particle_coord[1], particle_coord[3]);
1058
1059 qglEnable (GL_TEXTURE_2D);
1060 GL_TexEnv( GL_MODULATE );
1061 qglDepthMask (false);
1062 GLSTATE_ENABLE_BLEND
1063 GL_ShadeModel (GL_SMOOTH);
1064 GLSTATE_DISABLE_ALPHATEST
1065
1066 RenderDecalTree(parts_decals);
1067
1068 qglDepthRange (gldepthmin, gldepthmax);
1069 GL_BlendFunction (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1070 GL_TexEnv( GL_MODULATE );
1071 qglDepthMask (true);
1072 GLSTATE_DISABLE_BLEND
1073 qglColor4f (1,1,1,1);
1074 }
1075
1076
R_DrawAllAddGlareParticles(void)1077 void R_DrawAllAddGlareParticles (void)
1078 {
1079 vec3_t up = {vup[0] * 0.75f, vup[1] * 0.75f, vup[2] * 0.75f};
1080 vec3_t right = {vright[0] * 0.75f, vright[1] * 0.75f, vright[2] * 0.75f};
1081 int i;
1082
1083 VectorAdd (up, right, particle_coord[0]);
1084 VectorSubtract (right, up, particle_coord[1]);
1085 VectorNegate (particle_coord[0], particle_coord[2]);
1086 VectorNegate (particle_coord[1], particle_coord[3]);
1087
1088 qglEnable (GL_TEXTURE_2D);
1089 GL_TexEnv( GL_MODULATE );
1090 qglDepthMask (false);
1091 GLSTATE_ENABLE_BLEND
1092 GL_ShadeModel (GL_SMOOTH);
1093 GLSTATE_DISABLE_ALPHATEST
1094
1095 for ( i=0 ; i < r_newrefdef.num_particles ; i++)
1096 if (r_newrefdef.particles[i].flags&PART_GLARE)
1097 {
1098 if (r_newrefdef.particles[i].flags&PART_DECAL)
1099 renderDecal(&r_newrefdef.particles[i]);
1100 else
1101 renderParticle(&r_newrefdef.particles[i]);
1102 }
1103
1104 qglDepthRange (gldepthmin, gldepthmax);
1105 GL_BlendFunction (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1106 GL_TexEnv( GL_MODULATE );
1107 qglDepthMask (true);
1108 GLSTATE_DISABLE_BLEND
1109 qglColor4f (1,1,1,1);
1110 }
1111
R_DrawAllSubDecals(void)1112 void R_DrawAllSubDecals (void)
1113 {
1114 vec3_t up = {vup[0] * 0.75f, vup[1] * 0.75f, vup[2] * 0.75f};
1115 vec3_t right = {vright[0] * 0.75f, vright[1] * 0.75f, vright[2] * 0.75f};
1116 int i;
1117
1118 VectorAdd (up, right, particle_coord[0]);
1119 VectorSubtract (right, up, particle_coord[1]);
1120 VectorNegate (particle_coord[0], particle_coord[2]);
1121 VectorNegate (particle_coord[1], particle_coord[3]);
1122
1123 qglEnable (GL_TEXTURE_2D);
1124 GL_TexEnv( GL_MODULATE );
1125 qglDepthMask (false);
1126 GLSTATE_ENABLE_BLEND
1127 GL_ShadeModel (GL_SMOOTH);
1128 GLSTATE_DISABLE_ALPHATEST
1129
1130 for ( i=0 ; i < r_newrefdef.num_particles ; i++)
1131 if (r_newrefdef.particles[i].flags&PART_DECAL && r_newrefdef.particles[i].flags&PART_DECAL_SUB)
1132 renderDecal(&r_newrefdef.particles[i]);
1133
1134 qglDepthRange (gldepthmin, gldepthmax);
1135 GL_BlendFunction (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1136 GL_TexEnv( GL_MODULATE );
1137 qglDepthMask (true);
1138 GLSTATE_DISABLE_BLEND
1139 qglColor4f (1,1,1,1);
1140 }
1141
R_DrawAllDecals(void)1142 void R_DrawAllDecals (void)
1143 {
1144 vec3_t up = {vup[0] * 0.75f, vup[1] * 0.75f, vup[2] * 0.75f};
1145 vec3_t right = {vright[0] * 0.75f, vright[1] * 0.75f, vright[2] * 0.75f};
1146 int i;
1147
1148 VectorAdd (up, right, particle_coord[0]);
1149 VectorSubtract (right, up, particle_coord[1]);
1150 VectorNegate (particle_coord[0], particle_coord[2]);
1151 VectorNegate (particle_coord[1], particle_coord[3]);
1152
1153 qglEnable (GL_TEXTURE_2D);
1154 GL_TexEnv( GL_MODULATE );
1155 qglDepthMask (false);
1156 GLSTATE_ENABLE_BLEND
1157 GL_ShadeModel (GL_SMOOTH);
1158 GLSTATE_DISABLE_ALPHATEST
1159
1160 for ( i=0 ; i < r_newrefdef.num_particles ; i++)
1161 if (r_newrefdef.particles[i].flags&PART_DECAL)
1162 renderDecal(&r_newrefdef.particles[i]);
1163
1164 qglDepthRange (gldepthmin, gldepthmax);
1165 GL_BlendFunction (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1166 GL_TexEnv( GL_MODULATE );
1167 qglDepthMask (true);
1168 GLSTATE_DISABLE_BLEND
1169 qglColor4f (1,1,1,1);
1170 }
1171
1172 void SetVertexOverbrights(qboolean);
1173
1174 qboolean ParticleOverbright;
SetParticleOverbright(qboolean toggle)1175 void SetParticleOverbright(qboolean toggle)
1176 {
1177 if ( (toggle && !ParticleOverbright) || (!toggle && ParticleOverbright) )
1178 {
1179 SetVertexOverbrights(toggle);
1180 ParticleOverbright = toggle;
1181 }
1182 }
1183
R_DrawParticles(void * list)1184 void R_DrawParticles (void *list)
1185 {
1186 vec3_t up = {vup[0] * 0.75f, vup[1] * 0.75f, vup[2] * 0.75f};
1187 vec3_t right = {vright[0] * 0.75f, vright[1] * 0.75f, vright[2] * 0.75f};
1188
1189 VectorAdd (up, right, particle_coord[0]);
1190 VectorSubtract (right, up, particle_coord[1]);
1191 VectorNegate (particle_coord[0], particle_coord[2]);
1192 VectorNegate (particle_coord[1], particle_coord[3]);
1193
1194 qglEnable (GL_TEXTURE_2D);
1195 GL_TexEnv( GL_MODULATE );
1196 qglDepthMask (false);
1197 GLSTATE_ENABLE_BLEND
1198 GL_ShadeModel (GL_SMOOTH);
1199 GLSTATE_DISABLE_ALPHATEST
1200 ParticleOverbright = false;
1201
1202 RenderParticleTree(list);
1203
1204 qglDepthRange (gldepthmin, gldepthmax);
1205 GL_BlendFunction (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1206 GL_TexEnv( GL_MODULATE );
1207 qglDepthMask (true);
1208 GLSTATE_DISABLE_BLEND
1209 qglColor4f (1,1,1,1);
1210 }
1211
R_DrawAllParticles(void)1212 void R_DrawAllParticles (void)
1213 {
1214 vec3_t up = {vup[0] * 0.75f, vup[1] * 0.75f, vup[2] * 0.75f};
1215 vec3_t right = {vright[0] * 0.75f, vright[1] * 0.75f, vright[2] * 0.75f};
1216
1217 int i;
1218
1219 VectorAdd (up, right, particle_coord[0]);
1220 VectorSubtract (right, up, particle_coord[1]);
1221 VectorNegate (particle_coord[0], particle_coord[2]);
1222 VectorNegate (particle_coord[1], particle_coord[3]);
1223
1224 qglEnable (GL_TEXTURE_2D);
1225 GL_TexEnv( GL_MODULATE );
1226 qglDepthMask (false);
1227 GLSTATE_ENABLE_BLEND
1228 GL_ShadeModel (GL_SMOOTH);
1229 GLSTATE_DISABLE_ALPHATEST
1230 ParticleOverbright = false;
1231
1232 for ( i=0 ; i < r_newrefdef.num_particles ; i++)
1233 if (!(r_newrefdef.particles[i].flags&PART_DECAL))
1234 renderParticle(&r_newrefdef.particles[i]);
1235
1236 qglDepthRange (gldepthmin, gldepthmax);
1237 GL_BlendFunction (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1238 GL_TexEnv( GL_MODULATE );
1239 qglDepthMask (true);
1240 GLSTATE_DISABLE_BLEND
1241 qglColor4f (1,1,1,1);
1242 }
1243
1244 /**********************************************************
1245 renderParticle
1246 **********************************************************/
1247
texParticle(int type)1248 int texParticle (int type)
1249 {
1250 image_t *part_img;
1251
1252 part_img = r_particletextures [type];
1253
1254 return part_img->texnum;
1255 }
1256
vectoanglerolled(vec3_t value1,float angleyaw,vec3_t angles)1257 void vectoanglerolled (vec3_t value1, float angleyaw, vec3_t angles)
1258 {
1259 float forward, yaw, pitch;
1260
1261 yaw = (int) (atan2(value1[1], value1[0]) * 180 / M_PI);
1262 forward = sqrt (value1[0]*value1[0] + value1[1]*value1[1]);
1263 pitch = (int) (atan2(value1[2], forward) * 180 / M_PI);
1264
1265 if (pitch < 0)
1266 pitch += 360;
1267
1268 angles[PITCH] = -pitch;
1269 angles[YAW] = yaw;
1270 angles[ROLL] = - angleyaw;
1271 }
1272
AngleFind(float input)1273 float AngleFind(float input)
1274 {
1275 return 180.0/input;
1276 }
1277
setBeamAngles(vec3_t start,vec3_t end,vec3_t up,vec3_t right)1278 void setBeamAngles (vec3_t start, vec3_t end, vec3_t up, vec3_t right)
1279 {
1280 vec3_t move, delta;
1281
1282 VectorSubtract(end, start, move);
1283 VectorNormalize(move);
1284
1285 VectorCopy(move, up);
1286 VectorSubtract(r_newrefdef.vieworg, start, delta);
1287 CrossProduct(up, delta, right);
1288 // if(!VectorCompare(right, vec3_origin))
1289 VectorNormalize(right);
1290 }
1291
getParticleLight(particle_t * p,vec3_t pos,float lighting,vec3_t shadelight)1292 void getParticleLight (particle_t *p, vec3_t pos, float lighting, vec3_t shadelight)
1293 {
1294 int j;
1295 float lightest = 0;
1296
1297 if (!lighting)
1298 {
1299 VectorSet(shadelight, p->red, p->green, p->blue);
1300 return;
1301 }
1302
1303 R_LightPoint (pos, shadelight);
1304
1305 shadelight[0]= (lighting*shadelight[0]+(1-lighting)) * p->red;
1306 shadelight[1]= (lighting*shadelight[1]+(1-lighting)) * p->green;
1307 shadelight[2]= (lighting*shadelight[2]+(1-lighting)) * p->blue;
1308
1309 //this cleans up the lighting
1310 {
1311 for (j=0;j<3;j++)
1312 if (shadelight[j]>lightest)
1313 lightest= shadelight[j];
1314 if (lightest>255)
1315 for (j=0;j<3;j++)
1316 {
1317 shadelight[j]*= 255/lightest;
1318 if (shadelight[j]>255)
1319 shadelight[j] = 255;
1320 }
1321
1322 for (j=0;j<3;j++)
1323 {
1324 if (shadelight[j]<0)
1325 shadelight[j] = 0;
1326 }
1327 }
1328 }
1329
1330 //id move this somewhere less dirty, but im too damn lazy - psychospaz
1331 #define DEPTHHACK_RANGE_SHORT 0.999f
1332 #define DEPTHHACK_RANGE_MID 0.99f
1333 #define DEPTHHACK_RANGE_LONG 0.975f
1334
1335 vec3_t ParticleVec[4];
1336 vec3_t shadelight;
1337
shaderParticle(int type)1338 rscript_t *shaderParticle (int type)
1339 {
1340 image_t *part_img;
1341 part_img = r_particletextures[type];
1342
1343 return part_img->script;
1344 }
1345
renderParticleShader(particle_t * p,vec3_t origin,float size,qboolean translate)1346 void renderParticleShader (particle_t *p, vec3_t origin, float size, qboolean translate)
1347 {
1348 rscript_t *rs = NULL;
1349 float txm,tym, alpha,s,t;
1350 rs_stage_t *stage;
1351 char scriptname [MAX_QPATH];
1352 vec3_t color;
1353
1354 if (r_shaders->value)
1355 rs=shaderParticle(p->image);
1356
1357 if (rs)
1358 {
1359 RS_ReadyScript(rs);
1360
1361 stage=rs->stage;
1362 while (stage)
1363 {
1364 if (stage->colormap.enabled)
1365 qglDisable (GL_TEXTURE_2D);
1366 else if (stage->anim_count)
1367 GL_Bind(RS_Animate(stage));
1368 else
1369 GL_Bind (stage->texture->texnum);
1370
1371 if (stage->blendfunc.blend)
1372 GL_BlendFunction(stage->blendfunc.source,stage->blendfunc.dest);
1373 else
1374 GL_BlendFunction (p->blendfunc_src, p->blendfunc_dst);
1375
1376 alpha=1.0f;
1377 if (stage->alphashift.min || stage->alphashift.speed)
1378 {
1379 if (!stage->alphashift.speed && stage->alphashift.min > 0)
1380 {
1381 alpha=stage->alphashift.min;
1382 }
1383 else if (stage->alphashift.speed)
1384 {
1385 alpha=sin(rs_realtime * stage->alphashift.speed);
1386 alpha=(alpha+1)*0.5f;
1387 if (alpha > stage->alphashift.max) alpha=stage->alphashift.max;
1388 if (alpha < stage->alphashift.min) alpha=stage->alphashift.min;
1389 }
1390 }
1391 alpha *= p->alpha;
1392
1393 if (stage->alphamask)
1394 {
1395 GLSTATE_ENABLE_ALPHATEST
1396 }
1397 else
1398 {
1399 GLSTATE_DISABLE_ALPHATEST
1400 }
1401
1402 if (stage->colormap.enabled)
1403 {
1404 float red = 1, green = 1, blue = 1;
1405
1406 red = stage->colormap.red/255.0;
1407 green = stage->colormap.green/255.0;
1408 blue = stage->colormap.blue/255.0;
1409
1410 VectorSet(color, red,green,blue);
1411 }
1412 else if (stage->lightmap && p->flags&PART_SHADED)
1413 VectorSet(color, shadelight[0]/255.0, shadelight[1]/255.0, shadelight[2]/255.0);
1414 else
1415 VectorSet(color, p->red/255.0, p->green/255.0, p->blue/255.0);
1416
1417
1418 if (p->flags&PART_ALPHACOLOR)
1419 qglColor4f(color[0]*alpha,color[1]*alpha,color[2]*alpha, alpha);
1420 else
1421 qglColor4f(color[0],color[1],color[2], alpha);
1422
1423 qglPushMatrix();
1424 {
1425 if (translate)
1426 {
1427 qglTranslatef( origin[0], origin[1], origin[2] );
1428 qglScalef(size, size, size );
1429 }
1430 if (p->decal)
1431 {
1432 qglEnable(GL_POLYGON_OFFSET_FILL);
1433 qglPolygonOffset(-2, -1);
1434
1435 qglBegin (GL_TRIANGLE_FAN);
1436 {
1437 int i;
1438 float s, t;
1439 vec3_t point;
1440 decalpolys_t *decal = p->decal;
1441
1442 for (i = 0; i < p->decal->numpolys; i++)
1443 {
1444 s = p->decal->coords[i][0];
1445 t = p->decal->coords[i][1];
1446 VectorCopy(decal->polys[i], point);
1447
1448 RS_SetTexcoords2D (stage, &s, &t);
1449 qglTexCoord2f (s, t);
1450 qglVertex3fv (point);
1451 }
1452 }
1453 qglEnd ();
1454
1455 qglDisable(GL_POLYGON_OFFSET_FILL);
1456 }
1457 else
1458 {
1459 qglBegin (GL_QUADS);
1460 {
1461 float s, t;
1462
1463 s = 0;
1464 t = 1;
1465 RS_SetTexcoords2D (stage, &s, &t);
1466 qglTexCoord2f (s, t);
1467 qglVertex3fv (ParticleVec[0]);
1468 s = 0;
1469 t = 0;
1470 RS_SetTexcoords2D (stage, &s, &t);
1471 qglTexCoord2f (s, t);
1472 qglVertex3fv (ParticleVec[1]);
1473 s = 1;
1474 t = 0;
1475 RS_SetTexcoords2D (stage, &s, &t);
1476 qglTexCoord2f (s, t);
1477 qglVertex3fv (ParticleVec[2]);
1478 s = 1;
1479 t = 1;
1480 RS_SetTexcoords2D (stage, &s, &t);
1481 qglTexCoord2f (s, t);
1482 qglVertex3fv (ParticleVec[3]);
1483 }
1484 qglEnd ();
1485 }
1486 }
1487 qglPopMatrix ();
1488
1489 if (stage->colormap.enabled)
1490 qglEnable (GL_TEXTURE_2D);
1491
1492 stage=stage->next;
1493 }
1494 }
1495 else
1496 {
1497 qglPushMatrix();
1498 {
1499 if (translate)
1500 {
1501 qglTranslatef( origin[0], origin[1], origin[2] );
1502 qglScalef(size, size, size );
1503 }
1504 if (p->decal)
1505 {
1506 qglEnable(GL_POLYGON_OFFSET_FILL);
1507 qglPolygonOffset(-2, -1);
1508
1509 qglBegin (GL_TRIANGLE_FAN);
1510 {
1511 int i;
1512 for (i = 0; i < p->decal->numpolys; i++)
1513 {
1514 qglTexCoord2f (p->decal->coords[i][0], p->decal->coords[i][1]);
1515 qglVertex3fv (p->decal->polys[i]);
1516 }
1517 }
1518 qglEnd ();
1519
1520 qglDisable(GL_POLYGON_OFFSET_FILL);
1521 }
1522 else
1523 {
1524 qglBegin (GL_QUADS);
1525 {
1526 qglTexCoord2f (0, 1);
1527 qglVertex3fv (ParticleVec[0]);
1528 qglTexCoord2f (0, 0);
1529 qglVertex3fv (ParticleVec[1]);
1530 qglTexCoord2f (1, 0);
1531 qglVertex3fv (ParticleVec[2]);
1532 qglTexCoord2f (1, 1);
1533 qglVertex3fv (ParticleVec[3]);
1534 }
1535 qglEnd ();
1536 }
1537 }
1538 qglPopMatrix ();
1539 }
1540 }
1541
renderDecal(particle_t * p)1542 void renderDecal (particle_t *p)
1543 {
1544 float size, alpha;
1545 vec3_t angl_coord[4];
1546 vec3_t ang_up, ang_right, ang_forward, color;
1547 rscript_t *rs = NULL;
1548
1549 size = (p->size>0.1) ? p->size : 0.1;
1550 alpha = p->alpha;
1551
1552
1553 if (p->flags&PART_SHADED)
1554 {
1555 getParticleLight (p, p->origin, gl_particle_lighting->value, shadelight);
1556 VectorSet(color, shadelight[0]/255.0, shadelight[1]/255.0, shadelight[2]/255.0);
1557 }
1558 else
1559 {
1560 VectorSet(shadelight, p->red, p->green, p->blue);
1561 VectorSet(color, p->red/255.0, p->green/255.0, p->blue/255.0);
1562 }
1563
1564 if (!r_shaders->value || !shaderParticle(p->image))
1565 {
1566 GL_BlendFunction (p->blendfunc_src, p->blendfunc_dst);
1567 GL_Bind(texParticle(p->image));
1568
1569 if (p->flags&PART_ALPHACOLOR)
1570 qglColor4f(color[0]*alpha,color[1]*alpha,color[2]*alpha, alpha);
1571 else
1572 qglColor4f(color[0],color[1],color[2], alpha);
1573 }
1574
1575 if (!p->decal)
1576 {
1577 AngleVectors(p->angle, ang_forward, ang_right, ang_up);
1578
1579 VectorScale (ang_right, 0.75f, ang_right);
1580 VectorScale (ang_up, 0.75f, ang_up);
1581
1582 VectorAdd (ang_up, ang_right, angl_coord[0]);
1583 VectorSubtract (ang_right, ang_up, angl_coord[1]);
1584 VectorNegate (angl_coord[0], angl_coord[2]);
1585 VectorNegate (angl_coord[1], angl_coord[3]);
1586
1587 VectorMA(p->origin, size, angl_coord[0], ParticleVec[0]);
1588 VectorMA(p->origin, size, angl_coord[1], ParticleVec[1]);
1589 VectorMA(p->origin, size, angl_coord[2], ParticleVec[2]);
1590 VectorMA(p->origin, size, angl_coord[3], ParticleVec[3]);
1591 }
1592
1593 renderParticleShader(p, NULL, 0, false);
1594 }
1595
renderParticle(particle_t * p)1596 void renderParticle (particle_t *p)
1597 {
1598 float size, lighting = gl_particle_lighting->value;
1599 vec3_t up = {vup[0] * 0.75f, vup[1] * 0.75f, vup[2] * 0.75f};
1600 vec3_t right = {vright[0] * 0.75f, vright[1] * 0.75f, vright[2] * 0.75f};
1601 vec3_t shadelight;
1602 float alpha;
1603 vec3_t coord[4], color;
1604 rscript_t *rs = NULL;
1605
1606 VectorCopy(particle_coord[0], coord[0]);
1607 VectorCopy(particle_coord[1], coord[1]);
1608 VectorCopy(particle_coord[2], coord[2]);
1609 VectorCopy(particle_coord[3], coord[3]);
1610
1611 size = (p->size>0.1) ? p->size : 0.1;
1612 alpha = p->alpha;
1613
1614 if (p->flags&PART_DEPTHHACK_SHORT) //nice little poly-peeking - psychospaz
1615 qglDepthRange (gldepthmin, gldepthmin + DEPTHHACK_RANGE_SHORT*(gldepthmax-gldepthmin));
1616 if (p->flags&PART_DEPTHHACK_MID)
1617 qglDepthRange (gldepthmin, gldepthmin + DEPTHHACK_RANGE_MID*(gldepthmax-gldepthmin));
1618 if (p->flags&PART_DEPTHHACK_LONG)
1619 qglDepthRange (gldepthmin, gldepthmin + DEPTHHACK_RANGE_LONG*(gldepthmax-gldepthmin));
1620
1621 if (p->flags&PART_OVERBRIGHT)
1622 SetParticleOverbright(true);
1623
1624 if (p->flags&PART_SHADED)
1625 {
1626 getParticleLight (p, p->origin, lighting, shadelight);
1627 VectorSet(color, shadelight[0]/255.0, shadelight[1]/255.0, shadelight[2]/255.0);
1628 }
1629 else
1630 {
1631 VectorSet(shadelight, p->red, p->green, p->blue);
1632 VectorSet(color, p->red/255.0, p->green/255.0, p->blue/255.0);
1633 }
1634
1635 if (!r_shaders->value || !shaderParticle(p->image))
1636 {
1637 GL_BlendFunction (p->blendfunc_src, p->blendfunc_dst);
1638
1639 GL_Bind(texParticle(p->image));
1640
1641 if (p->flags&PART_ALPHACOLOR)
1642 qglColor4f(color[0]*alpha,color[1]*alpha,color[2]*alpha, alpha);
1643 else
1644 qglColor4f(color[0],color[1],color[2], alpha);
1645 }
1646
1647 if (p->flags&PART_BEAM) //given start and end positions, will have fun here :)
1648 { //p->angle = start
1649 //p->origin= end
1650 vec3_t angl_coord[4];
1651 vec3_t ang_up, ang_right;
1652
1653 setBeamAngles(p->angle, p->origin, ang_up, ang_right);
1654 VectorScale(ang_right, size, ang_right);
1655
1656 VectorAdd(p->origin, ang_right, ParticleVec[0]);
1657 VectorAdd(p->angle, ang_right, ParticleVec[1]);
1658 VectorSubtract(p->angle, ang_right, ParticleVec[2]);
1659 VectorSubtract(p->origin, ang_right, ParticleVec[3]);
1660
1661 renderParticleShader(p, NULL, 0, false);
1662 }
1663 else if (p->flags&PART_LIGHTNING) //given start and end positions, will have fun here :)
1664 { //p->angle = start
1665 //p->origin= end
1666 int k = 0;
1667 float len, dec, angdot;
1668 vec3_t move, lastvec, thisvec, tempvec;
1669 vec3_t angl_coord[4], old_coord[2];
1670 vec3_t ang_up, ang_right, last_right, abs_up, abs_right;
1671 float width, scale_up, scale_right;
1672
1673 scale_up = scale_right = 0;
1674 dec = size*5.0;
1675 width = size;
1676
1677 VectorSubtract(p->origin, p->angle, move);
1678 len = VectorNormalize(move);
1679
1680 setBeamAngles(p->angle, p->origin, abs_up, abs_right);
1681 VectorScale(move, dec, move);
1682 VectorCopy(p->angle, thisvec);
1683 VectorSubtract(thisvec, move, lastvec);
1684 VectorCopy(thisvec, tempvec);
1685 len+=dec;
1686
1687 setBeamAngles(lastvec, thisvec, ang_up, ang_right);
1688 VectorScale (ang_right, width, ang_right);
1689
1690 while (len>dec)
1691 {
1692 VectorCopy(ang_right, last_right);
1693
1694 setBeamAngles(lastvec, thisvec, ang_up, ang_right);
1695 VectorScale (ang_right, width, ang_right);
1696
1697 angdot = DotProduct(ang_right, last_right);
1698 {
1699 VectorAdd(lastvec, ang_right, ParticleVec[1]);
1700 VectorSubtract(lastvec, ang_right, ParticleVec[2]);
1701
1702 VectorAdd(thisvec, ang_right, ParticleVec[0]);
1703 VectorSubtract(thisvec, ang_right, ParticleVec[3]);
1704
1705 VectorCopy(ParticleVec[0], old_coord[0]);
1706 VectorCopy(ParticleVec[3], old_coord[1]);
1707 }
1708 if (k>0)
1709 renderParticleShader(p, NULL, 0, false);
1710
1711 k++;
1712
1713 len-=dec;
1714
1715 VectorCopy(thisvec, lastvec);
1716
1717 //now modify stuff
1718 {
1719 float diff = lastvec[0] + lastvec[1] + lastvec[2];
1720 //scale_up += crandom() * size;
1721 //scale_right -= crandom() * size;
1722
1723 scale_up = size*( cos(diff*0.1+rs_realtime*15.0) );
1724 scale_right = size*( sin( diff*0.1+rs_realtime*15.0) );
1725 }
1726 if (scale_right > size) scale_right = size;
1727 if (scale_right < -size) scale_right = -size;
1728 if (scale_up > size) scale_up = size;
1729 if (scale_up < -size) scale_up = -size;
1730
1731
1732 VectorAdd(tempvec, move, tempvec);
1733 thisvec[0] = tempvec[0] + abs_up[0]*scale_up + abs_right[0]*scale_right;
1734 thisvec[1] = tempvec[1] + abs_up[1]*scale_up + abs_right[1]*scale_right;
1735 thisvec[2] = tempvec[2] + abs_up[2]*scale_up + abs_right[2]*scale_right;
1736 }
1737
1738 //one more time
1739 if (len>0)
1740 {
1741 VectorCopy(p->origin, thisvec);
1742 VectorCopy(ang_right, last_right);
1743
1744 setBeamAngles(lastvec, thisvec, ang_up, ang_right);
1745 VectorScale (ang_right, width, ang_right);
1746
1747 angdot = DotProduct(ang_right, last_right);
1748 {
1749 VectorAdd(lastvec, ang_right, ParticleVec[1]);
1750 VectorSubtract(lastvec, ang_right, ParticleVec[2]);
1751
1752 VectorAdd(thisvec, ang_right, ParticleVec[0]);
1753 VectorSubtract(thisvec, ang_right, ParticleVec[3]);
1754
1755 VectorCopy(ParticleVec[0], old_coord[0]);
1756 VectorCopy(ParticleVec[3], old_coord[1]);
1757 }
1758 renderParticleShader(p, NULL, 0, false);
1759 }
1760 }
1761 else if (p->flags&PART_DIRECTION) //streched out in direction...tracers etc...
1762 //never dissapears because of angle like other engines :D
1763 {
1764 vec3_t angl_coord[4];
1765 vec3_t ang_up, ang_right, vdelta;
1766
1767 VectorAdd(p->angle, p->origin, vdelta);
1768 setBeamAngles(vdelta, p->origin, ang_up, ang_right);
1769
1770 VectorScale (ang_right, 0.75f, ang_right);
1771 VectorScale (ang_up, 0.75f * VectorLength(p->angle), ang_up);
1772
1773 VectorAdd (ang_up, ang_right, ParticleVec[0]);
1774 VectorSubtract (ang_right, ang_up, ParticleVec[1]);
1775 VectorNegate (ParticleVec[0], ParticleVec[2]);
1776 VectorNegate (ParticleVec[1], ParticleVec[3]);
1777
1778 renderParticleShader(p, p->origin, size, true);
1779 }
1780 else if (p->flags&PART_ANGLED) //facing direction... (decal wannabes)
1781 {
1782 vec3_t angl_coord[4];
1783 vec3_t ang_up, ang_right, ang_forward;
1784
1785 AngleVectors(p->angle, ang_forward, ang_right, ang_up);
1786
1787 VectorScale (ang_right, 0.75f, ang_right);
1788 VectorScale (ang_up, 0.75f, ang_up);
1789
1790 VectorAdd (ang_up, ang_right, ParticleVec[0]);
1791 VectorSubtract (ang_right, ang_up, ParticleVec[1]);
1792 VectorNegate (ParticleVec[0], ParticleVec[2]);
1793 VectorNegate (ParticleVec[1], ParticleVec[3]);
1794
1795 qglDisable (GL_CULL_FACE);
1796
1797 renderParticleShader(p, p->origin, size, true);
1798
1799 qglEnable (GL_CULL_FACE);
1800
1801 }
1802 else //normal sprites
1803 {
1804 if (p->angle[2]) //if we have roll, we do calcs
1805 {
1806 vec3_t angl_coord[4];
1807 vec3_t ang_up, ang_right, ang_forward;
1808
1809 VectorSubtract(p->origin, r_newrefdef.vieworg, angl_coord[0]);
1810
1811 vectoanglerolled(angl_coord[0], p->angle[2], angl_coord[1]);
1812 AngleVectors(angl_coord[1], ang_forward, ang_right, ang_up);
1813
1814 VectorScale (ang_forward, 0.75f, ang_forward);
1815 VectorScale (ang_right, 0.75f, ang_right);
1816 VectorScale (ang_up, 0.75f, ang_up);
1817
1818 VectorAdd (ang_up, ang_right, ParticleVec[0]);
1819 VectorSubtract (ang_right, ang_up, ParticleVec[1]);
1820 VectorNegate (ParticleVec[0], ParticleVec[2]);
1821 VectorNegate (ParticleVec[1], ParticleVec[3]);
1822 }
1823 else
1824 {
1825 VectorCopy(coord[0], ParticleVec[0]);
1826 VectorCopy(coord[1], ParticleVec[1]);
1827 VectorCopy(coord[2], ParticleVec[2]);
1828 VectorCopy(coord[3], ParticleVec[3]);
1829 }
1830 renderParticleShader(p, p->origin, size, true);
1831 }
1832
1833 if (p->flags&PART_OVERBRIGHT)
1834 SetParticleOverbright(false);
1835
1836 if (p->flags&PART_DEPTHHACK)
1837 qglDepthRange (gldepthmin, gldepthmax);
1838 }
1839
1840
1841 /*
1842 ============
1843 R_PolyBlend
1844 ============
1845 */
1846
R_MotionBlurBlend(void)1847 void R_MotionBlurBlend (void)
1848 {
1849 if (!gl_motionblur->value)
1850 return;
1851
1852 GLSTATE_DISABLE_ALPHATEST
1853 GLSTATE_ENABLE_BLEND
1854 qglDisable (GL_DEPTH_TEST);
1855 qglEnable (GL_TEXTURE_2D);
1856 GL_TexEnv( GL_MODULATE );
1857
1858 qglLoadIdentity ();
1859
1860 // FIXME: get rid of these
1861 qglRotatef (-90, 1, 0, 0); // put Z going up
1862 qglRotatef (90, 0, 0, 1); // put Z going up
1863
1864 GL_Bind(r_motionblurimage->texnum);
1865 GL_BlendFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR);
1866
1867 qglColor4ub(255, 255, 255, 250);
1868
1869 qglBegin (GL_QUADS);
1870 qglTexCoord2f (0, 0);
1871 qglVertex3f (100, 100, 100);
1872 qglTexCoord2f (1, 0);
1873 qglVertex3f (100, -100, 100);
1874 qglTexCoord2f (1, -1);
1875 qglVertex3f (100, -100, -100);
1876 qglTexCoord2f (0, -1);
1877 qglVertex3f (100, 100, -100);
1878 qglEnd ();
1879
1880 GLSTATE_DISABLE_BLEND
1881 GLSTATE_ENABLE_ALPHATEST
1882 GL_TexEnv( GL_REPLACE );
1883
1884 qglColor4f(1,1,1,1);
1885 }
1886
R_PolyBlend(void)1887 void R_PolyBlend (void)
1888 {
1889 if (!gl_polyblend->value)
1890 return;
1891 if (!v_blend[3])
1892 return;
1893
1894 GLSTATE_DISABLE_ALPHATEST
1895 GLSTATE_ENABLE_BLEND
1896 qglDisable (GL_DEPTH_TEST);
1897 qglDisable (GL_TEXTURE_2D);
1898 GL_BlendFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1899
1900 qglLoadIdentity ();
1901
1902 // FIXME: get rid of these
1903 qglRotatef (-90, 1, 0, 0); // put Z going up
1904 qglRotatef (90, 0, 0, 1); // put Z going up
1905
1906 qglColor4fv (v_blend);
1907
1908 qglBegin (GL_QUADS);
1909
1910 qglVertex3f (10, 100, 100);
1911 qglVertex3f (10, -100, 100);
1912 qglVertex3f (10, -100, -100);
1913 qglVertex3f (10, 100, -100);
1914 qglEnd ();
1915
1916 GLSTATE_DISABLE_BLEND
1917 qglEnable (GL_TEXTURE_2D);
1918 GLSTATE_ENABLE_ALPHATEST
1919
1920 qglColor4f(1,1,1,1);
1921 }
1922
R_StencilBlend(void)1923 void R_StencilBlend (void)
1924 {
1925
1926 GLSTATE_DISABLE_ALPHATEST
1927 GLSTATE_ENABLE_BLEND
1928 qglDisable (GL_DEPTH_TEST);
1929 qglDisable (GL_TEXTURE_2D);
1930
1931 qglLoadIdentity ();
1932
1933 // FIXME: get rid of these
1934 qglRotatef (-90, 1, 0, 0); // put Z going up
1935 qglRotatef (90, 0, 0, 1); // put Z going up
1936
1937 qglColor4f(0,0,0,0.3);
1938 qglStencilFunc( GL_NOTEQUAL, 0, 0xFFFFFFFFL );
1939 qglStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
1940 qglEnable(GL_STENCIL_TEST);
1941
1942 qglBegin (GL_QUADS);
1943 qglVertex3f (10, 100, 100);
1944 qglVertex3f (10, -100, 100);
1945 qglVertex3f (10, -100, -100);
1946 qglVertex3f (10, 100, -100);
1947 qglEnd ();
1948
1949 qglDisable(GL_STENCIL_TEST);
1950
1951
1952 GLSTATE_DISABLE_BLEND
1953 qglEnable (GL_TEXTURE_2D);
1954 GLSTATE_ENABLE_ALPHATEST
1955
1956 qglColor4f(1,1,1,1);
1957 }
1958
1959 //=======================================================================
1960
SignbitsForPlane(cplane_t * out)1961 int SignbitsForPlane (cplane_t *out)
1962 {
1963 int bits, j;
1964
1965 // for fast box on planeside test
1966
1967 bits = 0;
1968 for (j=0 ; j<3 ; j++)
1969 {
1970 if (out->normal[j] < 0)
1971 bits |= 1<<j;
1972 }
1973 return bits;
1974 }
1975
1976
R_SetFrustum(void)1977 void R_SetFrustum (void)
1978 {
1979 int i;
1980
1981 #if 0
1982 /*
1983 ** this code is wrong, since it presume a 90 degree FOV both in the
1984 ** horizontal and vertical plane
1985 */
1986 // front side is visible
1987 VectorAdd (vpn, vright, frustum[0].normal);
1988 VectorSubtract (vpn, vright, frustum[1].normal);
1989 VectorAdd (vpn, vup, frustum[2].normal);
1990 VectorSubtract (vpn, vup, frustum[3].normal);
1991
1992 // we theoretically don't need to normalize these vectors, but I do it
1993 // anyway so that debugging is a little easier
1994 VectorNormalize( frustum[0].normal );
1995 VectorNormalize( frustum[1].normal );
1996 VectorNormalize( frustum[2].normal );
1997 VectorNormalize( frustum[3].normal );
1998 #else
1999 // rotate VPN right by FOV_X/2 degrees
2000 RotatePointAroundVector( frustum[0].normal, vup, vpn, -(90-r_newrefdef.fov_x / 2 ) );
2001 // rotate VPN left by FOV_X/2 degrees
2002 RotatePointAroundVector( frustum[1].normal, vup, vpn, 90-r_newrefdef.fov_x / 2 );
2003 // rotate VPN up by FOV_X/2 degrees
2004 RotatePointAroundVector( frustum[2].normal, vright, vpn, 90-r_newrefdef.fov_y / 2 );
2005 // rotate VPN down by FOV_X/2 degrees
2006 RotatePointAroundVector( frustum[3].normal, vright, vpn, -( 90 - r_newrefdef.fov_y / 2 ) );
2007 #endif
2008
2009 for (i=0 ; i<4 ; i++)
2010 {
2011 frustum[i].type = PLANE_ANYZ;
2012 frustum[i].dist = DotProduct (r_origin, frustum[i].normal);
2013 frustum[i].signbits = SignbitsForPlane (&frustum[i]);
2014 }
2015 }
2016
2017 //=======================================================================
2018
2019 /*
2020 ===============
2021 R_SetupFrame
2022 ===============
2023 */
R_SetupFrame(void)2024 void R_SetupFrame (void)
2025 {
2026 int i;
2027 mleaf_t *leaf;
2028
2029 r_framecount++;
2030
2031 // build the transformation matrix for the given view angles
2032 VectorCopy (r_newrefdef.vieworg, r_origin);
2033
2034 AngleVectors (r_newrefdef.viewangles, vpn, vright, vup);
2035
2036 // current viewcluster
2037 if ( !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
2038 {
2039 r_oldviewcluster = r_viewcluster;
2040 r_oldviewcluster2 = r_viewcluster2;
2041 leaf = Mod_PointInLeaf (r_origin, r_worldmodel);
2042 r_viewcluster = r_viewcluster2 = leaf->cluster;
2043
2044 // check above and below so crossing solid water doesn't draw wrong
2045 if (!leaf->contents)
2046 { // look down a bit
2047 vec3_t temp;
2048
2049 VectorCopy (r_origin, temp);
2050 temp[2] -= 16;
2051 leaf = Mod_PointInLeaf (temp, r_worldmodel);
2052 if ( !(leaf->contents & CONTENTS_SOLID) &&
2053 (leaf->cluster != r_viewcluster2) )
2054 r_viewcluster2 = leaf->cluster;
2055 }
2056 else
2057 { // look up a bit
2058 vec3_t temp;
2059
2060 VectorCopy (r_origin, temp);
2061 temp[2] += 16;
2062 leaf = Mod_PointInLeaf (temp, r_worldmodel);
2063 if ( !(leaf->contents & CONTENTS_SOLID) &&
2064 (leaf->cluster != r_viewcluster2) )
2065 r_viewcluster2 = leaf->cluster;
2066 }
2067 }
2068
2069 for (i=0 ; i<4 ; i++)
2070 v_blend[i] = r_newrefdef.blend[i];
2071
2072 c_brush_polys = 0;
2073 c_alias_polys = 0;
2074
2075 // clear out the portion of the screen that the NOWORLDMODEL defines
2076 /* if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
2077 {
2078 qglEnable( GL_SCISSOR_TEST );
2079 qglClearColor( 0.3, 0.3, 0.3, 1 );
2080 qglScissor( r_newrefdef.x, vid.height - r_newrefdef.height - r_newrefdef.y, r_newrefdef.width, r_newrefdef.height );
2081 qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
2082 qglClearColor( 1, 0, 0.5, 0.5 );
2083 qglDisable( GL_SCISSOR_TEST );
2084 }*/
2085 }
2086
2087
MYgluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear,GLdouble zFar)2088 void MYgluPerspective( GLdouble fovy, GLdouble aspect,
2089 GLdouble zNear, GLdouble zFar )
2090 {
2091 GLdouble xmin, xmax, ymin, ymax;
2092
2093 ymax = zNear * tan( fovy * M_PI / 360.0 );
2094 ymin = -ymax;
2095
2096 xmin = ymin * aspect;
2097 xmax = ymax * aspect;
2098
2099 xmin += -( 2 * gl_state.camera_separation ) / zNear;
2100 xmax += -( 2 * gl_state.camera_separation ) / zNear;
2101
2102 qglFrustum( xmin, xmax, ymin, ymax, zNear, zFar );
2103 }
2104
2105
2106 /*
2107 =============
2108 R_SetupGL
2109 =============
2110 */
R_SetupGL(void)2111 void R_SetupGL (void)
2112 {
2113 static GLdouble farz; // DMP skybox size change
2114 GLdouble boxsize; // DMP skybox size change
2115
2116 float screenaspect;
2117 // float yfov;
2118 int x, x2, y2, y, w, h;
2119
2120 //
2121 // set up viewport
2122 //
2123 x = floor(r_newrefdef.x * vid.width / vid.width);
2124 x2 = ceil((r_newrefdef.x + r_newrefdef.width) * vid.width / vid.width);
2125 y = floor(vid.height - r_newrefdef.y * vid.height / vid.height);
2126 y2 = ceil(vid.height - (r_newrefdef.y + r_newrefdef.height) * vid.height / vid.height);
2127
2128 w = x2 - x;
2129 h = y - y2;
2130
2131 qglViewport (x, y2, w, h);
2132
2133 if (skydistance->modified)
2134 {
2135 skydistance->modified = false;
2136 boxsize = skydistance->value;
2137 boxsize -= 252 * ceil(boxsize / 2300);
2138 farz = 1.0;
2139 while (farz < boxsize) // DMP: make this value a power-of-2
2140 {
2141 farz *= 2.0;
2142 if (farz >= 65536.0) // DMP: don't make it larger than this
2143 break;
2144 }
2145 farz *= 2.0; // DMP: double since boxsize is distance from camera to
2146 // edge of skybox - not total size of skybox
2147 ri.Con_Printf(PRINT_DEVELOPER, "farz now set to %g\n", farz);
2148 }
2149
2150
2151 //
2152 // set up projection matrix
2153 //
2154 screenaspect = (float)r_newrefdef.width/r_newrefdef.height;
2155 // yfov = 2*atan((float)r_newrefdef.height/r_newrefdef.width)*180/M_PI;
2156 qglMatrixMode(GL_PROJECTION);
2157 qglLoadIdentity ();
2158
2159 // MYgluPerspective (r_newrefdef.fov_y, screenaspect, 4, 4096);
2160 MYgluPerspective (r_newrefdef.fov_y, screenaspect, 4, farz); // DMP skybox
2161
2162
2163 qglCullFace(GL_FRONT);
2164
2165 qglMatrixMode(GL_MODELVIEW);
2166 qglLoadIdentity ();
2167
2168 qglRotatef (-90, 1, 0, 0); // put Z going up
2169 qglRotatef (90, 0, 0, 1); // put Z going up
2170 qglRotatef (-r_newrefdef.viewangles[2], 1, 0, 0);
2171 qglRotatef (-r_newrefdef.viewangles[0], 0, 1, 0);
2172 qglRotatef (-r_newrefdef.viewangles[1], 0, 0, 1);
2173 qglTranslatef (-r_newrefdef.vieworg[0], -r_newrefdef.vieworg[1], -r_newrefdef.vieworg[2]);
2174
2175 // if ( gl_state.camera_separation != 0 && gl_state.stereo_enabled )
2176 // qglTranslatef ( gl_state.camera_separation, 0, 0 );
2177
2178 qglGetFloatv (GL_MODELVIEW_MATRIX, r_world_matrix);
2179
2180 qglGetIntegerv (GL_VIEWPORT, r_viewport);
2181
2182 //
2183 // set drawing parms
2184 //
2185 if (gl_cull->value)
2186 qglEnable(GL_CULL_FACE);
2187 else
2188 qglDisable(GL_CULL_FACE);
2189
2190 GLSTATE_DISABLE_BLEND
2191 GLSTATE_DISABLE_ALPHATEST
2192 qglEnable(GL_DEPTH_TEST);
2193 }
2194
2195 /*
2196 =============
2197 R_Clear
2198 =============
2199 */
R_Clear(void)2200 void R_Clear (void)
2201 {
2202
2203 if (gl_ztrick->value)
2204 {
2205 static int trickframe;
2206
2207 if (gl_clear->value)
2208 qglClear (GL_COLOR_BUFFER_BIT);
2209
2210 trickframe++;
2211 if (trickframe & 1)
2212 {
2213 gldepthmin = 0;
2214 gldepthmax = 0.49999;
2215 qglDepthFunc (GL_LEQUAL);
2216 }
2217 else
2218 {
2219 gldepthmin = 1;
2220 gldepthmax = 0.5;
2221 qglDepthFunc (GL_GEQUAL);
2222 }
2223 }
2224 else
2225 {
2226 if (gl_clear->value)
2227 qglClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2228 else
2229 qglClear (GL_DEPTH_BUFFER_BIT);
2230 gldepthmin = 0;
2231 gldepthmax = 1;
2232 qglDepthFunc (GL_LEQUAL);
2233 }
2234
2235 if (have_stencil)
2236 {
2237 qglClearStencil(0);
2238 qglClear(GL_STENCIL_BUFFER_BIT);
2239 }
2240
2241 //this is for spheremapping...
2242 qglTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
2243 qglTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
2244
2245 qglDepthRange (gldepthmin, gldepthmax);
2246
2247 }
2248
R_ShadowBlend()2249 void R_ShadowBlend()
2250 {
2251 if (!gl_shadows->value)
2252 return;
2253
2254 qglLoadIdentity ();
2255
2256 // FIXME: get rid of these
2257 qglRotatef (-90, 1, 0, 0); // put Z going up
2258 qglRotatef (90, 0, 0, 1); // put Z going up
2259
2260 qglColor4f (0,0,0,0.4f);
2261
2262 GLSTATE_DISABLE_ALPHATEST
2263 GLSTATE_ENABLE_BLEND
2264 qglDisable (GL_DEPTH_TEST);
2265 qglDisable (GL_TEXTURE_2D);
2266
2267 qglEnable(GL_STENCIL_TEST);
2268 qglStencilFunc( GL_NOTEQUAL, 0, 0xFF);
2269 qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2270
2271 qglBegin (GL_QUADS);
2272
2273 qglVertex3f (10, 100, 100);
2274 qglVertex3f (10, -100, 100);
2275 qglVertex3f (10, -100, -100);
2276 qglVertex3f (10, 100, -100);
2277 qglEnd ();
2278
2279 GLSTATE_DISABLE_BLEND
2280 qglEnable (GL_TEXTURE_2D);
2281 GLSTATE_ENABLE_ALPHATEST
2282 qglDisable(GL_STENCIL_TEST);
2283
2284 qglColor4f(1,1,1,1);
2285 }
2286
R_Flash(void)2287 void R_Flash( void )
2288 {
2289 R_PolyBlend ();
2290 R_ShadowBlend ();
2291 }
2292 /*
2293 ================
2294 R_RenderView
2295
2296 r_newrefdef must be set before the first call
2297 ================
2298 */
2299
2300 void R_DrawSkyBox_Models (void);
2301 void R_DrawSpecialSurfaces(void);
2302
R_RenderMotionBlurView(refdef_t * fd)2303 void R_RenderMotionBlurView (refdef_t *fd)
2304 {
2305 if (r_norefresh->value)
2306 return;
2307
2308 r_newrefdef = *fd;
2309
2310 if (!r_worldmodel && !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
2311 ri.Sys_Error (ERR_DROP, "R_RenderView: NULL worldmodel");
2312
2313 if (r_speeds->value)
2314 {
2315 c_brush_polys = 0;
2316 c_alias_polys = 0;
2317 }
2318
2319 R_PushDlights ();
2320
2321 if (gl_finish->value)
2322 qglFinish ();
2323
2324 R_SetupFrame ();
2325 R_SetFrustum ();
2326 R_SetupGL ();
2327 R_MarkLeaves (); // done here so we know if we're in water
2328 R_DrawWorld ();
2329
2330 GLSTATE_DISABLE_ALPHATEST
2331
2332 R_DrawMotionBlurEntities();
2333 R_MotionBlurBlend();
2334 }
2335
R_RenderDynamicView(refdef_t * fd)2336 void R_RenderDynamicView (refdef_t *fd)
2337 {
2338 if (r_norefresh->value)
2339 return;
2340
2341 r_newrefdef = *fd;
2342
2343 if (!r_worldmodel && !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
2344 ri.Sys_Error (ERR_DROP, "R_RenderView: NULL worldmodel");
2345
2346 if (r_speeds->value)
2347 {
2348 c_brush_polys = 0;
2349 c_alias_polys = 0;
2350 }
2351
2352 R_PushDlights ();
2353
2354 if (gl_finish->value)
2355 qglFinish ();
2356
2357 R_SetupFrame ();
2358 R_SetFrustum ();
2359 R_SetupGL ();
2360 R_MarkLeaves (); // done here so we know if we're in water
2361 R_DrawWorld ();
2362
2363 GLSTATE_DISABLE_ALPHATEST
2364
2365 R_RenderDlights ();
2366
2367 //never sort - could get too messy!
2368 R_DrawSpecialSurfaces();
2369 if (rs_dynamic_particles->value)
2370 {
2371 R_DrawAllDecals();
2372 R_DrawAllParticles();
2373 }
2374 if (rs_dynamic_entities->value)
2375 R_DrawAllEntities(false);
2376 R_DrawAlphaSurfaces (false);
2377 }
2378
R_RenderGlareView(refdef_t * fd)2379 void R_RenderGlareView (refdef_t *fd)
2380 {
2381
2382 if (r_norefresh->value)
2383 return;
2384
2385 r_newrefdef = *fd;
2386
2387 if (!r_worldmodel && !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
2388 ri.Sys_Error (ERR_DROP, "R_RenderView: NULL worldmodel");
2389
2390 if (r_speeds->value)
2391 {
2392 c_brush_polys = 0;
2393 c_alias_polys = 0;
2394 }
2395
2396 R_PushDlights ();
2397
2398 if (gl_finish->value)
2399 qglFinish ();
2400
2401 R_SetupFrame ();
2402 R_SetFrustum ();
2403 R_SetupGL ();
2404 R_MarkLeaves (); // done here so we know if we're in water
2405 R_DrawWorld ();
2406
2407 GLSTATE_DISABLE_ALPHATEST
2408
2409 R_DrawAllSubDecals();
2410 R_DrawAllEntities(true);
2411 if (rs_glares_particles->value)
2412 R_DrawAllAddGlareParticles();
2413 }
2414
2415
checkSurfaceTrace(msurface_t * surf,vec3_t end,vec3_t start)2416 qboolean checkSurfaceTrace (msurface_t *surf, vec3_t end, vec3_t start)
2417 {
2418 float front, back, side, dist;
2419 vec3_t normal;
2420 cplane_t *plane;
2421
2422 plane = surf->plane;
2423
2424 if (!plane)
2425 return false;
2426
2427 dist = plane->dist;
2428 VectorCopy(plane->normal, normal);
2429
2430 front = DotProduct (start, normal) - dist;
2431 back = DotProduct (end, normal) - dist;
2432 side = front < 0;
2433
2434 if ( (back < 0) == side)
2435 return false;
2436
2437 return true;
2438 }
2439
TracePoints(vec3_t start,vec3_t end,void * surface)2440 qboolean TracePoints (vec3_t start, vec3_t end, void *surface)
2441 {
2442 int i;
2443 msurface_t *surf = r_worldmodel->surfaces;
2444 for (i=0; i<r_worldmodel->numsurfaces; i++, surf++)
2445 {
2446 if (surf == surface)
2447 continue;
2448 if (surf->texinfo->flags & (SURF_TRANS33 | SURF_TRANS66))
2449 continue;
2450 if (checkSurfaceTrace(surf, start, end))
2451 return true;
2452 }
2453 return false;
2454 }
2455
2456
checkElementSurfaceScan(msurface_t * surf,vec3_t start)2457 qboolean checkElementSurfaceScan (msurface_t *surf, vec3_t start)
2458 {
2459 float front, back, side, dist;
2460 vec3_t end, normal;
2461 cplane_t *plane;
2462
2463 plane = surf->plane;
2464
2465 if (!plane)
2466 return false;
2467
2468 dist = plane->dist;
2469 VectorCopy(plane->normal, normal);
2470 VectorCopy(r_newrefdef.vieworg, end);
2471
2472 front = DotProduct (start, normal) - dist;
2473 back = DotProduct (end, normal) - dist;
2474 side = front < 0;
2475
2476 if ( (back < 0) == side)
2477 return false;
2478
2479 return true;
2480 }
2481
2482 sortedelement_t *listswap[2];
ElementChecker(sortedelement_t * element,msurface_t * surf)2483 void ElementChecker (sortedelement_t *element, msurface_t *surf)
2484 {
2485 if (!element)
2486 return;
2487
2488 ElementChecker(element->right, surf);
2489 ElementChecker(element->left, surf);
2490 element->left = element->right = NULL;
2491
2492 if (checkElementSurfaceScan(surf, element->org))
2493 {
2494 if (!listswap[0])
2495 listswap[0] = element;
2496 else
2497 ElementAddNode(listswap[0], element);
2498 }
2499 else
2500 {
2501 if (!listswap[1])
2502 listswap[1] = element;
2503 else
2504 ElementAddNode(listswap[1], element);
2505 }
2506 }
2507
surf_ElementList(msurface_t * surf,qboolean ents)2508 void surf_ElementList(msurface_t *surf, qboolean ents)
2509 {
2510 sortedelement_t *temp, *element, *last = NULL, *found = NULL;
2511
2512 listswap[0] = listswap[1] = NULL;
2513
2514 if (ents)
2515 ElementChecker(ents_prerender, surf);
2516 else
2517 ElementChecker(parts_prerender, surf);
2518
2519 if (ents)
2520 {
2521 ents_prerender = listswap[1];
2522 RenderEntTree(listswap[0]);
2523 }
2524 else
2525 {
2526 parts_prerender = listswap[1];
2527 R_DrawParticles(listswap[0]);
2528 }
2529 }
2530
R_DrawLastElements(void)2531 void R_DrawLastElements (void)
2532 {
2533 if (parts_prerender)
2534 R_DrawParticles(parts_prerender);
2535 if (ents_prerender)
2536 RenderEntTree(ents_prerender);
2537 }
2538
R_RenderView(refdef_t * fd)2539 void R_RenderView (refdef_t *fd)
2540 {
2541 qboolean mBlur = fd->rdflags & RDF_MOTIONBLUR;
2542
2543 if (mBlur)
2544 fd->rdflags &= ~RDF_MOTIONBLUR;
2545
2546 if (r_norefresh->value)
2547 return;
2548
2549 r_newrefdef = *fd;
2550
2551 if (!r_worldmodel && !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
2552 ri.Sys_Error (ERR_DROP, "R_RenderView: NULL worldmodel");
2553
2554 if (r_speeds->value)
2555 {
2556 c_brush_polys = 0;
2557 c_alias_polys = 0;
2558 }
2559
2560 R_PushDlights ();
2561
2562 if (gl_finish->value)
2563 qglFinish ();
2564
2565 R_SetupFrame ();
2566
2567 R_SetFrustum ();
2568
2569 R_SetupGL ();
2570
2571 R_MarkLeaves (); // done here so we know if we're in water
2572
2573 R_DrawWorld ();
2574
2575 if (r_newrefdef.rdflags & RDF_NOWORLDMODEL) //options menu
2576 {
2577 R_DrawAllDecals();
2578 R_DrawAllEntities(false);
2579 R_DrawAllParticles();
2580 }
2581 else
2582 {
2583 R_DrawSpecialSurfaces();
2584
2585 GLSTATE_DISABLE_ALPHATEST
2586
2587 R_RenderDlights ();
2588
2589 //spaz -> my nice trees
2590 if (gl_transrendersort->value)
2591 {
2592 GL_BuildParticleList();
2593 R_DrawSolidEntities();
2594 // R_DrawAllEntityShadows();
2595 R_DrawDecals ();
2596
2597 if (gl_transrendersort->value==1)
2598 {
2599 R_DrawLastElements();
2600 R_DrawAlphaSurfaces (false);
2601 }
2602 else
2603 {
2604 R_DrawAlphaSurfaces (true);
2605 R_DrawLastElements();
2606 }
2607 }
2608 //nonsorted routines
2609 else
2610 {
2611 R_DrawAllDecals();
2612
2613 R_DrawAllEntities(true);
2614 // R_DrawAllEntityShadows();
2615
2616 R_DrawAllParticles();
2617 R_DrawAlphaSurfaces (false);
2618 }
2619
2620 //always draw vwep last...
2621 R_DrawEntitiesOnList(ents_viewweaps);
2622 R_DrawEntitiesOnList(ents_viewweaps_trans);
2623
2624 R_DrawAllEntityShadows();
2625
2626 R_Flash();
2627
2628 if (r_speeds->value)
2629 {
2630 ri.Con_Printf (PRINT_ALL, "%4i wpoly %4i epoly %i tex %i lmaps\n",
2631 c_brush_polys,
2632 c_alias_polys,
2633 c_visible_textures,
2634 c_visible_lightmaps);
2635 }
2636 }
2637
2638 if (mBlur)
2639 {
2640 R_MotionBlurBlend();
2641 fd->rdflags |= RDF_MOTIONBLUR;
2642 }
2643 }
2644
mulc(int i1,const float mult)2645 byte mulc(int i1, const float mult)
2646 {
2647 //amplify colors a bit
2648 int r = i1 * mult;
2649
2650 if (r > 255) return 255;
2651 else return r;
2652 }
2653
ProcessGlare(byte glarepixels[][4],int width,int height,const float mult)2654 void ProcessGlare(byte glarepixels[][4], int width, int height, const float mult)
2655 {
2656 int i;
2657
2658 for (i=0; i<width*height; i++)
2659 {
2660
2661 if ( (glarepixels[i][0] != 0) ||
2662 (glarepixels[i][1] != 0) ||
2663 (glarepixels[i][2] != 0) )
2664 {
2665
2666 glarepixels[i][0] = mulc(glarepixels[i][0], mult);
2667 glarepixels[i][1] = mulc(glarepixels[i][1], mult);
2668 glarepixels[i][2] = mulc(glarepixels[i][2], mult);
2669 }
2670 else
2671 {
2672 glarepixels[i][0] = 0;
2673 glarepixels[i][1] = 0;
2674 glarepixels[i][2] = 0;
2675 }
2676 }
2677 }
2678
2679 /*
2680 Fast Idea Blurring from
2681 http://www.gamasutra.com/features/20010209/evans_01.htm
2682 */
2683 typedef struct bytecolor_s
2684 {
2685 byte r,g,b,a;
2686 } bytecolor_t;
2687 typedef struct longcolor_s
2688 {
2689 unsigned long r,g,b,a;
2690 } longcolor_t;
2691
DoPreComputation(bytecolor_t * src,int src_w,int src_h,longcolor_t * dst)2692 void DoPreComputation(bytecolor_t *src, int src_w, int src_h, longcolor_t *dst)
2693 {
2694 longcolor_t tot;
2695 int y,x;
2696
2697 for (y=0;y<src_h;y++)
2698 {
2699 for (x=0;x<src_w;x++)
2700 {
2701 tot.r = src[0].r;
2702 tot.g = src[0].g;
2703 tot.b = src[0].b;
2704 tot.a = 255;
2705
2706 if (x>0)
2707 {
2708 tot.r+=dst[-1].r;
2709 tot.g+=dst[-1].g;
2710 tot.b+=dst[-1].b;
2711 }
2712 if (y>0)
2713 {
2714 tot.r+=dst[-src_w].r;
2715 tot.g+=dst[-src_w].g;
2716 tot.b+=dst[-src_w].b;
2717 }
2718 if (x>0 && y>0)
2719 {
2720 tot.r-=dst[-src_w-1].r;
2721 tot.g-=dst[-src_w-1].g;
2722 tot.b-=dst[-src_w-1].b;
2723 }
2724 dst->r=tot.r;
2725 dst->g=tot.g;
2726 dst->b=tot.b;
2727 dst->a=255;
2728 dst++;
2729 src++;
2730 }
2731 }
2732 }
2733
2734 // this is a utility function used by DoBoxBlur below
ReadP(longcolor_t * p,int w,int h,int x,int y)2735 longcolor_t *ReadP(longcolor_t *p, int w, int h, int x, int y)
2736 {
2737 if (x<0) x=0; else if (x>=w) x=w-1;
2738 if (y<0) y=0; else if (y>=h) y=h-1;
2739 return &p[x+y*w];
2740 }
2741
2742 // the main meat of the algorithm lies here
DoBoxBlur(bytecolor_t * src,int src_w,int src_h,bytecolor_t * dst,longcolor_t * p,int boxw,int boxh)2743 void DoBoxBlur(bytecolor_t *src, int src_w, int src_h, bytecolor_t *dst, longcolor_t *p, int boxw, int boxh)
2744 {
2745 longcolor_t *to1, *to2, *to3, *to4;
2746 int y,x;
2747 float mul;
2748
2749 if (boxw<0 || boxh<0)
2750 {
2751 memcpy(dst,src,src_w*src_h*4); // deal with degenerate kernel sizes
2752 return;
2753 }
2754 mul=1.f/((boxw*2+1)*(boxh*2+1));
2755 for (y=0;y<src_h;y++)
2756 {
2757 for (x=0;x<src_w;x++)
2758 {
2759 to1 = ReadP(p, src_w, src_h, x+boxw, y+boxh);
2760 to2 = ReadP(p, src_w, src_h, x-boxw, y-boxh);
2761 to3 = ReadP(p, src_w, src_h, x-boxw, y+boxh);
2762 to4 = ReadP(p, src_w, src_h, x+boxw, y-boxh);
2763
2764 dst->r= (to1->r + to2->r - to3->r - to4->r)*mul;
2765 dst->g= (to1->g + to2->g - to3->g - to4->g)*mul;
2766 dst->b= (to1->b + to2->b - to3->b - to4->b)*mul;
2767
2768 dst->a= 255;
2769
2770 dst++;
2771 src++;
2772 }
2773 }
2774 }
2775
2776 qboolean screenMotionBlurRender = false;
ProcessBlur(bytecolor_t * src,int src_w,int src_h)2777 void ProcessBlur (bytecolor_t *src, int src_w, int src_h)
2778 {
2779 int x, y, alpha, r ,g ,b, noalpha= true;
2780
2781 for (y=0;y<src_h;y++)
2782 for (x=0;x<src_w;x++, src++)
2783 {
2784 r = src->r;
2785 g = src->g;
2786 b = src->b;
2787
2788 alpha = (r + g + b);
2789 src->r = r*r * DIV255;
2790 src->g = g*g * DIV255;
2791 src->b = b*b * DIV255;
2792
2793 if (alpha > 254)
2794 alpha = 254;
2795
2796 if (alpha > 0)
2797 noalpha = false;
2798
2799 src->a = alpha;
2800 }
2801
2802 if (noalpha)
2803 screenMotionBlurRender = false;
2804 }
2805
2806 byte imagepixels[256*256][4];
2807 byte glareblurpixels[256*256][4];
2808 long glaresum[256*256][4];
2809
2810 const int powerof2s[] = { 8, 16, 32, 64 , 128, 256 };
checkResolution(int check)2811 int checkResolution (int check)
2812 {
2813 int i;
2814
2815 for (i=5; i>0; i--)
2816 if (check>=powerof2s[i])
2817 return powerof2s[i];
2818
2819 return powerof2s[0];
2820 }
2821
2822 float CalcFov (float fov_x, float width, float height);
2823 int lastcapture = 0;
2824 qboolean renderDynamic = false;
2825 qboolean renderMotionBlur = false;
2826
setRenderDynamic(void)2827 void setRenderDynamic (void)
2828 {
2829 renderDynamic = true;
2830 }
setRenderMotionBlur(void)2831 void setRenderMotionBlur (void)
2832 {
2833 renderMotionBlur = true;
2834 }
2835
R_PreRenderDynamic(refdef_t * fd)2836 void R_PreRenderDynamic (refdef_t *fd)
2837 {
2838 int i;
2839 msurface_t *surf;
2840 refdef_t refdef;
2841 qboolean motionBlurScreen = fd->rdflags & RDF_MOTIONBLUR;
2842
2843 if (fd->rdflags & RDF_NOWORLDMODEL)
2844 return;
2845
2846 if (r_shaders->value && lastcapture++ > rs_dynamic_time->value && renderDynamic)
2847 {
2848 int width = checkResolution(rs_dynamic_size->value);
2849 int height = checkResolution(rs_dynamic_size->value);
2850
2851 //lower res wont get messed up
2852 if (vid.width < width || vid.height < height)
2853 width = height = 128;
2854
2855 renderDynamic = false;
2856 lastcapture = 0;
2857
2858 memcpy (&refdef, fd, sizeof( refdef ));
2859
2860 refdef.x = 0;
2861 refdef.y = vid.height - height;
2862 refdef.width = width;
2863 refdef.height = height;
2864 refdef.fov_x = 150;
2865 refdef.fov_y = CalcFov (refdef.fov_x, refdef.width, refdef.height);
2866 refdef.viewangles[1] += (refdef.viewangles[1]>180)? -180: 180;
2867 if (motionBlurScreen)
2868 refdef.rdflags &= ~RDF_MOTIONBLUR;
2869
2870 R_Clear();
2871 R_RenderDynamicView ( &refdef );
2872 GL_Bind(r_dynamicimage->texnum);
2873
2874 qglReadPixels (0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, imagepixels);
2875 qglTexImage2D (GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imagepixels);
2876
2877 r_dynamicimage->upload_width = width;
2878 r_dynamicimage->upload_height = height;
2879 }
2880
2881 if (rs_glares->value)
2882 {
2883 int width = checkResolution(rs_glares_size->value);
2884 int height = checkResolution(rs_glares_size->value);
2885
2886 //lower res wont get messed up
2887 if (vid.width < width || vid.height < height)
2888 width = height = 128;
2889
2890 memcpy (&refdef, fd, sizeof( refdef ));
2891
2892 refdef.x = 0;
2893 refdef.y = vid.height - height;
2894 refdef.width = width;
2895 refdef.height = height;
2896 refdef.fov_y = CalcFov (refdef.fov_x, refdef.width, refdef.height);
2897 refdef.rdflags |= RDF_LIGHTBLEND;
2898 if (motionBlurScreen)
2899 refdef.rdflags &= ~RDF_MOTIONBLUR;
2900
2901 R_Clear();
2902 R_RenderGlareView ( &refdef );
2903 GL_Bind(r_lblendimage->texnum);
2904
2905 qglReadPixels (0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, imagepixels);
2906
2907 ProcessGlare(imagepixels, width, height, 1 + rs_glares->value*.5);
2908 DoPreComputation((bytecolor_t *)imagepixels, width, height, (longcolor_t *)glaresum);
2909 DoBoxBlur((bytecolor_t *)imagepixels, width, height,
2910 (bytecolor_t *)glareblurpixels, (longcolor_t *)glaresum, rs_glares->value*3, rs_glares->value*3);
2911 if (rs_glares->value != 1)
2912 ProcessGlare(glareblurpixels, width, height, 1 + rs_glares->value/3);
2913 qglTexImage2D (GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, glareblurpixels);
2914
2915 r_lblendimage->upload_width = width;
2916 r_lblendimage->upload_height = height;
2917 }
2918
2919 if (gl_motionblur->value && (motionBlurScreen || renderMotionBlur || screenMotionBlurRender))
2920 {
2921 int width = checkResolution(gl_motionblur_size->value);
2922 int height = checkResolution(gl_motionblur_size->value);
2923
2924 //lower res wont get messed up
2925 if (vid.width < width || vid.height < height)
2926 width = height = 128;
2927
2928 renderMotionBlur = false;
2929 screenMotionBlurRender = true;
2930
2931 memcpy (&refdef, fd, sizeof( refdef ));
2932
2933 refdef.x = 0;
2934 refdef.y = vid.height - height;
2935 refdef.width = width;
2936 refdef.height = height;
2937 refdef.fov_y = CalcFov (refdef.fov_x, refdef.width, refdef.height);
2938
2939 R_Clear();
2940
2941 if (motionBlurScreen)
2942 {
2943 R_RenderView( &refdef );
2944 }
2945 else
2946 {
2947 refdef.rdflags |= RDF_MOTIONBLUR;
2948 R_RenderMotionBlurView ( &refdef );
2949 }
2950
2951 qglReadPixels (0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, imagepixels);
2952
2953 GL_Bind(r_motionblurimage->texnum);
2954 qglTexImage2D (GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imagepixels);
2955
2956 GL_Bind(r_motionblurscreenimage->texnum);
2957 ProcessBlur((void *)imagepixels, width, height);
2958 qglTexImage2D (GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imagepixels);
2959
2960
2961 r_motionblurscreenimage->upload_width = width;
2962 r_motionblurscreenimage->upload_height = height;
2963 r_motionblurimage->upload_width = width;
2964 r_motionblurimage->upload_height = height;
2965 }
2966
2967 R_Clear();
2968 }
2969
R_RenderPic(int x,int y,int w,int h)2970 void R_RenderPic(int x, int y, int w, int h)
2971 {
2972 qglTexCoord2f (0, 0);
2973 qglVertex2f (x, y);
2974 qglTexCoord2f (1, 0);
2975 qglVertex2f (x+w, y);
2976 qglTexCoord2f (1, -1);
2977 qglVertex2f (x+w, y+h);
2978 qglTexCoord2f (0, -1);
2979 qglVertex2f (x, y+h);
2980 }
2981
2982
2983
R_RenderMotionBlur(refdef_t * fd)2984 void R_RenderMotionBlur (refdef_t *fd)
2985 {
2986 int x, y, w, h;
2987
2988 if (fd->rdflags & RDF_NOWORLDMODEL)
2989 return;
2990 if (!gl_motionblur->value)
2991 return;
2992 if (!screenMotionBlurRender)
2993 return;
2994
2995 w = fd->width;
2996 h = fd->width;
2997 x = 0;
2998 y = (fd->width-fd->height)*-0.5;
2999
3000 GL_Bind (r_motionblurscreenimage->texnum);
3001 GL_BlendFunction(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
3002
3003 GLSTATE_DISABLE_ALPHATEST
3004 GLSTATE_ENABLE_BLEND
3005 GL_TexEnv( GL_MODULATE );
3006 qglColor4ub(255, 255, 255, 255);
3007
3008 qglBegin (GL_QUADS);
3009 R_RenderPic(x, y, w, h);
3010 qglEnd ();
3011
3012 GLSTATE_ENABLE_ALPHATEST
3013 GLSTATE_DISABLE_BLEND
3014 GL_TexEnv( GL_REPLACE );
3015 GL_BlendFunction(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
3016 }
R_RenderGlares(refdef_t * fd)3017 void R_RenderGlares (refdef_t *fd)
3018 {
3019 int x, y, w, h;
3020
3021 if (fd->rdflags & RDF_NOWORLDMODEL)
3022 return;
3023 if (!rs_glares->value)
3024 return;
3025
3026 w = fd->width;
3027 h = fd->width;
3028 x = 0;
3029 y = (fd->width-fd->height)*-0.5;
3030
3031 GL_Bind (r_lblendimage->texnum);
3032 GL_BlendFunction(GL_ONE,GL_ONE);
3033
3034 GLSTATE_DISABLE_ALPHATEST
3035 GLSTATE_ENABLE_BLEND
3036 GL_TexEnv( GL_MODULATE );
3037 qglColor4f(1,1,1,1);
3038
3039 qglBegin (GL_QUADS);
3040 R_RenderPic(x, y, w, h);
3041 qglEnd ();
3042
3043 GLSTATE_ENABLE_ALPHATEST
3044 GLSTATE_DISABLE_BLEND
3045 GL_TexEnv( GL_REPLACE );
3046 GL_BlendFunction(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
3047 }
3048
R_SetGL2D(void)3049 void R_SetGL2D (void)
3050 {
3051 // set 2D virtual screen size
3052 qglViewport (0,0, vid.width, vid.height);
3053 qglMatrixMode(GL_PROJECTION);
3054 qglLoadIdentity ();
3055 qglOrtho (0, vid.width, vid.height, 0, -99999, 99999);
3056 qglMatrixMode(GL_MODELVIEW);
3057 qglLoadIdentity ();
3058 qglDisable (GL_DEPTH_TEST);
3059 qglDisable (GL_CULL_FACE);
3060 GLSTATE_DISABLE_BLEND
3061 GLSTATE_ENABLE_ALPHATEST
3062 GLSTATE_DISABLE_TEXGEN
3063 qglColor4f (1,1,1,1);
3064 GL_BlendFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
3065 }
3066
GL_DrawColoredStereoLinePair(float r,float g,float b,float y)3067 static void GL_DrawColoredStereoLinePair( float r, float g, float b, float y )
3068 {
3069 qglColor3f( r, g, b );
3070 qglVertex2f( 0, y );
3071 qglVertex2f( vid.width, y );
3072 qglColor3f( 0, 0, 0 );
3073 qglVertex2f( 0, y + 1 );
3074 qglVertex2f( vid.width, y + 1 );
3075 }
3076
GL_DrawStereoPattern(void)3077 static void GL_DrawStereoPattern( void )
3078 {
3079 int i;
3080
3081 if ( !( gl_config.renderer & GL_RENDERER_INTERGRAPH ) )
3082 return;
3083
3084 if ( !gl_state.stereo_enabled )
3085 return;
3086
3087 R_SetGL2D();
3088
3089 qglDrawBuffer( GL_BACK_LEFT );
3090
3091 for ( i = 0; i < 20; i++ )
3092 {
3093 qglBegin( GL_LINES );
3094 GL_DrawColoredStereoLinePair( 1, 0, 0, 0 );
3095 GL_DrawColoredStereoLinePair( 1, 0, 0, 2 );
3096 GL_DrawColoredStereoLinePair( 1, 0, 0, 4 );
3097 GL_DrawColoredStereoLinePair( 1, 0, 0, 6 );
3098 GL_DrawColoredStereoLinePair( 0, 1, 0, 8 );
3099 GL_DrawColoredStereoLinePair( 1, 1, 0, 10);
3100 GL_DrawColoredStereoLinePair( 1, 1, 0, 12);
3101 GL_DrawColoredStereoLinePair( 0, 1, 0, 14);
3102 qglEnd();
3103
3104 GLimp_EndFrame();
3105 }
3106 }
3107
3108
3109 /*
3110 ====================
3111 R_SetLightLevel
3112
3113 ====================
3114 */
R_SetLightLevel(void)3115 void R_SetLightLevel (void)
3116 {
3117 vec3_t shadelight;
3118
3119 if (r_newrefdef.rdflags & RDF_NOWORLDMODEL)
3120 return;
3121
3122 // save off light value for server to look at (BIG HACK!)
3123
3124 R_LightPoint (r_newrefdef.vieworg, shadelight);
3125
3126 // pick the greatest component, which should be the same
3127 // as the mono value returned by software
3128 if (shadelight[0] > shadelight[1])
3129 {
3130 if (shadelight[0] > shadelight[2])
3131 r_lightlevel->value = 150*shadelight[0];
3132 else
3133 r_lightlevel->value = 150*shadelight[2];
3134 }
3135 else
3136 {
3137 if (shadelight[1] > shadelight[2])
3138 r_lightlevel->value = 150*shadelight[1];
3139 else
3140 r_lightlevel->value = 150*shadelight[2];
3141 }
3142
3143 }
3144
3145 /*
3146 @@@@@@@@@@@@@@@@@@@@@
3147 R_RenderFrame
3148
3149 @@@@@@@@@@@@@@@@@@@@@
3150 */
R_RenderFrame(refdef_t * fd)3151 void R_RenderFrame (refdef_t *fd)
3152 {
3153 R_PreRenderDynamic( fd );
3154
3155 R_RenderView( fd );
3156 R_SetLightLevel ();
3157 R_SetGL2D ();
3158
3159 R_RenderGlares(fd);
3160 R_RenderMotionBlur(fd);
3161 }
3162
3163
R_Register(void)3164 void R_Register( void )
3165 {
3166 con_font = ri.Cvar_Get ("con_font", "default", CVAR_ARCHIVE);
3167 con_font_size = ri.Cvar_Get ("con_font_size", "8", CVAR_ARCHIVE);
3168
3169 r_dlights_normal = ri.Cvar_Get("r_dlights_normal", "1", CVAR_ARCHIVE);
3170
3171 skydistance = ri.Cvar_Get("r_skydistance", "10000", CVAR_ARCHIVE); // DMP - skybox size change
3172 gl_transrendersort = ri.Cvar_Get ("gl_transrendersort", "1", CVAR_ARCHIVE );
3173 gl_particle_lighting = ri.Cvar_Get ("gl_particle_lighting", "0.75", CVAR_ARCHIVE );
3174 gl_particle_min = ri.Cvar_Get ("gl_particle_min", "0", CVAR_ARCHIVE );
3175 gl_particle_max = ri.Cvar_Get ("gl_particle_max", "0", CVAR_ARCHIVE );
3176 gl_surftrans_light = ri.Cvar_Get ("gl_surftrans_light", "1", CVAR_ARCHIVE );
3177
3178 gl_stencil = ri.Cvar_Get ("gl_stencil", "1", CVAR_ARCHIVE );
3179
3180 gl_screenshot_quality = ri.Cvar_Get ("gl_screenshot_quality", "85", CVAR_ARCHIVE );
3181
3182 r_lefthand = ri.Cvar_Get( "hand", "0", CVAR_USERINFO | CVAR_ARCHIVE );
3183 r_norefresh = ri.Cvar_Get ("r_norefresh", "0", 0);
3184 r_fullbright = ri.Cvar_Get ("r_fullbright", "0", 0);
3185 r_drawentities = ri.Cvar_Get ("r_drawentities", "1", 0);
3186 r_drawworld = ri.Cvar_Get ("r_drawworld", "1", 0);
3187 r_novis = ri.Cvar_Get ("r_novis", "0", 0);
3188 r_nocull = ri.Cvar_Get ("r_nocull", "0", 0);
3189 r_lerpmodels = ri.Cvar_Get ("r_lerpmodels", "1", 0);
3190 r_speeds = ri.Cvar_Get ("r_speeds", "0", 0);
3191
3192 r_lightlevel = ri.Cvar_Get ("r_lightlevel", "0", 0);
3193
3194 r_shaders = ri.Cvar_Get ("r_shaders", "1", CVAR_ARCHIVE);
3195
3196 rs_dynamic_time = ri.Cvar_Get("rs_dynamic_time", "2", CVAR_ARCHIVE);
3197 rs_dynamic_size = ri.Cvar_Get("rs_dynamic_size", "64", CVAR_ARCHIVE);
3198 rs_dynamic_particles = ri.Cvar_Get("rs_dynamic_particles", "1", CVAR_ARCHIVE);
3199 rs_dynamic_entities = ri.Cvar_Get("rs_dynamic_entities", "1", CVAR_ARCHIVE);
3200
3201 gl_motionblur = ri.Cvar_Get("gl_motionblur", "1", CVAR_ARCHIVE);
3202 gl_motionblur_size = ri.Cvar_Get("gl_motionblur_size", "128", CVAR_ARCHIVE);
3203
3204 rs_detail = ri.Cvar_Get("rs_detail", "1", CVAR_ARCHIVE);
3205
3206 rs_glares = ri.Cvar_Get("rs_glares", "0", CVAR_ARCHIVE);
3207 rs_glares_sky = ri.Cvar_Get("rs_glares_sky", "0", CVAR_ARCHIVE);
3208 rs_glares_size = ri.Cvar_Get("rs_glares_size", "128", CVAR_ARCHIVE);
3209 rs_glares_shell = ri.Cvar_Get("rs_glares_shell", "1", CVAR_ARCHIVE);
3210 rs_glares_particles = ri.Cvar_Get("rs_glares_particles", "1", CVAR_ARCHIVE);
3211
3212 r_model_lightlerp = ri.Cvar_Get( "r_model_lightlerp", "1", CVAR_ARCHIVE );
3213 r_model_dlights = ri.Cvar_Get( "r_model_dlights", "3", CVAR_ARCHIVE );
3214
3215 gl_nosubimage = ri.Cvar_Get( "gl_nosubimage", "0", 0 );
3216 gl_allow_software = ri.Cvar_Get( "gl_allow_software", "0", 0 );
3217
3218 // Vic - begin
3219 r_overbrightbits = ri.Cvar_Get( "r_overbrightbits", "2", CVAR_ARCHIVE );
3220 gl_ext_mtexcombine = ri.Cvar_Get( "gl_ext_mtexcombine", "1", CVAR_ARCHIVE );
3221 // Vic - end
3222 gl_ext_texture_compression = ri.Cvar_Get( "gl_ext_texture_compression", "0", CVAR_ARCHIVE ); // Heffo - ARB Texture Compression
3223
3224 gl_modulate = ri.Cvar_Get ("gl_modulate", "1", CVAR_ARCHIVE );
3225 gl_log = ri.Cvar_Get( "gl_log", "0", 0 );
3226 gl_bitdepth = ri.Cvar_Get( "gl_bitdepth", "0", 0 );
3227 gl_mode = ri.Cvar_Get( "gl_mode", "3", CVAR_ARCHIVE );
3228 gl_lightmap = ri.Cvar_Get ("gl_lightmap", "0", 0);
3229 gl_shadows = ri.Cvar_Get ("gl_shadows", "0", CVAR_ARCHIVE );
3230 gl_dynamic = ri.Cvar_Get ("gl_dynamic", "1", 0);
3231 gl_nobind = ri.Cvar_Get ("gl_nobind", "0", 0);
3232 gl_round_down = ri.Cvar_Get ("gl_round_down", "1", 0);
3233 gl_picmip = ri.Cvar_Get ("gl_picmip", "0", 0);
3234 gl_skymip = ri.Cvar_Get ("gl_skymip", "0", 0);
3235 gl_showtris = ri.Cvar_Get ("gl_showtris", "0", 0);
3236 gl_ztrick = ri.Cvar_Get ("gl_ztrick", "0", 0);
3237 gl_finish = ri.Cvar_Get ("gl_finish", "0", CVAR_ARCHIVE);
3238 gl_clear = ri.Cvar_Get ("gl_clear", "0", 0);
3239 gl_cull = ri.Cvar_Get ("gl_cull", "1", 0);
3240 gl_polyblend = ri.Cvar_Get ("gl_polyblend", "1", 0);
3241 gl_flashblend = ri.Cvar_Get ("gl_flashblend", "0", 0);
3242 gl_playermip = ri.Cvar_Get ("gl_playermip", "0", 0);
3243 gl_monolightmap = ri.Cvar_Get( "gl_monolightmap", "0", 0 );
3244 gl_driver = ri.Cvar_Get( "gl_driver", "libGL.so", CVAR_ARCHIVE );
3245 gl_texturemode = ri.Cvar_Get( "gl_texturemode", "GL_LINEAR_MIPMAP_NEAREST", CVAR_ARCHIVE );
3246 gl_anisotropic = ri.Cvar_Get( "gl_anisotropic", "0", CVAR_ARCHIVE );
3247 gl_texturealphamode = ri.Cvar_Get( "gl_texturealphamode", "default", CVAR_ARCHIVE );
3248 gl_texturesolidmode = ri.Cvar_Get( "gl_texturesolidmode", "default", CVAR_ARCHIVE );
3249 gl_lockpvs = ri.Cvar_Get( "gl_lockpvs", "0", 0 );
3250
3251
3252 gl_vertex_arrays = ri.Cvar_Get( "gl_vertex_arrays", "0", CVAR_ARCHIVE );
3253
3254 r_celshading = ri.Cvar_Get( "r_celshading", "0", CVAR_ARCHIVE );
3255 r_celshading_width = ri.Cvar_Get( "r_celshading_width", "4", CVAR_ARCHIVE );
3256
3257 cl_3dcam = ri.Cvar_Get ("cl_3dcam", "0", CVAR_ARCHIVE);
3258 cl_3dcam_angle = ri.Cvar_Get ("cl_3dcam_angle", "0", CVAR_ARCHIVE);
3259 cl_3dcam_dist = ri.Cvar_Get ("cl_3dcam_dist", "50", CVAR_ARCHIVE);
3260 cl_3dcam_alpha = ri.Cvar_Get ("cl_3dcam_alpha", "1", CVAR_ARCHIVE);
3261 cl_3dcam_chase = ri.Cvar_Get ("cl_3dcam_chase", "1", CVAR_ARCHIVE);
3262 cl_3dcam_adjust = ri.Cvar_Get ("cl_3dcam_adjust", "1", CVAR_ARCHIVE);
3263
3264 gl_ext_swapinterval = ri.Cvar_Get( "gl_ext_swapinterval", "1", CVAR_ARCHIVE );
3265 gl_ext_multitexture = ri.Cvar_Get( "gl_ext_multitexture", "1", CVAR_ARCHIVE );
3266 gl_ext_pointparameters = ri.Cvar_Get( "gl_ext_pointparameters", "1", CVAR_ARCHIVE );
3267 gl_ext_compiled_vertex_array = ri.Cvar_Get( "gl_ext_compiled_vertex_array", "1", CVAR_ARCHIVE );
3268
3269 gl_drawbuffer = ri.Cvar_Get( "gl_drawbuffer", "GL_BACK", 0 );
3270 gl_swapinterval = ri.Cvar_Get( "gl_swapinterval", "0", CVAR_ARCHIVE );
3271
3272 gl_saturatelighting = ri.Cvar_Get( "gl_saturatelighting", "0", 0 );
3273
3274 gl_3dlabs_broken = ri.Cvar_Get( "gl_3dlabs_broken", "1", CVAR_ARCHIVE );
3275
3276 vid_fullscreen = ri.Cvar_Get( "vid_fullscreen", "0", CVAR_ARCHIVE );
3277 vid_gamma = ri.Cvar_Get( "vid_gamma", "1.0", CVAR_ARCHIVE );
3278 vid_ref = ri.Cvar_Get( "vid_ref", "glx", CVAR_ARCHIVE );
3279
3280 ri.Cmd_AddCommand( "imagelist", GL_ImageList_f );
3281 ri.Cmd_AddCommand( "screenshot", GL_ScreenShot_f );
3282 ri.Cmd_AddCommand( "modellist", Mod_Modellist_f );
3283 ri.Cmd_AddCommand( "gl_strings", GL_Strings_f );
3284 }
3285
3286 /*
3287 ==================
3288 R_SetMode
3289 ==================
3290 */
R_SetMode(void)3291 qboolean R_SetMode (void)
3292 {
3293 rserr_t err;
3294 qboolean fullscreen;
3295
3296 if ( vid_fullscreen->modified && !gl_config.allow_cds )
3297 {
3298 ri.Con_Printf( PRINT_ALL, "R_SetMode() - CDS not allowed with this driver\n" );
3299 ri.Cvar_SetValue( "vid_fullscreen", !vid_fullscreen->value );
3300 vid_fullscreen->modified = false;
3301 }
3302
3303 fullscreen = vid_fullscreen->value;
3304
3305 skydistance->modified = true; // DMP skybox size change
3306 vid_fullscreen->modified = false;
3307 gl_mode->modified = false;
3308
3309 if ( ( err = GLimp_SetMode( &vid.width, &vid.height, gl_mode->value, fullscreen ) ) == rserr_ok )
3310 {
3311 gl_state.prev_mode = gl_mode->value;
3312 }
3313 else
3314 {
3315 if ( err == rserr_invalid_fullscreen )
3316 {
3317 ri.Cvar_SetValue( "vid_fullscreen", 0);
3318 vid_fullscreen->modified = false;
3319 ri.Con_Printf( PRINT_ALL, "rfx_gl::R_SetMode() - fullscreen unavailable in this mode\n" );
3320 if ( ( err = GLimp_SetMode( &vid.width, &vid.height, gl_mode->value, false ) ) == rserr_ok )
3321 return true;
3322 }
3323 else if ( err == rserr_invalid_mode )
3324 {
3325 ri.Cvar_SetValue( "gl_mode", gl_state.prev_mode );
3326 gl_mode->modified = false;
3327 ri.Con_Printf( PRINT_ALL, "rfx_gl::R_SetMode() - invalid mode\n" );
3328 }
3329
3330 // try setting it back to something safe
3331 if ( ( err = GLimp_SetMode( &vid.width, &vid.height, gl_state.prev_mode, false ) ) != rserr_ok )
3332 {
3333 ri.Con_Printf( PRINT_ALL, "rfx_gl::R_SetMode() - could not revert to safe mode\n" );
3334 return false;
3335 }
3336 }
3337 return true;
3338 }
3339
3340 /*
3341 ===============
3342 R_Init
3343 ===============
3344 */
R_Init(void * hinstance,void * hWnd)3345 int R_Init( void *hinstance, void *hWnd )
3346 {
3347 char renderer_buffer[1000];
3348 char vendor_buffer[1000];
3349 int err;
3350 int j;
3351 extern float r_turbsin[256];
3352
3353 for ( j = 0; j < 256; j++ )
3354 {
3355 r_turbsin[j] *= 0.5;
3356 }
3357
3358 ri.Con_Printf (PRINT_ALL, "rfx_gl version: "REF_VERSION"\n");
3359
3360 Draw_GetPalette ();
3361
3362 R_Register();
3363
3364 VLight_Init();
3365
3366 // initialize our QGL dynamic bindings
3367 if ( !QGL_Init( gl_driver->string ) )
3368 {
3369 QGL_Shutdown();
3370 ri.Con_Printf (PRINT_ALL, "rfx_gl::R_Init() - could not load \"%s\"\n", gl_driver->string );
3371 return -1;
3372 }
3373
3374 // initialize OS-specific parts of OpenGL
3375 if ( !GLimp_Init( hinstance, hWnd ) )
3376 {
3377 QGL_Shutdown();
3378 return -1;
3379 }
3380
3381 // set our "safe" modes
3382 gl_state.prev_mode = 3;
3383
3384 // create the window and set up the context
3385 if ( !R_SetMode () )
3386 {
3387 QGL_Shutdown();
3388 ri.Con_Printf (PRINT_ALL, "rfx_gl::R_Init() - could not R_SetMode()\n" );
3389 return -1;
3390 }
3391
3392 ri.Vid_MenuInit();
3393
3394 /*
3395 ** get our various GL strings
3396 */
3397 gl_config.vendor_string = qglGetString (GL_VENDOR);
3398 ri.Con_Printf (PRINT_ALL, "GL_VENDOR: %s\n", gl_config.vendor_string );
3399 gl_config.renderer_string = qglGetString (GL_RENDERER);
3400 ri.Con_Printf (PRINT_ALL, "GL_RENDERER: %s\n", gl_config.renderer_string );
3401 gl_config.version_string = qglGetString (GL_VERSION);
3402 ri.Con_Printf (PRINT_ALL, "GL_VERSION: %s\n", gl_config.version_string );
3403 gl_config.extensions_string = qglGetString (GL_EXTENSIONS);
3404 ri.Con_Printf (PRINT_ALL, "GL_EXTENSIONS: %s\n", gl_config.extensions_string );
3405
3406 strcpy( renderer_buffer, gl_config.renderer_string );
3407 strlwr( renderer_buffer );
3408
3409 strcpy( vendor_buffer, gl_config.vendor_string );
3410 strlwr( vendor_buffer );
3411
3412 if ( strstr( renderer_buffer, "voodoo" ) )
3413 {
3414 if ( !strstr( renderer_buffer, "rush" ) )
3415 gl_config.renderer = GL_RENDERER_VOODOO;
3416 else
3417 gl_config.renderer = GL_RENDERER_VOODOO_RUSH;
3418 }
3419 else if ( strstr( vendor_buffer, "sgi" ) )
3420 gl_config.renderer = GL_RENDERER_SGI;
3421 else if ( strstr( renderer_buffer, "permedia" ) )
3422 gl_config.renderer = GL_RENDERER_PERMEDIA2;
3423 else if ( strstr( renderer_buffer, "glint" ) )
3424 gl_config.renderer = GL_RENDERER_GLINT_MX;
3425 else if ( strstr( renderer_buffer, "glzicd" ) )
3426 gl_config.renderer = GL_RENDERER_REALIZM;
3427 else if ( strstr( renderer_buffer, "gdi" ) )
3428 gl_config.renderer = GL_RENDERER_MCD;
3429 else if ( strstr( renderer_buffer, "pcx2" ) )
3430 gl_config.renderer = GL_RENDERER_PCX2;
3431 else if ( strstr( renderer_buffer, "verite" ) )
3432 gl_config.renderer = GL_RENDERER_RENDITION;
3433 else
3434 gl_config.renderer = GL_RENDERER_OTHER;
3435
3436 if ( toupper( gl_monolightmap->string[1] ) != 'F' )
3437 {
3438 if ( gl_config.renderer == GL_RENDERER_PERMEDIA2 )
3439 {
3440 ri.Cvar_Set( "gl_monolightmap", "A" );
3441 ri.Con_Printf( PRINT_ALL, "...using gl_monolightmap 'a'\n" );
3442 }
3443 else if ( gl_config.renderer & GL_RENDERER_POWERVR )
3444 {
3445 ri.Cvar_Set( "gl_monolightmap", "0" );
3446 }
3447 else
3448 {
3449 ri.Cvar_Set( "gl_monolightmap", "0" );
3450 }
3451 }
3452
3453 // power vr can't have anything stay in the framebuffer, so
3454 // the screen needs to redraw the tiled background every frame
3455 if ( gl_config.renderer & GL_RENDERER_POWERVR )
3456 {
3457 ri.Cvar_Set( "scr_drawall", "1" );
3458 }
3459 else
3460 {
3461 ri.Cvar_Set( "scr_drawall", "0" );
3462 }
3463
3464 #ifdef __unix__
3465 ri.Cvar_SetValue( "gl_finish", 1 );
3466 #endif
3467
3468 // MCD has buffering issues
3469 if ( gl_config.renderer == GL_RENDERER_MCD )
3470 {
3471 ri.Cvar_SetValue( "gl_finish", 1 );
3472 }
3473
3474 if ( gl_config.renderer & GL_RENDERER_3DLABS )
3475 {
3476 if ( gl_3dlabs_broken->value )
3477 gl_config.allow_cds = false;
3478 else
3479 gl_config.allow_cds = true;
3480 }
3481 else
3482 {
3483 gl_config.allow_cds = true;
3484 }
3485
3486 if ( gl_config.allow_cds )
3487 ri.Con_Printf( PRINT_ALL, "...allowing CDS\n" );
3488 else
3489 ri.Con_Printf( PRINT_ALL, "...disabling CDS\n" );
3490
3491 /*
3492 ** grab extensions
3493 */
3494 if ( strstr( gl_config.extensions_string, "GL_EXT_compiled_vertex_array" ) ||
3495 strstr( gl_config.extensions_string, "GL_SGI_compiled_vertex_array" ) )
3496 {
3497 ri.Con_Printf( PRINT_ALL, "...enabling GL_EXT_compiled_vertex_array\n" );
3498 qglLockArraysEXT = ( void * ) qwglGetProcAddress( "glLockArraysEXT" );
3499 qglUnlockArraysEXT = ( void * ) qwglGetProcAddress( "glUnlockArraysEXT" );
3500 }
3501 else
3502 {
3503 ri.Con_Printf( PRINT_ALL, "...GL_EXT_compiled_vertex_array not found\n" );
3504 }
3505
3506 #ifdef _WIN32
3507 if ( strstr( gl_config.extensions_string, "WGL_EXT_swap_control" ) )
3508 {
3509 qwglSwapIntervalEXT = ( BOOL (WINAPI *)(int)) qwglGetProcAddress( "wglSwapIntervalEXT" );
3510 ri.Con_Printf( PRINT_ALL, "...enabling WGL_EXT_swap_control\n" );
3511 }
3512 else
3513 {
3514 ri.Con_Printf( PRINT_ALL, "...WGL_EXT_swap_control not found\n" );
3515 }
3516 #endif
3517
3518 if ( strstr( gl_config.extensions_string, "GL_EXT_point_parameters" ) )
3519 {
3520 if ( gl_ext_pointparameters->value )
3521 {
3522 qglPointParameterfEXT = ( void (APIENTRY *)( GLenum, GLfloat ) ) qwglGetProcAddress( "glPointParameterfEXT" );
3523 qglPointParameterfvEXT = ( void (APIENTRY *)( GLenum, const GLfloat * ) ) qwglGetProcAddress( "glPointParameterfvEXT" );
3524 ri.Con_Printf( PRINT_ALL, "...using GL_EXT_point_parameters\n" );
3525 }
3526 else
3527 {
3528 ri.Con_Printf( PRINT_ALL, "...ignoring GL_EXT_point_parameters\n" );
3529 }
3530 }
3531 else
3532 {
3533 ri.Con_Printf( PRINT_ALL, "...GL_EXT_point_parameters not found\n" );
3534 }
3535
3536 if ( strstr( gl_config.extensions_string, "GL_ARB_multitexture" ) )
3537 {
3538 if ( gl_ext_multitexture->value )
3539 {
3540 ri.Con_Printf( PRINT_ALL, "...using GL_ARB_multitexture\n" );
3541 qglMTexCoord2fSGIS = ( void * ) qwglGetProcAddress( "glMultiTexCoord2fARB" );
3542 qglActiveTextureARB = ( void * ) qwglGetProcAddress( "glActiveTextureARB" );
3543 qglClientActiveTextureARB = ( void * ) qwglGetProcAddress( "glClientActiveTextureARB" );
3544 GL_TEXTURE0 = GL_TEXTURE0_ARB;
3545 GL_TEXTURE1 = GL_TEXTURE1_ARB;
3546 }
3547 else
3548 {
3549 ri.Con_Printf( PRINT_ALL, "...ignoring GL_ARB_multitexture\n" );
3550 }
3551 }
3552 else
3553 {
3554 ri.Con_Printf( PRINT_ALL, "...GL_ARB_multitexture not found\n" );
3555 }
3556
3557 if ( strstr( gl_config.extensions_string, "GL_SGIS_multitexture" ) )
3558 {
3559 if ( qglActiveTextureARB )
3560 {
3561 ri.Con_Printf( PRINT_ALL, "...GL_SGIS_multitexture deprecated in favor of ARB_multitexture\n" );
3562 }
3563 else if ( gl_ext_multitexture->value )
3564 {
3565 ri.Con_Printf( PRINT_ALL, "...using GL_SGIS_multitexture\n" );
3566 qglMTexCoord2fSGIS = ( void * ) qwglGetProcAddress( "glMTexCoord2fSGIS" );
3567 qglSelectTextureSGIS = ( void * ) qwglGetProcAddress( "glSelectTextureSGIS" );
3568 GL_TEXTURE0 = GL_TEXTURE0_SGIS;
3569 GL_TEXTURE1 = GL_TEXTURE1_SGIS;
3570 }
3571 else
3572 {
3573 ri.Con_Printf( PRINT_ALL, "...ignoring GL_SGIS_multitexture\n" );
3574 }
3575 }
3576 else
3577 {
3578 ri.Con_Printf( PRINT_ALL, "...GL_SGIS_multitexture not found\n" );
3579 }
3580
3581 // Vic - begin
3582 gl_config.mtexcombine = false;
3583
3584 if ( strstr( gl_config.extensions_string, "GL_ARB_texture_env_combine" ) )
3585 {
3586 if ( gl_ext_mtexcombine->value )
3587 {
3588 Com_Printf( "...using GL_ARB_texture_env_combine\n" );
3589 gl_config.mtexcombine = true;
3590 }
3591 else
3592 {
3593 Com_Printf( "...ignoring GL_ARB_texture_env_combine\n" );
3594 }
3595 }
3596 else
3597 {
3598 Com_Printf( "...GL_ARB_texture_env_combine not found\n" );
3599 }
3600
3601 if ( !gl_config.mtexcombine )
3602 {
3603 if ( strstr( gl_config.extensions_string, "GL_EXT_texture_env_combine" ) )
3604 {
3605 if ( gl_ext_mtexcombine->value )
3606 {
3607 Com_Printf( "...using GL_EXT_texture_env_combine\n" );
3608 gl_config.mtexcombine = true;
3609 }
3610 else
3611 {
3612 Com_Printf( "...ignoring GL_EXT_texture_env_combine\n" );
3613 }
3614 }
3615 else
3616 {
3617 Com_Printf( "...GL_EXT_texture_env_combine not found\n" );
3618 }
3619 }
3620 // Vic - end
3621
3622 // Texture Shader support - MrG
3623 if ( strstr( gl_config.extensions_string, "GL_NV_texture_shader" ) )
3624 {
3625 ri.Con_Printf(PRINT_ALL, "...using GL_NV_texture_shader\n");
3626 gl_state.texshaders=true;
3627 }
3628 else
3629 {
3630 ri.Con_Printf(PRINT_ALL, "...GL_NV_texture_shader not found\n");
3631 gl_state.texshaders=false;
3632 }
3633
3634 if ( strstr( gl_config.extensions_string, "GL_SGIS_generate_mipmap" ) )
3635 {
3636 ri.Con_Printf(PRINT_ALL, "...using GL_SGIS_generate_mipmap\n");
3637 gl_state.sgis_mipmap=true;
3638 } else {
3639 ri.Con_Printf(PRINT_ALL, "...GL_SGIS_generate_mipmap not found\n");
3640 gl_state.sgis_mipmap=false;
3641 }
3642
3643 // Heffo - ARB Texture Compression
3644 if ( strstr( gl_config.extensions_string, "GL_ARB_texture_compression" ) )
3645 {
3646 if(!gl_ext_texture_compression->value)
3647 {
3648 ri.Con_Printf(PRINT_ALL, "...ignoring GL_ARB_texture_compression\n");
3649 gl_state.texture_compression = false;
3650 }
3651 else
3652 {
3653 ri.Con_Printf(PRINT_ALL, "...using GL_ARB_texture_compression\n");
3654 gl_state.texture_compression = true;
3655 }
3656 }
3657 else
3658 {
3659 ri.Con_Printf(PRINT_ALL, "...GL_ARB_texture_compression not found\n");
3660 gl_state.texture_compression = false;
3661 ri.Cvar_Set("gl_ext_texture_compression", "0");
3662 }
3663
3664 GL_SetDefaultState();
3665
3666 /*
3667 ** draw our stereo patterns
3668 */
3669 #if 0 // commented out until H3D pays us the money they owe us
3670 GL_DrawStereoPattern();
3671 #endif
3672
3673 gl_swapinterval->modified = true;
3674
3675 GL_InitImages ();
3676 Mod_Init ();
3677 R_InitParticleTexture ();
3678 Draw_InitLocal ();
3679
3680 if(gl_texturemode)
3681 GL_TextureMode( gl_texturemode->string );
3682
3683 err = qglGetError();
3684 if ( err != GL_NO_ERROR )
3685 ri.Con_Printf (PRINT_ALL, "glGetError() = 0x%x\n", err);
3686 }
3687
3688 /*
3689 ===============
3690 R_Shutdown
3691 ===============
3692 */
R_Shutdown(void)3693 void R_Shutdown (void)
3694 {
3695 ri.Cmd_RemoveCommand ("modellist");
3696 ri.Cmd_RemoveCommand ("screenshot");
3697 ri.Cmd_RemoveCommand ("imagelist");
3698 ri.Cmd_RemoveCommand ("gl_strings");
3699
3700 Mod_FreeAll ();
3701
3702 GL_ShutdownImages ();
3703
3704 /*
3705 ** shut down OS specific OpenGL stuff like contexts, etc.
3706 */
3707 GLimp_Shutdown();
3708
3709 /*
3710 ** shutdown our QGL subsystem
3711 */
3712 QGL_Shutdown();
3713 }
3714
3715
3716
3717 /*
3718 @@@@@@@@@@@@@@@@@@@@@
3719 R_BeginFrame
3720 @@@@@@@@@@@@@@@@@@@@@
3721 */
3722
3723 #ifdef _WIN32
3724 void UpdateGammaRamp();
3725 #endif
3726 void RefreshFont (void);
R_BeginFrame(float camera_separation)3727 void R_BeginFrame( float camera_separation )
3728 {
3729 gl_state.camera_separation = camera_separation;
3730
3731 if (con_font->modified)
3732 RefreshFont ();
3733
3734 if (con_font_size->modified)
3735 {
3736 if (con_font_size->value<4)
3737 ri.Cvar_Set( "con_font_size", "4" );
3738 else if (con_font_size->value>32)
3739 ri.Cvar_Set( "con_font_size", "32" );
3740
3741 con_font_size->modified = false;
3742 }
3743
3744 if (r_overbrightbits->modified)
3745 {
3746 if (r_overbrightbits->value<1)
3747 ri.Cvar_Set( "r_overbrightbits", "1" );
3748 else if (r_overbrightbits->value>2 && r_overbrightbits->value!=4)
3749 ri.Cvar_Set( "r_overbrightbits", "4" );
3750
3751 r_overbrightbits->modified = false;
3752 }
3753 if (gl_modulate->modified)
3754 {
3755 if (gl_modulate->value<0.5)
3756 ri.Cvar_Set( "gl_modulate", "0.5");
3757 else if (gl_modulate->value>3)
3758 ri.Cvar_Set( "gl_modulate", "3" );
3759
3760 gl_modulate->modified = false;
3761 }
3762
3763 /*
3764 ** change modes if necessary
3765 */
3766 if ( gl_mode->modified || vid_fullscreen->modified )
3767 { // FIXME: only restart if CDS is required
3768 cvar_t *ref;
3769
3770 ref = ri.Cvar_Get ("vid_ref", "glx", 0);
3771 ref->modified = true;
3772 }
3773
3774 if ( gl_log->modified )
3775 {
3776 GLimp_EnableLogging( gl_log->value );
3777 gl_log->modified = false;
3778 }
3779
3780 if ( gl_log->value )
3781 {
3782 GLimp_LogNewFrame();
3783 }
3784
3785 /*
3786 ** update 3Dfx gamma -- it is expected that a user will do a vid_restart
3787 ** after tweaking this value
3788 */
3789 if ( vid_gamma->modified )
3790 {
3791 vid_gamma->modified = false;
3792
3793 #ifdef _WIN32
3794 if (gl_state.gammaramp)
3795 UpdateGammaRamp();
3796 #else
3797 if ( gl_state.hwgamma )
3798 UpdateHardwareGamma();
3799 #endif
3800 else if ( gl_config.renderer & ( GL_RENDERER_VOODOO ) )
3801 {
3802 char envbuffer[1024];
3803 float g;
3804
3805 g = 2.00 * ( 0.8 - ( vid_gamma->value - 0.5 ) ) + 1.0F;
3806 Com_sprintf( envbuffer, sizeof(envbuffer), "SSTV2_GAMMA=%f", g );
3807 putenv( envbuffer );
3808 Com_sprintf( envbuffer, sizeof(envbuffer), "SST_GAMMA=%f", g );
3809 putenv( envbuffer );
3810 }
3811 }
3812
3813 if (gl_particle_lighting->modified)
3814 {
3815 gl_particle_lighting->modified = false;
3816 if (gl_particle_lighting->value<0)
3817 gl_particle_lighting->value=0;
3818 if (gl_particle_lighting->value>1)
3819 gl_particle_lighting->value=1;
3820 }
3821
3822 GLimp_BeginFrame( camera_separation );
3823
3824 /*
3825 ** go into 2D mode
3826 */
3827 qglViewport (0,0, vid.width, vid.height);
3828 qglMatrixMode(GL_PROJECTION);
3829 qglLoadIdentity ();
3830 qglOrtho (0, vid.width, vid.height, 0, -99999, 99999);
3831 qglMatrixMode(GL_MODELVIEW);
3832 qglLoadIdentity ();
3833 qglDisable (GL_DEPTH_TEST);
3834 qglDisable (GL_CULL_FACE);
3835 GLSTATE_DISABLE_BLEND
3836 GLSTATE_ENABLE_ALPHATEST
3837 qglColor4f (1,1,1,1);
3838
3839 /*
3840 ** draw buffer stuff
3841 */
3842 if ( gl_drawbuffer->modified )
3843 {
3844 gl_drawbuffer->modified = false;
3845
3846 if ( gl_state.camera_separation == 0 || !gl_state.stereo_enabled )
3847 {
3848 if ( Q_stricmp( gl_drawbuffer->string, "GL_FRONT" ) == 0 )
3849 qglDrawBuffer( GL_FRONT );
3850 else
3851 qglDrawBuffer( GL_BACK );
3852 }
3853 }
3854
3855 /*
3856 ** texturemode stuff
3857 */
3858 if ( gl_texturemode->modified )
3859 {
3860 GL_TextureMode( gl_texturemode->string );
3861 gl_texturemode->modified = false;
3862 }
3863
3864 if ( gl_texturealphamode->modified )
3865 {
3866 GL_TextureAlphaMode( gl_texturealphamode->string );
3867 gl_texturealphamode->modified = false;
3868 }
3869
3870 if ( gl_texturesolidmode->modified )
3871 {
3872 GL_TextureSolidMode( gl_texturesolidmode->string );
3873 gl_texturesolidmode->modified = false;
3874 }
3875
3876 /*
3877 ** swapinterval stuff
3878 */
3879 GL_UpdateSwapInterval();
3880
3881 //
3882 // clear screen if desired
3883 //
3884 R_Clear ();
3885 }
3886
3887 /*
3888 =============
3889 R_SetPalette
3890 =============
3891 */
3892 unsigned r_rawpalette[256];
3893
R_SetPalette(const unsigned char * palette)3894 void R_SetPalette ( const unsigned char *palette)
3895 {
3896 int i;
3897
3898 byte *rp = ( byte * ) r_rawpalette;
3899
3900 if ( palette )
3901 {
3902 for ( i = 0; i < 256; i++ )
3903 {
3904 rp[i*4+0] = palette[i*3+0];
3905 rp[i*4+1] = palette[i*3+1];
3906 rp[i*4+2] = palette[i*3+2];
3907 rp[i*4+3] = 0xff;
3908 }
3909 }
3910 else
3911 {
3912 for ( i = 0; i < 256; i++ )
3913 {
3914 rp[i*4+0] = d_8to24table[i] & 0xff;
3915 rp[i*4+1] = ( d_8to24table[i] >> 8 ) & 0xff;
3916 rp[i*4+2] = ( d_8to24table[i] >> 16 ) & 0xff;
3917 rp[i*4+3] = 0xff;
3918 }
3919 }
3920 // GL_SetTexturePalette( r_rawpalette );
3921
3922 qglClearColor (0,0,0,0);
3923 qglClear (GL_COLOR_BUFFER_BIT);
3924 qglClearColor (1,0, 0.5 , 0.5);
3925
3926 }
3927
3928 /*
3929 ** R_DrawBeam
3930 */
3931 void R_RenderBeam( vec3_t start, vec3_t end, float size, float red, float green, float blue, float alpha );
3932
R_DrawBeam(entity_t * e)3933 void R_DrawBeam( entity_t *e )
3934 {
3935
3936 R_RenderBeam( e->origin, e->oldorigin, e->frame,
3937 ( d_8to24table[e->skinnum & 0xFF] ) & 0xFF,
3938 ( d_8to24table[e->skinnum & 0xFF] >> 8 ) & 0xFF,
3939 ( d_8to24table[e->skinnum & 0xFF] >> 16 ) & 0xFF,
3940 e->alpha*254 );
3941
3942 //OLD BEAM RENDERING CODE ...
3943 /*
3944 #define NUM_BEAM_SEGS 12
3945
3946 int i;
3947 float r, g, b;
3948
3949 vec3_t perpvec;
3950 vec3_t direction, normalized_direction;
3951 vec3_t start_points[NUM_BEAM_SEGS], end_points[NUM_BEAM_SEGS];
3952 vec3_t oldorigin, origin;
3953
3954 oldorigin[0] = e->oldorigin[0];
3955 oldorigin[1] = e->oldorigin[1];
3956 oldorigin[2] = e->oldorigin[2];
3957
3958 origin[0] = e->origin[0];
3959 origin[1] = e->origin[1];
3960 origin[2] = e->origin[2];
3961
3962 normalized_direction[0] = direction[0] = oldorigin[0] - origin[0];
3963 normalized_direction[1] = direction[1] = oldorigin[1] - origin[1];
3964 normalized_direction[2] = direction[2] = oldorigin[2] - origin[2];
3965
3966 if ( VectorNormalize( normalized_direction ) == 0 )
3967 return;
3968
3969 PerpendicularVector( perpvec, normalized_direction );
3970 VectorScale( perpvec, e->frame / 2, perpvec );
3971
3972 for ( i = 0; i < NUM_BEAM_SEGS; i++ )
3973 {
3974 RotatePointAroundVector( start_points[i], normalized_direction, perpvec, (360.0/NUM_BEAM_SEGS)*i );
3975 VectorAdd( start_points[i], origin, start_points[i] );
3976 VectorAdd( start_points[i], direction, end_points[i] );
3977 }
3978
3979 qglDisable( GL_TEXTURE_2D );
3980 GLSTATE_ENABLE_BLEND
3981 qglDepthMask( GL_FALSE );
3982
3983 r = ( d_8to24table[e->skinnum & 0xFF] ) & 0xFF;
3984 g = ( d_8to24table[e->skinnum & 0xFF] >> 8 ) & 0xFF;
3985 b = ( d_8to24table[e->skinnum & 0xFF] >> 16 ) & 0xFF;
3986
3987 r *= DIV255;
3988 g *= DIV255;
3989 b *= DIV255;
3990
3991 qglColor4f( r, g, b, e->alpha );
3992
3993 qglBegin( GL_TRIANGLE_STRIP );
3994 for ( i = 0; i < NUM_BEAM_SEGS; i++ )
3995 {
3996 qglVertex3fv( start_points[i] );
3997 qglVertex3fv( end_points[i] );
3998 qglVertex3fv( start_points[(i+1)%NUM_BEAM_SEGS] );
3999 qglVertex3fv( end_points[(i+1)%NUM_BEAM_SEGS] );
4000 }
4001 qglEnd();
4002
4003 qglEnable( GL_TEXTURE_2D );
4004 GLSTATE_DISABLE_BLEND
4005 qglDepthMask( GL_TRUE );
4006 */
4007 }
4008
4009
R_RenderBeam(vec3_t start,vec3_t end,float size,float red,float green,float blue,float alpha)4010 void R_RenderBeam( vec3_t start, vec3_t end, float size, float red, float green, float blue, float alpha )
4011 {
4012 particle_t beam;
4013 vec3_t up = {vup[0] * 0.75f, vup[1] * 0.75f, vup[2] * 0.75f};
4014 vec3_t right = {vright[0] * 0.75f, vright[1] * 0.75f, vright[2] * 0.75f};
4015
4016 VectorAdd (up, right, particle_coord[0]);
4017 VectorSubtract (right, up, particle_coord[1]);
4018 VectorNegate (particle_coord[0], particle_coord[2]);
4019 VectorNegate (particle_coord[1], particle_coord[3]);
4020
4021 qglEnable (GL_TEXTURE_2D);
4022 GL_TexEnv( GL_MODULATE );
4023 qglDepthMask (false);
4024 GLSTATE_ENABLE_BLEND
4025 GL_ShadeModel (GL_SMOOTH);
4026 GLSTATE_DISABLE_ALPHATEST
4027 ParticleOverbright = false;
4028
4029 beam.alpha = alpha*DIV255*2.5;
4030 beam.blendfunc_src = GL_SRC_ALPHA;
4031 beam.blendfunc_dst = GL_ONE;
4032 beam.blue = blue*255;
4033 beam.red = red*255;
4034 beam.green = green*255;
4035 beam.decal = NULL;
4036 beam.flags = PART_BEAM;
4037 beam.image = 0;
4038 VectorCopy(start, beam.angle);
4039 VectorCopy(end, beam.origin);
4040 beam.size = size*2;
4041
4042 renderParticle (&beam);
4043
4044 qglDepthRange (gldepthmin, gldepthmax);
4045 GL_BlendFunction (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
4046 GL_TexEnv( GL_MODULATE );
4047 qglDepthMask (true);
4048 GLSTATE_DISABLE_BLEND
4049 qglColor4f (1,1,1,1);
4050 }
4051
4052 /*
4053 void R_RenderBeam( vec3_t start, vec3_t end, float size, float red, float green, float blue, float alpha )
4054 {
4055 float len;
4056 vec3_t coord[4], ang_up, ang_right, vdelta;
4057 particle_t beam;
4058
4059 GL_TexEnv( GL_MODULATE );
4060
4061 qglDepthMask (false);
4062 GL_BlendFunction (GL_SRC_ALPHA, GL_ONE);
4063 GLSTATE_ENABLE_BLEND
4064 GL_ShadeModel (GL_SMOOTH);
4065 GL_Bind(r_particlebeam->texnum);
4066 qglColor4ub(red, green, blue, alpha);
4067
4068 VectorSubtract(start, end, ang_up);
4069 len = VectorNormalize(ang_up);
4070
4071 VectorSubtract(r_newrefdef.vieworg, start, vdelta);
4072 CrossProduct(ang_up, vdelta, ang_right);
4073 if(!VectorCompare(ang_right, vec3_origin))
4074 VectorNormalize(ang_right);
4075
4076 VectorScale (ang_right, size*3.0, ang_right);
4077
4078 VectorAdd(start, ang_right, coord[0]);
4079 VectorAdd(end, ang_right, coord[1]);
4080 VectorSubtract(end, ang_right, coord[2]);
4081 VectorSubtract(start, ang_right, coord[3]);
4082
4083 qglPushMatrix();
4084 {
4085 qglBegin (GL_QUADS);
4086 {
4087 qglTexCoord2f (0, 1);
4088 qglVertex3fv (coord[0]);
4089 qglTexCoord2f (0, 0);
4090 qglVertex3fv (coord[1]);
4091 qglTexCoord2f (1, 0);
4092 qglVertex3fv (coord[2]);
4093 qglTexCoord2f (1, 1);
4094 qglVertex3fv (coord[3]);
4095 }
4096 qglEnd ();
4097 }
4098 qglPopMatrix ();
4099
4100 GL_BlendFunction (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
4101 GL_TexEnv( GL_MODULATE );
4102 qglDepthMask (true);
4103 GLSTATE_DISABLE_BLEND
4104 qglColor4f (1,1,1,1);
4105 }
4106 */
4107 //===================================================================
4108
4109
4110 void R_BeginRegistration (char *map);
4111 struct model_s *R_RegisterModel (char *name);
4112 struct image_s *R_RegisterSkin (char *name);
4113 void R_SetSky (char *name, float rotate, vec3_t axis);
4114 void R_EndRegistration (void);
4115
4116 void R_RenderFrame (refdef_t *fd);
4117
4118 struct image_s *Draw_FindPic (char *name);
4119
4120 void Draw_ScaledPic (int x, int y, float scale, char *pic);
4121 void Draw_Pic (int x, int y, char *name);
4122 void Draw_Char (float x, float y, int num, int alpha);
4123 void Draw_ScaledChar (float x, float y, int num, float scale,
4124 int red, int green, int blue, int alpha, qboolean italic);
4125 void Draw_TileClear (int x, int y, int w, int h, char *name);
4126 void Draw_Fill (int x, int y, int w, int h, int c);
4127 void Draw_FadeBox (int x, int y, int w, int h, float r, float g, float b, float alpha);
4128
4129 float CharMapScale (void);
4130 void SetParticlePicture (int num, char *name);
4131 int Mod_MarkFragments (const vec3_t origin, vec3_t axis[3], float radius, int maxPoints, vec3_t *points, vec2_t *tcoords, int maxFragments, markFragment_t *fragments);
4132
4133 /*
4134 @@@@@@@@@@@@@@@@@@@@@
4135 GetRefAPI
4136
4137 @@@@@@@@@@@@@@@@@@@@@
4138 */
GetRefAPI(refimport_t rimp)4139 refexport_t GetRefAPI (refimport_t rimp )
4140 {
4141 refexport_t re;
4142
4143 ri = rimp;
4144
4145 re.api_version = API_VERSION;
4146
4147 re.BeginRegistration = R_BeginRegistration;
4148 re.RegisterModel = R_RegisterModel;
4149 re.RegisterSkin = R_RegisterSkin;
4150 re.RegisterPic = Draw_FindPic;
4151 re.SetSky = R_SetSky;
4152 re.EndRegistration = R_EndRegistration;
4153
4154 re.RenderFrame = R_RenderFrame;
4155
4156 re.SetParticlePicture = SetParticlePicture;
4157
4158 re.DrawGetPicSize = Draw_GetPicSize;
4159 re.DrawScaledPic = Draw_ScaledPic;
4160 re.DrawPic = Draw_Pic;
4161 re.DrawStretchPic = Draw_StretchPic;
4162 re.DrawScaledChar = Draw_ScaledChar;
4163 re.DrawChar = Draw_Char;
4164 re.DrawTileClear = Draw_TileClear;
4165 re.DrawFill = Draw_Fill;
4166 re.DrawFadeBox= Draw_FadeBox;
4167 re.CharMap_Scale = CharMapScale;
4168
4169 re.DrawStretchRaw = Draw_StretchRaw;
4170
4171 re.MarkFragments = Mod_MarkFragments;
4172
4173 re.Init = R_Init;
4174 re.Shutdown = R_Shutdown;
4175
4176 re.CinematicSetPalette = R_SetPalette;
4177 re.BeginFrame = R_BeginFrame;
4178 re.EndFrame = GLimp_EndFrame;
4179
4180 re.AppActivate = GLimp_AppActivate;
4181
4182 Swap_Init ();
4183
4184 return re;
4185 }
4186
4187
4188 #ifndef REF_HARD_LINKED
4189 // this is only here so the functions in q_shared.c and q_shwin.c can link
Sys_Error(char * error,...)4190 void Sys_Error (char *error, ...)
4191 {
4192 va_list argptr;
4193 char text[1024];
4194
4195 va_start (argptr, error);
4196 vsprintf (text, error, argptr);
4197 va_end (argptr);
4198
4199 ri.Sys_Error (ERR_FATAL, "%s", text);
4200 }
4201
Com_Printf(char * fmt,...)4202 void Com_Printf (char *fmt, ...)
4203 {
4204 va_list argptr;
4205 char text[1024];
4206
4207 va_start (argptr, fmt);
4208 vsprintf (text, fmt, argptr);
4209 va_end (argptr);
4210
4211 ri.Con_Printf (PRINT_ALL, "%s", text);
4212 }
4213
4214 #endif
4215