]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
- Instead of global refdef, view and viewcache variables they're now encapsulated...
authorres <res@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 4 Jan 2008 19:12:11 +0000 (19:12 +0000)
committerres <res@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 4 Jan 2008 19:12:11 +0000 (19:12 +0000)
- Each program type got a renderscene.
- Changed multiple methods to not use the global refdef etc. but take a renderscene instead.
- Made multiple CSQC builtin implementations non-static to allow access from MQC.

git-svn-id: svn://svn.icculus.org/twilight/branches/dp-mqc-render/darkplaces@7902 d7cf8633-e32d-0410-b094-e92efae38249

cl_main.c
cl_screen.c
client.h
clvm_cmds.c
clvm_cmds.h
csprogs.c
gl_rmain.c
menu.c
mvm_cmds.c
r_shadow.c
render.h

index 44c156eae7907aff9438cf3753bd0df1cb64bf59..0198841286500cfe62f2120fe1b0be5ffa2ed1dc 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -607,17 +607,17 @@ void CL_ClearTempEntities (void)
        cl.num_temp_entities = 0;
 }
 
-entity_t *CL_NewTempEntity(void)
+entity_t *CL_NewTempEntity(renderscene_t* scene)
 {
        entity_t *ent;
 
-       if (r_refdef.numentities >= r_refdef.maxentities)
+       if (scene->refdef.numentities >= r_refdef.maxentities)
                return NULL;
        if (cl.num_temp_entities >= cl.max_temp_entities)
                return NULL;
        ent = &cl.temp_entities[cl.num_temp_entities++];
        memset (ent, 0, sizeof(*ent));
-       r_refdef.entities[r_refdef.numentities++] = &ent->render;
+       scene->refdef.entities[scene->refdef.numentities++] = &ent->render;
 
        ent->render.alpha = 1;
        VectorSet(ent->render.colormod, 1, 1, 1);
@@ -845,7 +845,7 @@ void CL_AddQWCTFFlagModel(entity_t *player, int skin)
        }
        // end of code taken from QuakeWorld
 
-       flag = CL_NewTempEntity();
+       flag = CL_NewTempEntity(&client_scene);
        if (!flag)
                return;
 
@@ -1552,7 +1552,7 @@ static void CL_RelinkEffects(void)
 
                        // if we're drawing effects, get a new temp entity
                        // (NewTempEntity adds it to the render entities list for us)
-                       if (r_draweffects.integer && (ent = CL_NewTempEntity()))
+                       if (r_draweffects.integer && (ent = CL_NewTempEntity(&client_scene)))
                        {
                                // interpolation stuff
                                ent->render.frame1 = intframe;
@@ -1676,7 +1676,7 @@ void CL_RelinkBeams(void)
                d = VectorNormalizeLength(dist);
                while (d > 0)
                {
-                       ent = CL_NewTempEntity ();
+                       ent = CL_NewTempEntity (&client_scene);
                        if (!ent)
                                return;
                        //VectorCopy (org, ent->render.origin);
@@ -1708,7 +1708,7 @@ static void CL_RelinkQWNails(void)
 
                // if we're drawing effects, get a new temp entity
                // (NewTempEntity adds it to the render entities list for us)
-               if (!(ent = CL_NewTempEntity()))
+               if (!(ent = CL_NewTempEntity(&client_scene)))
                        continue;
 
                // normal stuff
@@ -2236,15 +2236,20 @@ void CL_Shutdown (void)
 CL_Init
 =================
 */
+void CL_InitScene (renderscene_t* scene, mempool_t* pool)
+{
+       memset(&scene->refdef, 0, sizeof(scene->refdef));
+       // max entities sent to renderer per frame
+       scene->refdef.maxentities = MAX_EDICTS + 256 + 512;
+       scene->refdef.entities = (entity_render_t **)Mem_Alloc(pool, sizeof(entity_render_t *) * scene->refdef.maxentities);
+}
+
 void CL_Init (void)
 {
        cls.levelmempool = Mem_AllocPool("client (per-level memory)", 0, NULL);
        cls.permanentmempool = Mem_AllocPool("client (long term memory)", 0, NULL);
 
-       memset(&r_refdef, 0, sizeof(r_refdef));
-       // max entities sent to renderer per frame
-       r_refdef.maxentities = MAX_EDICTS + 256 + 512;
-       r_refdef.entities = (entity_render_t **)Mem_Alloc(cls.permanentmempool, sizeof(entity_render_t *) * r_refdef.maxentities);
+        CL_InitScene (&client_scene, cls.permanentmempool);
 
        CL_InitInput ();
 
index 7eb8bf880c9eb27fb2f8edb07a01c2b8a192e5ff..94eaf837faab2208aed034fee3c90d73b678861d 100644 (file)
@@ -1710,7 +1710,7 @@ static void R_Envmap_f (void)
 
        r_refdef.envmap = true;
 
-       R_UpdateVariables();
+       R_UpdateVariables (&client_scene);
 
        r_view.x = 0;
        r_view.y = 0;
@@ -1733,7 +1733,7 @@ static void R_Envmap_f (void)
                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_view.clear = true;
                R_Mesh_Start();
-               R_RenderView();
+               R_RenderView(&client_scene);
                R_Mesh_Finish();
                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);
        }
@@ -1900,7 +1900,7 @@ void SCR_DrawScreen (void)
 
        R_TimeReport_BeginFrame();
 
-       R_UpdateVariables();
+       R_UpdateVariables (&client_scene);
 
        // Quake uses clockwise winding, so these are swapped
        r_view.cullface_front = GL_BACK;
@@ -1948,7 +1948,7 @@ void SCR_DrawScreen (void)
                r_view.frustum_y *= r_refdef.frustumscale_y;
 
                if(!CL_VM_UpdateView())
-                       R_RenderView();
+                       R_RenderView(&client_scene);
 
                if (scr_zoomwindow.integer)
                {
@@ -1969,7 +1969,7 @@ void SCR_DrawScreen (void)
                        r_view.frustum_y *= r_refdef.frustumscale_y;
 
                        if(!CL_VM_UpdateView())
-                               R_RenderView();
+                               R_RenderView(&client_scene);
                }
        }
 
index 0e3163d1f20310e954b8e8b63d2312f2aef083bb..1aa559891dbdfa11b587a5d4aaa6cacae6596597 100644 (file)
--- a/client.h
+++ b/client.h
@@ -1168,7 +1168,8 @@ void CL_Beam_CalculatePositions (const beam_t *b, vec3_t start, vec3_t end);
 void CL_ClientMovement_Replay(void);
 
 void CL_ClearTempEntities (void);
-entity_t *CL_NewTempEntity (void);
+struct renderscene_s;
+entity_t *CL_NewTempEntity (struct renderscene_s* scene);
 
 void CL_Effect(vec3_t org, int modelindex, int startframe, int framecount, float framerate);
 
@@ -1511,9 +1512,23 @@ typedef struct r_viewcache_s
 }
 r_viewcache_t;
 
-extern r_refdef_t r_refdef;
-extern r_view_t r_view;
-extern r_viewcache_t r_viewcache;
+typedef struct renderscene_s
+{
+  //
+  // screen size info
+  //
+  r_refdef_t refdef;
+  r_view_t view;
+  r_viewcache_t viewcache;
+} renderscene_t;
+
+void CL_InitScene (renderscene_t* scene, mempool_t* pool);
+
+extern renderscene_t client_scene;
+/* Convenience */
+#define r_refdef    (client_scene.refdef)
+#define r_view      (client_scene.view)
+#define r_viewcache (client_scene.viewcache)
 
 #endif
 
index e21d090d362d70d20a0ff7054a6fcd3c64bdd605..c39b82c3120e380ab4cf8aeb898292b4c707158a 100644 (file)
@@ -5,6 +5,10 @@
 #include "cl_collision.h"
 #include "r_shadow.h"
 
+/* Per-VM scenes */
+renderscene_t* renderscenes[PRVM_MAXPROGS];
+#define RENDERSCENE     (*renderscenes[prognum])
+
 //============================================================================
 // Client
 //[515]: unsolved PROBLEMS
@@ -39,7 +43,7 @@ static void VM_CL_makevectors (void)
 }
 
 // #2 void(entity e, vector o) setorigin
-static void VM_CL_setorigin (void)
+void VM_CL_setorigin (void)
 {
        prvm_edict_t    *e;
        float   *org;
@@ -62,7 +66,7 @@ static void VM_CL_setorigin (void)
 }
 
 // #3 void(entity e, string m) setmodel
