[sw] Take advantage of the ECS for edge rendering

This fixes the segfault due to the world entity not actually existing,
without adding a world entity. It takes advantage of the ECS in that the
edge renderer needs only the world matrix, brush model pointer, and the
animation frame number (which is just 0/1 for brush models), thus the
inherent SOA of ECS helps out, though benchmarking is needed to see if
it made any real difference.

With this, all 4 renderers are working again.
This commit is contained in:
Bill Currie 2022-10-25 19:36:09 +09:00
parent 2a9fcf4f5f
commit 20c861027e
18 changed files with 168 additions and 82 deletions

View file

@ -166,6 +166,7 @@ typedef struct {
int ambientlight; int ambientlight;
int drawflat; int drawflat;
struct ecs_registry_s *registry;
struct model_s *worldmodel; struct model_s *worldmodel;
} refdef_t; } refdef_t;

View file

@ -48,6 +48,13 @@ enum scene_components {
scene_active, scene_active,
scene_old_origin, //XXX FIXME XXX should not be here scene_old_origin, //XXX FIXME XXX should not be here
//FIXME these should probably be private to the sw renderer (and in a
//group, which needs to be implemented), but need to sort out a good
//scheme for semi-dynamic components
scene_sw_matrix, // world transform matrix
scene_sw_frame, // animation frame
scene_sw_brush, // brush model data pointer
scene_num_components scene_num_components
}; };

View file

@ -201,7 +201,7 @@ typedef struct
extern drawsurf_t r_drawsurf; extern drawsurf_t r_drawsurf;
struct transform_s; struct transform_s;
void R_DrawSurface (struct transform_s transform); void R_DrawSurface (uint32_t render_id);
void R_GenTile (msurface_t *psurf, void *pdest); void R_GenTile (msurface_t *psurf, void *pdest);
// !!! if this is changed, it must be changed in d_iface.h too !!! // !!! if this is changed, it must be changed in d_iface.h too !!!

View file

@ -92,7 +92,7 @@ void D_DrawSkyScans (struct espan_s *pspan);
void R_ShowSubDiv (void); void R_ShowSubDiv (void);
extern void (*prealspandrawer)(void); extern void (*prealspandrawer)(void);
struct entity_s; struct entity_s;
surfcache_t *D_CacheSurface (struct entity_s ent, surfcache_t *D_CacheSurface (uint32_t render_id,
msurface_t *surface, int miplevel); msurface_t *surface, int miplevel);
int D_MipLevelForScale (float scale) __attribute__((pure)); int D_MipLevelForScale (float scale) __attribute__((pure));

View file

@ -21,6 +21,7 @@ extern vid_render_funcs_t *vid_render_funcs;
#define vr_funcs vid_render_funcs #define vr_funcs vid_render_funcs
extern refdef_t r_refdef; extern refdef_t r_refdef;
#define SW_COMP(comp, id) ((void *)((byte *)r_refdef.registry->comp_pools[comp].data + (id) * r_refdef.registry->components[comp].size))
extern int r_viewsize; extern int r_viewsize;
void R_LineGraph (int x, int y, int *h_vals, int count, int height); void R_LineGraph (int x, int y, int *h_vals, int count, int height);

View file

