reorganized a lot of renderer variables into r_refdef, and split some things out...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 12 May 2006 08:11:46 +0000 (08:11 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 12 May 2006 08:11:46 +0000 (08:11 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@6368 d7cf8633-e32d-0410-b094-e92efae38249

24 files changed:
cl_input.c
cl_main.c
cl_parse.c
cl_particles.c
cl_screen.c
client.h
clvm_cmds.c
gl_backend.c
gl_draw.c
gl_rmain.c
gl_rsurf.c
host.c
meshqueue.c
meshqueue.h
prvm_cmds.c
r_crosshairs.c
r_explosion.c
r_light.c
r_lightning.c
r_shadow.c
r_sky.c
r_sprites.c
render.h
view.c

index 6235e25..d9a0616 100644 (file)
@@ -495,8 +495,8 @@ void CL_UpdatePrydonCursor(void)
        cl.cmd.cursor_screen[1] = bound(-1, cl.cmd.cursor_screen[1], 1);
        cl.cmd.cursor_screen[2] = 1;
 
-       scale[0] = -r_refdef.frustum_x;
-       scale[1] = -r_refdef.frustum_y;
+       scale[0] = -r_view.frustum_x;
+       scale[1] = -r_view.frustum_y;
        scale[2] = 1;
 
        // trace distance
@@ -505,9 +505,9 @@ void CL_UpdatePrydonCursor(void)
        // calculate current view matrix
        V_CalcRefdef();
        VectorClear(temp);
-       Matrix4x4_Transform(&r_refdef.viewentitymatrix, temp, cl.cmd.cursor_start);
+       Matrix4x4_Transform(&r_view.matrix, temp, cl.cmd.cursor_start);
        VectorSet(temp, cl.cmd.cursor_screen[2] * scale[2], cl.cmd.cursor_screen[0] * scale[0], cl.cmd.cursor_screen[1] * scale[1]);
-       Matrix4x4_Transform(&r_refdef.viewentitymatrix, temp, cl.cmd.cursor_end);
+       Matrix4x4_Transform(&r_view.matrix, temp, cl.cmd.cursor_end);
        // trace from view origin to the cursor
        cl.cmd.cursor_fraction = CL_SelectTraceLine(cl.cmd.cursor_start, cl.cmd.cursor_end, cl.cmd.cursor_impact, cl.cmd.cursor_normal, &cl.cmd.cursor_entitynumber, (chase_active.integer || cl.intermission) ? &cl.entities[cl.playerentity].render : NULL, false);
 }
index 3cba5cb..2c0c4ff 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -850,7 +850,7 @@ void CL_LinkNetworkEntity(entity_t *e)
                e->render.skinnum = e->state_current.skin;
                if (e->render.flags & RENDER_VIEWMODEL && !e->state_current.tagentity)
                {
-                       if (!r_drawviewmodel.integer || chase_active.integer || envmap)// || csqc_loaded)
+                       if (!r_drawviewmodel.integer || chase_active.integer || r_refdef.envmap)// || csqc_loaded)
                                return;
                        if (!e->csqc)
                        {
@@ -1557,7 +1557,7 @@ int CL_ReadFromServer(void)
        r_refdef.time = cl.time;
        r_refdef.extraupdate = !r_speeds.integer;
        r_refdef.numentities = 0;
-       r_refdef.viewentitymatrix = identitymatrix;
+       r_view.matrix = identitymatrix;
 
        if (cls.state == ca_connected && cls.signon == SIGNONS)
        {
@@ -1621,13 +1621,13 @@ static void CL_Fog_f (void)
 {
        if (Cmd_Argc () == 1)
        {
-               Con_Printf("\"fog\" is \"%f %f %f %f\"\n", fog_density, fog_red, fog_green, fog_blue);
+               Con_Printf("\"fog\" is \"%f %f %f %f\"\n", r_refdef.fog_density, r_refdef.fog_red, r_refdef.fog_green, r_refdef.fog_blue);
                return;
        }
-       fog_density = atof(Cmd_Argv(1));
-       fog_red = atof(Cmd_Argv(2));
-       fog_green = atof(Cmd_Argv(3));
-       fog_blue = atof(Cmd_Argv(4));
+       r_refdef.fog_density = atof(Cmd_Argv(1));
+       r_refdef.fog_red = atof(Cmd_Argv(2));
+       r_refdef.fog_green = atof(Cmd_Argv(3));
+       r_refdef.fog_blue = atof(Cmd_Argv(4));
 }
 
 /*
@@ -1649,7 +1649,7 @@ static void CL_TimeRefresh_f (void)
        timestart = Sys_DoubleTime();
        for (i = 0;i < 128;i++)
        {
-               Matrix4x4_CreateFromQuakeEntity(&r_refdef.viewentitymatrix, r_vieworigin[0], r_vieworigin[1], r_vieworigin[2], 0, i / 128.0 * 360.0, 0, 1);
+               Matrix4x4_CreateFromQuakeEntity(&r_view.matrix, r_view.origin[0], r_view.origin[1], r_view.origin[2], 0, i / 128.0 * 360.0, 0, 1);
                CL_UpdateScreen();
        }
        timedelta = Sys_DoubleTime() - timestart;
index ffa7274..11688ac 100644 (file)
@@ -341,15 +341,15 @@ void CL_ParseEntityLump(char *entdata)
                else if (!strcmp("qlsky", key)) // non-standard, introduced by QuakeLives (EEK)
                        R_SetSkyBox(value);
                else if (!strcmp("fog", key))
-                       sscanf(value, "%f %f %f %f", &fog_density, &fog_red, &fog_green, &fog_blue);
+                       sscanf(value, "%f %f %f %f", &r_refdef.fog_density, &r_refdef.fog_red, &r_refdef.fog_green, &r_refdef.fog_blue);
                else if (!strcmp("fog_density", key))
-                       fog_density = atof(value);
+                       r_refdef.fog_density = atof(value);
                else if (!strcmp("fog_red", key))
-                       fog_red = atof(value);
+                       r_refdef.fog_red = atof(value);
                else if (!strcmp("fog_green", key))
-                       fog_green = atof(value);
+                       r_refdef.fog_green = atof(value);
                else if (!strcmp("fog_blue", key))
-                       fog_blue = atof(value);
+                       r_refdef.fog_blue = atof(value);
        }
 }
 
index a957f10..30278b1 100644 (file)
@@ -2069,18 +2069,18 @@ void R_DrawParticle_TransparentCallback(const entity_render_t *ent, const rtligh
                        cg *= (ambient[1] + 0.5 * diffuse[1]);
                        cb *= (ambient[2] + 0.5 * diffuse[2]);
                }
-               if (fogenabled)
+               if (r_refdef.fogenabled)
                {
-                       fog = VERTEXFOGTABLE(VectorDistance(p->org, r_vieworigin));
+                       fog = VERTEXFOGTABLE(VectorDistance(p->org, r_view.origin));
                        ifog = 1 - fog;
                        cr = cr * ifog;
                        cg = cg * ifog;
                        cb = cb * ifog;
                        if (blendmode == PBLEND_ALPHA)
                        {
-                               cr += fogcolor[0] * fog;
-                               cg += fogcolor[1] * fog;
-                               cb += fogcolor[2] * fog;
+                               cr += r_refdef.fogcolor[0] * fog;
+                               cg += r_refdef.fogcolor[1] * fog;
+                               cb += r_refdef.fogcolor[2] * fog;
                        }
                }
                c4f[0] = c4f[4] = c4f[8] = c4f[12] = cr;
@@ -2093,8 +2093,8 @@ void R_DrawParticle_TransparentCallback(const entity_render_t *ent, const rtligh
                tex = &particletexture[p->texnum];
                if (p->type->orientation == PARTICLE_BILLBOARD)
                {
-                       VectorScale(r_viewleft, -size, right);
-                       VectorScale(r_viewup, size, up);
+                       VectorScale(r_view.left, -size, right);
+                       VectorScale(r_view.up, size, up);
                        v3f[ 0] = org[0] - right[0] - up[0];
                        v3f[ 1] = org[1] - right[1] - up[1];
                        v3f[ 2] = org[2] - right[2] - up[2];
@@ -2115,7 +2115,7 @@ void R_DrawParticle_TransparentCallback(const entity_render_t *ent, const rtligh
                else if (p->type->orientation == PARTICLE_ORIENTED_DOUBLESIDED)
                {
                        // double-sided
-                       if (DotProduct(p->vel, r_vieworigin) > DotProduct(p->vel, org))
+                       if (DotProduct(p->vel, r_view.origin) > DotProduct(p->vel, org))
                        {
                                VectorNegate(p->vel, v);
                                VectorVectors(v, right, up);
@@ -2223,15 +2223,15 @@ void R_DrawParticles (void)
        if ((!cl.num_particles) || (!r_drawparticles.integer))
                return;
 
-       minparticledist = DotProduct(r_vieworigin, r_viewforward) + 4.0f;
+       minparticledist = DotProduct(r_view.origin, r_view.forward) + 4.0f;
 
        // LordHavoc: only render if not too close
        for (i = 0, p = cl.particles;i < cl.num_particles;i++, p++)
        {
                if (p->type)
                {
-                       renderstats.particles++;
-                       if (DotProduct(p->org, r_viewforward) >= minparticledist || p->type->orientation == PARTICLE_BEAM)
+                       r_refdef.stats.particles++;
+                       if (DotProduct(p->org, r_view.forward) >= minparticledist || p->type->orientation == PARTICLE_BEAM)
                                R_MeshQueue_AddTransparent(p->org, R_DrawParticle_TransparentCallback, NULL, i, NULL);
                }
        }
index eccb767..63a8e52 100644 (file)
@@ -464,15 +464,15 @@ void R_TimeReport_Frame(void)
                speedstringcount = 0;
                r_speeds_string[0] = 0;
                r_timereport_active = false;
-               sprintf(r_speeds_string + strlen(r_speeds_string), "org:'%+8.2f %+8.2f %+8.2f' dir:'%+2.3f %+2.3f %+2.3f'\n", r_vieworigin[0], r_vieworigin[1], r_vieworigin[2], r_viewforward[0], r_viewforward[1], r_viewforward[2]);
-               sprintf(r_speeds_string + strlen(r_speeds_string), "%5i entities%6i surfaces%6i triangles%5i leafs%5i portals%6i particles\n", renderstats.entities, renderstats.entities_surfaces, renderstats.entities_triangles, renderstats.world_leafs, renderstats.world_portals, renderstats.particles);
-               sprintf(r_speeds_string + strlen(r_speeds_string), "%4i lights%4i clears%4i scissored%7i light%7i shadow%7i dynamic\n", renderstats.lights, renderstats.lights_clears, renderstats.lights_scissored, renderstats.lights_lighttriangles, renderstats.lights_shadowtriangles, renderstats.lights_dynamicshadowtriangles);
-               if (renderstats.bloom)
-                       sprintf(r_speeds_string + strlen(r_speeds_string), "rendered%6i meshes%8i triangles bloompixels%8i copied%8i drawn\n", renderstats.meshes, renderstats.meshes_elements / 3, renderstats.bloom_copypixels, renderstats.bloom_drawpixels);
+               sprintf(r_speeds_string + strlen(r_speeds_string), "org:'%+8.2f %+8.2f %+8.2f' dir:'%+2.3f %+2.3f %+2.3f'\n", r_view.origin[0], r_view.origin[1], r_view.origin[2], r_view.forward[0], r_view.forward[1], r_view.forward[2]);
+               sprintf(r_speeds_string + strlen(r_speeds_string), "%5i entities%6i surfaces%6i triangles%5i leafs%5i portals%6i particles\n", r_refdef.stats.entities, r_refdef.stats.entities_surfaces, r_refdef.stats.entities_triangles, r_refdef.stats.world_leafs, r_refdef.stats.world_portals, r_refdef.stats.particles);
+               sprintf(r_speeds_string + strlen(r_speeds_string), "%4i lights%4i clears%4i scissored%7i light%7i shadow%7i dynamic\n", r_refdef.stats.lights, r_refdef.stats.lights_clears, r_refdef.stats.lights_scissored, r_refdef.stats.lights_lighttriangles, r_refdef.stats.lights_shadowtriangles, r_refdef.stats.lights_dynamicshadowtriangles);
+               if (r_refdef.stats.bloom)
+                       sprintf(r_speeds_string + strlen(r_speeds_string), "rendered%6i meshes%8i triangles bloompixels%8i copied%8i drawn\n", r_refdef.stats.meshes, r_refdef.stats.meshes_elements / 3, r_refdef.stats.bloom_copypixels, r_refdef.stats.bloom_drawpixels);
                else
-                       sprintf(r_speeds_string + strlen(r_speeds_string), "rendered%6i meshes%8i triangles\n", renderstats.meshes, renderstats.meshes_elements / 3);
+                       sprintf(r_speeds_string + strlen(r_speeds_string), "rendered%6i meshes%8i triangles\n", r_refdef.stats.meshes, r_refdef.stats.meshes_elements / 3);
 
-               memset(&renderstats, 0, sizeof(renderstats));
+               memset(&r_refdef.stats, 0, sizeof(r_refdef.stats));
 
                if (r_speeds.integer >= 2)
                {
@@ -951,15 +951,19 @@ static void R_Envmap_f (void)
                return;
        }
 
-       envmap = true;
+       r_refdef.envmap = true;
 
-       r_refdef.x = 0;
-       r_refdef.y = 0;
-       r_refdef.width = size;
-       r_refdef.height = size;
+       R_UpdateVariables();
 
-       r_refdef.frustum_x = tan(90 * M_PI / 360.0);
-       r_refdef.frustum_y = tan(90 * M_PI / 360.0);
+       r_view.x = 0;
+       r_view.y = 0;
+       r_view.z = 0;
+       r_view.width = size;
+       r_view.height = size;
+       r_view.depth = 1;
+
+       r_view.frustum_x = tan(90 * M_PI / 360.0);
+       r_view.frustum_y = tan(90 * M_PI / 360.0);
 
        buffer1 = (unsigned char *)Mem_Alloc(tempmempool, size * size * 3);
        buffer2 = (unsigned char *)Mem_Alloc(tempmempool, size * size * 3);
@@ -968,19 +972,19 @@ static void R_Envmap_f (void)
        for (j = 0;j < 12;j++)
        {
                sprintf(filename, "env/%s%s.tga", basename, envmapinfo[j].name);
-               Matrix4x4_CreateFromQuakeEntity(&r_refdef.viewentitymatrix, r_vieworigin[0], r_vieworigin[1], r_vieworigin[2], envmapinfo[j].angles[0], envmapinfo[j].angles[1], envmapinfo[j].angles[2], 1);
+               Matrix4x4_CreateFromQuakeEntity(&r_view.matrix, r_view.origin[0], r_view.origin[1], r_view.origin[2], envmapinfo[j].angles[0], envmapinfo[j].angles[1], envmapinfo[j].angles[2], 1);
                R_ClearScreen();
                R_Mesh_Start();
                R_RenderView();
                R_Mesh_Finish();
-               SCR_ScreenShot(filename, buffer1, buffer2, buffer3, 0, vid.height - (r_refdef.y + r_refdef.height), size, size, envmapinfo[j].flipx, envmapinfo[j].flipy, envmapinfo[j].flipdiagonaly, false, false);
+               SCR_ScreenShot(filename, buffer1, buffer2, buffer3, 0, vid.height - (r_view.y + r_view.height), size, size, envmapinfo[j].flipx, envmapinfo[j].flipy, envmapinfo[j].flipdiagonaly, false, false);
        }
 
        Mem_Free (buffer1);
        Mem_Free (buffer2);
        Mem_Free (buffer3);
 
-       envmap = false;
+       r_refdef.envmap = false;
 }
 
 //=============================================================================
@@ -1114,9 +1118,9 @@ void R_ClearScreen(void)
        {
                // clear to black
                CHECKGLERROR
-               if (fogenabled)
+               if (r_refdef.fogenabled)
                {
-                       qglClearColor(fogcolor[0],fogcolor[1],fogcolor[2],0);CHECKGLERROR
+                       qglClearColor(r_refdef.fogcolor[0],r_refdef.fogcolor[1],r_refdef.fogcolor[2],0);CHECKGLERROR
                }
                else
                {
@@ -1157,6 +1161,8 @@ void SCR_DrawScreen (void)
        if (r_timereport_active)
                R_TimeReport("setup");
 
+       R_UpdateVariables();
+
        if (cls.signon == SIGNONS)
        {
                float size;
@@ -1166,19 +1172,23 @@ void SCR_DrawScreen (void)
 
                if (r_stereo_sidebyside.integer)
                {
-                       r_refdef.width = (int)(vid.width * size / 2.5);
-                       r_refdef.height = (int)(vid.height * size / 2.5 * (1 - bound(0, r_letterbox.value, 100) / 100));
-                       r_refdef.x = (int)((vid.width - r_refdef.width * 2.5) * 0.5);
-                       r_refdef.y = (int)((vid.height - r_refdef.height)/2);
+                       r_view.width = (int)(vid.width * size / 2.5);
+                       r_view.height = (int)(vid.height * size / 2.5 * (1 - bound(0, r_letterbox.value, 100) / 100));
+                       r_view.depth = 1;
+                       r_view.x = (int)((vid.width - r_view.width * 2.5) * 0.5);
+                       r_view.y = (int)((vid.height - r_view.height)/2);
+                       r_view.z = 0;
                        if (r_stereo_side)
-                               r_refdef.x += (int)(r_refdef.width * 1.5);
+                               r_view.x += (int)(r_view.width * 1.5);
                }
                else
                {
-                       r_refdef.width = (int)(vid.width * size);
-                       r_refdef.height = (int)(vid.height * size * (1 - bound(0, r_letterbox.value, 100) / 100));
-                       r_refdef.x = (int)((vid.width - r_refdef.width)/2);
-                       r_refdef.y = (int)((vid.height - r_refdef.height)/2);
+                       r_view.width = (int)(vid.width * size);
+                       r_view.height = (int)(vid.height * size * (1 - bound(0, r_letterbox.value, 100) / 100));
+                       r_view.depth = 1;
+                       r_view.x = (int)((vid.width - r_view.width)/2);
+                       r_view.y = (int)((vid.height - r_view.height)/2);
+                       r_view.z = 0;
                }
 
                // LordHavoc: viewzoom (zoom in for sniper rifles, etc)
@@ -1187,11 +1197,11 @@ void SCR_DrawScreen (void)
                // this it simply assumes the requested fov is the vertical fov
                // for a 4x3 display, if the ratio is not 4x3 this makes the fov
                // higher/lower according to the ratio
-               r_refdef.frustum_y = tan(scr_fov.value * cl.viewzoom * M_PI / 360.0) * (3.0/4.0);
-               r_refdef.frustum_x = r_refdef.frustum_y * (float)r_refdef.width / (float)r_refdef.height / vid_pixelheight.value;
+               r_view.frustum_y = tan(scr_fov.value * cl.viewzoom * M_PI / 360.0) * (3.0/4.0);
+               r_view.frustum_x = r_view.frustum_y * (float)r_view.width / (float)r_view.height / vid_pixelheight.value;
 
-               r_refdef.frustum_x *= r_refdef.frustumscale_x;
-               r_refdef.frustum_y *= r_refdef.frustumscale_y;
+               r_view.frustum_x *= r_refdef.frustumscale_x;
+               r_view.frustum_y *= r_refdef.frustumscale_y;
 
                if(!CL_VM_UpdateView())
                        R_RenderView();
@@ -1202,16 +1212,18 @@ void SCR_DrawScreen (void)
                {
                        float sizex = bound(10, scr_zoomwindow_viewsizex.value, 100) / 100.0;
                        float sizey = bound(10, scr_zoomwindow_viewsizey.value, 100) / 100.0;
-                       r_refdef.width = (int)(vid.width * sizex);
-                       r_refdef.height = (int)(vid.height * sizey);
-                       r_refdef.x = (int)((vid.width - r_refdef.width)/2);
-                       r_refdef.y = 0;
+                       r_view.width = (int)(vid.width * sizex);
+                       r_view.height = (int)(vid.height * sizey);
+                       r_view.depth = 1;
+                       r_view.x = (int)((vid.width - r_view.width)/2);
+                       r_view.y = 0;
+                       r_view.z = 0;
 
-                       r_refdef.frustum_y = tan(scr_zoomwindow_fov.value * cl.viewzoom * M_PI / 360.0) * (3.0/4.0);
-                       r_refdef.frustum_x = r_refdef.frustum_y * vid_pixelheight.value * (float)r_refdef.width / (float)r_refdef.height;
+                       r_view.frustum_y = tan(scr_zoomwindow_fov.value * cl.viewzoom * M_PI / 360.0) * (3.0/4.0);
+                       r_view.frustum_x = r_view.frustum_y * vid_pixelheight.value * (float)r_view.width / (float)r_view.height;
 
-                       r_refdef.frustum_x *= r_refdef.frustumscale_x;
-                       r_refdef.frustum_y *= r_refdef.frustumscale_y;
+                       r_view.frustum_x *= r_refdef.frustumscale_x;
+                       r_view.frustum_y *= r_refdef.frustumscale_y;
 
                        if(!CL_VM_UpdateView())
                                R_RenderView();
@@ -1220,10 +1232,12 @@ void SCR_DrawScreen (void)
 
        if (!r_stereo_sidebyside.integer)
        {
-               r_refdef.width = vid.width;
-               r_refdef.height = vid.height;
-               r_refdef.x = 0;
-               r_refdef.y = 0;
+               r_view.width = vid.width;
+               r_view.height = vid.height;
+               r_view.depth = 1;
+               r_view.x = 0;
+               r_view.y = 0;
+               r_view.z = 0;
        }
 
        // draw 2D stuff
@@ -1380,9 +1394,9 @@ void CL_UpdateScreen(void)
                        sb_lines = 24+16+8;
        }
 
-       r_refdef.colormask[0] = 1;
-       r_refdef.colormask[1] = 1;
-       r_refdef.colormask[2] = 1;
+       r_view.colormask[0] = 1;
+       r_view.colormask[1] = 1;
+       r_view.colormask[2] = 1;
 
        if (r_timereport_active)
                R_TimeReport("other");
@@ -1405,40 +1419,40 @@ void CL_UpdateScreen(void)
 
        if (r_stereo_redblue.integer || r_stereo_redgreen.integer || r_stereo_redcyan.integer || r_stereo_sidebyside.integer)
        {
-               matrix4x4_t originalmatrix = r_refdef.viewentitymatrix;
-               r_refdef.viewentitymatrix.m[0][3] = originalmatrix.m[0][3] + r_stereo_separation.value * -0.5f * r_refdef.viewentitymatrix.m[0][1];
-               r_refdef.viewentitymatrix.m[1][3] = originalmatrix.m[1][3] + r_stereo_separation.value * -0.5f * r_refdef.viewentitymatrix.m[1][1];
-               r_refdef.viewentitymatrix.m[2][3] = originalmatrix.m[2][3] + r_stereo_separation.value * -0.5f * r_refdef.viewentitymatrix.m[2][1];
+               matrix4x4_t originalmatrix = r_view.matrix;
+               r_view.matrix.m[0][3] = originalmatrix.m[0][3] + r_stereo_separation.value * -0.5f * r_view.matrix.m[0][1];
+               r_view.matrix.m[1][3] = originalmatrix.m[1][3] + r_stereo_separation.value * -0.5f * r_view.matrix.m[1][1];
+               r_view.matrix.m[2][3] = originalmatrix.m[2][3] + r_stereo_separation.value * -0.5f * r_view.matrix.m[2][1];
 
                if (r_stereo_sidebyside.integer)
                        r_stereo_side = 0;
 
                if (r_stereo_redblue.integer || r_stereo_redgreen.integer || r_stereo_redcyan.integer)
                {
-                       r_refdef.colormask[0] = 1;
-                       r_refdef.colormask[1] = 0;
-                       r_refdef.colormask[2] = 0;
+                       r_view.colormask[0] = 1;
+                       r_view.colormask[1] = 0;
+                       r_view.colormask[2] = 0;
                }
 
                SCR_DrawScreen();
 
-               r_refdef.viewentitymatrix.m[0][3] = originalmatrix.m[0][3] + r_stereo_separation.value * 0.5f * r_refdef.viewentitymatrix.m[0][1];
-               r_refdef.viewentitymatrix.m[1][3] = originalmatrix.m[1][3] + r_stereo_separation.value * 0.5f * r_refdef.viewentitymatrix.m[1][1];
-               r_refdef.viewentitymatrix.m[2][3] = originalmatrix.m[2][3] + r_stereo_separation.value * 0.5f * r_refdef.viewentitymatrix.m[2][1];
+               r_view.matrix.m[0][3] = originalmatrix.m[0][3] + r_stereo_separation.value * 0.5f * r_view.matrix.m[0][1];
+               r_view.matrix.m[1][3] = originalmatrix.m[1][3] + r_stereo_separation.value * 0.5f * r_view.matrix.m[1][1];
+               r_view.matrix.m[2][3] = originalmatrix.m[2][3] + r_stereo_separation.value * 0.5f * r_view.matrix.m[2][1];
 
                if (r_stereo_sidebyside.integer)
                        r_stereo_side = 1;
 
                if (r_stereo_redblue.integer || r_stereo_redgreen.integer || r_stereo_redcyan.integer)
                {
-                       r_refdef.colormask[0] = 0;
-                       r_refdef.colormask[1] = r_stereo_redcyan.integer || r_stereo_redgreen.integer;
-                       r_refdef.colormask[2] = r_stereo_redcyan.integer || r_stereo_redblue.integer;
+                       r_view.colormask[0] = 0;
+                       r_view.colormask[1] = r_stereo_redcyan.integer || r_stereo_redgreen.integer;
+                       r_view.colormask[2] = r_stereo_redcyan.integer || r_stereo_redblue.integer;
                }
 
                SCR_DrawScreen();
 
-               r_refdef.viewentitymatrix = originalmatrix;
+               r_view.matrix = originalmatrix;
        }
        else
                SCR_DrawScreen();
index 246d425..02053f2 100644 (file)
--- a/client.h
+++ b/client.h
@@ -259,8 +259,6 @@ typedef struct entity_render_s
 
        // calculated by the renderer (but not persistent)
 
-       // if visframe == r_framecount, it is visible
-       int visframe;
        // calculated during R_AddModelEntities
        vec3_t mins, maxs;
        // 4 frame numbers (-1 if not used) and their blending scalers (0-1), if interpolation is not desired, use frame instead
@@ -1132,21 +1130,47 @@ void R_NewExplosion(const vec3_t org);
 #define NUMCROSSHAIRS 32
 extern cachepic_t *r_crosshairs[NUMCROSSHAIRS+1];
 
-typedef struct refdef_s
+#define FOGTABLEWIDTH 1024
+extern int fogtableindex;
+#define VERTEXFOGTABLE(dist) (fogtableindex = (int)((dist) * r_refdef.fogtabledistmultiplier), r_refdef.fogtable[bound(0, fogtableindex, FOGTABLEWIDTH - 1)])
+
+typedef struct r_refdef_stats_s
 {
-       // area to render in
-       int x, y, width, height;
-       float frustum_x, frustum_y;
+       int entities;
+       int entities_surfaces;
+       int entities_triangles;
+       int world_leafs;
+       int world_portals;
+       int particles;
+       int meshes;
+       int meshes_elements;
+       int lights;
+       int lights_clears;
+       int lights_scissored;
+       int lights_lighttriangles;
+       int lights_shadowtriangles;
+       int lights_dynamicshadowtriangles;
+       int bloom;
+       int bloom_copypixels;
+       int bloom_drawpixels;
+}
+r_refdef_stats_t;
+
+typedef struct r_refdef_s
+{
+       // these fields define the basic rendering information for the world
+       // but not the view, which could change multiple times in one rendered
+       // frame (for example when rendering textures for certain effects)
 
        // these are set for water warping before
        // frustum_x/frustum_y are calculated
        float frustumscale_x, frustumscale_y;
 
-       // view transform
-       matrix4x4_t viewentitymatrix;
-
-       // which color components to allow (for anaglyph glasses)
-       int colormask[4];
+       // minimum visible distance (pixels closer than this disappear)
+       double nearclip;
+       // maximum visible distance (pixels further than this disappear in 16bpp modes,
+       // in 32bpp an infinite-farclip matrix is used instead)
+       double farclip;
 
        // fullscreen color blend
        float viewblend[4];
@@ -1176,11 +1200,99 @@ typedef struct refdef_s
        // controls intensity of dynamic lights and lightmap layers
        unsigned short  lightstylevalue[256];   // 8.8 fraction of base light value
 
+       vec3_t fogcolor;
+       vec_t fogrange;
+       vec_t fograngerecip;
+       vec_t fogtabledistmultiplier;
+       float fogtable[FOGTABLEWIDTH];
+       float fog_density;
+       float fog_red;
+       float fog_green;
+       float fog_blue;
+       qboolean fogenabled;
+       qboolean oldgl_fogenable;
+
        qboolean draw2dstage;
+
+       // true during envmap command capture
+       qboolean envmap;
+
+       // brightness of world lightmaps and related lighting
+       // (often reduced when world rtlights are enabled)
+       float lightmapintensity;
+       // whether to draw world lights realtime, dlights realtime, and their shadows
+       qboolean rtworld;
+       qboolean rtworldshadows;
+       qboolean rtdlight;
+       qboolean rtdlightshadows;
+       float polygonfactor;
+       float polygonoffset;
+       float shadowpolygonfactor;
+       float shadowpolygonoffset;
+
+       // rendering stats for r_speeds display
+       // (these are incremented in many places)
+       r_refdef_stats_t stats;
+}
+r_refdef_t;
+
+typedef struct r_view_s
+{
+       // view information (changes multiple times per frame)
+       // if any of these variables change then r_viewcache must be regenerated
+       // by calling R_View_Update
+       // (which also updates viewport, scissor, colormask)
+
+       // it is safe and expected to copy this into a structure on the stack and
+       // call the renderer recursively, then restore from the stack afterward
+       // (as long as R_View_Update is called)
+
+       // eye position information
+       matrix4x4_t matrix;
+       vec3_t origin;
+       vec3_t forward;
+       vec3_t left;
+       vec3_t right;
+       vec3_t up;
+       mplane_t frustum[5];
+       float frustum_x, frustum_y;
+
+       // screen area to render in
+       int x;
+       int y;
+       int z;
+       int width;
+       int height;
+       int depth;
+
+       // which color components to allow (for anaglyph glasses)
+       int colormask[4];
+}
+r_view_t;
+
+typedef struct r_viewcache_s
+{
+       // these properties are generated by R_View_Update()
+
+       // which entities are currently visible for this viewpoint
+       // (the used range is 0...r_refdef.numentities)
+       unsigned char entityvisible[MAX_EDICTS];
+       // flag arrays used for visibility checking on world model
+       // (all other entities have no per-surface/per-leaf visibility checks)
+       // TODO: dynamic resize according to r_refdef.worldmodel->brush.num_clusters
+       unsigned char world_pvsbits[(32768+7)>>3];
+       // TODO: dynamic resize according to r_refdef.worldmodel->brush.num_leafs
+       unsigned char world_leafvisible[32768];
+       // TODO: dynamic resize according to r_refdef.worldmodel->num_surfaces
+       unsigned char world_surfacevisible[262144];
+       // if true, the view is currently in a leaf without pvs data
+       qboolean world_novis;
 }
-refdef_t;
+r_viewcache_t;
 
-extern refdef_t r_refdef;
+extern r_refdef_t r_refdef;
+extern r_view_t r_view;
+extern r_viewcache_t r_viewcache;
 
 #endif
 
index 59c34d5..011de9b 100644 (file)
@@ -729,8 +729,8 @@ static void CSQC_R_RecalcView (void)
 {
        extern matrix4x4_t viewmodelmatrix;
        viewmodelmatrix = identitymatrix;
-       r_refdef.viewentitymatrix = identitymatrix;
-       Matrix4x4_CreateFromQuakeEntity(&r_refdef.viewentitymatrix, csqc_origin[0], csqc_origin[1], csqc_origin[2], csqc_angles[0], csqc_angles[1], csqc_angles[2], 1);
+       r_view.matrix = identitymatrix;
+       Matrix4x4_CreateFromQuakeEntity(&r_view.matrix, csqc_origin[0], csqc_origin[1], csqc_origin[2], csqc_angles[0], csqc_angles[1], csqc_angles[2], 1);
        Matrix4x4_CreateFromQuakeEntity(&viewmodelmatrix, csqc_origin[0], csqc_origin[1], csqc_origin[2], csqc_angles[0], csqc_angles[1], csqc_angles[2], 0.3);
 }
 
@@ -774,25 +774,28 @@ void VM_R_SetView (void)
 
        switch(c)
        {
-       case VF_MIN:                    r_refdef.x = (int)f[0];
-                                                       r_refdef.y = (int)f[1];
+       case VF_MIN:                    r_view.x = (int)f[0];
+                                                       r_view.y = (int)f[1];
                                                        break;
-       case VF_MIN_X:                  r_refdef.x = (int)k;
+       case VF_MIN_X:                  r_view.x = (int)k;
                                                        break;
-       case VF_MIN_Y:                  r_refdef.y = (int)k;
+       case VF_MIN_Y:                  r_view.y = (int)k;
                                                        break;
-       case VF_SIZE:                   r_refdef.width = (int)f[0];
-                                                       r_refdef.height = (int)f[1];
+       case VF_SIZE:                   r_view.width = (int)f[0];
+                                                       r_view.height = (int)f[1];
                                                        break;
-       case VF_SIZE_Y:                 r_refdef.width = (int)k;
+       case VF_SIZE_Y:                 r_view.width = (int)k;
                                                        break;
-       case VF_SIZE_X:                 r_refdef.height = (int)k;
+       case VF_SIZE_X:                 r_view.height = (int)k;
                                                        break;
-       case VF_VIEWPORT:               r_refdef.x = (int)f[0];
-                                                       r_refdef.y = (int)f[1];
+       case VF_VIEWPORT:               r_view.x = (int)f[0];
+                                                       r_view.y = (int)f[1];
+                                                       r_view.z = 0;
+                                                       // TODO: make sure that view_z and view_depth are set properly even if csqc does not set them!
                                                        f = PRVM_G_VECTOR(OFS_PARM2);
-                                                       r_refdef.width = (int)f[0];
-                                                       r_refdef.height = (int)f[1];
+                                                       r_view.width = (int)f[0];
+                                                       r_view.height = (int)f[1];
+                                                       r_view.depth = 1;
                                                        break;
        case VF_FOV:                    //r_refdef.fov_x = f[0]; // FIXME!
                                                        //r_refdef.fov_y = f[1]; // FIXME!
@@ -886,8 +889,8 @@ void VM_CL_unproject (void)
 
        VM_SAFEPARMCOUNT(1, VM_CL_unproject);
        f = PRVM_G_VECTOR(OFS_PARM0);
-       VectorSet(temp, f[2], f[0] * f[2] * -r_refdef.frustum_x * 2.0 / r_refdef.width, f[1] * f[2] * -r_refdef.frustum_y * 2.0 / r_refdef.height);
-       Matrix4x4_Transform(&r_refdef.viewentitymatrix, temp, PRVM_G_VECTOR(OFS_RETURN));
+       VectorSet(temp, f[2], f[0] * f[2] * -r_view.frustum_x * 2.0 / r_view.width, f[1] * f[2] * -r_view.frustum_y * 2.0 / r_view.height);
+       Matrix4x4_Transform(&r_view.matrix, temp, PRVM_G_VECTOR(OFS_RETURN));
 }
 
 //#311 vector (vector v) cs_project (EXT_CSQC)
@@ -899,9 +902,9 @@ void VM_CL_project (void)
 
        VM_SAFEPARMCOUNT(1, VM_CL_project);
        f = PRVM_G_VECTOR(OFS_PARM0);
-       Matrix4x4_Invert_Simple(&m, &r_refdef.viewentitymatrix);
+       Matrix4x4_Invert_Simple(&m, &r_view.matrix);
        Matrix4x4_Transform(&m, f, v);
-       VectorSet(PRVM_G_VECTOR(OFS_RETURN), v[1]/v[0]/-r_refdef.frustum_x*0.5*r_refdef.width, v[2]/v[0]/-r_refdef.frustum_y*r_refdef.height*0.5, v[0]);
+       VectorSet(PRVM_G_VECTOR(OFS_RETURN), v[1]/v[0]/-r_view.frustum_x*0.5*r_view.width, v[2]/v[0]/-r_view.frustum_y*r_view.height*0.5, v[0]);
 }
 
 //#330 float(float stnum) getstatf (EXT_CSQC)
index 414911f..4bea75d 100644 (file)
@@ -735,9 +735,9 @@ void GL_TransformToScreen(const vec4_t in, vec4_t out)
        Matrix4x4_Transform4 (&backend_viewmatrix, in, temp);
        Matrix4x4_Transform4 (&backend_projectmatrix, temp, out);
        iw = 1.0f / out[3];
-       out[0] = r_view_x + (out[0] * iw + 1.0f) * r_view_width * 0.5f;
-       out[1] = r_view_y + (out[1] * iw + 1.0f) * r_view_height * 0.5f;
-       out[2] = r_view_z + (out[2] * iw + 1.0f) * r_view_depth * 0.5f;
+       out[0] = r_view.x + (out[0] * iw + 1.0f) * r_view.width * 0.5f;
+       out[1] = r_view.y + (out[1] * iw + 1.0f) * r_view.height * 0.5f;
+       out[2] = r_view.z + (out[2] * iw + 1.0f) * r_view.depth * 0.5f;
 }
 
 // called at beginning of frame
@@ -889,8 +889,8 @@ void R_Mesh_Draw(int firstvertex, int numvertices, int numtriangles, const int *
                return;
        }
        CHECKGLERROR
-       renderstats.meshes++;
-       renderstats.meshes_elements += numelements;
+       r_refdef.stats.meshes++;
+       r_refdef.stats.meshes_elements += numelements;
        if (gl_paranoid.integer)
        {
                unsigned int i, j, size;
index 38c6536..95f9e7b 100644 (file)
--- a/gl_draw.c
+++ b/gl_draw.c
@@ -493,17 +493,10 @@ void GL_Draw_Init (void)
 
 void DrawQ_Begin(void)
 {
-       r_view_width = bound(0, r_refdef.width, vid.width);
-       r_view_height = bound(0, r_refdef.height, vid.height);
-       r_view_depth = 1;
-       r_view_x = bound(0, r_refdef.x, vid.width - r_refdef.width);
-       r_view_y = bound(0, r_refdef.y, vid.height - r_refdef.height);
-       r_view_z = 0;
-       r_view_matrix = r_refdef.viewentitymatrix;
-       GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
+       GL_ColorMask(r_view.colormask[0], r_view.colormask[1], r_view.colormask[2], 1);
 
        CHECKGLERROR
-       qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);CHECKGLERROR
+       qglViewport(r_view.x, vid.height - (r_view.y + r_view.height), r_view.width, r_view.height);CHECKGLERROR
        GL_SetupView_Mode_Ortho(0, 0, vid_conwidth.integer, vid_conheight.integer, -10, 100);
        qglDepthFunc(GL_LEQUAL);CHECKGLERROR
        R_Mesh_Matrix(&identitymatrix);
index 7e19215..6b1e3cd 100644 (file)
@@ -26,49 +26,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 mempool_t *r_main_mempool;
 rtexturepool_t *r_main_texturepool;
 
-// used for dlight push checking and other things
-int r_framecount;
-
-mplane_t frustum[5];
-
-renderstats_t renderstats;
-
-// true during envmap command capture
-qboolean envmap;
-
-// maximum visible distance (recalculated from world box each frame)
-float r_farclip;
-// brightness of world lightmaps and related lighting
-// (often reduced when world rtlights are enabled)
-float r_lightmapintensity;
-// whether to draw world lights realtime, dlights realtime, and their shadows
-qboolean r_rtworld;
-qboolean r_rtworldshadows;
-qboolean r_rtdlight;
-qboolean r_rtdlightshadows;
-
-
-// view origin
-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;
-matrix4x4_t r_view_matrix;
-float r_polygonfactor;
-float r_polygonoffset;
-float r_shadowpolygonfactor;
-float r_shadowpolygonoffset;
 //
 // screen size info
 //
-refdef_t r_refdef;
+r_refdef_t r_refdef;
+r_view_t r_view;
+r_viewcache_t r_viewcache;
 
 cvar_t r_nearclip = {0, "r_nearclip", "1", "distance from camera of nearclip plane" };
 cvar_t r_showsurfaces = {0, "r_showsurfaces", "0", "shows surfaces as different colors"};
@@ -140,6 +103,9 @@ r_glsl_permutation_t r_glsl_permutations[SHADERPERMUTATION_COUNT];
 // currently selected permutation
 r_glsl_permutation_t *r_glsl_permutation;
 
+// temporary variable used by a macro
+int fogtableindex;
+
 void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
 {
        int i;
@@ -167,59 +133,6 @@ void R_FillColors(float *out, int verts, float r, float g, float b, float a)
        }
 }
 
-vec3_t fogcolor;
-vec_t fogdensity;
-vec_t fogrange;
-vec_t fograngerecip;
-int fogtableindex;
-vec_t fogtabledistmultiplier;
-float fogtable[FOGTABLEWIDTH];
-float fog_density, fog_red, fog_green, fog_blue;
-qboolean fogenabled;
-qboolean oldgl_fogenable;
-void R_UpdateFog(void)
-{
-       if (gamemode == GAME_NEHAHRA)
-       {
-               if (gl_fogenable.integer)
-               {
-                       oldgl_fogenable = true;
-                       fog_density = gl_fogdensity.value;
-                       fog_red = gl_fogred.value;
-                       fog_green = gl_foggreen.value;
-                       fog_blue = gl_fogblue.value;
-               }
-               else if (oldgl_fogenable)
-               {
-                       oldgl_fogenable = false;
-                       fog_density = 0;
-                       fog_red = 0;
-                       fog_green = 0;
-                       fog_blue = 0;
-               }
-       }
-       if (fog_density)
-       {
-               fogcolor[0] = fog_red   = bound(0.0f, fog_red  , 1.0f);
-               fogcolor[1] = fog_green = bound(0.0f, fog_green, 1.0f);
-               fogcolor[2] = fog_blue  = bound(0.0f, fog_blue , 1.0f);
-       }
-       if (fog_density)
-       {
-               fogenabled = true;
-               fogdensity = -4000.0f / (fog_density * fog_density);
-               // this is the point where the fog reaches 0.9986 alpha, which we
-               // consider a good enough cutoff point for the texture
-               // (0.9986 * 256 == 255.6)
-               fogrange = 400 / fog_density;
-               fograngerecip = 1.0f / fogrange;
-               fogtabledistmultiplier = FOGTABLEWIDTH * fograngerecip;
-               // fog color was already set
-       }
-       else
-               fogenabled = false;
-}
-
 // FIXME: move this to client?
 void FOG_clear(void)
 {
@@ -231,7 +144,7 @@ void FOG_clear(void)
                Cvar_Set("gl_foggreen", "0.3");
                Cvar_Set("gl_fogblue", "0.3");
        }
-       fog_density = fog_red = fog_green = fog_blue = 0.0f;
+       r_refdef.fog_density = r_refdef.fog_red = r_refdef.fog_green = r_refdef.fog_blue = 0.0f;
 }
 
 // FIXME: move this to client?
@@ -257,7 +170,7 @@ void FOG_registercvars(void)
                alpha = exp(r / ((double)x*(double)x));
                if (x == FOGTABLEWIDTH - 1)
                        alpha = 1;
-               fogtable[x] = bound(0, alpha, 1);
+               r_refdef.fogtable[x] = bound(0, alpha, 1);
        }
 }
 
@@ -886,7 +799,7 @@ int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting)
        }
        if (specularscale > 0)
                permutation |= SHADERPERMUTATION_SPECULAR;
-       if (fogenabled)
+       if (r_refdef.fogenabled)
                permutation |= SHADERPERMUTATION_FOG;
        if (rsurface_texture->colormapping)
                permutation |= SHADERPERMUTATION_COLORMAPPING;
@@ -946,8 +859,8 @@ int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting)
        else
        {
                if (r_glsl_permutation->loc_AmbientScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_AmbientScale, r_ambient.value * 2.0f / 128.0f);
-               if (r_glsl_permutation->loc_DiffuseScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_DiffuseScale, r_lightmapintensity * 2.0f);
-               if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, r_lightmapintensity * specularscale * 2.0f);
+               if (r_glsl_permutation->loc_DiffuseScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_DiffuseScale, r_refdef.lightmapintensity * 2.0f);
+               if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, r_refdef.lightmapintensity * specularscale * 2.0f);
        }
        if (r_glsl_permutation->loc_Texture_Normal >= 0) R_Mesh_TexBind(0, R_GetTexture(rsurface_texture->skin.nmap));
        if (r_glsl_permutation->loc_Texture_Color >= 0) R_Mesh_TexBind(1, R_GetTexture(rsurface_texture->basetexture));
@@ -965,7 +878,7 @@ int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting)
                if (r_shadow_rtlight || (rsurface_texture->currentmaterialflags & MATERIALFLAG_ADD))
                        qglUniform3fARB(r_glsl_permutation->loc_FogColor, 0, 0, 0);
                else
-                       qglUniform3fARB(r_glsl_permutation->loc_FogColor, fogcolor[0], fogcolor[1], fogcolor[2]);
+                       qglUniform3fARB(r_glsl_permutation->loc_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
        }
        if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_EyePosition, rsurface_modelorg[0], rsurface_modelorg[1], rsurface_modelorg[2]);
        if (r_glsl_permutation->loc_Color_Pants >= 0)
@@ -982,7 +895,7 @@ int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting)
                else
                        qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0);
        }
-       if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogRangeRecip, fograngerecip);
+       if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogRangeRecip, r_refdef.fograngerecip);
        if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface_texture->specularpower);
        if (r_glsl_permutation->loc_OffsetMapping_Scale >= 0) qglUniform1fARB(r_glsl_permutation->loc_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value);
        CHECKGLERROR
@@ -1035,7 +948,6 @@ void gl_main_newmap(void)
        // FIXME: move this code to client
        int l;
        char *entities, entname[MAX_QPATH];
-       r_framecount = 1;
        if (cl.worldmodel)
        {
                strlcpy(entname, cl.worldmodel->name, sizeof(entname));
@@ -1103,46 +1015,6 @@ void GL_Main_Init(void)
        R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap);
 }
 
-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
-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]
-         + (r_farclip_directionbit1 ? mins[1] : maxs[1]) * r_farclip_direction[1]
-         + (r_farclip_directionbit2 ? mins[2] : maxs[2]) * r_farclip_direction[2];
-       if (r_farclip_meshfarclip < d)
-               r_farclip_meshfarclip = d;
-}
-
-// return farclip value
-static float R_FarClip(vec3_t origin, vec3_t direction, vec_t startfarclip)
-{
-       int i;
-
-       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 (r_refdef.worldmodel)
-               R_FarClip_Box(r_refdef.worldmodel->normalmins, r_refdef.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 GL_Draw_Init(void);
 extern void GL_Main_Init(void);
@@ -1162,7 +1034,6 @@ void Render_Init(void)
 {
        gl_backend_init();
        R_Textures_Init();
-       R_MeshQueue_Init();
        GL_Main_Init();
        GL_Draw_Init();
        R_Shadow_Init();
@@ -1202,7 +1073,7 @@ int R_CullBox(const vec3_t mins, const vec3_t maxs)
        mplane_t *p;
        for (i = 0;i < 4;i++)
        {
-               p = frustum + i;
+               p = r_view.frustum + i;
                switch(p->signbits)
                {
                default:
@@ -1257,15 +1128,15 @@ static void R_UpdateEntityLighting(entity_render_t *ent)
                VectorSet(ent->modellight_ambient, 1, 1, 1);
        Matrix4x4_Transform3x3(&ent->inversematrix, tempdiffusenormal, ent->modellight_lightdir);
        VectorNormalize(ent->modellight_lightdir);
-       ent->modellight_ambient[0] *= ent->colormod[0] * r_lightmapintensity;
-       ent->modellight_ambient[1] *= ent->colormod[1] * r_lightmapintensity;
-       ent->modellight_ambient[2] *= ent->colormod[2] * r_lightmapintensity;
-       ent->modellight_diffuse[0] *= ent->colormod[0] * r_lightmapintensity;
-       ent->modellight_diffuse[1] *= ent->colormod[1] * r_lightmapintensity;
-       ent->modellight_diffuse[2] *= ent->colormod[2] * r_lightmapintensity;
+       ent->modellight_ambient[0] *= ent->colormod[0] * r_refdef.lightmapintensity;
+       ent->modellight_ambient[1] *= ent->colormod[1] * r_refdef.lightmapintensity;
+       ent->modellight_ambient[2] *= ent->colormod[2] * r_refdef.lightmapintensity;
+       ent->modellight_diffuse[0] *= ent->colormod[0] * r_refdef.lightmapintensity;
+       ent->modellight_diffuse[1] *= ent->colormod[1] * r_refdef.lightmapintensity;
+       ent->modellight_diffuse[2] *= ent->colormod[2] * r_refdef.lightmapintensity;
 }
 
-static void R_MarkEntities (void)
+static void R_View_UpdateEntityVisible (void)
 {
        int i, renderimask;
        entity_render_t *ent;
@@ -1273,23 +1144,14 @@ static void R_MarkEntities (void)
        if (!r_drawentities.integer)
                return;
 
-       r_refdef.worldentity->visframe = r_framecount;
-       renderimask = envmap ? (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL) : (chase_active.integer ? 0 : RENDER_EXTERIORMODEL);
+       renderimask = r_refdef.envmap ? (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL) : (chase_active.integer ? 0 : RENDER_EXTERIORMODEL);
        if (r_refdef.worldmodel && r_refdef.worldmodel->brush.BoxTouchingVisibleLeafs)
        {
                // worldmodel can check visibility
                for (i = 0;i < r_refdef.numentities;i++)
                {
                        ent = r_refdef.entities[i];
-                       // 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);
-                       if (!(ent->flags & renderimask) && !R_CullBox(ent->mins, ent->maxs) && ((ent->effects & EF_NODEPTHTEST) || r_refdef.worldmodel->brush.BoxTouchingVisibleLeafs(r_refdef.worldmodel, r_worldleafvisible, ent->mins, ent->maxs)))
-                       {
-                               ent->visframe = r_framecount;
-                               R_UpdateEntityLighting(ent);
-                       }
+                       r_viewcache.entityvisible[i] = !(ent->flags & renderimask) && !R_CullBox(ent->mins, ent->maxs) && ((ent->effects & EF_NODEPTHTEST) || r_refdef.worldmodel->brush.BoxTouchingVisibleLeafs(r_refdef.worldmodel, r_viewcache.world_leafvisible, ent->mins, ent->maxs));
                }
        }
        else
@@ -1298,15 +1160,7 @@ static void R_MarkEntities (void)
                for (i = 0;i < r_refdef.numentities;i++)
                {
                        ent = r_refdef.entities[i];
-                       // 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);
-                       if (!(ent->flags & renderimask) && !R_CullBox(ent->mins, ent->maxs) && (ent->effects & EF_NODEPTHTEST))
-                       {
-                               ent->visframe = r_framecount;
-                               R_UpdateEntityLighting(ent);
-                       }
+                       r_viewcache.entityvisible[i] = !(ent->flags & renderimask) && !R_CullBox(ent->mins, ent->maxs) && (ent->effects & EF_NODEPTHTEST);
                }
        }
 }
@@ -1323,12 +1177,13 @@ int R_DrawBrushModelsSky (void)
        sky = false;
        for (i = 0;i < r_refdef.numentities;i++)
        {
+               if (!r_viewcache.entityvisible[i])
+                       continue;
                ent = r_refdef.entities[i];
-               if (ent->visframe == r_framecount && ent->model && ent->model->DrawSky)
-               {
-                       ent->model->DrawSky(ent);
-                       sky = true;
-               }
+               if (!ent->model || !ent->model->DrawSky)
+                       continue;
+               ent->model->DrawSky(ent);
+               sky = true;
        }
        return sky;
 }
@@ -1344,138 +1199,148 @@ void R_DrawModels(void)
 
        for (i = 0;i < r_refdef.numentities;i++)
        {
+               if (!r_viewcache.entityvisible[i])
+                       continue;
                ent = r_refdef.entities[i];
-               if (ent->visframe == r_framecount)
-               {
-                       renderstats.entities++;
-                       if (ent->model && ent->model->Draw != NULL)
-                               ent->model->Draw(ent);
-                       else
-                               R_DrawNoModel(ent);
-               }
+               r_refdef.stats.entities++;
+               if (ent->model && ent->model->Draw != NULL)
+                       ent->model->Draw(ent);
+               else
+                       R_DrawNoModel(ent);
        }
 }
 
-static void R_SetFrustum(void)
+static void R_View_SetFrustum(void)
 {
        // 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);
+       Matrix4x4_ToVectors(&r_view.matrix, r_view.forward, r_view.left, r_view.up, r_view.origin);
+       VectorNegate(r_view.left, r_view.right);
 
 #if 0
-       frustum[0].normal[0] = 0 - 1.0 / r_refdef.frustum_x;
-       frustum[0].normal[1] = 0 - 0;
-       frustum[0].normal[2] = -1 - 0;
-       frustum[1].normal[0] = 0 + 1.0 / r_refdef.frustum_x;
-       frustum[1].normal[1] = 0 + 0;
-       frustum[1].normal[2] = -1 + 0;
-       frustum[2].normal[0] = 0 - 0;
-       frustum[2].normal[1] = 0 - 1.0 / r_refdef.frustum_y;
-       frustum[2].normal[2] = -1 - 0;
-       frustum[3].normal[0] = 0 + 0;
-       frustum[3].normal[1] = 0 + 1.0 / r_refdef.frustum_y;
-       frustum[3].normal[2] = -1 + 0;
+       r_view.frustum[0].normal[0] = 0 - 1.0 / r_view.frustum_x;
+       r_view.frustum[0].normal[1] = 0 - 0;
+       r_view.frustum[0].normal[2] = -1 - 0;
+       r_view.frustum[1].normal[0] = 0 + 1.0 / r_view.frustum_x;
+       r_view.frustum[1].normal[1] = 0 + 0;
+       r_view.frustum[1].normal[2] = -1 + 0;
+       r_view.frustum[2].normal[0] = 0 - 0;
+       r_view.frustum[2].normal[1] = 0 - 1.0 / r_view.frustum_y;
+       r_view.frustum[2].normal[2] = -1 - 0;
+       r_view.frustum[3].normal[0] = 0 + 0;
+       r_view.frustum[3].normal[1] = 0 + 1.0 / r_view.frustum_y;
+       r_view.frustum[3].normal[2] = -1 + 0;
 #endif
 
 #if 0
-       zNear = r_nearclip.value;
+       zNear = r_refdef.nearclip;
        nudge = 1.0 - 1.0 / (1<<23);
-       frustum[4].normal[0] = 0 - 0;
-       frustum[4].normal[1] = 0 - 0;
-       frustum[4].normal[2] = -1 - -nudge;
-       frustum[4].dist = 0 - -2 * zNear * nudge;
-       frustum[5].normal[0] = 0 + 0;
-       frustum[5].normal[1] = 0 + 0;
-       frustum[5].normal[2] = -1 + -nudge;
-       frustum[5].dist = 0 + -2 * zNear * nudge;
+       r_view.frustum[4].normal[0] = 0 - 0;
+       r_view.frustum[4].normal[1] = 0 - 0;
+       r_view.frustum[4].normal[2] = -1 - -nudge;
+       r_view.frustum[4].dist = 0 - -2 * zNear * nudge;
+       r_view.frustum[5].normal[0] = 0 + 0;
+       r_view.frustum[5].normal[1] = 0 + 0;
+       r_view.frustum[5].normal[2] = -1 + -nudge;
+       r_view.frustum[5].dist = 0 + -2 * zNear * nudge;
 #endif
 
 
 
 #if 0
-       frustum[0].normal[0] = m[3] - m[0];
-       frustum[0].normal[1] = m[7] - m[4];
-       frustum[0].normal[2] = m[11] - m[8];
-       frustum[0].dist = m[15] - m[12];
-
-       frustum[1].normal[0] = m[3] + m[0];
-       frustum[1].normal[1] = m[7] + m[4];
-       frustum[1].normal[2] = m[11] + m[8];
-       frustum[1].dist = m[15] + m[12];
-
-       frustum[2].normal[0] = m[3] - m[1];
-       frustum[2].normal[1] = m[7] - m[5];
-       frustum[2].normal[2] = m[11] - m[9];
-       frustum[2].dist = m[15] - m[13];
-
-       frustum[3].normal[0] = m[3] + m[1];
-       frustum[3].normal[1] = m[7] + m[5];
-       frustum[3].normal[2] = m[11] + m[9];
-       frustum[3].dist = m[15] + m[13];
-
-       frustum[4].normal[0] = m[3] - m[2];
-       frustum[4].normal[1] = m[7] - m[6];
-       frustum[4].normal[2] = m[11] - m[10];
-       frustum[4].dist = m[15] - m[14];
-
-       frustum[5].normal[0] = m[3] + m[2];
-       frustum[5].normal[1] = m[7] + m[6];
-       frustum[5].normal[2] = m[11] + m[10];
-       frustum[5].dist = m[15] + m[14];
+       r_view.frustum[0].normal[0] = m[3] - m[0];
+       r_view.frustum[0].normal[1] = m[7] - m[4];
+       r_view.frustum[0].normal[2] = m[11] - m[8];
+       r_view.frustum[0].dist = m[15] - m[12];
+
+       r_view.frustum[1].normal[0] = m[3] + m[0];
+       r_view.frustum[1].normal[1] = m[7] + m[4];
+       r_view.frustum[1].normal[2] = m[11] + m[8];
+       r_view.frustum[1].dist = m[15] + m[12];
+
+       r_view.frustum[2].normal[0] = m[3] - m[1];
+       r_view.frustum[2].normal[1] = m[7] - m[5];
+       r_view.frustum[2].normal[2] = m[11] - m[9];
+       r_view.frustum[2].dist = m[15] - m[13];
+
+       r_view.frustum[3].normal[0] = m[3] + m[1];
+       r_view.frustum[3].normal[1] = m[7] + m[5];
+       r_view.frustum[3].normal[2] = m[11] + m[9];
+       r_view.frustum[3].dist = m[15] + m[13];
+
+       r_view.frustum[4].normal[0] = m[3] - m[2];
+       r_view.frustum[4].normal[1] = m[7] - m[6];
+       r_view.frustum[4].normal[2] = m[11] - m[10];
+       r_view.frustum[4].dist = m[15] - m[14];
+
+       r_view.frustum[5].normal[0] = m[3] + m[2];
+       r_view.frustum[5].normal[1] = m[7] + m[6];
+       r_view.frustum[5].normal[2] = m[11] + m[10];
+       r_view.frustum[5].dist = m[15] + m[14];
 #endif
 
 
 
-       VectorMAM(1, r_viewforward, 1.0 / -r_refdef.frustum_x, r_viewleft, frustum[0].normal);
-       VectorMAM(1, r_viewforward, 1.0 /  r_refdef.frustum_x, r_viewleft, frustum[1].normal);
-       VectorMAM(1, r_viewforward, 1.0 / -r_refdef.frustum_y, r_viewup, frustum[2].normal);
-       VectorMAM(1, r_viewforward, 1.0 /  r_refdef.frustum_y, r_viewup, frustum[3].normal);
-       VectorCopy(r_viewforward, frustum[4].normal);
-       VectorNormalize(frustum[0].normal);
-       VectorNormalize(frustum[1].normal);
-       VectorNormalize(frustum[2].normal);
-       VectorNormalize(frustum[3].normal);
-       frustum[0].dist = DotProduct (r_vieworigin, frustum[0].normal);
-       frustum[1].dist = DotProduct (r_vieworigin, frustum[1].normal);
-       frustum[2].dist = DotProduct (r_vieworigin, frustum[2].normal);
-       frustum[3].dist = DotProduct (r_vieworigin, frustum[3].normal);
-       frustum[4].dist = DotProduct (r_vieworigin, frustum[4].normal) + r_nearclip.value;
-       PlaneClassify(&frustum[0]);
-       PlaneClassify(&frustum[1]);
-       PlaneClassify(&frustum[2]);
-       PlaneClassify(&frustum[3]);
-       PlaneClassify(&frustum[4]);
+       VectorMAM(1, r_view.forward, 1.0 / -r_view.frustum_x, r_view.left, r_view.frustum[0].normal);
+       VectorMAM(1, r_view.forward, 1.0 /  r_view.frustum_x, r_view.left, r_view.frustum[1].normal);
+       VectorMAM(1, r_view.forward, 1.0 / -r_view.frustum_y, r_view.up, r_view.frustum[2].normal);
+       VectorMAM(1, r_view.forward, 1.0 /  r_view.frustum_y, r_view.up, r_view.frustum[3].normal);
+       VectorCopy(r_view.forward, r_view.frustum[4].normal);
+       VectorNormalize(r_view.frustum[0].normal);
+       VectorNormalize(r_view.frustum[1].normal);
+       VectorNormalize(r_view.frustum[2].normal);
+       VectorNormalize(r_view.frustum[3].normal);
+       r_view.frustum[0].dist = DotProduct (r_view.origin, r_view.frustum[0].normal);
+       r_view.frustum[1].dist = DotProduct (r_view.origin, r_view.frustum[1].normal);
+       r_view.frustum[2].dist = DotProduct (r_view.origin, r_view.frustum[2].normal);
+       r_view.frustum[3].dist = DotProduct (r_view.origin, r_view.frustum[3].normal);
+       r_view.frustum[4].dist = DotProduct (r_view.origin, r_view.frustum[4].normal) + r_refdef.nearclip;
+       PlaneClassify(&r_view.frustum[0]);
+       PlaneClassify(&r_view.frustum[1]);
+       PlaneClassify(&r_view.frustum[2]);
+       PlaneClassify(&r_view.frustum[3]);
+       PlaneClassify(&r_view.frustum[4]);
 
        // LordHavoc: note to all quake engine coders, Quake had a special case
        // for 90 degrees which assumed a square view (wrong), so I removed it,
        // Quake2 has it disabled as well.
 
        // rotate R_VIEWFORWARD right by FOV_X/2 degrees
-       //RotatePointAroundVector( frustum[0].normal, r_viewup, r_viewforward, -(90 - r_refdef.fov_x / 2));
-       //frustum[0].dist = DotProduct (r_vieworigin, frustum[0].normal);
+       //RotatePointAroundVector( r_view.frustum[0].normal, r_view.up, r_view.forward, -(90 - r_refdef.fov_x / 2));
+       //r_view.frustum[0].dist = DotProduct (r_view.origin, 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_refdef.fov_x / 2));
-       //frustum[1].dist = DotProduct (r_vieworigin, frustum[1].normal);
+       //RotatePointAroundVector( r_view.frustum[1].normal, r_view.up, r_view.forward, (90 - r_refdef.fov_x / 2));
+       //r_view.frustum[1].dist = DotProduct (r_view.origin, 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_refdef.fov_y / 2));
-       //frustum[2].dist = DotProduct (r_vieworigin, frustum[2].normal);
+       //RotatePointAroundVector( r_view.frustum[2].normal, r_view.left, r_view.forward, -(90 - r_refdef.fov_y / 2));
+       //r_view.frustum[2].dist = DotProduct (r_view.origin, 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_refdef.fov_y / 2));
-       //frustum[3].dist = DotProduct (r_vieworigin, frustum[3].normal);
+       //RotatePointAroundVector( r_view.frustum[3].normal, r_view.left, r_view.forward, (90 - r_refdef.fov_y / 2));
+       //r_view.frustum[3].dist = DotProduct (r_view.origin, frustum[3].normal);
        //PlaneClassify(&frustum[3]);
 
        // nearclip plane
-       //VectorCopy(r_viewforward, frustum[4].normal);
-       //frustum[4].dist = DotProduct (r_vieworigin, frustum[4].normal) + r_nearclip.value;
+       //VectorCopy(r_view.forward, r_view.frustum[4].normal);
+       //r_view.frustum[4].dist = DotProduct (r_view.origin, frustum[4].normal) + r_nearclip.value;
        //PlaneClassify(&frustum[4]);
 }
 
+void R_View_Update(void)
+{
+       // GL is weird because it's bottom to top, r_view.y is top to bottom
+       qglViewport(r_view.x, vid.height - (r_view.y + r_view.height), r_view.width, r_view.height);CHECKGLERROR
+       GL_Scissor(r_view.x, r_view.y, r_view.width, r_view.height);
+       GL_ColorMask(r_view.colormask[0], r_view.colormask[1], r_view.colormask[2], 1);
+       R_View_SetFrustum();
+       R_View_WorldVisibility();
+       R_View_UpdateEntityVisible();
+}
+
 static void R_BlendView(void)
 {
        int screenwidth, screenheight;
@@ -1512,7 +1377,7 @@ static void R_BlendView(void)
        {
                int bloomwidth, bloomheight, x, range;
                float xoffset, yoffset, r;
-               renderstats.bloom++;
+               r_refdef.stats.bloom++;
                // allocate textures as needed
                if (!r_bloom_texture_screen)
                        r_bloom_texture_screen = R_LoadTexture2D(r_main_texturepool, "screen", screenwidth, screenheight, NULL, TEXTYPE_RGBA, TEXF_FORCENEAREST | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL);
@@ -1520,15 +1385,15 @@ static void R_BlendView(void)
                        r_bloom_texture_bloom = R_LoadTexture2D(r_main_texturepool, "bloom", screenwidth, screenheight, NULL, TEXTYPE_RGBA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL);
                // set bloomwidth and bloomheight to the bloom resolution that will be
                // used (often less than the screen resolution for faster rendering)
-               bloomwidth = min(r_view_width, r_bloom_resolution.integer);
-               bloomheight = min(r_view_height, bloomwidth * r_view_height / r_view_width);
+               bloomwidth = min(r_view.width, r_bloom_resolution.integer);
+               bloomheight = min(r_view.height, bloomwidth * r_view.height / r_view.width);
                // set up a texcoord array for the full resolution screen image
                // (we have to keep this around to copy back during final render)
                texcoord2f[0][0] = 0;
-               texcoord2f[0][1] = (float)r_view_height / (float)screenheight;
-               texcoord2f[0][2] = (float)r_view_width / (float)screenwidth;
-               texcoord2f[0][3] = (float)r_view_height / (float)screenheight;
-               texcoord2f[0][4] = (float)r_view_width / (float)screenwidth;
+               texcoord2f[0][1] = (float)r_view.height / (float)screenheight;
+               texcoord2f[0][2] = (float)r_view.width / (float)screenwidth;
+               texcoord2f[0][3] = (float)r_view.height / (float)screenheight;
+               texcoord2f[0][4] = (float)r_view.width / (float)screenwidth;
                texcoord2f[0][5] = 0;
                texcoord2f[0][6] = 0;
                texcoord2f[0][7] = 0;
@@ -1547,24 +1412,24 @@ static void R_BlendView(void)
                // copy view into the full resolution screen image texture
                GL_ActiveTexture(0);
                CHECKGLERROR
-               qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);CHECKGLERROR
-               renderstats.bloom_copypixels += r_view_width * r_view_height;
+               qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view.x, vid.height - (r_view.y + r_view.height), r_view.width, r_view.height);CHECKGLERROR
+               r_refdef.stats.bloom_copypixels += r_view.width * r_view.height;
                // now scale it down to the bloom size and raise to a power of itself
                // to darken it (this leaves the really bright stuff bright, and
                // everything else becomes very dark)
                // TODO: optimize with multitexture or GLSL
                CHECKGLERROR
-               qglViewport(r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);CHECKGLERROR
+               qglViewport(r_view.x, vid.height - (r_view.y + bloomheight), bloomwidth, bloomheight);CHECKGLERROR
                GL_BlendFunc(GL_ONE, GL_ZERO);
                GL_Color(1, 1, 1, 1);
                R_Mesh_Draw(0, 4, 2, polygonelements);
-               renderstats.bloom_drawpixels += bloomwidth * bloomheight;
+               r_refdef.stats.bloom_drawpixels += bloomwidth * bloomheight;
                // render multiple times with a multiply blendfunc to raise to a power
                GL_BlendFunc(GL_DST_COLOR, GL_ZERO);
                for (x = 1;x < r_bloom_power.integer;x++)
                {
                        R_Mesh_Draw(0, 4, 2, polygonelements);
-                       renderstats.bloom_drawpixels += bloomwidth * bloomheight;
+                       r_refdef.stats.bloom_drawpixels += bloomwidth * bloomheight;
                }
                // we now have a darkened bloom image in the framebuffer, copy it into
                // the bloom image texture for more processing
@@ -1572,8 +1437,8 @@ static void R_BlendView(void)
                R_Mesh_TexCoordPointer(0, 2, texcoord2f[2]);
                GL_ActiveTexture(0);
                CHECKGLERROR
-               qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);CHECKGLERROR
-               renderstats.bloom_copypixels += bloomwidth * bloomheight;
+               qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view.x, vid.height - (r_view.y + bloomheight), bloomwidth, bloomheight);CHECKGLERROR
+               r_refdef.stats.bloom_copypixels += bloomwidth * bloomheight;
                // blend on at multiple vertical offsets to achieve a vertical blur
                // TODO: do offset blends using GLSL
                range = r_bloom_blur.integer * bloomwidth / 320;
@@ -1599,14 +1464,14 @@ static void R_BlendView(void)
                                continue;
                        GL_Color(r, r, r, 1);
                        R_Mesh_Draw(0, 4, 2, polygonelements);
-                       renderstats.bloom_drawpixels += bloomwidth * bloomheight;
+                       r_refdef.stats.bloom_drawpixels += bloomwidth * bloomheight;
                        GL_BlendFunc(GL_ONE, GL_ONE);
                }
                // copy the vertically blurred bloom view to a texture
                GL_ActiveTexture(0);
                CHECKGLERROR
-               qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);CHECKGLERROR
-               renderstats.bloom_copypixels += bloomwidth * bloomheight;
+               qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view.x, vid.height - (r_view.y + bloomheight), bloomwidth, bloomheight);CHECKGLERROR
+               r_refdef.stats.bloom_copypixels += bloomwidth * bloomheight;
                // blend the vertically blurred image at multiple offsets horizontally
                // to finish the blur effect
                // TODO: do offset blends using GLSL
@@ -1633,16 +1498,16 @@ static void R_BlendView(void)
                                continue;
                        GL_Color(r, r, r, 1);
                        R_Mesh_Draw(0, 4, 2, polygonelements);
-                       renderstats.bloom_drawpixels += bloomwidth * bloomheight;
+                       r_refdef.stats.bloom_drawpixels += bloomwidth * bloomheight;
                        GL_BlendFunc(GL_ONE, GL_ONE);
                }
                // copy the blurred bloom view to a texture
                GL_ActiveTexture(0);
                CHECKGLERROR
-               qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);CHECKGLERROR
-               renderstats.bloom_copypixels += bloomwidth * bloomheight;
+               qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view.x, vid.height - (r_view.y + bloomheight), bloomwidth, bloomheight);CHECKGLERROR
+               r_refdef.stats.bloom_copypixels += bloomwidth * bloomheight;
                // go back to full view area
-               qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);CHECKGLERROR
+               qglViewport(r_view.x, vid.height - (r_view.y + r_view.height), r_view.width, r_view.height);CHECKGLERROR
                // put the original screen image back in place and blend the bloom
                // texture on it
                GL_Color(1,1,1,1);
@@ -1659,14 +1524,14 @@ static void R_BlendView(void)
                else
                {
                        R_Mesh_Draw(0, 4, 2, polygonelements);
-                       renderstats.bloom_drawpixels += r_view_width * r_view_height;
+                       r_refdef.stats.bloom_drawpixels += r_view.width * r_view.height;
                        // now blend on the bloom texture
                        GL_BlendFunc(GL_ONE, GL_ONE);
                        R_Mesh_TexBind(0, R_GetTexture(r_bloom_texture_bloom));
                        R_Mesh_TexCoordPointer(0, 2, texcoord2f[1]);
                }
                R_Mesh_Draw(0, 4, 2, polygonelements);
-               renderstats.bloom_drawpixels += r_view_width * r_view_height;
+               r_refdef.stats.bloom_drawpixels += r_view.width * r_view.height;
        }
        if (doblend)
        {
@@ -1682,6 +1547,87 @@ void R_RenderScene(void);
 
 matrix4x4_t r_waterscrollmatrix;
 
+void R_UpdateVariables(void)
+{
+       int i;
+
+       R_Textures_Frame();
+
+       r_refdef.farclip = 4096;
+       if (r_refdef.worldmodel)
+               r_refdef.farclip += VectorDistance(r_refdef.worldmodel->normalmins, r_refdef.worldmodel->normalmaxs);
+       r_refdef.nearclip = bound (0.001f, r_nearclip.value, r_refdef.farclip - 1.0f);
+
+       r_refdef.polygonfactor = 0;
+       r_refdef.polygonoffset = 0;
+       r_refdef.shadowpolygonfactor = r_refdef.polygonfactor + r_shadow_shadow_polygonfactor.value;
+       r_refdef.shadowpolygonoffset = r_refdef.polygonoffset + r_shadow_shadow_polygonoffset.value;
+
+       r_refdef.rtworld = r_shadow_realtime_world.integer;
+       r_refdef.rtworldshadows = r_shadow_realtime_world_shadows.integer && gl_stencil;
+       r_refdef.rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer;
+       r_refdef.rtdlightshadows = r_refdef.rtdlight && (r_refdef.rtworld ? r_shadow_realtime_world_dlightshadows.integer : r_shadow_realtime_dlight_shadows.integer) && gl_stencil;
+       r_refdef.lightmapintensity = r_refdef.rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
+       if (r_showsurfaces.integer)
+       {
+               r_refdef.rtworld = false;
+               r_refdef.rtworldshadows = false;
+               r_refdef.rtdlight = false;
+               r_refdef.rtdlightshadows = false;
+               r_refdef.lightmapintensity = 0;
+       }
+
+       if (gamemode == GAME_NEHAHRA)
+       {
+               if (gl_fogenable.integer)
+               {
+                       r_refdef.oldgl_fogenable = true;
+                       r_refdef.fog_density = gl_fogdensity.value;
+                       r_refdef.fog_red = gl_fogred.value;
+                       r_refdef.fog_green = gl_foggreen.value;
+                       r_refdef.fog_blue = gl_fogblue.value;
+               }
+               else if (r_refdef.oldgl_fogenable)
+               {
+                       r_refdef.oldgl_fogenable = false;
+                       r_refdef.fog_density = 0;
+                       r_refdef.fog_red = 0;
+                       r_refdef.fog_green = 0;
+                       r_refdef.fog_blue = 0;
+               }
+       }
+       if (r_refdef.fog_density)
+       {
+               r_refdef.fogcolor[0] = bound(0.0f, r_refdef.fog_red  , 1.0f);
+               r_refdef.fogcolor[1] = bound(0.0f, r_refdef.fog_green, 1.0f);
+               r_refdef.fogcolor[2] = bound(0.0f, r_refdef.fog_blue , 1.0f);
+       }
+       if (r_refdef.fog_density)
+       {
+               r_refdef.fogenabled = true;
+               // this is the point where the fog reaches 0.9986 alpha, which we
+               // consider a good enough cutoff point for the texture
+               // (0.9986 * 256 == 255.6)
+               r_refdef.fogrange = 400 / r_refdef.fog_density;
+               r_refdef.fograngerecip = 1.0f / r_refdef.fogrange;
+               r_refdef.fogtabledistmultiplier = FOGTABLEWIDTH * r_refdef.fograngerecip;
+               // fog color was already set
+       }
+       else
+               r_refdef.fogenabled = false;
+
+       // update some cached entity properties...
+       for (i = 0;i < r_refdef.numentities;i++)
+       {
+               entity_render_t *ent = r_refdef.entities[i];
+               // 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_UpdateEntityLighting(ent);
+       }
+}
+
 /*
 ================
 R_RenderView
@@ -1692,54 +1638,21 @@ void R_RenderView(void)
        if (!r_refdef.entities/* || !r_refdef.worldmodel*/)
                return; //Host_Error ("R_RenderView: NULL worldmodel");
 
-       r_view_width = bound(0, r_refdef.width, vid.width);
-       r_view_height = bound(0, r_refdef.height, vid.height);
-       r_view_depth = 1;
-       r_view_x = bound(0, r_refdef.x, vid.width - r_refdef.width);
-       r_view_y = bound(0, r_refdef.y, vid.height - r_refdef.height);
-       r_view_z = 0;
-       r_view_matrix = r_refdef.viewentitymatrix;
-       GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
-       r_rtworld = r_shadow_realtime_world.integer;
-       r_rtworldshadows = r_shadow_realtime_world_shadows.integer && gl_stencil;
-       r_rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer;
-       r_rtdlightshadows = r_rtdlight && (r_rtworld ? r_shadow_realtime_world_dlightshadows.integer : r_shadow_realtime_dlight_shadows.integer) && gl_stencil;
-       r_lightmapintensity = r_rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
-       r_polygonfactor = 0;
-       r_polygonoffset = 0;
-       r_shadowpolygonfactor = r_polygonfactor + r_shadow_shadow_polygonfactor.value;
-       r_shadowpolygonoffset = r_polygonoffset + r_shadow_shadow_polygonoffset.value;
-       if (r_showsurfaces.integer)
-       {
-               r_rtworld = false;
-               r_rtworldshadows = false;
-               r_rtdlight = false;
-               r_rtdlightshadows = false;
-               r_lightmapintensity = 0;
-       }
-
-       // GL is weird because it's bottom to top, r_view_y is top to bottom
        CHECKGLERROR
-       qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);CHECKGLERROR
-       GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height);
        GL_ScissorTest(true);
        GL_DepthMask(true);
-       R_ClearScreen();
-       R_Textures_Frame();
-       R_UpdateFog();
        if (r_timereport_active)
                R_TimeReport("setup");
 
-       CHECKGLERROR
-       qglDepthFunc(GL_LEQUAL);CHECKGLERROR
-       qglPolygonOffset(r_polygonfactor, r_polygonoffset);CHECKGLERROR
-       qglEnable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
+       R_View_Update();
+       if (r_timereport_active)
+               R_TimeReport("visibility");
 
-       R_RenderScene();
+       R_ClearScreen();
+       if (r_timereport_active)
+               R_TimeReport("clear");
 
-       CHECKGLERROR
-       qglPolygonOffset(r_polygonfactor, r_polygonoffset);CHECKGLERROR
-       qglDisable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
+       R_RenderScene();
 
        R_BlendView();
        if (r_timereport_active)
@@ -1756,60 +1669,27 @@ void CSQC_R_ClearScreen (void)
        if (!r_refdef.entities/* || !r_refdef.worldmodel*/)
                return; //Host_Error ("R_RenderView: NULL worldmodel");
 
-       r_view_width = bound(0, r_refdef.width, vid.width);
-       r_view_height = bound(0, r_refdef.height, vid.height);
-       r_view_depth = 1;
-       r_view_x = bound(0, r_refdef.x, vid.width - r_refdef.width);
-       r_view_y = bound(0, r_refdef.y, vid.height - r_refdef.height);
-       r_view_z = 0;
-       r_view_matrix = r_refdef.viewentitymatrix;
-       GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
-       r_rtworld = r_shadow_realtime_world.integer;
-       r_rtworldshadows = r_shadow_realtime_world_shadows.integer && gl_stencil;
-       r_rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer;
-       r_rtdlightshadows = r_rtdlight && (r_rtworld ? r_shadow_realtime_world_dlightshadows.integer : r_shadow_realtime_dlight_shadows.integer) && gl_stencil;
-       r_lightmapintensity = r_rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
-       r_polygonfactor = 0;
-       r_polygonoffset = 0;
-       r_shadowpolygonfactor = r_polygonfactor + r_shadow_shadow_polygonfactor.value;
-       r_shadowpolygonoffset = r_polygonoffset + r_shadow_shadow_polygonoffset.value;
-       if (r_showsurfaces.integer)
-       {
-               r_rtworld = false;
-               r_rtworldshadows = false;
-               r_rtdlight = false;
-               r_rtdlightshadows = false;
-               r_lightmapintensity = 0;
-       }
-
-       // GL is weird because it's bottom to top, r_view_y is top to bottom
        CHECKGLERROR
-       qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);CHECKGLERROR
-       GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height);
        GL_ScissorTest(true);
        GL_DepthMask(true);
