]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_rsurf.c
made the Sorted Edge Rasterizer (hidden surface removal) optional as the r_ser cvar...
[xonotic/darkplaces.git] / gl_rsurf.c
index 78ebba523ddbcaf209bca9056d0a0e97447ea77e..5105a699ac34d8ff931d5ce56aba5788d3f3bde5 100644 (file)
@@ -39,16 +39,17 @@ short lightmapupdate[MAX_LIGHTMAPS][2];
 signed int blocklights[BLOCK_WIDTH*BLOCK_HEIGHT*3]; // LordHavoc: *3 for colored lighting
 
 int lightmapalign, lightmapalignmask; // LordHavoc: NVIDIA's broken subimage fix, see BuildLightmaps for notes
-cvar_t gl_lightmapalign = {"gl_lightmapalign", "4"};
-cvar_t gl_lightmaprgba = {"gl_lightmaprgba", "1"};
-cvar_t gl_nosubimagefragments = {"gl_nosubimagefragments", "0"};
-cvar_t gl_nosubimage = {"gl_nosubimage", "0"};
-cvar_t r_ambient = {"r_ambient", "0"};
-cvar_t gl_vertex = {"gl_vertex", "0"};
-cvar_t r_dlightmap = {"r_dlightmap", "1"};
-cvar_t r_drawportals = {"r_drawportals", "0"};
-cvar_t r_testvis = {"r_testvis", "0"};
-cvar_t r_solidworldnode = {"r_solidworldnode", "1"};
+cvar_t gl_lightmapalign = {0, "gl_lightmapalign", "4"};
+cvar_t gl_lightmaprgba = {0, "gl_lightmaprgba", "1"};
+cvar_t gl_nosubimagefragments = {0, "gl_nosubimagefragments", "0"};
+cvar_t gl_nosubimage = {0, "gl_nosubimage", "0"};
+cvar_t r_ambient = {0, "r_ambient", "0"};
+cvar_t gl_vertex = {0, "gl_vertex", "0"};
+cvar_t r_dlightmap = {CVAR_SAVE, "r_dlightmap", "1"};
+cvar_t r_drawportals = {0, "r_drawportals", "0"};
+cvar_t r_testvis = {0, "r_testvis", "0"};
+cvar_t r_solidworldnode = {0, "r_solidworldnode", "3"};
+cvar_t r_pvsworldnode = {0, "r_pvsworldnode", "1"};
 
 qboolean lightmaprgba, nosubimagefragments, nosubimage;
 int lightmapbytes;
@@ -82,6 +83,7 @@ void GL_Surf_Init(void)
        Cvar_RegisterVariable(&r_drawportals);
        Cvar_RegisterVariable(&r_testvis);
        Cvar_RegisterVariable(&r_solidworldnode);
+       Cvar_RegisterVariable(&r_pvsworldnode);
 
        R_RegisterModule("GL_Surf", gl_surf_start, gl_surf_shutdown, gl_surf_newmap);
 }
@@ -915,7 +917,7 @@ R_DrawBrushModel
 */
 void R_DrawBrushModel (entity_t *e)
 {
-       int                     i, j;
+       int                     i, j, vertexlit;
        vec3_t          mins, maxs;
        msurface_t      *s;
        model_t         *clmodel;
@@ -979,7 +981,7 @@ void R_DrawBrushModel (entity_t *e)
                VectorSubtract(cl_dlights[i].origin, currententity->render.origin, org);
                R_NoVisMarkLights (org, &cl_dlights[i], 1<<(i&31), i >> 5, clmodel);
        }
-//     vertexlit = modelalpha != 1 || clmodel->firstmodelsurface == 0 || (currententity->render.effects & EF_FULLBRIGHT) || currententity->render.colormod[0] != 1 || currententity->render.colormod[2] != 1 || currententity->render.colormod[2] != 1;
+       vertexlit = modelalpha != 1 || clmodel->firstmodelsurface == 0 || (currententity->render.effects & EF_FULLBRIGHT) || currententity->render.colormod[0] != 1 || currententity->render.colormod[2] != 1 || currententity->render.colormod[2] != 1;
 
        // draw texture
        for (i = 0, s = &clmodel->surfaces[clmodel->firstmodelsurface];i < clmodel->nummodelsurfaces;i++, s++)
@@ -987,30 +989,34 @@ void R_DrawBrushModel (entity_t *e)
                if (s->visframe == r_framecount)
                {
 //                     R_DrawSurf(s, true, vertexlit || s->texinfo->texture->transparent);
-                       for (p = s->polys;p;p = p->next)
+                       if (r_ser.value)
                        {
-                               for (j = 0;j < p->numverts;j++)
-                                       softwaretransform(&p->verts[j][0], bmverts + j * 3);
-                               R_Clip_AddPolygon(bmverts, p->numverts, 3 * sizeof(float), (s->flags & SURF_CLIPSOLID) != 0 && modelalpha == 1, RBrushModelSurf_Callback, s, e, NULL);
-                       }
-                       /*
-                       if (s->flags & (SURF_DRAWSKY | SURF_DRAWTURB))
-                       {
-                               // sky and liquid don't need sorting (skypoly/transpoly)
-                               if (s->flags & SURF_DRAWSKY)
-                                       RSurf_DrawSky(s, true);
-                               else
-                                       RSurf_DrawWater(s, R_TextureAnimation(s->texinfo->texture), true, s->flags & SURF_DRAWNOALPHA ? 255 : wateralpha);
+                               for (p = s->polys;p;p = p->next)
+                               {
+                                       for (j = 0;j < p->numverts;j++)
+                                               softwaretransform(&p->verts[j][0], bmverts + j * 3);
+                                       R_Clip_AddPolygon(bmverts, p->numverts, 3 * sizeof(float), (s->flags & SURF_CLIPSOLID) != 0 && modelalpha == 1, RBrushModelSurf_Callback, s, e, NULL);
+                               }
                        }
                        else
                        {
-                               texture_t *t = R_TextureAnimation(s->texinfo->texture);
-                               if (vertexlit || s->texinfo->texture->transparent)
-                                       RSurf_DrawWallVertex(s, t, true, true);
+                               if (s->flags & (SURF_DRAWSKY | SURF_DRAWTURB))
+                               {
+                                       // sky and liquid don't need sorting (skypoly/transpoly)
+                                       if (s->flags & SURF_DRAWSKY)
+                                               RSurf_DrawSky(s, true);
+                                       else
+                                               RSurf_DrawWater(s, R_TextureAnimation(s->texinfo->texture), true, s->flags & SURF_DRAWNOALPHA ? 255 : wateralpha);
+                               }
                                else
-                                       RSurf_DrawWall(s, t, true);
+                               {
+                                       texture_t *t = R_TextureAnimation(s->texinfo->texture);
+                                       if (vertexlit || s->texinfo->texture->transparent)
+                                               RSurf_DrawWallVertex(s, t, true, true);
+                                       else
+                                               RSurf_DrawWall(s, t, true);
+                               }
                        }
-                       */
                }
        }
        UploadLightmaps();
