From 20c861027e2047e32384ab1ef7ab476cd1860669 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 25 Oct 2022 19:36:09 +0900 Subject: [PATCH] [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. --- include/QF/render.h | 1 + include/QF/scene/scene.h | 7 +++ include/d_iface.h | 2 +- include/d_local.h | 2 +- include/r_internal.h | 1 + include/r_local.h | 16 +++--- include/r_shared.h | 4 +- libs/scene/scene.c | 37 +++++++++++++ libs/video/renderer/gl/gl_rsurf.c | 2 +- libs/video/renderer/glsl/glsl_bsp.c | 2 +- libs/video/renderer/r_bsp.c | 4 +- libs/video/renderer/sw/d_edge.c | 9 ++-- libs/video/renderer/sw/d_surf.c | 10 ++-- libs/video/renderer/sw/sw_rbsp.c | 33 +++++------- libs/video/renderer/sw/sw_rdraw.c | 21 ++++---- libs/video/renderer/sw/sw_redge.c | 4 +- libs/video/renderer/sw/sw_rmain.c | 80 +++++++++++++++++++++++------ libs/video/renderer/sw/sw_rsurf.c | 15 +++--- 18 files changed, 168 insertions(+), 82 deletions(-) diff --git a/include/QF/render.h b/include/QF/render.h index 94e1f0a29..cd06fb44f 100644 --- a/include/QF/render.h +++ b/include/QF/render.h @@ -166,6 +166,7 @@ typedef struct { int ambientlight; int drawflat; + struct ecs_registry_s *registry; struct model_s *worldmodel; } refdef_t; diff --git a/include/QF/scene/scene.h b/include/QF/scene/scene.h index 14983c62c..ae9a03871 100644 --- a/include/QF/scene/scene.h +++ b/include/QF/scene/scene.h @@ -48,6 +48,13 @@ enum scene_components { scene_active, 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 }; diff --git a/include/d_iface.h b/include/d_iface.h index 454502fb2..7970064ed 100644 --- a/include/d_iface.h +++ b/include/d_iface.h @@ -201,7 +201,7 @@ typedef struct extern drawsurf_t r_drawsurf; 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); // !!! if this is changed, it must be changed in d_iface.h too !!! diff --git a/include/d_local.h b/include/d_local.h index cd06ab0ae..20ae2cb73 100644 --- a/include/d_local.h +++ b/include/d_local.h @@ -92,7 +92,7 @@ void D_DrawSkyScans (struct espan_s *pspan); void R_ShowSubDiv (void); extern void (*prealspandrawer)(void); struct entity_s; -surfcache_t *D_CacheSurface (struct entity_s ent, +surfcache_t *D_CacheSurface (uint32_t render_id, msurface_t *surface, int miplevel); int D_MipLevelForScale (float scale) __attribute__((pure)); diff --git a/include/r_internal.h b/include/r_internal.h index 1f1d72c77..4800384f4 100644 --- a/include/r_internal.h +++ b/include/r_internal.h @@ -21,6 +21,7 @@ extern vid_render_funcs_t *vid_render_funcs; #define vr_funcs vid_render_funcs 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; void R_LineGraph (int x, int y, int *h_vals, int count, int height); diff --git a/include/r_local.h b/include/r_local.h index fbb7e74d3..01fe81733 100644 --- a/include/r_local.h +++ b/include/r_local.h @@ -150,18 +150,18 @@ struct animation_s; void R_SpriteBegin (void); void R_SpriteEnd (void); void R_DrawSprite (struct entity_s ent); -void R_RenderFace (struct entity_s ent, msurface_t *fa, int clipflags); -void R_RenderPoly (struct entity_s ent, msurface_t *fa, int clipflags); -void R_RenderBmodelFace (struct entity_s ent, bedge_t *pedges, msurface_t *psurf); +void R_RenderFace (uint32_t render_id, msurface_t *fa, int clipflags); +void R_RenderPoly (uint32_t render_id, msurface_t *fa, int clipflags); +void R_RenderBmodelFace (uint32_t render_id, bedge_t *pedges, msurface_t *psurf); void R_TransformFrustum (void); void R_SetSkyFrame (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_SurfPatch (void); -void R_DrawSubmodelPolygons (struct entity_s ent, model_t *pmodel, int clipflags, struct mleaf_s *topleaf); -void R_DrawSolidClippedSubmodelPolygons (struct entity_s ent, model_t *pmodel, struct mnode_s *topnode); +void R_DrawSubmodelPolygons (uint32_t render_id, mod_brush_t *brush, int clipflags, struct mleaf_s *topleaf); +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); surf_t *R_GetSurf (void); @@ -198,7 +198,7 @@ extern void R_EdgeCodeStart (void); extern void R_EdgeCodeEnd (void); struct transform_s; -extern void R_RotateBmodel (struct transform_s transform); +extern void R_RotateBmodel (vec4f_t *mat); extern int c_faceclip; extern int r_polycount; @@ -230,7 +230,7 @@ typedef struct btofpoly_s { extern int numbtofpolys; 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 =========================================== diff --git a/include/r_shared.h b/include/r_shared.h index 90f69aa03..c189d876a 100644 --- a/include/r_shared.h +++ b/include/r_shared.h @@ -99,7 +99,7 @@ typedef struct surf_s { // start) int flags; // currentface flags void *data; // associated data like msurface_t - entity_t entity; + uint32_t render_id; float nearzi; // nearest 1/z on surface, for mipmapping qboolean insubmodel; float d_ziorigin, d_zistepu, d_zistepv; @@ -163,4 +163,6 @@ typedef struct edge_s extern float r_avertexnormals[NUMVERTEXNORMALS][3]; extern vec3_t ambientcolor; +uint32_t SW_AddEntity (entity_t ent); + #endif // _R_SHARED_H diff --git a/libs/scene/scene.c b/libs/scene/scene.c index 1800b87c8..4f1a0b22a 100644 --- a/libs/scene/scene.c +++ b/libs/scene/scene.c @@ -60,6 +60,27 @@ create_old_origin (void *_old_origin) *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[] = { [scene_href] = { .size = sizeof (hierref_t), @@ -91,6 +112,22 @@ static const component_t scene_components[] = { .create = create_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 }; diff --git a/libs/video/renderer/gl/gl_rsurf.c b/libs/video/renderer/gl/gl_rsurf.c index 73af64ca9..5d199d214 100644 --- a/libs/video/renderer/gl/gl_rsurf.c +++ b/libs/video/renderer/gl/gl_rsurf.c @@ -486,7 +486,7 @@ chain_surface (glbspctx_t *bctx, msurface_t *surf) if (!surf->texinfo->texture->anim_total) tx = surf->texinfo->texture; else - tx = R_TextureAnimation (bctx->animation, surf); + tx = R_TextureAnimation (bctx->animation->frame, surf); tex = tx->render; sc = CHAIN_SURF_F2B (surf, tex->tex_chain); diff --git a/libs/video/renderer/glsl/glsl_bsp.c b/libs/video/renderer/glsl/glsl_bsp.c index 1d31f81f2..6215498f7 100644 --- a/libs/video/renderer/glsl/glsl_bsp.c +++ b/libs/video/renderer/glsl/glsl_bsp.c @@ -399,7 +399,7 @@ chain_surface (glslbspctx_t *bctx, msurface_t *surf) if (!surf->texinfo->texture->anim_total) tx = surf->texinfo->texture; else - tx = R_TextureAnimation (bctx->animation, surf); + tx = R_TextureAnimation (bctx->animation->frame, surf); tex = tx->render; is = CHAIN_SURF_F2B (surf, tex->tex_chain); diff --git a/libs/video/renderer/r_bsp.c b/libs/video/renderer/r_bsp.c index e2b8b951e..19b5475e9 100644 --- a/libs/video/renderer/r_bsp.c +++ b/libs/video/renderer/r_bsp.c @@ -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 */ texture_t * -R_TextureAnimation (const animation_t *animation, msurface_t *surf) +R_TextureAnimation (int frame, msurface_t *surf) { texture_t *base = surf->texinfo->texture; int count, relative; - if (animation->frame) { + if (frame) { if (base->alternate_anims) base = base->alternate_anims; } diff --git a/libs/video/renderer/sw/d_edge.c b/libs/video/renderer/sw/d_edge.c index 80f7c9671..401349419 100644 --- a/libs/video/renderer/sw/d_edge.c +++ b/libs/video/renderer/sw/d_edge.c @@ -150,12 +150,11 @@ transform_submodel_poly (surf_t *s) { // FIXME: we don't want to do all this for every polygon! // TODO: store once at start of frame - transform_t transform = Entity_Transform (s->entity); - vec4f_t local_modelorg = r_refdef.frame.position - - Transform_GetWorldPosition (transform); + vec4f_t *transform = SW_COMP(scene_sw_matrix, s->render_id); + vec4f_t local_modelorg = r_refdef.frame.position - transform[3]; 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 } @@ -249,7 +248,7 @@ D_DrawSurfaces (void) * pface->texinfo->mipadjust); // 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; cachewidth = pcurrentcache->width; diff --git a/libs/video/renderer/sw/d_surf.c b/libs/video/renderer/sw/d_surf.c index 4a38de885..2c7b327b3 100644 --- a/libs/video/renderer/sw/d_surf.c +++ b/libs/video/renderer/sw/d_surf.c @@ -227,14 +227,13 @@ D_SCDump (void) #endif 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; - animation_t *animation = Ent_GetComponent (ent.id, scene_animation, - ent.reg); + byte frame = *(byte *) SW_COMP (scene_sw_frame, render_id); // 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[1] = d_lightstylevalue[surface->styles[1]]; 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; c_surf++; - transform_t transform = Entity_Transform (ent); - R_DrawSurface (transform); + R_DrawSurface (render_id); return surface->cachespots[miplevel]; } diff --git a/libs/video/renderer/sw/sw_rbsp.c b/libs/video/renderer/sw/sw_rbsp.c index e8544abd5..7e8a7e69a 100644 --- a/libs/video/renderer/sw/sw_rbsp.c +++ b/libs/video/renderer/sw/sw_rbsp.c @@ -44,7 +44,7 @@ typedef struct glbspctx_s { mod_brush_t *brush; - entity_t entity; + uint32_t render_id; } swbspctx_t; // current entity info @@ -85,10 +85,8 @@ R_EntityRotate (vec3_t vec) 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[1], entity_rotation[1]); VectorCopy (mat[2], entity_rotation[2]); @@ -104,7 +102,7 @@ R_RotateBmodel (transform_t transform) 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) { 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 && leaf->contents != CONTENTS_SOLID) { r_currentbkey = leaf->key; - R_RenderBmodelFace (ent, psideedges[i], psurf); + R_RenderBmodelFace (render_id, psideedges[i], psurf); } } else { 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 -R_DrawSolidClippedSubmodelPolygons (entity_t ent, model_t *model, +R_DrawSolidClippedSubmodelPolygons (uint32_t render_id, mod_brush_t *brush, mnode_t *topnode) { int i, j, lindex; @@ -263,7 +261,6 @@ R_DrawSolidClippedSubmodelPolygons (entity_t ent, model_t *model, mvertex_t bverts[MAX_BMODEL_VERTS]; bedge_t bedges[MAX_BMODEL_EDGES], *pbedge; medge_t *pedge, *pedges; - mod_brush_t *brush = &model->brush; // 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 - R_RecursiveClipBPoly (ent, pbedge, topnode, psurf); + R_RecursiveClipBPoly (render_id, pbedge, topnode, psurf); } else { Sys_Error ("no edges in bmodel"); } @@ -323,7 +320,7 @@ R_DrawSolidClippedSubmodelPolygons (entity_t ent, model_t *model, 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) { int i; @@ -331,7 +328,6 @@ R_DrawSubmodelPolygons (entity_t ent, model_t *model, int clipflags, msurface_t *psurf; int numsurfaces; plane_t *pplane; - mod_brush_t *brush = &model->brush; // 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; // 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; msurface_t *surf; - entity_t ent = bctx->entity; + uint32_t render_id = bctx->render_id; mod_brush_t *brush = bctx->brush; // 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++; } } else { - R_RenderPoly (ent, surf, clipflags); + R_RenderPoly (render_id, surf, clipflags); } } else { - R_RenderFace (ent, surf, clipflags); + R_RenderFace (render_id, surf, clipflags); } } // all surfaces on the same node share the same sequence number @@ -533,11 +529,10 @@ R_RenderWorld (void) { int i; btofpoly_t btofpolys[MAX_BTOFPOLYS]; - entity_t ent = nullentity; mod_brush_t *brush = &r_refdef.worldmodel->brush; swbspctx_t bspctx = { brush, - ent, + 0, }; pbtofpolys = btofpolys; @@ -551,7 +546,7 @@ R_RenderWorld (void) // back in that order if (r_worldpolysbacktofront) { 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); } } } diff --git a/libs/video/renderer/sw/sw_rdraw.c b/libs/video/renderer/sw/sw_rdraw.c index 2c2d4451f..bc5cb4670 100644 --- a/libs/video/renderer/sw/sw_rdraw.c +++ b/libs/video/renderer/sw/sw_rdraw.c @@ -347,7 +347,7 @@ R_EmitCachedEdge (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; unsigned int mask; @@ -356,8 +356,7 @@ R_RenderFace (entity_t ent, msurface_t *fa, int clipflags) vec3_t p_normal; medge_t *pedges, tedge; clipplane_t *pclip; - renderer_t *renderer = Ent_GetComponent (ent.id, scene_renderer, ent.reg); - mod_brush_t *brush = &renderer->model->brush; + mod_brush_t *brush = *(mod_brush_t **) SW_COMP (scene_sw_brush, render_id); // skip out if no more surfs 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->insubmodel = insubmodel; surface_p->spanstate = 0; - surface_p->entity = ent; + surface_p->render_id = render_id; surface_p->key = r_currentkey++; surface_p->spans = NULL; @@ -514,7 +513,7 @@ R_RenderFace (entity_t ent, msurface_t *fa, int clipflags) 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; 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->insubmodel = true; surface_p->spanstate = 0; - surface_p->entity = ent; + surface_p->render_id = render_id; surface_p->key = r_currentbkey; surface_p->spans = NULL; @@ -613,7 +612,7 @@ R_RenderBmodelFace (entity_t ent, bedge_t *pedges, msurface_t *psurf) 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; 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 int vertpage, newverts, newpage, lastvert; qboolean visible; - renderer_t *renderer = Ent_GetComponent (ent.id, scene_renderer, ent.reg); - mod_brush_t *brush = &renderer->model->brush; + mod_brush_t *brush = *(mod_brush_t **) SW_COMP (scene_sw_brush, render_id); // FIXME: clean this up and make it faster // FIXME: guard against running out of vertices @@ -782,13 +780,12 @@ R_RenderPoly (entity_t ent, msurface_t *fa, int clipflags) void -R_ZDrawSubmodelPolys (entity_t ent, model_t *model) +R_ZDrawSubmodelPolys (uint32_t render_id, mod_brush_t *brush) { int i, numsurfaces; msurface_t *psurf; float dot; plane_t *pplane; - mod_brush_t *brush = &model->brush; psurf = &brush->surfaces[brush->firstmodelsurface]; numsurfaces = brush->nummodelsurfaces; @@ -803,7 +800,7 @@ R_ZDrawSubmodelPolys (entity_t ent, model_t *model) if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) || (!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) { // FIXME: use bounding-box-based frustum clipping info? - R_RenderPoly (ent, psurf, 15); + R_RenderPoly (render_id, psurf, 15); } } } diff --git a/libs/video/renderer/sw/sw_redge.c b/libs/video/renderer/sw/sw_redge.c index 339c98bcb..df49f89ad 100644 --- a/libs/video/renderer/sw/sw_redge.c +++ b/libs/video/renderer/sw/sw_redge.c @@ -89,7 +89,7 @@ R_DrawCulledPolys (void) if (!(s->flags & SURF_DRAWBACKGROUND)) { pface = (msurface_t *) s->data; - R_RenderPoly (s->entity, pface, 15); + R_RenderPoly (s->render_id, pface, 15); } } } else { @@ -99,7 +99,7 @@ R_DrawCulledPolys (void) if (!(s->flags & SURF_DRAWBACKGROUND)) { pface = (msurface_t *) s->data; - R_RenderPoly (s->entity, pface, 15); + R_RenderPoly (s->render_id, pface, 15); } } } diff --git a/libs/video/renderer/sw/sw_rmain.c b/libs/video/renderer/sw/sw_rmain.c index 45f5debd2..61e9aa680 100644 --- a/libs/video/renderer/sw/sw_rmain.c +++ b/libs/video/renderer/sw/sw_rmain.c @@ -146,12 +146,58 @@ sw_R_Init (void) 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 = ®->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 = ®->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 R_NewScene (scene_t *scene) { model_t *worldmodel = scene->worldmodel; mod_brush_t *brush = &worldmodel->brush; + r_refdef.registry = scene->reg; r_refdef.worldmodel = worldmodel; // clear out efrags in case the level hasn't been reloaded @@ -380,25 +426,23 @@ R_DrawViewModel (void) } 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; vec3_t acceptpt, rejectpt; double d; - mat4f_t mat; clipflags = 0; - Transform_GetWorldMatrix (transform, mat); - if (mat[0][0] != 1 || mat[1][1] != 1 || mat[2][2] != 1) { + if (transform[0][0] != 1 || transform[1][1] != 1 || transform[2][2] != 1) { 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; - if (d <= -clmodel->radius) + if (d <= -radius) return BMODEL_FULLY_CLIPPED; - if (d <= clmodel->radius) + if (d <= radius) clipflags |= (1 << i); } } else { @@ -449,9 +493,11 @@ R_DrawBrushEntitiesOnList (entqueue_t *queue) for (size_t i = 0; i < queue->ent_queues[mod_brush].size; i++) { entity_t ent = queue->ent_queues[mod_brush].a[i]; + uint32_t render_id = SW_AddEntity (ent); - transform_t transform = Entity_Transform (ent); - VectorCopy (Transform_GetWorldPosition (transform), origin); + vec4f_t *transform = Ent_GetComponent (ent.id, scene_sw_matrix, + ent.reg); + VectorCopy (transform[3], origin); renderer_t *renderer = Ent_GetComponent (ent.id, scene_renderer, ent.reg); model_t *model = renderer->model; @@ -463,7 +509,7 @@ R_DrawBrushEntitiesOnList (entqueue_t *queue) 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) { 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 // world tree is needed, just frustum clipping if (r_drawpolys | r_drawculledpolys) { - R_ZDrawSubmodelPolys (ent, model); + R_ZDrawSubmodelPolys (render_id, brush); } else { visibility_t *visibility = Ent_GetComponent (ent.id, scene_visibility, ent.reg); 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) { // not a leaf; has to be clipped to the world // BSP - mnode_t *node = brush->nodes + topnode_id; + mnode_t *node = world_brush->nodes + topnode_id; r_clipflags = clipflags; - R_DrawSolidClippedSubmodelPolygons (ent, model, node); + R_DrawSolidClippedSubmodelPolygons (render_id, brush, node); } else { // falls entirely in one leaf, so we just put // all the edges in the edge list and let 1/z // sorting handle drawing order - mleaf_t *leaf = brush->leafs + ~topnode_id; - R_DrawSubmodelPolygons (ent, model, clipflags, leaf); + mleaf_t *leaf = world_brush->leafs + ~topnode_id; + R_DrawSubmodelPolygons (render_id, brush, clipflags, leaf); } } @@ -588,6 +634,8 @@ R_RenderView_ (void) return; } + reset_sw_components (r_refdef.registry); + *(mod_brush_t **) SW_COMP (scene_sw_brush, 0) = &r_refdef.worldmodel->brush; R_SetupFrame (); // make FDIV fast. This reduces timing precision after we've been running for a diff --git a/libs/video/renderer/sw/sw_rsurf.c b/libs/video/renderer/sw/sw_rsurf.c index 2b111cdf4..0cb651c15 100644 --- a/libs/video/renderer/sw/sw_rsurf.c +++ b/libs/video/renderer/sw/sw_rsurf.c @@ -73,7 +73,7 @@ static unsigned int blocklights[34 * 34]; //FIXME make dynamic static void -R_AddDynamicLights (transform_t transform) +R_AddDynamicLights (uint32_t render_id) { msurface_t *surf; unsigned int lnum; @@ -91,9 +91,10 @@ R_AddDynamicLights (transform_t transform) tmax = (surf->extents[1] >> 4) + 1; tex = surf->texinfo; - if (Transform_Valid (transform)) { + if (render_id) { //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++) { @@ -144,7 +145,7 @@ R_AddDynamicLights (transform_t transform) Combine and scale multiple lightmaps into the 8.8 format in blocklights */ static void -R_BuildLightMap (transform_t transform) +R_BuildLightMap (uint32_t render_id) { int smax, tmax; int t; @@ -180,7 +181,7 @@ R_BuildLightMap (transform_t transform) } // add all the dynamic lights if (surf->dlightframe == r_framecount) - R_AddDynamicLights (transform); + R_AddDynamicLights (render_id); // bound, invert, and shift for (i = 0; i < size; i++) { @@ -194,7 +195,7 @@ R_BuildLightMap (transform_t transform) } void -R_DrawSurface (transform_t transform) +R_DrawSurface (uint32_t render_id) { byte *basetptr; int smax, tmax, twidth; @@ -206,7 +207,7 @@ R_DrawSurface (transform_t transform) texture_t *mt; // calculate the lightings - R_BuildLightMap (transform); + R_BuildLightMap (render_id); surfrowbytes = r_drawsurf.rowbytes;