-       R_ClearScreen();
-       R_Textures_Frame();
-       R_UpdateFog();
        if (r_timereport_active)
                R_TimeReport("setup");
+
+       R_View_Update();
+       if (r_timereport_active)
+               R_TimeReport("visibility");
+
+       R_ClearScreen();
+       if (r_timereport_active)
+               R_TimeReport("clear");
        CHECKGLERROR
 }
 
 //[515]: csqc
 void CSQC_R_RenderScene (void)
 {
-       CHECKGLERROR
-       qglDepthFunc(GL_LEQUAL);CHECKGLERROR
-       qglPolygonOffset(r_polygonfactor, r_polygonoffset);CHECKGLERROR
-       qglEnable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
-
        R_RenderScene();
 
-       CHECKGLERROR
-       qglPolygonOffset(r_polygonfactor, r_polygonoffset);CHECKGLERROR
-       qglDisable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
-
        R_BlendView();
        if (r_timereport_active)
                R_TimeReport("blendview");
@@ -1823,47 +1703,33 @@ extern void R_DrawLightningBeams (void);
 extern void VM_AddPolygonsToMeshQueue (void);
 void R_RenderScene(void)
 {
-       float nearclip;
-
        // don't let sound skip if going slow
        if (r_refdef.extraupdate)
                S_ExtraUpdate ();
 
-       r_framecount++;
-
        CHECKGLERROR
        if (gl_support_fragment_shader)
        {
                qglUseProgramObjectARB(0);CHECKGLERROR
        }
+       qglDepthFunc(GL_LEQUAL);CHECKGLERROR
+       qglPolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);CHECKGLERROR
+       qglEnable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
 
        R_MeshQueue_BeginScene();
 
-       R_SetFrustum();
-
-       r_farclip = R_FarClip(r_vieworigin, r_viewforward, 768.0f) + 256.0f;
-       nearclip = bound (0.001f, r_nearclip.value, r_farclip - 1.0f);
-
-       if (r_rtworldshadows || r_rtdlightshadows)
-               GL_SetupView_Mode_PerspectiveInfiniteFarClip(r_refdef.frustum_x, r_refdef.frustum_y, nearclip);
+       if (r_refdef.rtworldshadows || r_refdef.rtdlightshadows)
+               GL_SetupView_Mode_PerspectiveInfiniteFarClip(r_view.frustum_x, r_view.frustum_y, r_refdef.nearclip);
        else
-               GL_SetupView_Mode_Perspective(r_refdef.frustum_x, r_refdef.frustum_y, nearclip, r_farclip);
+               GL_SetupView_Mode_Perspective(r_view.frustum_x, r_view.frustum_y, r_refdef.nearclip, r_refdef.farclip);
 
-       GL_SetupView_Orientation_FromEntity(&r_view_matrix);
+       GL_SetupView_Orientation_FromEntity(&r_view.matrix);
 
-       Matrix4x4_CreateTranslate(&r_waterscrollmatrix, sin(r_refdef.time) * 0.025 * r_waterscroll.value, sin(r_refdef.time * 0.8f) * 0.025 * r_waterscroll.value, 0);
+       R_Shadow_UpdateWorldLightSelection();
 
        R_SkyStartFrame();
 
-       R_WorldVisibility();
-       if (r_timereport_active)
-               R_TimeReport("worldvis");
-
-       R_MarkEntities();
-       if (r_timereport_active)
-               R_TimeReport("markentity");
-
-       R_Shadow_UpdateWorldLightSelection();
+       Matrix4x4_CreateTranslate(&r_waterscrollmatrix, sin(r_refdef.time) * 0.025 * r_waterscroll.value, sin(r_refdef.time * 0.8f) * 0.025 * r_waterscroll.value, 0);
 
        if (cl.csqc_vidvars.drawworld)
        {
@@ -1924,6 +1790,8 @@ void R_RenderScene(void)
                        R_TimeReport("explosions");
        }
 
+       VM_AddPolygonsToMeshQueue();
+
        R_MeshQueue_RenderTransparent();
        if (r_timereport_active)
                R_TimeReport("drawtrans");
@@ -1941,12 +1809,6 @@ void R_RenderScene(void)
                        R_TimeReport("crosshair");
        }
 