-static void VM_CL_setmodel (void)
+void VM_CL_setmodel (void)
 {
        prvm_edict_t    *e;
        const char              *m;
@@ -339,7 +343,7 @@ static void VM_CL_tracetoss (void)
 
 
 // #20 void(string s) precache_model
-static void VM_CL_precache_model (void)
+void VM_CL_precache_model (void)
 {
        const char      *name;
        int                     i;
@@ -636,38 +640,41 @@ static void VM_CL_getlight (void)
 
 //============================================================================
 //[515]: SCENE MANAGER builtins
-extern qboolean CSQC_AddRenderEdict (prvm_edict_t *ed);//csprogs.c
+extern qboolean CSQC_AddRenderEdict (renderscene_t* scene, prvm_edict_t *ed);//csprogs.c
 
 static void CSQC_R_RecalcView (void)
 {
        extern matrix4x4_t viewmodelmatrix;
-       Matrix4x4_CreateFromQuakeEntity(&r_view.matrix, cl.csqc_origin[0], cl.csqc_origin[1], cl.csqc_origin[2], cl.csqc_angles[0], cl.csqc_angles[1], cl.csqc_angles[2], 1);
+       const int prognum = PRVM_GetProgNr();
+       Matrix4x4_CreateFromQuakeEntity(&RENDERSCENE.view.matrix, cl.csqc_origin[0], cl.csqc_origin[1], cl.csqc_origin[2], cl.csqc_angles[0], cl.csqc_angles[1], cl.csqc_angles[2], 1);
        Matrix4x4_CreateFromQuakeEntity(&viewmodelmatrix, cl.csqc_origin[0], cl.csqc_origin[1], cl.csqc_origin[2], cl.csqc_angles[0], cl.csqc_angles[1], cl.csqc_angles[2], cl_viewmodel_scale.value);
 }
 
 void CL_RelinkLightFlashes(void);
 //#300 void() clearscene (EXT_CSQC)
-static void VM_CL_R_ClearScene (void)
+void VM_CL_R_ClearScene (void)
 {
+       const int prognum = PRVM_GetProgNr();
+       
        VM_SAFEPARMCOUNT(0, VM_CL_R_ClearScene);
        // clear renderable entity and light lists
-       r_refdef.numentities = 0;
-       r_refdef.numlights = 0;
+       RENDERSCENE.refdef.numentities = 0;
+       RENDERSCENE.refdef.numlights = 0;
        // FIXME: restore these to the values from VM_CL_UpdateView
-       r_view.x = 0;
-       r_view.y = 0;
-       r_view.z = 0;
-       r_view.width = vid.width;
-       r_view.height = vid.height;
-       r_view.depth = 1;
+       RENDERSCENE.view.x = 0;
+       RENDERSCENE.view.y = 0;
+       RENDERSCENE.view.z = 0;
+       RENDERSCENE.view.width = vid.width;
+       RENDERSCENE.view.height = vid.height;
+       RENDERSCENE.view.depth = 1;
        // FIXME: restore frustum_x/frustum_y
-       r_view.useperspective = true;
-       r_view.frustum_y = tan(scr_fov.value * M_PI / 360.0) * (3.0/4.0) * cl.viewzoom;
-       r_view.frustum_x = r_view.frustum_y * (float)r_view.width / (float)r_view.height / vid_pixelheight.value;
-       r_view.frustum_x *= r_refdef.frustumscale_x;
-       r_view.frustum_y *= r_refdef.frustumscale_y;
-       r_view.ortho_x = scr_fov.value * (3.0 / 4.0) * (float)r_view.width / (float)r_view.height / vid_pixelheight.value;
-       r_view.ortho_y = scr_fov.value * (3.0 / 4.0);
+       RENDERSCENE.view.useperspective = true;
+       RENDERSCENE.view.frustum_y = tan(scr_fov.value * M_PI / 360.0) * (3.0/4.0) * cl.viewzoom;
+       RENDERSCENE.view.frustum_x = RENDERSCENE.view.frustum_y * (float)RENDERSCENE.view.width / (float)RENDERSCENE.view.height / vid_pixelheight.value;
+       RENDERSCENE.view.frustum_x *= RENDERSCENE.refdef.frustumscale_x;
+       RENDERSCENE.view.frustum_y *= RENDERSCENE.refdef.frustumscale_y;
+       RENDERSCENE.view.ortho_x = scr_fov.value * (3.0 / 4.0) * (float)RENDERSCENE.view.width / (float)RENDERSCENE.view.height / vid_pixelheight.value;
+       RENDERSCENE.view.ortho_y = scr_fov.value * (3.0 / 4.0);
        // FIXME: restore cl.csqc_origin
        // FIXME: restore cl.csqc_angles
        cl.csqc_vidvars.drawworld = true;
@@ -678,10 +685,12 @@ static void VM_CL_R_ClearScene (void)
 //#301 void(float mask) addentities (EXT_CSQC)
 extern void CSQC_Predraw (prvm_edict_t *ed);//csprogs.c
 extern void CSQC_Think (prvm_edict_t *ed);//csprogs.c
-static void VM_CL_R_AddEntities (void)
+void VM_CL_R_AddEntities (void)
 {
        int                     i, drawmask;
        prvm_edict_t *ed;
+       const int prognum = PRVM_GetProgNr();
+       
        VM_SAFEPARMCOUNT(1, VM_CL_R_AddEntities);
        drawmask = (int)PRVM_G_FLOAT(OFS_PARM0);
        CSQC_RelinkAllEntities(drawmask);
@@ -702,23 +711,26 @@ static void VM_CL_R_AddEntities (void)
                        continue;
                if(!((int)ed->fields.client->drawmask & drawmask))
                        continue;
-               CSQC_AddRenderEdict(ed);
+               CSQC_AddRenderEdict(&RENDERSCENE, ed);
        }
 }
 
 //#302 void(entity ent) addentity (EXT_CSQC)
-static void VM_CL_R_AddEntity (void)
+void VM_CL_R_AddEntity (void)
 {
+       const int prognum = PRVM_GetProgNr();
+       
        VM_SAFEPARMCOUNT(1, VM_CL_R_AddEntity);
-       CSQC_AddRenderEdict(PRVM_G_EDICT(OFS_PARM0));
+       CSQC_AddRenderEdict(&RENDERSCENE, PRVM_G_EDICT(OFS_PARM0));
 }
 
 //#303 float(float property, ...) setproperty (EXT_CSQC)
-static void VM_CL_R_SetView (void)
+void VM_CL_R_SetView (void)
 {
        int             c;
        float   *f;
        float   k;
+       const int prognum = PRVM_GetProgNr();
 
        VM_SAFEPARMCOUNTRANGE(2, 3, VM_CL_R_SetView);
 
@@ -729,41 +741,41 @@ static void VM_CL_R_SetView (void)
        switch(c)
        {
        case VF_MIN:
-               r_view.x = (int)(f[0] * vid.width / vid_conwidth.value);
-               r_view.y = (int)(f[1] * vid.height / vid_conheight.value);
+               RENDERSCENE.view.x = (int)(f[0] * vid.width / vid_conwidth.value);
+               RENDERSCENE.view.y = (int)(f[1] * vid.height / vid_conheight.value);
                break;
        case VF_MIN_X:
-               r_view.x = (int)(k * vid.width / vid_conwidth.value);
+               RENDERSCENE.view.x = (int)(k * vid.width / vid_conwidth.value);
                break;
        case VF_MIN_Y:
-               r_view.y = (int)(k * vid.height / vid_conheight.value);
+               RENDERSCENE.view.y = (int)(k * vid.height / vid_conheight.value);
                break;
        case VF_SIZE:
-               r_view.width = (int)(f[0] * vid.width / vid_conwidth.value);
-               r_view.height = (int)(f[1] * vid.height / vid_conheight.value);
+               RENDERSCENE.view.width = (int)(f[0] * vid.width / vid_conwidth.value);
+               RENDERSCENE.view.height = (int)(f[1] * vid.height / vid_conheight.value);
                break;
        case VF_SIZE_Y:
-               r_view.width = (int)(k * vid.width / vid_conwidth.value);
+               RENDERSCENE.view.width = (int)(k * vid.width / vid_conwidth.value);
                break;
        case VF_SIZE_X:
-               r_view.height = (int)(k * vid.height / vid_conheight.value);
+               RENDERSCENE.view.height = (int)(k * vid.height / vid_conheight.value);
                break;
        case VF_VIEWPORT:
-               r_view.x = (int)(f[0] * vid.width / vid_conwidth.value);
-               r_view.y = (int)(f[1] * vid.height / vid_conheight.value);
+               RENDERSCENE.view.x = (int)(f[0] * vid.width / vid_conwidth.value);
+               RENDERSCENE.view.y = (int)(f[1] * vid.height / vid_conheight.value);
                f = PRVM_G_VECTOR(OFS_PARM2);
-               r_view.width = (int)(f[0] * vid.width / vid_conwidth.value);
-               r_view.height = (int)(f[1] * vid.height / vid_conheight.value);
+               RENDERSCENE.view.width = (int)(f[0] * vid.width / vid_conwidth.value);
+               RENDERSCENE.view.height = (int)(f[1] * vid.height / vid_conheight.value);
                break;
        case VF_FOV:
-               r_view.frustum_x = tan(f[0] * M_PI / 360.0);r_view.ortho_x = f[0];
-               r_view.frustum_y = tan(f[1] * M_PI / 360.0);r_view.ortho_y = f[1];
+               RENDERSCENE.view.frustum_x = tan(f[0] * M_PI / 360.0);RENDERSCENE.view.ortho_x = f[0];
+               RENDERSCENE.view.frustum_y = tan(f[1] * M_PI / 360.0);RENDERSCENE.view.ortho_y = f[1];
                break;
        case VF_FOVX:
-               r_view.frustum_x = tan(k * M_PI / 360.0);r_view.ortho_x = k;
+               RENDERSCENE.view.frustum_x = tan(k * M_PI / 360.0);RENDERSCENE.view.ortho_x = k;
                break;
        case VF_FOVY:
-               r_view.frustum_y = tan(k * M_PI / 360.0);r_view.ortho_y = k;
+               RENDERSCENE.view.frustum_y = tan(k * M_PI / 360.0);RENDERSCENE.view.ortho_y = k;
                break;
        case VF_ORIGIN:
                VectorCopy(f, cl.csqc_origin);
@@ -819,7 +831,7 @@ static void VM_CL_R_SetView (void)
                cl.viewangles[2] = k;
                break;
        case VF_PERSPECTIVE:
-               r_view.useperspective = k != 0;
+               RENDERSCENE.view.useperspective = k != 0;
                break;
        default:
                PRVM_G_FLOAT(OFS_RETURN) = 0;
@@ -830,31 +842,35 @@ static void VM_CL_R_SetView (void)
 }
 
 //#304 void() renderscene (EXT_CSQC)
-static void VM_CL_R_RenderScene (void)
+void VM_CL_R_RenderScene (void)
 {
+       const int prognum = PRVM_GetProgNr();
+       
        VM_SAFEPARMCOUNT(0, VM_CL_R_RenderScene);
-       // we need to update any RENDER_VIEWMODEL entities at this point because
+       // we need to update any RENDERENDERSCENE.viewMODEL entities at this point because
        // csqc supplies its own view matrix
        CL_UpdateViewEntities();
        // now draw stuff!
-       R_RenderView();
+       R_RenderView(&RENDERSCENE);
 }
 
 //#305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
-static void VM_CL_R_AddDynamicLight (void)
+void VM_CL_R_AddDynamicLight (void)
 {
        float           *pos, *col;
        matrix4x4_t     matrix;
+       const int prognum = PRVM_GetProgNr();
+       
        VM_SAFEPARMCOUNTRANGE(3, 3, VM_CL_R_AddDynamicLight);
 
        // if we've run out of dlights, just return
-       if (r_refdef.numlights >= MAX_DLIGHTS)
+       if (RENDERSCENE.refdef.numlights >= MAX_DLIGHTS)
                return;
 
        pos = PRVM_G_VECTOR(OFS_PARM0);
        col = PRVM_G_VECTOR(OFS_PARM2);
        Matrix4x4_CreateFromQuakeEntity(&matrix, pos[0], pos[1], pos[2], 0, 0, 0, PRVM_G_FLOAT(OFS_PARM1));
-       R_RTLight_Update(&r_refdef.lights[r_refdef.numlights++], false, &matrix, col, -1, NULL, true, 1, 0.25, 0, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
+       R_RTLight_Update(&RENDERSCENE.refdef.lights[RENDERSCENE.refdef.numlights++], false, &matrix, col, -1, NULL, true, 1, 0.25, 0, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
 }
 
 //============================================================================
@@ -864,11 +880,12 @@ static void VM_CL_unproject (void)
 {
        float   *f;
        vec3_t  temp;
+       const int prognum = PRVM_GetProgNr();
 
        VM_SAFEPARMCOUNT(1, VM_CL_unproject);
        f = PRVM_G_VECTOR(OFS_PARM0);
-       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));
+       VectorSet(temp, f[2], f[0] * f[2] * -RENDERSCENE.view.frustum_x * 2.0 / RENDERSCENE.view.width, f[1] * f[2] * -RENDERSCENE.view.frustum_y * 2.0 / RENDERSCENE.view.height);
+       Matrix4x4_Transform(&RENDERSCENE.view.matrix, temp, PRVM_G_VECTOR(OFS_RETURN));
 }
 
 //#311 vector (vector v) cs_project (EXT_CSQC)
@@ -877,12 +894,13 @@ static void VM_CL_project (void)
        float   *f;
        vec3_t  v;
        matrix4x4_t m;
+       const int prognum = PRVM_GetProgNr();
 
        VM_SAFEPARMCOUNT(1, VM_CL_project);
        f = PRVM_G_VECTOR(OFS_PARM0);
-       Matrix4x4_Invert_Simple(&m, &r_view.matrix);
+       Matrix4x4_Invert_Simple(&m, &RENDERSCENE.view.matrix);
        Matrix4x4_Transform(&m, f, v);
-       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]);
+       VectorSet(PRVM_G_VECTOR(OFS_RETURN), v[1]/v[0]/-RENDERSCENE.view.frustum_x*0.5*RENDERSCENE.view.width, v[2]/v[0]/-RENDERSCENE.view.frustum_y*RENDERSCENE.view.height*0.5, v[0]);
 }
 
 //#330 float(float stnum) getstatf (EXT_CSQC)
@@ -2239,13 +2257,17 @@ typedef struct
        unsigned char                   flags;  //[515]: + VM_POLYGON_2D and VM_POLYGON_FL4V flags
 }vm_polygon_t;
 
-//static float                 vm_polygon_linewidth = 1;
-static mempool_t               *vm_polygons_pool = NULL;
-static unsigned char                   vm_current_vertices = 0;
-static qboolean                        vm_polygons_initialized = false;
-static vm_polygon_t            *vm_polygons = NULL;
-static unsigned long   vm_polygons_num = 0, vm_drawpolygons_num = 0;   //[515]: ok long on 64bit ?
-static qboolean                        vm_polygonbegin = false;        //[515]: for "no-crap-on-the-screen" check
+typedef struct vmpolygons_s
+{
+  //static float                       vm_polygon_linewidth = 1;
+  mempool_t            *pool;
+  unsigned char                current_vertices;
+  qboolean             initialized;
+  vm_polygon_t         *polygons;
+  unsigned long        polygons_num, drawpolygons_num; //[515]: ok long on 64bit ?
+  qboolean             polygonbegin;   //[515]: for "no-crap-on-the-screen" check
+} vmpolygons_t;
+vmpolygons_t vmpolygons[PRVM_MAXPROGS];
 #define VM_DEFPOLYNUM 64       //[515]: enough for default ?
 
 #define VM_POLYGON_FL3V                16      //more than 2 vertices (used only for lines)