@ -150,18 +150,18 @@ struct animation_s;
void R_SpriteBegin (void); void R_SpriteBegin (void);
void R_SpriteEnd (void); void R_SpriteEnd (void);
void R_DrawSprite (struct entity_s ent); void R_DrawSprite (struct entity_s ent);
void R_RenderFace (struct entity_s ent, msurface_t *fa, int clipflags); void R_RenderFace (uint32_t render_id, msurface_t *fa, int clipflags);
void R_RenderPoly (struct entity_s ent, msurface_t *fa, int clipflags); void R_RenderPoly (uint32_t render_id, msurface_t *fa, int clipflags);
void R_RenderBmodelFace (struct entity_s ent, bedge_t *pedges, msurface_t *psurf); void R_RenderBmodelFace (uint32_t render_id, bedge_t *pedges, msurface_t *psurf);
void R_TransformFrustum (void); void R_TransformFrustum (void);
void R_SetSkyFrame (void); void R_SetSkyFrame (void);
void R_DrawSurfaceBlock (void); void R_DrawSurfaceBlock (void);
struct texture_s *R_TextureAnimation (const struct animation_s *animation, msurface_t *surf) __attribute__((pure)); struct texture_s *R_TextureAnimation (int frame, msurface_t *surf) __attribute__((pure));
void R_GenSkyTile (void *pdest); void R_GenSkyTile (void *pdest);
void R_SurfPatch (void); void R_SurfPatch (void);
void R_DrawSubmodelPolygons (struct entity_s ent, model_t *pmodel, int clipflags, struct mleaf_s *topleaf); void R_DrawSubmodelPolygons (uint32_t render_id, mod_brush_t *brush, int clipflags, struct mleaf_s *topleaf);
void R_DrawSolidClippedSubmodelPolygons (struct entity_s ent, model_t *pmodel, struct mnode_s *topnode); void R_DrawSolidClippedSubmodelPolygons (uint32_t render_id, mod_brush_t *brush, struct mnode_s *topnode);
void R_AddPolygonEdges (emitpoint_t *pverts, int numverts, int miplevel); void R_AddPolygonEdges (emitpoint_t *pverts, int numverts, int miplevel);
surf_t *R_GetSurf (void); surf_t *R_GetSurf (void);
@ -198,7 +198,7 @@ extern void R_EdgeCodeStart (void);
extern void R_EdgeCodeEnd (void); extern void R_EdgeCodeEnd (void);
struct transform_s; struct transform_s;
extern void R_RotateBmodel (struct transform_s transform); extern void R_RotateBmodel (vec4f_t *mat);
extern int c_faceclip; extern int c_faceclip;
extern int r_polycount; extern int r_polycount;
@ -230,7 +230,7 @@ typedef struct btofpoly_s {
extern int numbtofpolys; extern int numbtofpolys;
void R_InitTurb (void); void R_InitTurb (void);
void R_ZDrawSubmodelPolys (struct entity_s ent, model_t *clmodel); void R_ZDrawSubmodelPolys (uint32_t render_id, mod_brush_t *brush);
// Alias models =========================================== // Alias models ===========================================

View file

@ -99,7 +99,7 @@ typedef struct surf_s {
// start) // start)
int flags; // currentface flags int flags; // currentface flags
void *data; // associated data like msurface_t void *data; // associated data like msurface_t
entity_t entity; uint32_t render_id;
float nearzi; // nearest 1/z on surface, for mipmapping float nearzi; // nearest 1/z on surface, for mipmapping
qboolean insubmodel; qboolean insubmodel;
float d_ziorigin, d_zistepu, d_zistepv; float d_ziorigin, d_zistepu, d_zistepv;
@ -163,4 +163,6 @@ typedef struct edge_s
extern float r_avertexnormals[NUMVERTEXNORMALS][3]; extern float r_avertexnormals[NUMVERTEXNORMALS][3];
extern vec3_t ambientcolor; extern vec3_t ambientcolor;
uint32_t SW_AddEntity (entity_t ent);
#endif // _R_SHARED_H #endif // _R_SHARED_H

View file

@ -60,6 +60,27 @@ create_old_origin (void *_old_origin)
*old_origin = (vec4f_t) {0, 0, 0, 1}; *old_origin = (vec4f_t) {0, 0, 0, 1};
} }
static void
sw_identity_matrix (void *_mat)
{
mat4f_t *mat = _mat;
mat4fidentity (*mat);
}
static void
sw_frame_0 (void *_frame)
{
byte *frame = _frame;
*frame = 0;
}
static void
sw_null_brush (void *_brush)
{
struct mod_brush_s **brush = _brush;
*brush = 0;
}
static const component_t scene_components[] = { static const component_t scene_components[] = {
[scene_href] = { [scene_href] = {
.size = sizeof (hierref_t), .size = sizeof (hierref_t),
@ -91,6 +112,22 @@ static const component_t scene_components[] = {
.create = create_old_origin, .create = create_old_origin,
.name = "old_origin", .name = "old_origin",
}, },
[scene_sw_matrix] = {
.size = sizeof (mat4f_t),
.create = sw_identity_matrix,
.name = "sw world transform",
},
[scene_sw_frame] = {
.size = sizeof (byte),
.create = sw_frame_0,
.name = "sw brush model animation frame",
},
[scene_sw_brush] = {
.size = sizeof (struct mod_brush_s *),
.create = sw_null_brush,
.name = "sw brush model data pointer",
},
}; };
static byte empty_visdata[] = { 0x01 }; static byte empty_visdata[] = { 0x01 };

View file

@ -486,7 +486,7 @@ chain_surface (glbspctx_t *bctx, msurface_t *surf)
if (!surf->texinfo->texture->anim_total) if (!surf->texinfo->texture->anim_total)
tx = surf->texinfo->texture; tx = surf->texinfo->texture;
else else
tx = R_TextureAnimation (bctx->animation, surf); tx = R_TextureAnimation (bctx->animation->frame, surf);
tex = tx->render; tex = tx->render;
sc = CHAIN_SURF_F2B (surf, tex->tex_chain); sc = CHAIN_SURF_F2B (surf, tex->tex_chain);

View file

@ -399,7 +399,7 @@ chain_surface (glslbspctx_t *bctx, msurface_t *surf)
if (!surf->texinfo->texture->anim_total) if (!surf->texinfo->texture->anim_total)
tx = surf->texinfo->texture; tx = surf->texinfo->texture;
else else
tx = R_TextureAnimation (bctx->animation, surf); tx = R_TextureAnimation (bctx->animation->frame, surf);
tex = tx->render; tex = tx->render;
is = CHAIN_SURF_F2B (surf, tex->tex_chain); is = CHAIN_SURF_F2B (surf, tex->tex_chain);

View file

@ -103,12 +103,12 @@ R_MarkLeaves (mleaf_t *viewleaf, int *node_visframes, int *leaf_visframes,
Returns the proper texture for a given time and base texture Returns the proper texture for a given time and base texture
*/ */
texture_t * texture_t *
R_TextureAnimation (const animation_t *animation, msurface_t *surf) R_TextureAnimation (int frame, msurface_t *surf)
{ {
texture_t *base = surf->texinfo->texture; texture_t *base = surf->texinfo->texture;
int count, relative; int count, relative;
if (animation->frame) { if (frame) {
if (base->alternate_anims) if (base->alternate_anims)
base = base->alternate_anims; base = base->alternate_anims;
} }

View file

@ -150,12 +150,11 @@ transform_submodel_poly (surf_t *s)
{ {
// FIXME: we don't want to do all this for every polygon! // FIXME: we don't want to do all this for every polygon!
// TODO: store once at start of frame // TODO: store once at start of frame
transform_t transform = Entity_Transform (s->entity); vec4f_t *transform = SW_COMP(scene_sw_matrix, s->render_id);
vec4f_t local_modelorg = r_refdef.frame.position - vec4f_t local_modelorg = r_refdef.frame.position - transform[3];
Transform_GetWorldPosition (transform);
TransformVector ((vec_t*)&local_modelorg, transformed_modelorg);//FIXME TransformVector ((vec_t*)&local_modelorg, transformed_modelorg);//FIXME
R_RotateBmodel (transform); // FIXME: don't mess with the R_RotateBmodel (transform); // FIXME: don't mess with the
// frustum, make entity passed in // frustum, make entity passed in
} }
@ -249,7 +248,7 @@ D_DrawSurfaces (void)
* pface->texinfo->mipadjust); * pface->texinfo->mipadjust);
// FIXME: make this passed in to D_CacheSurface // FIXME: make this passed in to D_CacheSurface
pcurrentcache = D_CacheSurface (s->entity, pface, miplevel); pcurrentcache = D_CacheSurface (s->render_id, pface, miplevel);
cacheblock = (byte *) pcurrentcache->data; cacheblock = (byte *) pcurrentcache->data;
cachewidth = pcurrentcache->width; cachewidth = pcurrentcache->width;

View file

@ -227,14 +227,13 @@ D_SCDump (void)
#endif #endif
surfcache_t * surfcache_t *
D_CacheSurface (entity_t ent, msurface_t *surface, int miplevel) D_CacheSurface (uint32_t render_id, msurface_t *surface, int miplevel)
{ {
surfcache_t *cache; surfcache_t *cache;
animation_t *animation = Ent_GetComponent (ent.id, scene_animation, byte frame = *(byte *) SW_COMP (scene_sw_frame, render_id);
ent.reg);
// if the surface is animating or flashing, flush the cache // if the surface is animating or flashing, flush the cache
r_drawsurf.texture = R_TextureAnimation (animation, surface); r_drawsurf.texture = R_TextureAnimation (frame, surface);
r_drawsurf.lightadj[0] = d_lightstylevalue[surface->styles[0]]; r_drawsurf.lightadj[0] = d_lightstylevalue[surface->styles[0]];
r_drawsurf.lightadj[1] = d_lightstylevalue[surface->styles[1]]; r_drawsurf.lightadj[1] = d_lightstylevalue[surface->styles[1]];
r_drawsurf.lightadj[2] = d_lightstylevalue[surface->styles[2]]; r_drawsurf.lightadj[2] = d_lightstylevalue[surface->styles[2]];
@ -285,8 +284,7 @@ D_CacheSurface (entity_t ent, msurface_t *surface, int miplevel)
r_drawsurf.surf = surface; r_drawsurf.surf = surface;
c_surf++; c_surf++;
transform_t transform = Entity_Transform (ent); R_DrawSurface (render_id);
R_DrawSurface (transform);
return surface->cachespots[miplevel]; return surface->cachespots[miplevel];
} }

View file

@ -44,7 +44,7 @@
typedef struct glbspctx_s { typedef struct glbspctx_s {
mod_brush_t *brush; mod_brush_t *brush;
entity_t entity; uint32_t render_id;
} swbspctx_t; } swbspctx_t;
// current entity info // current entity info
@ -85,10 +85,8 @@ R_EntityRotate (vec3_t vec)
void void
R_RotateBmodel (transform_t transform) R_RotateBmodel (vec4f_t *mat)
{ {
mat4f_t mat;
Transform_GetWorldMatrix (transform, mat);
VectorCopy (mat[0], entity_rotation[0]); VectorCopy (mat[0], entity_rotation[0]);
VectorCopy (mat[1], entity_rotation[1]); VectorCopy (mat[1], entity_rotation[1]);
VectorCopy (mat[2], entity_rotation[2]); VectorCopy (mat[2], entity_rotation[2]);
@ -104,7 +102,7 @@ R_RotateBmodel (transform_t transform)
static void static void
R_RecursiveClipBPoly (entity_t ent, bedge_t *pedges, mnode_t *pnode, R_RecursiveClipBPoly (uint32_t render_id, bedge_t *pedges, mnode_t *pnode,
msurface_t *psurf) msurface_t *psurf)
{ {
bedge_t *psideedges[2], *pnextedge, *ptedge; bedge_t *psideedges[2], *pnextedge, *ptedge;
@ -239,11 +237,11 @@ R_RecursiveClipBPoly (entity_t ent, bedge_t *pedges, mnode_t *pnode,
if (r_leaf_visframes[~child_id] == r_visframecount if (r_leaf_visframes[~child_id] == r_visframecount
&& leaf->contents != CONTENTS_SOLID) { && leaf->contents != CONTENTS_SOLID) {
r_currentbkey = leaf->key; r_currentbkey = leaf->key;
R_RenderBmodelFace (ent, psideedges[i], psurf); R_RenderBmodelFace (render_id, psideedges[i], psurf);
} }
} else { } else {
if (r_node_visframes[child_id] == r_visframecount) { if (r_node_visframes[child_id] == r_visframecount) {
R_RecursiveClipBPoly (ent, psideedges[i], pn, psurf); R_RecursiveClipBPoly (render_id, psideedges[i], pn, psurf);
} }
} }
} }
@ -252,7 +250,7 @@ R_RecursiveClipBPoly (entity_t ent, bedge_t *pedges, mnode_t *pnode,
void void
R_DrawSolidClippedSubmodelPolygons (entity_t ent, model_t *model, R_DrawSolidClippedSubmodelPolygons (uint32_t render_id, mod_brush_t *brush,
mnode_t *topnode) mnode_t *topnode)
{ {
int i, j, lindex; int i, j, lindex;
@ -263,7 +261,6 @@ R_DrawSolidClippedSubmodelPolygons (entity_t ent, model_t *model,
mvertex_t bverts[MAX_BMODEL_VERTS]; mvertex_t bverts[MAX_BMODEL_VERTS];
bedge_t bedges[MAX_BMODEL_EDGES], *pbedge; bedge_t bedges[MAX_BMODEL_EDGES], *pbedge;
medge_t *pedge, *pedges; medge_t *pedge, *pedges;
mod_brush_t *brush = &model->brush;
// FIXME: use bounding-box-based frustum clipping info? // FIXME: use bounding-box-based frustum clipping info?
@ -313,7 +310,7 @@ R_DrawSolidClippedSubmodelPolygons (entity_t ent, model_t *model,
pbedge[j - 1].pnext = NULL; // mark end of edges pbedge[j - 1].pnext = NULL; // mark end of edges
R_RecursiveClipBPoly (ent, pbedge, topnode, psurf); R_RecursiveClipBPoly (render_id, pbedge, topnode, psurf);
} else { } else {
Sys_Error ("no edges in bmodel"); Sys_Error ("no edges in bmodel");
} }
@ -323,7 +320,7 @@ R_DrawSolidClippedSubmodelPolygons (entity_t ent, model_t *model,
void void
R_DrawSubmodelPolygons (entity_t ent, model_t *model, int clipflags, R_DrawSubmodelPolygons (uint32_t render_id, mod_brush_t *brush, int clipflags,
mleaf_t *topleaf) mleaf_t *topleaf)
{ {
int i; int i;
@ -331,7 +328,6 @@ R_DrawSubmodelPolygons (entity_t ent, model_t *model, int clipflags,
msurface_t *psurf; msurface_t *psurf;
int numsurfaces; int numsurfaces;
plane_t *pplane; plane_t *pplane;
mod_brush_t *brush = &model->brush;
// FIXME: use bounding-box-based frustum clipping info? // FIXME: use bounding-box-based frustum clipping info?
@ -350,7 +346,7 @@ R_DrawSubmodelPolygons (entity_t ent, model_t *model, int clipflags,
r_currentkey = topleaf->key; r_currentkey = topleaf->key;
// FIXME: use bounding-box-based frustum clipping info? // FIXME: use bounding-box-based frustum clipping info?
R_RenderFace (ent, psurf, clipflags); R_RenderFace (render_id, psurf, clipflags);
} }
} }
} }
@ -379,7 +375,7 @@ visit_node (swbspctx_t *bctx, mnode_t *node, int side, int clipflags)
{ {
int c; int c;
msurface_t *surf; msurface_t *surf;
entity_t ent = bctx->entity; uint32_t render_id = bctx->render_id;
mod_brush_t *brush = bctx->brush; mod_brush_t *brush = bctx->brush;
// sneaky hack for side = side ? SURF_PLANEBACK : 0; // sneaky hack for side = side ? SURF_PLANEBACK : 0;
@ -404,10 +400,10 @@ visit_node (swbspctx_t *bctx, mnode_t *node, int side, int clipflags)
numbtofpolys++; numbtofpolys++;
} }
} else { } else {
R_RenderPoly (ent, surf, clipflags); R_RenderPoly (render_id, surf, clipflags);
} }
} else { } else {
R_RenderFace (ent, surf, clipflags); R_RenderFace (render_id, surf, clipflags);
} }
} }
// all surfaces on the same node share the same sequence number // all surfaces on the same node share the same sequence number
@ -533,11 +529,10 @@ R_RenderWorld (void)
{ {
int i; int i;
btofpoly_t btofpolys[MAX_BTOFPOLYS]; btofpoly_t btofpolys[MAX_BTOFPOLYS];
entity_t ent = nullentity;
mod_brush_t *brush = &r_refdef.worldmodel->brush; mod_brush_t *brush = &r_refdef.worldmodel->brush;
swbspctx_t bspctx = { swbspctx_t bspctx = {
brush, brush,
ent, 0,
}; };
pbtofpolys = btofpolys; pbtofpolys = btofpolys;
@ -551,7 +546,7 @@ R_RenderWorld (void)
// back in that order // back in that order
if (r_worldpolysbacktofront) { if (r_worldpolysbacktofront) {
for (i = numbtofpolys - 1; i >= 0; i--) { for (i = numbtofpolys - 1; i >= 0; i--) {
R_RenderPoly (ent, btofpolys[i].psurf, btofpolys[i].clipflags); R_RenderPoly (0, btofpolys[i].psurf, btofpolys[i].clipflags);
} }
} }
} }