@@ -1163,72 +1169,213 @@ void R_MarkLeaves (void)
 
 void R_SolidWorldNode (void)
 {
-       if ((int) r_solidworldnode.value == 2)
+       if ((int) r_solidworldnode.value == 3)
        {
-               mnode_t *nodestack[8192], *node = cl.worldmodel->nodes;
-               int nodestackpos = 0;
-               glpoly_t *p;
+               int portalstack;
+               mportal_t *p, *pstack[8192];
+               msurface_t *surf, **mark, **endmark;
+               mleaf_t *leaf;
+               glpoly_t *poly;
+               tinyplane_t plane;
+
+               leaf = r_viewleaf;
+               leaf->worldnodeframe = r_framecount;
+               portalstack = 0;
+       loc0:
+               c_leafs++;
 
-loc0:
-               if (node->numsurfaces)
+               leaf->visframe = r_framecount;
+
+               if (leaf->nummarksurfaces)
                {
-                       msurface_t *surf = cl.worldmodel->surfaces + node->firstsurface, *surfend = surf + node->numsurfaces;
-                       tinyplane_t plane;
-                       if (PlaneDiff (r_origin, node->plane) < 0)
+                       mark = leaf->firstmarksurface;
+                       endmark = mark + leaf->nummarksurfaces;
+                       if (r_ser.value)
                        {
-                               for (;surf < surfend;surf++)
+                               do
                                {
-                                       if (surf->flags & SURF_PLANEBACK)
+                                       surf = *mark++;
+                                       // make sure surfaces are only processed once
+                                       if (surf->worldnodeframe == r_framecount)
+                                               continue;
+                                       surf->worldnodeframe = r_framecount;
+                                       if (PlaneDist(r_origin, surf->plane) < surf->plane->dist)
+                                       {
+                                               if (surf->flags & SURF_PLANEBACK)
+                                               {
+                                                       VectorNegate(surf->plane->normal, plane.normal);
+                                                       plane.dist = -surf->plane->dist;
+                                                       for (poly = surf->polys;poly;poly = poly->next)
+                                                               R_Clip_AddPolygon((float *)poly->verts, poly->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, &plane);
+                                               }
+                                       }
+                                       else
                                        {
-                                               VectorNegate(surf->plane->normal, plane.normal);
-                                               plane.dist = -surf->plane->dist;
-                                               for (p = surf->polys;p;p = p->next)
-                                                       R_Clip_AddPolygon((float *)p->verts, p->numverts, VERTEXSIZE * sizeof(float), surf->flags & SURF_CLIPSOLID, RSurf_Callback, surf, NULL, &plane);
+                                               if (!(surf->flags & SURF_PLANEBACK))
+                                                       for (poly = surf->polys;poly;poly = poly->next)
+                                                               R_Clip_AddPolygon((float *)poly->verts, poly->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, (tinyplane_t *)surf->plane);
                                        }
                                }
+                               while (mark < endmark);
                        }
                        else
                        {
-                               for (;surf < surfend;surf++)
+                               do
                                {
-                                       if (!(surf->flags & SURF_PLANEBACK))
-                                               for (p = surf->polys;p;p = p->next)
-                                                       R_Clip_AddPolygon((float *)p->verts, p->numverts, VERTEXSIZE * sizeof(float), surf->flags & SURF_CLIPSOLID, RSurf_Callback, surf, NULL, (tinyplane_t *)surf->plane);
+                                       surf = *mark++;
+                                       // make sure surfaces are only processed once
+                                       if (surf->worldnodeframe == r_framecount)
+                                               continue;
+                                       surf->worldnodeframe = r_framecount;
+                                       if (PlaneDist(r_origin, surf->plane) < surf->plane->dist)
+                                       {
+                                               if (surf->flags & SURF_PLANEBACK)
+                                                       surf->visframe = r_framecount;
+                                       }
+                                       else
+                                       {
+                                               if (!(surf->flags & SURF_PLANEBACK))
+                                                       surf->visframe = r_framecount;
+                                       }
                                }
+                               while (mark < endmark);
                        }
                }
 
-               // recurse down the children
-               if (node->children[0]->contents >= 0)
+               // follow portals into other leafs
+               p = leaf->portals;
+               for (;p;p = p->next)
                {
-                       if (node->children[1]->contents >= 0)
+                       if (DotProduct(r_origin, p->plane.normal) < p->plane.dist)
                        {
-                               if (nodestackpos < 8192)
-                                       nodestack[nodestackpos++] = node->children[1];
-                               node = node->children[0];
-                               goto loc0;
+                               leaf = p->past;
+                               if (leaf->worldnodeframe != r_framecount)
+                               {
+                                       leaf->worldnodeframe = r_framecount;
+                                       if (leaf->contents != CONTENTS_SOLID)
+                                       {
+                                               if (R_NotCulledBox(leaf->mins, leaf->maxs))
+                                               {
+                                                       pstack[portalstack++] = p;
+                                                       goto loc0;
+
+       loc1:
+                                                       p = pstack[--portalstack];
+                                               }
+                                       }
+                               }
                        }
-                       node = node->children[0];
-                       goto loc0;
                }
-               else if (node->children[1]->contents >= 0)
+
+               if (portalstack)
+                       goto loc1;
+       }
+       else if ((int) r_solidworldnode.value == 2)
+       {
+               mnode_t *nodestack[8192], *node = cl.worldmodel->nodes;
+               int nodestackpos = 0;
+               glpoly_t *poly;
+
+loc2:
+               if (R_NotCulledBox(node->mins, node->maxs))
                {
-                       node = node->children[1];
-                       goto loc0;
+                       if (r_ser.value)
+                       {
+                               if (node->numsurfaces)
+                               {
+                                       msurface_t *surf = cl.worldmodel->surfaces + node->firstsurface, *surfend = surf + node->numsurfaces;
+                                       tinyplane_t plane;
+                                       if (PlaneDiff (r_origin, node->plane) < 0)
+                                       {
+                                               for (;surf < surfend;surf++)
+                                               {
+                                                       if (surf->flags & SURF_PLANEBACK)
+                                                       {
+                                                               VectorNegate(surf->plane->normal, plane.normal);
+                                                               plane.dist = -surf->plane->dist;
+                                                               for (poly = surf->polys;poly;poly = poly->next)
+                                                                       R_Clip_AddPolygon((float *)poly->verts, poly->numverts, VERTEXSIZE * sizeof(float), surf->flags & SURF_CLIPSOLID, RSurf_Callback, surf, NULL, &plane);
+                                                       }
+                                               }
+                                       }
+                                       else
+                                       {
+                                               for (;surf < surfend;surf++)
+                                               {
+                                                       if (!(surf->flags & SURF_PLANEBACK))
+                                                               for (poly = surf->polys;poly;poly = poly->next)
+                                                                       R_Clip_AddPolygon((float *)poly->verts, poly->numverts, VERTEXSIZE * sizeof(float), surf->flags & SURF_CLIPSOLID, RSurf_Callback, surf, NULL, (tinyplane_t *)surf->plane);
+                                               }
+                                       }
+                               }
+                       }
+                       else
+                       {
+                               if (node->numsurfaces)
+                               {
+                                       msurface_t *surf = cl.worldmodel->surfaces + node->firstsurface, *surfend = surf + node->numsurfaces;
+                                       if (PlaneDiff (r_origin, node->plane) < 0)
+                                       {
+                                               for (;surf < surfend;surf++)
+                                               {
+                                                       if (surf->flags & SURF_PLANEBACK)
+                                                               surf->visframe = r_framecount;
+                                               }
+                                       }
+                                       else
+                                       {
+                                               for (;surf < surfend;surf++)
+                                               {
+                                                       if (!(surf->flags & SURF_PLANEBACK))
+                                                               surf->visframe = r_framecount;
+                                               }
+                                       }
+                               }
+                       }
+
+                       // recurse down the children
+                       if (node->children[0]->contents >= 0)
+                       {
+                               if (node->children[1]->contents >= 0)
+                               {
+                                       if (nodestackpos < 8192)
+                                               nodestack[nodestackpos++] = node->children[1];
+                                       node = node->children[0];
+                                       goto loc2;
+                               }
+                               else
+                                       ((mleaf_t *)node->children[1])->visframe = r_framecount;
+                               node = node->children[0];
+                               goto loc2;
+                       }
+                       else
+                       {
+                               ((mleaf_t *)node->children[0])->visframe = r_framecount;
+                               if (node->children[1]->contents >= 0)
+                               {
+                                       node = node->children[1];
+                                       goto loc2;
+                               }
+                               else if (nodestackpos > 0)
+                               {
+                                       ((mleaf_t *)node->children[1])->visframe = r_framecount;
+                                       node = nodestack[--nodestackpos];
+                                       goto loc2;
+                               }
+                       }
                }
                else if (nodestackpos > 0)
                {
                        node = nodestack[--nodestackpos];
-                       goto loc0;
+                       goto loc2;
                }
        }
-       else if ((int) r_solidworldnode.value == 1)
+       else if ((int) r_solidworldnode.value == 1 && r_ser.value)
        {
-               glpoly_t *p;
+               glpoly_t *poly;
                msurface_t *surf, *endsurf;
                tinyplane_t plane;
 
-
                surf = &cl.worldmodel->surfaces[cl.worldmodel->firstmodelsurface];
                endsurf = surf + cl.worldmodel->nummodelsurfaces;
                for (;surf < endsurf;surf++)
@@ -1239,15 +1386,15 @@ loc0:
                                {
                                        VectorNegate(surf->plane->normal, plane.normal);
                                        plane.dist = -surf->plane->dist;
-                                       for (p = surf->polys;p;p = p->next)
-                                               R_Clip_AddPolygon((float *)p->verts, p->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, &plane);
+                                       for (poly = surf->polys;poly;poly = poly->next)
+                                               R_Clip_AddPolygon((float *)poly->verts, poly->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, &plane);
                                }
                        }
                        else
                        {
                                if (!(surf->flags & SURF_PLANEBACK))
-                                       for (p = surf->polys;p;p = p->next)
-                                               R_Clip_AddPolygon((float *)p->verts, p->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, (tinyplane_t *)&surf->plane);
+                                       for (poly = surf->polys;poly;poly = poly->next)
+                                               R_Clip_AddPolygon((float *)poly->verts, poly->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, (tinyplane_t *)&surf->plane);
                        }
                }
        }