@@ -2253,24 +2275,26 @@ static qboolean                 vm_polygonbegin = false;        //[515]: for "no-crap-on-the-screen"
 #define VM_POLYGON_FL2D                64
 #define VM_POLYGON_FL4V                128     //4 vertices
 
-static void VM_InitPolygons (void)
+static void VM_InitPolygons (vmpolygons_t* polys)
 {
-       vm_polygons_pool = Mem_AllocPool("VMPOLY", 0, NULL);
-       vm_polygons = (vm_polygon_t *)Mem_Alloc(vm_polygons_pool, VM_DEFPOLYNUM*sizeof(vm_polygon_t));
-       memset(vm_polygons, 0, VM_DEFPOLYNUM*sizeof(vm_polygon_t));
-       vm_polygons_num = VM_DEFPOLYNUM;
-       vm_drawpolygons_num = 0;
-       vm_polygonbegin = false;
-       vm_polygons_initialized = true;
+       polys->pool = Mem_AllocPool("VMPOLY", 0, NULL);
+       polys->polygons = (vm_polygon_t *)Mem_Alloc(polys->pool, VM_DEFPOLYNUM*sizeof(vm_polygon_t));
+       memset(polys->polygons, 0, VM_DEFPOLYNUM*sizeof(vm_polygon_t));
+       polys->polygons_num = VM_DEFPOLYNUM;
+       polys->drawpolygons_num = 0;
+       polys->polygonbegin = false;
+       polys->initialized = true;
 }
 
 static void VM_DrawPolygonCallback (const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
 {
        int surfacelistindex;
+        vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
+        
        // LordHavoc: FIXME: this is stupid code
        for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++)
        {
-               const vm_polygon_t      *p = &vm_polygons[surfacelist[surfacelistindex]];
+               const vm_polygon_t      *p = &polys->polygons[surfacelist[surfacelistindex]];
                int                                     flags = p->flags & 0x0f;
 
                if(flags == DRAWFLAG_ADDITIVE)
@@ -2345,7 +2369,6 @@ static void VM_CL_AddPolygonTo2DScene (vm_polygon_t *p)
 {
        drawqueuemesh_t mesh;
        static int              picelements[6] = {0, 1, 2, 0, 2, 3};
-
        mesh.texture = p->tex;
        mesh.data_element3i = picelements;
        mesh.data_vertex3f = p->data;
@@ -2370,47 +2393,51 @@ static void VM_CL_AddPolygonTo2DScene (vm_polygon_t *p)
 void VM_CL_AddPolygonsToMeshQueue (void)
 {
        int i;
-       if(!vm_drawpolygons_num)
+        vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
+        
+       if(!polys->drawpolygons_num)
                return;
        R_Mesh_Matrix(&identitymatrix);
        GL_CullFace(GL_NONE);
-       for(i = 0;i < (int)vm_drawpolygons_num;i++)
+       for(i = 0;i < (int)polys->drawpolygons_num;i++)
                VM_DrawPolygonCallback(NULL, NULL, 1, &i);
-       vm_drawpolygons_num = 0;
+       polys->drawpolygons_num = 0;
 }
 
 //void(string texturename, float flag[, float 2d[, float lines]]) R_BeginPolygon
-static void VM_CL_R_PolygonBegin (void)
+void VM_CL_R_PolygonBegin (void)
 {
        vm_polygon_t    *p;
        const char              *picname;
+        vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
+        
        VM_SAFEPARMCOUNTRANGE(2, 4, VM_CL_R_PolygonBegin);
 
-       if(!vm_polygons_initialized)
-               VM_InitPolygons();
-       if(vm_polygonbegin)
+       if(!polys->initialized)
+               VM_InitPolygons(polys);
+       if(polys->polygonbegin)
        {
                VM_Warning("VM_CL_R_PolygonBegin: called twice without VM_CL_R_PolygonEnd after first\n");
                return;
        }
-       if(vm_drawpolygons_num >= vm_polygons_num)
+       if(polys->drawpolygons_num >= polys->polygons_num)
        {
-               p = (vm_polygon_t *)Mem_Alloc(vm_polygons_pool, 2 * vm_polygons_num * sizeof(vm_polygon_t));
-               memset(p, 0, 2 * vm_polygons_num * sizeof(vm_polygon_t));
-               memcpy(p, vm_polygons, vm_polygons_num * sizeof(vm_polygon_t));
-               Mem_Free(vm_polygons);
-               vm_polygons = p;
-               vm_polygons_num *= 2;
+               p = (vm_polygon_t *)Mem_Alloc(polys->pool, 2 * polys->polygons_num * sizeof(vm_polygon_t));
+               memset(p, 0, 2 * polys->polygons_num * sizeof(vm_polygon_t));
+               memcpy(p, polys->polygons, polys->polygons_num * sizeof(vm_polygon_t));
+               Mem_Free(polys->polygons);
+               polys->polygons = p;
+               polys->polygons_num *= 2;
        }
-       p = &vm_polygons[vm_drawpolygons_num];
+       p = &polys->polygons[polys->drawpolygons_num];
        picname = PRVM_G_STRING(OFS_PARM0);
        if(picname[0])
                p->tex = Draw_CachePic(picname, true)->tex;
        else
                p->tex = r_texture_white;
        p->flags = (unsigned char)PRVM_G_FLOAT(OFS_PARM1);
-       vm_current_vertices = 0;
-       vm_polygonbegin = true;
+       polys->current_vertices = 0;
+       polys->polygonbegin = true;
        if(prog->argc >= 3)
        {
                if(PRVM_G_FLOAT(OFS_PARM2))
@@ -2424,13 +2451,15 @@ static void VM_CL_R_PolygonBegin (void)
 }
 
 //void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
-static void VM_CL_R_PolygonVertex (void)
+void VM_CL_R_PolygonVertex (void)
 {
        float                   *coords, *tx, *rgb, alpha;
        vm_polygon_t    *p;
+        vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
+        
        VM_SAFEPARMCOUNT(4, VM_CL_R_PolygonVertex);
 
-       if(!vm_polygonbegin)
+       if(!polys->polygonbegin)
        {
                VM_Warning("VM_CL_R_PolygonVertex: VM_CL_R_PolygonBegin wasn't called\n");
                return;
@@ -2440,86 +2469,90 @@ static void VM_CL_R_PolygonVertex (void)
        rgb             = PRVM_G_VECTOR(OFS_PARM2);
        alpha = PRVM_G_FLOAT(OFS_PARM3);
 
-       p = &vm_polygons[vm_drawpolygons_num];
-       if(vm_current_vertices > 4)
+       p = &polys->polygons[polys->drawpolygons_num];
+       if(polys->current_vertices > 4)
        {
                VM_Warning("VM_CL_R_PolygonVertex: may have 4 vertices max\n");
                return;
        }
 
-       p->data[vm_current_vertices*3]          = coords[0];
-       p->data[1+vm_current_vertices*3]        = coords[1];
-       p->data[2+vm_current_vertices*3]        = coords[2];
+       p->data[polys->current_vertices*3]      = coords[0];
+       p->data[1+polys->current_vertices*3]    = coords[1];
+       p->data[2+polys->current_vertices*3]    = coords[2];
 
-       p->data[12+vm_current_vertices*2]       = tx[0];
+       p->data[12+polys->current_vertices*2]   = tx[0];
        if(!(p->flags & VM_POLYGON_FLLINES))
-               p->data[13+vm_current_vertices*2]       = tx[1];
+               p->data[13+polys->current_vertices*2]   = tx[1];
 
-       p->data[20+vm_current_vertices*4]       = rgb[0];
-       p->data[21+vm_current_vertices*4]       = rgb[1];
-       p->data[22+vm_current_vertices*4]       = rgb[2];
-       p->data[23+vm_current_vertices*4]       = alpha;
+       p->data[20+polys->current_vertices*4]   = rgb[0];
+       p->data[21+polys->current_vertices*4]   = rgb[1];
+       p->data[22+polys->current_vertices*4]   = rgb[2];
+       p->data[23+polys->current_vertices*4]   = alpha;
 
-       vm_current_vertices++;
-       if(vm_current_vertices == 4)
+       polys->current_vertices++;
+       if(polys->current_vertices == 4)
                p->flags |= VM_POLYGON_FL4V;
        else
-               if(vm_current_vertices == 3)
+               if(polys->current_vertices == 3)
                        p->flags |= VM_POLYGON_FL3V;
 }
 
 //void() R_EndPolygon
-static void VM_CL_R_PolygonEnd (void)
+void VM_CL_R_PolygonEnd (void)
 {
+        vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
+        
        VM_SAFEPARMCOUNT(0, VM_CL_R_PolygonEnd);
-       if(!vm_polygonbegin)
+       if(!polys->polygonbegin)
        {
                VM_Warning("VM_CL_R_PolygonEnd: VM_CL_R_PolygonBegin wasn't called\n");
                return;
        }
-       vm_polygonbegin = false;
-       if(vm_current_vertices > 2 || (vm_current_vertices >= 2 && vm_polygons[vm_drawpolygons_num].flags & VM_POLYGON_FLLINES))
+       polys->polygonbegin = false;
+       if(polys->current_vertices > 2 || (polys->current_vertices >= 2 && polys->polygons[polys->drawpolygons_num].flags & VM_POLYGON_FLLINES))
        {
-               if(vm_polygons[vm_drawpolygons_num].flags & VM_POLYGON_FL2D)    //[515]: don't use qcpolygons memory if 2D
-                       VM_CL_AddPolygonTo2DScene(&vm_polygons[vm_drawpolygons_num]);
+               if(polys->polygons[polys->drawpolygons_num].flags & VM_POLYGON_FL2D)    //[515]: don't use qcpolygons memory if 2D
+                       VM_CL_AddPolygonTo2DScene(&polys->polygons[polys->drawpolygons_num]);
                else
-                       vm_drawpolygons_num++;
+                       polys->drawpolygons_num++;
        }
        else
-               VM_Warning("VM_CL_R_PolygonEnd: %i vertices isn't a good choice\n", vm_current_vertices);
+               VM_Warning("VM_CL_R_PolygonEnd: %i vertices isn't a good choice\n", polys->current_vertices);
 }
 
+static vmpolygons_t debugPolys;
+
 void Debug_PolygonBegin(const char *picname, int flags, qboolean draw2d, float linewidth)
 {
        vm_polygon_t    *p;
 
-       if(!vm_polygons_initialized)
-               VM_InitPolygons();
-       if(vm_polygonbegin)
+       if(!debugPolys.initialized)
+               VM_InitPolygons(&debugPolys);
+       if(debugPolys.polygonbegin)
        {
                Con_Printf("Debug_PolygonBegin: called twice without Debug_PolygonEnd after first\n");
                return;
        }
        // limit polygons to a vaguely sane amount, beyond this each one just
        // replaces the last one
-       vm_drawpolygons_num = min(vm_drawpolygons_num, (1<<20)-1);
-       if(vm_drawpolygons_num >= vm_polygons_num)
+       debugPolys.drawpolygons_num = min(debugPolys.drawpolygons_num, (1<<20)-1);
+       if(debugPolys.drawpolygons_num >= debugPolys.polygons_num)
        {
-               p = (vm_polygon_t *)Mem_Alloc(vm_polygons_pool, 2 * vm_polygons_num * sizeof(vm_polygon_t));
-               memset(p, 0, 2 * vm_polygons_num * sizeof(vm_polygon_t));
-               memcpy(p, vm_polygons, vm_polygons_num * sizeof(vm_polygon_t));
-               Mem_Free(vm_polygons);
-               vm_polygons = p;
-               vm_polygons_num *= 2;
+               p = (vm_polygon_t *)Mem_Alloc(debugPolys.pool, 2 * debugPolys.polygons_num * sizeof(vm_polygon_t));
+               memset(p, 0, 2 * debugPolys.polygons_num * sizeof(vm_polygon_t));
+               memcpy(p, debugPolys.polygons, debugPolys.polygons_num * sizeof(vm_polygon_t));
+               Mem_Free(debugPolys.polygons);
+               debugPolys.polygons = p;
+               debugPolys.polygons_num *= 2;
        }
-       p = &vm_polygons[vm_drawpolygons_num];
+       p = &debugPolys.polygons[debugPolys.drawpolygons_num];
        if(picname && picname[0])
                p->tex = Draw_CachePic(picname, true)->tex;
        else
                p->tex = r_texture_white;
        p->flags = flags;
-       vm_current_vertices = 0;
-       vm_polygonbegin = true;
+       debugPolys.current_vertices = 0;
+       debugPolys.polygonbegin = true;
        if(draw2d)
                p->flags |= VM_POLYGON_FL2D;
        if(linewidth)
@@ -2533,57 +2566,57 @@ void Debug_PolygonVertex(float x, float y, float z, float s, float t, float r, f
 {
        vm_polygon_t    *p;
 
-       if(!vm_polygonbegin)
+       if(!debugPolys.polygonbegin)
        {
                Con_Printf("Debug_PolygonVertex: Debug_PolygonBegin wasn't called\n");
                return;
        }
 
-       p = &vm_polygons[vm_drawpolygons_num];
-       if(vm_current_vertices > 4)
+       p = &debugPolys.polygons[debugPolys.drawpolygons_num];
+       if(debugPolys.current_vertices > 4)
        {
                Con_Printf("Debug_PolygonVertex: may have 4 vertices max\n");
                return;
        }
 
-       p->data[vm_current_vertices*3]          = x;
-       p->data[1+vm_current_vertices*3]        = y;
-       p->data[2+vm_current_vertices*3]        = z;
+       p->data[debugPolys.current_vertices*3]          = x;
+       p->data[1+debugPolys.current_vertices*3]        = y;
+       p->data[2+debugPolys.current_vertices*3]        = z;
 
-       p->data[12+vm_current_vertices*2]       = s;
+       p->data[12+debugPolys.current_vertices*2]       = s;
        if(!(p->flags & VM_POLYGON_FLLINES))
-               p->data[13+vm_current_vertices*2]       = t;
+               p->data[13+debugPolys.current_vertices*2]       = t;
 
-       p->data[20+vm_current_vertices*4]       = r;
-       p->data[21+vm_current_vertices*4]       = g;
-       p->data[22+vm_current_vertices*4]       = b;
-       p->data[23+vm_current_vertices*4]       = a;
+       p->data[20+debugPolys.current_vertices*4]       = r;
+       p->data[21+debugPolys.current_vertices*4]       = g;
+       p->data[22+debugPolys.current_vertices*4]       = b;
+       p->data[23+debugPolys.current_vertices*4]       = a;
 
-       vm_current_vertices++;
-       if(vm_current_vertices == 4)
+       debugPolys.current_vertices++;
+       if(debugPolys.current_vertices == 4)
                p->flags |= VM_POLYGON_FL4V;
        else
-               if(vm_current_vertices == 3)
+               if(debugPolys.current_vertices == 3)
                        p->flags |= VM_POLYGON_FL3V;
 }
 
 void Debug_PolygonEnd(void)
 {
-       if(!vm_polygonbegin)
+       if(!debugPolys.polygonbegin)
        {
                Con_Printf("Debug_PolygonEnd: Debug_PolygonBegin wasn't called\n");
                return;
        }
-       vm_polygonbegin = false;
-       if(vm_current_vertices > 2 || (vm_current_vertices >= 2 && vm_polygons[vm_drawpolygons_num].flags & VM_POLYGON_FLLINES))
+       debugPolys.polygonbegin = false;
+       if(debugPolys.current_vertices > 2 || (debugPolys.current_vertices >= 2 && debugPolys.polygons[debugPolys.drawpolygons_num].flags & VM_POLYGON_FLLINES))
        {
-               if(vm_polygons[vm_drawpolygons_num].flags & VM_POLYGON_FL2D)    //[515]: don't use qcpolygons memory if 2D
-                       VM_CL_AddPolygonTo2DScene(&vm_polygons[vm_drawpolygons_num]);
+               if(debugPolys.polygons[debugPolys.drawpolygons_num].flags & VM_POLYGON_FL2D)    //[515]: don't use qcpolygons memory if 2D
+                       VM_CL_AddPolygonTo2DScene(&debugPolys.polygons[debugPolys.drawpolygons_num]);
                else
-                       vm_drawpolygons_num++;
+                       debugPolys.drawpolygons_num++;
        }
        else
-               Con_Printf("Debug_PolygonEnd: %i vertices isn't a good choice\n", vm_current_vertices);
+               Con_Printf("Debug_PolygonEnd: %i vertices isn't a good choice\n", debugPolys.current_vertices);
 }
 
 /*
@@ -3163,7 +3196,7 @@ VM_CL_R_AddDynamicLight,          // #305 void(vector org, float radius, vector lightcol
 VM_CL_R_PolygonBegin,                  // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
 VM_CL_R_PolygonVertex,                 // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
 VM_CL_R_PolygonEnd,                            // #308 void() R_EndPolygon
-NULL,                                                  // #309
+NULL /* R_LoadWorldModel in menu VM, should stay unassigned in client*/, // #309
 VM_CL_unproject,                               // #310 vector (vector v) cs_unproject (EXT_CSQC)
 VM_CL_project,                                 // #311 vector (vector v) cs_project (EXT_CSQC)
 NULL,                                                  // #312
@@ -3367,24 +3400,28 @@ NULL,                                                   // #499
 
 const int vm_cl_numbuiltins = sizeof(vm_cl_builtins) / sizeof(prvm_builtin_t);
 
-void VM_CL_Cmd_Init(void)
+void VM_Polygons_Reset(void)
 {
-       VM_Cmd_Init();
+        vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
+        
        // TODO: replace vm_polygons stuff with a more general debugging polygon system, and make vm_polygons functions use that system
-       if(vm_polygons_initialized)
+       if(polys->initialized)
        {
-               Mem_FreePool(&vm_polygons_pool);
-               vm_polygons_initialized = false;
+               Mem_FreePool(&polys->pool);
+               polys->initialized = false;
        }
 }
 
+void VM_CL_Cmd_Init(void)
+{
+       VM_Cmd_Init();
+       VM_Polygons_Reset();
+       renderscenes[PRVM_CLIENTPROG] = &client_scene;
+}
+
 void VM_CL_Cmd_Reset(void)
 {
        VM_Cmd_Reset();
-       if(vm_polygons_initialized)
-       {
-               Mem_FreePool(&vm_polygons_pool);
-               vm_polygons_initialized = false;
-       }
+       VM_Polygons_Reset();
 }
 
index 58928c2f938865e3bb742995d8f721797a26de83..2e5ca5cb5b84e2714c9d247bea8609692426e405 100644 (file)
@@ -3,4 +3,28 @@
 
 int CL_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex);
 
+/* These are VM built-ins that originate in the client-side programs support
+   but are reused by the other programs (usually the menu). */
+
+void VM_CL_setmodel (void);
+void VM_CL_precache_model (void);
+void VM_CL_setorigin (void);
+
+/* Per-VM scenes */
+extern renderscene_t* renderscenes[PRVM_MAXPROGS];
+
+void VM_CL_R_AddDynamicLight (void);
+void VM_CL_R_ClearScene (void);
+void VM_CL_R_AddEntities (void);
+void VM_CL_R_AddEntity (void);
+void VM_CL_R_SetView (void);
+void VM_CL_R_RenderScene (void);
+void VM_CL_R_LoadWorldModel (void);
+
+void VM_CL_R_PolygonBegin (void);
+void VM_CL_R_PolygonVertex (void);
+void VM_CL_R_PolygonEnd (void);
+/* VMs exposing the polygon calls must call this on Init/Reset */
+void VM_Polygons_Reset();
+
 #endif /* __CLVM_CMDS_H__ */
index ada3b073b486425d18942ca5abd926bcff4f86df..9809b5ead421b92824422daa824e8b2e462cf65e 100644 (file)
--- a/csprogs.c
+++ b/csprogs.c
@@ -123,7 +123,7 @@ void CSQC_Think (prvm_edict_t *ed)
 }
 
 extern cvar_t cl_noplayershadow;
-qboolean CSQC_AddRenderEdict(prvm_edict_t *ed)
+qboolean CSQC_AddRenderEdict(renderscene_t* scene, prvm_edict_t *ed)
 {
        int renderflags;
        int c;
@@ -137,7 +137,7 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed)
        if (!model)
                return false;
 
-       e = CL_NewTempEntity();
+       e = CL_NewTempEntity(scene);
        if (!e)
                return false;
 
index 3e4ec0565e8d31d0af237298fb629a20a6549cf2..6c41e1173bb7a1985ae63535338020938660b2d7 100644 (file)
@@ -28,12 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 mempool_t *r_main_mempool;
 rtexturepool_t *r_main_texturepool;
 
-//
-// screen size info
-//
-r_refdef_t r_refdef;
-r_view_t r_view;
-r_viewcache_t r_viewcache;
+renderscene_t client_scene;
 
 cvar_t r_depthfirst = {CVAR_SAVE, "r_depthfirst", "1", "renders a depth-only version of the scene before normal rendering begins to eliminate overdraw, values: 0 = off, 1 = world depth, 2 = world and model depth"};
 cvar_t r_nearclip = {0, "r_nearclip", "1", "distance from camera of nearclip plane" };
@@ -208,7 +203,7 @@ const static float r_screenvertex3f[12] =
        0, 1, 0
 };
 
-extern void R_DrawModelShadows(void);
+extern void R_DrawModelShadows(renderscene_t* scene);
 
 void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
 {
@@ -2196,7 +2191,7 @@ int R_CullBoxCustomPlanes(const vec3_t mins, const vec3_t maxs, int numplanes, c
 
 //==================================================================================
 
-static void R_View_UpdateEntityVisible (void)
+static void R_View_UpdateEntityVisible (renderscene_t* scene)
 {
        int i, renderimask;
        entity_render_t *ent;
@@ -2204,27 +2199,27 @@ static void R_View_UpdateEntityVisible (void)
        if (!r_drawentities.integer)
                return;
 
-       renderimask = r_refdef.envmap ? (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL) : ((chase_active.integer || r_waterstate.renderingscene) ? RENDER_VIEWMODEL : RENDER_EXTERIORMODEL);
-       if (r_refdef.worldmodel && r_refdef.worldmodel->brush.BoxTouchingVisibleLeafs)
+       renderimask = scene->refdef.envmap ? (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL) : ((chase_active.integer || r_waterstate.renderingscene) ? RENDER_VIEWMODEL : RENDER_EXTERIORMODEL);
+       if (scene->refdef.worldmodel && scene->refdef.worldmodel->brush.BoxTouchingVisibleLeafs)
        {
                // worldmodel can check visibility
-               for (i = 0;i < r_refdef.numentities;i++)
+               for (i = 0;i < scene->refdef.numentities;i++)
                {
-                       ent = r_refdef.entities[i];
-                       r_viewcache.entityvisible[i] = !(ent->flags & renderimask) && ((ent->model && ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)) || !R_CullBox(ent->mins, ent->maxs)) && ((ent->effects & EF_NODEPTHTEST) || (ent->flags & RENDER_VIEWMODEL) || r_refdef.worldmodel->brush.BoxTouchingVisibleLeafs(r_refdef.worldmodel, r_viewcache.world_leafvisible, ent->mins, ent->maxs));
+                       ent = scene->refdef.entities[i];
+                       scene->viewcache.entityvisible[i] = !(ent->flags & renderimask) && ((ent->model && ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)) || !R_CullBox(ent->mins, ent->maxs)) && ((ent->effects & EF_NODEPTHTEST) || (ent->flags & RENDER_VIEWMODEL) || scene->refdef.worldmodel->brush.BoxTouchingVisibleLeafs(scene->refdef.worldmodel, scene->viewcache.world_leafvisible, ent->mins, ent->maxs));
 
                }
                if(r_cullentities_trace.integer && r_refdef.worldmodel->brush.TraceLineOfSight)
                {
-                       for (i = 0;i < r_refdef.numentities;i++)
+                       for (i = 0;i < scene->refdef.numentities;i++)
                        {
-                               ent = r_refdef.entities[i];
-                               if(r_viewcache.entityvisible[i] && !(ent->effects & EF_NODEPTHTEST) && !(ent->flags & RENDER_VIEWMODEL) && !(ent->model && (ent->model->name[0] == '*')))
+                               ent = scene->refdef.entities[i];
+                               if(scene->viewcache.entityvisible[i] && !(ent->effects & EF_NODEPTHTEST) && !(ent->flags & RENDER_VIEWMODEL) && !(ent->model && (ent->model->name[0] == '*')))
                                {
-                                       if(Mod_CanSeeBox_Trace(r_cullentities_trace_samples.integer, r_cullentities_trace_enlarge.value, r_refdef.worldmodel, r_view.origin, ent->mins, ent->maxs))
+                                       if(Mod_CanSeeBox_Trace(r_cullentities_trace_samples.integer, r_cullentities_trace_enlarge.value, scene->refdef.worldmodel, scene->view.origin, ent->mins, ent->maxs))
                                                ent->last_trace_visibility = realtime;
                                        if(ent->last_trace_visibility < realtime - r_cullentities_trace_delay.value)
-                                               r_viewcache.entityvisible[i] = 0;
+                                               scene->viewcache.entityvisible[i] = 0;
                                }
                        }
                }
@@ -2232,10 +2227,10 @@ static void R_View_UpdateEntityVisible (void)
        else
        {
                // no worldmodel or it can't check visibility
-               for (i = 0;i < r_refdef.numentities;i++)
+               for (i = 0;i < scene->refdef.numentities;i++)
                {
-                       ent = r_refdef.entities[i];
-                       r_viewcache.entityvisible[i] = !(ent->flags & renderimask) && ((ent->model && ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)) || !R_CullBox(ent->mins, ent->maxs));
+                       ent = scene->refdef.entities[i];
+                       scene->viewcache.entityvisible[i] = !(ent->flags & renderimask) && ((ent->model && ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)) || !R_CullBox(ent->mins, ent->maxs));
                }
        }
 }
@@ -2264,7 +2259,7 @@ int R_DrawBrushModelsSky (void)
 }
 
 static void R_DrawNoModel(entity_render_t *ent);
-static void R_DrawModels(void)
+static void R_DrawModels(renderscene_t* scene)
 {
        int i;
        entity_render_t *ent;
@@ -2272,12 +2267,12 @@ static void R_DrawModels(void)
        if (!r_drawentities.integer)
                return;
 
-       for (i = 0;i < r_refdef.numentities;i++)
+       for (i = 0;i < scene->refdef.numentities;i++)
        {
-               if (!r_viewcache.entityvisible[i])
+               if (!scene->viewcache.entityvisible[i])
                        continue;
-               ent = r_refdef.entities[i];
-               r_refdef.stats.entities++;
+               ent = scene->refdef.entities[i];
+               scene->refdef.stats.entities++;
                if (ent->model && ent->model->Draw != NULL)
                        ent->model->Draw(ent);
                else
@@ -2285,7 +2280,7 @@ static void R_DrawModels(void)
        }
 }
 
-static void R_DrawModelsDepth(void)
+static void R_DrawModelsDepth(renderscene_t* scene)
 {
        int i;
        entity_render_t *ent;
@@ -2293,17 +2288,17 @@ static void R_DrawModelsDepth(void)
        if (!r_drawentities.integer)
                return;
 
-       for (i = 0;i < r_refdef.numentities;i++)
+       for (i = 0;i < scene->refdef.numentities;i++)
        {
-               if (!r_viewcache.entityvisible[i])
+               if (!scene->viewcache.entityvisible[i])
                        continue;
-               ent = r_refdef.entities[i];
+               ent = scene->refdef.entities[i];
                if (ent->model && ent->model->DrawDepth != NULL)
                        ent->model->DrawDepth(ent);
        }
 }
 
-static void R_DrawModelsDebug(void)
+static void R_DrawModelsDebug(renderscene_t* scene)
 {
        int i;
        entity_render_t *ent;
@@ -2311,17 +2306,17 @@ static void R_DrawModelsDebug(void)
        if (!r_drawentities.integer)
                return;
 
-       for (i = 0;i < r_refdef.numentities;i++)
+       for (i = 0;i < scene->refdef.numentities;i++)
        {
-               if (!r_viewcache.entityvisible[i])
+               if (!scene->viewcache.entityvisible[i])
                        continue;
-               ent = r_refdef.entities[i];
+               ent = scene->refdef.entities[i];
                if (ent->model && ent->model->DrawDebug != NULL)
                        ent->model->DrawDebug(ent);
        }
 }
 
-static void R_DrawModelsAddWaterPlanes(void)
+static void R_DrawModelsAddWaterPlanes(renderscene_t* scene)
 {
        int i;
        entity_render_t *ent;
@@ -2329,24 +2324,24 @@ static void R_DrawModelsAddWaterPlanes(void)
        if (!r_drawentities.integer)
                return;
 
-       for (i = 0;i < r_refdef.numentities;i++)
+       for (i = 0;i < scene->refdef.numentities;i++)
        {
-               if (!r_viewcache.entityvisible[i])
+               if (!scene->viewcache.entityvisible[i])
                        continue;
-               ent = r_refdef.entities[i];
+               ent = scene->refdef.entities[i];
                if (ent->model && ent->model->DrawAddWaterPlanes != NULL)
                        ent->model->DrawAddWaterPlanes(ent);
        }
 }
 
-static void R_View_SetFrustum(void)
+static void R_View_SetFrustum(renderscene_t* scene)
 {
        int i;
        double slopex, slopey;
 
        // break apart the view matrix into vectors for various purposes
-       Matrix4x4_ToVectors(&r_view.matrix, r_view.forward, r_view.left, r_view.up, r_view.origin);
-       VectorNegate(r_view.left, r_view.right);
+       Matrix4x4_ToVectors(&scene->view.matrix, scene->view.forward, scene->view.left, scene->view.up, scene->view.origin);
+       VectorNegate(scene->view.left, scene->view.right);
 
 #if 0
        r_view.frustum[0].normal[0] = 0 - 1.0 / r_view.frustum_x;
@@ -2410,59 +2405,59 @@ static void R_View_SetFrustum(void)
        r_view.frustum[5].dist = m[15] + m[14];
 #endif
 
-       if (r_view.useperspective)
+       if (scene->view.useperspective)
        {
-               slopex = 1.0 / r_view.frustum_x;
-               slopey = 1.0 / r_view.frustum_y;
-               VectorMA(r_view.forward, -slopex, r_view.left, r_view.frustum[0].normal);
-               VectorMA(r_view.forward,  slopex, r_view.left, r_view.frustum[1].normal);
-               VectorMA(r_view.forward, -slopey, r_view.up  , r_view.frustum[2].normal);
-               VectorMA(r_view.forward,  slopey, r_view.up  , r_view.frustum[3].normal);
-               VectorCopy(r_view.forward, r_view.frustum[4].normal);
+               slopex = 1.0 / scene->view.frustum_x;
+               slopey = 1.0 / scene->view.frustum_y;
+               VectorMA(scene->view.forward, -slopex, scene->view.left, scene->view.frustum[0].normal);
+               VectorMA(scene->view.forward,  slopex, scene->view.left, scene->view.frustum[1].normal);
+               VectorMA(scene->view.forward, -slopey, scene->view.up  , scene->view.frustum[2].normal);
+               VectorMA(scene->view.forward,  slopey, scene->view.up  , scene->view.frustum[3].normal);
+               VectorCopy(scene->view.forward, scene->view.frustum[4].normal);
 
                // Leaving those out was a mistake, those were in the old code, and they
                // fix a reproducable bug in this one: frustum culling got fucked up when viewmatrix was an identity matrix
                // I couldn't reproduce it after adding those normalizations. --blub
-               VectorNormalize(r_view.frustum[0].normal);
-               VectorNormalize(r_view.frustum[1].normal);
-               VectorNormalize(r_view.frustum[2].normal);
-               VectorNormalize(r_view.frustum[3].normal);
+               VectorNormalize(scene->view.frustum[0].normal);
+               VectorNormalize(scene->view.frustum[1].normal);
+               VectorNormalize(scene->view.frustum[2].normal);
+               VectorNormalize(scene->view.frustum[3].normal);
 
                // calculate frustum corners, which are used to calculate deformed frustum planes for shadow caster culling
-               VectorMAMAMAM(1, r_view.origin, 1024, r_view.forward, -1024 * slopex, r_view.left, -1024 * slopey, r_view.up, r_view.frustumcorner[0]);
-               VectorMAMAMAM(1, r_view.origin, 1024, r_view.forward,  1024 * slopex, r_view.left, -1024 * slopey, r_view.up, r_view.frustumcorner[1]);
-               VectorMAMAMAM(1, r_view.origin, 1024, r_view.forward, -1024 * slopex, r_view.left,  1024 * slopey, r_view.up, r_view.frustumcorner[2]);
-               VectorMAMAMAM(1, r_view.origin, 1024, r_view.forward,  1024 * slopex, r_view.left,  1024 * slopey, r_view.up, r_view.frustumcorner[3]);
+               VectorMAMAMAM(1, scene->view.origin, 1024, scene->view.forward, -1024 * slopex, scene->view.left, -1024 * slopey, scene->view.up, scene->view.frustumcorner[0]);
+               VectorMAMAMAM(1, scene->view.origin, 1024, scene->view.forward,  1024 * slopex, scene->view.left, -1024 * slopey, scene->view.up, scene->view.frustumcorner[1]);
+               VectorMAMAMAM(1, scene->view.origin, 1024, scene->view.forward, -1024 * slopex, scene->view.left,  1024 * slopey, scene->view.up, scene->view.frustumcorner[2]);
+               VectorMAMAMAM(1, scene->view.origin, 1024, scene->view.forward,  1024 * slopex, scene->view.left,  1024 * slopey, scene->view.up, scene->view.frustumcorner[3]);
 
-               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;
+               scene->view.frustum[0].dist = DotProduct (scene->view.origin, scene->view.frustum[0].normal);
+               scene->view.frustum[1].dist = DotProduct (scene->view.origin, scene->view.frustum[1].normal);
+               scene->view.frustum[2].dist = DotProduct (scene->view.origin, scene->view.frustum[2].normal);
+               scene->view.frustum[3].dist = DotProduct (scene->view.origin, scene->view.frustum[3].normal);
+               scene->view.frustum[4].dist = DotProduct (scene->view.origin, scene->view.frustum[4].normal) + scene->refdef.nearclip;
        }
        else
        {
-               VectorScale(r_view.left, -r_view.ortho_x, r_view.frustum[0].normal);
-               VectorScale(r_view.left,  r_view.ortho_x, r_view.frustum[1].normal);
-               VectorScale(r_view.up, -r_view.ortho_y, r_view.frustum[2].normal);
-               VectorScale(r_view.up,  r_view.ortho_y, r_view.frustum[3].normal);
-               VectorCopy(r_view.forward, r_view.frustum[4].normal);
-               r_view.frustum[0].dist = DotProduct (r_view.origin, r_view.frustum[0].normal) + r_view.ortho_x;
-               r_view.frustum[1].dist = DotProduct (r_view.origin, r_view.frustum[1].normal) + r_view.ortho_x;
-               r_view.frustum[2].dist = DotProduct (r_view.origin, r_view.frustum[2].normal) + r_view.ortho_y;
-               r_view.frustum[3].dist = DotProduct (r_view.origin, r_view.frustum[3].normal) + r_view.ortho_y;
-               r_view.frustum[4].dist = DotProduct (r_view.origin, r_view.frustum[4].normal) + r_refdef.nearclip;
+               VectorScale(scene->view.left, -scene->view.ortho_x, scene->view.frustum[0].normal);
+               VectorScale(scene->view.left,  scene->view.ortho_x, scene->view.frustum[1].normal);
+               VectorScale(scene->view.up, -scene->view.ortho_y, scene->view.frustum[2].normal);
+               VectorScale(scene->view.up,  scene->view.ortho_y, scene->view.frustum[3].normal);
+               VectorCopy(scene->view.forward, scene->view.frustum[4].normal);
+               scene->view.frustum[0].dist = DotProduct (scene->view.origin, scene->view.frustum[0].normal) + scene->view.ortho_x;
+               scene->view.frustum[1].dist = DotProduct (scene->view.origin, scene->view.frustum[1].normal) + scene->view.ortho_x;
+               scene->view.frustum[2].dist = DotProduct (scene->view.origin, scene->view.frustum[2].normal) + scene->view.ortho_y;
+               scene->view.frustum[3].dist = DotProduct (scene->view.origin, scene->view.frustum[3].normal) + scene->view.ortho_y;
+               scene->view.frustum[4].dist = DotProduct (scene->view.origin, scene->view.frustum[4].normal) + r_refdef.nearclip;
        }
-       r_view.numfrustumplanes = 5;
+       scene->view.numfrustumplanes = 5;
 
-       if (r_view.useclipplane)
+       if (scene->view.useclipplane)
        {
-               r_view.numfrustumplanes = 6;
-               r_view.frustum[5] = r_view.clipplane;
+               scene->view.numfrustumplanes = 6;
+               scene->view.frustum[5] = scene->view.clipplane;
        }
 
-       for (i = 0;i < r_view.numfrustumplanes;i++)
-               PlaneClassify(r_view.frustum + i);
+       for (i = 0;i < scene->view.numfrustumplanes;i++)
+               PlaneClassify(scene->view.frustum + i);
 
        // 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,
@@ -2494,32 +2489,32 @@ static void R_View_SetFrustum(void)
        //PlaneClassify(&frustum[4]);
 }
 
-void R_View_Update(void)
+void R_View_Update(renderscene_t* scene)
 {
-       R_View_SetFrustum();
-       R_View_WorldVisibility(r_view.useclipplane);
-       R_View_UpdateEntityVisible();
+       R_View_SetFrustum(scene);
+       R_View_WorldVisibility(scene->view.useclipplane);
+       R_View_UpdateEntityVisible(scene);
 }
 
-void R_SetupView(void)
+void R_SetupView(renderscene_t* scene)
 {
-       if (!r_view.useperspective)
-               GL_SetupView_Mode_Ortho(-r_view.ortho_x, -r_view.ortho_y, r_view.ortho_x, r_view.ortho_y, -r_refdef.farclip, r_refdef.farclip);
-       else if (r_refdef.rtworldshadows || r_refdef.rtdlightshadows)
-               GL_SetupView_Mode_PerspectiveInfiniteFarClip(r_view.frustum_x, r_view.frustum_y, r_refdef.nearclip);
+       if (!scene->view.useperspective)
+               GL_SetupView_Mode_Ortho(-scene->view.ortho_x, -scene->view.ortho_y, scene->view.ortho_x, scene->view.ortho_y, -scene->refdef.farclip, scene->refdef.farclip);
+       else if (scene->refdef.rtworldshadows || scene->refdef.rtdlightshadows)
+               GL_SetupView_Mode_PerspectiveInfiniteFarClip(scene->view.frustum_x, scene->view.frustum_y, scene->refdef.nearclip);
        else
-               GL_SetupView_Mode_Perspective(r_view.frustum_x, r_view.frustum_y, r_refdef.nearclip, r_refdef.farclip);
+               GL_SetupView_Mode_Perspective(scene->view.frustum_x, scene->view.frustum_y, scene->refdef.nearclip, scene->refdef.farclip);
 
-       GL_SetupView_Orientation_FromEntity(&r_view.matrix);
+       GL_SetupView_Orientation_FromEntity(&scene->view.matrix);
 
-       if (r_view.useclipplane)
+       if (scene->view.useclipplane)
        {
                // LordHavoc: couldn't figure out how to make this approach the
-               vec_t dist = r_view.clipplane.dist - r_water_clippingplanebias.value;
-               vec_t viewdist = DotProduct(r_view.origin, r_view.clipplane.normal);
-               if (viewdist < r_view.clipplane.dist + r_water_clippingplanebias.value)
-                       dist = r_view.clipplane.dist;
-               GL_SetupView_ApplyCustomNearClipPlane(r_view.clipplane.normal[0], r_view.clipplane.normal[1], r_view.clipplane.normal[2], dist);
+               vec_t dist = scene->view.clipplane.dist - r_water_clippingplanebias.value;
+               vec_t viewdist = DotProduct(scene->view.origin, scene->view.clipplane.normal);
+               if (viewdist < scene->view.clipplane.dist + r_water_clippingplanebias.value)
+                       dist = scene->view.clipplane.dist;
+               GL_SetupView_ApplyCustomNearClipPlane(scene->view.clipplane.normal[0], scene->view.clipplane.normal[1], scene->view.clipplane.normal[2], dist);
        }
 }
 
@@ -2556,7 +2551,7 @@ void R_ResetViewRendering2D(void)
        GL_CullFace(GL_FRONT); // quake is backwards, this culls back faces
 }
 
-void R_ResetViewRendering3D(void)
+void R_ResetViewRendering3D(renderscene_t* scene)
 {
        if (gl_support_fragment_shader)
        {
@@ -2566,11 +2561,11 @@ void R_ResetViewRendering3D(void)
        DrawQ_Finish();
 
        // 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
-       R_SetupView();
-       GL_Scissor(r_view.x, r_view.y, r_view.width, r_view.height);
+       qglViewport(scene->view.x, vid.height - (scene->view.y + scene->view.height), scene->view.width, scene->view.height);CHECKGLERROR
+       R_SetupView(scene);
+       GL_Scissor(scene->view.x, scene->view.y, scene->view.width, scene->view.height);
        GL_Color(1, 1, 1, 1);
-       GL_ColorMask(r_view.colormask[0], r_view.colormask[1], r_view.colormask[2], 1);
+       GL_ColorMask(scene->view.colormask[0], scene->view.colormask[1], scene->view.colormask[2], 1);
        GL_BlendFunc(GL_ONE, GL_ZERO);
        GL_AlphaTest(false);
        GL_ScissorTest(true);
@@ -2579,14 +2574,14 @@ void R_ResetViewRendering3D(void)
        GL_DepthTest(true);
        R_Mesh_Matrix(&identitymatrix);
        R_Mesh_ResetTextureState();
-       GL_PolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);
+       GL_PolygonOffset(scene->refdef.polygonfactor, scene->refdef.polygonoffset);
        qglEnable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
        qglDepthFunc(GL_LEQUAL);CHECKGLERROR
        qglDisable(GL_STENCIL_TEST);CHECKGLERROR
        qglStencilMask(~0);CHECKGLERROR
        qglStencilFunc(GL_ALWAYS, 128, ~0);CHECKGLERROR
        qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);CHECKGLERROR
-       GL_CullFace(r_view.cullface_back);
+       GL_CullFace(scene->view.cullface_back);
 }
 
 /*
@@ -2650,7 +2645,7 @@ void R_ResetViewRendering3D(void)
 "#endif // FRAGMENT_SHADER\n"
 */
 
