[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 drawflat;
struct ecs_registry_s *registry;
struct model_s *worldmodel;
} refdef_t;

View file

@ -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
};

View file

@ -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 !!!

View file

@ -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));

View file

@ -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);

View file

@ -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 ===========================================

View file

@ -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

View file

@ -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 };

View file

@ -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);

View file

@ -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);

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
*/
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;
}

View file

@ -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;

View file

@ -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];
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}
}

View file

@ -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 = &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
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

View file

@ -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;