mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-20 10:43:29 +00:00
[renderer] Split entity queue into per-model-type
While I doubt the difference is all that significant, this should speed up entity rendering because it cuts out a lot of branching, and eliminates scanning the same list multiple times only to not do anything for large chunks of the list.
This commit is contained in:
parent
ab91d73635
commit
ae6970a005
13 changed files with 334 additions and 315 deletions
|
@ -373,7 +373,14 @@ typedef struct {
|
|||
|
||||
// Whole model ================================================================
|
||||
|
||||
typedef enum {mod_brush, mod_sprite, mod_alias, mod_iqm} modtype_t;
|
||||
typedef enum {
|
||||
mod_brush,
|
||||
mod_sprite,
|
||||
mod_alias,
|
||||
mod_iqm,
|
||||
|
||||
mod_num_types
|
||||
} modtype_t;
|
||||
|
||||
#define EF_ROCKET 1 // leave a trail
|
||||
#define EF_GRENADE 2 // leave a trail
|
||||
|
|
|
@ -292,7 +292,7 @@ extern mleaf_t *r_viewleaf;
|
|||
extern int r_clipflags;
|
||||
extern int r_dlightframecount;
|
||||
|
||||
extern struct entity_s *r_ent_queue;
|
||||
extern struct entity_s *r_ent_queue[mod_num_types];
|
||||
struct dlight_s;
|
||||
|
||||
extern vec3_t lightspot;
|
||||
|
|
|
@ -598,11 +598,8 @@ gl_overbright_f (cvar_t *var)
|
|||
if (!gl_R_BuildLightMap)
|
||||
return;
|
||||
|
||||
for (ent = r_ent_queue; ent; ent = ent->next) {
|
||||
for (ent = r_ent_queue[mod_brush]; ent; ent = ent->next) {
|
||||
m = ent->renderer.model;
|
||||
|
||||
if (m->type != mod_brush)
|
||||
continue;
|
||||
if (m->path[0] == '*')
|
||||
continue;
|
||||
|
||||
|
|
|
@ -220,9 +220,7 @@ R_DrawEntitiesOnList (void)
|
|||
qfglEnable (GL_NORMALIZE);
|
||||
}
|
||||
|
||||
for (ent = r_ent_queue; ent; ent = ent->next) {
|
||||
if (ent->renderer.model->type != mod_alias)
|
||||
continue;
|
||||
for (ent = r_ent_queue[mod_alias]; ent; ent = ent->next) {
|
||||
gl_R_DrawAliasModel (ent);
|
||||
}
|
||||
qfglColor3ubv (color_white);
|
||||
|
@ -250,9 +248,7 @@ R_DrawEntitiesOnList (void)
|
|||
qglActiveTexture (gl_mtex_enum + 0);
|
||||
}
|
||||
|
||||
for (ent = r_ent_queue; ent; ent = ent->next) {
|
||||
if (ent->renderer.model->type != mod_iqm)
|
||||
continue;
|
||||
for (ent = r_ent_queue[mod_iqm]; ent; ent = ent->next) {
|
||||
gl_R_DrawIQMModel (ent);
|
||||
}
|
||||
qfglColor3ubv (color_white);
|
||||
|
@ -261,9 +257,7 @@ R_DrawEntitiesOnList (void)
|
|||
qfglEnable (GL_ALPHA_TEST);
|
||||
if (gl_va_capable)
|
||||
qfglInterleavedArrays (GL_T2F_C4UB_V3F, 0, gl_spriteVertexArray);
|
||||
for (ent = r_ent_queue; ent; ent = ent->next) {
|
||||
if (ent->renderer.model->type != mod_sprite)
|
||||
continue;
|
||||
for (ent = r_ent_queue[mod_sprite]; ent; ent = ent->next) {
|
||||
R_DrawSpriteModel (ent);
|
||||
}
|
||||
qfglDisable (GL_ALPHA_TEST);
|
||||
|
|
|
@ -741,10 +741,7 @@ gl_R_DrawWorld (void)
|
|||
R_VisitWorldNodes (&bctx);
|
||||
if (r_drawentities->int_val) {
|
||||
entity_t *ent;
|
||||
for (ent = r_ent_queue; ent; ent = ent->next) {
|
||||
if (ent->renderer.model->type != mod_brush) {
|
||||
continue;
|
||||
}
|
||||
for (ent = r_ent_queue[mod_brush]; ent; ent = ent->next) {
|
||||
gl_R_DrawBrushModel (ent);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1150,9 +1150,7 @@ glsl_R_DrawWorld (void)
|
|||
R_VisitWorldNodes (&bctx);
|
||||
if (r_drawentities->int_val) {
|
||||
entity_t *ent;
|
||||
for (ent = r_ent_queue; ent; ent = ent->next) {
|
||||
if (ent->renderer.model->type != mod_brush)
|
||||
continue;
|
||||
for (ent = r_ent_queue[mod_brush]; ent; ent = ent->next) {
|
||||
R_DrawBrushModel (ent);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,9 +149,7 @@ R_RenderEntities (void)
|
|||
#define RE_LOOP(type_name, Type) \
|
||||
do { \
|
||||
begun = 0; \
|
||||
for (ent = r_ent_queue; ent; ent = ent->next) { \
|
||||
if (ent->renderer.model->type != mod_##type_name) \
|
||||
continue; \
|
||||
for (ent = r_ent_queue[mod_##type_name]; ent; ent = ent->next) { \
|
||||
if (!begun) { \
|
||||
glsl_R_##Type##Begin (); \
|
||||
begun = 1; \
|
||||
|
|
|
@ -244,8 +244,6 @@ R_StoreEfrags (const efrag_t *efrag)
|
|||
break;
|
||||
|
||||
default:
|
||||
Sys_Error ("R_StoreEfrags: Bad entity type %d",
|
||||
model->type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,8 +55,13 @@ typedef struct entity_pool_s {
|
|||
entity_t entities[ENT_POOL_SIZE];
|
||||
} entity_pool_t;
|
||||
|
||||
entity_t *r_ent_queue;
|
||||
static entity_t **vis_tail = &r_ent_queue;
|
||||
entity_t *r_ent_queue[mod_num_types];
|
||||
static entity_t **vis_tail[mod_num_types] = {
|
||||
[mod_brush] &r_ent_queue[mod_brush],
|
||||
[mod_sprite] &r_ent_queue[mod_sprite],
|
||||
[mod_alias] &r_ent_queue[mod_alias],
|
||||
[mod_iqm] &r_ent_queue[mod_iqm],
|
||||
};
|
||||
|
||||
static entity_pool_t *entity_pools = 0;
|
||||
static entity_pool_t **entpool_tail = &entity_pools;
|
||||
|
@ -119,16 +124,23 @@ R_FreeAllEntities (void)
|
|||
void
|
||||
R_ClearEnts (void)
|
||||
{
|
||||
r_ent_queue = 0;
|
||||
vis_tail = &r_ent_queue;
|
||||
for (int i = 0; i < mod_num_types; i++) {
|
||||
r_ent_queue[i] = 0;
|
||||
vis_tail[i] = &r_ent_queue[i];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
R_EnqueueEntity (entity_t *ent)
|
||||
{
|
||||
modtype_t type = ent->renderer.model->type;
|
||||
|
||||
if (type < 0 || type >= mod_num_types) {
|
||||
Sys_Error ("R_EnqueueEntity: Bad entity model type %d", type);
|
||||
}
|
||||
ent->next = 0;
|
||||
*vis_tail = ent;
|
||||
vis_tail = &ent->next;
|
||||
*vis_tail[type] = ent;
|
||||
vis_tail[type] = &ent->next;
|
||||
}
|
||||
|
||||
float
|
||||
|
|
|
@ -340,84 +340,102 @@ R_ViewChanged (void)
|
|||
D_ViewChanged ();
|
||||
}
|
||||
|
||||
static inline void
|
||||
draw_sprite_entity (entity_t *ent)
|
||||
{
|
||||
VectorSubtract (r_origin, r_entorigin, modelorg);
|
||||
R_DrawSprite ();
|
||||
}
|
||||
|
||||
static inline void
|
||||
setup_lighting (alight_t *lighting)
|
||||
{
|
||||
float minlight = 0;
|
||||
int j;
|
||||
// FIXME: remove and do real lighting
|
||||
vec3_t dist;
|
||||
float add;
|
||||
float lightvec[3] = { -1, 0, 0 };
|
||||
|
||||
minlight = max (currententity->renderer.model->min_light,
|
||||
currententity->renderer.min_light);
|
||||
|
||||
// 128 instead of 255 due to clamping below
|
||||
j = max (R_LightPoint (&r_worldentity.renderer.model->brush, r_entorigin),
|
||||
minlight * 128);
|
||||
|
||||
lighting->ambientlight = j;
|
||||
lighting->shadelight = j;
|
||||
|
||||
lighting->plightvec = lightvec;
|
||||
|
||||
for (unsigned lnum = 0; lnum < r_maxdlights; lnum++) {
|
||||
if (r_dlights[lnum].die >= vr_data.realtime) {
|
||||
VectorSubtract (r_entorigin, r_dlights[lnum].origin, dist);
|
||||
add = r_dlights[lnum].radius - VectorLength (dist);
|
||||
|
||||
if (add > 0)
|
||||
lighting->ambientlight += add;
|
||||
}
|
||||
}
|
||||
|
||||
// clamp lighting so it doesn't overbright as much
|
||||
if (lighting->ambientlight > 128)
|
||||
lighting->ambientlight = 128;
|
||||
if (lighting->ambientlight + lighting->shadelight > 192)
|
||||
lighting->shadelight = 192 - lighting->ambientlight;
|
||||
}
|
||||
|
||||
static inline void
|
||||
draw_alias_entity (entity_t *ent)
|
||||
{
|
||||
VectorSubtract (r_origin, r_entorigin, modelorg);
|
||||
|
||||
// see if the bounding box lets us trivially reject, also
|
||||
// sets trivial accept status
|
||||
currententity->visibility.trivial_accept = 0; //FIXME
|
||||
if (R_AliasCheckBBox ()) {
|
||||
alight_t lighting;
|
||||
setup_lighting (&lighting);
|
||||
R_AliasDrawModel (&lighting);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
draw_iqm_entity (entity_t *ent)
|
||||
{
|
||||
VectorSubtract (r_origin, r_entorigin, modelorg);
|
||||
|
||||
// see if the bounding box lets us trivially reject, also
|
||||
// sets trivial accept status
|
||||
currententity->visibility.trivial_accept = 0; //FIXME
|
||||
|
||||
alight_t lighting;
|
||||
setup_lighting (&lighting);
|
||||
R_IQMDrawModel (&lighting);
|
||||
}
|
||||
|
||||
static void
|
||||
R_DrawEntitiesOnList (void)
|
||||
{
|
||||
int j;
|
||||
unsigned int lnum;
|
||||
alight_t lighting;
|
||||
entity_t *ent;
|
||||
|
||||
// FIXME: remove and do real lighting
|
||||
float lightvec[3] = { -1, 0, 0 };
|
||||
vec3_t dist;
|
||||
float add;
|
||||
float minlight = 0;
|
||||
|
||||
if (!r_drawentities->int_val)
|
||||
return;
|
||||
|
||||
for (ent = r_ent_queue; ent; ent = ent->next) {
|
||||
currententity = ent;
|
||||
#define RE_LOOP(type_name) \
|
||||
do { \
|
||||
for (ent = r_ent_queue[mod_##type_name]; ent; ent = ent->next) { \
|
||||
VectorCopy (Transform_GetWorldPosition (ent->transform), \
|
||||
r_entorigin); \
|
||||
currententity = ent; \
|
||||
draw_##type_name##_entity (ent); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
VectorCopy (Transform_GetWorldPosition (currententity->transform),
|
||||
r_entorigin);
|
||||
switch (currententity->renderer.model->type) {
|
||||
case mod_sprite:
|
||||
VectorSubtract (r_origin, r_entorigin, modelorg);
|
||||
R_DrawSprite ();
|
||||
break;
|
||||
|
||||
case mod_alias:
|
||||
case mod_iqm:
|
||||
VectorSubtract (r_origin, r_entorigin, modelorg);
|
||||
|
||||
minlight = max (currententity->renderer.model->min_light,
|
||||
currententity->renderer.min_light);
|
||||
|
||||
// see if the bounding box lets us trivially reject, also
|
||||
// sets trivial accept status
|
||||
currententity->visibility.trivial_accept = 0; //FIXME
|
||||
if (currententity->renderer.model->type == mod_iqm//FIXME
|
||||
|| R_AliasCheckBBox ()) {
|
||||
// 128 instead of 255 due to clamping below
|
||||
j = max (R_LightPoint (&r_worldentity.renderer.model->brush,
|
||||
r_entorigin), minlight * 128);
|
||||
|
||||
lighting.ambientlight = j;
|
||||
lighting.shadelight = j;
|
||||
|
||||
lighting.plightvec = lightvec;
|
||||
|
||||
for (lnum = 0; lnum < r_maxdlights; lnum++) {
|
||||
if (r_dlights[lnum].die >= vr_data.realtime) {
|
||||
VectorSubtract (r_entorigin,
|
||||
r_dlights[lnum].origin, dist);
|
||||
add = r_dlights[lnum].radius - VectorLength (dist);
|
||||
|
||||
if (add > 0)
|
||||
lighting.ambientlight += add;
|
||||
}
|
||||
}
|
||||
|
||||
// clamp lighting so it doesn't overbright as much
|
||||
if (lighting.ambientlight > 128)
|
||||
lighting.ambientlight = 128;
|
||||
if (lighting.ambientlight + lighting.shadelight > 192)
|
||||
lighting.shadelight = 192 - lighting.ambientlight;
|
||||
|
||||
if (currententity->renderer.model->type == mod_iqm)
|
||||
R_IQMDrawModel (&lighting);
|
||||
else
|
||||
R_AliasDrawModel (&lighting);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
RE_LOOP (alias);
|
||||
RE_LOOP (iqm);
|
||||
RE_LOOP (sprite);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -556,90 +574,83 @@ R_DrawBEntitiesOnList (void)
|
|||
VectorCopy (modelorg, oldorigin);
|
||||
insubmodel = true;
|
||||
|
||||
for (ent = r_ent_queue; ent; ent = ent->next) {
|
||||
for (ent = r_ent_queue[mod_brush]; ent; ent = ent->next) {
|
||||
currententity = ent;
|
||||
|
||||
VectorCopy (Transform_GetWorldPosition (currententity->transform),
|
||||
origin);
|
||||
switch (currententity->renderer.model->type) {
|
||||
case mod_brush:
|
||||
clmodel = currententity->renderer.model;
|
||||
clmodel = currententity->renderer.model;
|
||||
|
||||
// see if the bounding box lets us trivially reject, also
|
||||
// sets trivial accept status
|
||||
for (j = 0; j < 3; j++) {
|
||||
minmaxs[j] = origin[j] + clmodel->mins[j];
|
||||
minmaxs[3 + j] = origin[j] + clmodel->maxs[j];
|
||||
}
|
||||
// see if the bounding box lets us trivially reject, also
|
||||
// sets trivial accept status
|
||||
for (j = 0; j < 3; j++) {
|
||||
minmaxs[j] = origin[j] + clmodel->mins[j];
|
||||
minmaxs[3 + j] = origin[j] + clmodel->maxs[j];
|
||||
}
|
||||
|
||||
clipflags = R_BmodelCheckBBox (clmodel, minmaxs);
|
||||
clipflags = R_BmodelCheckBBox (clmodel, minmaxs);
|
||||
|
||||
if (clipflags != BMODEL_FULLY_CLIPPED) {
|
||||
mod_brush_t *brush = &clmodel->brush;
|
||||
VectorCopy (origin, r_entorigin);
|
||||
VectorSubtract (r_origin, r_entorigin, modelorg);
|
||||
if (clipflags != BMODEL_FULLY_CLIPPED) {
|
||||
mod_brush_t *brush = &clmodel->brush;
|
||||
VectorCopy (origin, r_entorigin);
|
||||
VectorSubtract (r_origin, r_entorigin, modelorg);
|
||||
|
||||
// FIXME: is this needed?
|
||||
VectorCopy (modelorg, r_worldmodelorg);
|
||||
r_pcurrentvertbase = brush->vertexes;
|
||||
// FIXME: is this needed?
|
||||
VectorCopy (modelorg, r_worldmodelorg);
|
||||
r_pcurrentvertbase = brush->vertexes;
|
||||
|
||||
// FIXME: stop transforming twice
|
||||
R_RotateBmodel ();
|
||||
// FIXME: stop transforming twice
|
||||
R_RotateBmodel ();
|
||||
|
||||
// calculate dynamic lighting for bmodel if it's not an
|
||||
// instanced model
|
||||
if (brush->firstmodelsurface != 0) {
|
||||
vec3_t lightorigin;
|
||||
// calculate dynamic lighting for bmodel if it's not an
|
||||
// instanced model
|
||||
if (brush->firstmodelsurface != 0) {
|
||||
vec3_t lightorigin;
|
||||
|
||||
for (k = 0; k < r_maxdlights; k++) {
|
||||
if ((r_dlights[k].die < vr_data.realtime) ||
|
||||
(!r_dlights[k].radius)) continue;
|
||||
|
||||
VectorSubtract (r_dlights[k].origin, origin,
|
||||
lightorigin);
|
||||
R_RecursiveMarkLights (brush, lightorigin,
|
||||
&r_dlights[k], k,
|
||||
brush->nodes
|
||||
+ brush->hulls[0].firstclipnode);
|
||||
}
|
||||
for (k = 0; k < r_maxdlights; k++) {
|
||||
if ((r_dlights[k].die < vr_data.realtime) ||
|
||||
(!r_dlights[k].radius)) {
|
||||
continue;
|
||||
}
|
||||
// if the driver wants polygons, deliver those.
|
||||
// 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 (clmodel);
|
||||
|
||||
VectorSubtract (r_dlights[k].origin, origin, lightorigin);
|
||||
R_RecursiveMarkLights (brush, lightorigin,
|
||||
&r_dlights[k], k,
|
||||
brush->nodes
|
||||
+ brush->hulls[0].firstclipnode);
|
||||
}
|
||||
}
|
||||
// if the driver wants polygons, deliver those.
|
||||
// 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 (clmodel);
|
||||
} else {
|
||||
if (currententity->visibility.topnode) {
|
||||
mnode_t *topnode = currententity->visibility.topnode;
|
||||
|
||||
if (topnode->contents >= 0) {
|
||||
// not a leaf; has to be clipped to the world
|
||||
// BSP
|
||||
r_clipflags = clipflags;
|
||||
R_DrawSolidClippedSubmodelPolygons (clmodel);
|
||||
} else {
|
||||
if (currententity->visibility.topnode) {
|
||||
mnode_t *topnode
|
||||
= currententity->visibility.topnode;
|
||||
|
||||
if (topnode->contents >= 0) {
|
||||
// not a leaf; has to be clipped to the world
|
||||
// BSP
|
||||
r_clipflags = clipflags;
|
||||
R_DrawSolidClippedSubmodelPolygons (clmodel);
|
||||
} 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
|
||||
R_DrawSubmodelPolygons (clmodel, clipflags);
|
||||
}
|
||||
|
||||
}
|
||||
// falls entirely in one leaf, so we just put
|
||||
// all the edges in the edge list and let 1/z
|
||||
// sorting handle drawing order
|
||||
R_DrawSubmodelPolygons (clmodel, clipflags);
|
||||
}
|
||||
|
||||
// put back world rotation and frustum clipping
|
||||
// FIXME: R_RotateBmodel should just work off base_vxx
|
||||
VectorCopy (base_vpn, vpn);
|
||||
VectorCopy (base_vup, vup);
|
||||
VectorCopy (base_vright, vright);
|
||||
VectorCopy (base_modelorg, modelorg);
|
||||
VectorCopy (oldorigin, modelorg);
|
||||
R_TransformFrustum ();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// put back world rotation and frustum clipping
|
||||
// FIXME: R_RotateBmodel should just work off base_vxx
|
||||
VectorCopy (base_vpn, vpn);
|
||||
VectorCopy (base_vup, vup);
|
||||
VectorCopy (base_vright, vright);
|
||||
VectorCopy (base_modelorg, modelorg);
|
||||
VectorCopy (oldorigin, modelorg);
|
||||
R_TransformFrustum ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -347,85 +347,102 @@ sw32_R_ViewChanged (void)
|
|||
sw32_D_ViewChanged ();
|
||||
}
|
||||
|
||||
static inline void
|
||||
draw_sprite_entity (entity_t *ent)
|
||||
{
|
||||
VectorSubtract (r_origin, r_entorigin, modelorg);
|
||||
sw32_R_DrawSprite ();
|
||||
}
|
||||
|
||||
static inline void
|
||||
setup_lighting (alight_t *lighting)
|
||||
{
|
||||
float minlight = 0;
|
||||
int j;
|
||||
// FIXME: remove and do real lighting
|
||||
vec3_t dist;
|
||||
float add;
|
||||
float lightvec[3] = { -1, 0, 0 };
|
||||
|
||||
minlight = max (currententity->renderer.model->min_light,
|
||||
currententity->renderer.min_light);
|
||||
|
||||
// 128 instead of 255 due to clamping below
|
||||
j = max (R_LightPoint (&r_worldentity.renderer.model->brush, r_entorigin),
|
||||
minlight * 128);
|
||||
|
||||
lighting->ambientlight = j;
|
||||
lighting->shadelight = j;
|
||||
|
||||
lighting->plightvec = lightvec;
|
||||
|
||||
for (unsigned lnum = 0; lnum < r_maxdlights; lnum++) {
|
||||
if (r_dlights[lnum].die >= vr_data.realtime) {
|
||||
VectorSubtract (r_entorigin, r_dlights[lnum].origin, dist);
|
||||
add = r_dlights[lnum].radius - VectorLength (dist);
|
||||
|
||||
if (add > 0)
|
||||
lighting->ambientlight += add;
|
||||
}
|
||||
}
|
||||
|
||||
// clamp lighting so it doesn't overbright as much
|
||||
if (lighting->ambientlight > 128)
|
||||
lighting->ambientlight = 128;
|
||||
if (lighting->ambientlight + lighting->shadelight > 192)
|
||||
lighting->shadelight = 192 - lighting->ambientlight;
|
||||
}
|
||||
|
||||
static inline void
|
||||
draw_alias_entity (entity_t *ent)
|
||||
{
|
||||
VectorSubtract (r_origin, r_entorigin, modelorg);
|
||||
|
||||
// see if the bounding box lets us trivially reject, also
|
||||
// sets trivial accept status
|
||||
currententity->visibility.trivial_accept = 0; //FIXME
|
||||
if (R_AliasCheckBBox ()) {
|
||||
alight_t lighting;
|
||||
setup_lighting (&lighting);
|
||||
sw32_R_AliasDrawModel (&lighting);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
draw_iqm_entity (entity_t *ent)
|
||||
{
|
||||
VectorSubtract (r_origin, r_entorigin, modelorg);
|
||||
|
||||
// see if the bounding box lets us trivially reject, also
|
||||
// sets trivial accept status
|
||||
currententity->visibility.trivial_accept = 0; //FIXME
|
||||
|
||||
alight_t lighting;
|
||||
setup_lighting (&lighting);
|
||||
sw32_R_IQMDrawModel (&lighting);
|
||||
}
|
||||
|
||||
static void
|
||||
R_DrawEntitiesOnList (void)
|
||||
{
|
||||
int j;
|
||||
unsigned int lnum;
|
||||
alight_t lighting;
|
||||
entity_t *ent;
|
||||
|
||||
// FIXME: remove and do real lighting
|
||||
float lightvec[3] = { -1, 0, 0 };
|
||||
vec3_t dist;
|
||||
float add;
|
||||
float minlight;
|
||||
|
||||
if (!r_drawentities->int_val)
|
||||
return;
|
||||
|
||||
for (ent = r_ent_queue; ent; ent = ent->next) {
|
||||
currententity = ent;
|
||||
#define RE_LOOP(type_name) \
|
||||
do { \
|
||||
for (ent = r_ent_queue[mod_##type_name]; ent; ent = ent->next) { \
|
||||
VectorCopy (Transform_GetWorldPosition (ent->transform), \
|
||||
r_entorigin); \
|
||||
currententity = ent; \
|
||||
draw_##type_name##_entity (ent); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
VectorCopy (Transform_GetWorldPosition (currententity->transform),
|
||||
r_entorigin);
|
||||
switch (currententity->renderer.model->type) {
|
||||
case mod_sprite:
|
||||
VectorSubtract (r_origin, r_entorigin, modelorg);
|
||||
sw32_R_DrawSprite ();
|
||||
break;
|
||||
|
||||
case mod_alias:
|
||||
case mod_iqm:
|
||||
VectorSubtract (r_origin, r_entorigin, modelorg);
|
||||
|
||||
minlight = max (currententity->renderer.min_light,
|
||||
currententity->renderer.model->min_light);
|
||||
|
||||
// see if the bounding box lets us trivially reject, also
|
||||
// sets trivial accept status
|
||||
currententity->visibility.trivial_accept = 0; //FIXME
|
||||
if (currententity->renderer.model->type == mod_iqm//FIXME
|
||||
|| sw32_R_AliasCheckBBox ()) {
|
||||
// 128 instead of 255 due to clamping below
|
||||
j = max (R_LightPoint (&r_worldentity.renderer.model->brush,
|
||||
r_entorigin),
|
||||
minlight * 128);
|
||||
|
||||
lighting.ambientlight = j;
|
||||
lighting.shadelight = j;
|
||||
|
||||
lighting.plightvec = lightvec;
|
||||
|
||||
for (lnum = 0; lnum < r_maxdlights; lnum++) {
|
||||
if (r_dlights[lnum].die >= vr_data.realtime) {
|
||||
VectorSubtract (r_entorigin,
|
||||
r_dlights[lnum].origin, dist);
|
||||
add = r_dlights[lnum].radius - VectorLength (dist);
|
||||
|
||||
if (add > 0)
|
||||
lighting.ambientlight += add;
|
||||
}
|
||||
}
|
||||
|
||||
// clamp lighting so it doesn't overbright as much
|
||||
if (lighting.ambientlight > 128)
|
||||
lighting.ambientlight = 128;
|
||||
if (lighting.ambientlight + lighting.shadelight > 192)
|
||||
lighting.shadelight = 192 - lighting.ambientlight;
|
||||
|
||||
if (currententity->renderer.model->type == mod_iqm)
|
||||
sw32_R_IQMDrawModel (&lighting);
|
||||
else
|
||||
sw32_R_AliasDrawModel (&lighting);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
RE_LOOP (alias);
|
||||
RE_LOOP (iqm);
|
||||
RE_LOOP (sprite);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -563,89 +580,83 @@ R_DrawBEntitiesOnList (void)
|
|||
VectorCopy (modelorg, oldorigin);
|
||||
insubmodel = true;
|
||||
|
||||
for (ent = r_ent_queue; ent; ent = ent->next) {
|
||||
for (ent = r_ent_queue[mod_brush]; ent; ent = ent->next) {
|
||||
currententity = ent;
|
||||
|
||||
VectorCopy (Transform_GetWorldPosition (currententity->transform),
|
||||
origin);
|
||||
switch (currententity->renderer.model->type) {
|
||||
case mod_brush:
|
||||
clmodel = currententity->renderer.model;
|
||||
clmodel = currententity->renderer.model;
|
||||
|
||||
// see if the bounding box lets us trivially reject, also
|
||||
// sets trivial accept status
|
||||
for (j = 0; j < 3; j++) {
|
||||
minmaxs[j] = origin[j] + clmodel->mins[j];
|
||||
minmaxs[3 + j] = origin[j] + clmodel->maxs[j];
|
||||
}
|
||||
// see if the bounding box lets us trivially reject, also
|
||||
// sets trivial accept status
|
||||
for (j = 0; j < 3; j++) {
|
||||
minmaxs[j] = origin[j] + clmodel->mins[j];
|
||||
minmaxs[3 + j] = origin[j] + clmodel->maxs[j];
|
||||
}
|
||||
|
||||
clipflags = R_BmodelCheckBBox (clmodel, minmaxs);
|
||||
clipflags = R_BmodelCheckBBox (clmodel, minmaxs);
|
||||
|
||||
if (clipflags != BMODEL_FULLY_CLIPPED) {
|
||||
mod_brush_t *brush = &clmodel->brush;
|
||||
VectorCopy (origin, r_entorigin);
|
||||
VectorSubtract (r_origin, r_entorigin, modelorg);
|
||||
if (clipflags != BMODEL_FULLY_CLIPPED) {
|
||||
mod_brush_t *brush = &clmodel->brush;
|
||||
VectorCopy (origin, r_entorigin);
|
||||
VectorSubtract (r_origin, r_entorigin, modelorg);
|
||||
|
||||
// FIXME: is this needed?
|
||||
VectorCopy (modelorg, sw32_r_worldmodelorg);
|
||||
r_pcurrentvertbase = brush->vertexes;
|
||||
// FIXME: is this needed?
|
||||
VectorCopy (modelorg, sw32_r_worldmodelorg);
|
||||
r_pcurrentvertbase = brush->vertexes;
|
||||
|
||||
// FIXME: stop transforming twice
|
||||
sw32_R_RotateBmodel ();
|
||||
// FIXME: stop transforming twice
|
||||
sw32_R_RotateBmodel ();
|
||||
|
||||
// calculate dynamic lighting for bmodel if it's not an
|
||||
// instanced model
|
||||
if (brush->firstmodelsurface != 0) {
|
||||
vec3_t lightorigin;
|
||||
// calculate dynamic lighting for bmodel if it's not an
|
||||
// instanced model
|
||||
if (brush->firstmodelsurface != 0) {
|
||||
vec3_t lightorigin;
|
||||
|
||||
for (k = 0; k < r_maxdlights; k++) {
|
||||
if ((r_dlights[k].die < vr_data.realtime) ||
|
||||
(!r_dlights[k].radius)) continue;
|
||||
|
||||
VectorSubtract (r_dlights[k].origin, origin,
|
||||
lightorigin);
|
||||
R_RecursiveMarkLights (brush, lightorigin,
|
||||
&r_dlights[k], k,
|
||||
brush->nodes
|
||||
+ brush->hulls[0].firstclipnode);
|
||||
}
|
||||
for (k = 0; k < r_maxdlights; k++) {
|
||||
if ((r_dlights[k].die < vr_data.realtime) ||
|
||||
(!r_dlights[k].radius)) {
|
||||
continue;
|
||||
}
|
||||
// if the driver wants polygons, deliver those.
|
||||
// Z-buffering is on at this point, so no clipping to the
|
||||
// world tree is needed, just frustum clipping
|
||||
if (sw32_r_drawpolys | sw32_r_drawculledpolys) {
|
||||
sw32_R_ZDrawSubmodelPolys (clmodel);
|
||||
|
||||
VectorSubtract (r_dlights[k].origin, origin, lightorigin);
|
||||
R_RecursiveMarkLights (brush, lightorigin,
|
||||
&r_dlights[k], k,
|
||||
brush->nodes
|
||||
+ brush->hulls[0].firstclipnode);
|
||||
}
|
||||
}
|
||||
// if the driver wants polygons, deliver those.
|
||||
// Z-buffering is on at this point, so no clipping to the
|
||||
// world tree is needed, just frustum clipping
|
||||
if (sw32_r_drawpolys | sw32_r_drawculledpolys) {
|
||||
sw32_R_ZDrawSubmodelPolys (clmodel);
|
||||
} else {
|
||||
if (currententity->visibility.topnode) {
|
||||
mnode_t *topnode = currententity->visibility.topnode;
|
||||
|
||||
if (topnode->contents >= 0) {
|
||||
// not a leaf; has to be clipped to the world
|
||||
// BSP
|
||||
sw32_r_clipflags = clipflags;
|
||||
sw32_R_DrawSolidClippedSubmodelPolygons (clmodel);
|
||||
} else {
|
||||
if (currententity->visibility.topnode) {
|
||||
mnode_t *topnode
|
||||
= currententity->visibility.topnode;
|
||||
|
||||
if (topnode->contents >= 0) {
|
||||
// not a leaf; has to be clipped to the world
|
||||
// BSP
|
||||
sw32_r_clipflags = clipflags;
|
||||
sw32_R_DrawSolidClippedSubmodelPolygons (clmodel);
|
||||
} 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
|
||||
sw32_R_DrawSubmodelPolygons (clmodel, clipflags);
|
||||
}
|
||||
}
|
||||
// falls entirely in one leaf, so we just put
|
||||
// all the edges in the edge list and let 1/z
|
||||
// sorting handle drawing order
|
||||
sw32_R_DrawSubmodelPolygons (clmodel, clipflags);
|
||||
}
|
||||
|
||||
// put back world rotation and frustum clipping
|
||||
// FIXME: sw32_R_RotateBmodel should just work off base_vxx
|
||||
VectorCopy (base_vpn, vpn);
|
||||
VectorCopy (base_vup, vup);
|
||||
VectorCopy (base_vright, vright);
|
||||
VectorCopy (base_modelorg, modelorg);
|
||||
VectorCopy (oldorigin, modelorg);
|
||||
sw32_R_TransformFrustum ();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// put back world rotation and frustum clipping
|
||||
// FIXME: sw32_R_RotateBmodel should just work off base_vxx
|
||||
VectorCopy (base_vpn, vpn);
|
||||
VectorCopy (base_vup, vup);
|
||||
VectorCopy (base_vright, vright);
|
||||
VectorCopy (base_modelorg, modelorg);
|
||||
VectorCopy (oldorigin, modelorg);
|
||||
sw32_R_TransformFrustum ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1040,9 +1040,7 @@ Vulkan_DrawWorld (qfv_renderframe_t *rFrame)
|
|||
R_VisitWorldNodes (brush, ctx);
|
||||
if (r_drawentities->int_val) {
|
||||
entity_t *ent;
|
||||
for (ent = r_ent_queue; ent; ent = ent->next) {
|
||||
if (ent->renderer.model->type != mod_brush)
|
||||
continue;
|
||||
for (ent = r_ent_queue[mod_brush]; ent; ent = ent->next) {
|
||||
R_DrawBrushModel (ent, ctx);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,9 +87,7 @@ Vulkan_RenderEntities (qfv_renderframe_t *rFrame)
|
|||
do { \
|
||||
entity_t *ent; \
|
||||
int begun = 0; \
|
||||
for (ent = r_ent_queue; ent; ent = ent->next) { \
|
||||
if (ent->renderer.model->type != mod_##type_name) \
|
||||
continue; \
|
||||
for (ent = r_ent_queue[mod_##type_name]; ent; ent = ent->next) { \
|
||||
if (!begun) { \
|
||||
Vulkan_##Type##Begin (rFrame); \
|
||||
begun = 1; \
|
||||
|
|
Loading…
Reference in a new issue