-void R_RenderScene(qboolean addwaterplanes);
+void R_RenderScene(renderscene_t* scene, qboolean addwaterplanes);
 
 static void R_Water_StartFrame(void)
 {
@@ -2772,13 +2767,13 @@ static void R_Water_AddWaterPlane(msurface_t *surface)
        }
 }
 
-static void R_Water_ProcessPlanes(void)
+static void R_Water_ProcessPlanes(renderscene_t* scene)
 {
        r_view_t originalview;
        int planeindex;
        r_waterstate_waterplane_t *p;
 
-       originalview = r_view;
+       originalview = scene->view;
 
        // make sure enough textures are allocated
        for (planeindex = 0, p = r_waterstate.waterplanes;planeindex < r_waterstate.numwaterplanes;planeindex++, p++)
@@ -2803,72 +2798,72 @@ static void R_Water_ProcessPlanes(void)
        // render views
        for (planeindex = 0, p = r_waterstate.waterplanes;planeindex < r_waterstate.numwaterplanes;planeindex++, p++)
        {
-               r_view.showdebug = false;
-               r_view.width = r_waterstate.waterwidth;
-               r_view.height = r_waterstate.waterheight;
-               r_view.useclipplane = true;
+               scene->view.showdebug = false;
+               scene->view.width = r_waterstate.waterwidth;
+               scene->view.height = r_waterstate.waterheight;
+               scene->view.useclipplane = true;
                r_waterstate.renderingscene = true;
 
                // render the normal view scene and copy into texture
                // (except that a clipping plane should be used to hide everything on one side of the water, and the viewer's weapon model should be omitted)
                if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION))
                {
-                       r_view.clipplane = p->plane;
-                       VectorNegate(r_view.clipplane.normal, r_view.clipplane.normal);
-                       r_view.clipplane.dist = -r_view.clipplane.dist;
-                       PlaneClassify(&r_view.clipplane);
+                       scene->view.clipplane = p->plane;
+                       VectorNegate(scene->view.clipplane.normal, scene->view.clipplane.normal);
+                       scene->view.clipplane.dist = -scene->view.clipplane.dist;
+                       PlaneClassify(&scene->view.clipplane);
 
-                       R_RenderScene(false);
+                       R_RenderScene(scene, false);
 
                        // copy view into the screen texture
                        R_Mesh_TexBind(0, R_GetTexture(p->texture_refraction));
                        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
+                       qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, scene->view.x, vid.height - (scene->view.y + scene->view.height), scene->view.width, scene->view.height);CHECKGLERROR
                }
 
                if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFLECTION))
                {
                        // render reflected scene and copy into texture
-                       Matrix4x4_Reflect(&r_view.matrix, p->plane.normal[0], p->plane.normal[1], p->plane.normal[2], p->plane.dist, -2);
-                       r_view.clipplane = p->plane;
+                       Matrix4x4_Reflect(&scene->view.matrix, p->plane.normal[0], p->plane.normal[1], p->plane.normal[2], p->plane.dist, -2);
+                       scene->view.clipplane = p->plane;
                        // reverse the cullface settings for this render
-                       r_view.cullface_front = GL_FRONT;
-                       r_view.cullface_back = GL_BACK;
-                       if (r_refdef.worldmodel && r_refdef.worldmodel->brush.num_pvsclusterbytes)
+                       scene->view.cullface_front = GL_FRONT;
+                       scene->view.cullface_back = GL_BACK;
+                       if (scene->refdef.worldmodel && scene->refdef.worldmodel->brush.num_pvsclusterbytes)
                        {
-                               r_view.usecustompvs = true;
+                               scene->view.usecustompvs = true;
                                if (p->pvsvalid)
-                                       memcpy(r_viewcache.world_pvsbits, p->pvsbits, r_refdef.worldmodel->brush.num_pvsclusterbytes);
+                                       memcpy(scene->viewcache.world_pvsbits, p->pvsbits, scene->refdef.worldmodel->brush.num_pvsclusterbytes);
                                else
-                                       memset(r_viewcache.world_pvsbits, 0xFF, r_refdef.worldmodel->brush.num_pvsclusterbytes);
+                                       memset(scene->viewcache.world_pvsbits, 0xFF, scene->refdef.worldmodel->brush.num_pvsclusterbytes);
                        }
 
-                       R_ResetViewRendering3D();
+                       R_ResetViewRendering3D(scene);
                        R_ClearScreen(r_refdef.fogenabled);
                        if (r_timereport_active)
                                R_TimeReport("viewclear");
 
-                       R_RenderScene(false);
+                       R_RenderScene(scene, false);
 
                        R_Mesh_TexBind(0, R_GetTexture(p->texture_reflection));
                        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
+                       qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, scene->view.x, vid.height - (scene->view.y + scene->view.height), scene->view.width, scene->view.height);CHECKGLERROR
 
