port broad phase clipping checks from interstice

This commit is contained in:
Shpuld Shpuldson 2023-09-05 08:45:55 +03:00
parent 52ad56f8c2
commit d9e7fe2f4c
5 changed files with 91 additions and 18 deletions

View file

@ -332,6 +332,8 @@ void EmitBothSkyLayers (msurface_t *fa);
void EmitUnderWaterPolys (void);
void EmitDetailPolys (void);
void R_DrawSkyChain (msurface_t *s);
int R_FrustumCheckBox (vec3_t mins, vec3_t maxs);
int R_FrustumCheckSphere (vec3_t centre, float radius);
int R_CullBox (vec3_t emins, vec3_t emaxs);
qboolean R_CullSphere (vec3_t centre, float radius);
void R_MarkLights (dlight_t *light, int bit, mnode_t *node);

View file

@ -309,6 +309,50 @@ void R_RotateForViewEntity (entity_t *ent)
sceGumRotateZYX(&rotation);
}
/*
=================
R_FrustumCheckBox
Returns 0 if box completely inside frustum
Returns +N with intersected planes count as N
Returns -1 when completely outside frustum
=================
*/
int R_FrustumCheckBox (vec3_t mins, vec3_t maxs)
{
int i, res;
int intersections = 0;
for (i=0 ; i<4 ; i++)
{
res = BoxOnPlaneSide (mins, maxs, &frustum[i]);
if (res == 2) return -1;
if (res == 3) ++intersections;
}
return intersections;
}
/*
=================
R_FrustumCheckSphere
=================
*/
int R_FrustumCheckSphere (vec3_t centre, float radius)
{
int i, res;
mplane_t *p;
int intersections = 0;
for (i=0, p=frustum ; i<4 ; i++, p++)
{
res = PlaneDiff(centre, p);
if (res <= -radius) return -1;
if (res < radius) ++intersections;
}
return intersections;
}
/*
=================
R_CullBox

View file

@ -120,6 +120,8 @@ typedef struct texture_s
#define TEXFLAG_REFLECT 512
#define TEXFLAG_NORMAL 1024
#define SURF_NEEDSCLIPPING 2048 // see texflags below
// !!! if this is changed, it must be changed in asm_draw.h too !!!
typedef struct
{

View file

@ -832,6 +832,14 @@ static void R_BlendLightmaps (void)
int ClipFace (msurface_t * fa)
{
// skip maths if broad phase tells us we don't need clipping
if (!(fa->flags & SURF_NEEDSCLIPPING))
{
fa->polys->numclippedverts = fa->polys->numverts;
fa->polys->display_list_verts = fa->polys->verts;
return fa->polys->numverts;
}
// shpuld: moved clipping here to have it in one place only
int verts_total = 0;
glpoly_t* poly = fa->polys;
@ -867,10 +875,7 @@ int ClipFace (msurface_t * fa)
poly->numclippedverts = clipped_vertex_count;
} else {
verts_total += unclipped_vertex_count;
const std::size_t buffer_size = unclipped_vertex_count * sizeof(glvert_t);
poly->display_list_verts = static_cast<glvert_t*>(sceGuGetMemory(buffer_size));
memcpy(poly->display_list_verts, unclipped_vertices, buffer_size);
poly->display_list_verts = poly->verts;
poly->numclippedverts = unclipped_vertex_count;
}
return verts_total;
@ -1162,22 +1167,25 @@ void R_DrawBrushModel (entity_t *e)
clmodel = e->model;
int frustum_check;
if (e->angles[0] || e->angles[1] || e->angles[2])
{
rotated = qtrue;
if (R_CullSphere(e->origin, clmodel->radius))
return;
frustum_check = R_FrustumCheckSphere(e->origin, clmodel->radius);
}
else
{
rotated = qfalse;
VectorAdd (e->origin, clmodel->mins, mins);
VectorAdd (e->origin, clmodel->maxs, maxs);
if (R_CullBox (mins, maxs) == 2)
return;
frustum_check = R_FrustumCheckBox(mins, maxs);
}
if (frustum_check < 0)
return;
memset (lightmap_chains, 0, sizeof(lightmap_chains));
num_lightmapped_faces = 0;
@ -1281,6 +1289,8 @@ void R_DrawBrushModel (entity_t *e)
if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
{
psurf->flags &= ~SURF_NEEDSCLIPPING;
psurf->flags |= SURF_NEEDSCLIPPING * (frustum_check > 1);
R_RenderBrushPoly (psurf);
}
}
@ -1356,7 +1366,11 @@ void R_RecursiveWorldNode (mnode_t *node)
if (node->visframe != r_visframecount)
return;
if (R_CullBox (node->minmaxs, node->minmaxs+3) == 2)
// maybe we can avoid extra checks if we remember results for "completely inside",
// then we don't need to check at all for next one? experiment with it.
int frustum_check = R_FrustumCheckBox (node->minmaxs, node->minmaxs+3);
if (frustum_check < 0)
return;
// if a leaf node, draw stuff
@ -1435,14 +1449,17 @@ void R_RecursiveWorldNode (mnode_t *node)
// if sorting by texture, just store it out
/*if (gl_texsort.value)*/
if (!mirror
|| surf->texinfo->texture != cl.worldmodel->textures[mirrortexturenum])
{
if (!mirror
|| surf->texinfo->texture != cl.worldmodel->textures[mirrortexturenum])
{
surf->texturechain = surf->texinfo->texture->texturechain;
surf->texinfo->texture->texturechain = surf;
}
}/* else if (surf->flags & SURF_DRAWSKY) {
surf->flags &= ~SURF_NEEDSCLIPPING;
surf->flags |= SURF_NEEDSCLIPPING * (frustum_check > 1);
surf->texturechain = surf->texinfo->texture->texturechain;
surf->texinfo->texture->texturechain = surf;
}
/* else if (surf->flags & SURF_DRAWSKY) {
surf->texturechain = skychain;
skychain = surf;
} else if (surf->flags & SURF_DRAWTURB) {
@ -1484,7 +1501,6 @@ void R_DrawWorld (void)
R_ClearSkyBox ();
R_RecursiveWorldNode (cl.worldmodel->nodes);
DrawTextureChains ();

View file

@ -398,6 +398,15 @@ void EmitWaterPolys (msurface_t *fa)
++dst;
}
if (!(fa->flags & SURF_NEEDSCLIPPING))
{
sceGuDrawArray(
GU_TRIANGLE_FAN,
GU_TEXTURE_32BITF | GU_VERTEX_32BITF,
unclipped_vertex_count, 0, unclipped_vertices);
return;
}
// Do these vertices need clipped?
if (clipping::is_clipping_required(unclipped_vertices, unclipped_vertex_count))
{