@@ -1256,14 +1403,14 @@ loc0:
                int l;
                mleaf_t *leaf;
                msurface_t *surf, **mark, **endmark;
-               glpoly_t *p;
+               glpoly_t *poly;
                tinyplane_t plane;
 
                for (l = 0, leaf = cl.worldmodel->leafs;l < cl.worldmodel->numleafs;l++, leaf++)
                {
                        if (R_CullBox(leaf->mins, leaf->maxs))
                                continue;
-//                     leaf->visframe = r_framecount;
+                       leaf->visframe = r_framecount;
                        c_leafs++;
                        if (leaf->nummarksurfaces)
                        {
@@ -1274,31 +1421,56 @@ loc0:
                                {
                                        mark = leaf->firstmarksurface;
                                        endmark = mark + leaf->nummarksurfaces;
-                                       do
+                                       if (r_ser.value)
                                        {
-                                               surf = *mark++;
-                                               // make sure surfaces are only processed once
-                                               if (surf->worldnodeframe == r_framecount)
-                                                       continue;
-                                               surf->worldnodeframe = r_framecount;
-                                               if (PlaneDist(r_origin, surf->plane) < surf->plane->dist)
+                                               do
                                                {
-                                                       if (surf->flags & SURF_PLANEBACK)
+                                                       surf = *mark++;
+                                                       // make sure surfaces are only processed once
+                                                       if (surf->worldnodeframe == r_framecount)
+                                                               continue;
+                                                       surf->worldnodeframe = r_framecount;
+                                                       if (PlaneDist(r_origin, surf->plane) < surf->plane->dist)
                                                        {
-                                                               VectorNegate(surf->plane->normal, plane.normal);
-                                                               plane.dist = -surf->plane->dist;
-                                                               for (p = surf->polys;p;p = p->next)
-                                                                       R_Clip_AddPolygon((float *)p->verts, p->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, &plane);
+                                                               if (surf->flags & SURF_PLANEBACK)
+                                                               {
+                                                                       VectorNegate(surf->plane->normal, plane.normal);
+                                                                       plane.dist = -surf->plane->dist;
+                                                                       for (poly = surf->polys;poly;poly = poly->next)
+                                                                               R_Clip_AddPolygon((float *)poly->verts, poly->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, &plane);
+                                                               }
+                                                       }
+                                                       else
+                                                       {
+                                                               if (!(surf->flags & SURF_PLANEBACK))
+                                                                       for (poly = surf->polys;poly;poly = poly->next)
+                                                                               R_Clip_AddPolygon((float *)poly->verts, poly->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, (tinyplane_t *)surf->plane);
                                                        }
                                                }
-                                               else
+                                               while (mark < endmark);
+                                       }
+                                       else
+                                       {
+                                               do
                                                {
-                                                       if (!(surf->flags & SURF_PLANEBACK))
-                                                               for (p = surf->polys;p;p = p->next)
-                                                                       R_Clip_AddPolygon((float *)p->verts, p->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, (tinyplane_t *)surf->plane);
+                                                       surf = *mark++;
+                                                       // make sure surfaces are only processed once
+                                                       if (surf->worldnodeframe == r_framecount)
+                                                               continue;
+                                                       surf->worldnodeframe = r_framecount;
+                                                       if (PlaneDist(r_origin, surf->plane) < surf->plane->dist)
+                                                       {
+                                                               if (surf->flags & SURF_PLANEBACK)
+                                                                       surf->visframe = r_framecount;
+                                                       }
+                                                       else
+                                                       {
+                                                               if (!(surf->flags & SURF_PLANEBACK))
+                                                                       surf->visframe = r_framecount;
+                                                       }
                                                }
+                                               while (mark < endmark);
                                        }
-                                       while (mark < endmark);
                                }
                        }
                }