-                       R_ResetViewRendering3D();
+                       R_ResetViewRendering3D(scene);
                        R_ClearScreen(r_refdef.fogenabled);
                        if (r_timereport_active)
                                R_TimeReport("viewclear");
                }
 
-               r_view = originalview;
-               r_view.clear = true;
+               scene->view = originalview;
+               scene->view.clear = true;
                r_waterstate.renderingscene = false;
        }
        return;
 error:
-       r_view = originalview;
+       scene->view = originalview;
        r_waterstate.renderingscene = false;
        Cvar_SetValueQuick(&r_water, 0);
        Con_Printf("R_Water_ProcessPlanes: Error: texture creation failed!  Turned off r_water.\n");
@@ -3125,31 +3120,31 @@ void R_Bloom_MakeTexture(void)
        }
 }
 
-void R_HDR_RenderBloomTexture(void)
+void R_HDR_RenderBloomTexture(renderscene_t* scene)
 {
        int oldwidth, oldheight;
        float oldcolorscale;
 
-       oldcolorscale = r_view.colorscale;
-       oldwidth = r_view.width;
-       oldheight = r_view.height;
-       r_view.width = r_bloomstate.bloomwidth;
-       r_view.height = r_bloomstate.bloomheight;
+       oldcolorscale = scene->view.colorscale;
+       oldwidth = scene->view.width;
+       oldheight = scene->view.height;
+       scene->view.width = r_bloomstate.bloomwidth;
+       scene->view.height = r_bloomstate.bloomheight;
 
        // TODO: support GL_EXT_framebuffer_object rather than reusing the framebuffer?  it might improve SLI performance.
        // TODO: add exposure compensation features
        // TODO: add fp16 framebuffer support
 
-       r_view.showdebug = false;
-       r_view.colorscale *= r_bloom_colorscale.value / bound(1, r_hdr_range.value, 16);
+       scene->view.showdebug = false;
+       scene->view.colorscale *= r_bloom_colorscale.value / bound(1, r_hdr_range.value, 16);
 
        R_ClearScreen(r_refdef.fogenabled);
        if (r_timereport_active)
                R_TimeReport("HDRclear");
 
        r_waterstate.numwaterplanes = 0;
-       R_RenderScene(r_waterstate.enabled);
-       r_view.showdebug = true;
+       R_RenderScene(scene, r_waterstate.enabled);
+       scene->view.showdebug = true;
 
        R_ResetViewRendering2D();
 
@@ -3157,11 +3152,11 @@ void R_HDR_RenderBloomTexture(void)
        R_Bloom_MakeTexture();
 
        // restore the view settings
-       r_view.width = oldwidth;
-       r_view.height = oldheight;
-       r_view.colorscale = oldcolorscale;
+       scene->view.width = oldwidth;
+       scene->view.height = oldheight;
+       scene->view.colorscale = oldcolorscale;
 
-       R_ResetViewRendering3D();
+       R_ResetViewRendering3D(scene);
 
        R_ClearScreen(r_refdef.fogenabled);
        if (r_timereport_active)
@@ -3232,8 +3227,6 @@ static void R_BlendView(void)
        }
 }
 
