2 Copyright (C) 1996-1997 Id Software, Inc.
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.
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.
13 See the GNU General Public License for more details.
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.
25 // used for dlight push checking and other things
28 // used for visibility checking
29 qbyte r_pvsbits[(MAX_MAP_LEAFS+7)>>3];
33 matrix4x4_t r_identitymatrix;
35 int c_alias_polys, c_light_polys, c_faces, c_nodes, c_leafs, c_models, c_bmodels, c_sprites, c_particles, c_dlights;
37 // true during envmap command capture
42 // forces all rendering to draw triangle outlines
57 matrix4x4_t r_view_matrix;
64 // 8.8 fraction of base light value
65 unsigned short d_lightstylevalue[256];
67 cvar_t r_showtris = {0, "r_showtris", "0"};
68 cvar_t r_drawentities = {0, "r_drawentities","1"};
69 cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1"};
70 cvar_t r_speeds = {0, "r_speeds","0"};
71 cvar_t r_fullbright = {0, "r_fullbright","0"};
72 cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1"};
73 cvar_t r_dynamic = {CVAR_SAVE, "r_dynamic","1"};
74 cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1"};
75 cvar_t r_drawcollisionbrushes = {0, "r_drawcollisionbrushes", "0"};
77 cvar_t gl_fogenable = {0, "gl_fogenable", "0"};
78 cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25"};
79 cvar_t gl_fogred = {0, "gl_fogred","0.3"};
80 cvar_t gl_foggreen = {0, "gl_foggreen","0.3"};
81 cvar_t gl_fogblue = {0, "gl_fogblue","0.3"};
82 cvar_t gl_fogstart = {0, "gl_fogstart", "0"};
83 cvar_t gl_fogend = {0, "gl_fogend","0"};
85 cvar_t r_textureunits = {0, "r_textureunits", "32"};
87 cvar_t r_lerpsprites = {CVAR_SAVE, "r_lerpsprites", "1"};
88 cvar_t r_lerpmodels = {CVAR_SAVE, "r_lerpmodels", "1"};
89 cvar_t r_waterscroll = {CVAR_SAVE, "r_waterscroll", "1"};
90 cvar_t r_watershader = {CVAR_SAVE, "r_watershader", "1"};
93 void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
96 for (i = 0;i < verts;i++)
107 void R_FillColors(float *out, int verts, float r, float g, float b, float a)
110 for (i = 0;i < verts;i++)
124 For program optimization
127 qboolean intimerefresh = 0;
128 static void R_TimeRefresh_f (void)
131 float timestart, timedelta, oldangles[3];
134 VectorCopy(cl.viewangles, oldangles);
135 VectorClear(cl.viewangles);
137 timestart = Sys_DoubleTime();
138 for (i = 0;i < 128;i++)
140 Matrix4x4_CreateFromQuakeEntity(&r_refdef.viewentitymatrix, r_vieworigin[0], r_vieworigin[1], r_vieworigin[2], 0, i / 128.0 * 360.0, 0, 1);
143 timedelta = Sys_DoubleTime() - timestart;
145 VectorCopy(oldangles, cl.viewangles);
147 Con_Printf("%f seconds (%f fps)\n", timedelta, 128/timedelta);
152 float fog_density, fog_red, fog_green, fog_blue;
154 qboolean oldgl_fogenable;
155 void R_UpdateFog(void)
157 if (gamemode == GAME_NEHAHRA)
159 if (gl_fogenable.integer)
161 oldgl_fogenable = true;
162 fog_density = gl_fogdensity.value;
163 fog_red = gl_fogred.value;
164 fog_green = gl_foggreen.value;
165 fog_blue = gl_fogblue.value;
167 else if (oldgl_fogenable)
169 oldgl_fogenable = false;
178 fogcolor[0] = fog_red = bound(0.0f, fog_red , 1.0f);
179 fogcolor[1] = fog_green = bound(0.0f, fog_green, 1.0f);
180 fogcolor[2] = fog_blue = bound(0.0f, fog_blue , 1.0f);
185 fogdensity = -4000.0f / (fog_density * fog_density);
186 // fog color was already set
192 // FIXME: move this to client?
195 if (gamemode == GAME_NEHAHRA)
197 Cvar_Set("gl_fogenable", "0");
198 Cvar_Set("gl_fogdensity", "0.2");
199 Cvar_Set("gl_fogred", "0.3");
200 Cvar_Set("gl_foggreen", "0.3");
201 Cvar_Set("gl_fogblue", "0.3");
203 fog_density = fog_red = fog_green = fog_blue = 0.0f;
206 // FIXME: move this to client?
207 void FOG_registercvars(void)
209 if (gamemode == GAME_NEHAHRA)
211 Cvar_RegisterVariable (&gl_fogenable);
212 Cvar_RegisterVariable (&gl_fogdensity);
213 Cvar_RegisterVariable (&gl_fogred);
214 Cvar_RegisterVariable (&gl_foggreen);
215 Cvar_RegisterVariable (&gl_fogblue);
216 Cvar_RegisterVariable (&gl_fogstart);
217 Cvar_RegisterVariable (&gl_fogend);
221 void gl_main_start(void)
225 void gl_main_shutdown(void)
229 extern void CL_ParseEntityLump(char *entitystring);
230 void gl_main_newmap(void)
233 char *entities, entname[MAX_QPATH];
237 strcpy(entname, cl.worldmodel->name);
238 l = strlen(entname) - 4;
239 if (l >= 0 && !strcmp(entname + l, ".bsp"))
241 strcpy(entname + l, ".ent");
242 if ((entities = FS_LoadFile(entname, true)))
244 CL_ParseEntityLump(entities);
249 if (cl.worldmodel->brush.entities)
250 CL_ParseEntityLump(cl.worldmodel->brush.entities);
254 void GL_Main_Init(void)
256 Matrix4x4_CreateIdentity(&r_identitymatrix);
257 // FIXME: move this to client?
259 Cmd_AddCommand("timerefresh", R_TimeRefresh_f);
260 Cvar_RegisterVariable(&r_showtris);
261 Cvar_RegisterVariable(&r_drawentities);
262 Cvar_RegisterVariable(&r_drawviewmodel);
263 Cvar_RegisterVariable(&r_speeds);
264 Cvar_RegisterVariable(&r_fullbrights);
265 Cvar_RegisterVariable(&r_wateralpha);
266 Cvar_RegisterVariable(&r_dynamic);
267 Cvar_RegisterVariable(&r_fullbright);
268 Cvar_RegisterVariable(&r_textureunits);
269 Cvar_RegisterVariable(&r_lerpsprites);
270 Cvar_RegisterVariable(&r_lerpmodels);
271 Cvar_RegisterVariable(&r_waterscroll);
272 Cvar_RegisterVariable(&r_watershader);
273 Cvar_RegisterVariable(&r_drawcollisionbrushes);
274 if (gamemode == GAME_NEHAHRA || gamemode == GAME_NEXUIZ || gamemode == GAME_TENEBRAE)
275 Cvar_SetValue("r_fullbrights", 0);
276 R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap);
279 static vec3_t r_farclip_origin;
280 static vec3_t r_farclip_direction;
281 static vec_t r_farclip_directiondist;
282 static vec_t r_farclip_meshfarclip;
283 static int r_farclip_directionbit0;
284 static int r_farclip_directionbit1;
285 static int r_farclip_directionbit2;
287 // enlarge farclip to accomodate box
288 static void R_FarClip_Box(vec3_t mins, vec3_t maxs)
291 d = (r_farclip_directionbit0 ? mins[0] : maxs[0]) * r_farclip_direction[0]
292 + (r_farclip_directionbit1 ? mins[1] : maxs[1]) * r_farclip_direction[1]
293 + (r_farclip_directionbit2 ? mins[2] : maxs[2]) * r_farclip_direction[2];
294 if (r_farclip_meshfarclip < d)
295 r_farclip_meshfarclip = d;
298 // return farclip value
299 static float R_FarClip(vec3_t origin, vec3_t direction, vec_t startfarclip)
303 VectorCopy(origin, r_farclip_origin);
304 VectorCopy(direction, r_farclip_direction);
305 r_farclip_directiondist = DotProduct(r_farclip_origin, r_farclip_direction);
306 r_farclip_directionbit0 = r_farclip_direction[0] < 0;
307 r_farclip_directionbit1 = r_farclip_direction[1] < 0;
308 r_farclip_directionbit2 = r_farclip_direction[2] < 0;
309 r_farclip_meshfarclip = r_farclip_directiondist + startfarclip;
312 R_FarClip_Box(cl.worldmodel->normalmins, cl.worldmodel->normalmaxs);
313 for (i = 0;i < r_refdef.numentities;i++)
314 R_FarClip_Box(r_refdef.entities[i]->mins, r_refdef.entities[i]->maxs);
316 return r_farclip_meshfarclip - r_farclip_directiondist;
319 extern void R_Textures_Init(void);
320 extern void Mod_RenderInit(void);
321 extern void GL_Draw_Init(void);
322 extern void GL_Main_Init(void);
323 extern void R_Shadow_Init(void);
324 extern void GL_Models_Init(void);
325 extern void R_Sky_Init(void);
326 extern void GL_Surf_Init(void);
327 extern void R_Crosshairs_Init(void);
328 extern void R_Light_Init(void);
329 extern void R_Particles_Init(void);
330 extern void R_Explosion_Init(void);
331 extern void ui_init(void);
332 extern void gl_backend_init(void);
333 extern void Sbar_Init(void);
334 extern void R_LightningBeams_Init(void);
336 void Render_Init(void)
355 R_LightningBeams_Init();
363 extern char *ENGINE_EXTENSIONS;
366 VID_CheckExtensions();
368 // LordHavoc: report supported extensions
369 Con_DPrintf("\nengine extensions: %s\n", ENGINE_EXTENSIONS);
372 int R_CullBox(const vec3_t mins, const vec3_t maxs)
376 for (i = 0;i < 4;i++)
383 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
387 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
391 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
395 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
399 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
403 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
407 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
411 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
419 //==================================================================================
421 static void R_MarkEntities (void)
424 entity_render_t *ent;
426 ent = &cl_entities[0].render;
427 Matrix4x4_CreateIdentity(&ent->matrix);
428 Matrix4x4_CreateIdentity(&ent->inversematrix);
430 if (!r_drawentities.integer)
433 for (i = 0;i < r_refdef.numentities;i++)
435 ent = r_refdef.entities[i];
436 Mod_CheckLoaded(ent->model);
437 // some of the renderer still relies on origin...
438 Matrix4x4_OriginFromMatrix(&ent->matrix, ent->origin);
439 // some of the renderer still relies on scale...
440 ent->scale = Matrix4x4_ScaleFromMatrix(&ent->matrix);
441 R_LerpAnimation(ent);
442 R_UpdateEntLights(ent);
443 if ((chase_active.integer || !(ent->flags & RENDER_EXTERIORMODEL))
444 && !VIS_CullBox(ent->mins, ent->maxs)
445 && (!envmap || !(ent->flags & (RENDER_VIEWMODEL | RENDER_EXTERIORMODEL))))
446 ent->visframe = r_framecount;
450 // only used if skyrendermasked, and normally returns false
451 int R_DrawBrushModelsSky (void)
454 entity_render_t *ent;
456 if (!r_drawentities.integer)
460 for (i = 0;i < r_refdef.numentities;i++)
462 ent = r_refdef.entities[i];
463 if (ent->visframe == r_framecount && ent->model && ent->model->DrawSky)
465 ent->model->DrawSky(ent);
478 void R_DrawViewModel (void)
480 entity_render_t *ent;
482 // FIXME: move these checks to client
483 if (!r_drawviewmodel.integer || chase_active.integer || envmap || !r_drawentities.integer || cl.items & IT_INVISIBILITY || cl.stats[STAT_HEALTH] <= 0 || !cl.viewent.render.model)
486 ent = &cl.viewent.render;
487 Mod_CheckLoaded(ent->model);
488 R_LerpAnimation(ent);
489 Matrix4x4_CreateFromQuakeEntity(&ent->matrix, ent->origin[0], ent->origin[1], ent->origin[2], -ent->angles[0], ent->angles[1], ent->angles[2], ent->scale);
490 Matrix4x4_Invert_Simple(&ent->inversematrix, &ent->matrix);
491 R_UpdateEntLights(ent);
492 ent->model->Draw(ent);
496 void R_DrawNoModel(entity_render_t *ent);
497 void R_DrawModels(void)
500 entity_render_t *ent;
502 if (!r_drawentities.integer)
505 for (i = 0;i < r_refdef.numentities;i++)
507 ent = r_refdef.entities[i];
508 if (ent->visframe == r_framecount)
510 if (ent->model && ent->model->Draw != NULL)
511 ent->model->Draw(ent);
518 static void R_SetFrustum(void)
520 // break apart the view matrix into vectors for various purposes
521 Matrix4x4_ToVectors(&r_view_matrix, r_viewforward, r_viewleft, r_viewup, r_vieworigin);
522 VectorNegate(r_viewleft, r_viewright);
524 // LordHavoc: note to all quake engine coders, the special case for 90
525 // degrees assumed a square view (wrong), so I removed it, Quake2 has it
528 // rotate R_VIEWFORWARD right by FOV_X/2 degrees
529 RotatePointAroundVector( frustum[0].normal, r_viewup, r_viewforward, -(90 - r_view_fov_x / 2));
530 frustum[0].dist = DotProduct (r_vieworigin, frustum[0].normal);
531 PlaneClassify(&frustum[0]);
533 // rotate R_VIEWFORWARD left by FOV_X/2 degrees
534 RotatePointAroundVector( frustum[1].normal, r_viewup, r_viewforward, (90 - r_view_fov_x / 2));
535 frustum[1].dist = DotProduct (r_vieworigin, frustum[1].normal);
536 PlaneClassify(&frustum[1]);
538 // rotate R_VIEWFORWARD up by FOV_X/2 degrees
539 RotatePointAroundVector( frustum[2].normal, r_viewleft, r_viewforward, -(90 - r_view_fov_y / 2));
540 frustum[2].dist = DotProduct (r_vieworigin, frustum[2].normal);
541 PlaneClassify(&frustum[2]);
543 // rotate R_VIEWFORWARD down by FOV_X/2 degrees
544 RotatePointAroundVector( frustum[3].normal, r_viewleft, r_viewforward, (90 - r_view_fov_y / 2));
545 frustum[3].dist = DotProduct (r_vieworigin, frustum[3].normal);
546 PlaneClassify(&frustum[3]);
549 static void R_BlendView(void)
555 if (r_refdef.viewblend[3] < 0.01f)
558 R_Mesh_Matrix(&r_identitymatrix);
560 memset(&m, 0, sizeof(m));
561 R_Mesh_State_Texture(&m);
563 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
565 GL_DepthTest(false); // magic
566 GL_VertexPointer(vertex3f);
567 GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
569 vertex3f[0] = r_vieworigin[0] + r_viewforward[0] * 1.5 + r_viewleft[0] * r - r_viewup[0] * r;
570 vertex3f[1] = r_vieworigin[1] + r_viewforward[1] * 1.5 + r_viewleft[1] * r - r_viewup[1] * r;
571 vertex3f[2] = r_vieworigin[2] + r_viewforward[2] * 1.5 + r_viewleft[2] * r - r_viewup[2] * r;
572 vertex3f[3] = r_vieworigin[0] + r_viewforward[0] * 1.5 + r_viewleft[0] * r + r_viewup[0] * r * 3;
573 vertex3f[4] = r_vieworigin[1] + r_viewforward[1] * 1.5 + r_viewleft[1] * r + r_viewup[1] * r * 3;
574 vertex3f[5] = r_vieworigin[2] + r_viewforward[2] * 1.5 + r_viewleft[2] * r + r_viewup[2] * r * 3;
575 vertex3f[6] = r_vieworigin[0] + r_viewforward[0] * 1.5 - r_viewleft[0] * r * 3 - r_viewup[0] * r;
576 vertex3f[7] = r_vieworigin[1] + r_viewforward[1] * 1.5 - r_viewleft[1] * r * 3 - r_viewup[1] * r;
577 vertex3f[8] = r_vieworigin[2] + r_viewforward[2] * 1.5 - r_viewleft[2] * r * 3 - r_viewup[2] * r;
578 R_Mesh_Draw(3, 1, polygonelements);
581 void R_UpdateWorld(void)
583 if (!r_refdef.entities/* || !cl.worldmodel*/)
584 return; //Host_Error ("R_RenderView: NULL worldmodel");
586 if (r_shadow_realtime_world.integer && !gl_stencil)
588 Con_Print("Realtime world lighting requires 32bit color; turning off r_shadow_realtime_world, please type vid_bitsperpixel 32;vid_restart and try again\n");
589 Cvar_SetValueQuick(&r_shadow_realtime_world, 0);
592 // don't allow cheats in multiplayer
595 if (r_fullbright.integer != 0)
596 Cvar_Set ("r_fullbright", "0");
597 if (r_ambient.value != 0)
598 Cvar_Set ("r_ambient", "0");
606 void R_RenderScene(void);
613 void R_RenderView(void)
615 if (!r_refdef.entities/* || !cl.worldmodel*/)
616 return; //Host_Error ("R_RenderView: NULL worldmodel");
618 r_view_width = bound(0, r_refdef.width, vid.realwidth);
619 r_view_height = bound(0, r_refdef.height, vid.realheight);
620 r_view_x = bound(0, r_refdef.x, vid.realwidth - r_refdef.width);
621 r_view_y = bound(0, r_refdef.y, vid.realheight - r_refdef.height);
622 r_view_fov_x = bound(1, r_refdef.fov_x, 170);
623 r_view_fov_y = bound(1, r_refdef.fov_y, 170);
624 r_view_matrix = r_refdef.viewentitymatrix;
626 // GL is weird because it's bottom to top, r_view_y is top to bottom
627 qglViewport(r_view_x, vid.realheight - (r_view_y + r_view_height), r_view_width, r_view_height);
628 GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height);
629 GL_ScissorTest(true);
631 R_TimeReport("setup");
633 qglDepthFunc(GL_LEQUAL);
634 qglPolygonOffset(0, 0);
635 qglEnable(GL_POLYGON_OFFSET_FILL);
639 qglPolygonOffset(0, 0);
640 qglDisable(GL_POLYGON_OFFSET_FILL);
643 R_TimeReport("blendview");
645 GL_Scissor(0, 0, vid.realwidth, vid.realheight);
646 GL_ScissorTest(false);
649 extern void R_DrawLightningBeams (void);
650 void R_RenderScene(void)
652 entity_render_t *world;
654 // don't let sound skip if going slow
655 if (!intimerefresh && !r_speeds.integer)
660 GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
664 r_farclip = R_FarClip(r_vieworigin, r_viewforward, 768.0f) + 256.0f;
665 if (gl_stencil && ((r_shadow_realtime_world.integer && r_shadow_worldshadows.integer) || ((r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && r_shadow_dlightshadows.integer)))
666 GL_SetupView_Mode_PerspectiveInfiniteFarClip(r_view_fov_x, r_view_fov_y, 1.0f);
668 GL_SetupView_Mode_Perspective(r_view_fov_x, r_view_fov_y, 1.0f, r_farclip);
670 GL_SetupView_Orientation_FromEntity(&r_view_matrix);
674 if (cl.worldmodel && cl.worldmodel->brush.FatPVS)
675 cl.worldmodel->brush.FatPVS(cl.worldmodel, r_vieworigin, 2, r_pvsbits, sizeof(r_pvsbits));
676 world = &cl_entities[0].render;
677 R_WorldVisibility(world);
678 R_TimeReport("worldvis");
681 R_TimeReport("markentity");
683 R_MeshQueue_BeginScene();
685 R_Shadow_UpdateWorldLightSelection();
687 // don't let sound skip if going slow
688 if (!intimerefresh && !r_speeds.integer)
691 if (R_DrawBrushModelsSky())
692 R_TimeReport("bmodelsky");
694 // must occur early because it can draw sky
696 R_TimeReport("world");
698 // don't let sound skip if going slow
699 if (!intimerefresh && !r_speeds.integer)
702 GL_ShowTrisColor(0, 0.015, 0, 1);
705 R_TimeReport("models");
707 // don't let sound skip if going slow
708 if (!intimerefresh && !r_speeds.integer)
711 GL_ShowTrisColor(0, 0, 0.033, 1);
712 R_ShadowVolumeLighting(false);
713 R_TimeReport("rtlights");
715 // don't let sound skip if going slow
716 if (!intimerefresh && !r_speeds.integer)
719 GL_ShowTrisColor(0.1, 0, 0, 1);
721 R_DrawLightningBeams();
722 R_TimeReport("lightning");
725 R_TimeReport("particles");
728 R_TimeReport("explosions");
730 R_MeshQueue_RenderTransparent();
731 R_TimeReport("drawtrans");
734 R_TimeReport("coronas");
736 R_DrawWorldCrosshair();
737 R_TimeReport("crosshair");
739 R_MeshQueue_Render();
740 R_MeshQueue_EndScene();
742 if (r_shadow_visiblevolumes.integer && !r_showtrispass)
744 R_ShadowVolumeLighting(true);
745 R_TimeReport("shadowvolume");
748 GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
750 // don't let sound skip if going slow
751 if (!intimerefresh && !r_speeds.integer)
756 void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, float ca)
759 float *v, *c, f1, f2, diff[3], vertex3f[8*3], color4f[8*4];
761 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
764 R_Mesh_Matrix(&r_identitymatrix);
766 memset(&m, 0, sizeof(m));
767 R_Mesh_State_Texture(&m);
770 vertex3f[ 0] = mins[0];vertex3f[ 1] = mins[1];vertex3f[ 2] = mins[2];
771 vertex3f[ 3] = maxs[0];vertex3f[ 4] = mins[1];vertex3f[ 5] = mins[2];
772 vertex3f[ 6] = mins[0];vertex3f[ 7] = maxs[1];vertex3f[ 8] = mins[2];
773 vertex3f[ 9] = maxs[0];vertex3f[10] = maxs[1];vertex3f[11] = mins[2];
774 vertex3f[12] = mins[0];vertex3f[13] = mins[1];vertex3f[14] = maxs[2];
775 vertex3f[15] = maxs[0];vertex3f[16] = mins[1];vertex3f[17] = maxs[2];
776 vertex3f[18] = mins[0];vertex3f[19] = maxs[1];vertex3f[20] = maxs[2];
777 vertex3f[21] = maxs[0];vertex3f[22] = maxs[1];vertex3f[23] = maxs[2];
778 GL_ColorPointer(color);
779 R_FillColors(color, 8, cr, cg, cb, ca);
782 for (i = 0, v = vertex, c = color;i < 8;i++, v += 4, c += 4)
784 VectorSubtract(v, r_vieworigin, diff);
785 f2 = exp(fogdensity/DotProduct(diff, diff));
787 c[0] = c[0] * f1 + fogcolor[0] * f2;
788 c[1] = c[1] * f1 + fogcolor[1] * f2;
789 c[2] = c[2] * f1 + fogcolor[2] * f2;
796 int nomodelelements[24] =
808 float nomodelvertex3f[6*3] =
818 float nomodelcolor4f[6*4] =
820 0.0f, 0.0f, 0.5f, 1.0f,
821 0.0f, 0.0f, 0.5f, 1.0f,
822 0.0f, 0.5f, 0.0f, 1.0f,
823 0.0f, 0.5f, 0.0f, 1.0f,
824 0.5f, 0.0f, 0.0f, 1.0f,
825 0.5f, 0.0f, 0.0f, 1.0f
828 void R_DrawNoModelCallback(const void *calldata1, int calldata2)
830 const entity_render_t *ent = calldata1;
832 float f1, f2, *c, diff[3];
835 R_Mesh_Matrix(&ent->matrix);
837 memset(&m, 0, sizeof(m));
838 R_Mesh_State_Texture(&m);
840 if (ent->flags & EF_ADDITIVE)
842 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
845 else if (ent->alpha < 1)
847 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
852 GL_BlendFunc(GL_ONE, GL_ZERO);
856 GL_VertexPointer(nomodelvertex3f);
859 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
860 GL_ColorPointer(color4f);
861 VectorSubtract(ent->origin, r_vieworigin, diff);
862 f2 = exp(fogdensity/DotProduct(diff, diff));
864 for (i = 0, c = color4f;i < 6;i++, c += 4)
866 c[0] = (c[0] * f1 + fogcolor[0] * f2);
867 c[1] = (c[1] * f1 + fogcolor[1] * f2);
868 c[2] = (c[2] * f1 + fogcolor[2] * f2);
872 else if (ent->alpha != 1)
874 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
875 GL_ColorPointer(color4f);
876 for (i = 0, c = color4f;i < 6;i++, c += 4)
880 GL_ColorPointer(nomodelcolor4f);
881 R_Mesh_Draw(6, 8, nomodelelements);
884 void R_DrawNoModel(entity_render_t *ent)
886 //if ((ent->effects & EF_ADDITIVE) || (ent->alpha < 1))
887 R_MeshQueue_AddTransparent(ent->origin, R_DrawNoModelCallback, ent, 0);
889 // R_DrawNoModelCallback(ent, 0);
892 void R_CalcBeam_Vertex3f (float *vert, const vec3_t org1, const vec3_t org2, float width)
894 vec3_t right1, right2, diff, normal;
896 VectorSubtract (org2, org1, normal);
897 VectorNormalizeFast (normal);
899 // calculate 'right' vector for start
900 VectorSubtract (r_vieworigin, org1, diff);
901 VectorNormalizeFast (diff);
902 CrossProduct (normal, diff, right1);
904 // calculate 'right' vector for end
905 VectorSubtract (r_vieworigin, org2, diff);
906 VectorNormalizeFast (diff);
907 CrossProduct (normal, diff, right2);
909 vert[ 0] = org1[0] + width * right1[0];
910 vert[ 1] = org1[1] + width * right1[1];
911 vert[ 2] = org1[2] + width * right1[2];
912 vert[ 3] = org1[0] - width * right1[0];
913 vert[ 4] = org1[1] - width * right1[1];
914 vert[ 5] = org1[2] - width * right1[2];
915 vert[ 6] = org2[0] - width * right2[0];
916 vert[ 7] = org2[1] - width * right2[1];
917 vert[ 8] = org2[2] - width * right2[2];
918 vert[ 9] = org2[0] + width * right2[0];
919 vert[10] = org2[1] + width * right2[1];
920 vert[11] = org2[2] + width * right2[2];
923 float spritetexcoord2f[4*2] = {0, 1, 0, 0, 1, 0, 1, 1};
925 void R_DrawSprite(int blendfunc1, int blendfunc2, rtexture_t *texture, int depthdisable, const vec3_t origin, const vec3_t left, const vec3_t up, float scalex1, float scalex2, float scaley1, float scaley2, float cr, float cg, float cb, float ca)
932 VectorSubtract(origin, r_vieworigin, diff);
933 ca *= 1 - exp(fogdensity/DotProduct(diff,diff));
936 R_Mesh_Matrix(&r_identitymatrix);
937 GL_Color(cr, cg, cb, ca);
938 GL_VertexPointer(varray_vertex3f);
939 GL_BlendFunc(blendfunc1, blendfunc2);
941 GL_DepthTest(!depthdisable);
943 memset(&m, 0, sizeof(m));
944 m.tex[0] = R_GetTexture(texture);
945 m.pointer_texcoord[0] = spritetexcoord2f;
946 R_Mesh_State_Texture(&m);
948 varray_vertex3f[ 0] = origin[0] + left[0] * scalex2 + up[0] * scaley1;
949 varray_vertex3f[ 1] = origin[1] + left[1] * scalex2 + up[1] * scaley1;
950 varray_vertex3f[ 2] = origin[2] + left[2] * scalex2 + up[2] * scaley1;
951 varray_vertex3f[ 3] = origin[0] + left[0] * scalex2 + up[0] * scaley2;
952 varray_vertex3f[ 4] = origin[1] + left[1] * scalex2 + up[1] * scaley2;
953 varray_vertex3f[ 5] = origin[2] + left[2] * scalex2 + up[2] * scaley2;
954 varray_vertex3f[ 6] = origin[0] + left[0] * scalex1 + up[0] * scaley2;
955 varray_vertex3f[ 7] = origin[1] + left[1] * scalex1 + up[1] * scaley2;
956 varray_vertex3f[ 8] = origin[2] + left[2] * scalex1 + up[2] * scaley2;
957 varray_vertex3f[ 9] = origin[0] + left[0] * scalex1 + up[0] * scaley1;
958 varray_vertex3f[10] = origin[1] + left[1] * scalex1 + up[1] * scaley1;
959 varray_vertex3f[11] = origin[2] + left[2] * scalex1 + up[2] * scaley1;
960 R_Mesh_Draw(4, 2, polygonelements);