diff --git a/engine/client/p_script.c b/engine/client/p_script.c index af05422b..c1af8104 100644 --- a/engine/client/p_script.c +++ b/engine/client/p_script.c @@ -4007,7 +4007,7 @@ static void PScript_EmitSkyEffectTris(model_t *mod, msurface_t *fa, int ptype) v2 = v3; } } -static void P_AddRainParticles(model_t *mod, vec3_t axis[3], vec3_t eorg, int visframe, float contribution) +static void P_AddRainParticles(model_t *mod, vec3_t axis[3], vec3_t eorg, float contribution) { float x; float y; @@ -4018,6 +4018,9 @@ static void P_AddRainParticles(model_t *mod, vec3_t axis[3], vec3_t eorg, int vi skytris_t *st; size_t nc,oc; float ot; + int area; + int cluster; + unsigned int contentbits; if (mod->engineflags & MDLF_RECALCULATERAIN) { @@ -4073,12 +4076,6 @@ static void P_AddRainParticles(model_t *mod, vec3_t axis[3], vec3_t eorg, int vi for (st = mod->skytris; st; st = st->next) { - if (st->face->visframe != visframe) - { - st->nexttime = mod->skytime; - continue; - } - if ((unsigned int)st->ptype >= (unsigned int)numparticletypes) continue; type = &part_type[st->ptype]; @@ -4110,6 +4107,15 @@ static void P_AddRainParticles(model_t *mod, vec3_t axis[3], vec3_t eorg, int vi if (VectorLength(vdist) > (1024+512)*frandom()) continue; + if (cl.worldmodel->funcs.InfoForPoint) + { + cl.worldmodel->funcs.InfoForPoint(cl.worldmodel, worg, &area, &cluster, &contentbits); + if (contentbits & FTECONTENTS_SOLID) + continue; + if (r_refdef.scenevis && !(r_refdef.scenevis[cluster>>3] & (1<<(cluster&7)))) + continue; + } + if (st->face->flags & SURF_PLANEBACK) VectorScale(st->face->plane->normal, -1, vdist); else @@ -4120,10 +4126,8 @@ static void P_AddRainParticles(model_t *mod, vec3_t axis[3], vec3_t eorg, int vi wnorm[2] = DotProduct(vdist, axis[2]); VectorMA(worg, 0.5, wnorm, worg); - if (!(cl.worldmodel->funcs.PointContents(cl.worldmodel, NULL, worg) & FTECONTENTS_SOLID)) //should be paranoia, at least for the world. - { - P_RunParticleEffectType(worg, wnorm, 1, st->ptype); - } + + P_RunParticleEffectType(worg, wnorm, 1, st->ptype); } } } @@ -7713,7 +7717,7 @@ static void PScript_DrawParticles (void) entity_t *ent; int i; - P_AddRainParticles(cl.worldmodel, r_worldentity.axis, r_worldentity.origin, r_framecount, pframetime); + P_AddRainParticles(cl.worldmodel, r_worldentity.axis, r_worldentity.origin, pframetime); for (i = 0; i < cl_numvisedicts ; i++) { @@ -7723,7 +7727,7 @@ static void PScript_DrawParticles (void) //this timer, as well as the per-tri timer, are unable to deal with certain rates+sizes. it would be good to fix that... //it would also be nice to do mdls too... - P_AddRainParticles(ent->model, ent->axis, ent->origin, 0, pframetime); + P_AddRainParticles(ent->model, ent->axis, ent->origin, pframetime); } } diff --git a/engine/client/r_surf.c b/engine/client/r_surf.c index 7e542fe7..d4c06700 100644 --- a/engine/client/r_surf.c +++ b/engine/client/r_surf.c @@ -39,8 +39,6 @@ qboolean r_pushdepth; extern cvar_t r_ambient; -static vec3_t modelorg; /*set before recursively entering the visible surface finder*/ - model_t *currentmodel; static size_t maxblocksize; @@ -2082,259 +2080,7 @@ dynamic: ============================================================= */ -#if 0 -static qbyte *R_MarkLeafSurfaces_Q1 (void) -{ - qbyte *vis; - mleaf_t *leaf; - int i, j; - msurface_t *surf; - int shift; - vis = R_CalcVis_Q1(); - - for (i=0 ; inumvisleafs ; i++) - { - if (vis[i>>3] & (1<<(i&7))) - { - leaf = (mleaf_t *)&cl.worldmodel->leafs[i+1]; - - if (R_CullBox (leaf->minmaxs, leaf->minmaxs+3)) - continue; - leaf->visframe = r_visframecount; - - for (j = 0; j < leaf->nummarksurfaces; j++) - { - surf = leaf->firstmarksurface[j]; - if (surf->visframe == r_visframecount) - continue; - surf->visframe = r_visframecount; - - *surf->mark = surf; - } - } - } - - { - texture_t *tex; - - shift = Surf_LightmapShift(cl.worldmodel); - - for (i = 0; i < cl.worldmodel->numtextures; i++) - { - tex = cl.worldmodel->textures[i]; - if (!tex) - continue; - for (j = 0; j < tex->vbo.meshcount; j++) - { - surf = tex->vbo.meshlist[j]; - if (surf) - { - Surf_RenderDynamicLightmaps (surf); - - tex->vbo.meshlist[j] = NULL; - surf->sbatch->mesh[surf->sbatch->meshes++] = surf->mesh; - } - } - } - } - return vis; -} -#endif - -/* -static qbyte *Surf_MaskVis(qbyte *src, qbyte *dest) -{ - int i; - if (cl.worldmodel->leafs[i].ma -} -*/ -static qbyte *q1frustumvis; - -#ifdef Q1BSPS -/* -================ -R_RecursiveWorldNode -================ -*/ -static void Surf_RecursiveWorldNode (mnode_t *node, unsigned int clipflags) -{ - int c, side, clipped; - mplane_t *plane, *clipplane; - msurface_t *surf, **mark; - mleaf_t *pleaf; - double dot; - -start: - - if (node->contents == Q1CONTENTS_SOLID) - return; // solid - - if (node->visframe != r_visframecount) - return; - - for (c = 0, clipplane = r_refdef.frustum; c < r_refdef.frustum_numworldplanes; c++, clipplane++) - { - if (!(clipflags & (1 << c))) - continue; // don't need to clip against it - - clipped = BOX_ON_PLANE_SIDE (node->minmaxs, node->minmaxs + 3, clipplane); - if (clipped == 2) - return; - else if (clipped == 1) - clipflags -= (1<contents < 0) - { - pleaf = (mleaf_t *)node; - - c = (pleaf - cl.worldmodel->leafs)-1; - q1frustumvis[c>>3] |= 1<<(c&7); - - mark = pleaf->firstmarksurface; - c = pleaf->nummarksurfaces; - - if (c) - { - do - { - (*mark++)->visframe = r_framecount; - } while (--c); - } - return; - } - -// node is just a decision point, so go down the apropriate sides - -// find which side of the node we are on - plane = node->plane; - - switch (plane->type) - { - case PLANE_X: - dot = modelorg[0] - plane->dist; - break; - case PLANE_Y: - dot = modelorg[1] - plane->dist; - break; - case PLANE_Z: - dot = modelorg[2] - plane->dist; - break; - default: - dot = DotProduct (modelorg, plane->normal) - plane->dist; - break; - } - - if (dot >= 0) - side = 0; - else - side = 1; - -// recurse down the children, front side first - Surf_RecursiveWorldNode (node->children[side], clipflags); - -// draw stuff - c = node->numsurfaces; - - if (c) - { - surf = cl.worldmodel->surfaces + node->firstsurface; - - if (dot < 0 -BACKFACE_EPSILON) - side = SURF_PLANEBACK; - else if (dot > BACKFACE_EPSILON) - side = 0; - { - for ( ; c ; c--, surf++) - { - if (surf->visframe != r_framecount) - continue; - - if (((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK))) - continue; // wrong side - - Surf_RenderDynamicLightmaps (surf); - surf->sbatch->mesh[surf->sbatch->meshes++] = surf->mesh; - } - } - } - -// recurse down the back side - //GLR_RecursiveWorldNode (node->children[!side], clipflags); - node = node->children[!side]; - goto start; -} - -static void Surf_OrthoRecursiveWorldNode (mnode_t *node, unsigned int clipflags) -{ - //when rendering as ortho the front and back sides are technically equal. the only culling comes from frustum culling. - - int c, clipped; - mplane_t *clipplane; - msurface_t *surf, **mark; - mleaf_t *pleaf; - - if (node->contents == Q1CONTENTS_SOLID) - return; // solid - - if (node->visframe != r_visframecount) - return; - - for (c = 0, clipplane = r_refdef.frustum; c < r_refdef.frustum_numworldplanes; c++, clipplane++) - { - if (!(clipflags & (1 << c))) - continue; // don't need to clip against it - - clipped = BOX_ON_PLANE_SIDE (node->minmaxs, node->minmaxs + 3, clipplane); - if (clipped == 2) - return; - else if (clipped == 1) - clipflags -= (1<contents < 0) - { - pleaf = (mleaf_t *)node; - - mark = pleaf->firstmarksurface; - c = pleaf->nummarksurfaces; - - if (c) - { - do - { - (*mark++)->visframe = r_framecount; - } while (--c); - } - return; - } - -// recurse down the children - Surf_OrthoRecursiveWorldNode (node->children[0], clipflags); - Surf_OrthoRecursiveWorldNode (node->children[1], clipflags); - -// draw stuff - c = node->numsurfaces; - - if (c) - { - surf = cl.worldmodel->surfaces + node->firstsurface; - - for ( ; c ; c--, surf++) - { - if (surf->visframe != r_framecount) - continue; - - Surf_RenderDynamicLightmaps (surf); - surf->sbatch->mesh[surf->sbatch->meshes++] = surf->mesh; - } - } - return; -} -#endif static void Surf_PushChains(batch_t **batches) { @@ -2417,7 +2163,6 @@ void Surf_SetupFrame(void) r_refdef.flags |= RDF_NOWORLDMODEL; R_AnimateLight(); - r_framecount++; if (r_refdef.recurse) { @@ -2912,7 +2657,7 @@ static void Surf_SimpleWorld_Q1BSP(struct webostate_s *es, qbyte *pvs) mesh_t *mesh; model_t *wmodel = es->wmodel; int l = wmodel->numclusters; - int fc = -r_framecount; + int fc = es->framecount; int i; // int s, f, lastface; struct wesbatch_s *eb; @@ -3360,6 +3105,7 @@ void Surf_DrawWorld (void) if (gennew) { int i; + static int ebogensequence; if (!currentmodel->numbatches) { int sortid; @@ -3401,7 +3147,7 @@ void Surf_DrawWorld (void) } VectorCopy(r_refdef.vieworg, webogenerating->lastpos); webogenerating->wmodel = currentmodel; - webogenerating->framecount = -r_framecount; + webogenerating->framecount = --ebogensequence; webogenerating->cluster[0] = r_viewcluster; webogenerating->cluster[1] = r_viewcluster2; webogenerating->pvs.buffer = (qbyte*)(webogenerating+1) + sizeof(webogenerating->batches[0])*(currentmodel->numbatches-1); @@ -3430,6 +3176,11 @@ void Surf_DrawWorld (void) COM_WorkerPartialSync(webogenerating, &webogeneratingstate, true); } } + else if (webogenerating && !webostate) + { //block the first time around to avoid possible race conditions. + webostate = webogenerating; + COM_WorkerPartialSync(webogenerating, &webogeneratingstate, true); + } if (webostate) { @@ -3483,27 +3234,6 @@ void Surf_DrawWorld (void) entvis = surfvis = NULL; R_DoomWorld(); } -#endif -#ifdef Q1BSPS - else if (currentmodel->fromgame == fg_quake || currentmodel->fromgame == fg_halflife) - { - pvsbuffer_t *vis = &surf_frustumvis[r_refdef.recurse]; - - entvis = R_MarkLeaves_Q1 (false); - if (!(r_novis.ival & 2)) - VectorCopy (r_origin, modelorg); - - if (vis->buffersize < currentmodel->pvsbytes) - vis->buffer = BZ_Realloc(vis->buffer, vis->buffersize=currentmodel->pvsbytes); - q1frustumvis = vis->buffer; - memset(q1frustumvis, 0, currentmodel->pvsbytes); - - if (r_refdef.useperspective) - Surf_RecursiveWorldNode (currentmodel->nodes, 0x1f); - else - Surf_OrthoRecursiveWorldNode (currentmodel->nodes, 0x1f); - surfvis = q1frustumvis; - } #endif else entvis = surfvis = NULL; @@ -4210,8 +3940,6 @@ void Surf_BuildLightmaps (void) R_BumpLightstyles(maxstyle); //should only really happen with lazy loading R_AnimateLight(); - r_framecount = 1; // no dlightcache - while(numlightmaps > 0) { numlightmaps--; @@ -4276,9 +4004,9 @@ void Surf_NewMap (void) Surf_DeInit(); r_viewcluster = -1; - r_oldviewcluster = 0; + r_oldviewcluster = -5; r_viewcluster2 = -1; - r_oldviewcluster2 = 0; + r_oldviewcluster2 = -4; #ifdef BEF_PUSHDEPTH r_pushdepth = false; for (s = r_polygonoffset_submodel_maps.string; s && *s; ) diff --git a/engine/client/render.h b/engine/client/render.h index cb86422e..52bc7d8a 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -27,8 +27,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define TOP_RANGE (TOP_DEFAULT<<4) #define BOTTOM_RANGE (BOTTOM_DEFAULT<<4) -extern int r_framecount; - struct msurface_s; struct batch_s; struct model_s; @@ -615,7 +613,6 @@ void Media_VideoRestarted(void); void MYgluPerspective(double fovx, double fovy, double zNear, double zFar); void R_PushDlights (void); -qbyte *R_MarkLeaves_Q1 (qboolean getvisonly); qbyte *R_CalcVis_Q1 (void); qbyte *R_MarkLeaves_Q2 (void); qbyte *R_MarkLeaves_Q3 (void); diff --git a/engine/client/renderer.c b/engine/client/renderer.c index ef76e4d1..936a7b4e 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -2662,115 +2662,8 @@ unsigned int r_viewcontents; //mleaf_t *r_viewleaf2, *r_oldviewleaf2; int r_viewarea; int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2; -int r_visframecount; -static pvsbuffer_t curframevis[R_MAX_RECURSE]; -#ifdef Q1BSPS -qbyte *R_MarkLeaves_Q1 (qboolean getvisonly) -{ - static qbyte *cvis[R_MAX_RECURSE]; - qbyte *vis; - mnode_t *node; - int i; - int portal = r_refdef.recurse; - - //for portals to work, we need two sets of any pvs caches - //this means lights can still check pvs at the end of the frame despite recursing in the mean time - //however, we still need to invalidate the cache because we only have one 'visframe' field in nodes. - - if (r_refdef.forcevis) - { - vis = cvis[portal] = r_refdef.forcedvis; - - r_oldviewcluster = -1; - r_oldviewcluster2 = -2; - } - else - { - if (!portal) - { - if (((r_oldviewcluster == r_viewcluster && r_oldviewcluster2 == r_viewcluster2) && !r_novis.ival) || r_novis.ival & 2) - return cvis[portal]; - - r_oldviewcluster = r_viewcluster; - r_oldviewcluster2 = r_viewcluster2; - } - else - { - r_oldviewcluster = -1; - r_oldviewcluster2 = -2; - } - - if (r_novis.ival) - { - if (curframevis[portal].buffersize < cl.worldmodel->pvsbytes) - curframevis[portal].buffer = BZ_Realloc(curframevis[portal].buffer, curframevis[portal].buffersize=cl.worldmodel->pvsbytes); - vis = cvis[portal] = curframevis[portal].buffer; - memset (curframevis[portal].buffer, 0xff, curframevis[portal].buffersize); - - r_oldviewcluster = -1; - r_oldviewcluster2 = -2; - } - else - { - if (r_viewcluster2 != -1 && r_viewcluster2 != r_viewcluster) - { - vis = cvis[portal] = cl.worldmodel->funcs.ClusterPVS(cl.worldmodel, r_viewcluster, &curframevis[portal], PVM_REPLACE); - vis = cvis[portal] = cl.worldmodel->funcs.ClusterPVS(cl.worldmodel, r_viewcluster2, &curframevis[portal], PVM_MERGE); - } - else - vis = cvis[portal] = cl.worldmodel->funcs.ClusterPVS(cl.worldmodel, r_viewcluster, &curframevis[portal], PVM_FAST); - } - } - - r_visframecount++; - - if (getvisonly) - return vis; - else if (r_viewcluster == -1) - { - //to improve spectating, when the camera is in a wall, we ignore any sky leafs. - //this prevents seeing the upwards-facing sky surfaces within the sky volumes. - //this will not affect inwards facing sky, so sky will basically appear as though it is identical to solid brushes. - for (i=0 ; inumclusters ; i++) - { - if (vis[i>>3] & (1<<(i&7))) - { - if (cl.worldmodel->leafs[i+1].contents == Q1CONTENTS_SKY) - continue; - node = (mnode_t *)&cl.worldmodel->leafs[i+1]; - do - { - if (node->visframe == r_visframecount) - break; - node->visframe = r_visframecount; - node = node->parent; - } while (node); - } - } - } - else - { - for (i=0 ; inumclusters ; i++) - { - if (vis[i>>3] & (1<<(i&7))) - { - node = (mnode_t *)&cl.worldmodel->leafs[i+1]; - do - { - if (node->visframe == r_visframecount) - break; - node->visframe = r_visframecount; - node = node->parent; - } while (node); - } - } - } - return vis; -} -#endif - /* ================= R_CullBox diff --git a/engine/common/gl_q2bsp.c b/engine/common/gl_q2bsp.c index aec3f108..b6eb27af 100644 --- a/engine/common/gl_q2bsp.c +++ b/engine/common/gl_q2bsp.c @@ -7344,6 +7344,8 @@ static unsigned int Q2BSP_PointContents(model_t *mod, const vec3_t axis[3], cons #ifdef HAVE_CLIENT static qbyte *frustumvis; static vec3_t modelorg; +static unsigned int scenesequence; +static unsigned int vissequence; /* =============== R_MarkLeaves @@ -7373,7 +7375,7 @@ qbyte *R_MarkLeaves_Q3 (void) // if (r_lockpvs->value) // return; - r_visframecount++; + vissequence++; r_oldviewcluster = r_viewcluster; if (r_novis.ival || r_viewcluster == -1 || !cl.worldmodel->vis ) @@ -7390,12 +7392,12 @@ qbyte *R_MarkLeaves_Q3 (void) #if 1 for (node = (mnode_t*)leaf; node; node = node->parent) { - if (node->visframe == r_visframecount) + if (node->visframe == vissequence) break; - node->visframe = r_visframecount; + node->visframe = vissequence; } #else - leaf->visframe = r_visframecount; + leaf->visframe = vissequence; leaf->vischain = r_vischain; r_vischain = leaf; #endif @@ -7416,12 +7418,12 @@ qbyte *R_MarkLeaves_Q3 (void) #if 1 for (node = (mnode_t*)leaf; node; node = node->parent) { - if (node->visframe == r_visframecount) + if (node->visframe == vissequence) break; - node->visframe = r_visframecount; + node->visframe = vissequence; } #else - leaf->visframe = r_visframecount; + leaf->visframe = vissequence; leaf->vischain = r_vischain; r_vischain = leaf; #endif @@ -7442,7 +7444,7 @@ static void Surf_RecursiveQ3WorldNode (mnode_t *node, unsigned int clipflags) start: - if (node->visframe != r_visframecount) + if (node->visframe != vissequence) return; for (c = 0, clipplane = r_refdef.frustum; c < r_refdef.frustum_numworldplanes; c++, clipplane++) @@ -7473,9 +7475,9 @@ start: for (c = pleaf->nummarksurfaces; c; c--) { surf = *mark++; - if (surf->visframe == r_framecount) + if (surf->visframe == scenesequence) continue; - surf->visframe = r_framecount; + surf->visframe = scenesequence; // if (((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK))) // continue; // wrong side @@ -7568,9 +7570,9 @@ qbyte *R_MarkLeaves_Q2 (void) { // mark everything for (i=0 ; inumleafs ; i++) - cl.worldmodel->leafs[i].visframe = r_visframecount; + cl.worldmodel->leafs[i].visframe = vissequence; for (i=0 ; inumnodes ; i++) - cl.worldmodel->nodes[i].visframe = r_visframecount; + cl.worldmodel->nodes[i].visframe = vissequence; return vis; } @@ -7584,7 +7586,7 @@ qbyte *R_MarkLeaves_Q2 (void) cvis[portal] = vis; } - r_visframecount++; + vissequence++; for (i=0,leaf=cl.worldmodel->leafs ; inumleafs ; i++, leaf++) { @@ -7596,9 +7598,9 @@ qbyte *R_MarkLeaves_Q2 (void) node = (mnode_t *)leaf; do { - if (node->visframe == r_visframecount) + if (node->visframe == vissequence) break; - node->visframe = r_visframecount; + node->visframe = vissequence; node = node->parent; } while (node); } @@ -7618,7 +7620,7 @@ static void Surf_RecursiveQ2WorldNode (mnode_t *node) if (node->contents == Q2CONTENTS_SOLID) return; // solid - if (node->visframe != r_visframecount) + if (node->visframe != vissequence) return; if (R_CullBox (node->minmaxs, node->minmaxs+3)) return; @@ -7643,7 +7645,7 @@ static void Surf_RecursiveQ2WorldNode (mnode_t *node) { do { - (*mark)->visframe = r_framecount; + (*mark)->visframe = scenesequence; mark++; } while (--c); } @@ -7688,13 +7690,13 @@ static void Surf_RecursiveQ2WorldNode (mnode_t *node) // draw stuff for ( c = node->numsurfaces, surf = currentmodel->surfaces + node->firstsurface; c ; c--, surf++) { - if (surf->visframe != r_framecount) + if (surf->visframe != scenesequence) continue; if ( (surf->flags & SURF_PLANEBACK) != sidebit ) continue; // wrong side - surf->visframe = 0;//r_framecount+1;//-1; + surf->visframe = 0;//scenesequence+1;//-1; Surf_RenderDynamicLightmaps (surf); @@ -7720,6 +7722,7 @@ static void CM_PrepareFrame(model_t *mod, refdef_t *refdef, int area, int viewcl VectorCopy (r_refdef.vieworg, modelorg); + scenesequence++; #ifdef Q3BSPS if (currentmodel->fromgame == fg_quake3) { diff --git a/engine/common/q1bsp.c b/engine/common/q1bsp.c index ead5018f..b8dda440 100644 --- a/engine/common/q1bsp.c +++ b/engine/common/q1bsp.c @@ -174,7 +174,7 @@ size_t Fragment_ClipPlaneToBrush(vecV_t *points, size_t maxpoints, void *planes, return numverts; } -#ifndef SERVERONLY +#ifdef HAVE_CLIENT #define MAXFRAGMENTTRIS 256 vec3_t decalfragmentverts[MAXFRAGMENTTRIS*3]; @@ -1642,7 +1642,7 @@ Physics functions (common) Rendering functions (Client only) */ -#ifndef SERVERONLY +#ifdef HAVE_CLIENT extern int r_dlightframecount; @@ -1749,6 +1749,327 @@ static void Q1BSP_StainNode (mnode_t *node, float *parms) Q1BSP_StainNode (node->children[0], parms); Q1BSP_StainNode (node->children[1], parms); } + + +static qbyte *q1frustumvis; //temp use +static int q1_visframecount;//temp use +static int q1_framecount; //temp use +struct q1bspprv_s +{ + int visframecount; + int framecount; + int oldviewclusters[2]; +}; +#define BACKFACE_EPSILON 0.01 +static void Q1BSP_RecursiveWorldNode (mnode_t *node, unsigned int clipflags) +{ + int c, side, clipped; + mplane_t *plane, *clipplane; + msurface_t *surf, **mark; + mleaf_t *pleaf; + double dot; + +start: + + if (node->contents == Q1CONTENTS_SOLID) + return; // solid + + if (node->visframe != q1_visframecount) + return; + + for (c = 0, clipplane = r_refdef.frustum; c < r_refdef.frustum_numworldplanes; c++, clipplane++) + { + if (!(clipflags & (1 << c))) + continue; // don't need to clip against it + + clipped = BOX_ON_PLANE_SIDE (node->minmaxs, node->minmaxs + 3, clipplane); + if (clipped == 2) + return; + else if (clipped == 1) + clipflags -= (1<contents < 0) + { + pleaf = (mleaf_t *)node; + + c = (pleaf - cl.worldmodel->leafs)-1; + q1frustumvis[c>>3] |= 1<<(c&7); + + mark = pleaf->firstmarksurface; + c = pleaf->nummarksurfaces; + + if (c) + { + do + { + (*mark++)->visframe = q1_framecount; + } while (--c); + } + return; + } + +// node is just a decision point, so go down the apropriate sides + +// find which side of the node we are on + plane = node->plane; + + switch (plane->type) + { + case PLANE_X: + dot = r_origin[0] - plane->dist; + break; + case PLANE_Y: + dot = r_origin[1] - plane->dist; + break; + case PLANE_Z: + dot = r_origin[2] - plane->dist; + break; + default: + dot = DotProduct (r_origin, plane->normal) - plane->dist; + break; + } + + if (dot >= 0) + side = 0; + else + side = 1; + +// recurse down the children, front side first + Q1BSP_RecursiveWorldNode (node->children[side], clipflags); + +// draw stuff + c = node->numsurfaces; + + if (c) + { + surf = cl.worldmodel->surfaces + node->firstsurface; + + if (dot < 0 -BACKFACE_EPSILON) + side = SURF_PLANEBACK; + else if (dot > BACKFACE_EPSILON) + side = 0; + { + for ( ; c ; c--, surf++) + { + if (surf->visframe != q1_framecount) + continue; + + if (((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK))) + continue; // wrong side + + Surf_RenderDynamicLightmaps (surf); + surf->sbatch->mesh[surf->sbatch->meshes++] = surf->mesh; + } + } + } + +// recurse down the back side + //GLR_RecursiveWorldNode (node->children[!side], clipflags); + node = node->children[!side]; + goto start; +} + +static void Q1BSP_OrthoRecursiveWorldNode (mnode_t *node, unsigned int clipflags) +{ + //when rendering as ortho the front and back sides are technically equal. the only culling comes from frustum culling. + + int c, clipped; + mplane_t *clipplane; + msurface_t *surf, **mark; + mleaf_t *pleaf; + + if (node->contents == Q1CONTENTS_SOLID) + return; // solid + + if (node->visframe != q1_visframecount) + return; + + for (c = 0, clipplane = r_refdef.frustum; c < r_refdef.frustum_numworldplanes; c++, clipplane++) + { + if (!(clipflags & (1 << c))) + continue; // don't need to clip against it + + clipped = BOX_ON_PLANE_SIDE (node->minmaxs, node->minmaxs + 3, clipplane); + if (clipped == 2) + return; + else if (clipped == 1) + clipflags -= (1<contents < 0) + { + pleaf = (mleaf_t *)node; + + mark = pleaf->firstmarksurface; + c = pleaf->nummarksurfaces; + + if (c) + { + do + { + (*mark++)->visframe = q1_framecount; + } while (--c); + } + return; + } + +// recurse down the children + Q1BSP_OrthoRecursiveWorldNode (node->children[0], clipflags); + Q1BSP_OrthoRecursiveWorldNode (node->children[1], clipflags); + +// draw stuff + c = node->numsurfaces; + + if (c) + { + surf = cl.worldmodel->surfaces + node->firstsurface; + + for ( ; c ; c--, surf++) + { + if (surf->visframe != q1_framecount) + continue; + + Surf_RenderDynamicLightmaps (surf); + surf->sbatch->mesh[surf->sbatch->meshes++] = surf->mesh; + } + } + return; +} + +static qbyte *Q1BSP_MarkLeaves (model_t *model, int clusters[2]) +{ + static qbyte *cvis; + qbyte *vis; + mnode_t *node; + int i; + int portal = r_refdef.recurse; + static pvsbuffer_t pvsbuf; + struct q1bspprv_s *prv = model->meshinfo; + + q1_framecount = ++prv->framecount; + + //for portals to work, we need two sets of any pvs caches + //this means lights can still check pvs at the end of the frame despite recursing in the mean time + //however, we still need to invalidate the cache because we only have one 'visframe' field in nodes. + + if (r_refdef.forcevis) + { + vis = r_refdef.forcedvis; + + prv->oldviewclusters[0] = -1; + prv->oldviewclusters[1] = -2; + cvis = NULL; + } + else + { + if (!portal) + { + if (((prv->oldviewclusters[0] == clusters[0] && prv->oldviewclusters[1] == clusters[1]) && !r_novis.ival) || r_novis.ival & 2) + if (cvis) + { + q1_visframecount = prv->visframecount; + return cvis; + } + + prv->oldviewclusters[0] = clusters[0]; + prv->oldviewclusters[1] = clusters[1]; + } + else + { + prv->oldviewclusters[0] = -1; + prv->oldviewclusters[1] = -2; + cvis = NULL; + } + + if (r_novis.ival) + { + if (pvsbuf.buffersize < model->pvsbytes) + pvsbuf.buffer = BZ_Realloc(pvsbuf.buffer, pvsbuf.buffersize=model->pvsbytes); + vis = cvis = pvsbuf.buffer; + memset (pvsbuf.buffer, 0xff, pvsbuf.buffersize); + + prv->oldviewclusters[0] = -1; + prv->oldviewclusters[1] = -2; + } + else + { + if (clusters[1] >= 0 && clusters[1] != clusters[0]) + { + vis = cvis = model->funcs.ClusterPVS(model, clusters[0], &pvsbuf, PVM_REPLACE); + vis = cvis = model->funcs.ClusterPVS(model, clusters[1], &pvsbuf, PVM_MERGE); + } + else + vis = cvis = model->funcs.ClusterPVS(model, clusters[0], &pvsbuf, PVM_FAST); + } + } + + prv->visframecount++; + q1_visframecount = prv->visframecount; + + if (clusters[0] < 0) + { + //to improve spectating, when the camera is in a wall, we ignore any sky leafs. + //this prevents seeing the upwards-facing sky surfaces within the sky volumes. + //this will not affect inwards facing sky, so sky will basically appear as though it is identical to solid brushes. + for (i=0 ; inumclusters ; i++) + { + if (vis[i>>3] & (1<<(i&7))) + { + if (model->leafs[i+1].contents == Q1CONTENTS_SKY) + continue; + node = (mnode_t *)&model->leafs[i+1]; + do + { + if (node->visframe == q1_visframecount) + break; + node->visframe = q1_visframecount; + node = node->parent; + } while (node); + } + } + } + else + { + for (i=0 ; inumclusters ; i++) + { + if (vis[i>>3] & (1<<(i&7))) + { + node = (mnode_t *)&model->leafs[i+1]; + do + { + if (node->visframe == q1_visframecount) + break; + node->visframe = q1_visframecount; + node = node->parent; + } while (node); + } + } + } + return vis; +} + +static void Q1BSP_PrepareFrame(model_t *model, refdef_t *refdef, int area, int clusters[2], pvsbuffer_t *vis, qbyte **entvis_out, qbyte **surfvis_out) +{ + *entvis_out = Q1BSP_MarkLeaves (model, clusters); + + if (vis->buffersize < model->pvsbytes) + vis->buffer = BZ_Realloc(vis->buffer, vis->buffersize=model->pvsbytes); + q1frustumvis = vis->buffer; + memset(q1frustumvis, 0, model->pvsbytes); + + if (model != cl.worldmodel) + ; //global abuse... + else if (r_refdef.useperspective) + Q1BSP_RecursiveWorldNode (model->nodes, 0x1f); + else + Q1BSP_OrthoRecursiveWorldNode (model->nodes, 0x1f); + *surfvis_out = q1frustumvis; +} + + #endif /* Rendering functions (Client only) @@ -1757,7 +2078,7 @@ Rendering functions (Client only) Server only functions */ -#ifndef CLIENTONLY +#ifdef HAVE_SERVER static qbyte *Q1BSP_ClusterPVS (model_t *model, int cluster, pvsbuffer_t *buffer, pvsmerge_t merge); //does the recursive work of Q1BSP_FatPVS @@ -2197,6 +2518,7 @@ void Q1BSP_SetModelFuncs(model_t *mod) mod->funcs.NativeTrace = Q1BSP_Trace; mod->funcs.PointContents = Q1BSP_PointContents; + mod->funcs.InfoForPoint = Q1BSP_InfoForPoint; #ifdef HAVE_CLIENT mod->funcs.LightPointValues = GLQ1BSP_LightPointValues; mod->funcs.MarkLights = Q1BSP_MarkLights; @@ -2204,9 +2526,14 @@ void Q1BSP_SetModelFuncs(model_t *mod) #ifdef RTLIGHTS mod->funcs.GenerateShadowMesh = Q1BSP_GenerateShadowMesh; #endif -#endif + mod->funcs.PrepareFrame = Q1BSP_PrepareFrame; - mod->funcs.InfoForPoint = Q1BSP_InfoForPoint; + { + struct q1bspprv_s *prv = mod->meshinfo = ZG_Malloc(&mod->memgroup, sizeof(struct q1bspprv_s)); + prv->oldviewclusters[0] = -2; //make sure its reset properly. + prv->oldviewclusters[1] = -3; + } +#endif } #endif @@ -2305,7 +2632,7 @@ bspx_header_t *BSPX_Setup(model_t *mod, char *filebase, size_t filelen, lump_t * return h; } -#ifdef SERVERONLY +#ifndef HAVE_CLIENT void BSPX_LoadEnvmaps(model_t *mod, bspx_header_t *bspx, void *mod_base) { } diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index 180a7a2c..c238ccd5 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -1211,13 +1211,8 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e skins += e->skinnum; else { - if (developer.ival) - { - static int lastframe; - if (lastframe != r_framecount && lastframe != r_framecount-1) //patented anti-spam technology!... actually, I wonder if it would actually be eligable for a patent. - Con_DPrintf("Skin number out of range (%u >= %u - %s)\n", e->skinnum, inf->numskins, model->name); - lastframe = r_framecount; - } + static float timer; + Con_ThrottlePrintf(&timer, 1, "Skin number out of range (%u >= %u - %s)\n", e->skinnum, inf->numskins, model->name); if (!inf->numskins) return NULL; } diff --git a/engine/gl/gl_rlight.c b/engine/gl/gl_rlight.c index ec13af20..caa51a21 100644 --- a/engine/gl/gl_rlight.c +++ b/engine/gl/gl_rlight.c @@ -728,7 +728,7 @@ void R_PushDlights (void) int i; dlight_t *l; - r_dlightframecount = r_framecount + 1; // because the count hasn't + r_dlightframecount++; // because the count hasn't // advanced yet for this frame #ifdef RTLIGHTS diff --git a/engine/gl/gl_rmain.c b/engine/gl/gl_rmain.c index 7ce1ebc6..f00b06be 100644 --- a/engine/gl/gl_rmain.c +++ b/engine/gl/gl_rmain.c @@ -34,9 +34,6 @@ void R_RenderBrushPoly (msurface_t *fa); extern int gl_stencilbits; -extern int r_visframecount; // bumped when going to a new PVS -extern int r_framecount; // used for dlight push checking - //mplane_t frustum[4]; // @@ -831,7 +828,6 @@ static void R_RenderScene (void) stereoframes = 2; } - r_framecount++; if (vid.vr && !r_refdef.recurse && vid.vr->Render(R_RenderEyeScene)) ; //we drew something VR-ey else if (stereomode == STEREO_OFF) @@ -897,7 +893,6 @@ static void R_RenderScene (void) qglClear (GL_DEPTH_BUFFER_BIT); depthcleared = true; } - r_framecount++; //view position changes, if only slightly. which means we need to rebuild vis info. :( eyeangorg[0][0] = 0; eyeangorg[0][1] = r_stereo_convergence.value * (i?0.5:-0.5); @@ -1867,8 +1862,6 @@ qboolean R_RenderScene_Cubemap(void) GL_MTBind(0, GL_TEXTURE_CUBE_MAP_ARB, scenepp_postproc_cube); qglCopyTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + i, 0, 0, 0, 0, vid.fbpheight - (prect.y + cmapsize), cmapsize, cmapsize); } - - r_framecount++; } if (usefbo) diff --git a/engine/gl/gl_shadow.c b/engine/gl/gl_shadow.c index aa74282c..a834d940 100644 --- a/engine/gl/gl_shadow.c +++ b/engine/gl/gl_shadow.c @@ -1827,37 +1827,7 @@ static qboolean Sh_VisOverlaps(qbyte *v1, qbyte *v2) return false; } -#if 1 #define Sh_LeafInView Sh_VisOverlaps -#else -static qboolean Sh_LeafInView(qbyte *lightvis, qbyte *vvis) -{ - int i; - int m = (cl.worldmodel->numvisleafs); - mleaf_t *wl = cl.worldmodel->leafs; - unsigned char lv; - - /*we can potentially walk off the end of the leafs, but lightvis shouldn't be set for those*/ - - - for (i = 0; i < m; i += 1<<3) - { - lv = lightvis[i>>3];// & vvis[i>>3]; - if (!lv) - continue; - if ((lv&0x01) && wl[i+0].visframe == r_visframecount) return true; - if ((lv&0x02) && wl[i+1].visframe == r_visframecount) return true; - if ((lv&0x04) && wl[i+2].visframe == r_visframecount) return true; - if ((lv&0x08) && wl[i+3].visframe == r_visframecount) return true; - if ((lv&0x10) && wl[i+4].visframe == r_visframecount) return true; - if ((lv&0x20) && wl[i+5].visframe == r_visframecount) return true; - if ((lv&0x40) && wl[i+6].visframe == r_visframecount) return true; - if ((lv&0x80) && wl[i+7].visframe == r_visframecount) return true; - } - - return false; -} -#endif /* diff --git a/engine/gl/glquake.h b/engine/gl/glquake.h index 7e737f39..02ef4c6b 100644 --- a/engine/gl/glquake.h +++ b/engine/gl/glquake.h @@ -270,8 +270,6 @@ FTE_DEPRECATED extern glvert_t glv; //#define SKYSIZE (1 << SKYSHIFT) //#define SKYMASK (SKYSIZE - 1) -#define BACKFACE_EPSILON 0.01 - void R_TimeRefresh_f (void); @@ -282,8 +280,6 @@ void R_TimeRefresh_f (void); extern entity_t r_worldentity; extern vec3_t r_entorigin; extern entity_t *currententity; -extern int r_visframecount; // ??? what difs? -extern int r_framecount; //number of scenes drawn (specifically, number of times the world is frustum culled) extern qboolean r_loadbumpmapping; diff --git a/engine/vk/vk_init.c b/engine/vk/vk_init.c index a5db84db..cddb79b3 100644 --- a/engine/vk/vk_init.c +++ b/engine/vk/vk_init.c @@ -2750,7 +2750,6 @@ static qboolean VK_R_RenderScene_Cubemap(struct vk_rendertarg *fb) Con_Printf("no flush\n"); VKBE_RT_End(&rtc->face[i]); - r_framecount++; } r_refdef.vrect = vrect; diff --git a/plugins/hl2/mod_vbsp.c b/plugins/hl2/mod_vbsp.c index ffdeeacc..1ad21aee 100644 --- a/plugins/hl2/mod_vbsp.c +++ b/plugins/hl2/mod_vbsp.c @@ -3689,7 +3689,7 @@ static void VBSP_MarkShadows(model_t *model, dlight_t *dl, const qbyte *lvis) } }*/ } -void VBSP_GenerateShadowMesh(model_t *model, dlight_t *dl, const qbyte *lightvis, qbyte *litvis, void (*callback)(msurface_t *surf)) +static void VBSP_GenerateShadowMesh(model_t *model, dlight_t *dl, const qbyte *lightvis, qbyte *litvis, void (*callback)(msurface_t *surf)) { vbspinfo_t *prv = model->meshinfo; dispinfo_t *disp;