-void R_RenderScene(qboolean addwaterplanes);
-
 matrix4x4_t r_waterscrollmatrix;
 
 void R_UpdateFogColor(void) // needs to be called before HDR subrender too, as that changes colorscale!
@@ -3263,88 +3256,88 @@ void R_UpdateFogColor(void) // needs to be called before HDR subrender too, as t
        }
 }
 
-void R_UpdateVariables(void)
+void R_UpdateVariables(renderscene_t* scene)
 {
        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);
+       scene->refdef.farclip = 4096;
+       if (scene->refdef.worldmodel)
+               scene->refdef.farclip += VectorDistance(scene->refdef.worldmodel->normalmins, scene->refdef.worldmodel->normalmaxs);
+       scene->refdef.nearclip = bound (0.001f, r_nearclip.value, scene->refdef.farclip - 1.0f);
 
        if (r_shadow_frontsidecasting.integer < 0 || r_shadow_frontsidecasting.integer > 1)
                Cvar_SetValueQuick(&r_shadow_frontsidecasting, 1);
-       r_refdef.polygonfactor = 0;
-       r_refdef.polygonoffset = 0;
-       r_refdef.shadowpolygonfactor = r_refdef.polygonfactor + r_shadow_polygonfactor.value * (r_shadow_frontsidecasting.integer ? 1 : -1);
-       r_refdef.shadowpolygonoffset = r_refdef.polygonoffset + r_shadow_polygonoffset.value * (r_shadow_frontsidecasting.integer ? 1 : -1);
-
-       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_dynamic.integer;
-       r_refdef.rtdlightshadows = r_refdef.rtdlight && r_shadow_realtime_dlight_shadows.integer && gl_stencil;
-       r_refdef.lightmapintensity = r_refdef.rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
+       scene->refdef.polygonfactor = 0;
+       scene->refdef.polygonoffset = 0;
+       scene->refdef.shadowpolygonfactor = scene->refdef.polygonfactor + r_shadow_polygonfactor.value * (r_shadow_frontsidecasting.integer ? 1 : -1);
+       scene->refdef.shadowpolygonoffset = scene->refdef.polygonoffset + r_shadow_polygonoffset.value * (r_shadow_frontsidecasting.integer ? 1 : -1);
+
+       scene->refdef.rtworld = r_shadow_realtime_world.integer;
+       scene->refdef.rtworldshadows = r_shadow_realtime_world_shadows.integer && gl_stencil;
+       scene->refdef.rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer && r_dynamic.integer;
+       scene->refdef.rtdlightshadows = r_refdef.rtdlight && r_shadow_realtime_dlight_shadows.integer && gl_stencil;
+       scene->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;
+               scene->refdef.rtworld = false;
+               scene->refdef.rtworldshadows = false;
+               scene->refdef.rtdlight = false;
+               scene->refdef.rtdlightshadows = false;
+               scene->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;
-                       r_refdef.fog_alpha = 1;
-                       r_refdef.fog_start = 0;
-                       r_refdef.fog_end = gl_skyclip.value;
+                       scene->refdef.oldgl_fogenable = true;
+                       scene->refdef.fog_density = gl_fogdensity.value;
+                       scene->refdef.fog_red = gl_fogred.value;
+                       scene->refdef.fog_green = gl_foggreen.value;
+                       scene->refdef.fog_blue = gl_fogblue.value;
+                       scene->refdef.fog_alpha = 1;
+                       scene->refdef.fog_start = 0;
+                       scene->refdef.fog_end = gl_skyclip.value;
                }
