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
40 // maximum visible distance (recalculated from world box each frame)
42 // brightness of world lightmaps and related lighting
43 // (often reduced when world rtlights are enabled)
44 float r_lightmapintensity;
45 // whether to draw world lights realtime, dlights realtime, and their shadows
47 qboolean r_rtworldshadows;
49 qboolean r_rtdlightshadows;
52 // forces all rendering to draw triangle outlines
69 matrix4x4_t r_view_matrix;
76 // 8.8 fraction of base light value
77 unsigned short d_lightstylevalue[256];
79 cvar_t r_showtris = {0, "r_showtris", "0"};
80 cvar_t r_drawentities = {0, "r_drawentities","1"};
81 cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1"};
82 cvar_t r_speeds = {0, "r_speeds","0"};
83 cvar_t r_fullbright = {0, "r_fullbright","0"};
84 cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1"};
85 cvar_t r_dynamic = {CVAR_SAVE, "r_dynamic","1"};
86 cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1"};
87 cvar_t r_drawcollisionbrushes = {0, "r_drawcollisionbrushes", "0"};
89 cvar_t gl_fogenable = {0, "gl_fogenable", "0"};
90 cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25"};
91 cvar_t gl_fogred = {0, "gl_fogred","0.3"};
92 cvar_t gl_foggreen = {0, "gl_foggreen","0.3"};
93 cvar_t gl_fogblue = {0, "gl_fogblue","0.3"};
94 cvar_t gl_fogstart = {0, "gl_fogstart", "0"};
95 cvar_t gl_fogend = {0, "gl_fogend","0"};
97 cvar_t r_textureunits = {0, "r_textureunits", "32"};
99 cvar_t r_lerpsprites = {CVAR_SAVE, "r_lerpsprites", "1"};
100 cvar_t r_lerpmodels = {CVAR_SAVE, "r_lerpmodels", "1"};
101 cvar_t r_waterscroll = {CVAR_SAVE, "r_waterscroll", "1"};
102 cvar_t r_watershader = {CVAR_SAVE, "r_watershader", "1"};
105 void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
108 for (i = 0;i < verts;i++)
119 void R_FillColors(float *out, int verts, float r, float g, float b, float a)
122 for (i = 0;i < verts;i++)
136 For program optimization
139 qboolean intimerefresh = 0;
140 static void R_TimeRefresh_f (void)
143 float timestart, timedelta, oldangles[3];
146 VectorCopy(cl.viewangles, oldangles);
147 VectorClear(cl.viewangles);
149 timestart = Sys_DoubleTime();
150 for (i = 0;i < 128;i++)
152 Matrix4x4_CreateFromQuakeEntity(&r_refdef.viewentitymatrix, r_vieworigin[0], r_vieworigin[1], r_vieworigin[2], 0, i / 128.0 * 360.0, 0, 1);
155 timedelta = Sys_DoubleTime() - timestart;
157 VectorCopy(oldangles, cl.viewangles);
159 Con_Printf("%f seconds (%f fps)\n", timedelta, 128/timedelta);
164 float fog_density, fog_red, fog_green, fog_blue;
166 qboolean oldgl_fogenable;
167 void R_UpdateFog(void)
169 if (gamemode == GAME_NEHAHRA)
171 if (gl_fogenable.integer)
173 oldgl_fogenable = true;
174 fog_density = gl_fogdensity.value;
175 fog_red = gl_fogred.value;
176 fog_green = gl_foggreen.value;
177 fog_blue = gl_fogblue.value;
179 else if (oldgl_fogenable)
181 oldgl_fogenable = false;
190 fogcolor[0] = fog_red = bound(0.0f, fog_red , 1.0f);
191 fogcolor[1] = fog_green = bound(0.0f, fog_green, 1.0f);
192 fogcolor[2] = fog_blue = bound(0.0f, fog_blue , 1.0f);
197 fogdensity = -4000.0f / (fog_density * fog_density);
198 // fog color was already set
204 // FIXME: move this to client?
207 if (gamemode == GAME_NEHAHRA)
209 Cvar_Set("gl_fogenable", "0");
210 Cvar_Set("gl_fogdensity", "0.2");
211 Cvar_Set("gl_fogred", "0.3");
212 Cvar_Set("gl_foggreen", "0.3");
213 Cvar_Set("gl_fogblue", "0.3");
215 fog_density = fog_red = fog_green = fog_blue = 0.0f;
218 // FIXME: move this to client?
219 void FOG_registercvars(void)
221 if (gamemode == GAME_NEHAHRA)
223 Cvar_RegisterVariable (&gl_fogenable);
224 Cvar_RegisterVariable (&gl_fogdensity);
225 Cvar_RegisterVariable (&gl_fogred);
226 Cvar_RegisterVariable (&gl_foggreen);
227 Cvar_RegisterVariable (&gl_fogblue);
228 Cvar_RegisterVariable (&gl_fogstart);
229 Cvar_RegisterVariable (&gl_fogend);
233 void gl_main_start(void)
237 void gl_main_shutdown(void)
241 extern void CL_ParseEntityLump(char *entitystring);
242 void gl_main_newmap(void)
245 char *entities, entname[MAX_QPATH];
249 strcpy(entname, cl.worldmodel->name);
250 l = strlen(entname) - 4;
251 if (l >= 0 && !strcmp(entname + l, ".bsp"))
253 strcpy(entname + l, ".ent");
254 if ((entities = FS_LoadFile(entname, tempmempool, true)))
256 CL_ParseEntityLump(entities);
261 if (cl.worldmodel->brush.entities)
262 CL_ParseEntityLump(cl.worldmodel->brush.entities);
266 void GL_Main_Init(void)
268 Matrix4x4_CreateIdentity(&r_identitymatrix);
269 // FIXME: move this to client?
271 Cmd_AddCommand("timerefresh", R_TimeRefresh_f);
272 Cvar_RegisterVariable(&r_showtris);
273 Cvar_RegisterVariable(&r_drawentities);
274 Cvar_RegisterVariable(&r_drawviewmodel);
275 Cvar_RegisterVariable(&r_speeds);
276 Cvar_RegisterVariable(&r_fullbrights);
277 Cvar_RegisterVariable(&r_wateralpha);
278 Cvar_RegisterVariable(&r_dynamic);
279 Cvar_RegisterVariable(&r_fullbright);
280 Cvar_RegisterVariable(&r_textureunits);
281 Cvar_RegisterVariable(&r_lerpsprites);
282 Cvar_RegisterVariable(&r_lerpmodels);
283 Cvar_RegisterVariable(&r_waterscroll);
284 Cvar_RegisterVariable(&r_watershader);
285 Cvar_RegisterVariable(&r_drawcollisionbrushes);
286 if (gamemode == GAME_NEHAHRA || gamemode == GAME_NEXUIZ || gamemode == GAME_TENEBRAE)
287 Cvar_SetValue("r_fullbrights", 0);
288 R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap);
291 static vec3_t r_farclip_origin;
292 static vec3_t r_farclip_direction;
293 static vec_t r_farclip_directiondist;
294 static vec_t r_farclip_meshfarclip;
295 static int r_farclip_directionbit0;
296 static int r_farclip_directionbit1;
297 static int r_farclip_directionbit2;
299 // enlarge farclip to accomodate box
300 static void R_FarClip_Box(vec3_t mins, vec3_t maxs)
303 d = (r_farclip_directionbit0 ? mins[0] : maxs[0]) * r_farclip_direction[0]
304 + (r_farclip_directionbit1 ? mins[1] : maxs[1]) * r_farclip_direction[1]
305 + (r_farclip_directionbit2 ? mins[2] : maxs[2]) * r_farclip_direction[2];
306 if (r_farclip_meshfarclip < d)
307 r_farclip_meshfarclip = d;
310 // return farclip value
311 static float R_FarClip(vec3_t origin, vec3_t direction, vec_t startfarclip)
315 VectorCopy(origin, r_farclip_origin);
316 VectorCopy(direction, r_farclip_direction);
317 r_farclip_directiondist = DotProduct(r_farclip_origin, r_farclip_direction);
318 r_farclip_directionbit0 = r_farclip_direction[0] < 0;
319 r_farclip_directionbit1 = r_farclip_direction[1] < 0;
320 r_farclip_directionbit2 = r_farclip_direction[2] < 0;
321 r_farclip_meshfarclip = r_farclip_directiondist + startfarclip;
324 R_FarClip_Box(cl.worldmodel->normalmins, cl.worldmodel->normalmaxs);
325 for (i = 0;i < r_refdef.numentities;i++)
326 R_FarClip_Box(r_refdef.entities[i]->mins, r_refdef.entities[i]->maxs);
328 return r_farclip_meshfarclip - r_farclip_directiondist;
331 extern void R_Textures_Init(void);
332 extern void Mod_RenderInit(void);
333 extern void GL_Draw_Init(void);
334 extern void GL_Main_Init(void);
335 extern void R_Shadow_Init(void);
336 extern void GL_Models_Init(void);
337 extern void R_Sky_Init(void);
338 extern void GL_Surf_Init(void);
339 extern void R_Crosshairs_Init(void);
340 extern void R_Light_Init(void);
341 extern void R_Particles_Init(void);
342 extern void R_Explosion_Init(void);
343 extern void ui_init(void);
344 extern void gl_backend_init(void);
345 extern void Sbar_Init(void);
346 extern void R_LightningBeams_Init(void);
348 void Render_Init(void)
367 R_LightningBeams_Init();
375 extern char *ENGINE_EXTENSIONS;
378 VID_CheckExtensions();
380 // LordHavoc: report supported extensions
381 Con_DPrintf("\nengine extensions: %s\n", ENGINE_EXTENSIONS);
383 // clear to black (loading plaque will be seen over this)
384 qglClearColor(0,0,0,1);
385 qglClear(GL_COLOR_BUFFER_BIT);
388 int R_CullBox(const vec3_t mins, const vec3_t maxs)
392 for (i = 0;i < 4;i++)
399 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
403 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
407 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
411 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
415 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
419 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
423 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
427 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
435 //==================================================================================
437 static void R_MarkEntities (void)
440 entity_render_t *ent;
442 ent = &cl_entities[0].render;
443 Matrix4x4_CreateIdentity(&ent->matrix);
444 Matrix4x4_CreateIdentity(&ent->inversematrix);
446 if (!r_drawentities.integer)
449 for (i = 0;i < r_refdef.numentities;i++)
451 ent = r_refdef.entities[i];
452 Mod_CheckLoaded(ent->model);
453 // some of the renderer still relies on origin...
454 Matrix4x4_OriginFromMatrix(&ent->matrix, ent->origin);
455 // some of the renderer still relies on scale...
456 ent->scale = Matrix4x4_ScaleFromMatrix(&ent->matrix);
457 R_UpdateEntLights(ent);
458 if ((chase_active.integer || !(ent->flags & RENDER_EXTERIORMODEL))
459 && (!VIS_CullBox(ent->mins, ent->maxs) || (ent->effects & EF_NODEPTHTEST))
460 && (!envmap || !(ent->flags & (RENDER_VIEWMODEL | RENDER_EXTERIORMODEL))))
461 ent->visframe = r_framecount;
465 // only used if skyrendermasked, and normally returns false
466 int R_DrawBrushModelsSky (void)
469 entity_render_t *ent;
471 if (!r_drawentities.integer)
475 for (i = 0;i < r_refdef.numentities;i++)
477 ent = r_refdef.entities[i];
478 if (ent->visframe == r_framecount && ent->model && ent->model->DrawSky)
480 ent->model->DrawSky(ent);
487 void R_DrawNoModel(entity_render_t *ent);
488 void R_DrawModels(void)
491 entity_render_t *ent;
493 if (!r_drawentities.integer)
496 for (i = 0;i < r_refdef.numentities;i++)
498 ent = r_refdef.entities[i];
499 if (ent->visframe == r_framecount)
501 if (ent->model && ent->model->Draw != NULL)
502 ent->model->Draw(ent);
509 static void R_SetFrustum(void)
511 // break apart the view matrix into vectors for various purposes
512 Matrix4x4_ToVectors(&r_view_matrix, r_viewforward, r_viewleft, r_viewup, r_vieworigin);
513 VectorNegate(r_viewleft, r_viewright);
515 // LordHavoc: note to all quake engine coders, the special case for 90
516 // degrees assumed a square view (wrong), so I removed it, Quake2 has it
519 // rotate R_VIEWFORWARD right by FOV_X/2 degrees
520 RotatePointAroundVector( frustum[0].normal, r_viewup, r_viewforward, -(90 - r_view_fov_x / 2));
521 frustum[0].dist = DotProduct (r_vieworigin, frustum[0].normal);
522 PlaneClassify(&frustum[0]);
524 // rotate R_VIEWFORWARD left by FOV_X/2 degrees
525 RotatePointAroundVector( frustum[1].normal, r_viewup, r_viewforward, (90 - r_view_fov_x / 2));
526 frustum[1].dist = DotProduct (r_vieworigin, frustum[1].normal);
527 PlaneClassify(&frustum[1]);
529 // rotate R_VIEWFORWARD up by FOV_X/2 degrees
530 RotatePointAroundVector( frustum[2].normal, r_viewleft, r_viewforward, -(90 - r_view_fov_y / 2));
531 frustum[2].dist = DotProduct (r_vieworigin, frustum[2].normal);
532 PlaneClassify(&frustum[2]);
534 // rotate R_VIEWFORWARD down by FOV_X/2 degrees
535 RotatePointAroundVector( frustum[3].normal, r_viewleft, r_viewforward, (90 - r_view_fov_y / 2));
536 frustum[3].dist = DotProduct (r_vieworigin, frustum[3].normal);
537 PlaneClassify(&frustum[3]);
540 static void R_BlendView(void)
546 if (r_refdef.viewblend[3] < 0.01f)
549 R_Mesh_Matrix(&r_identitymatrix);
551 memset(&m, 0, sizeof(m));
552 m.pointer_vertex = vertex3f;
555 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
557 GL_DepthTest(false); // magic
558 GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
560 vertex3f[0] = r_vieworigin[0] + r_viewforward[0] * 1.5 + r_viewleft[0] * r - r_viewup[0] * r;
561 vertex3f[1] = r_vieworigin[1] + r_viewforward[1] * 1.5 + r_viewleft[1] * r - r_viewup[1] * r;
562 vertex3f[2] = r_vieworigin[2] + r_viewforward[2] * 1.5 + r_viewleft[2] * r - r_viewup[2] * r;
563 vertex3f[3] = r_vieworigin[0] + r_viewforward[0] * 1.5 + r_viewleft[0] * r + r_viewup[0] * r * 3;
564 vertex3f[4] = r_vieworigin[1] + r_viewforward[1] * 1.5 + r_viewleft[1] * r + r_viewup[1] * r * 3;
565 vertex3f[5] = r_vieworigin[2] + r_viewforward[2] * 1.5 + r_viewleft[2] * r + r_viewup[2] * r * 3;
566 vertex3f[6] = r_vieworigin[0] + r_viewforward[0] * 1.5 - r_viewleft[0] * r * 3 - r_viewup[0] * r;
567 vertex3f[7] = r_vieworigin[1] + r_viewforward[1] * 1.5 - r_viewleft[1] * r * 3 - r_viewup[1] * r;
568 vertex3f[8] = r_vieworigin[2] + r_viewforward[2] * 1.5 - r_viewleft[2] * r * 3 - r_viewup[2] * r;
569 R_Mesh_Draw(3, 1, polygonelements);
572 void R_RenderScene(void);
579 void R_RenderView(void)
581 if (!r_refdef.entities/* || !cl.worldmodel*/)
582 return; //Host_Error ("R_RenderView: NULL worldmodel");
584 r_view_width = bound(0, r_refdef.width, vid.realwidth);
585 r_view_height = bound(0, r_refdef.height, vid.realheight);
587 r_view_x = bound(0, r_refdef.x, vid.realwidth - r_refdef.width);
588 r_view_y = bound(0, r_refdef.y, vid.realheight - r_refdef.height);
590 r_view_fov_x = bound(1, r_refdef.fov_x, 170);
591 r_view_fov_y = bound(1, r_refdef.fov_y, 170);
592 r_view_matrix = r_refdef.viewentitymatrix;
593 GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
594 r_rtworld = r_shadow_realtime_world.integer;
595 r_rtworldshadows = r_shadow_realtime_world_shadows.integer && gl_stencil;
596 r_rtdlight = r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer;
597 r_rtdlightshadows = r_rtdlight && (r_rtworld ? r_shadow_realtime_world_dlightshadows.integer : r_shadow_realtime_dlight_shadows.integer) && gl_stencil;
598 r_lightmapintensity = r_rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
600 // GL is weird because it's bottom to top, r_view_y is top to bottom
601 qglViewport(r_view_x, vid.realheight - (r_view_y + r_view_height), r_view_width, r_view_height);
602 GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height);
603 GL_ScissorTest(true);
609 R_TimeReport("setup");
611 qglDepthFunc(GL_LEQUAL);
612 qglPolygonOffset(0, 0);
613 qglEnable(GL_POLYGON_OFFSET_FILL);
617 qglPolygonOffset(0, 0);
618 qglDisable(GL_POLYGON_OFFSET_FILL);
621 R_TimeReport("blendview");
623 GL_Scissor(0, 0, vid.realwidth, vid.realheight);
624 GL_ScissorTest(false);
627 extern void R_DrawLightningBeams (void);
628 void R_RenderScene(void)
630 entity_render_t *world;
632 // don't let sound skip if going slow
633 if (!intimerefresh && !r_speeds.integer)
638 R_MeshQueue_BeginScene();
640 GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
644 r_farclip = R_FarClip(r_vieworigin, r_viewforward, 768.0f) + 256.0f;
645 if (r_rtworldshadows || r_rtdlightshadows)
646 GL_SetupView_Mode_PerspectiveInfiniteFarClip(r_view_fov_x, r_view_fov_y, 1.0f);
648 GL_SetupView_Mode_Perspective(r_view_fov_x, r_view_fov_y, 1.0f, r_farclip);
650 GL_SetupView_Orientation_FromEntity(&r_view_matrix);
654 if (cl.worldmodel && cl.worldmodel->brush.FatPVS)
655 cl.worldmodel->brush.FatPVS(cl.worldmodel, r_vieworigin, 2, r_pvsbits, sizeof(r_pvsbits));
656 world = &cl_entities[0].render;
657 R_WorldVisibility(world);
658 R_TimeReport("worldvis");
661 R_TimeReport("markentity");
663 R_Shadow_UpdateWorldLightSelection();
665 // don't let sound skip if going slow
666 if (!intimerefresh && !r_speeds.integer)
669 GL_ShowTrisColor(0.025, 0.025, 0, 1);
670 if (world->model && world->model->DrawSky)
672 world->model->DrawSky(world);
673 R_TimeReport("worldsky");
676 if (R_DrawBrushModelsSky())
677 R_TimeReport("bmodelsky");
679 GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
680 if (world->model && world->model->Draw)
682 world->model->Draw(world);
683 R_TimeReport("world");
686 // don't let sound skip if going slow
687 if (!intimerefresh && !r_speeds.integer)
690 GL_ShowTrisColor(0, 0.015, 0, 1);
693 R_TimeReport("models");
695 // don't let sound skip if going slow
696 if (!intimerefresh && !r_speeds.integer)
699 GL_ShowTrisColor(0, 0, 0.033, 1);
700 R_ShadowVolumeLighting(false);
701 R_TimeReport("rtlights");
703 // don't let sound skip if going slow
704 if (!intimerefresh && !r_speeds.integer)
707 GL_ShowTrisColor(0.1, 0, 0, 1);
709 R_DrawLightningBeams();
710 R_TimeReport("lightning");
713 R_TimeReport("particles");
716 R_TimeReport("explosions");
718 R_MeshQueue_RenderTransparent();
719 R_TimeReport("drawtrans");
722 R_TimeReport("coronas");
724 R_DrawWorldCrosshair();
725 R_TimeReport("crosshair");
727 R_MeshQueue_Render();
728 R_MeshQueue_EndScene();
730 if (r_shadow_visiblevolumes.integer && !r_showtrispass)
732 R_ShadowVolumeLighting(true);
733 R_TimeReport("shadowvolume");
736 GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
738 // don't let sound skip if going slow
739 if (!intimerefresh && !r_speeds.integer)
744 void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, float ca)
747 float *v, *c, f1, f2, diff[3], vertex3f[8*3], color4f[8*4];
749 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
752 R_Mesh_Matrix(&r_identitymatrix);
754 vertex3f[ 0] = mins[0];vertex3f[ 1] = mins[1];vertex3f[ 2] = mins[2];
755 vertex3f[ 3] = maxs[0];vertex3f[ 4] = mins[1];vertex3f[ 5] = mins[2];
756 vertex3f[ 6] = mins[0];vertex3f[ 7] = maxs[1];vertex3f[ 8] = mins[2];
757 vertex3f[ 9] = maxs[0];vertex3f[10] = maxs[1];vertex3f[11] = mins[2];
758 vertex3f[12] = mins[0];vertex3f[13] = mins[1];vertex3f[14] = maxs[2];
759 vertex3f[15] = maxs[0];vertex3f[16] = mins[1];vertex3f[17] = maxs[2];
760 vertex3f[18] = mins[0];vertex3f[19] = maxs[1];vertex3f[20] = maxs[2];
761 vertex3f[21] = maxs[0];vertex3f[22] = maxs[1];vertex3f[23] = maxs[2];
762 R_FillColors(color, 8, cr, cg, cb, ca);
765 for (i = 0, v = vertex, c = color;i < 8;i++, v += 4, c += 4)
767 VectorSubtract(v, r_vieworigin, diff);
768 f2 = exp(fogdensity/DotProduct(diff, diff));
770 c[0] = c[0] * f1 + fogcolor[0] * f2;
771 c[1] = c[1] * f1 + fogcolor[1] * f2;
772 c[2] = c[2] * f1 + fogcolor[2] * f2;
775 memset(&m, 0, sizeof(m));
776 m.pointer_vertex = vertex3f;
777 m.pointer_color = color;
783 int nomodelelements[24] =
795 float nomodelvertex3f[6*3] =
805 float nomodelcolor4f[6*4] =
807 0.0f, 0.0f, 0.5f, 1.0f,
808 0.0f, 0.0f, 0.5f, 1.0f,
809 0.0f, 0.5f, 0.0f, 1.0f,
810 0.0f, 0.5f, 0.0f, 1.0f,
811 0.5f, 0.0f, 0.0f, 1.0f,
812 0.5f, 0.0f, 0.0f, 1.0f
815 void R_DrawNoModelCallback(const void *calldata1, int calldata2)
817 const entity_render_t *ent = calldata1;
819 float f1, f2, *c, diff[3];
822 R_Mesh_Matrix(&ent->matrix);
824 memset(&m, 0, sizeof(m));
825 m.pointer_vertex = nomodelvertex3f;
827 if (ent->flags & EF_ADDITIVE)
829 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
832 else if (ent->alpha < 1)
834 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
839 GL_BlendFunc(GL_ONE, GL_ZERO);
842 GL_DepthTest(!(ent->effects & EF_NODEPTHTEST));
845 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
846 m.pointer_color = color4f;
847 VectorSubtract(ent->origin, r_vieworigin, diff);
848 f2 = exp(fogdensity/DotProduct(diff, diff));
850 for (i = 0, c = color4f;i < 6;i++, c += 4)
852 c[0] = (c[0] * f1 + fogcolor[0] * f2);
853 c[1] = (c[1] * f1 + fogcolor[1] * f2);
854 c[2] = (c[2] * f1 + fogcolor[2] * f2);
858 else if (ent->alpha != 1)
860 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
861 m.pointer_color = color4f;
862 for (i = 0, c = color4f;i < 6;i++, c += 4)
866 m.pointer_color = nomodelcolor4f;
868 R_Mesh_Draw(6, 8, nomodelelements);
871 void R_DrawNoModel(entity_render_t *ent)
873 //if ((ent->effects & EF_ADDITIVE) || (ent->alpha < 1))
874 R_MeshQueue_AddTransparent(ent->effects & EF_NODEPTHTEST ? r_vieworigin : ent->origin, R_DrawNoModelCallback, ent, 0);
876 // R_DrawNoModelCallback(ent, 0);
879 void R_CalcBeam_Vertex3f (float *vert, const vec3_t org1, const vec3_t org2, float width)
881 vec3_t right1, right2, diff, normal;
883 VectorSubtract (org2, org1, normal);
884 VectorNormalizeFast (normal);
886 // calculate 'right' vector for start
887 VectorSubtract (r_vieworigin, org1, diff);
888 VectorNormalizeFast (diff);
889 CrossProduct (normal, diff, right1);
891 // calculate 'right' vector for end
892 VectorSubtract (r_vieworigin, org2, diff);
893 VectorNormalizeFast (diff);
894 CrossProduct (normal, diff, right2);
896 vert[ 0] = org1[0] + width * right1[0];
897 vert[ 1] = org1[1] + width * right1[1];
898 vert[ 2] = org1[2] + width * right1[2];
899 vert[ 3] = org1[0] - width * right1[0];
900 vert[ 4] = org1[1] - width * right1[1];
901 vert[ 5] = org1[2] - width * right1[2];
902 vert[ 6] = org2[0] - width * right2[0];
903 vert[ 7] = org2[1] - width * right2[1];
904 vert[ 8] = org2[2] - width * right2[2];
905 vert[ 9] = org2[0] + width * right2[0];
906 vert[10] = org2[1] + width * right2[1];
907 vert[11] = org2[2] + width * right2[2];
910 float spritetexcoord2f[4*2] = {0, 1, 0, 0, 1, 0, 1, 1};
912 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)
919 VectorSubtract(origin, r_vieworigin, diff);
920 ca *= 1 - exp(fogdensity/DotProduct(diff,diff));
923 R_Mesh_Matrix(&r_identitymatrix);
924 GL_BlendFunc(blendfunc1, blendfunc2);
926 GL_DepthTest(!depthdisable);
928 varray_vertex3f[ 0] = origin[0] + left[0] * scalex2 + up[0] * scaley1;
929 varray_vertex3f[ 1] = origin[1] + left[1] * scalex2 + up[1] * scaley1;
930 varray_vertex3f[ 2] = origin[2] + left[2] * scalex2 + up[2] * scaley1;
931 varray_vertex3f[ 3] = origin[0] + left[0] * scalex2 + up[0] * scaley2;
932 varray_vertex3f[ 4] = origin[1] + left[1] * scalex2 + up[1] * scaley2;
933 varray_vertex3f[ 5] = origin[2] + left[2] * scalex2 + up[2] * scaley2;
934 varray_vertex3f[ 6] = origin[0] + left[0] * scalex1 + up[0] * scaley2;
935 varray_vertex3f[ 7] = origin[1] + left[1] * scalex1 + up[1] * scaley2;
936 varray_vertex3f[ 8] = origin[2] + left[2] * scalex1 + up[2] * scaley2;
937 varray_vertex3f[ 9] = origin[0] + left[0] * scalex1 + up[0] * scaley1;
938 varray_vertex3f[10] = origin[1] + left[1] * scalex1 + up[1] * scaley1;
939 varray_vertex3f[11] = origin[2] + left[2] * scalex1 + up[2] * scaley1;
941 memset(&m, 0, sizeof(m));
942 m.tex[0] = R_GetTexture(texture);
943 m.pointer_texcoord[0] = spritetexcoord2f;
944 m.pointer_vertex = varray_vertex3f;
946 GL_Color(cr, cg, cb, ca);
947 R_Mesh_Draw(4, 2, polygonelements);