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++)
134 float fog_density, fog_red, fog_green, fog_blue;
136 qboolean oldgl_fogenable;
137 void R_UpdateFog(void)
139 if (gamemode == GAME_NEHAHRA)
141 if (gl_fogenable.integer)
143 oldgl_fogenable = true;
144 fog_density = gl_fogdensity.value;
145 fog_red = gl_fogred.value;
146 fog_green = gl_foggreen.value;
147 fog_blue = gl_fogblue.value;
149 else if (oldgl_fogenable)
151 oldgl_fogenable = false;
160 fogcolor[0] = fog_red = bound(0.0f, fog_red , 1.0f);
161 fogcolor[1] = fog_green = bound(0.0f, fog_green, 1.0f);
162 fogcolor[2] = fog_blue = bound(0.0f, fog_blue , 1.0f);
167 fogdensity = -4000.0f / (fog_density * fog_density);
168 // fog color was already set
174 // FIXME: move this to client?
177 if (gamemode == GAME_NEHAHRA)
179 Cvar_Set("gl_fogenable", "0");
180 Cvar_Set("gl_fogdensity", "0.2");
181 Cvar_Set("gl_fogred", "0.3");
182 Cvar_Set("gl_foggreen", "0.3");
183 Cvar_Set("gl_fogblue", "0.3");
185 fog_density = fog_red = fog_green = fog_blue = 0.0f;
188 // FIXME: move this to client?
189 void FOG_registercvars(void)
191 if (gamemode == GAME_NEHAHRA)
193 Cvar_RegisterVariable (&gl_fogenable);
194 Cvar_RegisterVariable (&gl_fogdensity);
195 Cvar_RegisterVariable (&gl_fogred);
196 Cvar_RegisterVariable (&gl_foggreen);
197 Cvar_RegisterVariable (&gl_fogblue);
198 Cvar_RegisterVariable (&gl_fogstart);
199 Cvar_RegisterVariable (&gl_fogend);
203 void gl_main_start(void)
207 void gl_main_shutdown(void)
211 extern void CL_ParseEntityLump(char *entitystring);
212 void gl_main_newmap(void)
214 // FIXME: move this code to client
216 char *entities, entname[MAX_QPATH];
220 strlcpy(entname, cl.worldmodel->name, sizeof(entname));
221 l = strlen(entname) - 4;
222 if (l >= 0 && !strcmp(entname + l, ".bsp"))
224 strcpy(entname + l, ".ent");
225 if ((entities = FS_LoadFile(entname, tempmempool, true)))
227 CL_ParseEntityLump(entities);
232 if (cl.worldmodel->brush.entities)
233 CL_ParseEntityLump(cl.worldmodel->brush.entities);
237 void GL_Main_Init(void)
239 Matrix4x4_CreateIdentity(&r_identitymatrix);
240 // FIXME: move this to client?
242 Cvar_RegisterVariable(&r_showtris);
243 Cvar_RegisterVariable(&r_drawentities);
244 Cvar_RegisterVariable(&r_drawviewmodel);
245 Cvar_RegisterVariable(&r_speeds);
246 Cvar_RegisterVariable(&r_fullbrights);
247 Cvar_RegisterVariable(&r_wateralpha);
248 Cvar_RegisterVariable(&r_dynamic);
249 Cvar_RegisterVariable(&r_fullbright);
250 Cvar_RegisterVariable(&r_textureunits);
251 Cvar_RegisterVariable(&r_lerpsprites);
252 Cvar_RegisterVariable(&r_lerpmodels);
253 Cvar_RegisterVariable(&r_waterscroll);
254 Cvar_RegisterVariable(&r_watershader);
255 Cvar_RegisterVariable(&r_drawcollisionbrushes);
256 if (gamemode == GAME_NEHAHRA || gamemode == GAME_NEXUIZ || gamemode == GAME_TENEBRAE)
257 Cvar_SetValue("r_fullbrights", 0);
258 R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap);
261 static vec3_t r_farclip_origin;
262 static vec3_t r_farclip_direction;
263 static vec_t r_farclip_directiondist;
264 static vec_t r_farclip_meshfarclip;
265 static int r_farclip_directionbit0;
266 static int r_farclip_directionbit1;
267 static int r_farclip_directionbit2;
269 // enlarge farclip to accomodate box
270 static void R_FarClip_Box(vec3_t mins, vec3_t maxs)
273 d = (r_farclip_directionbit0 ? mins[0] : maxs[0]) * r_farclip_direction[0]
274 + (r_farclip_directionbit1 ? mins[1] : maxs[1]) * r_farclip_direction[1]
275 + (r_farclip_directionbit2 ? mins[2] : maxs[2]) * r_farclip_direction[2];
276 if (r_farclip_meshfarclip < d)
277 r_farclip_meshfarclip = d;
280 // return farclip value
281 static float R_FarClip(vec3_t origin, vec3_t direction, vec_t startfarclip)
285 VectorCopy(origin, r_farclip_origin);
286 VectorCopy(direction, r_farclip_direction);
287 r_farclip_directiondist = DotProduct(r_farclip_origin, r_farclip_direction);
288 r_farclip_directionbit0 = r_farclip_direction[0] < 0;
289 r_farclip_directionbit1 = r_farclip_direction[1] < 0;
290 r_farclip_directionbit2 = r_farclip_direction[2] < 0;
291 r_farclip_meshfarclip = r_farclip_directiondist + startfarclip;
293 if (r_refdef.worldmodel)
294 R_FarClip_Box(r_refdef.worldmodel->normalmins, r_refdef.worldmodel->normalmaxs);
295 for (i = 0;i < r_refdef.numentities;i++)
296 R_FarClip_Box(r_refdef.entities[i]->mins, r_refdef.entities[i]->maxs);
298 return r_farclip_meshfarclip - r_farclip_directiondist;
301 extern void R_Textures_Init(void);
302 extern void Mod_RenderInit(void);
303 extern void GL_Draw_Init(void);
304 extern void GL_Main_Init(void);
305 extern void R_Shadow_Init(void);
306 extern void GL_Models_Init(void);
307 extern void R_Sky_Init(void);
308 extern void GL_Surf_Init(void);
309 extern void R_Crosshairs_Init(void);
310 extern void R_Light_Init(void);
311 extern void R_Particles_Init(void);
312 extern void R_Explosion_Init(void);
313 extern void ui_init(void);
314 extern void gl_backend_init(void);
315 extern void Sbar_Init(void);
316 extern void R_LightningBeams_Init(void);
318 void Render_Init(void)
337 R_LightningBeams_Init();
345 extern char *ENGINE_EXTENSIONS;
348 VID_CheckExtensions();
350 // LordHavoc: report supported extensions
351 Con_DPrintf("\nengine extensions: %s\n", ENGINE_EXTENSIONS);
353 // clear to black (loading plaque will be seen over this)
354 qglClearColor(0,0,0,1);
355 qglClear(GL_COLOR_BUFFER_BIT);
358 int R_CullBox(const vec3_t mins, const vec3_t maxs)
362 for (i = 0;i < 4;i++)
369 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
373 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
377 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
381 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
385 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
389 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
393 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
397 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
405 //==================================================================================
407 static void R_MarkEntities (void)
410 entity_render_t *ent;
412 if (!r_drawentities.integer)
415 for (i = 0;i < r_refdef.numentities;i++)
417 ent = r_refdef.entities[i];
418 Mod_CheckLoaded(ent->model);
419 // some of the renderer still relies on origin...
420 Matrix4x4_OriginFromMatrix(&ent->matrix, ent->origin);
421 // some of the renderer still relies on scale...
422 ent->scale = Matrix4x4_ScaleFromMatrix(&ent->matrix);
423 R_UpdateEntLights(ent);
424 if ((chase_active.integer || !(ent->flags & RENDER_EXTERIORMODEL))
425 && (!VIS_CullBox(ent->mins, ent->maxs) || (ent->effects & EF_NODEPTHTEST))
426 && (!envmap || !(ent->flags & (RENDER_VIEWMODEL | RENDER_EXTERIORMODEL))))
427 ent->visframe = r_framecount;
431 // only used if skyrendermasked, and normally returns false
432 int R_DrawBrushModelsSky (void)
435 entity_render_t *ent;
437 if (!r_drawentities.integer)
441 for (i = 0;i < r_refdef.numentities;i++)
443 ent = r_refdef.entities[i];
444 if (ent->visframe == r_framecount && ent->model && ent->model->DrawSky)
446 ent->model->DrawSky(ent);
453 void R_DrawNoModel(entity_render_t *ent);
454 void R_DrawModels(void)
457 entity_render_t *ent;
459 if (!r_drawentities.integer)
462 for (i = 0;i < r_refdef.numentities;i++)
464 ent = r_refdef.entities[i];
465 if (ent->visframe == r_framecount)
467 if (ent->model && ent->model->Draw != NULL)
468 ent->model->Draw(ent);
475 static void R_SetFrustum(void)
477 // break apart the view matrix into vectors for various purposes
478 Matrix4x4_ToVectors(&r_view_matrix, r_viewforward, r_viewleft, r_viewup, r_vieworigin);
479 VectorNegate(r_viewleft, r_viewright);
481 // LordHavoc: note to all quake engine coders, the special case for 90
482 // degrees assumed a square view (wrong), so I removed it, Quake2 has it
485 // rotate R_VIEWFORWARD right by FOV_X/2 degrees
486 RotatePointAroundVector( frustum[0].normal, r_viewup, r_viewforward, -(90 - r_view_fov_x / 2));
487 frustum[0].dist = DotProduct (r_vieworigin, frustum[0].normal);
488 PlaneClassify(&frustum[0]);
490 // rotate R_VIEWFORWARD left by FOV_X/2 degrees
491 RotatePointAroundVector( frustum[1].normal, r_viewup, r_viewforward, (90 - r_view_fov_x / 2));
492 frustum[1].dist = DotProduct (r_vieworigin, frustum[1].normal);
493 PlaneClassify(&frustum[1]);
495 // rotate R_VIEWFORWARD up by FOV_X/2 degrees
496 RotatePointAroundVector( frustum[2].normal, r_viewleft, r_viewforward, -(90 - r_view_fov_y / 2));
497 frustum[2].dist = DotProduct (r_vieworigin, frustum[2].normal);
498 PlaneClassify(&frustum[2]);
500 // rotate R_VIEWFORWARD down by FOV_X/2 degrees
501 RotatePointAroundVector( frustum[3].normal, r_viewleft, r_viewforward, (90 - r_view_fov_y / 2));
502 frustum[3].dist = DotProduct (r_vieworigin, frustum[3].normal);
503 PlaneClassify(&frustum[3]);
506 static void R_BlendView(void)
512 if (r_refdef.viewblend[3] < 0.01f)
515 R_Mesh_Matrix(&r_identitymatrix);
517 memset(&m, 0, sizeof(m));
518 m.pointer_vertex = vertex3f;
521 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
523 GL_DepthTest(false); // magic
524 GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
526 vertex3f[0] = r_vieworigin[0] + r_viewforward[0] * 1.5 + r_viewleft[0] * r - r_viewup[0] * r;
527 vertex3f[1] = r_vieworigin[1] + r_viewforward[1] * 1.5 + r_viewleft[1] * r - r_viewup[1] * r;
528 vertex3f[2] = r_vieworigin[2] + r_viewforward[2] * 1.5 + r_viewleft[2] * r - r_viewup[2] * r;
529 vertex3f[3] = r_vieworigin[0] + r_viewforward[0] * 1.5 + r_viewleft[0] * r + r_viewup[0] * r * 3;
530 vertex3f[4] = r_vieworigin[1] + r_viewforward[1] * 1.5 + r_viewleft[1] * r + r_viewup[1] * r * 3;
531 vertex3f[5] = r_vieworigin[2] + r_viewforward[2] * 1.5 + r_viewleft[2] * r + r_viewup[2] * r * 3;
532 vertex3f[6] = r_vieworigin[0] + r_viewforward[0] * 1.5 - r_viewleft[0] * r * 3 - r_viewup[0] * r;
533 vertex3f[7] = r_vieworigin[1] + r_viewforward[1] * 1.5 - r_viewleft[1] * r * 3 - r_viewup[1] * r;
534 vertex3f[8] = r_vieworigin[2] + r_viewforward[2] * 1.5 - r_viewleft[2] * r * 3 - r_viewup[2] * r;
535 R_Mesh_Draw(3, 1, polygonelements);
538 void R_RenderScene(void);
545 void R_RenderView(void)
547 if (!r_refdef.entities/* || !r_refdef.worldmodel*/)
548 return; //Host_Error ("R_RenderView: NULL worldmodel");
550 r_view_width = bound(0, r_refdef.width, vid.realwidth);
551 r_view_height = bound(0, r_refdef.height, vid.realheight);
553 r_view_x = bound(0, r_refdef.x, vid.realwidth - r_refdef.width);
554 r_view_y = bound(0, r_refdef.y, vid.realheight - r_refdef.height);
556 r_view_fov_x = bound(1, r_refdef.fov_x, 170);
557 r_view_fov_y = bound(1, r_refdef.fov_y, 170);
558 r_view_matrix = r_refdef.viewentitymatrix;
559 GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
560 r_rtworld = r_shadow_realtime_world.integer;
561 r_rtworldshadows = r_shadow_realtime_world_shadows.integer && gl_stencil;
562 r_rtdlight = r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer;
563 r_rtdlightshadows = r_rtdlight && (r_rtworld ? r_shadow_realtime_world_dlightshadows.integer : r_shadow_realtime_dlight_shadows.integer) && gl_stencil;
564 r_lightmapintensity = r_rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
566 // GL is weird because it's bottom to top, r_view_y is top to bottom
567 qglViewport(r_view_x, vid.realheight - (r_view_y + r_view_height), r_view_width, r_view_height);
568 GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height);
569 GL_ScissorTest(true);
575 R_TimeReport("setup");
577 qglDepthFunc(GL_LEQUAL);
578 qglPolygonOffset(0, 0);
579 qglEnable(GL_POLYGON_OFFSET_FILL);
583 qglPolygonOffset(0, 0);
584 qglDisable(GL_POLYGON_OFFSET_FILL);
587 R_TimeReport("blendview");
589 GL_Scissor(0, 0, vid.realwidth, vid.realheight);
590 GL_ScissorTest(false);
593 extern void R_DrawLightningBeams (void);
594 void R_RenderScene(void)
596 // don't let sound skip if going slow
597 if (r_refdef.extraupdate)
602 R_MeshQueue_BeginScene();
604 GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
608 r_farclip = R_FarClip(r_vieworigin, r_viewforward, 768.0f) + 256.0f;
609 if (r_rtworldshadows || r_rtdlightshadows)
610 GL_SetupView_Mode_PerspectiveInfiniteFarClip(r_view_fov_x, r_view_fov_y, 1.0f);
612 GL_SetupView_Mode_Perspective(r_view_fov_x, r_view_fov_y, 1.0f, r_farclip);
614 GL_SetupView_Orientation_FromEntity(&r_view_matrix);
618 if (r_refdef.worldmodel && r_refdef.worldmodel->brush.FatPVS)
619 r_refdef.worldmodel->brush.FatPVS(r_refdef.worldmodel, r_vieworigin, 2, r_pvsbits, sizeof(r_pvsbits));
621 R_TimeReport("worldvis");
624 R_TimeReport("markentity");
626 R_Shadow_UpdateWorldLightSelection();
628 // don't let sound skip if going slow
629 if (r_refdef.extraupdate)
632 GL_ShowTrisColor(0.025, 0.025, 0, 1);
633 if (r_refdef.worldmodel && r_refdef.worldmodel->DrawSky)
635 r_refdef.worldmodel->DrawSky(r_refdef.worldentity);
636 R_TimeReport("worldsky");
639 if (R_DrawBrushModelsSky())
640 R_TimeReport("bmodelsky");
642 GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
643 if (r_refdef.worldmodel && r_refdef.worldmodel->Draw)
645 r_refdef.worldmodel->Draw(r_refdef.worldentity);
646 R_TimeReport("world");
649 // don't let sound skip if going slow
650 if (r_refdef.extraupdate)
653 GL_ShowTrisColor(0, 0.015, 0, 1);
656 R_TimeReport("models");
658 // don't let sound skip if going slow
659 if (r_refdef.extraupdate)
662 GL_ShowTrisColor(0, 0, 0.033, 1);
663 R_ShadowVolumeLighting(false);
664 R_TimeReport("rtlights");
666 // don't let sound skip if going slow
667 if (r_refdef.extraupdate)
670 GL_ShowTrisColor(0.1, 0, 0, 1);
672 R_DrawLightningBeams();
673 R_TimeReport("lightning");
676 R_TimeReport("particles");
679 R_TimeReport("explosions");
681 R_MeshQueue_RenderTransparent();
682 R_TimeReport("drawtrans");
685 R_TimeReport("coronas");
687 R_DrawWorldCrosshair();
688 R_TimeReport("crosshair");
690 R_MeshQueue_Render();
691 R_MeshQueue_EndScene();
693 if (r_shadow_visiblevolumes.integer && !r_showtrispass)
695 R_ShadowVolumeLighting(true);
696 R_TimeReport("shadowvolume");
699 GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
701 // don't let sound skip if going slow
702 if (r_refdef.extraupdate)
707 void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, float ca)
710 float *v, *c, f1, f2, diff[3], vertex3f[8*3], color4f[8*4];
712 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
715 R_Mesh_Matrix(&r_identitymatrix);
717 vertex3f[ 0] = mins[0];vertex3f[ 1] = mins[1];vertex3f[ 2] = mins[2];
718 vertex3f[ 3] = maxs[0];vertex3f[ 4] = mins[1];vertex3f[ 5] = mins[2];
719 vertex3f[ 6] = mins[0];vertex3f[ 7] = maxs[1];vertex3f[ 8] = mins[2];
720 vertex3f[ 9] = maxs[0];vertex3f[10] = maxs[1];vertex3f[11] = mins[2];
721 vertex3f[12] = mins[0];vertex3f[13] = mins[1];vertex3f[14] = maxs[2];
722 vertex3f[15] = maxs[0];vertex3f[16] = mins[1];vertex3f[17] = maxs[2];
723 vertex3f[18] = mins[0];vertex3f[19] = maxs[1];vertex3f[20] = maxs[2];
724 vertex3f[21] = maxs[0];vertex3f[22] = maxs[1];vertex3f[23] = maxs[2];
725 R_FillColors(color, 8, cr, cg, cb, ca);
728 for (i = 0, v = vertex, c = color;i < 8;i++, v += 4, c += 4)
730 VectorSubtract(v, r_vieworigin, diff);
731 f2 = exp(fogdensity/DotProduct(diff, diff));
733 c[0] = c[0] * f1 + fogcolor[0] * f2;
734 c[1] = c[1] * f1 + fogcolor[1] * f2;
735 c[2] = c[2] * f1 + fogcolor[2] * f2;
738 memset(&m, 0, sizeof(m));
739 m.pointer_vertex = vertex3f;
740 m.pointer_color = color;
746 int nomodelelements[24] =
758 float nomodelvertex3f[6*3] =
768 float nomodelcolor4f[6*4] =
770 0.0f, 0.0f, 0.5f, 1.0f,
771 0.0f, 0.0f, 0.5f, 1.0f,
772 0.0f, 0.5f, 0.0f, 1.0f,
773 0.0f, 0.5f, 0.0f, 1.0f,
774 0.5f, 0.0f, 0.0f, 1.0f,
775 0.5f, 0.0f, 0.0f, 1.0f
778 void R_DrawNoModelCallback(const void *calldata1, int calldata2)
780 const entity_render_t *ent = calldata1;
782 float f1, f2, *c, diff[3];
785 R_Mesh_Matrix(&ent->matrix);
787 memset(&m, 0, sizeof(m));
788 m.pointer_vertex = nomodelvertex3f;
790 if (ent->flags & EF_ADDITIVE)
792 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
795 else if (ent->alpha < 1)
797 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
802 GL_BlendFunc(GL_ONE, GL_ZERO);
805 GL_DepthTest(!(ent->effects & EF_NODEPTHTEST));
808 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
809 m.pointer_color = color4f;
810 VectorSubtract(ent->origin, r_vieworigin, diff);
811 f2 = exp(fogdensity/DotProduct(diff, diff));
813 for (i = 0, c = color4f;i < 6;i++, c += 4)
815 c[0] = (c[0] * f1 + fogcolor[0] * f2);
816 c[1] = (c[1] * f1 + fogcolor[1] * f2);
817 c[2] = (c[2] * f1 + fogcolor[2] * f2);
821 else if (ent->alpha != 1)
823 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
824 m.pointer_color = color4f;
825 for (i = 0, c = color4f;i < 6;i++, c += 4)
829 m.pointer_color = nomodelcolor4f;
831 R_Mesh_Draw(6, 8, nomodelelements);
834 void R_DrawNoModel(entity_render_t *ent)
836 //if ((ent->effects & EF_ADDITIVE) || (ent->alpha < 1))
837 R_MeshQueue_AddTransparent(ent->effects & EF_NODEPTHTEST ? r_vieworigin : ent->origin, R_DrawNoModelCallback, ent, 0);
839 // R_DrawNoModelCallback(ent, 0);
842 void R_CalcBeam_Vertex3f (float *vert, const vec3_t org1, const vec3_t org2, float width)
844 vec3_t right1, right2, diff, normal;
846 VectorSubtract (org2, org1, normal);
847 VectorNormalizeFast (normal);
849 // calculate 'right' vector for start
850 VectorSubtract (r_vieworigin, org1, diff);
851 VectorNormalizeFast (diff);
852 CrossProduct (normal, diff, right1);
854 // calculate 'right' vector for end
855 VectorSubtract (r_vieworigin, org2, diff);
856 VectorNormalizeFast (diff);
857 CrossProduct (normal, diff, right2);
859 vert[ 0] = org1[0] + width * right1[0];
860 vert[ 1] = org1[1] + width * right1[1];
861 vert[ 2] = org1[2] + width * right1[2];
862 vert[ 3] = org1[0] - width * right1[0];
863 vert[ 4] = org1[1] - width * right1[1];
864 vert[ 5] = org1[2] - width * right1[2];
865 vert[ 6] = org2[0] - width * right2[0];
866 vert[ 7] = org2[1] - width * right2[1];
867 vert[ 8] = org2[2] - width * right2[2];
868 vert[ 9] = org2[0] + width * right2[0];
869 vert[10] = org2[1] + width * right2[1];
870 vert[11] = org2[2] + width * right2[2];
873 float spritetexcoord2f[4*2] = {0, 1, 0, 0, 1, 0, 1, 1};
875 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)
882 VectorSubtract(origin, r_vieworigin, diff);
883 ca *= 1 - exp(fogdensity/DotProduct(diff,diff));
886 R_Mesh_Matrix(&r_identitymatrix);
887 GL_BlendFunc(blendfunc1, blendfunc2);
889 GL_DepthTest(!depthdisable);
891 varray_vertex3f[ 0] = origin[0] + left[0] * scalex2 + up[0] * scaley1;
892 varray_vertex3f[ 1] = origin[1] + left[1] * scalex2 + up[1] * scaley1;
893 varray_vertex3f[ 2] = origin[2] + left[2] * scalex2 + up[2] * scaley1;
894 varray_vertex3f[ 3] = origin[0] + left[0] * scalex2 + up[0] * scaley2;
895 varray_vertex3f[ 4] = origin[1] + left[1] * scalex2 + up[1] * scaley2;
896 varray_vertex3f[ 5] = origin[2] + left[2] * scalex2 + up[2] * scaley2;
897 varray_vertex3f[ 6] = origin[0] + left[0] * scalex1 + up[0] * scaley2;
898 varray_vertex3f[ 7] = origin[1] + left[1] * scalex1 + up[1] * scaley2;
899 varray_vertex3f[ 8] = origin[2] + left[2] * scalex1 + up[2] * scaley2;
900 varray_vertex3f[ 9] = origin[0] + left[0] * scalex1 + up[0] * scaley1;
901 varray_vertex3f[10] = origin[1] + left[1] * scalex1 + up[1] * scaley1;
902 varray_vertex3f[11] = origin[2] + left[2] * scalex1 + up[2] * scaley1;
904 memset(&m, 0, sizeof(m));
905 m.tex[0] = R_GetTexture(texture);
906 m.pointer_texcoord[0] = spritetexcoord2f;
907 m.pointer_vertex = varray_vertex3f;
909 GL_Color(cr, cg, cb, ca);
910 R_Mesh_Draw(4, 2, polygonelements);