@@ -1469,457 +1641,252 @@ void R_PortalWorldNode (void)
 }
 */
 
-/*
-#define MAXRECURSIVEPORTALPLANES 1024
-#define MAXRECURSIVEPORTALS 256
-
-tinyplane_t portalplanes[MAXRECURSIVEPORTALPLANES];
-int portalplanestack[MAXRECURSIVEPORTALS];
-int portalplanecount;
-int ranoutofportalplanes;
-int ranoutofportals;
-int ranoutofleafs;
-int portalcantseeself;
-int portalrecursion;
-
-int R_ClipPolygonToPlane(float *in, float *out, int inpoints, int maxoutpoints, tinyplane_t *p)
-{
-       int i, outpoints, prevside, side;
-       float *prevpoint, prevdist, dist, dot;
-
-       if (inpoints < 3)
-               return inpoints;
-       // begin with the last point, then enter the loop with the first point as current
-       prevpoint = in + 3 * (inpoints - 1);
-       prevdist = DotProduct(prevpoint, p->normal) - p->dist;
-       prevside = prevdist >= 0 ? SIDE_FRONT : SIDE_BACK;
-       i = 0;
-       outpoints = 0;
-       goto begin;
-       for (;i < inpoints;i++)
-       {
-               prevpoint = in;
-               prevdist = dist;
-               prevside = side;
-               in += 3;
 
-begin:
-               dist = DotProduct(in, p->normal) - p->dist;
-               side = dist >= 0 ? SIDE_FRONT : SIDE_BACK;
-
-               if (prevside == SIDE_FRONT)
-               {
-                       if (outpoints >= maxoutpoints)
-                               return -1;
-                       VectorCopy(prevpoint, out);
-                       out += 3;
-                       outpoints++;
-                       if (side == SIDE_FRONT)
-                               continue;
-               }
-               else if (side == SIDE_BACK)
-                       continue;
-
-               // generate a split point
-               if (outpoints >= maxoutpoints)
-                       return -1;
-               dot = prevdist / (prevdist - dist);
-               out[0] = prevpoint[0] + dot * (in[0] - prevpoint[0]);
-               out[1] = prevpoint[1] + dot * (in[1] - prevpoint[1]);
-               out[2] = prevpoint[2] + dot * (in[2] - prevpoint[2]);
-               out += 3;
-               outpoints++;
-       }
-
-       return outpoints;
-}
-
-float portaltemppoints[2][256][3];
-float portaltemppoints2[256][3];
+int r_portalframecount = 0;
 
-int R_FrustumTestPolygon(float *points, int numpoints, int stride)
+/*
+void R_Portal_Callback(void *data, void *data2)
 {
-       int i;
-       float *out;
-       if (numpoints < 3)
-               return numpoints;
-       out = &portaltemppoints[0][0][0];
-       for (i = 0;i < numpoints;i++)
+       mleaf_t *leaf = data;
+       if (!r_testvis.value)
+               ((mportal_t *)data2)->visframe = r_portalframecount;
+       if (leaf->visframe != r_framecount)
        {
-               VectorCopy(points, portaltemppoints[0][i]);
-               (byte *)points += stride;
+               c_leafs++;
+               leaf->visframe = r_framecount;
        }
-       numpoints = R_ClipPolygonToPlane(&portaltemppoints[0][0][0], &portaltemppoints[1][0][0], numpoints, 256, (tinyplane_t *)&frustum[0]);
-       if (numpoints < 3)
-               return numpoints;
-       numpoints = R_ClipPolygonToPlane(&portaltemppoints[1][0][0], &portaltemppoints[0][0][0], numpoints, 256, (tinyplane_t *)&frustum[1]);
-       if (numpoints < 3)
-               return numpoints;
-       numpoints = R_ClipPolygonToPlane(&portaltemppoints[0][0][0], &portaltemppoints[1][0][0], numpoints, 256, (tinyplane_t *)&frustum[2]);
-       if (numpoints < 3)
-               return numpoints;
-       return      R_ClipPolygonToPlane(&portaltemppoints[1][0][0], &portaltemppoints[0][0][0], numpoints, 256, (tinyplane_t *)&frustum[3]);
-}
-
-void R_TriangleToPlane(vec3_t point1, vec3_t point2, vec3_t point3, tinyplane_t *p)
-{
-       vec3_t v1, v2;
-       VectorSubtract(point1, point2, v1);
-       VectorSubtract(point3, point2, v2);
-       CrossProduct(v1, v2, p->normal);
-//     VectorNormalize(p->normal);
-       VectorNormalizeFast(p->normal);
-       p->dist = DotProduct(point1, p->normal);
 }
+*/
 
