muzzleflash fades out
authorlordhavoc <lordhavoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 15 May 2002 08:56:45 +0000 (08:56 +0000)
committerlordhavoc <lordhavoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 15 May 2002 08:56:45 +0000 (08:56 +0000)
changed .lights file format very slightly to add customizable distance bias (softness)
now splits surface meshs bigger than 1000 tris into multiple smaller ones automatically while loading

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@1841 d7cf8633-e32d-0410-b094-e92efae38249

cl_main.c
client.h
gl_rsurf.c
model_brush.c
model_brush.h
r_light.c

index 1115575..b387596 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -476,18 +476,7 @@ static void CL_RelinkNetworkEntities()
                        if (effects & EF_BRIGHTFIELD)
                                CL_EntityParticles (ent);
                        if (effects & EF_MUZZLEFLASH)
-                       {
-                               vec3_t v, v2;
-
-                               AngleVectors (ent->render.angles, v, NULL, NULL);
-
-                               v2[0] = v[0] * 18 + neworg[0];
-                               v2[1] = v[1] * 18 + neworg[1];
-                               v2[2] = v[2] * 18 + neworg[2] + 16;
-                               TraceLine(neworg, v2, v, NULL, 0, true);
-
-                               CL_AllocDlight (NULL, v, 100, 1, 1, 1, 0, 0);
-                       }
+                               ent->persistent.muzzleflash = 100.0f;
                        if (effects & EF_DIMLIGHT)
                        {
                                dlightcolor[0] += 200.0f;
@@ -591,6 +580,21 @@ static void CL_RelinkNetworkEntities()
                        }
                }
 
+               if (ent->persistent.muzzleflash > 0)
+               {
+                       vec3_t v, v2;
+
+                       AngleVectors (ent->render.angles, v, NULL, NULL);
+
+                       v2[0] = v[0] * 18 + neworg[0];
+                       v2[1] = v[1] * 18 + neworg[1];
+                       v2[2] = v[2] * 18 + neworg[2] + 16;
+                       TraceLine(neworg, v2, v, NULL, 0, true);
+
+                       CL_AllocDlight (NULL, v, ent->persistent.muzzleflash, 1, 1, 1, 0, 0);
+                       ent->persistent.muzzleflash -= cl.frametime * 1000;
+               }
+
                // LordHavoc: if the model has no flags, don't check each
                if (ent->render.model && ent->render.model->flags)
                {
index 9430e3a..a2fccef 100644 (file)
--- a/client.h
+++ b/client.h
@@ -29,57 +29,96 @@ frameblend_t;
 // LordHavoc: nothing in this structure is persistant, it may be overwritten by the client every frame, for persistant data use entity_lerp_t.
 typedef struct entity_render_s
 {
-       vec3_t  origin;                 // location
-       vec3_t  angles;                 // orientation
-       float   alpha;                  // opacity (alpha) of the model
-       float   scale;                  // size the model is shown
-
-       model_t *model;                 // NULL = no model
-       int             frame;                  // current uninterpolated animation frame (for things which do not use interpolation)
-       int             colormap;               // entity shirt and pants colors
-       int             effects;                // light, particles, etc
-       int             skinnum;                // for Alias models
-       int             flags;                  // render flags
+       // location
+       vec3_t origin;
+       // orientation
+       vec3_t angles;
+       // opacity (alpha) of the model
+       float alpha;
+       // size the model is shown
+       float scale;
+
+       // NULL = no model
+       model_t *model;
+       // current uninterpolated animation frame (for things which do not use interpolation)
+       int frame;
+       // entity shirt and pants colors
+       int colormap;
+       // light, particles, etc
+       int effects;
+       // for Alias models
+       int skinnum;
+       // render flags
+       int flags;
 
        // these are copied from the persistent data
-       int             frame1;                 // frame that the model is interpolating from
-       int             frame2;                 // frame that the model is interpolating to
-       double  framelerp;              // interpolation factor, usually computed from frame2time
-       double  frame1time;             // time frame1 began playing (for framegroup animations)
-       double  frame2time;             // time frame2 began playing (for framegroup animations)
+
+       // frame that the model is interpolating from
+       int frame1;
+       // frame that the model is interpolating to
+       int frame2;
+       // interpolation factor, usually computed from frame2time
+       double framelerp;
+       // time frame1 began playing (for framegroup animations)
+       double frame1time;
+       // time frame2 began playing (for framegroup animations)
+       double frame2time;
 
        // calculated by the renderer (but not persistent)
-       int             visframe;               // if visframe == r_framecount, it is visible
-       vec3_t  mins, maxs;             // calculated during R_AddModelEntities
-       frameblend_t    frameblend[4]; // 4 frame numbers (-1 if not used) and their blending scalers (0-1), if interpolation is not desired, use frame instead
+
+       // if visframe == r_framecount, it is visible
+       int visframe;
+       // calculated during R_AddModelEntities
+       vec3_t mins, maxs;
+       // 4 frame numbers (-1 if not used) and their blending scalers (0-1), if interpolation is not desired, use frame instead
+       frameblend_t frameblend[4];
 }
 entity_render_t;
 
 typedef struct entity_persistent_s
 {
        // particles
-       vec3_t  trail_origin;   // trail rendering
-       float   trail_time;             // trail rendering
+
+       // trail rendering
+       vec3_t trail_origin;
+       float trail_time;
+
+       // effects
+
+       // muzzleflash fading
+       float muzzleflash;
 
        // interpolated animation
-       int             modelindex;             // lerp resets when model changes
-       int             frame1;                 // frame that the model is interpolating from
-       int             frame2;                 // frame that the model is interpolating to
-       double  framelerp;              // interpolation factor, usually computed from frame2time
-       double  frame1time;             // time frame1 began playing (for framegroup animations)
-       double  frame2time;             // time frame2 began playing (for framegroup animations)
+
+       // lerp resets when model changes
+       int modelindex;
+       // frame that the model is interpolating from
+       int frame1;
+       // frame that the model is interpolating to
+       int frame2;
+       // interpolation factor, usually computed from frame2time
+       double framelerp;
+       // time frame1 began playing (for framegroup animations)
+       double frame1time;
+       // time frame2 began playing (for framegroup animations)
+       double frame2time;
 }
 entity_persistent_t;
 
 typedef struct entity_s
 {
-       entity_state_t state_baseline;  // baseline state (default values)
-       entity_state_t state_previous;  // previous state (interpolating from this)
-       entity_state_t state_current;   // current state (interpolating to this)
-
-       entity_persistent_t persistent; // used for regenerating parts of render
-
-       entity_render_t render; // the only data the renderer should know about
+       // baseline state (default values)
+       entity_state_t state_baseline;
+       // previous state (interpolating from this)
+       entity_state_t state_previous;
+       // current state (interpolating to this)
+       entity_state_t state_current;
+
+       // used for regenerating parts of render
+       entity_persistent_t persistent;
+
+       // the only data the renderer should know about
+       entity_render_t render;
 }
 entity_t;
 
index 7649393..edfe4cd 100644 (file)
@@ -503,6 +503,7 @@ static void RSurfShader_Sky(msurface_t *firstsurf)
        float number, length, dir[3], speedscale;
        surfvertex_t *v;
        surfvert_t *sv;
+       surfmesh_t *mesh;
        rmeshinfo_t m;
 
        // LordHavoc: HalfLife maps have freaky skypolys...
@@ -524,26 +525,29 @@ static void RSurfShader_Sky(msurface_t *firstsurf)
                        m.blendfunc1 = GL_ZERO;
                        m.blendfunc2 = GL_ONE;
                        m.depthwrite = true;
-                       m.numtriangles = surf->mesh.numtriangles;
-                       m.numverts = surf->mesh.numverts;
-                       m.index = surf->mesh.index;
-                       //m.cr = 0;
-                       //m.cg = 0;
-                       //m.cb = 0;
-                       //m.ca = 0;
-                       if (softwaretransform_complexity)
-                       {
-                               m.vertex = &svert[0].v[0];
-                               m.vertexstep = sizeof(surfvert_t);
-                               for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++)
-                                       softwaretransform(v->v, sv->v);
-                       }
-                       else
+                       for (mesh = surf->mesh;mesh;mesh = mesh->chain)
                        {
-                               m.vertex = &surf->mesh.vertex[0].v[0];
-                               m.vertexstep = sizeof(surfvertex_t);
+                               m.numtriangles = mesh->numtriangles;
+                               m.numverts = mesh->numverts;
+                               m.index = mesh->index;
+                               //m.cr = 0;
+                               //m.cg = 0;
+                               //m.cb = 0;
+                               //m.ca = 0;
+                               if (softwaretransform_complexity)
+                               {
+                                       m.vertex = &svert[0].v[0];
+                                       m.vertexstep = sizeof(surfvert_t);
+                                       for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++)
+                                               softwaretransform(v->v, sv->v);
+                               }
+                               else
+                               {
+                                       m.vertex = &mesh->vertex[0].v[0];
+                                       m.vertexstep = sizeof(surfvertex_t);
+                               }
+                               R_Mesh_Draw(&m);
                        }
-                       R_Mesh_Draw(&m);
                }
        }
        else if (skyrenderglquake)
@@ -554,9 +558,6 @@ static void RSurfShader_Sky(msurface_t *firstsurf)
                        m.transparent = false;
                        m.blendfunc1 = GL_ONE;
                        m.blendfunc2 = GL_ZERO;
