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
59 matrix4x4_t r_view_matrix;
66 // 8.8 fraction of base light value
67 unsigned short d_lightstylevalue[256];
69 cvar_t r_showtris = {0, "r_showtris", "0"};
70 cvar_t r_drawentities = {0, "r_drawentities","1"};
71 cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1"};
72 cvar_t r_speeds = {0, "r_speeds","0"};
73 cvar_t r_fullbright = {0, "r_fullbright","0"};
74 cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1"};
75 cvar_t r_dynamic = {CVAR_SAVE, "r_dynamic","1"};
76 cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1"};
77 cvar_t r_drawcollisionbrushes = {0, "r_drawcollisionbrushes", "0"};
79 cvar_t gl_fogenable = {0, "gl_fogenable", "0"};
80 cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25"};
81 cvar_t gl_fogred = {0, "gl_fogred","0.3"};
82 cvar_t gl_foggreen = {0, "gl_foggreen","0.3"};
83 cvar_t gl_fogblue = {0, "gl_fogblue","0.3"};
84 cvar_t gl_fogstart = {0, "gl_fogstart", "0"};
85 cvar_t gl_fogend = {0, "gl_fogend","0"};
87 cvar_t r_textureunits = {0, "r_textureunits", "32"};
89 cvar_t r_lerpsprites = {CVAR_SAVE, "r_lerpsprites", "1"};
90 cvar_t r_lerpmodels = {CVAR_SAVE, "r_lerpmodels", "1"};
91 cvar_t r_waterscroll = {CVAR_SAVE, "r_waterscroll", "1"};
92 cvar_t r_watershader = {CVAR_SAVE, "r_watershader", "1"};
95 void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
98 for (i = 0;i < verts;i++)
109 void R_FillColors(float *out, int verts, float r, float g, float b, float a)
112 for (i = 0;i < verts;i++)
126 For program optimization
129 qboolean intimerefresh = 0;
130 static void R_TimeRefresh_f (void)
133 float timestart, timedelta, oldangles[3];
136 VectorCopy(cl.viewangles, oldangles);
137 VectorClear(cl.viewangles);
139 timestart = Sys_DoubleTime();
140 for (i = 0;i < 128;i++)
142 Matrix4x4_CreateFromQuakeEntity(&r_refdef.viewentitymatrix, r_vieworigin[0], r_vieworigin[1], r_vieworigin[2], 0, i / 128.0 * 360.0, 0, 1);
145 timedelta = Sys_DoubleTime() - timestart;
147 VectorCopy(oldangles, cl.viewangles);
149 Con_Printf("%f seconds (%f fps)\n", timedelta, 128/timedelta);
154 float fog_density, fog_red, fog_green, fog_blue;
156 qboolean oldgl_fogenable;
157 void R_UpdateFog(void)
159 if (gamemode == GAME_NEHAHRA)
161 if (gl_fogenable.integer)
163 oldgl_fogenable = true;
164 fog_density = gl_fogdensity.value;
165 fog_red = gl_fogred.value;
166 fog_green = gl_foggreen.value;
167 fog_blue = gl_fogblue.value;
169 else if (oldgl_fogenable)
171 oldgl_fogenable = false;
180 fogcolor[0] = fog_red = bound(0.0f, fog_red , 1.0f);
181 fogcolor[1] = fog_green = bound(0.0f, fog_green, 1.0f);
182 fogcolor[2] = fog_blue = bound(0.0f, fog_blue , 1.0f);
187 fogdensity = -4000.0f / (fog_density * fog_density);
188 // fog color was already set
194 // FIXME: move this to client?
197 if (gamemode == GAME_NEHAHRA)
199 Cvar_Set("gl_fogenable", "0");
200 Cvar_Set("gl_fogdensity", "0.2");
201 Cvar_Set("gl_fogred", "0.3");
202 Cvar_Set("gl_foggreen", "0.3");
203 Cvar_Set("gl_fogblue", "0.3");
205 fog_density = fog_red = fog_green = fog_blue = 0.0f;
208 // FIXME: move this to client?
209 void FOG_registercvars(void)
211 if (gamemode == GAME_NEHAHRA)
213 Cvar_RegisterVariable (&gl_fogenable);
214 Cvar_RegisterVariable (&gl_fogdensity);
215 Cvar_RegisterVariable (&gl_fogred);
216 Cvar_RegisterVariable (&gl_foggreen);
217 Cvar_RegisterVariable (&gl_fogblue);
218 Cvar_RegisterVariable (&gl_fogstart);
219 Cvar_RegisterVariable (&gl_fogend);
223 void gl_main_start(void)
227 void gl_main_shutdown(void)
231 extern void CL_ParseEntityLump(char *entitystring);
232 void gl_main_newmap(void)
235 char *entities, entname[MAX_QPATH];
239 strcpy(entname, cl.worldmodel->name);
240 l = strlen(entname) - 4;
241 if (l >= 0 && !strcmp(entname + l, ".bsp"))
243 strcpy(entname + l, ".ent");
244 if ((entities = FS_LoadFile(entname, tempmempool, true)))
246 CL_ParseEntityLump(entities);
251 if (cl.worldmodel->brush.entities)
252 CL_ParseEntityLump(cl.worldmodel->brush.entities);
256 void GL_Main_Init(void)
258 Matrix4x4_CreateIdentity(&r_identitymatrix);
259 // FIXME: move this to client?
261 Cmd_AddCommand("timerefresh", R_TimeRefresh_f);
262 Cvar_RegisterVariable(&r_showtris);
263 Cvar_RegisterVariable(&r_drawentities);
264 Cvar_RegisterVariable(&r_drawviewmodel);
265 Cvar_RegisterVariable(&r_speeds);
266 Cvar_RegisterVariable(&r_fullbrights);
267 Cvar_RegisterVariable(&r_wateralpha);
268 Cvar_RegisterVariable(&r_dynamic);
269 Cvar_RegisterVariable(&r_fullbright);
270 Cvar_RegisterVariable(&r_textureunits);
271 Cvar_RegisterVariable(&r_lerpsprites);
272 Cvar_RegisterVariable(&r_lerpmodels);
273 Cvar_RegisterVariable(&r_waterscroll);
274 Cvar_RegisterVariable(&r_watershader);
275 Cvar_RegisterVariable(&r_drawcollisionbrushes);
276 if (gamemode == GAME_NEHAHRA || gamemode == GAME_NEXUIZ || gamemode == GAME_TENEBRAE)
277 Cvar_SetValue("r_fullbrights", 0);
278 R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap);
281 static vec3_t r_farclip_origin;
282 static vec3_t r_farclip_direction;
283 static vec_t r_farclip_directiondist;
284 static vec_t r_farclip_meshfarclip;
285 static int r_farclip_directionbit0;
286 static int r_farclip_directionbit1;
287 static int r_farclip_directionbit2;
289 // enlarge farclip to accomodate box
290 static void R_FarClip_Box(vec3_t mins, vec3_t maxs)
293 d = (r_farclip_directionbit0 ? mins[0] : maxs[0]) * r_farclip_direction[0]
294 + (r_farclip_directionbit1 ? mins[1] : maxs[1]) * r_farclip_direction[1]
295 + (r_farclip_directionbit2 ? mins[2] : maxs[2]) * r_farclip_direction[2];
296 if (r_farclip_meshfarclip < d)
297 r_farclip_meshfarclip = d;
300 // return farclip value
301 static float R_FarClip(vec3_t origin, vec3_t direction, vec_t startfarclip)
305 VectorCopy(origin, r_farclip_origin);
306 VectorCopy(direction, r_farclip_direction);
307 r_farclip_directiondist = DotProduct(r_farclip_origin, r_farclip_direction);
308 r_farclip_directionbit0 = r_farclip_direction[0] < 0;
309 r_farclip_directionbit1 = r_farclip_direction[1] < 0;
310 r_farclip_directionbit2 = r_farclip_direction[2] < 0;
311 r_farclip_meshfarclip = r_farclip_directiondist + startfarclip;
314 R_FarClip_Box(cl.worldmodel->normalmins, cl.worldmodel->normalmaxs);
315 for (i = 0;i < r_refdef.numentities;i++)
316 R_FarClip_Box(r_refdef.entities[i]->mins, r_refdef.entities[i]->maxs);
318 return r_farclip_meshfarclip - r_farclip_directiondist;
321 extern void R_Textures_Init(void);
322 extern void Mod_RenderInit(void);
323 extern void GL_Draw_Init(void);
324 extern void GL_Main_Init(void);
325 extern void R_Shadow_Init(void);
326 extern void GL_Models_Init(void);
327 extern void R_Sky_Init(void);
328 extern void GL_Surf_Init(void);
329 extern void R_Crosshairs_Init(void);
330 extern void R_Light_Init(void);
331 extern void R_Particles_Init(void);
332 extern void R_Explosion_Init(void);
333 extern void ui_init(void);
334 extern void gl_backend_init(void);
335 extern void Sbar_Init(void);
336 extern void R_LightningBeams_Init(void);
338 void Render_Init(void)
357 R_LightningBeams_Init();
365 extern char *ENGINE_EXTENSIONS;
368 VID_CheckExtensions();
370 // LordHavoc: report supported extensions
371 Con_DPrintf("\nengine extensions: %s\n", ENGINE_EXTENSIONS);
374 int R_CullBox(const vec3_t mins, const vec3_t maxs)
378 for (i = 0;i < 4;i++)
385 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
389 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
393 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
397 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
401 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
405 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
409 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
413 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
421 //==================================================================================
423 static void R_MarkEntities (void)
426 entity_render_t *ent;
428 ent = &cl_entities[0].render;
429 Matrix4x4_CreateIdentity(&ent->matrix);
430 Matrix4x4_CreateIdentity(&ent->inversematrix);
432 if (!r_drawentities.integer)
435 for (i = 0;i < r_refdef.numentities;i++)
437 ent = r_refdef.entities[i];
438 Mod_CheckLoaded(ent->model);
439 // some of the renderer still relies on origin...
440 Matrix4x4_OriginFromMatrix(&ent->matrix, ent->origin);
441 // some of the renderer still relies on scale...
442 ent->scale = Matrix4x4_ScaleFromMatrix(&ent->matrix);
443 R_LerpAnimation(ent);
444 R_UpdateEntLights(ent);
445 if ((chase_active.integer || !(ent->flags & RENDER_EXTERIORMODEL))
446 && !VIS_CullBox(ent->mins, ent->maxs)
447 && (!envmap || !(ent->flags & (RENDER_VIEWMODEL | RENDER_EXTERIORMODEL))))
448 ent->visframe = r_framecount;
452 // only used if skyrendermasked, and normally returns false
453 int R_DrawBrushModelsSky (void)
456 entity_render_t *ent;
458 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 && ent->model && ent->model->DrawSky)
467 ent->model->DrawSky(ent);
480 void R_DrawViewModel (void)
482 entity_render_t *ent;
484 // FIXME: move these checks to client
485 if (!r_drawviewmodel.integer || chase_active.integer || envmap || !r_drawentities.integer || cl.items & IT_INVISIBILITY || cl.stats[STAT_HEALTH] <= 0 || !cl.viewent.render.model)
488 ent = &cl.viewent.render;
489 Mod_CheckLoaded(ent->model);
490 R_LerpAnimation(ent);
491 Matrix4x4_CreateFromQuakeEntity(&ent->matrix, ent->origin[0], ent->origin[1], ent->origin[2], -ent->angles[0], ent->angles[1], ent->angles[2], ent->scale);
492 Matrix4x4_Invert_Simple(&ent->inversematrix, &ent->matrix);
493 R_UpdateEntLights(ent);
494 ent->model->Draw(ent);
498 void R_DrawNoModel(entity_render_t *ent);
499 void R_DrawModels(void)
502 entity_render_t *ent;
504 if (!r_drawentities.integer)
507 for (i = 0;i < r_refdef.numentities;i++)
509 ent = r_refdef.entities[i];
510 if (ent->visframe == r_framecount)
512 if (ent->model && ent->model->Draw != NULL)
513 ent->model->Draw(ent);
520 static void R_SetFrustum(void)
522 // break apart the view matrix into vectors for various purposes
523 Matrix4x4_ToVectors(&r_view_matrix, r_viewforward, r_viewleft, r_viewup, r_vieworigin);
524 VectorNegate(r_viewleft, r_viewright);
526 // LordHavoc: note to all quake engine coders, the special case for 90
527 // degrees assumed a square view (wrong), so I removed it, Quake2 has it
530 // rotate R_VIEWFORWARD right by FOV_X/2 degrees
531 RotatePointAroundVector( frustum[0].normal, r_viewup, r_viewforward, -(90 - r_view_fov_x / 2));
532 frustum[0].dist = DotProduct (r_vieworigin, frustum[0].normal);
533 PlaneClassify(&frustum[0]);
535 // rotate R_VIEWFORWARD left by FOV_X/2 degrees
536 RotatePointAroundVector( frustum[1].normal, r_viewup, r_viewforward, (90 - r_view_fov_x / 2));
537 frustum[1].dist = DotProduct (r_vieworigin, frustum[1].normal);
538 PlaneClassify(&frustum[1]);
540 // rotate R_VIEWFORWARD up by FOV_X/2 degrees
541 RotatePointAroundVector( frustum[2].normal, r_viewleft, r_viewforward, -(90 - r_view_fov_y / 2));
542 frustum[2].dist = DotProduct (r_vieworigin, frustum[2].normal);
543 PlaneClassify(&frustum[2]);
545 // rotate R_VIEWFORWARD down by FOV_X/2 degrees
546 RotatePointAroundVector( frustum[3].normal, r_viewleft, r_viewforward, (90 - r_view_fov_y / 2));
547 frustum[3].dist = DotProduct (r_vieworigin, frustum[3].normal);
548 PlaneClassify(&frustum[3]);
551 static void R_BlendView(void)
557 if (r_refdef.viewblend[3] < 0.01f)
560 R_Mesh_Matrix(&r_identitymatrix);
562 memset(&m, 0, sizeof(m));
563 m.pointer_vertex = vertex3f;
566 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
568 GL_DepthTest(false); // magic
569 GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
571 vertex3f[0] = r_vieworigin[0] + r_viewforward[0] * 1.5 + r_viewleft[0] * r - r_viewup[0] * r;
572 vertex3f[1] = r_vieworigin[1] + r_viewforward[1] * 1.5 + r_viewleft[1] * r - r_viewup[1] * r;
573 vertex3f[2] = r_vieworigin[2] + r_viewforward[2] * 1.5 + r_viewleft[2] * r - r_viewup[2] * r;
574 vertex3f[3] = r_vieworigin[0] + r_viewforward[0] * 1.5 + r_viewleft[0] * r + r_viewup[0] * r * 3;
575 vertex3f[4] = r_vieworigin[1] + r_viewforward[1] * 1.5 + r_viewleft[1] * r + r_viewup[1] * r * 3;
576 vertex3f[5] = r_vieworigin[2] + r_viewforward[2] * 1.5 + r_viewleft[2] * r + r_viewup[2] * r * 3;
577 vertex3f[6] = r_vieworigin[0] + r_viewforward[0] * 1.5 - r_viewleft[0] * r * 3 - r_viewup[0] * r;
578 vertex3f[7] = r_vieworigin[1] + r_viewforward[1] * 1.5 - r_viewleft[1] * r * 3 - r_viewup[1] * r;
579 vertex3f[8] = r_vieworigin[2] + r_viewforward[2] * 1.5 - r_viewleft[2] * r * 3 - r_viewup[2] * r;
580 R_Mesh_Draw(3, 1, polygonelements);
583 void R_UpdateWorld(void)
585 if (!r_refdef.entities/* || !cl.worldmodel*/)
586 return; //Host_Error ("R_RenderView: NULL worldmodel");
588 if (r_shadow_realtime_world.integer && !gl_stencil)
590 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");
591 Cvar_SetValueQuick(&r_shadow_realtime_world, 0);
594 // don't allow cheats in multiplayer
595 if (!cl.islocalgame && cl.worldmodel)
597 if (r_fullbright.integer != 0)
598 Cvar_Set ("r_fullbright", "0");
599 if (r_ambient.value != 0)
600 Cvar_Set ("r_ambient", "0");
608 void R_RenderScene(void);
615 void R_RenderView(void)
617 if (!r_refdef.entities/* || !cl.worldmodel*/)
618 return; //Host_Error ("R_RenderView: NULL worldmodel");
620 r_view_width = bound(0, r_refdef.width, vid.realwidth);
621 r_view_height = bound(0, r_refdef.height, vid.realheight);
623 r_view_x = bound(0, r_refdef.x, vid.realwidth - r_refdef.width);
624 r_view_y = bound(0, r_refdef.y, vid.realheight - r_refdef.height);
626 r_view_fov_x = bound(1, r_refdef.fov_x, 170);
627 r_view_fov_y = bound(1, r_refdef.fov_y, 170);
628 r_view_matrix = r_refdef.viewentitymatrix;
630 // GL is weird because it's bottom to top, r_view_y is top to bottom
631 qglViewport(r_view_x, vid.realheight - (r_view_y + r_view_height), r_view_width, r_view_height);
632 GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height);
633 GL_ScissorTest(true);
635 R_TimeReport("setup");
637 qglDepthFunc(GL_LEQUAL);
638 qglPolygonOffset(0, 0);
639 qglEnable(GL_POLYGON_OFFSET_FILL);
643 qglPolygonOffset(0, 0);
644 qglDisable(GL_POLYGON_OFFSET_FILL);
647 R_TimeReport("blendview");
649 GL_Scissor(0, 0, vid.realwidth, vid.realheight);
650 GL_ScissorTest(false);
653 extern void R_DrawLightningBeams (void);
654 void R_RenderScene(void)
656 entity_render_t *world;
658 // don't let sound skip if going slow
659 if (!intimerefresh && !r_speeds.integer)
664 GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
668 r_farclip = R_FarClip(r_vieworigin, r_viewforward, 768.0f) + 256.0f;
669 if (gl_stencil && (r_shadow_realtime_world.integer || (r_shadow_realtime_dlight.integer && r_shadow_realtime_dlight_shadows.integer)))
670 GL_SetupView_Mode_PerspectiveInfiniteFarClip(r_view_fov_x, r_view_fov_y, 1.0f);
672 GL_SetupView_Mode_Perspective(r_view_fov_x, r_view_fov_y, 1.0f, r_farclip);
674 GL_SetupView_Orientation_FromEntity(&r_view_matrix);
678 if (cl.worldmodel && cl.worldmodel->brush.FatPVS)
679 cl.worldmodel->brush.FatPVS(cl.worldmodel, r_vieworigin, 2, r_pvsbits, sizeof(r_pvsbits));
680 world = &cl_entities[0].render;
681 R_WorldVisibility(world);
682 R_TimeReport("worldvis");
685 R_TimeReport("markentity");
687 R_MeshQueue_BeginScene();
689 R_Shadow_UpdateWorldLightSelection();
691 // don't let sound skip if going slow
692 if (!intimerefresh && !r_speeds.integer)
695 GL_ShowTrisColor(0.025, 0.025, 0, 1);
696 if (world->model && world->model->DrawSky)
698 world->model->DrawSky(world);
699 R_TimeReport("worldsky");
702 if (R_DrawBrushModelsSky())
703 R_TimeReport("bmodelsky");
705 GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
706 if (world->model && world->model->Draw)
708 world->model->Draw(world);
709 R_TimeReport("world");
712 // don't let sound skip if going slow
713 if (!intimerefresh && !r_speeds.integer)
716 GL_ShowTrisColor(0, 0.015, 0, 1);
719 R_TimeReport("models");
721 // don't let sound skip if going slow
722 if (!intimerefresh && !r_speeds.integer)
725 GL_ShowTrisColor(0, 0, 0.033, 1);
726 R_ShadowVolumeLighting(false);
727 R_TimeReport("rtlights");
729 // don't let sound skip if going slow
730 if (!intimerefresh && !r_speeds.integer)
733 GL_ShowTrisColor(0.1, 0, 0, 1);
735 R_DrawLightningBeams();
736 R_TimeReport("lightning");
739 R_TimeReport("particles");
742 R_TimeReport("explosions");
744 R_MeshQueue_RenderTransparent();
745 R_TimeReport("drawtrans");
748 R_TimeReport("coronas");
750 R_DrawWorldCrosshair();
751 R_TimeReport("crosshair");
753 R_MeshQueue_Render();
754 R_MeshQueue_EndScene();
756 if (r_shadow_visiblevolumes.integer && !r_showtrispass)
758 R_ShadowVolumeLighting(true);
759 R_TimeReport("shadowvolume");
762 GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
764 // don't let sound skip if going slow
765 if (!intimerefresh && !r_speeds.integer)
770 void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, float ca)
773 float *v, *c, f1, f2, diff[3], vertex3f[8*3], color4f[8*4];
775 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
778 R_Mesh_Matrix(&r_identitymatrix);
780 vertex3f[ 0] = mins[0];vertex3f[ 1] = mins[1];vertex3f[ 2] = mins[2];
781 vertex3f[ 3] = maxs[0];vertex3f[ 4] = mins[1];vertex3f[ 5] = mins[2];
782 vertex3f[ 6] = mins[0];vertex3f[ 7] = maxs[1];vertex3f[ 8] = mins[2];
783 vertex3f[ 9] = maxs[0];vertex3f[10] = maxs[1];vertex3f[11] = mins[2];
784 vertex3f[12] = mins[0];vertex3f[13] = mins[1];vertex3f[14] = maxs[2];
785 vertex3f[15] = maxs[0];vertex3f[16] = mins[1];vertex3f[17] = maxs[2];
786 vertex3f[18] = mins[0];vertex3f[19] = maxs[1];vertex3f[20] = maxs[2];
787 vertex3f[21] = maxs[0];vertex3f[22] = maxs[1];vertex3f[23] = maxs[2];
788 R_FillColors(color, 8, cr, cg, cb, ca);
791 for (i = 0, v = vertex, c = color;i < 8;i++, v += 4, c += 4)
793 VectorSubtract(v, r_vieworigin, diff);
794 f2 = exp(fogdensity/DotProduct(diff, diff));
796 c[0] = c[0] * f1 + fogcolor[0] * f2;
797 c[1] = c[1] * f1 + fogcolor[1] * f2;
798 c[2] = c[2] * f1 + fogcolor[2] * f2;
801 memset(&m, 0, sizeof(m));
802 m.pointer_vertex = vertex3f;
803 m.pointer_color = color;
809 int nomodelelements[24] =
821 float nomodelvertex3f[6*3] =
831 float nomodelcolor4f[6*4] =
833 0.0f, 0.0f, 0.5f, 1.0f,
834 0.0f, 0.0f, 0.5f, 1.0f,
835 0.0f, 0.5f, 0.0f, 1.0f,
836 0.0f, 0.5f, 0.0f, 1.0f,
837 0.5f, 0.0f, 0.0f, 1.0f,
838 0.5f, 0.0f, 0.0f, 1.0f
841 void R_DrawNoModelCallback(const void *calldata1, int calldata2)
843 const entity_render_t *ent = calldata1;
845 float f1, f2, *c, diff[3];
848 R_Mesh_Matrix(&ent->matrix);
850 memset(&m, 0, sizeof(m));
851 m.pointer_vertex = nomodelvertex3f;
853 if (ent->flags & EF_ADDITIVE)
855 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
858 else if (ent->alpha < 1)
860 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
865 GL_BlendFunc(GL_ONE, GL_ZERO);
871 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
872 m.pointer_color = color4f;
873 VectorSubtract(ent->origin, r_vieworigin, diff);
874 f2 = exp(fogdensity/DotProduct(diff, diff));
876 for (i = 0, c = color4f;i < 6;i++, c += 4)
878 c[0] = (c[0] * f1 + fogcolor[0] * f2);
879 c[1] = (c[1] * f1 + fogcolor[1] * f2);
880 c[2] = (c[2] * f1 + fogcolor[2] * f2);
884 else if (ent->alpha != 1)
886 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
887 m.pointer_color = color4f;
888 for (i = 0, c = color4f;i < 6;i++, c += 4)
892 m.pointer_color = nomodelcolor4f;
894 R_Mesh_Draw(6, 8, nomodelelements);
897 void R_DrawNoModel(entity_render_t *ent)
899 //if ((ent->effects & EF_ADDITIVE) || (ent->alpha < 1))
900 R_MeshQueue_AddTransparent(ent->origin, R_DrawNoModelCallback, ent, 0);
902 // R_DrawNoModelCallback(ent, 0);
905 void R_CalcBeam_Vertex3f (float *vert, const vec3_t org1, const vec3_t org2, float width)
907 vec3_t right1, right2, diff, normal;
909 VectorSubtract (org2, org1, normal);
910 VectorNormalizeFast (normal);
912 // calculate 'right' vector for start
913 VectorSubtract (r_vieworigin, org1, diff);
914 VectorNormalizeFast (diff);
915 CrossProduct (normal, diff, right1);
917 // calculate 'right' vector for end
918 VectorSubtract (r_vieworigin, org2, diff);
919 VectorNormalizeFast (diff);
920 CrossProduct (normal, diff, right2);
922 vert[ 0] = org1[0] + width * right1[0];
923 vert[ 1] = org1[1] + width * right1[1];
924 vert[ 2] = org1[2] + width * right1[2];
925 vert[ 3] = org1[0] - width * right1[0];
926 vert[ 4] = org1[1] - width * right1[1];
927 vert[ 5] = org1[2] - width * right1[2];
928 vert[ 6] = org2[0] - width * right2[0];
929 vert[ 7] = org2[1] - width * right2[1];
930 vert[ 8] = org2[2] - width * right2[2];
931 vert[ 9] = org2[0] + width * right2[0];
932 vert[10] = org2[1] + width * right2[1];
933 vert[11] = org2[2] + width * right2[2];
936 float spritetexcoord2f[4*2] = {0, 1, 0, 0, 1, 0, 1, 1};
938 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)
945 VectorSubtract(origin, r_vieworigin, diff);
946 ca *= 1 - exp(fogdensity/DotProduct(diff,diff));
949 R_Mesh_Matrix(&r_identitymatrix);
950 GL_BlendFunc(blendfunc1, blendfunc2);
952 GL_DepthTest(!depthdisable);
954 varray_vertex3f[ 0] = origin[0] + left[0] * scalex2 + up[0] * scaley1;
955 varray_vertex3f[ 1] = origin[1] + left[1] * scalex2 + up[1] * scaley1;
956 varray_vertex3f[ 2] = origin[2] + left[2] * scalex2 + up[2] * scaley1;
957 varray_vertex3f[ 3] = origin[0] + left[0] * scalex2 + up[0] * scaley2;
958 varray_vertex3f[ 4] = origin[1] + left[1] * scalex2 + up[1] * scaley2;
959 varray_vertex3f[ 5] = origin[2] + left[2] * scalex2 + up[2] * scaley2;
960 varray_vertex3f[ 6] = origin[0] + left[0] * scalex1 + up[0] * scaley2;
961 varray_vertex3f[ 7] = origin[1] + left[1] * scalex1 + up[1] * scaley2;
962 varray_vertex3f[ 8] = origin[2] + left[2] * scalex1 + up[2] * scaley2;
963 varray_vertex3f[ 9] = origin[0] + left[0] * scalex1 + up[0] * scaley1;
964 varray_vertex3f[10] = origin[1] + left[1] * scalex1 + up[1] * scaley1;
965 varray_vertex3f[11] = origin[2] + left[2] * scalex1 + up[2] * scaley1;
967 memset(&m, 0, sizeof(m));
968 m.tex[0] = R_GetTexture(texture);
969 m.pointer_texcoord[0] = spritetexcoord2f;
970 m.pointer_vertex = varray_vertex3f;
972 GL_Color(cr, cg, cb, ca);
973 R_Mesh_Draw(4, 2, polygonelements);