-int R_PortalThroughPortalPlanes(tinyplane_t *clipplanes, int clipnumplanes, float *targpoints, int targnumpoints, float *out, int maxpoints)
+void R_PVSWorldNode()
 {
-       int numpoints, i;
-       if (targnumpoints < 3)
-               return targnumpoints;
-       if (maxpoints < 3)
-               return -1;
-       numpoints = targnumpoints;
-       memcpy(&portaltemppoints[0][0][0], targpoints, numpoints * 3 * sizeof(float));
-       for (i = 0;i < clipnumplanes;i++)
+       if (r_pvsworldnode.value == 1)
        {
-               numpoints = R_ClipPolygonToPlane(&portaltemppoints[0][0][0], &portaltemppoints[1][0][0], numpoints, 256, clipplanes + i);
-               if (numpoints < 3)
-                       return numpoints;
-               memcpy(&portaltemppoints[0][0][0], &portaltemppoints[1][0][0], numpoints * 3 * sizeof(float));
-       }
-       if (numpoints > maxpoints)
-               return -1;
-       memcpy(out, &portaltemppoints[1][0][0], numpoints * 3 * sizeof(float));
-       return numpoints;
-}
-
-#define MAXRECURSIVEPORTALLEAFS 256
-
-//mleaf_t *leafstack[MAXRECURSIVEPORTALLEAFS];
-//int leafstackpos;
-int r_portalframecount;
-
-void R_RecursivePortalWorldNode (mleaf_t *leaf, int firstclipplane, int numclipplanes)
-{
-       mportal_t *p;
-
-//     if (leafstackpos >= MAXRECURSIVEPORTALLEAFS)
-//     {
-//             ranoutofleafs = true;
-//             return;
-//     }
+               int portalstack, i;
+               mportal_t *p, *pstack[8192];
+               msurface_t *surf, **mark, **endmark;
+               mleaf_t *leaf;
+               tinyplane_t plane;
+               glpoly_t *poly;
+               byte *worldvis;
 
-//     leafstack[leafstackpos++] = leaf;
+               worldvis = Mod_LeafPVS (r_viewleaf, cl.worldmodel);
 
-       if (leaf->visframe != r_framecount)
-       {
+               leaf = r_viewleaf;
+               leaf->worldnodeframe = r_framecount;
+               portalstack = 0;
+       loc0:
                c_leafs++;
+
                leaf->visframe = r_framecount;
+
                if (leaf->nummarksurfaces)
                {
-                       msurface_t *surf, **mark, **endmark;
                        mark = leaf->firstmarksurface;
                        endmark = mark + leaf->nummarksurfaces;
-                       do
+                       if (r_ser.value)
                        {
-                               surf = *mark++;
-                               // make sure surfaces are only processed once
-                               if (surf->worldnodeframe == r_framecount)
-                                       continue;
-                               surf->worldnodeframe = r_framecount;
-                               if (PlaneDist(modelorg, surf->plane) < surf->plane->dist)
+                               do
                                {
-                                       if (surf->flags & SURF_PLANEBACK)
-                                               RSurf_DoVisible(surf);
+                                       surf = *mark++;
+                                       // make sure surfaces are only processed once
+                                       if (surf->worldnodeframe == r_framecount)
+                                               continue;
+                                       surf->worldnodeframe = r_framecount;
+                                       if (PlaneDist(modelorg, surf->plane) < surf->plane->dist)
+                                       {
+                                               if (surf->flags & SURF_PLANEBACK)
+                                               {
+                                                       VectorNegate(surf->plane->normal, plane.normal);
+                                                       plane.dist = -surf->plane->dist;
+                                                       for (poly = surf->polys;poly;poly = poly->next)
+                                                               R_Clip_AddPolygon((float *)poly->verts, poly->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, &plane);
+                                               }
+                                       }
+                                       else
+                                       {
+                                               if (!(surf->flags & SURF_PLANEBACK))
+                                                       for (poly = surf->polys;poly;poly = poly->next)
+                                                               R_Clip_AddPolygon((float *)poly->verts, poly->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, (tinyplane_t *)surf->plane);
+                                       }
                                }
-                               else
+                               while (mark < endmark);
+                       }
+                       else
+                       {
+                               do
                                {
-                                       if (!(surf->flags & SURF_PLANEBACK))
-                                               RSurf_DoVisible(surf);
+                                       surf = *mark++;
+                                       // make sure surfaces are only processed once
+                                       if (surf->worldnodeframe == r_framecount)
+                                               continue;
+                                       surf->worldnodeframe = r_framecount;
+                                       if (PlaneDist(modelorg, surf->plane) < surf->plane->dist)
+                                       {
+                                               if (surf->flags & SURF_PLANEBACK)
+                                                       surf->visframe = r_framecount;
+                                       }
+                                       else
+                                       {
+                                               if (!(surf->flags & SURF_PLANEBACK))
+                                                       surf->visframe = r_framecount;
+                                       }
                                }
+                               while (mark < endmark);
                        }
-                       while (mark < endmark);
                }
-       }
 
-       // follow portals into other leafs
-       for (p = leaf->portals;p;p = p->next)
-       {
-               int newpoints, i, prev;
-               vec3_t center;
-               vec3_t v1, v2;
-               tinyplane_t *newplanes;
-               // only flow through portals facing away from the viewer
-               if (PlaneDiff(r_origin, (&p->plane)) < 0)
+               // follow portals into other leafs
+               p = leaf->portals;
+               for (;p;p = p->next)
                {
-*/
-                       /*
-                       for (i = 0;i < leafstackpos;i++)
-                               if (leafstack[i] == p->past)
-                                       break;
-                       if (i < leafstackpos)
+                       if (DotProduct(r_origin, p->plane.normal) < p->plane.dist)
                        {
-                               portalrecursion = true;
-                               continue;
-                       }
-                       */
-/*
-                       newpoints = R_PortalThroughPortalPlanes(&portalplanes[firstclipplane], numclipplanes, (float *) p->points, p->numpoints, &portaltemppoints2[0][0], 256);
-                       if (newpoints < 3)
-                               continue;
-                       else if (firstclipplane + numclipplanes + newpoints > MAXRECURSIVEPORTALPLANES)
-                               ranoutofportalplanes = true;
-                       else
-                       {
-                               // go ahead and mark the leaf early, nothing can abort here
-                               if (!r_testvis.value)
-                                       p->visframe = r_portalframecount;
-
-                               // find the center by averaging
-                               VectorClear(center);
-                               for (i = 0;i < newpoints;i++)
-                                       VectorAdd(center, portaltemppoints2[i], center);
-                               // ixtable is a 1.0f / N table
-                               VectorScale(center, ixtable[newpoints], center);
-                               // calculate the planes, and make sure the polygon can see it's own center
-                               newplanes = &portalplanes[firstclipplane + numclipplanes];
-                               for (prev = newpoints - 1, i = 0;i < newpoints;prev = i, i++)
+                               leaf = p->past;
+                               if (leaf->worldnodeframe != r_framecount)
                                {
-//                                     R_TriangleToPlane(r_origin, portaltemppoints2[i], portaltemppoints2[prev], newplanes + i);
-                                       VectorSubtract(r_origin, portaltemppoints2[i], v1);
-                                       VectorSubtract(portaltemppoints2[prev], portaltemppoints2[i], v2);
-                                       CrossProduct(v1, v2, newplanes[i].normal);
-                                       VectorNormalizeFast(newplanes[i].normal);
-                                       newplanes[i].dist = DotProduct(r_origin, newplanes[i].normal);
-                                       if (DotProduct(newplanes[i].normal, center) <= newplanes[i].dist)
+                                       leaf->worldnodeframe = r_framecount;
+                                       if (leaf->contents != CONTENTS_SOLID)
                                        {
-                                               // polygon can't see it's own center, discard and use parent portal
-                                               break;
+                                               i = (leaf - cl.worldmodel->leafs) - 1;
+                                               if (worldvis[i>>3] & (1<<(i&7)))
+                                               {
+                                                       if (R_NotCulledBox(leaf->mins, leaf->maxs))
+                                                       {
+                                                               pstack[portalstack++] = p;
+                                                               goto loc0;
+
+               loc1:
+                                                               p = pstack[--portalstack];
+                                                       }
+                                               }
                                        }
                                }
-                               if (i == newpoints)
-                                       R_RecursivePortalWorldNode(p->past, firstclipplane + numclipplanes, newpoints);
-                               else
-                                       R_RecursivePortalWorldNode(p->past, firstclipplane, numclipplanes);
                        }
                }
-       }
-//     leafstackpos--;
-}
-
-//float viewportalpoints[16*3];
-
-*/
 
-int r_portalframecount = 0;
+               if (portalstack)
+                       goto loc1;
 
-/*
-void R_Portal_Callback(void *data, void *data2)
-{
-       mleaf_t *leaf = data;
-       if (!r_testvis.value)
-               ((mportal_t *)data2)->visframe = r_portalframecount;
-       if (leaf->visframe != r_framecount)
-       {
-               c_leafs++;
-               leaf->visframe = r_framecount;
+               i = 0;
+               portalstack = 0;
+               p = r_viewleaf->portals;
+               for (;p;p = p->next)
+               {
+                       portalstack++;
+                       if (p->past->worldnodeframe != r_framecount)
+                               i++;
+               }
+               if (i)
+                       Con_Printf("%i portals of viewleaf (%i portals) were not checked\n", i, portalstack);
        }
-}
-*/
+       else
+       {
+               int i/*, l*/, k, c, row, numbits, bit, leafnum, numleafs;
+               mleaf_t *leaf;
+               msurface_t *surf, **mark, **endmark;
+               model_t *model = cl.worldmodel;
+               byte *in;
+       //      mportal_t *portal;
+               glpoly_t *poly;
+               tinyplane_t plane;
 
-void R_PVSWorldNode()
-{
-       int i/*, l*/, k, c, row, numbits, bit, leafnum, numleafs;
-       mleaf_t *leaf;
-       msurface_t *surf, **mark, **endmark;
-       model_t *model = cl.worldmodel;
-       byte *in;
-//     mportal_t *portal;
-       glpoly_t *p;
-       tinyplane_t plane;
+       //      c_leafs++;
+       //      r_viewleaf->visframe = r_framecount;
+               if (!r_testvis.value)
+                       r_portalframecount++;
 
-//     c_leafs++;
-//     r_viewleaf->visframe = r_framecount;
-       if (!r_testvis.value)
-               r_portalframecount++;
-
-       numleafs = model->numleafs;
-       numbits = numleafs;
-       k = 0;
-       in = r_viewleaf->compressed_vis;
-       row = (numbits + 7) >> 3;
-       while (k < row)
-       {
-               c = *in++;
-               if (c)
+               numleafs = model->numleafs;
+               numbits = numleafs;
+               k = 0;
+               in = r_viewleaf->compressed_vis;
+               row = (numbits + 7) >> 3;
+               while (k < row)
                {
-                       for (i = 0, bit = 1;c;i++, bit <<= 1)
+                       c = *in++;
+                       if (c)
                        {
-                               if (c & bit)
+                               for (i = 0, bit = 1;c;i++, bit <<= 1)
                                {
-                                       leafnum = (k << 3)+i+1;
-                                       if (leafnum > numleafs)
-                                               return;
-                                       c -= bit;
-                                       leaf = &model->leafs[leafnum];
-                                       if (R_NotCulledBox(leaf->mins, leaf->maxs))
+                                       if (c & bit)
                                        {
-                                               //for (portal = leaf->portals;portal;portal = portal->next)
-                                               //      if (DotProduct(r_origin, portal->plane.normal) > portal->plane.dist)
-                                               //              R_Clip_AddPolygon((float *)portal->points, portal->numpoints, sizeof(mvertex_t), false, R_Portal_Callback, leaf, portal, portal->plane);
-                                               //leaf->visframe = r_framecount;
-                                               c_leafs++;
-                                               if (leaf->nummarksurfaces)
+                                               leafnum = (k << 3)+i+1;
+                                               if (leafnum > numleafs)
+                                                       return;
+                                               c -= bit;
+                                               leaf = &model->leafs[leafnum];
+                                               if (R_NotCulledBox(leaf->mins, leaf->maxs))
                                                {
-                                                       mark = leaf->firstmarksurface;
-                                                       endmark = mark + leaf->nummarksurfaces;
-                                                       do
+                                                       //for (portal = leaf->portals;portal;portal = portal->next)
+                                                       //      if (DotProduct(r_origin, portal->plane.normal) > portal->plane.dist)
+                                                       //              R_Clip_AddPolygon((float *)portal->points, portal->numpoints, sizeof(mvertex_t), false, R_Portal_Callback, leaf, portal, portal->plane);
+                                                       //leaf->visframe = r_framecount;
+                                                       c_leafs++;
+                                                       if (leaf->nummarksurfaces)
                                                        {
-                                                               surf = *mark++;
-                                                               // make sure surfaces are only processed once
-                                                               if (surf->worldnodeframe == r_framecount)
-                                                                       continue;
-                                                               surf->worldnodeframe = r_framecount;
-                                                               if (PlaneDist(r_origin, surf->plane) < surf->plane->dist)
+                                                               mark = leaf->firstmarksurface;
+                                                               endmark = mark + leaf->nummarksurfaces;
+                                                               if (r_ser.value)
                                                                {
-                                                                       if (surf->flags & SURF_PLANEBACK)
+                                                                       do
                                                                        {
-                                                                               VectorNegate(surf->plane->normal, plane.normal);
-                                                                               plane.dist = -surf->plane->dist;
-                                                                               for (p = surf->polys;p;p = p->next)
-                                                                                       R_Clip_AddPolygon((float *)p->verts, p->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, &plane);
+                                                                               surf = *mark++;
+                                                                               // make sure surfaces are only processed once
+                                                                               if (surf->worldnodeframe == r_framecount)
+                                                                                       continue;
+                                                                               surf->worldnodeframe = r_framecount;
+                                                                               if (PlaneDist(r_origin, surf->plane) < surf->plane->dist)
+                                                                               {
+                                                                                       if (surf->flags & SURF_PLANEBACK)
+                                                                                       {
+                                                                                               VectorNegate(surf->plane->normal, plane.normal);
+                                                                                               plane.dist = -surf->plane->dist;
+                                                                                               for (poly = surf->polys;poly;poly = poly->next)
+                                                                                                       R_Clip_AddPolygon((float *)poly->verts, poly->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, &plane);
+                                                                                       }
+                                                                               }
+                                                                               else
+                                                                               {
+                                                                                       if (!(surf->flags & SURF_PLANEBACK))
+                                                                                               for (poly = surf->polys;poly;poly = poly->next)
+                                                                                                       R_Clip_AddPolygon((float *)poly->verts, poly->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, (tinyplane_t *)surf->plane);
+                                                                               }
                                                                        }
+                                                                       while (mark < endmark);
                                                                }
                                                                else
                                                                {
-                                                                       if (!(surf->flags & SURF_PLANEBACK))
-                                                                               for (p = surf->polys;p;p = p->next)
-                                                                                       R_Clip_AddPolygon((float *)p->verts, p->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, (tinyplane_t *)surf->plane);
+                                                                       do
+                                                                       {
+                                                                               surf = *mark++;
+                                                                               // make sure surfaces are only processed once
+                                                                               if (surf->worldnodeframe == r_framecount)
+                                                                                       continue;
+                                                                               surf->worldnodeframe = r_framecount;
+                                                                               if (PlaneDist(r_origin, surf->plane) < surf->plane->dist)
+                                                                               {
+                                                                                       if (surf->flags & SURF_PLANEBACK)
+                                                                                               surf->visframe = r_framecount;
+                                                                               }
+                                                                               else
+                                                                               {
+                                                                                       if (!(surf->flags & SURF_PLANEBACK))
+                                                                                               surf->visframe = r_framecount;
+                                                                               }
+                                                                       }
+                                                                       while (mark < endmark);
                                                                }
                                                        }
-                                                       while (mark < endmark);
                                                }
                                        }
                                }
-                       }
-                       k++;
-               }
-               else
-                       k += *in++;
-       }
-}
-
-       /*
-       if (!r_testvis.value)
-               r_portalframecount = r_framecount;
-       portalplanecount = 0;
-//     leafstackpos = 0;
-       ranoutofportalplanes = false;
-       ranoutofportals = false;
-       ranoutofleafs = false;
-       portalcantseeself = 0;
-       portalrecursion = false;
-       memcpy(&portalplanes[0], &frustum[0], sizeof(tinyplane_t));
-       memcpy(&portalplanes[1], &frustum[1], sizeof(tinyplane_t));
-       memcpy(&portalplanes[2], &frustum[2], sizeof(tinyplane_t));
-       memcpy(&portalplanes[3], &frustum[3], sizeof(tinyplane_t));
-       R_RecursivePortalWorldNode(r_viewleaf, 0, 4);
-       if (ranoutofportalplanes)
-               Con_Printf("R_RecursivePortalWorldNode: ran out of %d plane stack when recursing through portals\n", MAXRECURSIVEPORTALPLANES);
-       if (ranoutofportals)
-               Con_Printf("R_RecursivePortalWorldNode: ran out of %d portal stack when recursing through portals\n", MAXRECURSIVEPORTALS);
-       if (ranoutofleafs)
-               Con_Printf("R_RecursivePortalWorldNode: ran out of %d leaf stack when recursing through portals\n", MAXRECURSIVEPORTALLEAFS);
-//     if (portalcantseeself)
-//             Con_Printf("R_RecursivePortalWorldNode: %d portals could not see themself during clipping\n", portalcantseeself);
-       if (portalrecursion)
-               Con_Printf("R_RecursivePortalWorldNode: portal saw into previously encountered leaf??\n");
-       */
-
-/*
-void R_OldPortalWorldNode (void)
-{
-       int portalstack, i;
-       mportal_t *p, *pstack[8192];
-       msurface_t *surf, **mark, **endmark;
-       mleaf_t *leaf;
-
-       leaf = r_viewleaf;
-       leaf->worldnodeframe = r_framecount;
-       portalstack = 0;
-loc0:
-       c_leafs++;
-
-       leaf->visframe = r_framecount;
-
-       if (leaf->nummarksurfaces)
-       {
-               mark = leaf->firstmarksurface;
-               endmark = mark + leaf->nummarksurfaces;
-               do
-               {
-                       surf = *mark++;
-                       // make sure surfaces are only processed once
-                       if (surf->worldnodeframe == r_framecount)
-                               continue;
-                       surf->worldnodeframe = r_framecount;
-                       if (PlaneDist(modelorg, surf->plane) < surf->plane->dist)
-                       {
-                               if (surf->flags & SURF_PLANEBACK)
-                                       surf->visframe = r_framecount;
+                               k++;
                        }
                        else
-                       {
-                               if (!(surf->flags & SURF_PLANEBACK))
-                                       surf->visframe = r_framecount;
-                       }
-               }
-               while (mark < endmark);
-       }
-
-       // follow portals into other leafs
-       p = leaf->portals;
-       for (;p;p = p->next)
-       {
-               leaf = p->past;
-               if (leaf->worldnodeframe != r_framecount)
-               {
-                       leaf->worldnodeframe = r_framecount;
-                       if (leaf->contents != CONTENTS_SOLID)
-                       {
-                               i = (leaf - cl.worldmodel->leafs) - 1;
-                               if (worldvis[i>>3] & (1<<(i&7)))
-                               {
-                                       if (R_NotCulledBox(leaf->mins, leaf->maxs))
-                                       {
-                                               pstack[portalstack++] = p;
-                                               goto loc0;
-
-loc1:
-                                               p = pstack[--portalstack];
-                                       }
-                               }
-                       }
+                               k += *in++;
                }
        }
-
-       if (portalstack)
-               goto loc1;
-
-       i = 0;
-       portalstack = 0;
-       p = r_viewleaf->portals;
-       for (;p;p = p->next)
-       {
-               portalstack++;
-               if (p->past->worldnodeframe != r_framecount)
-                       i++;
-       }
-       if (i)
-               Con_Printf("%i portals of viewleaf (%i portals) were not checked\n", i, portalstack);
 }
-*/
 
 entity_t clworldent;
 
@@ -1942,7 +1909,6 @@ void R_DrawSurfaces (void)
                        c_faces++;
                        if (surf->flags & (SURF_DRAWSKY | SURF_DRAWTURB))
                        {
-                               // sky and liquid don't need sorting (skypoly/transpoly)
                                if (surf->flags & SURF_DRAWSKY)
                                        RSurf_DrawSky(surf, false);
                                else