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_ColorPointer(NULL);
568 GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
570 vertex3f[0] = r_vieworigin[0] + r_viewforward[0] * 1.5 + r_viewleft[0] * r - r_viewup[0] * r;
571 vertex3f[1] = r_vieworigin[1] + r_viewforward[1] * 1.5 + r_viewleft[1] * r - r_viewup[1] * r;
572 vertex3f[2] = r_vieworigin[2] + r_viewforward[2] * 1.5 + r_viewleft[2] * r - r_viewup[2] * r;
573 vertex3f[3] = r_vieworigin[0] + r_viewforward[0] * 1.5 + r_viewleft[0] * r + r_viewup[0] * r * 3;
574 vertex3f[4] = r_vieworigin[1] + r_viewforward[1] * 1.5 + r_viewleft[1] * r + r_viewup[1] * r * 3;
575 vertex3f[5] = r_vieworigin[2] + r_viewforward[2] * 1.5 + r_viewleft[2] * r + r_viewup[2] * r * 3;
576 vertex3f[6] = r_vieworigin[0] + r_viewforward[0] * 1.5 - r_viewleft[0] * r * 3 - r_viewup[0] * r;
577 vertex3f[7] = r_vieworigin[1] + r_viewforward[1] * 1.5 - r_viewleft[1] * r * 3 - r_viewup[1] * r;
578 vertex3f[8] = r_vieworigin[2] + r_viewforward[2] * 1.5 - r_viewleft[2] * r * 3 - r_viewup[2] * r;
579 R_Mesh_Draw(3, 1, polygonelements);
582 void R_UpdateWorld(void)
584 if (!r_refdef.entities/* || !cl.worldmodel*/)
585 return; //Host_Error ("R_RenderView: NULL worldmodel");
587 if (r_shadow_realtime_world.integer && !gl_stencil)
589 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");
590 Cvar_SetValueQuick(&r_shadow_realtime_world, 0);
593 // don't allow cheats in multiplayer
596 if (r_fullbright.integer != 0)
597 Cvar_Set ("r_fullbright", "0");
598 if (r_ambient.value != 0)
599 Cvar_Set ("r_ambient", "0");
607 void R_RenderScene(void);
614 void R_RenderView(void)
616 if (!r_refdef.entities/* || !cl.worldmodel*/)
617 return; //Host_Error ("R_RenderView: NULL worldmodel");
619 r_view_width = bound(0, r_refdef.width, vid.realwidth);
620 r_view_height = bound(0, r_refdef.height, vid.realheight);
621 r_view_x = bound(0, r_refdef.x, vid.realwidth - r_refdef.width);
622 r_view_y = bound(0, r_refdef.y, vid.realheight - r_refdef.height);
623 r_view_fov_x = bound(1, r_refdef.fov_x, 170);
624 r_view_fov_y = bound(1, r_refdef.fov_y, 170);
625 r_view_matrix = r_refdef.viewentitymatrix;
627 // GL is weird because it's bottom to top, r_view_y is top to bottom
628 qglViewport(r_view_x, vid.realheight - (r_view_y + r_view_height), r_view_width, r_view_height);
629 GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height);
630 GL_ScissorTest(true);
632 R_TimeReport("setup");
634 qglDepthFunc(GL_LEQUAL);
635 qglPolygonOffset(0, 0);
636 qglEnable(GL_POLYGON_OFFSET_FILL);
640 qglPolygonOffset(0, 0);
641 qglDisable(GL_POLYGON_OFFSET_FILL);
644 R_TimeReport("blendview");
646 GL_Scissor(0, 0, vid.realwidth, vid.realheight);
647 GL_ScissorTest(false);
650 extern void R_DrawLightningBeams (void);
651 void R_RenderScene(void)
653 entity_render_t *world;
655 // don't let sound skip if going slow
656 if (!intimerefresh && !r_speeds.integer)
661 GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
665 r_farclip = R_FarClip(r_vieworigin, r_viewforward, 768.0f) + 256.0f;
666 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)))
667 GL_SetupView_Mode_PerspectiveInfiniteFarClip(r_view_fov_x, r_view_fov_y, 1.0f);
669 GL_SetupView_Mode_Perspective(r_view_fov_x, r_view_fov_y, 1.0f, r_farclip);
671 GL_SetupView_Orientation_FromEntity(&r_view_matrix);
675 if (cl.worldmodel && cl.worldmodel->brush.FatPVS)
676 cl.worldmodel->brush.FatPVS(cl.worldmodel, r_vieworigin, 2, r_pvsbits, sizeof(r_pvsbits));
677 world = &cl_entities[0].render;
678 R_WorldVisibility(world);
679 R_TimeReport("worldvis");
682 R_TimeReport("markentity");
684 R_MeshQueue_BeginScene();
686 R_Shadow_UpdateWorldLightSelection();
688 // don't let sound skip if going slow
689 if (!intimerefresh && !r_speeds.integer)
692 if (R_DrawBrushModelsSky())
693 R_TimeReport("bmodelsky");
695 // must occur early because it can draw sky
697 R_TimeReport("world");
699 // don't let sound skip if going slow
700 if (!intimerefresh && !r_speeds.integer)
703 GL_ShowTrisColor(0, 0.015, 0, 1);
706 R_TimeReport("models");
708 // don't let sound skip if going slow
709 if (!intimerefresh && !r_speeds.integer)
712 GL_ShowTrisColor(0, 0, 0.033, 1);
713 R_ShadowVolumeLighting(false);
714 R_TimeReport("rtlights");
716 // don't let sound skip if going slow
717 if (!intimerefresh && !r_speeds.integer)
720 GL_ShowTrisColor(0.1, 0, 0, 1);
722 R_DrawLightningBeams();
723 R_TimeReport("lightning");
726 R_TimeReport("particles");
729 R_TimeReport("explosions");
731 R_MeshQueue_RenderTransparent();
732 R_TimeReport("drawtrans");
735 R_TimeReport("coronas");
737 R_DrawWorldCrosshair();
738 R_TimeReport("crosshair");
740 R_MeshQueue_Render();
741 R_MeshQueue_EndScene();
743 if (r_shadow_visiblevolumes.integer && !r_showtrispass)
745 R_ShadowVolumeLighting(true);
746 R_TimeReport("shadowvolume");
749 GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
751 // don't let sound skip if going slow
752 if (!intimerefresh && !r_speeds.integer)
757 void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, float ca)
760 float *v, *c, f1, f2, diff[3], vertex3f[8*3], color4f[8*4];
762 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
765 R_Mesh_Matrix(&r_identitymatrix);
767 memset(&m, 0, sizeof(m));
768 R_Mesh_State_Texture(&m);
771 vertex3f[ 0] = mins[0];vertex3f[ 1] = mins[1];vertex3f[ 2] = mins[2];
772 vertex3f[ 3] = maxs[0];vertex3f[ 4] = mins[1];vertex3f[ 5] = mins[2];
773 vertex3f[ 6] = mins[0];vertex3f[ 7] = maxs[1];vertex3f[ 8] = mins[2];
774 vertex3f[ 9] = maxs[0];vertex3f[10] = maxs[1];vertex3f[11] = mins[2];
775 vertex3f[12] = mins[0];vertex3f[13] = mins[1];vertex3f[14] = maxs[2];
776 vertex3f[15] = maxs[0];vertex3f[16] = mins[1];vertex3f[17] = maxs[2];
777 vertex3f[18] = mins[0];vertex3f[19] = maxs[1];vertex3f[20] = maxs[2];
778 vertex3f[21] = maxs[0];vertex3f[22] = maxs[1];vertex3f[23] = maxs[2];
779 GL_ColorPointer(color);
780 R_FillColors(color, 8, cr, cg, cb, ca);
783 for (i = 0, v = vertex, c = color;i < 8;i++, v += 4, c += 4)
785 VectorSubtract(v, r_vieworigin, diff);
786 f2 = exp(fogdensity/DotProduct(diff, diff));
788 c[0] = c[0] * f1 + fogcolor[0] * f2;
789 c[1] = c[1] * f1 + fogcolor[1] * f2;
790 c[2] = c[2] * f1 + fogcolor[2] * f2;
797 int nomodelelements[24] =
809 float nomodelvertex3f[6*3] =
819 float nomodelcolor4f[6*4] =
821 0.0f, 0.0f, 0.5f, 1.0f,
822 0.0f, 0.0f, 0.5f, 1.0f,
823 0.0f, 0.5f, 0.0f, 1.0f,
824 0.0f, 0.5f, 0.0f, 1.0f,
825 0.5f, 0.0f, 0.0f, 1.0f,
826 0.5f, 0.0f, 0.0f, 1.0f
829 void R_DrawNoModelCallback(const void *calldata1, int calldata2)
831 const entity_render_t *ent = calldata1;
833 float f1, f2, *c, diff[3];
836 R_Mesh_Matrix(&ent->matrix);
838 memset(&m, 0, sizeof(m));
839 R_Mesh_State_Texture(&m);
841 if (ent->flags & EF_ADDITIVE)
843 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
846 else if (ent->alpha < 1)
848 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
853 GL_BlendFunc(GL_ONE, GL_ZERO);
857 GL_VertexPointer(nomodelvertex3f);
860 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
861 GL_ColorPointer(color4f);
862 VectorSubtract(ent->origin, r_vieworigin, diff);
863 f2 = exp(fogdensity/DotProduct(diff, diff));
865 for (i = 0, c = color4f;i < 6;i++, c += 4)
867 c[0] = (c[0] * f1 + fogcolor[0] * f2);
868 c[1] = (c[1] * f1 + fogcolor[1] * f2);
869 c[2] = (c[2] * f1 + fogcolor[2] * f2);
873 else if (ent->alpha != 1)
875 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
876 GL_ColorPointer(color4f);
877 for (i = 0, c = color4f;i < 6;i++, c += 4)
881 GL_ColorPointer(nomodelcolor4f);
882 R_Mesh_Draw(6, 8, nomodelelements);
885 void R_DrawNoModel(entity_render_t *ent)
887 //if ((ent->effects & EF_ADDITIVE) || (ent->alpha < 1))
888 R_MeshQueue_AddTransparent(ent->origin, R_DrawNoModelCallback, ent, 0);
890 // R_DrawNoModelCallback(ent, 0);
893 void R_CalcBeam_Vertex3f (float *vert, const vec3_t org1, const vec3_t org2, float width)
895 vec3_t right1, right2, diff, normal;
897 VectorSubtract (org2, org1, normal);
898 VectorNormalizeFast (normal);
900 // calculate 'right' vector for start
901 VectorSubtract (r_vieworigin, org1, diff);
902 VectorNormalizeFast (diff);
903 CrossProduct (normal, diff, right1);
905 // calculate 'right' vector for end
906 VectorSubtract (r_vieworigin, org2, diff);
907 VectorNormalizeFast (diff);
908 CrossProduct (normal, diff, right2);
910 vert[ 0] = org1[0] + width * right1[0];
911 vert[ 1] = org1[1] + width * right1[1];
912 vert[ 2] = org1[2] + width * right1[2];
913 vert[ 3] = org1[0] - width * right1[0];
914 vert[ 4] = org1[1] - width * right1[1];
915 vert[ 5] = org1[2] - width * right1[2];
916 vert[ 6] = org2[0] - width * right2[0];
917 vert[ 7] = org2[1] - width * right2[1];
918 vert[ 8] = org2[2] - width * right2[2];
919 vert[ 9] = org2[0] + width * right2[0];
920 vert[10] = org2[1] + width * right2[1];
921 vert[11] = org2[2] + width * right2[2];
924 float spritetexcoord2f[4*2] = {0, 1, 0, 0, 1, 0, 1, 1};
926 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)
933 VectorSubtract(origin, r_vieworigin, diff);
934 ca *= 1 - exp(fogdensity/DotProduct(diff,diff));
937 R_Mesh_Matrix(&r_identitymatrix);
938 GL_ColorPointer(NULL);
939 GL_Color(cr, cg, cb, ca);
940 GL_VertexPointer(varray_vertex3f);
941 GL_BlendFunc(blendfunc1, blendfunc2);
943 GL_DepthTest(!depthdisable);
945 memset(&m, 0, sizeof(m));
946 m.tex[0] = R_GetTexture(texture);
947 m.pointer_texcoord[0] = spritetexcoord2f;
948 R_Mesh_State_Texture(&m);
950 varray_vertex3f[ 0] = origin[0] + left[0] * scalex2 + up[0] * scaley1;
951 varray_vertex3f[ 1] = origin[1] + left[1] * scalex2 + up[1] * scaley1;
952 varray_vertex3f[ 2] = origin[2] + left[2] * scalex2 + up[2] * scaley1;
953 varray_vertex3f[ 3] = origin[0] + left[0] * scalex2 + up[0] * scaley2;
954 varray_vertex3f[ 4] = origin[1] + left[1] * scalex2 + up[1] * scaley2;
955 varray_vertex3f[ 5] = origin[2] + left[2] * scalex2 + up[2] * scaley2;
956 varray_vertex3f[ 6] = origin[0] + left[0] * scalex1 + up[0] * scaley2;
957 varray_vertex3f[ 7] = origin[1] + left[1] * scalex1 + up[1] * scaley2;
958 varray_vertex3f[ 8] = origin[2] + left[2] * scalex1 + up[2] * scaley2;
959 varray_vertex3f[ 9] = origin[0] + left[0] * scalex1 + up[0] * scaley1;
960 varray_vertex3f[10] = origin[1] + left[1] * scalex1 + up[1] * scaley1;
961 varray_vertex3f[11] = origin[2] + left[2] * scalex1 + up[2] * scaley1;
962 R_Mesh_Draw(4, 2, polygonelements);