View file

@ -347,7 +347,7 @@ R_EmitCachedEdge (void)
void void
R_RenderFace (entity_t ent, msurface_t *fa, int clipflags) R_RenderFace (uint32_t render_id, msurface_t *fa, int clipflags)
{ {
int i, lindex; int i, lindex;
unsigned int mask; unsigned int mask;
@ -356,8 +356,7 @@ R_RenderFace (entity_t ent, msurface_t *fa, int clipflags)
vec3_t p_normal; vec3_t p_normal;
medge_t *pedges, tedge; medge_t *pedges, tedge;
clipplane_t *pclip; clipplane_t *pclip;
renderer_t *renderer = Ent_GetComponent (ent.id, scene_renderer, ent.reg); mod_brush_t *brush = *(mod_brush_t **) SW_COMP (scene_sw_brush, render_id);
mod_brush_t *brush = &renderer->model->brush;
// skip out if no more surfs // skip out if no more surfs
if ((surface_p) >= surf_max) { if ((surface_p) >= surf_max) {
@ -494,7 +493,7 @@ R_RenderFace (entity_t ent, msurface_t *fa, int clipflags)
surface_p->flags = fa->flags; surface_p->flags = fa->flags;
surface_p->insubmodel = insubmodel; surface_p->insubmodel = insubmodel;
surface_p->spanstate = 0; surface_p->spanstate = 0;
surface_p->entity = ent; surface_p->render_id = render_id;
surface_p->key = r_currentkey++; surface_p->key = r_currentkey++;
surface_p->spans = NULL; surface_p->spans = NULL;
@ -514,7 +513,7 @@ R_RenderFace (entity_t ent, msurface_t *fa, int clipflags)
void void
R_RenderBmodelFace (entity_t ent, bedge_t *pedges, msurface_t *psurf) R_RenderBmodelFace (uint32_t render_id, bedge_t *pedges, msurface_t *psurf)
{ {
int i; int i;
unsigned int mask; unsigned int mask;
@ -593,7 +592,7 @@ R_RenderBmodelFace (entity_t ent, bedge_t *pedges, msurface_t *psurf)
surface_p->flags = psurf->flags; surface_p->flags = psurf->flags;
surface_p->insubmodel = true; surface_p->insubmodel = true;
surface_p->spanstate = 0; surface_p->spanstate = 0;
surface_p->entity = ent; surface_p->render_id = render_id;
surface_p->key = r_currentbkey; surface_p->key = r_currentbkey;
surface_p->spans = NULL; surface_p->spans = NULL;
@ -613,7 +612,7 @@ R_RenderBmodelFace (entity_t ent, bedge_t *pedges, msurface_t *psurf)
void void
R_RenderPoly (entity_t ent, msurface_t *fa, int clipflags) R_RenderPoly (uint32_t render_id, msurface_t *fa, int clipflags)
{ {
int i, lindex, lnumverts, s_axis, t_axis; int i, lindex, lnumverts, s_axis, t_axis;
float dist, lastdist, lzi, scale, u, v, frac; float dist, lastdist, lzi, scale, u, v, frac;
@ -626,8 +625,7 @@ R_RenderPoly (entity_t ent, msurface_t *fa, int clipflags)
polyvert_t pverts[100]; // FIXME: do real number, safely polyvert_t pverts[100]; // FIXME: do real number, safely
int vertpage, newverts, newpage, lastvert; int vertpage, newverts, newpage, lastvert;
qboolean visible; qboolean visible;
renderer_t *renderer = Ent_GetComponent (ent.id, scene_renderer, ent.reg); mod_brush_t *brush = *(mod_brush_t **) SW_COMP (scene_sw_brush, render_id);
mod_brush_t *brush = &renderer->model->brush;
// FIXME: clean this up and make it faster // FIXME: clean this up and make it faster
// FIXME: guard against running out of vertices // FIXME: guard against running out of vertices
@ -782,13 +780,12 @@ R_RenderPoly (entity_t ent, msurface_t *fa, int clipflags)
void void
R_ZDrawSubmodelPolys (entity_t ent, model_t *model) R_ZDrawSubmodelPolys (uint32_t render_id, mod_brush_t *brush)
{ {
int i, numsurfaces; int i, numsurfaces;
msurface_t *psurf; msurface_t *psurf;
float dot; float dot;
plane_t *pplane; plane_t *pplane;
mod_brush_t *brush = &model->brush;
psurf = &brush->surfaces[brush->firstmodelsurface]; psurf = &brush->surfaces[brush->firstmodelsurface];
numsurfaces = brush->nummodelsurfaces; numsurfaces = brush->nummodelsurfaces;
@ -803,7 +800,7 @@ R_ZDrawSubmodelPolys (entity_t ent, model_t *model)
if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) || if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) { (!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) {
// FIXME: use bounding-box-based frustum clipping info? // FIXME: use bounding-box-based frustum clipping info?
R_RenderPoly (ent, psurf, 15); R_RenderPoly (render_id, psurf, 15);
} }
} }
} }

View file

@ -89,7 +89,7 @@ R_DrawCulledPolys (void)
if (!(s->flags & SURF_DRAWBACKGROUND)) { if (!(s->flags & SURF_DRAWBACKGROUND)) {
pface = (msurface_t *) s->data; pface = (msurface_t *) s->data;
R_RenderPoly (s->entity, pface, 15); R_RenderPoly (s->render_id, pface, 15);
} }
} }
} else { } else {
@ -99,7 +99,7 @@ R_DrawCulledPolys (void)
if (!(s->flags & SURF_DRAWBACKGROUND)) { if (!(s->flags & SURF_DRAWBACKGROUND)) {
pface = (msurface_t *) s->data; pface = (msurface_t *) s->data;
R_RenderPoly (s->entity, pface, 15); R_RenderPoly (s->render_id, pface, 15);
} }
} }
} }