-                       m.numtriangles = surf->mesh.numtriangles;
-                       m.numverts = surf->mesh.numverts;
-                       m.index = surf->mesh.index;
                        m.vertex = &svert[0].v[0];
                        m.vertexstep = sizeof(surfvert_t);
                        m.cr = 1;
@@ -568,25 +569,31 @@ static void RSurfShader_Sky(msurface_t *firstsurf)
                        m.texcoordstep[0] = sizeof(surfvert_t);
                        speedscale = cl.time * (8.0/128.0);
                        speedscale -= (int)speedscale;
-                       for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++)
+                       for (mesh = surf->mesh;mesh;mesh = mesh->chain)
                        {
-                               softwaretransform(v->v, sv->v);
-                               VectorSubtract (sv->v, r_origin, dir);
-                               // flatten the sphere
-                               dir[2] *= 3;
-
-                               number = DotProduct(dir, dir);
-                               #if SLOWMATH
-                               length = 3.0f / sqrt(number);
-                               #else
-                               *((int *)&length) = 0x5f3759df - ((* (int *) &number) >> 1);
-                               length = 3.0f * (length * (1.5f - (number * 0.5f * length * length)));
-                               #endif
-
-                               sv->st[0] = speedscale + dir[0] * length;
-                               sv->st[1] = speedscale + dir[1] * length;
+                               m.numtriangles = mesh->numtriangles;
+                               m.numverts = mesh->numverts;
+                               m.index = mesh->index;
+                               for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++)
+                               {
+                                       softwaretransform(v->v, sv->v);
+                                       VectorSubtract (sv->v, r_origin, dir);
+                                       // flatten the sphere
+                                       dir[2] *= 3;
+
+                                       number = DotProduct(dir, dir);
+                                       #if SLOWMATH
+                                       length = 3.0f / sqrt(number);
+                                       #else
+                                       *((int *)&length) = 0x5f3759df - ((* (int *) &number) >> 1);
+                                       length = 3.0f * (length * (1.5f - (number * 0.5f * length * length)));
+                                       #endif
+
+                                       sv->st[0] = speedscale + dir[0] * length;
+                                       sv->st[1] = speedscale + dir[1] * length;
+                               }
+                               R_Mesh_Draw(&m);
                        }
-                       R_Mesh_Draw(&m);
                }
        }
        else
@@ -598,26 +605,29 @@ static void RSurfShader_Sky(msurface_t *firstsurf)
                        m.transparent = false;
                        m.blendfunc1 = GL_ONE;
                        m.blendfunc2 = GL_ZERO;
-                       m.numtriangles = surf->mesh.numtriangles;
-                       m.numverts = surf->mesh.numverts;
-                       m.index = surf->mesh.index;
                        m.cr = fogcolor[0];
                        m.cg = fogcolor[1];
                        m.cb = fogcolor[2];
                        m.ca = 1;
-                       if (softwaretransform_complexity)
-                       {
-                               m.vertex = &svert[0].v[0];
-                               m.vertexstep = sizeof(surfvert_t);
-                               for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++)
-                                       softwaretransform(v->v, sv->v);
-                       }
-                       else
+                       for (mesh = surf->mesh;mesh;mesh = mesh->chain)
                        {
-                               m.vertex = &surf->mesh.vertex[0].v[0];
-                               m.vertexstep = sizeof(surfvertex_t);
+                               m.numtriangles = mesh->numtriangles;
+                               m.numverts = mesh->numverts;
+                               m.index = mesh->index;
+                               if (softwaretransform_complexity)
+                               {
+                                       m.vertex = &svert[0].v[0];
+                                       m.vertexstep = sizeof(surfvert_t);
+                                       for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++)
+                                               softwaretransform(v->v, sv->v);
+                               }
+                               else
+                               {
+                                       m.vertex = &mesh->vertex[0].v[0];
+                                       m.vertexstep = sizeof(surfvertex_t);
+                               }
+                               R_Mesh_Draw(&m);
                        }
-                       R_Mesh_Draw(&m);
                }
        }
        if (skyrenderglquake)
@@ -628,9 +638,6 @@ static void RSurfShader_Sky(msurface_t *firstsurf)
                        m.transparent = false;
                        m.blendfunc1 = GL_SRC_ALPHA;
                        m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
-                       m.numtriangles = surf->mesh.numtriangles;
-                       m.numverts = surf->mesh.numverts;
-                       m.index = surf->mesh.index;
                        m.vertex = &svert[0].v[0];
                        m.vertexstep = sizeof(surfvert_t);
                        m.cr = 1;
@@ -642,25 +649,31 @@ static void RSurfShader_Sky(msurface_t *firstsurf)
                        m.texcoordstep[0] = sizeof(surfvert_t);
                        speedscale = cl.time * (16.0/128.0);
                        speedscale -= (int)speedscale;
-                       for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++)
+                       for (mesh = surf->mesh;mesh;mesh = mesh->chain)
                        {
-                               softwaretransform(v->v, sv->v);
-                               VectorSubtract (sv->v, r_origin, dir);
-                               // flatten the sphere
-                               dir[2] *= 3;
-
-                               number = DotProduct(dir, dir);
-                               #if SLOWMATH
-                               length = 3.0f / sqrt(number);
-                               #else
-                               *((int *)&length) = 0x5f3759df - ((* (int *) &number) >> 1);
-                               length = 3.0f * (length * (1.5f - (number * 0.5f * length * length)));
-                               #endif
-
-                               sv->st[0] = speedscale + dir[0] * length;
-                               sv->st[1] = speedscale + dir[1] * length;
+                               m.numtriangles = mesh->numtriangles;
+                               m.numverts = mesh->numverts;
+                               m.index = mesh->index;
+                               for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++)
+                               {
+                                       softwaretransform(v->v, sv->v);
+                                       VectorSubtract (sv->v, r_origin, dir);
+                                       // flatten the sphere
+                                       dir[2] *= 3;
+
+                                       number = DotProduct(dir, dir);
+                                       #if SLOWMATH
+                                       length = 3.0f / sqrt(number);
+                                       #else
+                                       *((int *)&length) = 0x5f3759df - ((* (int *) &number) >> 1);
+                                       length = 3.0f * (length * (1.5f - (number * 0.5f * length * length)));
+                                       #endif
+
+                                       sv->st[0] = speedscale + dir[0] * length;
+                                       sv->st[1] = speedscale + dir[1] * length;
+                               }
+                               R_Mesh_Draw(&m);
                        }
-                       R_Mesh_Draw(&m);
                }
        }
 }
@@ -698,11 +711,12 @@ static int RSurf_Light(int *dlightbits, int numverts)
 
 static void RSurfShader_Water_Pass_Base(msurface_t *surf)
 {
-       int                             i;
-       float                   diff[3], alpha, ifog;
-       surfvertex_t    *v;
-       surfvert_t              *sv;
-       rmeshinfo_t             m;
+       int i;
+       float diff[3], alpha, ifog;
+       surfvertex_t *v;
+       surfvert_t *sv;
+       surfmesh_t *mesh;
+       rmeshinfo_t m;
        alpha = currentrenderentity->alpha * (surf->flags & SURF_DRAWNOALPHA ? 1 : r_wateralpha.value);
 
        memset(&m, 0, sizeof(m));
@@ -718,9 +732,6 @@ static void RSurfShader_Water_Pass_Base(msurface_t *surf)
                m.blendfunc1 = GL_ONE;
                m.blendfunc2 = GL_ZERO;
        }
-       m.numtriangles = surf->mesh.numtriangles;
-       m.numverts = surf->mesh.numverts;
-       m.index = surf->mesh.index;
        m.vertex = &svert[0].v[0];
        m.vertexstep = sizeof(surfvert_t);
        m.color = &svert[0].c[0];
@@ -728,60 +739,64 @@ static void RSurfShader_Water_Pass_Base(msurface_t *surf)
        m.tex[0] = R_GetTexture(surf->currenttexture->texture);
        m.texcoords[0] = &svert[0].st[0];
        m.texcoordstep[0] = sizeof(surfvert_t);