-               else if (r_refdef.oldgl_fogenable)
+               else if (scene->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;
-                       r_refdef.fog_alpha = 0;
-                       r_refdef.fog_start = 0;
-                       r_refdef.fog_end = 0;
+                       scene->refdef.oldgl_fogenable = false;
+                       scene->refdef.fog_density = 0;
+                       scene->refdef.fog_red = 0;
+                       scene->refdef.fog_green = 0;
+                       scene->refdef.fog_blue = 0;
+                       scene->refdef.fog_alpha = 0;
+                       scene->refdef.fog_start = 0;
+                       scene->refdef.fog_end = 0;
                }
        }
 
-       r_refdef.fog_alpha = bound(0, r_refdef.fog_alpha, 1);
-       r_refdef.fog_start = max(0, r_refdef.fog_start);
-       r_refdef.fog_end = max(r_refdef.fog_start + 0.01, r_refdef.fog_end);
+       scene->refdef.fog_alpha = bound(0, scene->refdef.fog_alpha, 1);
+       scene->refdef.fog_start = max(0, scene->refdef.fog_start);
+       scene->refdef.fog_end = max(scene->refdef.fog_start + 0.01, scene->refdef.fog_end);
 
        // R_UpdateFogColor(); // why? R_RenderScene does it anyway
 
-       if (r_refdef.fog_density)
+       if (scene->refdef.fog_density)
        {
-               r_refdef.fogenabled = true;
+               scene->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)
                if (r_fog_exp2.integer)
-                       r_refdef.fogrange = 32 / (r_refdef.fog_density * r_refdef.fog_density) + r_refdef.fog_start;
+                       scene->refdef.fogrange = 32 / (scene->refdef.fog_density * scene->refdef.fog_density) + scene->refdef.fog_start;
                else
-                       r_refdef.fogrange = 2048 / r_refdef.fog_density + r_refdef.fog_start;
-               r_refdef.fogrange = bound(r_refdef.fog_start, r_refdef.fogrange, r_refdef.fog_end);
-               r_refdef.fograngerecip = 1.0f / r_refdef.fogrange;
-               r_refdef.fogmasktabledistmultiplier = FOGMASKTABLEWIDTH * r_refdef.fograngerecip;
+                       scene->refdef.fogrange = 2048 / scene->refdef.fog_density + scene->refdef.fog_start;
+               scene->refdef.fogrange = bound(scene->refdef.fog_start, scene->refdef.fogrange, scene->refdef.fog_end);
+               scene->refdef.fograngerecip = 1.0f / scene->refdef.fogrange;
+               scene->refdef.fogmasktabledistmultiplier = FOGMASKTABLEWIDTH * scene->refdef.fograngerecip;
                // fog color was already set
                // update the fog texture
-               if (r_refdef.fogmasktable_start != r_refdef.fog_start || r_refdef.fogmasktable_alpha != r_refdef.fog_alpha || r_refdef.fogmasktable_density != r_refdef.fog_density || r_refdef.fogmasktable_range != r_refdef.fogrange)
-                       R_BuildFogTexture();
+               if (scene->refdef.fogmasktable_start != scene->refdef.fog_start || scene->refdef.fogmasktable_alpha != scene->refdef.fog_alpha || scene->refdef.fogmasktable_density != scene->refdef.fog_density || scene->refdef.fogmasktable_range != scene->refdef.fogrange)
+                       R_BuildFogTexture(scene);
        }
        else
-               r_refdef.fogenabled = false;
+               scene->refdef.fogenabled = false;
 }
 
 /*
@@ -3352,9 +3345,9 @@ void R_UpdateVariables(void)
 R_RenderView
 ================
 */