View file

@ -146,12 +146,58 @@ sw_R_Init (void)
Skin_Init (); Skin_Init ();
} }
uint32_t
SW_AddEntity (entity_t ent)
{
// This takes advantage of the implicit (FIXME, make explicit) grouping of
// the sw components: as all entities that get added here will always have
// all three components, the three component pools are always in sync, thus
// the pool count can be used as a render id which can in turn be used to
// index the components within the pools.
ecs_registry_t *reg = ent.reg;
ecs_pool_t *pool = &reg->comp_pools[scene_sw_matrix];
uint32_t render_id = pool->count;
transform_t transform = Entity_Transform (ent);
Ent_SetComponent (ent.id, scene_sw_matrix, reg,
Transform_GetWorldMatrixPtr (transform));
animation_t *animation = Ent_GetComponent (ent.id, scene_animation, reg);
Ent_SetComponent (ent.id, scene_sw_frame, reg, &animation->frame);
renderer_t *renderer = Ent_GetComponent (ent.id, scene_renderer, reg);
mod_brush_t *brush = &renderer->model->brush;
Ent_SetComponent (ent.id, scene_sw_brush, reg, &brush);
return render_id;
}
static void
reset_sw_components (ecs_registry_t *reg)
{
static uint32_t sw_comps[] = {
scene_sw_matrix,
scene_sw_frame,
scene_sw_brush,
};
for (int i = 0; i < 3; i++) {
ecs_pool_t *pool = &reg->comp_pools[sw_comps[i]];
pool->count = 0; // remove component from every entity
// reserve first component object (render id 0) for the world
// pseudo-entity.
Ent_SetComponent (0, sw_comps[i], reg, 0);
// make sure entity 0 gets allocated a new component object as the
// world pseudo-entity currently has no actual entity (FIXME)
pool->dense[0] = nullent;
}
}
void void
R_NewScene (scene_t *scene) R_NewScene (scene_t *scene)
{ {
model_t *worldmodel = scene->worldmodel; model_t *worldmodel = scene->worldmodel;
mod_brush_t *brush = &worldmodel->brush; mod_brush_t *brush = &worldmodel->brush;
r_refdef.registry = scene->reg;
r_refdef.worldmodel = worldmodel; r_refdef.worldmodel = worldmodel;
// clear out efrags in case the level hasn't been reloaded // clear out efrags in case the level hasn't been reloaded
@ -380,25 +426,23 @@ R_DrawViewModel (void)
} }
static int static int
R_BmodelCheckBBox (transform_t transform, model_t *clmodel, float *minmaxs) R_BmodelCheckBBox (const vec4f_t *transform, float radius, float *minmaxs)
{ {
int i, *pindex, clipflags; int i, *pindex, clipflags;
vec3_t acceptpt, rejectpt; vec3_t acceptpt, rejectpt;
double d; double d;
mat4f_t mat;
clipflags = 0; clipflags = 0;
Transform_GetWorldMatrix (transform, mat); if (transform[0][0] != 1 || transform[1][1] != 1 || transform[2][2] != 1) {
if (mat[0][0] != 1 || mat[1][1] != 1 || mat[2][2] != 1) {
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
d = DotProduct (mat[3], view_clipplanes[i].normal); d = DotProduct (transform[3], view_clipplanes[i].normal);
d -= view_clipplanes[i].dist; d -= view_clipplanes[i].dist;
if (d <= -clmodel->radius) if (d <= -radius)
return BMODEL_FULLY_CLIPPED; return BMODEL_FULLY_CLIPPED;
if (d <= clmodel->radius) if (d <= radius)
clipflags |= (1 << i); clipflags |= (1 << i);
} }
} else { } else {
@ -449,9 +493,11 @@ R_DrawBrushEntitiesOnList (entqueue_t *queue)
for (size_t i = 0; i < queue->ent_queues[mod_brush].size; i++) { for (size_t i = 0; i < queue->ent_queues[mod_brush].size; i++) {
entity_t ent = queue->ent_queues[mod_brush].a[i]; entity_t ent = queue->ent_queues[mod_brush].a[i];
uint32_t render_id = SW_AddEntity (ent);
transform_t transform = Entity_Transform (ent); vec4f_t *transform = Ent_GetComponent (ent.id, scene_sw_matrix,
VectorCopy (Transform_GetWorldPosition (transform), origin); ent.reg);
VectorCopy (transform[3], origin);
renderer_t *renderer = Ent_GetComponent (ent.id, scene_renderer, renderer_t *renderer = Ent_GetComponent (ent.id, scene_renderer,
ent.reg); ent.reg);
model_t *model = renderer->model; model_t *model = renderer->model;
@ -463,7 +509,7 @@ R_DrawBrushEntitiesOnList (entqueue_t *queue)
minmaxs[3 + j] = origin[j] + model->maxs[j]; minmaxs[3 + j] = origin[j] + model->maxs[j];
} }
clipflags = R_BmodelCheckBBox (transform, model, minmaxs); clipflags = R_BmodelCheckBBox (transform, model->radius, minmaxs);
if (clipflags != BMODEL_FULLY_CLIPPED) { if (clipflags != BMODEL_FULLY_CLIPPED) {
mod_brush_t *brush = &model->brush; mod_brush_t *brush = &model->brush;
@ -496,26 +542,26 @@ R_DrawBrushEntitiesOnList (entqueue_t *queue)
// Z-buffering is on at this point, so no clipping to the // Z-buffering is on at this point, so no clipping to the
// world tree is needed, just frustum clipping // world tree is needed, just frustum clipping
if (r_drawpolys | r_drawculledpolys) { if (r_drawpolys | r_drawculledpolys) {
R_ZDrawSubmodelPolys (ent, model); R_ZDrawSubmodelPolys (render_id, brush);
} else { } else {
visibility_t *visibility = Ent_GetComponent (ent.id, visibility_t *visibility = Ent_GetComponent (ent.id,
scene_visibility, scene_visibility,
ent.reg); ent.reg);
int topnode_id = visibility->topnode_id; int topnode_id = visibility->topnode_id;
mod_brush_t *brush = &r_refdef.worldmodel->brush; mod_brush_t *world_brush = &r_refdef.worldmodel->brush;
if (topnode_id >= 0) { if (topnode_id >= 0) {
// not a leaf; has to be clipped to the world // not a leaf; has to be clipped to the world
// BSP // BSP
mnode_t *node = brush->nodes + topnode_id; mnode_t *node = world_brush->nodes + topnode_id;
r_clipflags = clipflags; r_clipflags = clipflags;
R_DrawSolidClippedSubmodelPolygons (ent, model, node); R_DrawSolidClippedSubmodelPolygons (render_id, brush, node);
} else { } else {
// falls entirely in one leaf, so we just put // falls entirely in one leaf, so we just put
// all the edges in the edge list and let 1/z // all the edges in the edge list and let 1/z
// sorting handle drawing order // sorting handle drawing order
mleaf_t *leaf = brush->leafs + ~topnode_id; mleaf_t *leaf = world_brush->leafs + ~topnode_id;
R_DrawSubmodelPolygons (ent, model, clipflags, leaf); R_DrawSubmodelPolygons (render_id, brush, clipflags, leaf);
} }
} }
@ -588,6 +634,8 @@ R_RenderView_ (void)
return; return;
} }
reset_sw_components (r_refdef.registry);
*(mod_brush_t **) SW_COMP (scene_sw_brush, 0) = &r_refdef.worldmodel->brush;
R_SetupFrame (); R_SetupFrame ();
// make FDIV fast. This reduces timing precision after we've been running for a // make FDIV fast. This reduces timing precision after we've been running for a

View file

@ -73,7 +73,7 @@ static unsigned int blocklights[34 * 34]; //FIXME make dynamic
static void static void
R_AddDynamicLights (transform_t transform) R_AddDynamicLights (uint32_t render_id)
{ {
msurface_t *surf; msurface_t *surf;
unsigned int lnum; unsigned int lnum;
@ -91,9 +91,10 @@ R_AddDynamicLights (transform_t transform)
tmax = (surf->extents[1] >> 4) + 1; tmax = (surf->extents[1] >> 4) + 1;
tex = surf->texinfo; tex = surf->texinfo;
if (Transform_Valid (transform)) { if (render_id) {
//FIXME give world entity a transform //FIXME give world entity a transform
entorigin = Transform_GetWorldPosition (transform); vec4f_t *transform = SW_COMP (scene_sw_matrix, render_id);
entorigin = transform[3];
} }
for (lnum = 0; lnum < r_maxdlights; lnum++) { for (lnum = 0; lnum < r_maxdlights; lnum++) {
@ -144,7 +145,7 @@ R_AddDynamicLights (transform_t transform)
Combine and scale multiple lightmaps into the 8.8 format in blocklights Combine and scale multiple lightmaps into the 8.8 format in blocklights
*/ */
static void static void
R_BuildLightMap (transform_t transform) R_BuildLightMap (uint32_t render_id)
{ {
int smax, tmax; int smax, tmax;
int t; int t;
@ -180,7 +181,7 @@ R_BuildLightMap (transform_t transform)
} }
// add all the dynamic lights // add all the dynamic lights
if (surf->dlightframe == r_framecount) if (surf->dlightframe == r_framecount)
R_AddDynamicLights (transform); R_AddDynamicLights (render_id);
// bound, invert, and shift // bound, invert, and shift
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
@ -194,7 +195,7 @@ R_BuildLightMap (transform_t transform)
} }
void void
R_DrawSurface (transform_t transform) R_DrawSurface (uint32_t render_id)
{ {
byte *basetptr; byte *basetptr;
int smax, tmax, twidth; int smax, tmax, twidth;
@ -206,7 +207,7 @@ R_DrawSurface (transform_t transform)
texture_t *mt; texture_t *mt;
// calculate the lightings // calculate the lightings
R_BuildLightMap (transform); R_BuildLightMap (render_id);
surfrowbytes = r_drawsurf.rowbytes; surfrowbytes = r_drawsurf.rowbytes;