-       for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++)
+       for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
-               softwaretransform(v->v, sv->v);
-               if (r_waterripple.value)
-                       sv->v[2] += r_waterripple.value * (1.0f / 64.0f) * turbsin[(int)((v->v[0]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255] * turbsin[(int)((v->v[1]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255];
-               if (surf->flags & SURF_DRAWFULLBRIGHT)
-               {
-                       sv->c[0] = 1;
-                       sv->c[1] = 1;
-                       sv->c[2] = 1;
-                       sv->c[3] = alpha;
-               }
-               else
+               m.numtriangles = mesh->numtriangles;
+               m.numverts = mesh->numverts;
+               m.index = mesh->index;
+               for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++)
                {
-                       sv->c[0] = 0.5f;
-                       sv->c[1] = 0.5f;
-                       sv->c[2] = 0.5f;
-                       sv->c[3] = alpha;
+                       softwaretransform(v->v, sv->v);
+                       if (r_waterripple.value)
+                               sv->v[2] += r_waterripple.value * (1.0f / 64.0f) * turbsin[(int)((v->v[0]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255] * turbsin[(int)((v->v[1]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255];
+                       if (surf->flags & SURF_DRAWFULLBRIGHT)
+                       {
+                               sv->c[0] = 1;
+                               sv->c[1] = 1;
+                               sv->c[2] = 1;
+                               sv->c[3] = alpha;
+                       }
+                       else
+                       {
+                               sv->c[0] = 0.5f;
+                               sv->c[1] = 0.5f;
+                               sv->c[2] = 0.5f;
+                               sv->c[3] = alpha;
+                       }
+                       sv->st[0] = (v->st[0] + turbsin[(int)((v->st[1]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f);
+                       sv->st[1] = (v->st[1] + turbsin[(int)((v->st[0]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f);
                }
-               sv->st[0] = (v->st[0] + turbsin[(int)((v->st[1]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f);
-               sv->st[1] = (v->st[1] + turbsin[(int)((v->st[0]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f);
-       }
-       if (surf->dlightframe == r_framecount && !(surf->flags & SURF_DRAWFULLBRIGHT))
-               RSurf_Light(surf->dlightbits, m.numverts);
-       if (fogenabled && (surf->flags & SURF_DRAWNOALPHA))
-       {
-               for (i = 0, sv = svert;i < m.numverts;i++, sv++)
+               if (surf->dlightframe == r_framecount && !(surf->flags & SURF_DRAWFULLBRIGHT))
+                       RSurf_Light(surf->dlightbits, m.numverts);
+               if (fogenabled && (surf->flags & SURF_DRAWNOALPHA))
                {
-                       VectorSubtract(sv->v, r_origin, diff);
-                       ifog = 1 - exp(fogdensity/DotProduct(diff, diff));
-                       sv->c[0] *= ifog;
-                       sv->c[1] *= ifog;
-                       sv->c[2] *= ifog;
+                       for (i = 0, sv = svert;i < m.numverts;i++, sv++)
+                       {
+                               VectorSubtract(sv->v, r_origin, diff);
+                               ifog = 1 - exp(fogdensity/DotProduct(diff, diff));
+                               sv->c[0] *= ifog;
+                               sv->c[1] *= ifog;
+                               sv->c[2] *= ifog;
+                       }
                }
+               R_Mesh_Draw(&m);
        }
-       R_Mesh_Draw(&m);
 }
 
 static void RSurfShader_Water_Pass_Glow(msurface_t *surf)
 {
-       int                             i;
-       float                   diff[3], alpha, ifog;
-       surfvertex_t    *v;
-       surfvert_t              *sv;
-       rmeshinfo_t             m;
+       int i;
+       float diff[3], alpha, ifog;
+       surfvertex_t *v;
+       surfvert_t *sv;
+       surfmesh_t *mesh;
+       rmeshinfo_t m;
        alpha = currentrenderentity->alpha * (surf->flags & SURF_DRAWNOALPHA ? 1 : r_wateralpha.value);
 
        memset(&m, 0, sizeof(m));
        m.transparent = alpha != 1 || surf->currenttexture->fogtexture != NULL;
        m.blendfunc1 = GL_SRC_ALPHA;
        m.blendfunc2 = GL_ONE;
-       m.numtriangles = surf->mesh.numtriangles;
-       m.numverts = surf->mesh.numverts;
-       m.index = surf->mesh.index;
        m.vertex = &svert[0].v[0];
        m.vertexstep = sizeof(surfvert_t);
        m.cr = 1;
@@ -791,56 +806,60 @@ static void RSurfShader_Water_Pass_Glow(msurface_t *surf)
        m.tex[0] = R_GetTexture(surf->currenttexture->glowtexture);
        m.texcoords[0] = &svert[0].st[0];
        m.texcoordstep[0] = sizeof(surfvert_t);
-       if (fogenabled)
+       for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
-               m.color = &svert[0].c[0];
-               m.colorstep = sizeof(surfvert_t);
-               for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++)
+               m.numtriangles = mesh->numtriangles;
+               m.numverts = mesh->numverts;
+               m.index = mesh->index;
+               if (fogenabled)
                {
-                       softwaretransform(v->v, sv->v);
-                       if (r_waterripple.value)
-                               sv->v[2] += r_waterripple.value * (1.0f / 64.0f) * turbsin[(int)((v->v[0]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255] * turbsin[(int)((v->v[1]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255];
-                       sv->st[0] = (v->st[0] + turbsin[(int)((v->st[1]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f);
-                       sv->st[1] = (v->st[1] + turbsin[(int)((v->st[0]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f);
-                       VectorSubtract(sv->v, r_origin, diff);
-                       ifog = 1 - exp(fogdensity/DotProduct(diff, diff));
-                       sv->c[0] = m.cr * ifog;
-                       sv->c[1] = m.cg * ifog;
-                       sv->c[2] = m.cb * ifog;
-                       sv->c[3] = m.ca;
+                       m.color = &svert[0].c[0];
+                       m.colorstep = sizeof(surfvert_t);
+                       for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++)
+                       {
+                               softwaretransform(v->v, sv->v);
+                               if (r_waterripple.value)
+                                       sv->v[2] += r_waterripple.value * (1.0f / 64.0f) * turbsin[(int)((v->v[0]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255] * turbsin[(int)((v->v[1]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255];
+                               sv->st[0] = (v->st[0] + turbsin[(int)((v->st[1]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f);
+                               sv->st[1] = (v->st[1] + turbsin[(int)((v->st[0]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f);
+                               VectorSubtract(sv->v, r_origin, diff);
+                               ifog = 1 - exp(fogdensity/DotProduct(diff, diff));
+                               sv->c[0] = m.cr * ifog;
+                               sv->c[1] = m.cg * ifog;
+                               sv->c[2] = m.cb * ifog;
+                               sv->c[3] = m.ca;
+                       }
                }
-       }
-       else
-       {
-               for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++)
+               else
                {
-                       softwaretransform(v->v, sv->v);
-                       if (r_waterripple.value)
-                               sv->v[2] += r_waterripple.value * (1.0f / 64.0f) * turbsin[(int)((v->v[0]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255] * turbsin[(int)((v->v[1]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255];
-                       sv->st[0] = (v->st[0] + turbsin[(int)((v->st[1]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f);
-                       sv->st[1] = (v->st[1] + turbsin[(int)((v->st[0]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f);
+                       for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++)
+                       {
+                               softwaretransform(v->v, sv->v);
+                               if (r_waterripple.value)
+                                       sv->v[2] += r_waterripple.value * (1.0f / 64.0f) * turbsin[(int)((v->v[0]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255] * turbsin[(int)((v->v[1]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255];
+                               sv->st[0] = (v->st[0] + turbsin[(int)((v->st[1]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f);
+                               sv->st[1] = (v->st[1] + turbsin[(int)((v->st[0]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f);
+                       }
                }
+               R_Mesh_Draw(&m);
        }
-       R_Mesh_Draw(&m);
 }
 
 static void RSurfShader_Water_Pass_Fog(msurface_t *surf)
 {
-       int                             i;
-       float                   alpha;
-       surfvertex_t    *v;
-       surfvert_t              *sv;
-       rmeshinfo_t             m;
-       vec3_t                  diff;
+       int i;
+       float alpha;
+       surfvertex_t *v;
+       surfvert_t *sv;
+       surfmesh_t *mesh;
+       rmeshinfo_t m;
+       vec3_t diff;
        alpha = currentrenderentity->alpha * (surf->flags & SURF_DRAWNOALPHA ? 1 : r_wateralpha.value);
 
        memset(&m, 0, sizeof(m));
        m.transparent = alpha != 1 || surf->currenttexture->fogtexture != NULL;
        m.blendfunc1 = GL_SRC_ALPHA;
        m.blendfunc2 = GL_ONE;
-       m.numtriangles = surf->mesh.numtriangles;
-       m.numverts = surf->mesh.numverts;
-       m.index = surf->mesh.index;
        m.vertex = &svert[0].v[0];
        m.vertexstep = sizeof(surfvert_t);
        m.color = &svert[0].c[0];
@@ -849,23 +868,29 @@ static void RSurfShader_Water_Pass_Fog(msurface_t *surf)
        m.texcoords[0] = &svert[0].st[0];
        m.texcoordstep[0] = sizeof(surfvert_t);
 
-       for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++)
+       for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
-               softwaretransform(v->v, sv->v);
-               if (r_waterripple.value)
-                       sv->v[2] += r_waterripple.value * (1.0f / 64.0f) * turbsin[(int)((v->v[0]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255] * turbsin[(int)((v->v[1]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255];
-               if (m.tex[0])
+               m.numtriangles = mesh->numtriangles;
+               m.numverts = mesh->numverts;
+               m.index = mesh->index;
+               for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++)
                {
-                       sv->st[0] = (v->st[0] + turbsin[(int)((v->st[1]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f);
-                       sv->st[1] = (v->st[1] + turbsin[(int)((v->st[0]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f);
+                       softwaretransform(v->v, sv->v);
+                       if (r_waterripple.value)
+                               sv->v[2] += r_waterripple.value * (1.0f / 64.0f) * turbsin[(int)((v->v[0]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255] * turbsin[(int)((v->v[1]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255];
+                       if (m.tex[0])
+                       {
+                               sv->st[0] = (v->st[0] + turbsin[(int)((v->st[1]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f);
+                               sv->st[1] = (v->st[1] + turbsin[(int)((v->st[0]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f);
+                       }
+                       VectorSubtract(sv->v, r_origin, diff);
+                       sv->c[0] = fogcolor[0];
+                       sv->c[1] = fogcolor[1];
+                       sv->c[2] = fogcolor[2];
+                       sv->c[3] = alpha * exp(fogdensity/DotProduct(diff, diff));
                }
-               VectorSubtract(sv->v, r_origin, diff);
-               sv->c[0] = fogcolor[0];
-               sv->c[1] = fogcolor[1];
-               sv->c[2] = fogcolor[2];
-               sv->c[3] = alpha * exp(fogdensity/DotProduct(diff, diff));
+               R_Mesh_Draw(&m);
        }
-       R_Mesh_Draw(&m);
 }
 
 static void RSurfShader_Water(msurface_t *firstsurf)
@@ -884,11 +909,12 @@ static void RSurfShader_Water(msurface_t *firstsurf)
 
 static void RSurfShader_Wall_Pass_BaseMTex(msurface_t *surf)
 {
-       int                             i;
-       float                   diff[3], ifog;
-       surfvertex_t    *v;
-       surfvert_t              *sv;
-       rmeshinfo_t             m;
+       int i;
+       float diff[3], ifog;
+       surfvertex_t *v;
+       surfvert_t *sv;
+       surfmesh_t *mesh;
+       rmeshinfo_t m;
 
        memset(&m, 0, sizeof(m));
        if (currentrenderentity->effects & EF_ADDITIVE)
@@ -909,173 +935,184 @@ static void RSurfShader_Wall_Pass_BaseMTex(msurface_t *surf)
                m.blendfunc1 = GL_ONE;
                m.blendfunc2 = GL_ZERO;
        }
-       m.numtriangles = surf->mesh.numtriangles;
-       m.numverts = surf->mesh.numverts;
-       m.index = surf->mesh.index;
        m.cr = m.cg = m.cb = (float) (1 << lightscalebit);
        m.ca = currentrenderentity->alpha;
        m.tex[0] = R_GetTexture(surf->currenttexture->texture);
        m.tex[1] = R_GetTexture(surf->lightmaptexture);
-       m.texcoords[0] = &surf->mesh.vertex->st[0];
-       m.texcoords[1] = &surf->mesh.vertex->uv[0];
        m.texcoordstep[0] = sizeof(surfvertex_t);
        m.texcoordstep[1] = sizeof(surfvertex_t);
-       if (fogenabled)
+       for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
-               m.color = &svert[0].c[0];
-               m.colorstep = sizeof(surfvert_t);
-               if (softwaretransform_complexity)
+               m.numtriangles = mesh->numtriangles;
+               m.numverts = mesh->numverts;
+               m.index = mesh->index;
+               m.texcoords[0] = &mesh->vertex->st[0];
+               m.texcoords[1] = &mesh->vertex->uv[0];
+               if (fogenabled)
                {
-                       m.vertex = &svert[0].v[0];
-                       m.vertexstep = sizeof(surfvert_t);
-                       for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++)
+                       m.color = &svert[0].c[0];
+                       m.colorstep = sizeof(surfvert_t);
+                       if (softwaretransform_complexity)
                        {
-                               softwaretransform(v->v, sv->v);
-                               VectorSubtract(sv->v, r_origin, diff);
-                               ifog = 1 - exp(fogdensity/DotProduct(diff, diff));
-                               sv->c[0] = m.cr * ifog;
-                               sv->c[1] = m.cg * ifog;
-                               sv->c[2] = m.cb * ifog;
-                               sv->c[3] = m.ca;
+                               m.vertex = &svert[0].v[0];
+                               m.vertexstep = sizeof(surfvert_t);
+                               for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++)
+                               {
+                                       softwaretransform(v->v, sv->v);
+                                       VectorSubtract(sv->v, r_origin, diff);
+                                       ifog = 1 - exp(fogdensity/DotProduct(diff, diff));
+                                       sv->c[0] = m.cr * ifog;
+                                       sv->c[1] = m.cg * ifog;
+                                       sv->c[2] = m.cb * ifog;
+                                       sv->c[3] = m.ca;
+                               }
                        }
-               }
-               else
-               {
-                       m.vertex = &surf->mesh.vertex->v[0];
-                       m.vertexstep = sizeof(surfvertex_t);
-                       for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++)
+                       else
                        {
-                               VectorSubtract(v->v, r_origin, diff);
-                               ifog = 1 - exp(fogdensity/DotProduct(diff, diff));
-                               sv->c[0] = m.cr * ifog;
-                               sv->c[1] = m.cg * ifog;
-                               sv->c[2] = m.cb * ifog;
-                               sv->c[3] = m.ca;
+                               m.vertex = &mesh->vertex->v[0];
+                               m.vertexstep = sizeof(surfvertex_t);
+                               for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++)
+                               {
+                                       VectorSubtract(v->v, r_origin, diff);
+                                       ifog = 1 - exp(fogdensity/DotProduct(diff, diff));
+                                       sv->c[0] = m.cr * ifog;
+                                       sv->c[1] = m.cg * ifog;
+                                       sv->c[2] = m.cb * ifog;
+                                       sv->c[3] = m.ca;
+                               }
                        }
                }
-       }
-       else
-       {
-               if (softwaretransform_complexity)
-               {
-                       m.vertex = &svert[0].v[0];
-                       m.vertexstep = sizeof(surfvert_t);
-                       for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++)
-                               softwaretransform(v->v, sv->v);
-               }
                else
                {
-                       m.vertex = &surf->mesh.vertex->v[0];
-                       m.vertexstep = sizeof(surfvertex_t);
+                       if (softwaretransform_complexity)
+                       {
+                               m.vertex = &svert[0].v[0];
+                               m.vertexstep = sizeof(surfvert_t);
+                               for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++)
+                                       softwaretransform(v->v, sv->v);
+                       }
+                       else
+                       {
+                               m.vertex = &mesh->vertex->v[0];
+                               m.vertexstep = sizeof(surfvertex_t);
+                       }
                }
+               R_Mesh_Draw(&m);
        }
-       R_Mesh_Draw(&m);
 }
 
 static void RSurfShader_Wall_Pass_BaseTexture(msurface_t *surf)
 {
-       int                             i;
-       surfvertex_t    *v;
-       surfvert_t              *sv;
-       rmeshinfo_t             m;
+       int i;
+       surfvertex_t *v;
+       surfvert_t *sv;
+       surfmesh_t *mesh;
+       rmeshinfo_t m;
 
        memset(&m, 0, sizeof(m));
        m.transparent = false;
        m.blendfunc1 = GL_ONE;
        m.blendfunc2 = GL_ZERO;
-       m.numtriangles = surf->mesh.numtriangles;
-       m.numverts = surf->mesh.numverts;
-       m.index = surf->mesh.index;
        m.cr = m.cg = m.cb = (float) (1 << v_overbrightbits.integer);
        m.ca = 1;
        m.tex[0] = R_GetTexture(surf->currenttexture->texture);
-       m.texcoords[0] = &surf->mesh.vertex->st[0];
        m.texcoordstep[0] = sizeof(surfvertex_t);
-       if (softwaretransform_complexity)
-       {
-               m.vertex = &svert[0].v[0];
-               m.vertexstep = sizeof(surfvert_t);
-               for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++)
-                       softwaretransform(v->v, sv->v);
-       }
-       else
+       for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
-               m.vertex = &surf->mesh.vertex->v[0];
-               m.vertexstep = sizeof(surfvertex_t);
+               m.numtriangles = mesh->numtriangles;
+               m.numverts = mesh->numverts;
+               m.index = mesh->index;
+               m.texcoords[0] = &mesh->vertex->st[0];
+               if (softwaretransform_complexity)
+               {
+                       m.vertex = &svert[0].v[0];
+                       m.vertexstep = sizeof(surfvert_t);
+                       for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++)
+                               softwaretransform(v->v, sv->v);
+               }
+               else
+               {
+                       m.vertex = &mesh->vertex->v[0];
+                       m.vertexstep = sizeof(surfvertex_t);
+               }
+               R_Mesh_Draw(&m);
        }
-       R_Mesh_Draw(&m);
 }
 
 static void RSurfShader_Wall_Pass_BaseLightmap(msurface_t *surf)
 {
-       int                             i;
-       float                   diff[3], ifog;
-       surfvertex_t    *v;
-       surfvert_t              *sv;
-       rmeshinfo_t             m;
+       int i;
+       float diff[3], ifog;
+       surfvertex_t *v;
+       surfvert_t *sv;
+       surfmesh_t *mesh;
+       rmeshinfo_t m;
 
        memset(&m, 0, sizeof(m));
        m.transparent = false;
        m.blendfunc1 = GL_ZERO;
        m.blendfunc2 = GL_SRC_COLOR;
-       m.numtriangles = surf->mesh.numtriangles;
-       m.numverts = surf->mesh.numverts;
-       m.index = surf->mesh.index;
        m.cr = m.cg = m.cb = (float) (1 << v_overbrightbits.integer);
        m.ca = 1;
        m.tex[0] = R_GetTexture(surf->lightmaptexture);
-       m.texcoords[0] = &surf->mesh.vertex->uv[0];
        m.texcoordstep[0] = sizeof(surfvertex_t);
-       if (fogenabled)
+       for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
-               m.color = &svert[0].c[0];
-               m.colorstep = sizeof(surfvert_t);
-               if (softwaretransform_complexity)
+               m.numtriangles = mesh->numtriangles;
+               m.numverts = mesh->numverts;
+               m.index = mesh->index;
+               m.texcoords[0] = &mesh->vertex->uv[0];
+               if (fogenabled)
                {
-                       m.vertex = &svert[0].v[0];
-                       m.vertexstep = sizeof(surfvert_t);
-                       for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++)
+                       m.color = &svert[0].c[0];
+                       m.colorstep = sizeof(surfvert_t);
+                       if (softwaretransform_complexity)
                        {
-                               softwaretransform(v->v, sv->v);
-                               VectorSubtract(sv->v, r_origin, diff);
-                               ifog = 1 - exp(fogdensity/DotProduct(diff, diff));
-                               sv->c[0] = m.cr * ifog;
-                               sv->c[1] = m.cg * ifog;
-                               sv->c[2] = m.cb * ifog;
-                               sv->c[3] = m.ca;
+                               m.vertex = &svert[0].v[0];
+                               m.vertexstep = sizeof(surfvert_t);
+                               for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++)
+                               {
+                                       softwaretransform(v->v, sv->v);
+                                       VectorSubtract(sv->v, r_origin, diff);
+                                       ifog = 1 - exp(fogdensity/DotProduct(diff, diff));
+                                       sv->c[0] = m.cr * ifog;
+                                       sv->c[1] = m.cg * ifog;
+                                       sv->c[2] = m.cb * ifog;
+                                       sv->c[3] = m.ca;
+                               }
                        }
-               }
-               else
-               {
-                       m.vertex = &surf->mesh.vertex->v[0];
-                       m.vertexstep = sizeof(surfvertex_t);
-                       for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++)
+                       else
                        {
-                               VectorSubtract(v->v, r_origin, diff);
-                               ifog = 1 - exp(fogdensity/DotProduct(diff, diff));
-                               sv->c[0] = m.cr * ifog;
-                               sv->c[1] = m.cg * ifog;
-                               sv->c[2] = m.cb * ifog;
-                               sv->c[3] = m.ca;
+                               m.vertex = &mesh->vertex->v[0];
+                               m.vertexstep = sizeof(surfvertex_t);
+                               for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++)
+                               {
+                                       VectorSubtract(v->v, r_origin, diff);
+                                       ifog = 1 - exp(fogdensity/DotProduct(diff, diff));
+                                       sv->c[0] = m.cr * ifog;
+                                       sv->c[1] = m.cg * ifog;
+                                       sv->c[2] = m.cb * ifog;
+                                       sv->c[3] = m.ca;
+                               }
                        }
                }
-       }
-       else
-       {
-               if (softwaretransform_complexity)
-               {
-                       m.vertex = &svert[0].v[0];
-                       m.vertexstep = sizeof(surfvert_t);
-                       for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++)
-                               softwaretransform(v->v, sv->v);
-               }
                else
                {
-                       m.vertex = &surf->mesh.vertex->v[0];
-                       m.vertexstep = sizeof(surfvertex_t);
+                       if (softwaretransform_complexity)
+                       {
+                               m.vertex = &svert[0].v[0];
+                               m.vertexstep = sizeof(surfvert_t);
+                               for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++)
+                                       softwaretransform(v->v, sv->v);
+                       }
+                       else
+                       {
+                               m.vertex = &mesh->vertex->v[0];
+                               m.vertexstep = sizeof(surfvertex_t);
+                       }
                }
+               R_Mesh_Draw(&m);
        }
-       R_Mesh_Draw(&m);
 }
 
 static void RSurfShader_Wall_Pass_BaseVertex(msurface_t *surf)
@@ -1084,6 +1121,7 @@ static void RSurfShader_Wall_Pass_BaseVertex(msurface_t *surf)
        float c[3], base[3], scale, diff[3], ifog;
        surfvertex_t *v;
        surfvert_t *sv;
+       surfmesh_t *mesh;
        rmeshinfo_t m;
        qbyte *lm;
 
@@ -1110,72 +1148,76 @@ static void RSurfShader_Wall_Pass_BaseVertex(msurface_t *surf)
                m.blendfunc1 = GL_ONE;
                m.blendfunc2 = GL_ZERO;
        }
-       m.numtriangles = surf->mesh.numtriangles;
-       m.numverts = surf->mesh.numverts;
-       m.index = surf->mesh.index;
        m.vertex = &svert[0].v[0];
        m.vertexstep = sizeof(surfvert_t);
        m.color = &svert[0].c[0];
        m.colorstep = sizeof(surfvert_t);
        m.tex[0] = R_GetTexture(surf->currenttexture->texture);
-       m.texcoords[0] = &surf->mesh.vertex->st[0];
        m.texcoordstep[0] = sizeof(surfvertex_t);
-       for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++)
+       for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
-               softwaretransform(v->v, sv->v);
-               VectorCopy(base, c);
-               if (surf->styles[0] != 255)
+               m.numtriangles = mesh->numtriangles;
+               m.numverts = mesh->numverts;
+               m.index = mesh->index;
+               m.texcoords[0] = &mesh->vertex->st[0];
+               for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++)
                {
-                       lm = surf->samples + v->lightmapoffset;
-                       scale = d_lightstylevalue[surf->styles[0]] * (1.0f / 32768.0f);
-                       VectorMA(c, scale, lm, c);
-                       if (surf->styles[1] != 255)
+                       softwaretransform(v->v, sv->v);
+                       VectorCopy(base, c);
+                       if (surf->styles[0] != 255)
                        {
-                               lm += size3;
-                               scale = d_lightstylevalue[surf->styles[1]] * (1.0f / 32768.0f);
+                               lm = surf->samples + v->lightmapoffset;
+                               scale = d_lightstylevalue[surf->styles[0]] * (1.0f / 32768.0f);
                                VectorMA(c, scale, lm, c);
-                               if (surf->styles[2] != 255)
+                               if (surf->styles[1] != 255)
                                {
                                        lm += size3;
-                                       scale = d_lightstylevalue[surf->styles[2]] * (1.0f / 32768.0f);
+                                       scale = d_lightstylevalue[surf->styles[1]] * (1.0f / 32768.0f);
                                        VectorMA(c, scale, lm, c);
-                                       if (surf->styles[3] != 255)
+                                       if (surf->styles[2] != 255)
                                        {
                                                lm += size3;
-                                               scale = d_lightstylevalue[surf->styles[3]] * (1.0f / 32768.0f);
+                                               scale = d_lightstylevalue[surf->styles[2]] * (1.0f / 32768.0f);
                                                VectorMA(c, scale, lm, c);
+                                               if (surf->styles[3] != 255)
+                                               {
+                                                       lm += size3;
+                                                       scale = d_lightstylevalue[surf->styles[3]] * (1.0f / 32768.0f);
+                                                       VectorMA(c, scale, lm, c);
+                                               }
                                        }
                                }
                        }
+                       sv->c[0] = c[0];
+                       sv->c[1] = c[1];
+                       sv->c[2] = c[2];
+                       sv->c[3] = currentrenderentity->alpha;
                }
-               sv->c[0] = c[0];
-               sv->c[1] = c[1];
-               sv->c[2] = c[2];
-               sv->c[3] = currentrenderentity->alpha;
-       }
-       if (surf->dlightframe == r_framecount)
-               RSurf_Light(surf->dlightbits, m.numverts);
-       if (fogenabled)
-       {
-               for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++)
+               if (surf->dlightframe == r_framecount)
+                       RSurf_Light(surf->dlightbits, m.numverts);
+               if (fogenabled)
                {
-                       VectorSubtract(sv->v, r_origin, diff);
-                       ifog = 1 - exp(fogdensity/DotProduct(diff, diff));
-                       sv->c[0] *= ifog;
-                       sv->c[1] *= ifog;
-                       sv->c[2] *= ifog;
+                       for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++)
+                       {
+                               VectorSubtract(sv->v, r_origin, diff);
+                               ifog = 1 - exp(fogdensity/DotProduct(diff, diff));
+                               sv->c[0] *= ifog;
+                               sv->c[1] *= ifog;
+                               sv->c[2] *= ifog;
+                       }
                }
+               R_Mesh_Draw(&m);
        }
-       R_Mesh_Draw(&m);
 }
 
 static void RSurfShader_Wall_Pass_BaseFullbright(msurface_t *surf)
 {
-       int                             i;
-       float                   diff[3], ifog;
-       surfvertex_t    *v;
-       surfvert_t              *sv;
-       rmeshinfo_t             m;
+       int i;
+       float diff[3], ifog;
+       surfvertex_t *v;
+       surfvert_t *sv;
+       surfmesh_t *mesh;
+       rmeshinfo_t m;
 
        memset(&m, 0, sizeof(m));
        if (currentrenderentity->effects & EF_ADDITIVE)
@@ -1196,46 +1238,50 @@ static void RSurfShader_Wall_Pass_BaseFullbright(msurface_t *surf)
                m.blendfunc1 = GL_ONE;
                m.blendfunc2 = GL_ZERO;
        }
-       m.numtriangles = surf->mesh.numtriangles;
-       m.numverts = surf->mesh.numverts;
-       m.index = surf->mesh.index;
        m.vertex = &svert[0].v[0];
        m.vertexstep = sizeof(surfvert_t);
        m.tex[0] = R_GetTexture(surf->currenttexture->texture);
-       m.texcoords[0] = &surf->mesh.vertex->st[0];
        m.texcoordstep[0] = sizeof(surfvertex_t);
-       if (fogenabled)
+       for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
-               m.color = &svert[0].c[0];
-               m.colorstep = sizeof(surfvert_t);
-               for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++)
+               m.numtriangles = mesh->numtriangles;
+               m.numverts = mesh->numverts;
+               m.index = mesh->index;
+               m.texcoords[0] = &mesh->vertex->st[0];
+               if (fogenabled)
                {
-                       softwaretransform(v->v, sv->v);
-                       VectorSubtract(sv->v, r_origin, diff);
-                       ifog = 1 - exp(fogdensity/DotProduct(diff, diff));
-                       sv->c[0] = ifog;
-                       sv->c[1] = ifog;
-                       sv->c[2] = ifog;
-                       sv->c[3] = currentrenderentity->alpha;
+                       m.color = &svert[0].c[0];
+                       m.colorstep = sizeof(surfvert_t);
+                       for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++)
+                       {
+                               softwaretransform(v->v, sv->v);
+                               VectorSubtract(sv->v, r_origin, diff);
+                               ifog = 1 - exp(fogdensity/DotProduct(diff, diff));
+                               sv->c[0] = ifog;
+                               sv->c[1] = ifog;
+                               sv->c[2] = ifog;
+                               sv->c[3] = currentrenderentity->alpha;
+                       }
                }
+               else
+               {
+                       m.cr = m.cg = m.cb = 1;
+                       m.ca = currentrenderentity->alpha;
+                       for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++)
+                               softwaretransform(v->v, sv->v);
+               }
+               R_Mesh_Draw(&m);
        }
-       else
-       {
-               m.cr = m.cg = m.cb = 1;
-               m.ca = currentrenderentity->alpha;
-               for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++)
-                       softwaretransform(v->v, sv->v);
-       }
-       R_Mesh_Draw(&m);
 }
 
 static void RSurfShader_Wall_Pass_Light(msurface_t *surf)
 {
-       int                             i;
-       float                   diff[3], ifog;
-       surfvertex_t    *v;
-       surfvert_t              *sv;
-       rmeshinfo_t             m;
+       int i;
+       float diff[3], ifog;
+       surfvertex_t *v;
+       surfvert_t *sv;
+       surfmesh_t *mesh;
+       rmeshinfo_t m;
 
        memset(&m, 0, sizeof(m));
        if (currentrenderentity->effects & EF_ADDITIVE)
@@ -1246,48 +1292,52 @@ static void RSurfShader_Wall_Pass_Light(msurface_t *surf)
                m.transparent = false;
        m.blendfunc1 = GL_SRC_ALPHA;
        m.blendfunc2 = GL_ONE;
-       m.numtriangles = surf->mesh.numtriangles;
-       m.numverts = surf->mesh.numverts;
-       m.index = surf->mesh.index;
        m.vertex = &svert[0].v[0];
        m.vertexstep = sizeof(surfvert_t);
        m.color = &svert[0].c[0];
        m.colorstep = sizeof(surfvert_t);
        m.tex[0] = R_GetTexture(surf->currenttexture->texture);
-       m.texcoords[0] = &surf->mesh.vertex->st[0];
        m.texcoordstep[0] = sizeof(surfvertex_t);
-       for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++)
-       {
-               softwaretransform(v->v, sv->v);
-               sv->c[0] = 0;
-               sv->c[1] = 0;
-               sv->c[2] = 0;
-               sv->c[3] = currentrenderentity->alpha;
-       }
-       if (RSurf_Light(surf->dlightbits, m.numverts))
+       for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
-               if (fogenabled)
+               m.numtriangles = mesh->numtriangles;
+               m.numverts = mesh->numverts;
+               m.index = mesh->index;
+               m.texcoords[0] = &mesh->vertex->st[0];
+               for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++)
                {
-                       for (i = 0, sv = svert;i < m.numverts;i++, sv++)
+                       softwaretransform(v->v, sv->v);
+                       sv->c[0] = 0;
+                       sv->c[1] = 0;
+                       sv->c[2] = 0;
+                       sv->c[3] = currentrenderentity->alpha;
+               }
+               if (RSurf_Light(surf->dlightbits, m.numverts))
+               {
+                       if (fogenabled)
                        {
-                               VectorSubtract(sv->v, r_origin, diff);
-                               ifog = 1 - exp(fogdensity/DotProduct(diff, diff));
-                               sv->c[0] *= ifog;
-                               sv->c[1] *= ifog;
-                               sv->c[2] *= ifog;
+                               for (i = 0, sv = svert;i < m.numverts;i++, sv++)
+                               {
+                                       VectorSubtract(sv->v, r_origin, diff);
+                                       ifog = 1 - exp(fogdensity/DotProduct(diff, diff));
+                                       sv->c[0] *= ifog;
+                                       sv->c[1] *= ifog;
+                                       sv->c[2] *= ifog;
+                               }
                        }
+                       R_Mesh_Draw(&m);
                }
-               R_Mesh_Draw(&m);
        }
 }
 
 static void RSurfShader_Wall_Pass_Glow(msurface_t *surf)
 {
-       int                             i;
-       float                   diff[3], ifog;
-       surfvertex_t    *v;
-       surfvert_t              *sv;
-       rmeshinfo_t             m;
+       int i;
+       float diff[3], ifog;
+       surfvertex_t *v;
+       surfvert_t *sv;
+       surfmesh_t *mesh;
+       rmeshinfo_t m;
 
        memset(&m, 0, sizeof(m));
        if (currentrenderentity->effects & EF_ADDITIVE)
@@ -1298,75 +1348,79 @@ static void RSurfShader_Wall_Pass_Glow(msurface_t *surf)
                m.transparent = false;
        m.blendfunc1 = GL_SRC_ALPHA;
        m.blendfunc2 = GL_ONE;
-       m.numtriangles = surf->mesh.numtriangles;
-       m.numverts = surf->mesh.numverts;
-       m.index = surf->mesh.index;
        m.cr = 1;
        m.cg = 1;
        m.cb = 1;
        m.ca = currentrenderentity->alpha;
        m.tex[0] = R_GetTexture(surf->currenttexture->glowtexture);
-       m.texcoords[0] = &surf->mesh.vertex->st[0];
        m.texcoordstep[0] = sizeof(surfvertex_t);
-       if (fogenabled)
+       for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
-               m.color = &svert[0].c[0];
-               m.colorstep = sizeof(surfvert_t);
-               if (softwaretransform_complexity)
+               m.numtriangles = mesh->numtriangles;
+               m.numverts = mesh->numverts;
+               m.index = mesh->index;
+               m.texcoords[0] = &mesh->vertex->st[0];
+               if (fogenabled)
                {
-                       m.vertex = &svert[0].v[0];
-                       m.vertexstep = sizeof(surfvert_t);
-                       for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++)
+                       m.color = &svert[0].c[0];
+                       m.colorstep = sizeof(surfvert_t);
+                       if (softwaretransform_complexity)
                        {
-                               softwaretransform(v->v, sv->v);
-                               VectorSubtract(sv->v, r_origin, diff);
-                               ifog = 1 - exp(fogdensity/DotProduct(diff, diff));
-                               sv->c[0] = m.cr * ifog;
-                               sv->c[1] = m.cg * ifog;
-                               sv->c[2] = m.cb * ifog;
-                               sv->c[3] = m.ca;
+                               m.vertex = &svert[0].v[0];
+                               m.vertexstep = sizeof(surfvert_t);
+                               for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++)
+                               {
+                                       softwaretransform(v->v, sv->v);
+                                       VectorSubtract(sv->v, r_origin, diff);
+                                       ifog = 1 - exp(fogdensity/DotProduct(diff, diff));
+                                       sv->c[0] = m.cr * ifog;
+                                       sv->c[1] = m.cg * ifog;
+                                       sv->c[2] = m.cb * ifog;
+                                       sv->c[3] = m.ca;
+                               }
                        }
-               }
-               else
-               {
-                       m.vertex = &surf->mesh.vertex->v[0];
-                       m.vertexstep = sizeof(surfvertex_t);
-                       for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++)
+                       else
                        {
-                               VectorSubtract(v->v, r_origin, diff);
-                               ifog = 1 - exp(fogdensity/DotProduct(diff, diff));
-                               sv->c[0] = m.cr * ifog;
-                               sv->c[1] = m.cg * ifog;
-                               sv->c[2] = m.cb * ifog;
-                               sv->c[3] = m.ca;
+                               m.vertex = &mesh->vertex->v[0];
+                               m.vertexstep = sizeof(surfvertex_t);
+                               for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++)
+                               {
+                                       VectorSubtract(v->v, r_origin, diff);
+                                       ifog = 1 - exp(fogdensity/DotProduct(diff, diff));
+                                       sv->c[0] = m.cr * ifog;
+                                       sv->c[1] = m.cg * ifog;
+                                       sv->c[2] = m.cb * ifog;
+                                       sv->c[3] = m.ca;
+                               }
                        }
                }
-       }
-       else
-       {
-               if (softwaretransform_complexity)
-               {
-                       m.vertex = &svert[0].v[0];
-                       m.vertexstep = sizeof(surfvert_t);
-                       for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++)
-                               softwaretransform(v->v, sv->v);
-               }
                else
                {
-                       m.vertex = &surf->mesh.vertex->v[0];
-                       m.vertexstep = sizeof(surfvertex_t);
+                       if (softwaretransform_complexity)
+                       {
+                               m.vertex = &svert[0].v[0];
+                               m.vertexstep = sizeof(surfvert_t);
+                               for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++)
+                                       softwaretransform(v->v, sv->v);
+                       }
+                       else
+                       {
+                               m.vertex = &mesh->vertex->v[0];
+                               m.vertexstep = sizeof(surfvertex_t);
+                       }
                }
+               R_Mesh_Draw(&m);
        }
-       R_Mesh_Draw(&m);
 }
 
 static void RSurfShader_Wall_Pass_Fog(msurface_t *surf)
 {
-       int                             i;
-       surfvertex_t    *v;
-       surfvert_t              *sv;
-       rmeshinfo_t             m;
-       vec3_t                  diff;
+       int i;
+       surfvertex_t *v;
+       surfvert_t *sv;
+       rmeshinfo_t m;
+       surfmesh_t *mesh;
+       vec3_t diff;
 
        memset(&m, 0, sizeof(m));
        if (currentrenderentity->effects & EF_ADDITIVE)
@@ -1377,42 +1431,45 @@ static void RSurfShader_Wall_Pass_Fog(msurface_t *surf)
                m.transparent = false;
        m.blendfunc1 = GL_SRC_ALPHA;
        m.blendfunc2 = GL_ONE;
-       m.numtriangles = surf->mesh.numtriangles;
-       m.numverts = surf->mesh.numverts;
-       m.index = surf->mesh.index;
        m.color = &svert[0].c[0];
        m.colorstep = sizeof(surfvert_t);
        m.tex[0] = R_GetTexture(surf->currenttexture->fogtexture);
-       m.texcoords[0] = &surf->mesh.vertex->st[0];
        m.texcoordstep[0] = sizeof(surfvertex_t);
-       if (softwaretransform_complexity)
+       for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
-               m.vertex = &svert[0].v[0];
-               m.vertexstep = sizeof(surfvert_t);
-               for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++)
+               m.numtriangles = mesh->numtriangles;
+               m.numverts = mesh->numverts;
+               m.index = mesh->index;
+               m.texcoords[0] = &mesh->vertex->st[0];
+               if (softwaretransform_complexity)
                {
-                       softwaretransform(v->v, sv->v);
-                       VectorSubtract(sv->v, r_origin, diff);
-                       sv->c[0] = fogcolor[0];
-                       sv->c[1] = fogcolor[1];
-                       sv->c[2] = fogcolor[2];
-                       sv->c[3] = currentrenderentity->alpha * exp(fogdensity/DotProduct(diff,diff));
+                       m.vertex = &svert[0].v[0];
+                       m.vertexstep = sizeof(surfvert_t);
+                       for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++)
+                       {
+                               softwaretransform(v->v, sv->v);
+                               VectorSubtract(sv->v, r_origin, diff);
+                               sv->c[0] = fogcolor[0];
+                               sv->c[1] = fogcolor[1];
+                               sv->c[2] = fogcolor[2];
+                               sv->c[3] = currentrenderentity->alpha * exp(fogdensity/DotProduct(diff,diff));
+                       }
                }
-       }
-       else
-       {
-               m.vertex = &surf->mesh.vertex->v[0];
-               m.vertexstep = sizeof(surfvertex_t);
-               for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++)
+               else
                {
-                       VectorSubtract(v->v, r_origin, diff);
-                       sv->c[0] = fogcolor[0];
-                       sv->c[1] = fogcolor[1];
-                       sv->c[2] = fogcolor[2];
-                       sv->c[3] = currentrenderentity->alpha * exp(fogdensity/DotProduct(diff,diff));
+                       m.vertex = &mesh->vertex->v[0];
+                       m.vertexstep = sizeof(surfvertex_t);
+                       for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++)
+                       {
+                               VectorSubtract(v->v, r_origin, diff);
+                               sv->c[0] = fogcolor[0];
+                               sv->c[1] = fogcolor[1];
+                               sv->c[2] = fogcolor[2];
+                               sv->c[3] = currentrenderentity->alpha * exp(fogdensity/DotProduct(diff,diff));
+                       }
                }
+               R_Mesh_Draw(&m);
        }
-       R_Mesh_Draw(&m);
 }
 
 static void RSurfShader_Wall_Fullbright(msurface_t *firstsurf)
index 0c87d8b..5aecaa7 100644 (file)
@@ -586,9 +586,9 @@ void Mod_LoadLightList(void)
                        }
                        e = loadmodel->lights + n;
                        *s = 0;
-                       a = sscanf(t, "%f %f %f %f %f %f %f %f %f %f %f %f %d", &e->origin[0], &e->origin[1], &e->origin[2], &e->falloff, &e->light[0], &e->light[1], &e->light[2], &e->subtract, &e->spotdir[0], &e->spotdir[1], &e->spotdir[2], &e->spotcone, &e->style);
+                       a = sscanf(t, "%f %f %f %f %f %f %f %f %f %f %f %f %f %d", &e->origin[0], &e->origin[1], &e->origin[2], &e->falloff, &e->light[0], &e->light[1], &e->light[2], &e->subtract, &e->spotdir[0], &e->spotdir[1], &e->spotdir[2], &e->spotcone, &e->distbias, &e->style);
                        *s = '\n';
-                       if (a != 13)
+                       if (a != 14)
                        {
                                Mem_Free(lightsstring);
                                Host_Error("invalid lights file, found %d parameters on line %i, should be 13 parameters (origin[0] origin[1] origin[2] falloff light[0] light[1] light[2] subtract spotdir[0] spotdir[1] spotdir[2] spotcone style)\n", a, n + 1);
@@ -1028,14 +1028,14 @@ void Mod_GenerateWarpMesh (msurface_t *surf)
        subdivpolytriangles = 0;
        subdivpolyverts = 0;
        SubdividePolygon (surf->poly_numverts, surf->poly_verts);
+       if (subdivpolytriangles < 1)
+               Host_Error("Mod_GenerateWarpMesh: no triangles?\n");
 
-       mesh = &surf->mesh;
+       surf->mesh = mesh = Mem_Alloc(loadmodel->mempool, sizeof(surfmesh_t) + subdivpolytriangles * sizeof(int[3]) + subdivpolyverts * sizeof(surfvertex_t));
        mesh->numverts = subdivpolyverts;
        mesh->numtriangles = subdivpolytriangles;
-       if (mesh->numtriangles < 1)
-               Host_Error("Mod_GenerateWarpMesh: no triangles?\n");
-       mesh->index = Mem_Alloc(loadmodel->mempool, mesh->numtriangles * sizeof(int[3]) + mesh->numverts * sizeof(surfvertex_t));
-       mesh->vertex = (surfvertex_t *)((qbyte *) mesh->index + mesh->numtriangles * sizeof(int[3]));
+       mesh->vertex = (surfvertex_t *)(mesh + 1);
+       mesh->index = (int *)(mesh->vertex + mesh->numverts);
        memset(mesh->vertex, 0, mesh->numverts * sizeof(surfvertex_t));
 
        for (i = 0;i < mesh->numtriangles;i++)
@@ -1069,11 +1069,11 @@ void Mod_GenerateVertexLitMesh (msurface_t *surf)
        surf->lightmaptexturestride = 0;
        surf->lightmaptexture = NULL;
 
-       mesh = &surf->mesh;
+       surf->mesh = mesh = Mem_Alloc(loadmodel->mempool, sizeof(surfmesh_t) + (surf->poly_numverts - 2) * sizeof(int[3]) + surf->poly_numverts * sizeof(surfvertex_t));
        mesh->numverts = surf->poly_numverts;
        mesh->numtriangles = surf->poly_numverts - 2;
-       mesh->index = Mem_Alloc(loadmodel->mempool, mesh->numtriangles * sizeof(int[3]) + mesh->numverts * sizeof(surfvertex_t));
-       mesh->vertex = (surfvertex_t *)((qbyte *) mesh->index + mesh->numtriangles * sizeof(int[3]));
+       mesh->vertex = (surfvertex_t *)(mesh + 1);
+       mesh->index = (int *)(mesh->vertex + mesh->numverts);
        memset(mesh->vertex, 0, mesh->numverts * sizeof(surfvertex_t));
 
        index = mesh->index;
@@ -1136,11 +1136,11 @@ void Mod_GenerateLightmappedMesh (msurface_t *surf)
        xscale = (xscale - xbase) * 16.0 / ((surf->extents[0] & ~15) + 16);
        yscale = (yscale - ybase) * 16.0 / ((surf->extents[1] & ~15) + 16);
 
-       mesh = &surf->mesh;
+       surf->mesh = mesh = Mem_Alloc(loadmodel->mempool, sizeof(surfmesh_t) + (surf->poly_numverts - 2) * sizeof(int[3]) + surf->poly_numverts * sizeof(surfvertex_t));
        mesh->numverts = surf->poly_numverts;
        mesh->numtriangles = surf->poly_numverts - 2;
-       mesh->index = Mem_Alloc(loadmodel->mempool, mesh->numtriangles * sizeof(int[3]) + mesh->numverts * sizeof(surfvertex_t));
-       mesh->vertex = (surfvertex_t *)((qbyte *) mesh->index + mesh->numtriangles * sizeof(int[3]));
+       mesh->vertex = (surfvertex_t *)(mesh + 1);
+       mesh->index = (int *)(mesh->vertex + mesh->numverts);
        memset(mesh->vertex, 0, mesh->numverts * sizeof(surfvertex_t));
 
        index = mesh->index;
@@ -1187,11 +1187,11 @@ void Mod_GenerateVertexMesh (msurface_t *surf)
        surf->lightmaptexturestride = 0;
        surf->lightmaptexture = NULL;
 
-       mesh = &surf->mesh;
+       surf->mesh = mesh = Mem_Alloc(loadmodel->mempool, sizeof(surfmesh_t) + (surf->poly_numverts - 2) * sizeof(int[3]) + surf->poly_numverts * sizeof(surfvertex_t));
        mesh->numverts = surf->poly_numverts;
        mesh->numtriangles = surf->poly_numverts - 2;
-       mesh->index = Mem_Alloc(loadmodel->mempool, mesh->numtriangles * sizeof(int[3]) + mesh->numverts * sizeof(surfvertex_t));
-       mesh->vertex = (surfvertex_t *)((qbyte *) mesh->index + mesh->numtriangles * sizeof(int[3]));
+       mesh->vertex = (surfvertex_t *)(mesh + 1);
+       mesh->index = (int *)(mesh->vertex + mesh->numverts);
        memset(mesh->vertex, 0, mesh->numverts * sizeof(surfvertex_t));
 
        index = mesh->index;
@@ -1232,6 +1232,55 @@ void Mod_GenerateSurfacePolygon (msurface_t *surf)
        }
 }
 
+static void Mod_SplitSurfMeshIfTooBig(msurface_t *s)
+{
+       int j, base, tricount, newvertexcount, *index, *vertexremap;
+       surfmesh_t *newmesh, *oldmesh, *firstmesh;
+       if (s->mesh->numtriangles > 1000)
+       {
+               vertexremap = Mem_Alloc(tempmempool, s->mesh->numverts * sizeof(int));
+               memset(vertexremap, -1, s->mesh->numverts * sizeof(int));
+               base = 0;
+               oldmesh = NULL;
+               firstmesh = NULL;
+               newmesh = NULL;
+               while (base < s->mesh->numtriangles)
+               {
+                       tricount = s->mesh->numtriangles - base;
+                       if (tricount > 1000)
+                               tricount = 1000;
+                       index = s->mesh->index + base * 3;
+                       base += tricount;
+
+                       newvertexcount = 0;
+                       for (j = 0;j < tricount * 3;j++)
+                               if (vertexremap[index[j]] < 0)
+                                       vertexremap[index[j]] = newvertexcount++;
+
+                       newmesh = Mem_Alloc(loadmodel->mempool, sizeof(surfmesh_t) + newvertexcount * sizeof(surfvertex_t) + tricount * sizeof(int[3]));
+                       newmesh->chain = NULL;
+                       newmesh->numverts = newvertexcount;
+                       newmesh->numtriangles = tricount;
+                       newmesh->vertex = (surfvertex_t *)(newmesh + 1);
+                       newmesh->index = (int *)(newmesh->vertex + newvertexcount);
+                       for (j = 0;j < tricount * 3;j++)
+                       {
+                               newmesh->index[j] = vertexremap[index[j]];
+                               // yes this copies the same vertex multiple times in many cases...  but that's ok...
+                               memcpy(&newmesh->vertex[newmesh->index[j]], &s->mesh->vertex[index[j]], sizeof(surfvertex_t));
+                       }
+                       if (oldmesh)
+                               oldmesh->chain = newmesh;
+                       else
+                               firstmesh = newmesh;
+                       oldmesh = newmesh;
+               }
+               Mem_Free(vertexremap);
+               Mem_Free(s->mesh);
+               s->mesh = firstmesh;
+       }
+}
+
 /*
 =================
 Mod_LoadFaces
@@ -1299,10 +1348,8 @@ static void Mod_LoadFaces (lump_t *l)
                        out->shader = &Cshader_sky;
                        out->samples = NULL;
                        Mod_GenerateWarpMesh (out);
-                       continue;
                }
-
-               if (out->texinfo->texture->flags & SURF_DRAWTURB)
+               else if (out->texinfo->texture->flags & SURF_DRAWTURB)
                {
                        out->shader = &Cshader_water;
                        /*
@@ -1314,43 +1361,45 @@ static void Mod_LoadFaces (lump_t *l)
                        */
                        out->samples = NULL;
                        Mod_GenerateWarpMesh (out);
-                       continue;
-               }
-
-               if (!R_TextureHasAlpha(out->texinfo->texture->texture))
-                       out->flags |= SURF_CLIPSOLID;
-               if (out->texinfo->flags & TEX_SPECIAL)
-               {
-                       // qbsp couldn't find the texture for this surface, but it was either turb or sky...  assume turb
-                       out->shader = &Cshader_water;
-                       out->shader = &Cshader_water;
-                       out->samples = NULL;
-                       Mod_GenerateWarpMesh (out);
-               }
-               else if ((out->extents[0]+1) > (256*16) || (out->extents[1]+1) > (256*16))
-               {
-                       Con_Printf ("Bad surface extents, converting to fullbright polygon");
-                       out->shader = &Cshader_wall_fullbright;
-                       out->samples = NULL;
-                       Mod_GenerateVertexMesh(out);
                }
                else
                {
-                       // stainmap for permanent marks on walls
-                       out->stainsamples = Mem_Alloc(loadmodel->mempool, ssize * tsize * 3);
-                       // clear to white
-                       memset(out->stainsamples, 255, ssize * tsize * 3);
-                       if (out->extents[0] < r_vertexsurfacesthreshold.integer && out->extents[1] < r_vertexsurfacesthreshold.integer)
+                       if (!R_TextureHasAlpha(out->texinfo->texture->texture))
+                               out->flags |= SURF_CLIPSOLID;
+                       if (out->texinfo->flags & TEX_SPECIAL)
+                       {
+                               // qbsp couldn't find the texture for this surface, but it was either turb or sky...  assume turb
+                               out->shader = &Cshader_water;
+                               out->shader = &Cshader_water;
+                               out->samples = NULL;
+                               Mod_GenerateWarpMesh (out);
+                       }
+                       else if ((out->extents[0]+1) > (256*16) || (out->extents[1]+1) > (256*16))
                        {
-                               out->shader = &Cshader_wall_vertex;
-                               Mod_GenerateVertexLitMesh(out);
+                               Con_Printf ("Bad surface extents, converting to fullbright polygon");
+                               out->shader = &Cshader_wall_fullbright;
+                               out->samples = NULL;
+                               Mod_GenerateVertexMesh(out);
                        }
                        else
                        {
-                               out->shader = &Cshader_wall_lightmap;
-                               Mod_GenerateLightmappedMesh(out);
+                               // stainmap for permanent marks on walls
+                               out->stainsamples = Mem_Alloc(loadmodel->mempool, ssize * tsize * 3);
+                               // clear to white
+                               memset(out->stainsamples, 255, ssize * tsize * 3);
+                               if (out->extents[0] < r_vertexsurfacesthreshold.integer && out->extents[1] < r_vertexsurfacesthreshold.integer)
+                               {
+                                       out->shader = &Cshader_wall_vertex;
+                                       Mod_GenerateVertexLitMesh(out);
+                               }
+                               else
+                               {
+                                       out->shader = &Cshader_wall_lightmap;
+                                       Mod_GenerateLightmappedMesh(out);
+                               }
                        }
                }
+               Mod_SplitSurfMeshIfTooBig(out);
        }
 }
 
index 1ab081b..40ea1a6 100644 (file)
@@ -111,6 +111,8 @@ surfvertex_t;
 // LordHavoc: replaces glpoly, triangle mesh
 typedef struct surfmesh_s
 {
+       // can be multiple meshs per surface
+       struct surfmesh_s *chain;
        int numverts;
        int numtriangles;
        surfvertex_t *vertex;
@@ -153,7 +155,7 @@ typedef struct msurface_s
        // the stride when building lightmaps to comply with fragment update
        int                     lightmaptexturestride;
        // mesh for rendering
-       surfmesh_t      mesh;
+       surfmesh_t      *mesh;
 
        // these are just 3D points defining the outline of the polygon,
        // no texcoord info (that can be generated from these)
@@ -285,6 +287,7 @@ typedef struct mlight_s
        float subtract;
        vec3_t spotdir;
        float spotcone; // cosine of spotlight cone angle (or 0 if not a spotlight)
+       float distbias;
        int style;
        int numleafs; // used only for loading calculations, number of leafs this shines on
 }
index 2e99dff..6860122 100644 (file)
--- a/r_light.c
+++ b/r_light.c
@@ -755,7 +755,7 @@ void R_CompleteLightPoint (vec3_t color, vec3_t p, int dynamic, mleaf_t *leaf)
                        if (d_lightstylevalue[sl->style] > 0)
                        {
                                VectorSubtract (p, sl->origin, dist);
-                               f = DotProduct(dist, dist) + 65536.0f;
+                               f = DotProduct(dist, dist) + sl->distbias;
                                f = (1.0f / f) - sl->subtract;
                                if (f > 0)
                                {
@@ -897,7 +897,7 @@ void R_LightModel(int numverts, float colorr, float colorg, float colorb, int wo
                                        VectorScale(sl->light, f, nl->light);
                                        nl->cullradius2 = 99999999;
                                        nl->lightsubtract = sl->subtract;
-                                       nl->offset = 65536.0f;
+                                       nl->offset = sl->distbias;
                                        nl++;
                                        nearlights++;
                                }