-void R_RenderView(void)
+void R_RenderView(renderscene_t* scene)
 {
-       if (!r_refdef.entities/* || !r_refdef.worldmodel*/)
+       if (!scene->refdef.entities/* || !r_refdef.worldmodel*/)
                return; //Host_Error ("R_RenderView: NULL worldmodel");
 
        r_view.colorscale = r_hdr_scenebrightness.value;
@@ -3368,24 +3361,24 @@ void R_RenderView(void)
        if (r_timereport_active)
                R_TimeReport("viewsetup");
 
-       R_ResetViewRendering3D();
+       R_ResetViewRendering3D(scene);
 
-       if (r_view.clear || r_refdef.fogenabled)
+       if (scene->view.clear || scene->refdef.fogenabled)
        {
                R_ClearScreen(r_refdef.fogenabled);
                if (r_timereport_active)
                        R_TimeReport("viewclear");
        }
-       r_view.clear = true;
+       scene->view.clear = true;
 
-       r_view.showdebug = true;
+       scene->view.showdebug = true;
 
        // this produces a bloom texture to be used in R_BlendView() later
        if (r_hdr.integer)
-               R_HDR_RenderBloomTexture();
+               R_HDR_RenderBloomTexture(scene);
 
        r_waterstate.numwaterplanes = 0;
-       R_RenderScene(r_waterstate.enabled);
+       R_RenderScene(scene, r_waterstate.enabled);
 
        R_BlendView();
        if (r_timereport_active)
@@ -3402,16 +3395,16 @@ extern void R_DrawPortals (void);
 extern cvar_t cl_locs_show;
 static void R_DrawLocs(void);
 static void R_DrawEntityBBoxes(void);
-void R_RenderScene(qboolean addwaterplanes)
+void R_RenderScene(renderscene_t* scene, qboolean addwaterplanes)
 {
        Matrix4x4_Invert_Simple(&r_view.inverse_matrix, &r_view.matrix);
        R_UpdateFogColor();
 
        if (addwaterplanes)
        {
-               R_ResetViewRendering3D();
+               R_ResetViewRendering3D(scene);
 
-               R_View_Update();
+               R_View_Update(scene);
                if (r_timereport_active)
                        R_TimeReport("watervis");
 
@@ -3426,16 +3419,16 @@ void R_RenderScene(qboolean addwaterplanes)
                if (r_refdef.extraupdate)
                        S_ExtraUpdate ();
 
-               R_DrawModelsAddWaterPlanes();
+               R_DrawModelsAddWaterPlanes(scene);
                if (r_timereport_active)
                        R_TimeReport("watermodels");
 
-               R_Water_ProcessPlanes();
+               R_Water_ProcessPlanes(scene);
                if (r_timereport_active)
                        R_TimeReport("waterscenes");
        }
 
-       R_ResetViewRendering3D();
+       R_ResetViewRendering3D(scene);
 
        // don't let sound skip if going slow
        if (r_refdef.extraupdate)
@@ -3445,7 +3438,7 @@ void R_RenderScene(qboolean addwaterplanes)
 
        R_SkyStartFrame();
 
-       R_View_Update();
+       R_View_Update(scene);
        if (r_timereport_active)
                R_TimeReport("visibility");
 
@@ -3476,7 +3469,7 @@ void R_RenderScene(qboolean addwaterplanes)
        }
        if (r_depthfirst.integer >= 2)
        {
-               R_DrawModelsDepth();
+               R_DrawModelsDepth(scene);
                if (r_timereport_active)
                        R_TimeReport("modeldepth");
        }
@@ -3492,7 +3485,7 @@ void R_RenderScene(qboolean addwaterplanes)
        if (r_refdef.extraupdate)
                S_ExtraUpdate ();
 
-       R_DrawModels();
+       R_DrawModels(scene);
        if (r_timereport_active)
                R_TimeReport("models");
 
@@ -3502,9 +3495,9 @@ void R_RenderScene(qboolean addwaterplanes)
 
        if (r_shadows.integer > 0 && r_refdef.lightmapintensity > 0)
        {
-               R_DrawModelShadows();
+               R_DrawModelShadows(scene);
 
-               R_ResetViewRendering3D();
+               R_ResetViewRendering3D(scene);
 
                // don't let sound skip if going slow
                if (r_refdef.extraupdate)
@@ -3586,7 +3579,7 @@ void R_RenderScene(qboolean addwaterplanes)
                r_refdef.worldmodel->DrawDebug(r_refdef.worldentity);
                if (r_timereport_active)
                        R_TimeReport("worlddebug");
-               R_DrawModelsDebug();
+               R_DrawModelsDebug(scene);
                if (r_timereport_active)
                        R_TimeReport("modeldebug");
        }
diff --git a/menu.c b/menu.c
index 29467965802cf1c5f50e6c4c383ff0063ca50e05..d7078b4f2af1179799624142aa6637c9e894bde0 100644 (file)
--- a/menu.c
+++ b/menu.c
@@ -5068,11 +5068,16 @@ void MP_KeyEvent (int key, char ascii, qboolean downevent)
        PRVM_End;
 }
 
+extern renderscene_t menu_renderscene;
+
 void MP_Draw (void)
 {
        PRVM_Begin;
        PRVM_SetProg(PRVM_MENUPROG);
 
+       // Here?
+       R_UpdateVariables (&menu_renderscene);
+
        PRVM_ExecuteProgram(prog->funcoffsets.m_draw,"m_draw() required");
 
        PRVM_End;
@@ -5223,4 +5228,7 @@ void MR_Init(void)
                MR_SetRouting (TRUE);
        else
                MR_SetRouting (FALSE);
+
+       // FIXME: needed so cl.max_entities is set
+       CL_ClearState ();
 }
index 11d0ddc92cb73b8b576523757a853a9f4c149147..6dc565334e38b8ade7408d2a6c1b5df6bc5217fc 100644 (file)
@@ -1,6 +1,7 @@
 #include "quakedef.h"
 
 #include "prvm_cmds.h"
+#include "clvm_cmds.h"
 #include "menu.h"
 
 //============================================================================
@@ -23,6 +24,7 @@ char *vm_m_extensions =
 #ifdef SUPPORT_GECKO
 "DP_GECKO_SUPPORT "
 #endif
+"DP_QC_RENDER_SCENE"
 ;
 
 /*
@@ -872,9 +874,9 @@ VM_altstr_ins,                                              //  #86
 VM_findflags,                                          //  #87
 VM_findchainflags,                             //  #88
 VM_cvar_defstring,                             //  #89
-NULL,                                                                  //  #90
-NULL,                                                                  //  #91
-NULL,                                                                  //  #92
+VM_CL_setmodel,                                        // #90 void(entity e, string m) setmodel (QUAKE)
+VM_CL_precache_model,                  // #91 void(string s) precache_model (QUAKE)
+VM_CL_setorigin,                               // #92 void(entity e, vector o) setorigin (QUAKE)
 NULL,                                                                  //  #93
 NULL,                                                                  //  #94
 NULL,                                                                  //  #95
@@ -1082,16 +1084,17 @@ NULL,                                                                   // #296
 NULL,                                                                  // #297
 NULL,                                                                  // #298
 NULL,                                                                  // #299
-NULL,                                                                  // #300
-NULL,                                                                  // #301
-NULL,                                                                  // #302
-NULL,                                                                  // #303
-NULL,                                                                  // #304
-NULL,                                                                  // #305
-NULL,                                                                  // #306
-NULL,                                                                  // #307
-NULL,                                                                  // #308
-NULL,                                                                  // #309
+// CSQC range #300-#399
+VM_CL_R_ClearScene,                            // #300 void() clearscene (DP_QC_RENDER_SCENE)
+VM_CL_R_AddEntities,                   // #301 void(float mask) addentities (DP_QC_RENDER_SCENE)
+VM_CL_R_AddEntity,                             // #302 void(entity ent) addentity (DP_QC_RENDER_SCENE)
+VM_CL_R_SetView,                               // #303 float(float property, ...) setproperty (DP_QC_RENDER_SCENE)
+VM_CL_R_RenderScene,                   // #304 void() renderscene (DP_QC_RENDER_SCENE)
+VM_CL_R_AddDynamicLight,               // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (DP_QC_RENDER_SCENE)
+VM_CL_R_PolygonBegin,                  // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
+VM_CL_R_PolygonVertex,                 // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
+VM_CL_R_PolygonEnd,                            // #308 void() R_EndPolygon
+NULL/*VM_CL_R_LoadWorldModel*/,                                // #309 void(string modelname) R_LoadWorldModel
 NULL,                                                                  // #310
 NULL,                                                                  // #311
 NULL,                                                                  // #312
@@ -1421,13 +1424,39 @@ VM_M_getextresponse                             // #624
 
 const int vm_m_numbuiltins = sizeof(vm_m_builtins) / sizeof(prvm_builtin_t);
 
+renderscene_t menu_renderscene;
+
 void VM_M_Cmd_Init(void)
 {
        VM_Cmd_Init();
+       VM_Polygons_Reset();
+       renderscenes[PRVM_MENUPROG] = &menu_renderscene;
+       memset (&menu_renderscene, 0, sizeof (renderscene_t));
+       
+       menu_renderscene.refdef.frustumscale_x = 1;
+       menu_renderscene.refdef.frustumscale_y = 1;
+       menu_renderscene.refdef.maxentities = MAX_EDICTS + 256 + 512;
+       menu_renderscene.refdef.entities = (entity_render_t **)Mem_Alloc(cls.permanentmempool, sizeof(entity_render_t *) * menu_renderscene.refdef.maxentities);
+       
+       menu_renderscene.view.width = vid.width;
+       menu_renderscene.view.height = vid.height;
+       menu_renderscene.view.depth = 1;
+       menu_renderscene.view.x = 0;
+       menu_renderscene.view.y = 0;
+       menu_renderscene.view.z = 0;
+       menu_renderscene.view.colormask[0] = true;
+       menu_renderscene.view.colormask[1] = true;
+       menu_renderscene.view.colormask[2] = true;
+       menu_renderscene.view.colormask[3] = true;
+       
+       menu_renderscene.view.useperspective = true;
+       menu_renderscene.view.frustum_y = tan(scr_fov.value * M_PI / 360.0) * (3.0/4.0);
+       menu_renderscene.view.frustum_x = r_view.frustum_y * (float)menu_renderscene.view.width / (float)menu_renderscene.view.height / vid_pixelheight.value;
 }
 
 void VM_M_Cmd_Reset(void)
 {
        //VM_Cmd_Init();
        VM_Cmd_Reset();
+       VM_Polygons_Reset();
 }
index c4f98c9218ff4d449af48a3e0218f5d9a9f13bc8..14d671cd4967931cb2f215867eceb64970627d1c 100644 (file)
@@ -3165,7 +3165,7 @@ void R_ShadowVolumeLighting(qboolean visible)
 
 extern void R_SetupView(void);
 extern cvar_t r_shadows_throwdistance;
-void R_DrawModelShadows(void)
+void R_DrawModelShadows(renderscene_t* scene)
 {
        int i;
        float relativethrowdistance;
@@ -3179,7 +3179,7 @@ void R_DrawModelShadows(void)
                return;
 
        CHECKGLERROR
-       GL_Scissor(r_view.x, r_view.y, r_view.width, r_view.height);
+       GL_Scissor(scene->view.x, scene->view.y, scene->view.width, scene->view.height);
 
        r_shadow_rendermode = R_SHADOW_RENDERMODE_NONE;
 
@@ -3192,9 +3192,9 @@ void R_DrawModelShadows(void)
 
        R_Shadow_RenderMode_StencilShadowVolumes(true);
 
-       for (i = 0;i < r_refdef.numentities;i++)
+       for (i = 0;i < scene->refdef.numentities;i++)
        {
-               ent = r_refdef.entities[i];
+               ent = scene->refdef.entities[i];
                // cast shadows from anything that is not a submodel of the map
                if (ent->model && ent->model->DrawShadowVolume != NULL && !ent->model->brush.submodel && (ent->flags & RENDER_SHADOW))
                {
@@ -3219,8 +3219,8 @@ void R_DrawModelShadows(void)
 
        // set up ortho view for rendering this pass
        GL_SetupView_Mode_Ortho(0, 0, 1, 1, -10, 100);
-       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(scene->view.x, scene->view.y, scene->view.width, scene->view.height);
+       GL_ColorMask(scene->view.colormask[0], scene->view.colormask[1], scene->view.colormask[2], 1);
        GL_ScissorTest(true);
        R_Mesh_Matrix(&identitymatrix);
        R_Mesh_ResetTextureState();
@@ -3234,7 +3234,7 @@ void R_DrawModelShadows(void)
        GL_DepthMask(false);
        GL_PolygonOffset(0, 0);CHECKGLERROR
        GL_Color(0, 0, 0, 0.5);
-       GL_ColorMask(r_view.colormask[0], r_view.colormask[1], r_view.colormask[2], 1);
+       GL_ColorMask(scene->view.colormask[0], scene->view.colormask[1], scene->view.colormask[2], 1);
        qglDepthFunc(GL_ALWAYS);CHECKGLERROR
        qglEnable(GL_STENCIL_TEST);CHECKGLERROR
        qglStencilMask(~0);CHECKGLERROR
index 49d3c3620aa4a2f1e203a11f78f90bf0e948b8be..4982b4a44002774aab6d020a9493e2221126904b 100644 (file)
--- a/render.h
+++ b/render.h
@@ -121,8 +121,8 @@ extern cvar_t r_wateralpha;
 extern cvar_t r_dynamic;
 
 void R_Init(void);
-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_UpdateVariables(renderscene_t* scene); // must call after setting up most of r_refdef, but before calling R_RenderView
+void R_RenderView(renderscene_t* scene); // must set r_refdef and call R_UpdateVariables first
 
 
 void R_InitSky (unsigned char *src, int bytesperpixel); // called at level load