-       VM_AddPolygonsToMeshQueue();
-
-       R_MeshQueue_Render();
-
-       R_MeshQueue_EndScene();
-
        // don't let sound skip if going slow
        if (r_refdef.extraupdate)
                S_ExtraUpdate ();
@@ -1956,6 +1818,8 @@ void R_RenderScene(void)
        {
                qglUseProgramObjectARB(0);CHECKGLERROR
        }
+       qglPolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);CHECKGLERROR
+       qglDisable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
 }
 
 /*
@@ -1977,15 +1841,15 @@ void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, floa
        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)
+       if (r_refdef.fogenabled)
        {
                for (i = 0, v = vertex, c = color;i < 8;i++, v += 4, c += 4)
                {
-                       f2 = VERTEXFOGTABLE(VectorDistance(v, r_vieworigin));
+                       f2 = VERTEXFOGTABLE(VectorDistance(v, r_view.origin));
                        f1 = 1 - f2;
-                       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[0] = c[0] * f1 + r_refdef.fogcolor[0] * f2;
+                       c[1] = c[1] * f1 + r_refdef.fogcolor[1] * f2;
+                       c[2] = c[2] * f1 + r_refdef.fogcolor[2] * f2;
                }
        }
        R_Mesh_VertexPointer(vertex3f);
@@ -2053,17 +1917,17 @@ void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, const rtlight
        }
        GL_DepthTest(!(ent->effects & EF_NODEPTHTEST));
        R_Mesh_VertexPointer(nomodelvertex3f);
-       if (fogenabled)
+       if (r_refdef.fogenabled)
        {
                memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
                R_Mesh_ColorPointer(color4f);
-               f2 = VERTEXFOGTABLE(VectorDistance(ent->origin, r_vieworigin));
+               f2 = VERTEXFOGTABLE(VectorDistance(ent->origin, r_view.origin));
                f1 = 1 - f2;
                for (i = 0, c = color4f;i < 6;i++, c += 4)
                {
-                       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[0] = (c[0] * f1 + r_refdef.fogcolor[0] * f2);
+                       c[1] = (c[1] * f1 + r_refdef.fogcolor[1] * f2);
+                       c[2] = (c[2] * f1 + r_refdef.fogcolor[2] * f2);
                        c[3] *= ent->alpha;
                }
        }
@@ -2083,7 +1947,7 @@ void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, const rtlight
 void R_DrawNoModel(entity_render_t *ent)
 {
        //if ((ent->effects & EF_ADDITIVE) || (ent->alpha < 1))
-               R_MeshQueue_AddTransparent(ent->effects & EF_NODEPTHTEST ? r_vieworigin : ent->origin, R_DrawNoModel_TransparentCallback, ent, 0, r_shadow_rtlight);
+               R_MeshQueue_AddTransparent(ent->effects & EF_NODEPTHTEST ? r_view.origin : ent->origin, R_DrawNoModel_TransparentCallback, ent, 0, r_shadow_rtlight);
        //else
        //      R_DrawNoModelCallback(ent, 0);
 }
@@ -2095,12 +1959,12 @@ void R_CalcBeam_Vertex3f (float *vert, const vec3_t org1, const vec3_t org2, flo
        VectorSubtract (org2, org1, normal);
 
        // calculate 'right' vector for start
-       VectorSubtract (r_vieworigin, org1, diff);
+       VectorSubtract (r_view.origin, org1, diff);
        CrossProduct (normal, diff, right1);
        VectorNormalize (right1);
 
        // calculate 'right' vector for end
-       VectorSubtract (r_vieworigin, org2, diff);
+       VectorSubtract (r_view.origin, org2, diff);
        CrossProduct (normal, diff, right2);
        VectorNormalize (right2);
 
@@ -2125,8 +1989,8 @@ void R_DrawSprite(int blendfunc1, int blendfunc2, rtexture_t *texture, rtexture_
        float fog = 0.0f, ifog;
        float vertex3f[12];
 
-       if (fogenabled)
-               fog = VERTEXFOGTABLE(VectorDistance(origin, r_vieworigin));
+       if (r_refdef.fogenabled)
+               fog = VERTEXFOGTABLE(VectorDistance(origin, r_view.origin));
        ifog = 1 - fog;
 
        R_Mesh_Matrix(&identitymatrix);
@@ -2159,7 +2023,7 @@ void R_DrawSprite(int blendfunc1, int blendfunc2, rtexture_t *texture, rtexture_
        {
                R_Mesh_TexBind(0, R_GetTexture(fogtexture));
                GL_BlendFunc(blendfunc1, GL_ONE);
-               GL_Color(fogcolor[0] * fog, fogcolor[1] * fog, fogcolor[2] * fog, ca);
+               GL_Color(r_refdef.fogcolor[0] * fog, r_refdef.fogcolor[1] * fog, r_refdef.fogcolor[2] * fog, ca);
                R_Mesh_Draw(0, 4, 2, polygonelements);
        }
 }
@@ -2365,12 +2229,12 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
                        {
                                rtexture_t *currentbasetexture;
                                int layerflags = 0;
-                               if (fogenabled && (t->currentmaterialflags & MATERIALFLAG_BLENDED))
+                               if (r_refdef.fogenabled && (t->currentmaterialflags & MATERIALFLAG_BLENDED))
                                        layerflags |= TEXTURELAYERFLAG_FOGDARKEN;
                                currentbasetexture = (VectorLength2(ent->colormap_pantscolor) + VectorLength2(ent->colormap_shirtcolor) < (1.0f / 1048576.0f) && t->skin.merged) ? t->skin.merged : t->skin.base;
                                if (t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
                                {
-                                       // fullbright is not affected by r_lightmapintensity
+                                       // fullbright is not affected by r_refdef.lightmapintensity
                                        R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_TEXTURE, currentbasetexture, &t->currenttexmatrix, ent->colormod[0], ent->colormod[1], ent->colormod[2], t->currentalpha);
                                        if (VectorLength2(ent->colormap_pantscolor) >= (1.0f / 1048576.0f) && t->skin.pants)
                                                R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->skin.pants, &t->currenttexmatrix, ent->colormap_pantscolor[0] * ent->colormod[0], ent->colormap_pantscolor[1] * ent->colormod[1], ent->colormap_pantscolor[2] * ent->colormod[2], t->currentalpha);
@@ -2386,7 +2250,7 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
                                        // applied to the color
                                        if (ent->model->type == mod_brushq3)
                                                colorscale *= r_refdef.lightstylevalue[0] * (1.0f / 256.0f);
-                                       colorscale *= r_lightmapintensity;
+                                       colorscale *= r_refdef.lightmapintensity;
                                        R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE, currentbasetexture, &t->currenttexmatrix, ent->colormod[0] * colorscale, ent->colormod[1] * colorscale, ent->colormod[2] * colorscale, t->currentalpha);
                                        if (r_ambient.value >= (1.0f/64.0f))
                                                R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, currentbasetexture, &t->currenttexmatrix, ent->colormod[0] * r_ambient.value * (1.0f / 64.0f), ent->colormod[1] * r_ambient.value * (1.0f / 64.0f), ent->colormod[2] * r_ambient.value * (1.0f / 64.0f), t->currentalpha);
@@ -2405,7 +2269,7 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
                                }
                                if (t->skin.glow != NULL)
                                        R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->skin.glow, &t->currenttexmatrix, 1, 1, 1, t->currentalpha);
-                               if (fogenabled && !(t->currentmaterialflags & MATERIALFLAG_ADD))
+                               if (r_refdef.fogenabled && !(t->currentmaterialflags & MATERIALFLAG_ADD))
                                {
                                        // if this is opaque use alpha blend which will darken the earlier
                                        // passes cheaply.
@@ -2418,7 +2282,7 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
                                        // were darkened by fog already, and we should not add fog color
                                        // (because the background was not darkened, there is no fog color
                                        // that was lost behind it).
-                                       R_Texture_AddLayer(t, false, GL_SRC_ALPHA, (t->currentmaterialflags & MATERIALFLAG_BLENDED) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, TEXTURELAYERTYPE_FOG, t->skin.fog, &identitymatrix, fogcolor[0], fogcolor[1], fogcolor[2], t->currentalpha);
+                                       R_Texture_AddLayer(t, false, GL_SRC_ALPHA, (t->currentmaterialflags & MATERIALFLAG_BLENDED) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, TEXTURELAYERTYPE_FOG, t->skin.fog, &identitymatrix, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2], t->currentalpha);
                                }
                        }
                }
@@ -2487,13 +2351,13 @@ qboolean rsurface_glsl_uselightmap;
 
 void RSurf_ActiveEntity(const entity_render_t *ent, qboolean wantnormals, qboolean wanttangents)
 {
-       Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, rsurface_modelorg);
+       Matrix4x4_Transform(&ent->inversematrix, r_view.origin, rsurface_modelorg);
        rsurface_entity = ent;
        rsurface_model = ent->model;
        if (rsurface_array_size < rsurface_model->surfmesh.num_vertices)
                R_Mesh_ResizeArrays(rsurface_model->surfmesh.num_vertices);
        R_Mesh_Matrix(&ent->matrix);
-       Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, rsurface_modelorg);
+       Matrix4x4_Transform(&ent->inversematrix, r_view.origin, rsurface_modelorg);
        if ((rsurface_entity->frameblend[0].lerp != 1 || rsurface_entity->frameblend[0].frame != 0) && (rsurface_model->surfmesh.data_morphvertex3f || rsurface_model->surfmesh.data_vertexweightindex4i))
        {
                if (wanttangents)
@@ -2581,9 +2445,9 @@ void RSurf_PrepareVerticesForBatch(qboolean generatenormals, qboolean generateta
                int texturesurfaceindex;
                float center[3], forward[3], right[3], up[3], v[4][3];
                matrix4x4_t matrix1, imatrix1;
-               Matrix4x4_Transform(&rsurface_entity->inversematrix, r_viewforward, forward);
-               Matrix4x4_Transform(&rsurface_entity->inversematrix, r_viewright, right);
-               Matrix4x4_Transform(&rsurface_entity->inversematrix, r_viewup, up);
+               Matrix4x4_Transform(&rsurface_entity->inversematrix, r_view.forward, forward);
+               Matrix4x4_Transform(&rsurface_entity->inversematrix, r_view.right, right);
+               Matrix4x4_Transform(&rsurface_entity->inversematrix, r_view.up, up);
                // make deformed versions of only the vertices used by the specified surfaces
                for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                {
@@ -2924,9 +2788,9 @@ static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, msurface_t **te
        // in Quake3 maps as it causes problems with q3map2 sky tricks,
        // and skymasking also looks very bad when noclipping outside the
        // level, so don't use it then either.
-       if (rsurface_model->type == mod_brushq1 && r_q1bsp_skymasking.integer && !r_worldnovis)
+       if (rsurface_model->type == mod_brushq1 && r_q1bsp_skymasking.integer && !r_viewcache.world_novis)
        {
-               GL_Color(fogcolor[0], fogcolor[1], fogcolor[2], 1);
+               GL_Color(r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2], 1);
                R_Mesh_ColorPointer(NULL);
                R_Mesh_ResetTextureState();
                if (skyrendermasked)
@@ -2942,19 +2806,10 @@ static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, msurface_t **te
                        // fog sky
                        GL_BlendFunc(GL_ONE, GL_ZERO);
                }
-       }
-       // LordHavoc: HalfLife maps have freaky skypolys so don't use
-       // skymasking on them, and Quake3 never did sky masking (unlike
-       // software Quake and software Quake2), so disable the sky masking
-       // in Quake3 maps as it causes problems with q3map2 sky tricks,
-       // and skymasking also looks very bad when noclipping outside the
-       // level, so don't use it then either.
-       if (rsurface_model->type == mod_brushq1 && r_q1bsp_skymasking.integer && !r_worldnovis)
-       {
                RSurf_PrepareVerticesForBatch(false, false, texturenumsurfaces, texturesurfacelist);
                RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist);
                if (skyrendermasked)
-                       GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
+                       GL_ColorMask(r_view.colormask[0], r_view.colormask[1], r_view.colormask[2], 1);
        }
 }
 
@@ -3256,7 +3111,7 @@ static void R_DrawTextureSurfaceList(int texturenumsurfaces, msurface_t **textur
        if (rsurface_texture->currentmaterialflags & MATERIALFLAG_NODRAW)
                return;
        r_shadow_rtlight = NULL;
-       renderstats.entities_surfaces += texturenumsurfaces;
+       r_refdef.stats.entities_surfaces += texturenumsurfaces;
        CHECKGLERROR
        GL_DepthTest(!(rsurface_texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
        if ((rsurface_texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (rsurface_entity->flags & RENDER_NOCULLFACE))
@@ -3340,7 +3195,7 @@ void R_QueueTextureSurfaceList(int texturenumsurfaces, msurface_t **texturesurfa
                                tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f;
                                tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f;
                                Matrix4x4_Transform(&rsurface_entity->matrix, tempcenter, center);
-                               R_MeshQueue_AddTransparent(rsurface_texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_vieworigin : center, R_DrawSurface_TransparentCallback, rsurface_entity, surface - rsurface_model->data_surfaces, r_shadow_rtlight);
+                               R_MeshQueue_AddTransparent(rsurface_texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_view.origin : center, R_DrawSurface_TransparentCallback, rsurface_entity, surface - rsurface_model->data_surfaces, r_shadow_rtlight);
                        }
                }
        }
@@ -3397,7 +3252,7 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
                msurface_t *surface;
                for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
                {
-                       if (!r_worldsurfacevisible[j])
+                       if (!r_viewcache.world_surfacevisible[j])
                                continue;
                        if (t != surface->texture || rsurface_lightmaptexture != surface->lightmaptexture)
                        {
@@ -3462,7 +3317,7 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
        }
        if (numsurfacelist)
                R_QueueTextureSurfaceList(numsurfacelist, surfacelist);
-       renderstats.entities_triangles += counttriangles;
+       r_refdef.stats.entities_triangles += counttriangles;
        RSurf_CleanUp();
 
        if (r_showcollisionbrushes.integer && model->brush.num_brushes && !skysurfaces)
@@ -3477,14 +3332,14 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
                GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
                GL_DepthMask(false);
                GL_DepthTest(!r_showdisabledepthtest.integer);
-               qglPolygonOffset(r_polygonfactor + r_showcollisionbrushes_polygonfactor.value, r_polygonoffset + r_showcollisionbrushes_polygonoffset.value);CHECKGLERROR
+               qglPolygonOffset(r_refdef.polygonfactor + r_showcollisionbrushes_polygonfactor.value, r_refdef.polygonoffset + r_showcollisionbrushes_polygonoffset.value);CHECKGLERROR
                for (i = 0, brush = model->brush.data_brushes + model->firstmodelbrush;i < model->nummodelbrushes;i++, brush++)
                        if (brush->colbrushf && brush->colbrushf->numtriangles)
                                R_DrawCollisionBrush(brush->colbrushf);
                for (i = 0, surface = model->data_surfaces + model->firstmodelsurface;i < model->nummodelsurfaces;i++, surface++)
                        if (surface->num_collisiontriangles)
                                R_DrawCollisionSurface(ent, surface);
-               qglPolygonOffset(r_polygonfactor, r_polygonoffset);CHECKGLERROR
+               qglPolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);CHECKGLERROR
        }
 
        if (r_showtris.integer || r_shownormals.integer)
@@ -3505,7 +3360,7 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
                R_Mesh_ResetTextureState();
                for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
                {
-                       if (ent == r_refdef.worldentity && !r_worldsurfacevisible[j])
+                       if (ent == r_refdef.worldentity && !r_viewcache.world_surfacevisible[j])
                                continue;
                        rsurface_texture = surface->texture->currentframe;
                        if ((rsurface_texture->currentmaterialflags & flagsmask) && surface->num_triangles)
index a8448d6..e02f055 100644 (file)
@@ -32,17 +32,6 @@ cvar_t r_lockvisibility = {0, "r_lockvisibility", "0", "disables visibility upda
 cvar_t r_useportalculling = {0, "r_useportalculling", "1", "use advanced portal culling visibility method to improve performance over just Potentially Visible Set, provides an even more significant speed improvement in unvised maps"};
 cvar_t r_q3bsp_renderskydepth = {0, "r_q3bsp_renderskydepth", "0", "draws sky depth masking in q3 maps (as in q1 maps), this means for example that sky polygons can hide other things"};
 
-// flag arrays used for visibility checking on world model
-// (all other entities have no per-surface/per-leaf visibility checks)
-// TODO: dynamic resize according to r_refdef.worldmodel->brush.num_clusters
-unsigned char r_pvsbits[(32768+7)>>3];
-// TODO: dynamic resize according to r_refdef.worldmodel->brush.num_leafs
-unsigned char r_worldleafvisible[32768];
-// TODO: dynamic resize according to r_refdef.worldmodel->num_surfaces
-unsigned char r_worldsurfacevisible[262144];
-// if true, the view is currently in a leaf without pvs data
-qboolean r_worldnovis;
-
 /*
 ===============
 R_BuildLightMap
@@ -381,7 +370,7 @@ static void R_DrawPortals(void)
                return;
        for (leafnum = 0;leafnum < r_refdef.worldmodel->brush.num_leafs;leafnum++)
        {
-               if (r_worldleafvisible[leafnum])
+               if (r_viewcache.world_leafvisible[leafnum])
                {
                        //for (portalnum = 0, portal = model->brush.data_portals;portalnum < model->brush.num_portals;portalnum++, portal++)
                        for (portal = r_refdef.worldmodel->brush.data_leafs[leafnum].portals;portal;portal = portal->next)
@@ -401,7 +390,7 @@ static void R_DrawPortals(void)
        }
 }
 
-void R_WorldVisibility(void)
+void R_View_WorldVisibility(void)
 {
        int i, j, *mark;
        mleaf_t *leaf;
@@ -412,18 +401,18 @@ void R_WorldVisibility(void)
                return;
 
        // if possible find the leaf the view origin is in
-       viewleaf = model->brush.PointInLeaf ? model->brush.PointInLeaf(model, r_vieworigin) : NULL;
+       viewleaf = model->brush.PointInLeaf ? model->brush.PointInLeaf(model, r_view.origin) : NULL;
        // if possible fetch the visible cluster bits
        if (!r_lockpvs.integer && model->brush.FatPVS)
-               model->brush.FatPVS(model, r_vieworigin, 2, r_pvsbits, sizeof(r_pvsbits));
+               model->brush.FatPVS(model, r_view.origin, 2, r_viewcache.world_pvsbits, sizeof(r_viewcache.world_pvsbits));
 
        if (!r_lockvisibility.integer)
        {
                // clear the visible surface and leaf flags arrays
-               memset(r_worldsurfacevisible, 0, model->num_surfaces);
-               memset(r_worldleafvisible, 0, model->brush.num_leafs);
+               memset(r_viewcache.world_surfacevisible, 0, model->num_surfaces);
+               memset(r_viewcache.world_leafvisible, 0, model->brush.num_leafs);
 
-               r_worldnovis = false;
+               r_viewcache.world_novis = false;
 
                // if floating around in the void (no pvs data available, and no
                // portals available), simply use all on-screen leafs.
@@ -432,17 +421,17 @@ void R_WorldVisibility(void)
                        // no visibility method: (used when floating around in the void)
                        // simply cull each leaf to the frustum (view pyramid)
                        // similar to quake's RecursiveWorldNode but without cache misses
-                       r_worldnovis = true;
+                       r_viewcache.world_novis = true;
                        for (j = 0, leaf = model->brush.data_leafs;j < model->brush.num_leafs;j++, leaf++)
                        {
                                // if leaf is in current pvs and on the screen, mark its surfaces
                                if (!R_CullBox(leaf->mins, leaf->maxs))
                                {
-                                       renderstats.world_leafs++;
-                                       r_worldleafvisible[j] = true;
+                                       r_refdef.stats.world_leafs++;
+                                       r_viewcache.world_leafvisible[j] = true;
                                        if (leaf->numleafsurfaces)
                                                for (i = 0, mark = leaf->firstleafsurface;i < leaf->numleafsurfaces;i++, mark++)
-                                                       r_worldsurfacevisible[*mark] = true;
+                                                       r_viewcache.world_surfacevisible[*mark] = true;
                                }
                        }
                }
@@ -457,13 +446,13 @@ void R_WorldVisibility(void)
                        for (j = 0, leaf = model->brush.data_leafs;j < model->brush.num_leafs;j++, leaf++)
                        {
                                // if leaf is in current pvs and on the screen, mark its surfaces
-                               if (CHECKPVSBIT(r_pvsbits, leaf->clusterindex) && !R_CullBox(leaf->mins, leaf->maxs))
+                               if (CHECKPVSBIT(r_viewcache.world_pvsbits, leaf->clusterindex) && !R_CullBox(leaf->mins, leaf->maxs))
                                {
-                                       renderstats.world_leafs++;
-                                       r_worldleafvisible[j] = true;
+                                       r_refdef.stats.world_leafs++;
+                                       r_viewcache.world_leafvisible[j] = true;
                                        if (leaf->numleafsurfaces)
                                                for (i = 0, mark = leaf->firstleafsurface;i < leaf->numleafsurfaces;i++, mark++)
-                                                       r_worldsurfacevisible[*mark] = true;
+                                                       r_viewcache.world_surfacevisible[*mark] = true;
                                }
                        }
                }
@@ -485,13 +474,13 @@ void R_WorldVisibility(void)
                        leafstackpos = 1;
                        while (leafstackpos)
                        {
-                               renderstats.world_leafs++;
+                               r_refdef.stats.world_leafs++;
                                leaf = leafstack[--leafstackpos];
-                               r_worldleafvisible[leaf - model->brush.data_leafs] = true;
+                               r_viewcache.world_leafvisible[leaf - model->brush.data_leafs] = true;
                                // mark any surfaces bounding this leaf
                                if (leaf->numleafsurfaces)
                                        for (i = 0, mark = leaf->firstleafsurface;i < leaf->numleafsurfaces;i++, mark++)
-                                               r_worldsurfacevisible[*mark] = true;
+                                               r_viewcache.world_surfacevisible[*mark] = true;
                                // follow portals into other leafs
                                // the checks are:
                                // if viewer is behind portal (portal faces outward into the scene)
@@ -501,8 +490,8 @@ void R_WorldVisibility(void)
                                // (the first two checks won't cause as many cache misses as the leaf checks)
                                for (p = leaf->portals;p;p = p->next)
                                {
-                                       renderstats.world_portals++;
-                                       if (DotProduct(r_vieworigin, p->plane.normal) < (p->plane.dist + 1) && !R_CullBox(p->mins, p->maxs) && !r_worldleafvisible[p->past - model->brush.data_leafs] && CHECKPVSBIT(r_pvsbits, p->past->clusterindex))
+                                       r_refdef.stats.world_portals++;
+                                       if (DotProduct(r_view.origin, p->plane.normal) < (p->plane.dist + 1) && !R_CullBox(p->mins, p->maxs) && !r_viewcache.world_leafvisible[p->past - model->brush.data_leafs] && CHECKPVSBIT(r_viewcache.world_pvsbits, p->past->clusterindex))
                                                leafstack[leafstackpos++] = p->past;
                                }
                        }
@@ -824,7 +813,7 @@ static void R_Q1BSP_DrawLight_TransparentBatch(int batchnumsurfaces, msurface_t
                tempcenter[1] = (batchsurface->mins[1] + batchsurface->maxs[1]) * 0.5f;
                tempcenter[2] = (batchsurface->mins[2] + batchsurface->maxs[2]) * 0.5f;
                Matrix4x4_Transform(&rsurface_entity->matrix, tempcenter, center);
-               R_MeshQueue_AddTransparent(rsurface_texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_vieworigin : center, R_Q1BSP_DrawLight_TransparentCallback, rsurface_entity, batchsurface - rsurface_model->data_surfaces, r_shadow_rtlight);
+               R_MeshQueue_AddTransparent(rsurface_texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_view.origin : center, R_Q1BSP_DrawLight_TransparentCallback, rsurface_entity, batchsurface - rsurface_model->data_surfaces, r_shadow_rtlight);
        }
 }
 
@@ -848,10 +837,10 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, int numsurfaces, const int *surface
        CHECKGLERROR
        for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++)
        {
-               if ((ent == r_refdef.worldentity && !r_worldsurfacevisible[surfacelist[surfacelistindex]]))
+               if ((ent == r_refdef.worldentity && !r_viewcache.world_surfacevisible[surfacelist[surfacelistindex]]))
                        continue;
                surface = model->data_surfaces + surfacelist[surfacelistindex];
-               renderstats.lights_lighttriangles += surface->num_triangles;
+               r_refdef.stats.lights_lighttriangles += surface->num_triangles;
                if (tex != surface->texture)
                {
                        if (batchnumsurfaces > 0)
diff --git a/host.c b/host.c
index e0883ae..0623c1a 100644 (file)
--- a/host.c
+++ b/host.c
@@ -653,8 +653,15 @@ void Host_Main(void)
                                // don't allow simulation to run too fast or too slow or logic glitches can occur
 
                                // stop running server frames if the wall time reaches this value
-                               if (sys_ticrate.value <= 0 || (cl.islocalgame && !sv_fixedframeratesingleplayer.integer))
+                               if (sys_ticrate.value <= 0)
                                        advancetime = sv_timer;
+                               else if (cl.islocalgame && !sv_fixedframeratesingleplayer.integer)
+                               {
+                                       // synchronize to the client frametime, but no less than 10ms and no more than sys_ticrate
+                                       advancetime = bound(0.01, cl_timer, sys_ticrate.value);
+                                       framelimit = 10;
+                                       aborttime = Sys_DoubleTime() + 0.1;
+                               }
                                else
                                {
                                        advancetime = sys_ticrate.value;
@@ -786,7 +793,7 @@ void Host_Main(void)
                                        csqc_usecsqclistener = false;
                                }
                                else
-                                       S_Update(&r_refdef.viewentitymatrix);
+                                       S_Update(&r_view.matrix);
 
                                CDAudio_Update();
                        }
index 6b6ff07..f1d01ed 100644 (file)
@@ -2,10 +2,6 @@
 #include "quakedef.h"
 #include "meshqueue.h"
 
-cvar_t r_meshqueue_entries = {CVAR_SAVE, "r_meshqueue_entries", "16", "maximum number of meshes to batch together and sort before issuing render calls (unused)"};
-cvar_t r_meshqueue_immediaterender = {0, "r_meshqueue_immediaterender", "0", "immediately render non-transparent meshes rather than batching"};
-cvar_t r_meshqueue_sort = {0, "r_meshqueue_sort", "0", "whether to sort meshes in a batch before issuing calls"};
-
 typedef struct meshqueue_s
 {
        struct meshqueue_s *next;
@@ -19,108 +15,38 @@ meshqueue_t;
 
 float mqt_viewplanedist;
 float mqt_viewmaxdist;
-meshqueue_t *mq_array, *mqt_array, *mq_listhead;
-int mq_count, mqt_count;
-int mq_total, mqt_total;
+meshqueue_t *mqt_array;
+int mqt_count;
+int mqt_total;
 
-void R_MeshQueue_Init(void)
+void R_MeshQueue_BeginScene(void)
 {
-       Cvar_RegisterVariable(&r_meshqueue_entries);
-       Cvar_RegisterVariable(&r_meshqueue_immediaterender);
-       Cvar_RegisterVariable(&r_meshqueue_sort);
-
-       mq_total = 0;
-       mqt_total = 0;
-       mq_array = NULL;
-       mqt_array = NULL;
+       mqt_count = 0;
+       mqt_viewplanedist = DotProduct(r_view.origin, r_view.forward);
+       mqt_viewmaxdist = 0;
 }
 
-void R_MeshQueue_Render(void)
+void R_MeshQueue_AddTransparent(const vec3_t center, void (*callback)(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist), const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight)
 {
-       // this is only used by one piece of code in prvm_cmds, why is it used at all?
        meshqueue_t *mq;
-       if (!mq_count)
-               return;
-       for (mq = mq_listhead;mq;mq = mq->next)
-               mq->callback(mq->ent, mq->rtlight, 1, &mq->surfacenumber);
-       mq_count = 0;
-       mq_listhead = NULL;
-}
-
-static void R_MeshQueue_EnlargeTransparentArray(int newtotal)
-{
-       meshqueue_t *newarray;
-       newarray = (meshqueue_t *)Mem_Alloc(cls.permanentmempool, newtotal * sizeof(meshqueue_t));
-       if (mqt_array)
+       if (mqt_count >= mqt_total || !mqt_array)
        {
-               memcpy(newarray, mqt_array, mqt_total * sizeof(meshqueue_t));
-               Mem_Free(mqt_array);
-       }
-       mqt_array = newarray;
-       mqt_total = newtotal;
-}
-
-void R_MeshQueue_Add(void (*callback)(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist), const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight)
-{
-       // this is only used by one piece of code in prvm_cmds, why is it used at all?
-       meshqueue_t *mq, **mqnext;
-       if (r_meshqueue_immediaterender.integer)
-       {
-               callback(ent, rtlight, 1, &surfacenumber);
-               return;
-       }
-       if (mq_count >= mq_total)
-               R_MeshQueue_Render();
-       mq = &mq_array[mq_count++];
-       mq->callback = callback;
-       mq->ent = ent;
-       mq->surfacenumber = surfacenumber;
-       mq->rtlight = rtlight;
-
-       if (r_meshqueue_sort.integer)
-       {
-               // bubble-insert sort into meshqueue
-               for(mqnext = &mq_listhead;*mqnext;mqnext = &(*mqnext)->next)
+               int newtotal = max(1024, mqt_total * 2);
+               meshqueue_t *newarray = (meshqueue_t *)Mem_Alloc(cls.permanentmempool, newtotal * sizeof(meshqueue_t));
+               if (mqt_array)
                {
-                       if (mq->callback == (*mqnext)->callback)
-                       {
-                               if (mq->ent == (*mqnext)->ent)
-                               {
-                                       if (mq->surfacenumber == (*mqnext)->surfacenumber)
-                                       {
-                                               if (mq->rtlight <= (*mqnext)->rtlight)
-                                                       break;
-                                       }
-                                       else if (mq->surfacenumber < (*mqnext)->surfacenumber)
-                                               break;
-                               }
-                               else if (mq->ent < (*mqnext)->ent)
-                                       break;
-                       }
-                       else if (mq->callback < (*mqnext)->callback)
-                               break;
+                       memcpy(newarray, mqt_array, mqt_total * sizeof(meshqueue_t));
+                       Mem_Free(mqt_array);
                }
+               mqt_array = newarray;
+               mqt_total = newtotal;
        }
-       else
-       {
-               // maintain the order
-               for(mqnext = &mq_listhead;*mqnext;mqnext = &(*mqnext)->next);
-       }
-       mq->next = *mqnext;
-       *mqnext = mq;
-}
-
-void R_MeshQueue_AddTransparent(const vec3_t center, void (*callback)(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist), const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight)
-{
-       meshqueue_t *mq;
-       if (mqt_count >= mqt_total)
-               R_MeshQueue_EnlargeTransparentArray(mqt_total + 100);
        mq = &mqt_array[mqt_count++];
        mq->callback = callback;
        mq->ent = ent;
        mq->surfacenumber = surfacenumber;
        mq->rtlight = rtlight;
-       mq->dist = DotProduct(center, r_viewforward) - mqt_viewplanedist;
+       mq->dist = DotProduct(center, r_view.forward) - mqt_viewplanedist;
        mq->next = NULL;
        mqt_viewmaxdist = max(mqt_viewmaxdist, mq->dist);
 }
@@ -137,8 +63,6 @@ void R_MeshQueue_RenderTransparent(void)
        meshqueue_t *mqt;
        meshqueue_t *hash[4096], **hashpointer[4096];
        int batchsurfaceindex[256];
-       if (mq_count)
-               R_MeshQueue_Render();
        if (!mqt_count)
                return;
        memset(hash, 0, sizeof(hash));
@@ -182,43 +106,3 @@ void R_MeshQueue_RenderTransparent(void)
                callback(ent, rtlight, batchnumsurfaces, batchsurfaceindex);
        mqt_count = 0;
 }
-
-void R_MeshQueue_BeginScene(void)
-{
-       if (r_meshqueue_entries.integer < 1)
-               Cvar_SetValueQuick(&r_meshqueue_entries, 1);
-       if (r_meshqueue_entries.integer > 65536)
-               Cvar_SetValueQuick(&r_meshqueue_entries, 65536);
-
-       if (mq_total != r_meshqueue_entries.integer || mq_array == NULL)
-       {
-               mq_total = r_meshqueue_entries.integer;
-               if (mq_array)
-                       Mem_Free(mq_array);
-               mq_array = (meshqueue_t *)Mem_Alloc(cls.permanentmempool, mq_total * sizeof(meshqueue_t));
-       }
-
-       if (mqt_array == NULL)
-               mqt_array = (meshqueue_t *)Mem_Alloc(cls.permanentmempool, mqt_total * sizeof(meshqueue_t));
-
-       mq_count = 0;
-       mqt_count = 0;
-       mq_listhead = NULL;
-       mqt_viewplanedist = DotProduct(r_vieworigin, r_viewforward);
-       mqt_viewmaxdist = 0;
-}
-
-void R_MeshQueue_EndScene(void)
-{
-       if (mq_count)
-       {
-               Con_Printf("R_MeshQueue_EndScene: main mesh queue still has %i items left, flushing\n", mq_count);
-               R_MeshQueue_Render();
-       }
-       if (mqt_count)
-       {
-               Con_Printf("R_MeshQueue_EndScene: transparent mesh queue still has %i items left, flushing\n", mqt_count);
-               R_MeshQueue_RenderTransparent();
-       }
-}
-
index be2e3f0..8e5b36e 100644 (file)
@@ -2,12 +2,8 @@
 #ifndef MESHQUEUE_H
 #define MESHQUEUE_H
 
-void R_MeshQueue_Init(void);
-void R_MeshQueue_Add(void (*callback)(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist), const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight);
-void R_MeshQueue_AddTransparent(const vec3_t center, void (*callback)(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist), const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight);
 void R_MeshQueue_BeginScene(void);
-void R_MeshQueue_Render(void);
+void R_MeshQueue_AddTransparent(const vec3_t center, void (*callback)(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist), const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight);
 void R_MeshQueue_RenderTransparent(void);
-void R_MeshQueue_EndScene(void);
 
 #endif
index 0ea7436..8533991 100644 (file)
@@ -3075,7 +3075,7 @@ void VM_AddPolygonsToMeshQueue (void)
        if(!vm_drawpolygons_num)
                return;
        for(i = 0;i < vm_drawpolygons_num;i++)
-               R_MeshQueue_Add(VM_DrawPolygonCallback, NULL, i, NULL);
+               VM_DrawPolygonCallback(NULL, NULL, i, NULL);
        vm_drawpolygons_num = 0;
 }
 
index e0fd5b2..c47f34b 100644 (file)
@@ -80,14 +80,14 @@ void R_DrawWorldCrosshair(void)
 
        // get the forward vector for the gun (not the view)
        AngleVectors(cl.viewangles, v2, NULL, NULL);
-       //VectorCopy(r_vieworigin, v1);
+       //VectorCopy(r_view.origin, v1);
        VectorMA(v1, 8192, v2, v2);
        trace = CL_TraceBox(v1, vec3_origin, vec3_origin, v2, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, false);
        spritescale = trace.fraction * (8192.0f / 40.0f) * crosshair_size.value;
        VectorCopy(trace.endpos, spriteorigin);
 
        // draw the sprite
-       R_DrawSprite(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, pic->tex, NULL, true, spriteorigin, r_viewright, r_viewup, spritescale, -spritescale, -spritescale, spritescale, color[0], color[1], color[2], color[3]);
+       R_DrawSprite(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, pic->tex, NULL, true, spriteorigin, r_view.right, r_view.up, spritescale, -spritescale, -spritescale, spritescale, color[0], color[1], color[2], color[3]);
 }
 
 void R_Draw2DCrosshair(void)
index a486f42..6f2c36e 100644 (file)
@@ -151,7 +151,7 @@ void R_NewExplosion(const vec3_t org)
        fractalnoisequick(noise, EXPLOSIONGRID, 4); // adjust noise grid size according to explosion
        for (i = 0, e = explosion;i < MAX_EXPLOSIONS;i++, e++)
        {
-               if (cl.time >= e->endtime)
+               if (!e->alpha)
                {
                        e->starttime = cl.time;
                        e->endtime = cl.time + cl_explosions_lifetime.value;
@@ -215,6 +215,11 @@ static void R_MoveExplosion(explosion_t *e)
        frametime = cl.time - e->time;
        e->time = cl.time;
        e->alpha = e->alpha - (e->fade * frametime);
+       if (e->alpha < 0 || cl.time > e->endtime)
+       {
+               e->alpha = 0;
+               return;
+       }
        for (i = 0;i < EXPLOSIONVERTS;i++)
        {
                if (e->vertvel[i][0] || e->vertvel[i][1] || e->vertvel[i][2])
@@ -242,7 +247,7 @@ void R_MoveExplosions(void)
 {
        int i;
        for (i = 0;i < MAX_EXPLOSIONS;i++)
-               if (cl.time < explosion[i].endtime)
+               if (explosion[i].alpha)
                        R_MoveExplosion(&explosion[i]);
 }
 
@@ -253,7 +258,7 @@ void R_DrawExplosions(void)
        if (!r_drawexplosions.integer)
                return;
        for (i = 0;i < MAX_EXPLOSIONS;i++)
-               if (r_refdef.time < explosion[i].endtime)
+               if (explosion[i].alpha)
                        R_MeshQueue_AddTransparent(explosion[i].origin, R_DrawExplosion_TransparentCallback, NULL, i, NULL);
 }
 
index ecab72a..944988e 100644 (file)
--- a/r_light.c
+++ b/r_light.c
@@ -80,21 +80,21 @@ void R_DrawCoronas(void)
        if (r_coronas.value < 0.01)
                return;
        R_Mesh_Matrix(&identitymatrix);
-       viewdist = DotProduct(r_vieworigin, r_viewforward);
-       flag = r_rtworld ? LIGHTFLAG_REALTIMEMODE : LIGHTFLAG_NORMALMODE;
+       viewdist = DotProduct(r_view.origin, r_view.forward);
+       flag = r_refdef.rtworld ? LIGHTFLAG_REALTIMEMODE : LIGHTFLAG_NORMALMODE;
        for (lnum = 0, light = r_shadow_worldlightchain;light;light = light->next, lnum++)
        {
-               if ((light->flags & flag) && light->corona * r_coronas.value > 0 && (r_shadow_debuglight.integer < 0 || r_shadow_debuglight.integer == lnum) && (dist = (DotProduct(light->rtlight.shadoworigin, r_viewforward) - viewdist)) >= 24.0f && CL_TraceBox(light->rtlight.shadoworigin, vec3_origin, vec3_origin, r_vieworigin, true, NULL, SUPERCONTENTS_SOLID, false).fraction == 1)
+               if ((light->flags & flag) && light->corona * r_coronas.value > 0 && (r_shadow_debuglight.integer < 0 || r_shadow_debuglight.integer == lnum) && (dist = (DotProduct(light->rtlight.shadoworigin, r_view.forward) - viewdist)) >= 24.0f && CL_TraceBox(light->rtlight.shadoworigin, vec3_origin, vec3_origin, r_view.origin, true, NULL, SUPERCONTENTS_SOLID, false).fraction == 1)
                {
                        cscale = light->rtlight.corona * r_coronas.value * 0.25f;
                        scale = light->rtlight.radius * light->rtlight.coronasizescale;
-                       R_DrawSprite(GL_ONE, GL_ONE, lightcorona, NULL, true, light->rtlight.shadoworigin, r_viewright, r_viewup, scale, -scale, -scale, scale, light->rtlight.color[0] * cscale, light->rtlight.color[1] * cscale, light->rtlight.color[2] * cscale, 1);
+                       R_DrawSprite(GL_ONE, GL_ONE, lightcorona, NULL, true, light->rtlight.shadoworigin, r_view.right, r_view.up, scale, -scale, -scale, scale, light->rtlight.color[0] * cscale, light->rtlight.color[1] * cscale, light->rtlight.color[2] * cscale, 1);
                }
        }
        for (i = 0;i < r_refdef.numlights;i++)
        {
                light = r_refdef.lights[i];
-               if ((light->flags & flag) && light->corona * r_coronas.value > 0 && (dist = (DotProduct(light->origin, r_viewforward) - viewdist)) >= 24.0f && CL_TraceBox(light->origin, vec3_origin, vec3_origin, r_vieworigin, true, NULL, SUPERCONTENTS_SOLID, false).fraction == 1)
+               if ((light->flags & flag) && light->corona * r_coronas.value > 0 && (dist = (DotProduct(light->origin, r_view.forward) - viewdist)) >= 24.0f && CL_TraceBox(light->origin, vec3_origin, vec3_origin, r_view.origin, true, NULL, SUPERCONTENTS_SOLID, false).fraction == 1)
                {
                        cscale = light->corona * r_coronas.value * 0.25f;
                        scale = light->rtlight.radius * light->rtlight.coronasizescale;
@@ -103,7 +103,7 @@ void R_DrawCoronas(void)
                                cscale *= 4.0f;
                                scale *= 2.0f;
                        }
-                       R_DrawSprite(GL_ONE, GL_ONE, lightcorona, NULL, true, light->origin, r_viewright, r_viewup, scale, -scale, -scale, scale, light->color[0] * cscale, light->color[1] * cscale, light->color[2] * cscale, 1);
+                       R_DrawSprite(GL_ONE, GL_ONE, lightcorona, NULL, true, light->origin, r_view.right, r_view.up, scale, -scale, -scale, scale, light->color[0] * cscale, light->color[1] * cscale, light->color[2] * cscale, 1);
                }
        }
 }
index 8bc5600..68f6b8f 100644 (file)
@@ -219,7 +219,7 @@ void R_FogLightningBeam_Vertex3f_Color4f(const float *v, float *c, int numverts,
        float ifog;
        for (i = 0;i < numverts;i++, v += 3, c += 4)
        {
-               ifog = 1 - VERTEXFOGTABLE(VectorDistance(v, r_vieworigin));
+               ifog = 1 - VERTEXFOGTABLE(VectorDistance(v, r_view.origin));
                c[0] = r * ifog;
                c[1] = g * ifog;
                c[2] = b * ifog;
@@ -246,7 +246,7 @@ void R_DrawLightningBeam_TransparentCallback(const entity_render_t *ent, const r
                r_lightningbeams_setuptexture();
 
        R_Mesh_VertexPointer(vertex3f);
-       if (fogenabled)
+       if (r_refdef.fogenabled)
        {
                // per vertex colors if fog is used
                R_Mesh_ColorPointer(color4f);
@@ -284,7 +284,7 @@ void R_DrawLightningBeam_TransparentCallback(const entity_render_t *ent, const r
 
                // calculate up vector such that it points toward viewer, and rotates around the beamdir
                // get direction from start of beam to viewer
-               VectorSubtract(r_vieworigin, b->start, up);
+               VectorSubtract(r_view.origin, b->start, up);
                // remove the portion of the vector that moves along the beam
                // (this leaves only a vector pointing directly away from the beam)
                t1 = -DotProduct(up, beamdir);
@@ -325,7 +325,7 @@ void R_DrawLightningBeam_TransparentCallback(const entity_render_t *ent, const r
                R_CalcLightningBeamPolygonTexCoord2f(texcoord2f + 0, t1, t2);
                R_CalcLightningBeamPolygonTexCoord2f(texcoord2f + 8, t1 + 0.33, t2 + 0.33);
                R_CalcLightningBeamPolygonTexCoord2f(texcoord2f + 16, t1 + 0.66, t2 + 0.66);
-               if (fogenabled)
+               if (r_refdef.fogenabled)
                {
                        // per vertex colors if fog is used
                        R_FogLightningBeam_Vertex3f_Color4f(vertex3f, color4f, 12, r_lightningbeam_color_red.value, r_lightningbeam_color_green.value, r_lightningbeam_color_blue.value, 1);
index e1a736e..5541bfd 100644 (file)
@@ -659,7 +659,7 @@ void R_Shadow_VolumeFromList(int numverts, int numtris, const float *invertex3f,
        if (maxshadowtriangles < nummarktris || maxshadowvertices < numverts)
                R_Shadow_ResizeShadowArrays((numverts + 255) & ~255, (nummarktris + 255) & ~255);
        tris = R_Shadow_ConstructShadowVolume(numverts, numtris, elements, neighbors, invertex3f, &outverts, shadowelements, shadowvertex3f, projectorigin, projectdistance, nummarktris, marktris);
-       renderstats.lights_dynamicshadowtriangles += tris;
+       r_refdef.stats.lights_dynamicshadowtriangles += tris;
        R_Shadow_RenderVolume(outverts, tris, shadowvertex3f, shadowelements);
 }
 
@@ -708,7 +708,7 @@ void R_Shadow_RenderVolume(int numvertices, int numtriangles, const float *verte
                Mod_ShadowMesh_AddMesh(r_main_mempool, r_shadow_compilingrtlight->static_meshchain_shadow, NULL, NULL, NULL, vertex3f, NULL, NULL, NULL, NULL, numtriangles, element3i);
                return;
        }
-       renderstats.lights_shadowtriangles += numtriangles;
+       r_refdef.stats.lights_shadowtriangles += numtriangles;
        CHECKGLERROR
        R_Mesh_VertexPointer(vertex3f);
        GL_LockArrays(0, numvertices);
@@ -825,7 +825,7 @@ void R_Shadow_RenderMode_Begin(void)
        GL_Color(0, 0, 0, 1);
        qglCullFace(GL_FRONT);CHECKGLERROR // quake is backwards, this culls back faces
        qglEnable(GL_CULL_FACE);CHECKGLERROR
-       GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height);
+       GL_Scissor(r_view.x, r_view.y, r_view.width, r_view.height);
 
        r_shadow_rendermode = R_SHADOW_RENDERMODE_NONE;
 
@@ -871,7 +871,7 @@ void R_Shadow_RenderMode_StencilShadowVolumes(void)
        GL_BlendFunc(GL_ONE, GL_ZERO);
        GL_DepthMask(false);
        GL_DepthTest(true);
-       qglPolygonOffset(r_shadowpolygonfactor, r_shadowpolygonoffset);CHECKGLERROR
+       qglPolygonOffset(r_refdef.shadowpolygonfactor, r_refdef.shadowpolygonoffset);CHECKGLERROR
        qglDepthFunc(GL_LESS);CHECKGLERROR
        qglCullFace(GL_FRONT);CHECKGLERROR // quake is backwards, this culls back faces
        qglEnable(GL_STENCIL_TEST);CHECKGLERROR
@@ -896,7 +896,7 @@ void R_Shadow_RenderMode_StencilShadowVolumes(void)
                qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);CHECKGLERROR
        }
        GL_Clear(GL_STENCIL_BUFFER_BIT);
-       renderstats.lights_clears++;
+       r_refdef.stats.lights_clears++;
 }
 
 void R_Shadow_RenderMode_Lighting(qboolean stenciltest, qboolean transparent)
@@ -906,10 +906,10 @@ void R_Shadow_RenderMode_Lighting(qboolean stenciltest, qboolean transparent)
        GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
        GL_DepthMask(false);
        GL_DepthTest(true);
-       qglPolygonOffset(r_polygonfactor, r_polygonoffset);CHECKGLERROR
+       qglPolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);CHECKGLERROR
        //qglDisable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
        GL_Color(1, 1, 1, 1);
-       GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
+       GL_ColorMask(r_view.colormask[0], r_view.colormask[1], r_view.colormask[2], 1);
        if (transparent)
        {
                qglDepthFunc(GL_LEQUAL);CHECKGLERROR
@@ -949,7 +949,7 @@ void R_Shadow_RenderMode_Lighting(qboolean stenciltest, qboolean transparent)
                R_Mesh_TexBind(9, R_GetTexture(r_texture_black)); // glow
                //R_Mesh_TexMatrix(3, r_shadow_entitytolight); // light filter matrix
                GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
-               GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 0);
+               GL_ColorMask(r_view.colormask[0], r_view.colormask[1], r_view.colormask[2], 0);
                CHECKGLERROR
        }
 }
@@ -961,9 +961,9 @@ void R_Shadow_RenderMode_VisibleShadowVolumes(void)
        GL_BlendFunc(GL_ONE, GL_ONE);
        GL_DepthMask(false);
        GL_DepthTest(!r_showdisabledepthtest.integer);
-       qglPolygonOffset(r_polygonfactor, r_polygonoffset);CHECKGLERROR
+       qglPolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);CHECKGLERROR
        GL_Color(0.0, 0.0125, 0.1, 1);
-       GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
+       GL_ColorMask(r_view.colormask[0], r_view.colormask[1], r_view.colormask[2], 1);
        qglDepthFunc(GL_GEQUAL);CHECKGLERROR
        qglCullFace(GL_FRONT);CHECKGLERROR // this culls back
        qglDisable(GL_CULL_FACE);CHECKGLERROR
@@ -978,9 +978,9 @@ void R_Shadow_RenderMode_VisibleLighting(qboolean stenciltest, qboolean transpar
        GL_BlendFunc(GL_ONE, GL_ONE);
        GL_DepthMask(false);
        GL_DepthTest(!r_showdisabledepthtest.integer);
-       qglPolygonOffset(r_polygonfactor, r_polygonoffset);CHECKGLERROR
+       qglPolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);CHECKGLERROR
        GL_Color(0.1, 0.0125, 0, 1);
-       GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
+       GL_ColorMask(r_view.colormask[0], r_view.colormask[1], r_view.colormask[2], 1);
        if (transparent)
        {
                qglDepthFunc(GL_LEQUAL);CHECKGLERROR
@@ -1010,11 +1010,11 @@ void R_Shadow_RenderMode_End(void)
        GL_BlendFunc(GL_ONE, GL_ZERO);
        GL_DepthMask(true);
        GL_DepthTest(true);
-       qglPolygonOffset(r_polygonfactor, r_polygonoffset);CHECKGLERROR
+       qglPolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);CHECKGLERROR
        //qglDisable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
        GL_Color(1, 1, 1, 1);
-       GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
-       GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height);
+       GL_ColorMask(r_view.colormask[0], r_view.colormask[1], r_view.colormask[2], 1);
+       GL_Scissor(r_view.x, r_view.y, r_view.width, r_view.height);
        qglDepthFunc(GL_LEQUAL);CHECKGLERROR
        qglCullFace(GL_FRONT);CHECKGLERROR // quake is backwards, this culls back faces
        qglEnable(GL_CULL_FACE);CHECKGLERROR
@@ -1039,18 +1039,18 @@ qboolean R_Shadow_ScissorForBBox(const float *mins, const float *maxs)
        float vertex3f[256*3];
 
        // if view is inside the light box, just say yes it's visible
-       if (BoxesOverlap(r_vieworigin, r_vieworigin, mins, maxs))
+       if (BoxesOverlap(r_view.origin, r_view.origin, mins, maxs))
        {
-               GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height);
+               GL_Scissor(r_view.x, r_view.y, r_view.width, r_view.height);
                return false;
        }
 
        // create a temporary brush describing the area the light can affect in worldspace
-       VectorNegate(frustum[0].normal, planes[ 0].normal);planes[ 0].dist = -frustum[0].dist;
-       VectorNegate(frustum[1].normal, planes[ 1].normal);planes[ 1].dist = -frustum[1].dist;
-       VectorNegate(frustum[2].normal, planes[ 2].normal);planes[ 2].dist = -frustum[2].dist;
-       VectorNegate(frustum[3].normal, planes[ 3].normal);planes[ 3].dist = -frustum[3].dist;
-       VectorNegate(frustum[4].normal, planes[ 4].normal);planes[ 4].dist = -frustum[4].dist;
+       VectorNegate(r_view.frustum[0].normal, planes[ 0].normal);planes[ 0].dist = -r_view.frustum[0].dist;
+       VectorNegate(r_view.frustum[1].normal, planes[ 1].normal);planes[ 1].dist = -r_view.frustum[1].dist;
+       VectorNegate(r_view.frustum[2].normal, planes[ 2].normal);planes[ 2].dist = -r_view.frustum[2].dist;
+       VectorNegate(r_view.frustum[3].normal, planes[ 3].normal);planes[ 3].dist = -r_view.frustum[3].dist;
+       VectorNegate(r_view.frustum[4].normal, planes[ 4].normal);planes[ 4].dist = -r_view.frustum[4].dist;
        VectorSet   (planes[ 5].normal,  1, 0, 0);         planes[ 5].dist =  maxs[0];
        VectorSet   (planes[ 6].normal, -1, 0, 0);         planes[ 6].dist = -mins[0];
        VectorSet   (planes[ 7].normal, 0,  1, 0);         planes[ 7].dist =  maxs[1];
@@ -1102,10 +1102,10 @@ qboolean R_Shadow_ScissorForBBox(const float *mins, const float *maxs)
        //Con_Printf("%f %f %f %f\n", x1, y1, x2, y2);
 
        // clamp it to the screen
-       if (ix1 < r_view_x) ix1 = r_view_x;
-       if (iy1 < r_view_y) iy1 = r_view_y;
-       if (ix2 > r_view_x + r_view_width) ix2 = r_view_x + r_view_width;
-       if (iy2 > r_view_y + r_view_height) iy2 = r_view_y + r_view_height;
+       if (ix1 < r_view.x) ix1 = r_view.x;
+       if (iy1 < r_view.y) iy1 = r_view.y;
+       if (ix2 > r_view.x + r_view.width) ix2 = r_view.x + r_view.width;
+       if (iy2 > r_view.y + r_view.height) iy2 = r_view.y + r_view.height;
 
        // if it is inside out, it's not visible
        if (ix2 <= ix1 || iy2 <= iy1)
@@ -1115,7 +1115,7 @@ qboolean R_Shadow_ScissorForBBox(const float *mins, const float *maxs)
        GL_Scissor(ix1, vid.height - iy2, ix2 - ix1, iy2 - iy1);
        //qglScissor(ix1, iy1, ix2 - ix1, iy2 - iy1);CHECKGLERROR
        //qglEnable(GL_SCISSOR_TEST);CHECKGLERROR
-       renderstats.lights_scissored++;
+       r_refdef.stats.lights_scissored++;
        return false;
 }
 
@@ -1138,7 +1138,7 @@ static void R_Shadow_RenderSurfacesLighting_Light_Vertex_Shading(const msurface_
                                color4f[0] = (ambientcolor[0] + shadeintensity * diffusecolor[0]);
                                color4f[1] = (ambientcolor[1] + shadeintensity * diffusecolor[1]);
                                color4f[2] = (ambientcolor[2] + shadeintensity * diffusecolor[2]);
-                               if (fogenabled)
+                               if (r_refdef.fogenabled)
                                {
                                        float f = VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg));
                                        VectorScale(color4f, f, color4f);
@@ -1171,7 +1171,7 @@ static void R_Shadow_RenderSurfacesLighting_Light_Vertex_Shading(const msurface_
                                        color4f[1] = ambientcolor[1] * distintensity;
                                        color4f[2] = ambientcolor[2] * distintensity;
                                }
-                               if (fogenabled)
+                               if (r_refdef.fogenabled)
                                {
                                        float f = VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg));
                                        VectorScale(color4f, f, color4f);
@@ -1205,7 +1205,7 @@ static void R_Shadow_RenderSurfacesLighting_Light_Vertex_Shading(const msurface_
                                        color4f[1] = ambientcolor[1] * distintensity;
                                        color4f[2] = ambientcolor[2] * distintensity;
                                }
-                               if (fogenabled)
+                               if (r_refdef.fogenabled)
                                {
                                        float f = VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg));
                                        VectorScale(color4f, f, color4f);
@@ -1308,7 +1308,7 @@ static void R_Shadow_RenderSurfacesLighting_Light_Dot3_Finalize(int numsurfaces,
 {
        // shared final code for all the dot3 layers
        int renders;
-       GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 0);
+       GL_ColorMask(r_view.colormask[0], r_view.colormask[1], r_view.colormask[2], 0);
        for (renders = 0;renders < 64 && (r > 0 || g > 0 || b > 0);renders++, r--, g--, b--)
        {
                GL_Color(bound(0, r, 1), bound(0, g, 1), bound(0, b, 1), 1);
@@ -2204,7 +2204,7 @@ void R_Shadow_DrawEntityShadow(entity_render_t *ent, int numsurfaces, int *surfa
                        CHECKGLERROR
                        for (mesh = r_shadow_rtlight->static_meshchain_shadow;mesh;mesh = mesh->next)
                        {
-                               renderstats.lights_shadowtriangles += mesh->numtriangles;
+                               r_refdef.stats.lights_shadowtriangles += mesh->numtriangles;
                                R_Mesh_VertexPointer(mesh->vertex3f);
                                GL_LockArrays(0, mesh->numverts);
                                if (r_shadow_rendermode == R_SHADOW_RENDERMODE_STENCIL)
@@ -2348,7 +2348,7 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible)
        if (numleafs)
        {
                for (i = 0;i < numleafs;i++)
-                       if (r_worldleafvisible[leaflist[i]])
+                       if (r_viewcache.world_leafvisible[leaflist[i]])
                                break;
                if (i == numleafs)
                        return;
@@ -2381,7 +2381,7 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible)
                                // about the VectorDistance2 - light emitting entities should not cast their own shadow
                                if ((ent->flags & RENDER_SHADOW) && model->DrawShadowVolume && VectorDistance2(ent->origin, rtlight->shadoworigin) > 0.1)
                                        shadowentities[numshadowentities++] = ent;
-                               if (ent->visframe == r_framecount && (ent->flags & RENDER_LIGHT) && model->DrawLight)
+                               if (r_viewcache.entityvisible[i] && (ent->flags & RENDER_LIGHT) && model->DrawLight)
                                        lightentities[numlightentities++] = ent;
                        }
                }
@@ -2398,10 +2398,10 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible)
        // make this the active rtlight for rendering purposes
        R_Shadow_RenderMode_ActiveLight(rtlight);
        // count this light in the r_speeds
-       renderstats.lights++;
+       r_refdef.stats.lights++;
 
        usestencil = false;
-       if (numshadowentities && rtlight->shadow && (rtlight->isstatic ? r_rtworldshadows : r_rtdlightshadows))
+       if (numshadowentities && rtlight->shadow && (rtlight->isstatic ? r_refdef.rtworldshadows : r_refdef.rtdlightshadows))
        {
                // draw stencil shadow volumes to mask off pixels that are in shadow
                // so that they won't receive lighting
@@ -2451,7 +2451,7 @@ void R_ShadowVolumeLighting(qboolean visible)
 
        R_Shadow_RenderMode_Begin();
 
-       flag = r_rtworld ? LIGHTFLAG_REALTIMEMODE : LIGHTFLAG_NORMALMODE;
+       flag = r_refdef.rtworld ? LIGHTFLAG_REALTIMEMODE : LIGHTFLAG_NORMALMODE;
        if (r_shadow_debuglight.integer >= 0)
        {
                for (lnum = 0, light = r_shadow_worldlightchain;light;lnum++, light = light->next)
@@ -2462,7 +2462,7 @@ void R_ShadowVolumeLighting(qboolean visible)
                for (lnum = 0, light = r_shadow_worldlightchain;light;lnum++, light = light->next)
                        if (light->flags & flag)
                                R_DrawRTLight(&light->rtlight, visible);
-       if (r_rtdlight)
+       if (r_refdef.rtdlight)
                for (lnum = 0;lnum < r_refdef.numlights;lnum++)
                        R_DrawRTLight(&r_refdef.lights[lnum]->rtlight, visible);
 
@@ -2661,7 +2661,7 @@ void R_Shadow_DrawCursor_TransparentCallback(const entity_render_t *ent, const r
 {
        // this is never batched (there can be only one)
        float scale = r_editlights_cursorgrid.value * 0.5f;
-       R_DrawSprite(GL_SRC_ALPHA, GL_ONE, r_crosshairs[1]->tex, NULL, false, r_editlights_cursorlocation, r_viewright, r_viewup, scale, -scale, -scale, scale, 1, 1, 1, 0.5f);
+       R_DrawSprite(GL_SRC_ALPHA, GL_ONE, r_crosshairs[1]->tex, NULL, false, r_editlights_cursorlocation, r_view.right, r_view.up, scale, -scale, -scale, scale, 1, 1, 1, 0.5f);
 }
 
 void R_Shadow_DrawLightSprite_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
@@ -2675,7 +2675,7 @@ void R_Shadow_DrawLightSprite_TransparentCallback(const entity_render_t *ent, co
                intensity = 0.75 + 0.25 * sin(realtime * M_PI * 4.0);
        if (!light->shadow)
                intensity *= 0.5f;
-       R_DrawSprite(GL_SRC_ALPHA, GL_ONE, r_crosshairs[surfacelist[0]]->tex, NULL, false, light->origin, r_viewright, r_viewup, 8, -8, -8, 8, intensity, intensity, intensity, 0.5);
+       R_DrawSprite(GL_SRC_ALPHA, GL_ONE, r_crosshairs[surfacelist[0]]->tex, NULL, false, light->origin, r_view.right, r_view.up, 8, -8, -8, 8, intensity, intensity, intensity, 0.5);
 }
 
 void R_Shadow_DrawLightSprites(void)
@@ -2696,12 +2696,12 @@ void R_Shadow_SelectLightInView(void)
        bestrating = 0;
        for (light = r_shadow_worldlightchain;light;light = light->next)
        {
-               VectorSubtract(light->origin, r_vieworigin, temp);
-               rating = (DotProduct(temp, r_viewforward) / sqrt(DotProduct(temp, temp)));
+               VectorSubtract(light->origin, r_view.origin, temp);
+               rating = (DotProduct(temp, r_view.forward) / sqrt(DotProduct(temp, temp)));
                if (rating >= 0.95)
                {
                        rating /= (1 + 0.0625f * sqrt(DotProduct(temp, temp)));
-                       if (bestrating < rating && CL_TraceBox(light->origin, vec3_origin, vec3_origin, r_vieworigin, true, NULL, SUPERCONTENTS_SOLID, false).fraction == 1.0f)
+                       if (bestrating < rating && CL_TraceBox(light->origin, vec3_origin, vec3_origin, r_view.origin, true, NULL, SUPERCONTENTS_SOLID, false).fraction == 1.0f)
                        {
                                bestrating = rating;
                                best = light;
@@ -3127,8 +3127,8 @@ void R_Shadow_SetCursorLocationForView(void)
        vec_t dist, push;
        vec3_t dest, endpos;
        trace_t trace;
-       VectorMA(r_vieworigin, r_editlights_cursordistance.value, r_viewforward, dest);
-       trace = CL_TraceBox(r_vieworigin, vec3_origin, vec3_origin, dest, true, NULL, SUPERCONTENTS_SOLID, false);
+       VectorMA(r_view.origin, r_editlights_cursordistance.value, r_view.forward, dest);
+       trace = CL_TraceBox(r_view.origin, vec3_origin, vec3_origin, dest, true, NULL, SUPERCONTENTS_SOLID, false);
        if (trace.fraction < 1)
        {
                dist = trace.fraction * r_editlights_cursordistance.value;
@@ -3136,7 +3136,7 @@ void R_Shadow_SetCursorLocationForView(void)
                if (push > dist)
                        push = dist;
                push = -push;
-               VectorMA(trace.endpos, push, r_viewforward, endpos);
+               VectorMA(trace.endpos, push, r_view.forward, endpos);
                VectorMA(endpos, r_editlights_cursorpushoff.value, trace.plane.normal, endpos);
        }
        else
diff --git a/r_sky.c b/r_sky.c
index a505372..487ebb5 100644 (file)
--- a/r_sky.c
+++ b/r_sky.c
@@ -56,7 +56,7 @@ void R_SkyStartFrame(void)
        skyrendersphere = false;
        skyrenderbox = false;
        skyrendermasked = false;
-       if (r_sky.integer && !fogenabled)
+       if (r_sky.integer && !r_refdef.fogenabled)
        {
                if (skyboxside[0] || skyboxside[1] || skyboxside[2] || skyboxside[3] || skyboxside[4] || skyboxside[5])
                        skyrenderbox = true;
@@ -406,7 +406,7 @@ void R_Sky(void)
        matrix4x4_t skymatrix;
        if (skyrendermasked)
        {
-               Matrix4x4_CreateTranslate(&skymatrix, r_vieworigin[0], r_vieworigin[1], r_vieworigin[2]);
+               Matrix4x4_CreateTranslate(&skymatrix, r_view.origin[0], r_view.origin[1], r_view.origin[2]);
                R_Mesh_Matrix(&skymatrix);
                if (skyrendersphere)
                {
index 02f7f2e..5530a59 100644 (file)
@@ -11,17 +11,17 @@ void R_Model_Sprite_Draw_TransparentCallback(const entity_render_t *ent, const r
        float scale;
 
        // nudge it toward the view to make sure it isn't in a wall
-       org[0] = ent->matrix.m[0][3] - r_viewforward[0];
-       org[1] = ent->matrix.m[1][3] - r_viewforward[1];
-       org[2] = ent->matrix.m[2][3] - r_viewforward[2];
+       org[0] = ent->matrix.m[0][3] - r_view.forward[0];
+       org[1] = ent->matrix.m[1][3] - r_view.forward[1];
+       org[2] = ent->matrix.m[2][3] - r_view.forward[2];
        switch(model->sprite.sprnum_type)
        {
        case SPR_VP_PARALLEL_UPRIGHT:
                // flames and such
                // vertical beam sprite, faces view plane
-               scale = ent->scale / sqrt(r_viewforward[0]*r_viewforward[0]+r_viewforward[1]*r_viewforward[1]);
-               left[0] = -r_viewforward[1] * scale;
-               left[1] = r_viewforward[0] * scale;
+               scale = ent->scale / sqrt(r_view.forward[0]*r_view.forward[0]+r_view.forward[1]*r_view.forward[1]);
+               left[0] = -r_view.forward[1] * scale;
+               left[1] = r_view.forward[0] * scale;
                left[2] = 0;
                up[0] = 0;
                up[1] = 0;
@@ -30,9 +30,9 @@ void R_Model_Sprite_Draw_TransparentCallback(const entity_render_t *ent, const r
        case SPR_FACING_UPRIGHT:
                // flames and such
                // vertical beam sprite, faces viewer's origin (not the view plane)
-               scale = ent->scale / sqrt((org[0] - r_vieworigin[0])*(org[0] - r_vieworigin[0])+(org[1] - r_vieworigin[1])*(org[1] - r_vieworigin[1]));
-               left[0] = (org[1] - r_vieworigin[1]) * scale;
-               left[1] = -(org[0] - r_vieworigin[0]) * scale;
+               scale = ent->scale / sqrt((org[0] - r_view.origin[0])*(org[0] - r_view.origin[0])+(org[1] - r_view.origin[1])*(org[1] - r_view.origin[1]));
+               left[0] = (org[1] - r_view.origin[1]) * scale;
+               left[1] = -(org[0] - r_view.origin[0]) * scale;
                left[2] = 0;
                up[0] = 0;
                up[1] = 0;
@@ -44,12 +44,12 @@ void R_Model_Sprite_Draw_TransparentCallback(const entity_render_t *ent, const r
        case SPR_VP_PARALLEL:
                // normal sprite
                // faces view plane
-               left[0] = r_viewleft[0] * ent->scale;
-               left[1] = r_viewleft[1] * ent->scale;
-               left[2] = r_viewleft[2] * ent->scale;
-               up[0] = r_viewup[0] * ent->scale;
-               up[1] = r_viewup[1] * ent->scale;
-               up[2] = r_viewup[2] * ent->scale;
+               left[0] = r_view.left[0] * ent->scale;
+               left[1] = r_view.left[1] * ent->scale;
+               left[2] = r_view.left[2] * ent->scale;
+               up[0] = r_view.up[0] * ent->scale;
+               up[1] = r_view.up[1] * ent->scale;
+               up[2] = r_view.up[2] * ent->scale;
                break;
        case SPR_ORIENTED:
                // bullet marks on walls
@@ -65,12 +65,12 @@ void R_Model_Sprite_Draw_TransparentCallback(const entity_render_t *ent, const r
                // I have no idea what people would use this for...
                // oriented relative to view space
                // FIXME: test this and make sure it mimicks software
-               left[0] = ent->matrix.m[0][1] * r_viewforward[0] + ent->matrix.m[1][1] * r_viewleft[0] + ent->matrix.m[2][1] * r_viewup[0];
-               left[1] = ent->matrix.m[0][1] * r_viewforward[1] + ent->matrix.m[1][1] * r_viewleft[1] + ent->matrix.m[2][1] * r_viewup[1];
-               left[2] = ent->matrix.m[0][1] * r_viewforward[2] + ent->matrix.m[1][1] * r_viewleft[2] + ent->matrix.m[2][1] * r_viewup[2];
-               up[0] = ent->matrix.m[0][2] * r_viewforward[0] + ent->matrix.m[1][2] * r_viewleft[0] + ent->matrix.m[2][2] * r_viewup[0];
-               up[1] = ent->matrix.m[0][2] * r_viewforward[1] + ent->matrix.m[1][2] * r_viewleft[1] + ent->matrix.m[2][2] * r_viewup[1];
-               up[2] = ent->matrix.m[0][2] * r_viewforward[2] + ent->matrix.m[1][2] * r_viewleft[2] + ent->matrix.m[2][2] * r_viewup[2];
+               left[0] = ent->matrix.m[0][1] * r_view.forward[0] + ent->matrix.m[1][1] * r_view.left[0] + ent->matrix.m[2][1] * r_view.up[0];
+               left[1] = ent->matrix.m[0][1] * r_view.forward[1] + ent->matrix.m[1][1] * r_view.left[1] + ent->matrix.m[2][1] * r_view.up[1];
+               left[2] = ent->matrix.m[0][1] * r_view.forward[2] + ent->matrix.m[1][1] * r_view.left[2] + ent->matrix.m[2][1] * r_view.up[2];
+               up[0] = ent->matrix.m[0][2] * r_view.forward[0] + ent->matrix.m[1][2] * r_view.left[0] + ent->matrix.m[2][2] * r_view.up[0];
+               up[1] = ent->matrix.m[0][2] * r_view.forward[1] + ent->matrix.m[1][2] * r_view.left[1] + ent->matrix.m[2][2] * r_view.up[1];
+               up[2] = ent->matrix.m[0][2] * r_view.forward[2] + ent->matrix.m[1][2] * r_view.left[2] + ent->matrix.m[2][2] * r_view.up[2];
                break;
        }
 
@@ -104,6 +104,6 @@ void R_Model_Sprite_Draw(entity_render_t *ent)
        if (ent->frameblend[0].frame < 0)
                return;
 
-       R_MeshQueue_AddTransparent(ent->effects & EF_NODEPTHTEST ? r_vieworigin : ent->origin, R_Model_Sprite_Draw_TransparentCallback, ent, 0, r_shadow_rtlight);
+       R_MeshQueue_AddTransparent(ent->effects & EF_NODEPTHTEST ? r_view.origin : ent->origin, R_Model_Sprite_Draw_TransparentCallback, ent, 0, r_shadow_rtlight);
 }
 
index 0a092a0..5f22191 100644 (file)
--- a/render.h
+++ b/render.h
@@ -21,26 +21,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #ifndef RENDER_H
 #define RENDER_H
 
-// flag arrays used for visibility checking on world model
-// (all other entities have no per-surface/per-leaf visibility checks)
-// TODO: dynamic resize according to r_refdef.worldmodel->brush.num_clusters
-extern unsigned char r_pvsbits[(32768+7)>>3];
-// TODO: dynamic resize according to r_refdef.worldmodel->brush.num_leafs
-extern unsigned char r_worldleafvisible[32768];
-// TODO: dynamic resize according to r_refdef.worldmodel->num_surfaces
-extern unsigned char r_worldsurfacevisible[262144];
-// if true, the view is currently in a leaf without pvs data
-extern qboolean r_worldnovis;
-
 // 1.0f / N table
 extern float ixtable[4096];
 
-// far clip distance for scene
-extern float r_farclip;
-
 // fog stuff
 extern void FOG_clear(void);
-extern float fog_density, fog_red, fog_green, fog_blue;
 
 // sky stuff
 extern cvar_t r_sky;
@@ -109,42 +94,6 @@ void R_Mesh_AddBrushMeshFromPlanes(rmesh_t *mesh, int numplanes, mplane_t *plane
 
 //=============================================================================
 
-extern int r_framecount;
-extern mplane_t frustum[5];
-
-typedef struct renderstats_s
-{
-       int entities;
-       int entities_surfaces;
-       int entities_triangles;
-       int world_leafs;
-       int world_portals;
-       int particles;
-       int meshes;
-       int meshes_elements;
-       int lights;
-       int lights_clears;
-       int lights_scissored;
-       int lights_lighttriangles;
-       int lights_shadowtriangles;
-       int lights_dynamicshadowtriangles;
-       int bloom;
-       int bloom_copypixels;
-       int bloom_drawpixels;
-}
-renderstats_t;
-
-extern renderstats_t renderstats;
-
-// brightness of world lightmaps and related lighting
-// (often reduced when world rtlights are enabled)
-extern float r_lightmapintensity;
-// whether to draw world lights realtime, dlights realtime, and their shadows
-extern qboolean r_rtworld;
-extern qboolean r_rtworldshadows;
-extern qboolean r_rtdlight;
-extern qboolean r_rtdlightshadows;
-
 extern cvar_t r_nearclip;
 
 // forces all rendering to draw triangle outlines
@@ -160,27 +109,6 @@ extern cvar_t r_showdisabledepthtest;
 //
 // view origin
 //
-extern vec3_t r_vieworigin;
-extern vec3_t r_viewforward;
-extern vec3_t r_viewleft;
-extern vec3_t r_viewright;
-extern vec3_t r_viewup;
-extern int r_view_x;
-extern int r_view_y;
-extern int r_view_z;
-extern int r_view_width;
-extern int r_view_height;
-extern int r_view_depth;
-extern matrix4x4_t r_view_matrix;
-extern float r_polygonfactor;
-extern float r_polygonoffset;
-extern float r_shadowpolygonfactor;
-extern float r_shadowpolygonoffset;
-
-extern mleaf_t         *r_viewleaf, *r_oldviewleaf;
-
-extern qboolean        envmap;
-
 extern cvar_t r_drawentities;
 extern cvar_t r_drawviewmodel;
 extern cvar_t r_speeds;
@@ -189,13 +117,13 @@ extern cvar_t r_wateralpha;
 extern cvar_t r_dynamic;
 
 void R_Init(void);
-void R_UpdateWorld(void); // needs no r_refdef
-void R_RenderView(void); // must call R_UpdateWorld and set r_refdef first
+void R_UpdateVariables(void); // must call after setting up most of r_refdef, but before calling R_RenderView
+void R_RenderView(void); // must set r_refdef and call R_UpdateVariables first
 
 
 void R_InitSky (unsigned char *src, int bytesperpixel); // called at level load
 
-void R_WorldVisibility();
+void R_View_WorldVisibility();
 void R_DrawParticles(void);
 void R_DrawExplosions(void);
 
@@ -204,17 +132,6 @@ void R_DrawExplosions(void);
 
 int R_CullBox(const vec3_t mins, const vec3_t maxs);
 
-#define FOGTABLEWIDTH 1024
-extern vec3_t fogcolor;
-extern vec_t fogdensity;
-extern vec_t fogrange;
-extern vec_t fograngerecip;
-extern int fogtableindex;
-extern vec_t fogtabledistmultiplier;
-extern float fogtable[FOGTABLEWIDTH];
-extern qboolean fogenabled;
-#define VERTEXFOGTABLE(dist) (fogtableindex = (int)((dist) * fogtabledistmultiplier), fogtable[bound(0, fogtableindex, FOGTABLEWIDTH - 1)])
-
 #include "r_modules.h"
 
 #include "meshqueue.h"
diff --git a/view.c b/view.c
index b00c344..dfcba08 100644 (file)
--- a/view.c
+++ b/view.c
@@ -327,7 +327,7 @@ void V_CalcRefdef (void)
                return;
        VectorClear(gunorg);
        viewmodelmatrix = identitymatrix;
-       r_refdef.viewentitymatrix = identitymatrix;
+       r_view.matrix = identitymatrix;
        if (cls.state == ca_connected && cls.signon == SIGNONS)
        {
                // ent is the view entity (visible when out of body)
@@ -355,13 +355,13 @@ void V_CalcRefdef (void)
                {
                        // entity is a fixed camera, just copy the matrix
                        if (cls.protocol == PROTOCOL_QUAKEWORLD)
-                               Matrix4x4_CreateFromQuakeEntity(&r_refdef.viewentitymatrix, cl.qw_intermission_origin[0], cl.qw_intermission_origin[1], cl.qw_intermission_origin[2], cl.qw_intermission_angles[0], cl.qw_intermission_angles[1], cl.qw_intermission_angles[2], 1);
+                               Matrix4x4_CreateFromQuakeEntity(&r_view.matrix, cl.qw_intermission_origin[0], cl.qw_intermission_origin[1], cl.qw_intermission_origin[2], cl.qw_intermission_angles[0], cl.qw_intermission_angles[1], cl.qw_intermission_angles[2], 1);
                        else
                        {
-                               r_refdef.viewentitymatrix = ent->render.matrix;
-                               r_refdef.viewentitymatrix.m[2][3] += cl.stats[STAT_VIEWHEIGHT];
+                               r_view.matrix = ent->render.matrix;
+                               r_view.matrix.m[2][3] += cl.stats[STAT_VIEWHEIGHT];
                        }
-                       viewmodelmatrix = r_refdef.viewentitymatrix;
+                       viewmodelmatrix = r_view.matrix;
                }
                else
                {
@@ -511,9 +511,9 @@ void V_CalcRefdef (void)
                        }
                        // calculate a view matrix for rendering the scene
                        if (v_idlescale.value)
-                               Matrix4x4_CreateFromQuakeEntity(&r_refdef.viewentitymatrix, vieworg[0], vieworg[1], vieworg[2], viewangles[0] + v_idlescale.value * sin(cl.time*v_ipitch_cycle.value) * v_ipitch_level.value, viewangles[1] + v_idlescale.value * sin(cl.time*v_iyaw_cycle.value) * v_iyaw_level.value, viewangles[2] + v_idlescale.value * sin(cl.time*v_iroll_cycle.value) * v_iroll_level.value, 1);
+                               Matrix4x4_CreateFromQuakeEntity(&r_view.matrix, vieworg[0], vieworg[1], vieworg[2], viewangles[0] + v_idlescale.value * sin(cl.time*v_ipitch_cycle.value) * v_ipitch_level.value, viewangles[1] + v_idlescale.value * sin(cl.time*v_iyaw_cycle.value) * v_iyaw_level.value, viewangles[2] + v_idlescale.value * sin(cl.time*v_iroll_cycle.value) * v_iroll_level.value, 1);
                        else
-                               Matrix4x4_CreateFromQuakeEntity(&r_refdef.viewentitymatrix, vieworg[0], vieworg[1], vieworg[2], viewangles[0], viewangles[1], viewangles[2] + v_idlescale.value * sin(cl.time*v_iroll_cycle.value) * v_iroll_level.value, 1);
+                               Matrix4x4_CreateFromQuakeEntity(&r_view.matrix, vieworg[0], vieworg[1], vieworg[2], viewangles[0], viewangles[1], viewangles[2] + v_idlescale.value * sin(cl.time*v_iroll_cycle.value) * v_iroll_level.value, 1);
                        // calculate a viewmodel matrix for use in view-attached entities
                        Matrix4x4_CreateFromQuakeEntity(&viewmodelmatrix, gunorg[0], gunorg[1], gunorg[2], viewangles[0], viewangles[1], viewangles[2], 0.3);
                        VectorCopy(vieworg, csqc_origin);
@@ -549,7 +549,7 @@ void V_CalcViewBlend(void)
                // set contents color
                int supercontents;
                vec3_t vieworigin;
-               Matrix4x4_OriginFromMatrix(&r_refdef.viewentitymatrix, vieworigin);
+               Matrix4x4_OriginFromMatrix(&r_view.matrix, vieworigin);
                supercontents = CL_PointSuperContents(vieworigin);
                if (supercontents & SUPERCONTENTS_LIQUIDSMASK)
                {