From: lordhavoc Date: Sun, 28 Oct 2001 09:18:01 +0000 (+0000) Subject: made the Sorted Edge Rasterizer (hidden surface removal) optional as the r_ser cvar... X-Git-Tag: RELEASE_0_2_0_RC1~776 X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=commitdiff_plain;h=5680867262036b514af3ae2fdc27b504675f30f7 made the Sorted Edge Rasterizer (hidden surface removal) optional as the r_ser cvar, can be a speed difference added back the old portal-passage worldnode code (sometimes faster) recalculate node bounding boxes when loading (based on leaf bounding boxes which are calculated from portal generation) added untested code for qftol (much faster double to integer conversion on x86, not used yet) added a couple Hunk_Check calls while loading things (just to be a little more paranoid) minor whitespace cleanup, some commented out code removed git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@956 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/cl_parse.c b/cl_parse.c index 86014414..9f12f901 100644 --- a/cl_parse.c +++ b/cl_parse.c @@ -390,6 +390,8 @@ void CL_ParseServerInfo (void) // needlessly purge it // + Hunk_Check (); + // precache models memset (cl.model_precache, 0, sizeof(cl.model_precache)); for (nummodels=1 ; ; nummodels++) @@ -406,6 +408,9 @@ void CL_ParseServerInfo (void) Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1); strcpy (model_precache[nummodels], str); Mod_TouchModel (str); + +// Hunk_Check (); + } // precache sounds @@ -430,10 +435,15 @@ void CL_ParseServerInfo (void) // now we try to load everything else until a cache allocation fails // + Hunk_Check (); + for (i=1 ; irender.origin, currententity->render.model->mins, mins); VectorAdd(currententity->render.origin, currententity->render.model->maxs, maxs); - R_Clip_AddBox(mins, maxs, R_Entity_Callback, currententity, NULL); + if (r_ser.value) + R_Clip_AddBox(mins, maxs, R_Entity_Callback, currententity, NULL); + else if (R_NotCulledBox(mins, maxs)) + currententity->render.visframe = r_framecount; } else if (currententity->render.model->type == mod_sprite) { R_LerpUpdate(currententity); - R_LerpAnimation(currententity->render.model, currententity->render.frame1, currententity->render.frame2, currententity->render.frame1start, currententity->render.frame2start, currententity->render.framelerp, blend); - R_ClipSprite(currententity, blend); + if (r_ser.value) + { + R_LerpAnimation(currententity->render.model, currententity->render.frame1, currententity->render.frame2, currententity->render.frame1start, currententity->render.frame2start, currententity->render.framelerp, blend); + R_ClipSprite(currententity, blend); + } + else + { + VectorAdd(currententity->render.origin, currententity->render.model->mins, mins); + VectorAdd(currententity->render.origin, currententity->render.model->maxs, maxs); + if (R_NotCulledBox(mins, maxs)) + currententity->render.visframe = r_framecount; + } } } } diff --git a/gl_rsurf.c b/gl_rsurf.c index 6f258d0e..5105a699 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -48,7 +48,8 @@ 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", "1"}; +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); } } } @@ -1488,169 +1660,233 @@ void R_Portal_Callback(void *data, void *data2) 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++; - - numleafs = model->numleafs; - numbits = numleafs; - k = 0; - in = r_viewleaf->compressed_vis; - row = (numbits + 7) >> 3; - while (k < row) + if (r_pvsworldnode.value == 1) { - c = *in++; - if (c) + int portalstack, i; + mportal_t *p, *pstack[8192]; + msurface_t *surf, **mark, **endmark; + mleaf_t *leaf; + tinyplane_t plane; + glpoly_t *poly; + byte *worldvis; + + worldvis = Mod_LeafPVS (r_viewleaf, cl.worldmodel); + + leaf = r_viewleaf; + leaf->worldnodeframe = r_framecount; + portalstack = 0; + loc0: + c_leafs++; + + leaf->visframe = r_framecount; + + if (leaf->nummarksurfaces) { - for (i = 0, bit = 1;c;i++, bit <<= 1) + mark = leaf->firstmarksurface; + endmark = mark + leaf->nummarksurfaces; + if (r_ser.value) { - if (c & bit) + do { - leafnum = (k << 3)+i+1; - if (leafnum > numleafs) - return; - c -= bit; - leaf = &model->leafs[leafnum]; - if (R_NotCulledBox(leaf->mins, leaf->maxs)) + 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) { - //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) + if (surf->flags & SURF_PLANEBACK) { - 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(r_origin, surf->plane) < surf->plane->dist) - { - if (surf->flags & SURF_PLANEBACK) - { - 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); - } - } - 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); - } - } - while (mark < endmark); + 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); + } } - } - k++; - } - else - k += *in++; - } -} - -/* -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; + while (mark < endmark); } else { - if (!(surf->flags & SURF_PLANEBACK)) - surf->visframe = r_framecount; + 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; + } + else + { + if (!(surf->flags & SURF_PLANEBACK)) + surf->visframe = r_framecount; + } + } + while (mark < endmark); } } - while (mark < endmark); - } - // follow portals into other leafs - p = leaf->portals; - for (;p;p = p->next) - { - leaf = p->past; - if (leaf->worldnodeframe != r_framecount) + // follow portals into other leafs + p = leaf->portals; + for (;p;p = p->next) { - leaf->worldnodeframe = r_framecount; - if (leaf->contents != CONTENTS_SOLID) + if (DotProduct(r_origin, p->plane.normal) < p->plane.dist) { - i = (leaf - cl.worldmodel->leafs) - 1; - if (worldvis[i>>3] & (1<<(i&7))) + leaf = p->past; + if (leaf->worldnodeframe != r_framecount) { - if (R_NotCulledBox(leaf->mins, leaf->maxs)) + leaf->worldnodeframe = r_framecount; + if (leaf->contents != CONTENTS_SOLID) { - pstack[portalstack++] = p; - goto loc0; + 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]; + loc1: + p = pstack[--portalstack]; + } + } } } } } - } - if (portalstack) - goto loc1; + if (portalstack) + goto loc1; - i = 0; - portalstack = 0; - p = r_viewleaf->portals; - for (;p;p = p->next) + 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 { - portalstack++; - if (p->past->worldnodeframe != r_framecount) - i++; + 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; + + // 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) + { + for (i = 0, bit = 1;c;i++, bit <<= 1) + { + if (c & bit) + { + leafnum = (k << 3)+i+1; + if (leafnum > numleafs) + return; + c -= bit; + leaf = &model->leafs[leafnum]; + if (R_NotCulledBox(leaf->mins, leaf->maxs)) + { + //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) + { + mark = leaf->firstmarksurface; + endmark = mark + leaf->nummarksurfaces; + if (r_ser.value) + { + 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) + { + 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 + { + 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); + } + } + } + } + } + k++; + } + else + k += *in++; + } } - if (i) - Con_Printf("%i portals of viewleaf (%i portals) were not checked\n", i, portalstack); } -*/ entity_t clworldent; @@ -1673,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 diff --git a/mathlib.c b/mathlib.c index 8a5de30c..371bfa86 100644 --- a/mathlib.c +++ b/mathlib.c @@ -40,7 +40,7 @@ float m_bytenormals[NUMVERTEXNORMALS][3] = {0.295242, 0.000000, 0.955423}, {0.442863, 0.238856, 0.864188}, {0.162460, 0.262866, 0.951056}, {-0.681718, 0.147621, 0.716567}, {-0.809017, 0.309017, 0.500000}, {-0.587785, 0.425325, 0.688191}, -{-0.850651, 0.525731, 0.000000}, {-0.864188, 0.442863, 0.238856}, +{-0.850651, 0.525731, 0.000000}, {-0.864188, 0.442863, 0.238856}, {-0.716567, 0.681718, 0.147621}, {-0.688191, 0.587785, 0.425325}, {-0.500000, 0.809017, 0.309017}, {-0.238856, 0.864188, 0.442863}, {-0.425325, 0.688191, 0.587785}, {-0.716567, 0.681718, -0.147621}, @@ -64,7 +64,7 @@ float m_bytenormals[NUMVERTEXNORMALS][3] = {0.850651, 0.000000, 0.525731}, {0.864188, 0.442863, -0.238856}, {0.809017, 0.309017, -0.500000}, {0.951056, 0.162460, -0.262866}, {0.525731, 0.000000, -0.850651}, {0.681718, 0.147621, -0.716567}, -{0.681718, -0.147621, -0.716567}, {0.850651, 0.000000, -0.525731}, +{0.681718, -0.147621, -0.716567}, {0.850651, 0.000000, -0.525731}, {0.809017, -0.309017, -0.500000}, {0.864188, -0.442863, -0.238856}, {0.951056, -0.162460, -0.262866}, {0.147621, 0.716567, -0.681718}, {0.309017, 0.500000, -0.809017}, {0.425325, 0.688191, -0.587785}, @@ -82,7 +82,7 @@ float m_bytenormals[NUMVERTEXNORMALS][3] = {0.162460, -0.262866, -0.951056}, {0.238856, -0.864188, -0.442863}, {0.500000, -0.809017, -0.309017}, {0.425325, -0.688191, -0.587785}, {0.716567, -0.681718, -0.147621}, {0.688191, -0.587785, -0.425325}, -{0.587785, -0.425325, -0.688191}, {0.000000, -0.955423, -0.295242}, +{0.587785, -0.425325, -0.688191}, {0.000000, -0.955423, -0.295242}, {0.000000, -1.000000, 0.000000}, {0.262866, -0.951056, -0.162460}, {0.000000, -0.850651, 0.525731}, {0.000000, -0.955423, 0.295242}, {0.238856, -0.864188, 0.442863}, {0.262866, -0.951056, 0.162460}, @@ -106,7 +106,7 @@ float m_bytenormals[NUMVERTEXNORMALS][3] = {-0.850651, 0.000000, 0.525731}, {-0.955423, -0.295242, 0.000000}, {-0.951056, -0.162460, 0.262866}, {-0.864188, 0.442863, -0.238856}, {-0.951056, 0.162460, -0.262866}, {-0.809017, 0.309017, -0.500000}, -{-0.864188, -0.442863, -0.238856}, {-0.951056, -0.162460, -0.262866}, +{-0.864188, -0.442863, -0.238856}, {-0.951056, -0.162460, -0.262866}, {-0.809017, -0.309017, -0.500000}, {-0.681718, 0.147621, -0.716567}, {-0.681718, -0.147621, -0.716567}, {-0.850651, 0.000000, -0.525731}, {-0.688191, 0.587785, -0.425325}, {-0.587785, 0.425325, -0.688191}, @@ -689,6 +689,27 @@ vec_t Length(vec3_t v) return length; } +/* +// LordHavoc: fixme: do more research on gcc assembly so that qftol_minushalf and result will not be considered unused +static double qftol_minushalf = -0.5; + +int qftol(double v) +{ + int result; +#ifdef _MSC_VER + __asm + { + fld v + fadd qftol_minushalf + fistp result + } +#else // gcc hopefully + asm("fldl v\n\tfaddl qftol_minushalf\n\tfistpl result"); +#endif + return result; +} +*/ + // LordHavoc: renamed these to Length, and made the normal ones #define float VectorNormalizeLength (vec3_t v) { diff --git a/model_brush.c b/model_brush.c index d417326f..d2cee3f5 100644 --- a/model_brush.c +++ b/model_brush.c @@ -82,7 +82,7 @@ mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model) else node = node->children[1]; } - + return NULL; // never reached } */ @@ -613,7 +613,8 @@ void Mod_LoadSubmodels (lump_t *l) for ( i=0 ; imins[j] = LittleFloat (in->mins[j]) - 1; out->maxs[j] = LittleFloat (in->maxs[j]) + 1; out->origin[j] = LittleFloat (in->origin[j]); @@ -795,7 +796,7 @@ void Mod_LoadFaces (lump_t *l) out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo); CalcSurfaceExtents (out); - + // lighting info for (i=0 ; imins[j] = LittleShort (in->mins[j]); -// out->maxs[j] = LittleShort (in->maxs[j]); -// } + for (j=0 ; j<3 ; j++) + { + out->mins[j] = LittleShort (in->mins[j]); + out->maxs[j] = LittleShort (in->maxs[j]); + } p = LittleLong(in->planenum); out->plane = loadmodel->planes + p; @@ -1482,6 +1483,23 @@ portal_t *AllocPortal (void) return p; } +void Mod_RecursiveRecalcNodeBBox(mnode_t *node) +{ + // calculate children first + if (node->children[0]->contents >= 0) + Mod_RecursiveRecalcNodeBBox(node->children[0]); + if (node->children[1]->contents >= 0) + Mod_RecursiveRecalcNodeBBox(node->children[1]); + + // make combined bounding box from children + node->mins[0] = min(node->children[0]->mins[0], node->children[1]->mins[0]); + node->mins[1] = min(node->children[0]->mins[1], node->children[1]->mins[1]); + node->mins[2] = min(node->children[0]->mins[2], node->children[1]->mins[2]); + node->maxs[0] = max(node->children[0]->maxs[0], node->children[1]->maxs[0]); + node->maxs[1] = max(node->children[0]->maxs[1], node->children[1]->maxs[1]); + node->maxs[2] = max(node->children[0]->maxs[2], node->children[1]->maxs[2]); +} + void Mod_FinalizePortals(void) { int i, j, numportals, numpoints; @@ -1522,13 +1540,23 @@ void Mod_FinalizePortals(void) p = p->chain; } +// Hunk_Check(); + + Mod_RecursiveRecalcNodeBBox(loadmodel->nodes); + +// Hunk_Check(); + // tally up portal and point counts p = portalchain; numportals = 0; numpoints = 0; while(p) { - if (p->winding && p->nodes[0] != p->nodes[1] && p->nodes[0]->contents != CONTENTS_SOLID && p->nodes[1]->contents != CONTENTS_SOLID) + // note: this check must match the one below or it will usually corrupt the hunk + // the nodes[0] != nodes[1] check is because leaf 0 is the shared solid leaf, it can have many portals inside with leaf 0 on both sides + if (p->winding && p->nodes[0] != p->nodes[1] + && p->nodes[0]->contents != CONTENTS_SOLID && p->nodes[1]->contents != CONTENTS_SOLID + && p->nodes[0]->contents != CONTENTS_SKY && p->nodes[1]->contents != CONTENTS_SKY) { numportals += 2; numpoints += p->winding->numpoints * 2; @@ -1553,8 +1581,11 @@ void Mod_FinalizePortals(void) if (p->winding) { + // note: this check must match the one below or it will usually corrupt the hunk // the nodes[0] != nodes[1] check is because leaf 0 is the shared solid leaf, it can have many portals inside with leaf 0 on both sides - if (p->nodes[0] != p->nodes[1] && p->nodes[0]->contents != CONTENTS_SOLID && p->nodes[1]->contents != CONTENTS_SOLID) + if (p->nodes[0] != p->nodes[1] + && p->nodes[0]->contents != CONTENTS_SOLID && p->nodes[1]->contents != CONTENTS_SOLID + && p->nodes[0]->contents != CONTENTS_SKY && p->nodes[1]->contents != CONTENTS_SKY) { // first make the back to front portal (forward portal) portal->points = point; @@ -1662,7 +1693,7 @@ void RemovePortalFromNodes(portal_t *portal) } else if (portal->nodes[1] == node) { - *portalpointer = portal->next[1]; + *portalpointer = portal->next[1]; portal->nodes[1] = NULL; } else @@ -1861,9 +1892,9 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer) int i, j; dheader_t *header; dmodel_t *bm; - + loadmodel->type = mod_brush; - + header = (dheader_t *)buffer; i = LittleLong (header->version); @@ -1879,7 +1910,7 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer) ((int *)header)[i] = LittleLong ( ((int *)header)[i]); // load into heap - + // LordHavoc: had to move entity loading above everything to allow parsing various settings from worldspawn Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]); @@ -1902,9 +1933,9 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer) Mod_MakeHull0 (); Mod_MakePortals(); - + mod->numframes = 2; // regular and alternate animation - + // // set up the submodels (FIXME: this is confusing) // @@ -1918,10 +1949,10 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer) mod->hulls[j].firstclipnode = bm->headnode[j]; mod->hulls[j].lastclipnode = mod->numclipnodes - 1; } - + mod->firstmodelsurface = bm->firstface; mod->nummodelsurfaces = bm->numfaces; - + VectorCopy (bm->maxs, mod->maxs); VectorCopy (bm->mins, mod->mins); diff --git a/model_brush.h b/model_brush.h index 41d42c95..2d2634eb 100644 --- a/model_brush.h +++ b/model_brush.h @@ -149,6 +149,10 @@ typedef struct mnode_s struct mnode_s *parent; struct mportal_s *portals; + // for bounding box culling + vec3_t mins; + vec3_t maxs; + // node specific mplane_t *plane; struct mnode_s *children[2]; @@ -167,15 +171,15 @@ typedef struct mleaf_s struct mnode_s *parent; struct mportal_s *portals; -// leaf specific -// int visframe; // visible if current (r_framecount) -// int worldnodeframe; // used by certain worldnode variants to avoid processing the same leaf twice in a frame - int portalmarkid; // used by polygon-through-portals visibility checker - // for bounding box culling vec3_t mins; vec3_t maxs; +// leaf specific + int visframe; // visible if current (r_framecount) + int worldnodeframe; // used by certain worldnode variants to avoid processing the same leaf twice in a frame + int portalmarkid; // used by polygon-through-portals visibility checker + // LordHavoc: leaf based dynamic lighting int dlightbits[8]; int dlightframe; diff --git a/render.h b/render.h index b8f164f6..041c3bc7 100644 --- a/render.h +++ b/render.h @@ -201,4 +201,5 @@ void R_Entity_Callback(void *data, void *junk); extern cvar_t r_render; extern cvar_t r_upload; +extern cvar_t r_ser; #include "image.h"