// r_main.c
#include "quakedef.h"
+#include "r_shadow.h"
// used for dlight push checking and other things
int r_framecount;
+// used for visibility checking
+qbyte r_pvsbits[(MAX_MAP_LEAFS+7)>>3];
+
mplane_t frustum[4];
matrix4x4_t r_identitymatrix;
float r_farclip;
+// forces all rendering to draw triangle outlines
+int r_showtrispass;
+
// view origin
-vec3_t r_origin;
-vec3_t vpn;
-vec3_t vright;
-vec3_t vup;
+vec3_t r_vieworigin;
+vec3_t r_viewforward;
+vec3_t r_viewleft;
+vec3_t r_viewright;
+vec3_t r_viewup;
+int r_view_x;
+int r_view_y;
+int r_view_z;
+int r_view_width;
+int r_view_height;
+int r_view_depth;
+float r_view_fov_x;
+float r_view_fov_y;
+matrix4x4_t r_view_matrix;
//
// screen size info
// 8.8 fraction of base light value
unsigned short d_lightstylevalue[256];
+cvar_t r_showtris = {0, "r_showtris", "0"};
cvar_t r_drawentities = {0, "r_drawentities","1"};
cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1"};
cvar_t r_speeds = {0, "r_speeds","0"};
cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1"};
cvar_t r_dynamic = {CVAR_SAVE, "r_dynamic","1"};
cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1"};
+cvar_t r_drawcollisionbrushes = {0, "r_drawcollisionbrushes", "0"};
cvar_t gl_fogenable = {0, "gl_fogenable", "0"};
cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25"};
cvar_t r_textureunits = {0, "r_textureunits", "32"};
+cvar_t r_lerpsprites = {CVAR_SAVE, "r_lerpsprites", "1"};
+cvar_t r_lerpmodels = {CVAR_SAVE, "r_lerpmodels", "1"};
+cvar_t r_waterscroll = {CVAR_SAVE, "r_waterscroll", "1"};
+cvar_t r_watershader = {CVAR_SAVE, "r_watershader", "1"};
+
+
void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
{
int i;
static void R_TimeRefresh_f (void)
{
int i;
- float start, stop, time;
+ float timestart, timedelta, oldangles[3];
intimerefresh = 1;
- start = Sys_DoubleTime ();
+ VectorCopy(cl.viewangles, oldangles);
+ VectorClear(cl.viewangles);
+
+ timestart = Sys_DoubleTime();
for (i = 0;i < 128;i++)
{
- r_refdef.viewangles[0] = 0;
- r_refdef.viewangles[1] = i/128.0*360.0;
- r_refdef.viewangles[2] = 0;
+ Matrix4x4_CreateFromQuakeEntity(&r_refdef.viewentitymatrix, r_vieworigin[0], r_vieworigin[1], r_vieworigin[2], 0, i / 128.0 * 360.0, 0, 1);
CL_UpdateScreen();
}
+ timedelta = Sys_DoubleTime() - timestart;
- stop = Sys_DoubleTime ();
+ VectorCopy(oldangles, cl.viewangles);
intimerefresh = 0;
- time = stop-start;
- Con_Printf ("%f seconds (%f fps)\n", time, 128/time);
+ Con_Printf("%f seconds (%f fps)\n", timedelta, 128/timedelta);
}
vec3_t fogcolor;
float fog_density, fog_red, fog_green, fog_blue;
qboolean fogenabled;
qboolean oldgl_fogenable;
-void R_SetupFog(void)
+void R_UpdateFog(void)
{
if (gamemode == GAME_NEHAHRA)
{
extern void CL_ParseEntityLump(char *entitystring);
void gl_main_newmap(void)
{
- if (cl.worldmodel && cl.worldmodel->entities)
- CL_ParseEntityLump(cl.worldmodel->entities);
+ int l;
+ char *entities, entname[MAX_QPATH];
r_framecount = 1;
+ if (cl.worldmodel)
+ {
+ strcpy(entname, cl.worldmodel->name);
+ l = strlen(entname) - 4;
+ if (l >= 0 && !strcmp(entname + l, ".bsp"))
+ {
+ strcpy(entname + l, ".ent");
+ if ((entities = FS_LoadFile(entname, tempmempool, true)))
+ {
+ CL_ParseEntityLump(entities);
+ Mem_Free(entities);
+ return;
+ }
+ }
+ if (cl.worldmodel->brush.entities)
+ CL_ParseEntityLump(cl.worldmodel->brush.entities);
+ }
}
void GL_Main_Init(void)
Matrix4x4_CreateIdentity(&r_identitymatrix);
// FIXME: move this to client?
FOG_registercvars();
- Cmd_AddCommand ("timerefresh", R_TimeRefresh_f);
- Cvar_RegisterVariable (&r_drawentities);
- Cvar_RegisterVariable (&r_drawviewmodel);
- Cvar_RegisterVariable (&r_speeds);
- Cvar_RegisterVariable (&r_fullbrights);
- Cvar_RegisterVariable (&r_wateralpha);
- Cvar_RegisterVariable (&r_dynamic);
- Cvar_RegisterVariable (&r_fullbright);
- Cvar_RegisterVariable (&r_textureunits);
- if (gamemode == GAME_NEHAHRA)
+ Cmd_AddCommand("timerefresh", R_TimeRefresh_f);
+ Cvar_RegisterVariable(&r_showtris);
+ Cvar_RegisterVariable(&r_drawentities);
+ Cvar_RegisterVariable(&r_drawviewmodel);
+ Cvar_RegisterVariable(&r_speeds);
+ Cvar_RegisterVariable(&r_fullbrights);
+ Cvar_RegisterVariable(&r_wateralpha);
+ Cvar_RegisterVariable(&r_dynamic);
+ Cvar_RegisterVariable(&r_fullbright);
+ Cvar_RegisterVariable(&r_textureunits);
+ Cvar_RegisterVariable(&r_lerpsprites);
+ Cvar_RegisterVariable(&r_lerpmodels);
+ Cvar_RegisterVariable(&r_waterscroll);
+ Cvar_RegisterVariable(&r_watershader);
+ Cvar_RegisterVariable(&r_drawcollisionbrushes);
+ if (gamemode == GAME_NEHAHRA || gamemode == GAME_NEXUIZ || gamemode == GAME_TENEBRAE)
Cvar_SetValue("r_fullbrights", 0);
R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap);
}
-vec3_t r_farclip_origin;
-vec3_t r_farclip_direction;
-vec_t r_farclip_directiondist;
-vec_t r_farclip_meshfarclip;
-int r_farclip_directionbit0;
-int r_farclip_directionbit1;
-int r_farclip_directionbit2;
-
-// start a farclip measuring session
-void R_FarClip_Start(vec3_t origin, vec3_t direction, vec_t startfarclip)
-{
- VectorCopy(origin, r_farclip_origin);
- VectorCopy(direction, r_farclip_direction);
- r_farclip_directiondist = DotProduct(r_farclip_origin, r_farclip_direction);
- r_farclip_directionbit0 = r_farclip_direction[0] < 0;
- r_farclip_directionbit1 = r_farclip_direction[1] < 0;
- r_farclip_directionbit2 = r_farclip_direction[2] < 0;
- r_farclip_meshfarclip = r_farclip_directiondist + startfarclip;
-}
+static vec3_t r_farclip_origin;
+static vec3_t r_farclip_direction;
+static vec_t r_farclip_directiondist;
+static vec_t r_farclip_meshfarclip;
+static int r_farclip_directionbit0;
+static int r_farclip_directionbit1;
+static int r_farclip_directionbit2;
// enlarge farclip to accomodate box
-void R_FarClip_Box(vec3_t mins, vec3_t maxs)
+static void R_FarClip_Box(vec3_t mins, vec3_t maxs)
{
float d;
d = (r_farclip_directionbit0 ? mins[0] : maxs[0]) * r_farclip_direction[0]
}
// return farclip value
-float R_FarClip_Finish(void)
+static float R_FarClip(vec3_t origin, vec3_t direction, vec_t startfarclip)
{
- return r_farclip_meshfarclip - r_farclip_directiondist;
-}
+ int i;
-/*
-===============
-R_NewMap
-===============
-*/
-void R_NewMap (void)
-{
- R_Modules_NewMap();
+ VectorCopy(origin, r_farclip_origin);
+ VectorCopy(direction, r_farclip_direction);
+ r_farclip_directiondist = DotProduct(r_farclip_origin, r_farclip_direction);
+ r_farclip_directionbit0 = r_farclip_direction[0] < 0;
+ r_farclip_directionbit1 = r_farclip_direction[1] < 0;
+ r_farclip_directionbit2 = r_farclip_direction[2] < 0;
+ r_farclip_meshfarclip = r_farclip_directiondist + startfarclip;
+
+ if (cl.worldmodel)
+ R_FarClip_Box(cl.worldmodel->normalmins, cl.worldmodel->normalmaxs);
+ for (i = 0;i < r_refdef.numentities;i++)
+ R_FarClip_Box(r_refdef.entities[i]->mins, r_refdef.entities[i]->maxs);
+
+ return r_farclip_meshfarclip - r_farclip_directiondist;
}
extern void R_Textures_Init(void);
extern void Mod_RenderInit(void);
extern void GL_Draw_Init(void);
extern void GL_Main_Init(void);
+extern void R_Shadow_Init(void);
extern void GL_Models_Init(void);
extern void R_Sky_Init(void);
extern void GL_Surf_Init(void);
extern void R_Explosion_Init(void);
extern void ui_init(void);
extern void gl_backend_init(void);
+extern void Sbar_Init(void);
+extern void R_LightningBeams_Init(void);
void Render_Init(void)
{
- R_Modules_Shutdown();
R_Textures_Init();
Mod_RenderInit();
gl_backend_init();
R_MeshQueue_Init();
GL_Draw_Init();
GL_Main_Init();
+ R_Shadow_Init();
GL_Models_Init();
R_Sky_Init();
GL_Surf_Init();
R_Light_Init();
R_Particles_Init();
R_Explosion_Init();
- ui_init();
- R_Modules_Start();
+ //ui_init();
+ UI_Init();
+ Sbar_Init();
+ R_LightningBeams_Init();
}
/*
VID_CheckExtensions();
// LordHavoc: report supported extensions
- Con_Printf ("\nengine extensions: %s\n", ENGINE_EXTENSIONS);
-
- qglCullFace(GL_FRONT);
- qglEnable(GL_TEXTURE_2D);
+ Con_DPrintf("\nengine extensions: %s\n", ENGINE_EXTENSIONS);
}
-int R_CullBox(const vec3_t emins, const vec3_t emaxs)
+int R_CullBox(const vec3_t mins, const vec3_t maxs)
{
int i;
mplane_t *p;
{
default:
case 0:
- if (p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2] < p->dist)
+ if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
return true;
break;
case 1:
- if (p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2] < p->dist)
+ if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
return true;
break;
case 2:
- if (p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2] < p->dist)
+ if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
return true;
break;
case 3:
- if (p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2] < p->dist)
+ if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
return true;
break;
case 4:
- if (p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2] < p->dist)
+ if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
return true;
break;
case 5:
- if (p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2] < p->dist)
+ if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
return true;
break;
case 6:
- if (p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2] < p->dist)
+ if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
return true;
break;
case 7:
- if (p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2] < p->dist)
+ if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
return true;
break;
}
return false;
}
-int R_NotCulledBox(const vec3_t emins, const vec3_t emaxs)
-{
- int i;
- mplane_t *p;
- for (i = 0;i < 4;i++)
- {
- p = frustum + i;
- switch(p->signbits)
- {
- default:
- case 0:
- if (p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2] < p->dist)
- return false;
- break;
- case 1:
- if (p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2] < p->dist)
- return false;
- break;
- case 2:
- if (p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2] < p->dist)
- return false;
- break;
- case 3:
- if (p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2] < p->dist)
- return false;
- break;
- case 4:
- if (p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2] < p->dist)
- return false;
- break;
- case 5:
- if (p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2] < p->dist)
- return false;
- break;
- case 6:
- if (p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2] < p->dist)
- return false;
- break;
- case 7:
- if (p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2] < p->dist)
- return false;
- break;
- }
- }
- return true;
-}
-
-
//==================================================================================
static void R_MarkEntities (void)
{
int i;
- vec3_t v;
entity_render_t *ent;
ent = &cl_entities[0].render;
Matrix4x4_CreateIdentity(&ent->matrix);
Matrix4x4_CreateIdentity(&ent->inversematrix);
- if (cl.worldmodel)
- R_FarClip_Box(cl.worldmodel->normalmins, cl.worldmodel->normalmaxs);
-
if (!r_drawentities.integer)
return;
{
ent = r_refdef.entities[i];
Mod_CheckLoaded(ent->model);
-
- // move view-relative models to where they should be
- if (ent->flags & RENDER_VIEWMODEL)
- {
- // remove flag so it will not be repeated incase RelinkEntities is not called again for a while
- ent->flags -= RENDER_VIEWMODEL;
- // transform origin
- VectorCopy(ent->origin, v);
- ent->origin[0] = v[0] * vpn[0] + v[1] * vright[0] + v[2] * vup[0] + r_origin[0];
- ent->origin[1] = v[0] * vpn[1] + v[1] * vright[1] + v[2] * vup[1] + r_origin[1];
- ent->origin[2] = v[0] * vpn[2] + v[1] * vright[2] + v[2] * vup[2] + r_origin[2];
- // adjust angles
- VectorAdd(ent->angles, r_refdef.viewangles, ent->angles);
- }
-
- if (R_CullBox(ent->mins, ent->maxs))
- continue;
-
- ent->visframe = r_framecount;
- VectorCopy(ent->angles, v);
- if (!ent->model || ent->model->type != mod_brush)
- v[0] = -v[0];
- Matrix4x4_CreateFromQuakeEntity(&ent->matrix, ent->origin[0], ent->origin[1], ent->origin[2], v[0], v[1], v[2], ent->scale);
- Matrix4x4_Invert_Simple(&ent->inversematrix, &ent->matrix);
+ // some of the renderer still relies on origin...
+ Matrix4x4_OriginFromMatrix(&ent->matrix, ent->origin);
+ // some of the renderer still relies on scale...
+ ent->scale = Matrix4x4_ScaleFromMatrix(&ent->matrix);
R_LerpAnimation(ent);
R_UpdateEntLights(ent);
- R_FarClip_Box(ent->mins, ent->maxs);
+ if ((chase_active.integer || !(ent->flags & RENDER_EXTERIORMODEL))
+ && !VIS_CullBox(ent->mins, ent->maxs)
+ && (!envmap || !(ent->flags & (RENDER_VIEWMODEL | RENDER_EXTERIORMODEL))))
+ ent->visframe = r_framecount;
}
}
R_DrawViewModel
=============
*/
+/*
void R_DrawViewModel (void)
{
entity_render_t *ent;
R_UpdateEntLights(ent);
ent->model->Draw(ent);
}
+*/
void R_DrawNoModel(entity_render_t *ent);
-void R_DrawModels (void)
+void R_DrawModels(void)
{
int i;
entity_render_t *ent;
if (!r_drawentities.integer)
return;
- R_DrawViewModel();
for (i = 0;i < r_refdef.numentities;i++)
{
ent = r_refdef.entities[i];
if (ent->visframe == r_framecount)
{
- if (ent->model)
- {
- if (ent->model->Draw)
- ent->model->Draw(ent);
- }
+ if (ent->model && ent->model->Draw != NULL)
+ ent->model->Draw(ent);
else
R_DrawNoModel(ent);
}
}
}
-static void R_SetFrustum (void)
+static void R_SetFrustum(void)
{
- int i;
+ // break apart the view matrix into vectors for various purposes
+ Matrix4x4_ToVectors(&r_view_matrix, r_viewforward, r_viewleft, r_viewup, r_vieworigin);
+ VectorNegate(r_viewleft, r_viewright);
// LordHavoc: note to all quake engine coders, the special case for 90
// degrees assumed a square view (wrong), so I removed it, Quake2 has it
// disabled as well.
- // rotate VPN right by FOV_X/2 degrees
- RotatePointAroundVector( frustum[0].normal, vup, vpn, -(90-r_refdef.fov_x / 2 ) );
- // rotate VPN left by FOV_X/2 degrees
- RotatePointAroundVector( frustum[1].normal, vup, vpn, 90-r_refdef.fov_x / 2 );
- // rotate VPN up by FOV_X/2 degrees
- RotatePointAroundVector( frustum[2].normal, vright, vpn, 90-r_refdef.fov_y / 2 );
- // rotate VPN down by FOV_X/2 degrees
- RotatePointAroundVector( frustum[3].normal, vright, vpn, -( 90 - r_refdef.fov_y / 2 ) );
-
- for (i = 0;i < 4;i++)
- {
- frustum[i].type = PLANE_ANYZ;
- frustum[i].dist = DotProduct (r_origin, frustum[i].normal);
- PlaneClassify(&frustum[i]);
- }
-}
-
-/*
-===============
-R_SetupFrame
-===============
-*/
-static void R_SetupFrame (void)
-{
-// don't allow cheats in multiplayer
- if (cl.maxclients > 1)
- {
- if (r_fullbright.integer != 0)
- Cvar_Set ("r_fullbright", "0");
- if (r_ambient.value != 0)
- Cvar_Set ("r_ambient", "0");
- }
-
- r_framecount++;
-// build the transformation matrix for the given view angles
- VectorCopy (r_refdef.vieworg, r_origin);
-
- AngleVectors (r_refdef.viewangles, vpn, vright, vup);
-
- R_AnimateLight ();
+ // rotate R_VIEWFORWARD right by FOV_X/2 degrees
+ RotatePointAroundVector( frustum[0].normal, r_viewup, r_viewforward, -(90 - r_view_fov_x / 2));
+ frustum[0].dist = DotProduct (r_vieworigin, frustum[0].normal);
+ PlaneClassify(&frustum[0]);
+
+ // rotate R_VIEWFORWARD left by FOV_X/2 degrees
+ RotatePointAroundVector( frustum[1].normal, r_viewup, r_viewforward, (90 - r_view_fov_x / 2));
+ frustum[1].dist = DotProduct (r_vieworigin, frustum[1].normal);
+ PlaneClassify(&frustum[1]);
+
+ // rotate R_VIEWFORWARD up by FOV_X/2 degrees
+ RotatePointAroundVector( frustum[2].normal, r_viewleft, r_viewforward, -(90 - r_view_fov_y / 2));
+ frustum[2].dist = DotProduct (r_vieworigin, frustum[2].normal);
+ PlaneClassify(&frustum[2]);
+
+ // rotate R_VIEWFORWARD down by FOV_X/2 degrees
+ RotatePointAroundVector( frustum[3].normal, r_viewleft, r_viewforward, (90 - r_view_fov_y / 2));
+ frustum[3].dist = DotProduct (r_vieworigin, frustum[3].normal);
+ PlaneClassify(&frustum[3]);
}
-
static void R_BlendView(void)
{
rmeshstate_t m;
float r;
+ float vertex3f[3*3];
if (r_refdef.viewblend[3] < 0.01f)
return;
- memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
- m.wantoverbright = false;
- m.depthdisable = true; // magic
R_Mesh_Matrix(&r_identitymatrix);
+
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = vertex3f;
R_Mesh_State(&m);
- varray_color[0] = varray_color[4] = varray_color[8] = r_refdef.viewblend[0];
- varray_color[1] = varray_color[5] = varray_color[9] = r_refdef.viewblend[1];
- varray_color[2] = varray_color[6] = varray_color[10] = r_refdef.viewblend[2];
- varray_color[3] = varray_color[7] = varray_color[11] = r_refdef.viewblend[3];
- r = 64000;
- varray_vertex[0] = r_origin[0] + vpn[0] * 1.5 - vright[0] * r - vup[0] * r;
- varray_vertex[1] = r_origin[1] + vpn[1] * 1.5 - vright[1] * r - vup[1] * r;
- varray_vertex[2] = r_origin[2] + vpn[2] * 1.5 - vright[2] * r - vup[2] * r;
- r *= 3;
- varray_vertex[4] = varray_vertex[0] + vup[0] * r;
- varray_vertex[5] = varray_vertex[1] + vup[1] * r;
- varray_vertex[6] = varray_vertex[2] + vup[2] * r;
- varray_vertex[8] = varray_vertex[0] + vright[0] * r;
- varray_vertex[9] = varray_vertex[1] + vright[1] * r;
- varray_vertex[10] = varray_vertex[2] + vright[2] * r;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GL_DepthMask(true);
+ GL_DepthTest(false); // magic
+ GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
+ r = 64;
+ vertex3f[0] = r_vieworigin[0] + r_viewforward[0] * 1.5 + r_viewleft[0] * r - r_viewup[0] * r;
+ vertex3f[1] = r_vieworigin[1] + r_viewforward[1] * 1.5 + r_viewleft[1] * r - r_viewup[1] * r;
+ vertex3f[2] = r_vieworigin[2] + r_viewforward[2] * 1.5 + r_viewleft[2] * r - r_viewup[2] * r;
+ vertex3f[3] = r_vieworigin[0] + r_viewforward[0] * 1.5 + r_viewleft[0] * r + r_viewup[0] * r * 3;
+ vertex3f[4] = r_vieworigin[1] + r_viewforward[1] * 1.5 + r_viewleft[1] * r + r_viewup[1] * r * 3;
+ vertex3f[5] = r_vieworigin[2] + r_viewforward[2] * 1.5 + r_viewleft[2] * r + r_viewup[2] * r * 3;
+ vertex3f[6] = r_vieworigin[0] + r_viewforward[0] * 1.5 - r_viewleft[0] * r * 3 - r_viewup[0] * r;
+ vertex3f[7] = r_vieworigin[1] + r_viewforward[1] * 1.5 - r_viewleft[1] * r * 3 - r_viewup[1] * r;
+ vertex3f[8] = r_vieworigin[2] + r_viewforward[2] * 1.5 - r_viewleft[2] * r * 3 - r_viewup[2] * r;
R_Mesh_Draw(3, 1, polygonelements);
}
+void R_UpdateWorld(void)
+{
+ if (!r_refdef.entities/* || !cl.worldmodel*/)
+ return; //Host_Error ("R_RenderView: NULL worldmodel");
+
+ if (r_shadow_realtime_world.integer && !gl_stencil)
+ {
+ 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");
+ Cvar_SetValueQuick(&r_shadow_realtime_world, 0);
+ }
+
+ // don't allow cheats in multiplayer
+ if (!cl.islocalgame && cl.worldmodel)
+ {
+ if (r_fullbright.integer != 0)
+ Cvar_Set ("r_fullbright", "0");
+ if (r_ambient.value != 0)
+ Cvar_Set ("r_ambient", "0");
+ }
+
+ R_Textures_Frame();
+ R_UpdateFog();
+ R_UpdateLights();
+}
+
+void R_RenderScene(void);
+
/*
================
R_RenderView
-
-r_refdef must be set before the first call
================
*/
-void R_RenderView (void)
+void R_RenderView(void)
{
- entity_render_t *world;
if (!r_refdef.entities/* || !cl.worldmodel*/)
return; //Host_Error ("R_RenderView: NULL worldmodel");
+
+ r_view_width = bound(0, r_refdef.width, vid.realwidth);
+ r_view_height = bound(0, r_refdef.height, vid.realheight);
+ r_view_depth = 1;
+ r_view_x = bound(0, r_refdef.x, vid.realwidth - r_refdef.width);
+ r_view_y = bound(0, r_refdef.y, vid.realheight - r_refdef.height);
+ r_view_z = 0;
+ r_view_fov_x = bound(1, r_refdef.fov_x, 170);
+ r_view_fov_y = bound(1, r_refdef.fov_y, 170);
+ r_view_matrix = r_refdef.viewentitymatrix;
+
+ // GL is weird because it's bottom to top, r_view_y is top to bottom
+ qglViewport(r_view_x, vid.realheight - (r_view_y + r_view_height), r_view_width, r_view_height);
+ GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height);
+ GL_ScissorTest(true);
+ R_ClearScreen();
+ R_TimeReport("setup");
- world = &cl_entities[0].render;
+ qglDepthFunc(GL_LEQUAL);
+ qglPolygonOffset(0, 0);
+ qglEnable(GL_POLYGON_OFFSET_FILL);
- // FIXME: move to client
- R_MoveExplosions();
- R_TimeReport("mexplosion");
+ R_RenderScene();
+
+ qglPolygonOffset(0, 0);
+ qglDisable(GL_POLYGON_OFFSET_FILL);
+
+ R_BlendView();
+ R_TimeReport("blendview");
+
+ GL_Scissor(0, 0, vid.realwidth, vid.realheight);
+ GL_ScissorTest(false);
+}
+
+extern void R_DrawLightningBeams (void);
+void R_RenderScene(void)
+{
+ entity_render_t *world;
+
+ // don't let sound skip if going slow
+ if (!intimerefresh && !r_speeds.integer)
+ S_ExtraUpdate ();
+
+ r_framecount++;
+
+ GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
- R_Textures_Frame();
- R_SetupFrame();
R_SetFrustum();
- R_SetupFog();
+
+ r_farclip = R_FarClip(r_vieworigin, r_viewforward, 768.0f) + 256.0f;
+ if (gl_stencil && (r_shadow_realtime_world.integer || (r_shadow_realtime_dlight.integer && r_shadow_realtime_dlight_shadows.integer)))
+ GL_SetupView_Mode_PerspectiveInfiniteFarClip(r_view_fov_x, r_view_fov_y, 1.0f);
+ else
+ GL_SetupView_Mode_Perspective(r_view_fov_x, r_view_fov_y, 1.0f, r_farclip);
+
+ GL_SetupView_Orientation_FromEntity(&r_view_matrix);
+
R_SkyStartFrame();
- R_BuildLightList();
- R_TimeReport("setup");
- R_FarClip_Start(r_origin, vpn, 768.0f);
+ if (cl.worldmodel && cl.worldmodel->brush.FatPVS)
+ cl.worldmodel->brush.FatPVS(cl.worldmodel, r_vieworigin, 2, r_pvsbits, sizeof(r_pvsbits));
+ world = &cl_entities[0].render;
+ R_WorldVisibility(world);
+ R_TimeReport("worldvis");
+
R_MarkEntities();
- r_farclip = R_FarClip_Finish() + 256.0f;
R_TimeReport("markentity");
- R_Mesh_Start(r_farclip);
R_MeshQueue_BeginScene();
+ R_Shadow_UpdateWorldLightSelection();
+
+ // don't let sound skip if going slow
+ if (!intimerefresh && !r_speeds.integer)
+ S_ExtraUpdate ();
+
+ GL_ShowTrisColor(0.025, 0.025, 0, 1);
+ if (world->model && world->model->DrawSky)
+ {
+ world->model->DrawSky(world);
+ R_TimeReport("worldsky");
+ }
+
if (R_DrawBrushModelsSky())
R_TimeReport("bmodelsky");
- // must occur early because it can draw sky
- R_DrawWorld(world);
- R_TimeReport("world");
+ GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
+ if (world->model && world->model->Draw)
+ {
+ world->model->Draw(world);
+ R_TimeReport("world");
+ }
// don't let sound skip if going slow
if (!intimerefresh && !r_speeds.integer)
S_ExtraUpdate ();
+ GL_ShowTrisColor(0, 0.015, 0, 1);
+
R_DrawModels();
R_TimeReport("models");
+ // don't let sound skip if going slow
+ if (!intimerefresh && !r_speeds.integer)
+ S_ExtraUpdate ();
+
+ GL_ShowTrisColor(0, 0, 0.033, 1);
+ R_ShadowVolumeLighting(false);
+ R_TimeReport("rtlights");
+
+ // don't let sound skip if going slow
+ if (!intimerefresh && !r_speeds.integer)
+ S_ExtraUpdate ();
+
+ GL_ShowTrisColor(0.1, 0, 0, 1);
+
+ R_DrawLightningBeams();
+ R_TimeReport("lightning");
+
R_DrawParticles();
R_TimeReport("particles");
R_DrawCoronas();
R_TimeReport("coronas");
- R_DrawCrosshair();
+ R_DrawWorldCrosshair();
R_TimeReport("crosshair");
- R_BlendView();
- R_TimeReport("blendview");
-
R_MeshQueue_Render();
R_MeshQueue_EndScene();
- R_Mesh_Finish();
- R_TimeReport("meshfinish");
+
+ if (r_shadow_visiblevolumes.integer && !r_showtrispass)
+ {
+ R_ShadowVolumeLighting(true);
+ R_TimeReport("shadowvolume");
+ }
+
+ GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
+
+ // don't let sound skip if going slow
+ if (!intimerefresh && !r_speeds.integer)
+ S_ExtraUpdate ();
}
/*
void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, float ca)
{
int i;
- float *v, *c, f1, f2, diff[3];
+ float *v, *c, f1, f2, diff[3], vertex3f[8*3], color4f[8*4];
rmeshstate_t m;
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
- m.wantoverbright = false;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GL_DepthMask(false);
+ GL_DepthTest(true);
R_Mesh_Matrix(&r_identitymatrix);
- R_Mesh_State(&m);
- varray_vertex[ 0] = mins[0];varray_vertex[ 1] = mins[1];varray_vertex[ 2] = mins[2];
- varray_vertex[ 4] = maxs[0];varray_vertex[ 5] = mins[1];varray_vertex[ 6] = mins[2];
- varray_vertex[ 8] = mins[0];varray_vertex[ 9] = maxs[1];varray_vertex[10] = mins[2];
- varray_vertex[12] = maxs[0];varray_vertex[13] = maxs[1];varray_vertex[14] = mins[2];
- varray_vertex[16] = mins[0];varray_vertex[17] = mins[1];varray_vertex[18] = maxs[2];
- varray_vertex[20] = maxs[0];varray_vertex[21] = mins[1];varray_vertex[22] = maxs[2];
- varray_vertex[24] = mins[0];varray_vertex[25] = maxs[1];varray_vertex[26] = maxs[2];
- varray_vertex[28] = maxs[0];varray_vertex[29] = maxs[1];varray_vertex[30] = maxs[2];
- varray_color[ 0] = varray_color[ 4] = varray_color[ 8] = varray_color[12] = varray_color[16] = varray_color[20] = varray_color[24] = varray_color[28] = cr * mesh_colorscale;
- varray_color[ 1] = varray_color[ 5] = varray_color[ 9] = varray_color[13] = varray_color[17] = varray_color[21] = varray_color[25] = varray_color[29] = cg * mesh_colorscale;
- varray_color[ 2] = varray_color[ 6] = varray_color[10] = varray_color[14] = varray_color[18] = varray_color[22] = varray_color[26] = varray_color[30] = cb * mesh_colorscale;
- varray_color[ 3] = varray_color[ 7] = varray_color[11] = varray_color[15] = varray_color[19] = varray_color[23] = varray_color[27] = varray_color[31] = ca;
+ vertex3f[ 0] = mins[0];vertex3f[ 1] = mins[1];vertex3f[ 2] = mins[2];
+ vertex3f[ 3] = maxs[0];vertex3f[ 4] = mins[1];vertex3f[ 5] = mins[2];
+ vertex3f[ 6] = mins[0];vertex3f[ 7] = maxs[1];vertex3f[ 8] = mins[2];
+ vertex3f[ 9] = maxs[0];vertex3f[10] = maxs[1];vertex3f[11] = mins[2];
+ vertex3f[12] = mins[0];vertex3f[13] = mins[1];vertex3f[14] = maxs[2];
+ vertex3f[15] = maxs[0];vertex3f[16] = mins[1];vertex3f[17] = maxs[2];
+ vertex3f[18] = mins[0];vertex3f[19] = maxs[1];vertex3f[20] = maxs[2];
+ vertex3f[21] = maxs[0];vertex3f[22] = maxs[1];vertex3f[23] = maxs[2];
+ R_FillColors(color, 8, cr, cg, cb, ca);
if (fogenabled)
{
- for (i = 0, v = varray_vertex, c = varray_color;i < 8;i++, v += 4, c += 4)
+ for (i = 0, v = vertex, c = color;i < 8;i++, v += 4, c += 4)
{
- VectorSubtract(v, r_origin, diff);
+ VectorSubtract(v, r_vieworigin, diff);
f2 = exp(fogdensity/DotProduct(diff, diff));
f1 = 1 - f2;
- f2 *= mesh_colorscale;
c[0] = c[0] * f1 + fogcolor[0] * f2;
c[1] = c[1] * f1 + fogcolor[1] * f2;
c[2] = c[2] * f1 + fogcolor[2] * f2;
}
}
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = vertex3f;
+ m.pointer_color = color;
+ R_Mesh_State(&m);
R_Mesh_Draw(8, 12);
}
*/
+int nomodelelements[24] =
+{
+ 5, 2, 0,
+ 5, 1, 2,
+ 5, 0, 3,
+ 5, 3, 1,
+ 0, 2, 4,
+ 2, 1, 4,
+ 3, 0, 4,
+ 1, 3, 4
+};
+
+float nomodelvertex3f[6*3] =
+{
+ -16, 0, 0,
+ 16, 0, 0,
+ 0, -16, 0,
+ 0, 16, 0,
+ 0, 0, -16,
+ 0, 0, 16
+};
+
+float nomodelcolor4f[6*4] =
+{
+ 0.0f, 0.0f, 0.5f, 1.0f,
+ 0.0f, 0.0f, 0.5f, 1.0f,
+ 0.0f, 0.5f, 0.0f, 1.0f,
+ 0.0f, 0.5f, 0.0f, 1.0f,
+ 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, 0.0f, 0.0f, 1.0f
+};
+
void R_DrawNoModelCallback(const void *calldata1, int calldata2)
{
const entity_render_t *ent = calldata1;
- int i, element[24];
+ int i;
float f1, f2, *c, diff[3];
+ float color4f[6*4];
rmeshstate_t m;
+ R_Mesh_Matrix(&ent->matrix);
+
memset(&m, 0, sizeof(m));
+ m.pointer_vertex = nomodelvertex3f;
+
if (ent->flags & EF_ADDITIVE)
{
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ GL_DepthMask(false);
}
else if (ent->alpha < 1)
{
- m.blendfunc1 = GL_SRC_ALPHA;
- m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GL_DepthMask(false);
}
else
{
- m.blendfunc1 = GL_ONE;
- m.blendfunc2 = GL_ZERO;
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ GL_DepthMask(true);
}
- m.wantoverbright = false;
- R_Mesh_Matrix(&ent->matrix);
- R_Mesh_State(&m);
-
- element[ 0] = 5;element[ 1] = 2;element[ 2] = 0;
- element[ 3] = 5;element[ 4] = 1;element[ 5] = 2;
- element[ 6] = 5;element[ 7] = 0;element[ 8] = 3;
- element[ 9] = 5;element[10] = 3;element[11] = 1;
- element[12] = 0;element[13] = 2;element[14] = 4;
- element[15] = 2;element[16] = 1;element[17] = 4;
- element[18] = 3;element[19] = 0;element[20] = 4;
- element[21] = 1;element[22] = 3;element[23] = 4;
- varray_vertex[ 0] = -16;varray_vertex[ 1] = 0;varray_vertex[ 2] = 0;
- varray_vertex[ 4] = 16;varray_vertex[ 5] = 0;varray_vertex[ 6] = 0;
- varray_vertex[ 8] = 0;varray_vertex[ 9] = -16;varray_vertex[10] = 0;
- varray_vertex[12] = 0;varray_vertex[13] = 16;varray_vertex[14] = 0;
- varray_vertex[16] = 0;varray_vertex[17] = 0;varray_vertex[18] = -16;
- varray_vertex[20] = 0;varray_vertex[21] = 0;varray_vertex[22] = 16;
- varray_color[ 0] = 0.00f;varray_color[ 1] = 0.00f;varray_color[ 2] = 0.50f;varray_color[ 3] = ent->alpha;
- varray_color[ 4] = 0.00f;varray_color[ 5] = 0.00f;varray_color[ 6] = 0.50f;varray_color[ 7] = ent->alpha;
- varray_color[ 8] = 0.00f;varray_color[ 9] = 0.50f;varray_color[10] = 0.00f;varray_color[11] = ent->alpha;
- varray_color[12] = 0.00f;varray_color[13] = 0.50f;varray_color[14] = 0.00f;varray_color[15] = ent->alpha;
- varray_color[16] = 0.50f;varray_color[17] = 0.00f;varray_color[18] = 0.00f;varray_color[19] = ent->alpha;
- varray_color[20] = 0.50f;varray_color[21] = 0.00f;varray_color[22] = 0.00f;varray_color[23] = ent->alpha;
+ GL_DepthTest(true);
if (fogenabled)
{
- VectorSubtract(ent->origin, r_origin, diff);
+ memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
+ m.pointer_color = color4f;
+ VectorSubtract(ent->origin, r_vieworigin, diff);
f2 = exp(fogdensity/DotProduct(diff, diff));
f1 = 1 - f2;
- for (i = 0, c = varray_color;i < 6;i++, c += 4)
+ for (i = 0, c = color4f;i < 6;i++, c += 4)
{
- c[0] = (c[0] * f1 + fogcolor[0] * f2) * mesh_colorscale;
- c[1] = (c[1] * f1 + fogcolor[1] * f2) * mesh_colorscale;
- c[2] = (c[2] * f1 + fogcolor[2] * f2) * mesh_colorscale;
+ c[0] = (c[0] * f1 + fogcolor[0] * f2);
+ c[1] = (c[1] * f1 + fogcolor[1] * f2);
+ c[2] = (c[2] * f1 + fogcolor[2] * f2);
+ c[3] *= ent->alpha;
}
}
- else
+ else if (ent->alpha != 1)
{
- for (i = 0, c = varray_color;i < 6;i++, c += 4)
- {
- c[0] *= mesh_colorscale;
- c[1] *= mesh_colorscale;
- c[2] *= mesh_colorscale;
- }
+ memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
+ m.pointer_color = color4f;
+ for (i = 0, c = color4f;i < 6;i++, c += 4)
+ c[3] *= ent->alpha;
}
- R_Mesh_Draw(6, 8, element);
+ else
+ m.pointer_color = nomodelcolor4f;
+ R_Mesh_State(&m);
+ R_Mesh_Draw(6, 8, nomodelelements);
}
void R_DrawNoModel(entity_render_t *ent)
// R_DrawNoModelCallback(ent, 0);
}
+void R_CalcBeam_Vertex3f (float *vert, const vec3_t org1, const vec3_t org2, float width)
+{
+ vec3_t right1, right2, diff, normal;
+
+ VectorSubtract (org2, org1, normal);
+ VectorNormalizeFast (normal);
+
+ // calculate 'right' vector for start
+ VectorSubtract (r_vieworigin, org1, diff);
+ VectorNormalizeFast (diff);
+ CrossProduct (normal, diff, right1);
+
+ // calculate 'right' vector for end
+ VectorSubtract (r_vieworigin, org2, diff);
+ VectorNormalizeFast (diff);
+ CrossProduct (normal, diff, right2);
+
+ vert[ 0] = org1[0] + width * right1[0];
+ vert[ 1] = org1[1] + width * right1[1];
+ vert[ 2] = org1[2] + width * right1[2];
+ vert[ 3] = org1[0] - width * right1[0];
+ vert[ 4] = org1[1] - width * right1[1];
+ vert[ 5] = org1[2] - width * right1[2];
+ vert[ 6] = org2[0] - width * right2[0];
+ vert[ 7] = org2[1] - width * right2[1];
+ vert[ 8] = org2[2] - width * right2[2];
+ vert[ 9] = org2[0] + width * right2[0];
+ vert[10] = org2[1] + width * right2[1];
+ vert[11] = org2[2] + width * right2[2];
+}
+
+float spritetexcoord2f[4*2] = {0, 1, 0, 0, 1, 0, 1, 1};
+
+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)
+{
+ float diff[3];
+ rmeshstate_t m;
+
+ if (fogenabled)
+ {
+ VectorSubtract(origin, r_vieworigin, diff);
+ ca *= 1 - exp(fogdensity/DotProduct(diff,diff));
+ }
+
+ R_Mesh_Matrix(&r_identitymatrix);
+ GL_BlendFunc(blendfunc1, blendfunc2);
+ GL_DepthMask(false);
+ GL_DepthTest(!depthdisable);
+
+ varray_vertex3f[ 0] = origin[0] + left[0] * scalex2 + up[0] * scaley1;
+ varray_vertex3f[ 1] = origin[1] + left[1] * scalex2 + up[1] * scaley1;
+ varray_vertex3f[ 2] = origin[2] + left[2] * scalex2 + up[2] * scaley1;
+ varray_vertex3f[ 3] = origin[0] + left[0] * scalex2 + up[0] * scaley2;
+ varray_vertex3f[ 4] = origin[1] + left[1] * scalex2 + up[1] * scaley2;
+ varray_vertex3f[ 5] = origin[2] + left[2] * scalex2 + up[2] * scaley2;
+ varray_vertex3f[ 6] = origin[0] + left[0] * scalex1 + up[0] * scaley2;
+ varray_vertex3f[ 7] = origin[1] + left[1] * scalex1 + up[1] * scaley2;
+ varray_vertex3f[ 8] = origin[2] + left[2] * scalex1 + up[2] * scaley2;
+ varray_vertex3f[ 9] = origin[0] + left[0] * scalex1 + up[0] * scaley1;
+ varray_vertex3f[10] = origin[1] + left[1] * scalex1 + up[1] * scaley1;
+ varray_vertex3f[11] = origin[2] + left[2] * scalex1 + up[2] * scaley1;
+
+ memset(&m, 0, sizeof(m));
+ m.tex[0] = R_GetTexture(texture);
+ m.pointer_texcoord[0] = spritetexcoord2f;
+ m.pointer_vertex = varray_vertex3f;
+ R_Mesh_State(&m);
+ GL_Color(cr, cg, cb, ca);
+ R_Mesh_Draw(4, 2, polygonelements);
+}
+