mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 07:11:41 +00:00
[scene] Move dynamic lights into the scene ECS
While the insertion of dlights into the BSP might wind up being overly expensive, the automatic management of the component pool cleans up the various loops in the renderers. Unfortunately, (current bug) lights on entities cause the entity to disappear due to how the entity queue system works, and the doubled efrag chain causes crashes when changing maps, meaning lights should be on their own entities, not additional components on entities with visible models. Also, the vulkan renderer segfaults on dlights (fix incoming, along with shadows for dlights).
This commit is contained in:
parent
7537cb8d1c
commit
35ec2ebb4c
34 changed files with 405 additions and 444 deletions
|
@ -96,22 +96,16 @@ typedef struct subpic_s {
|
|||
|
||||
// dynamic lights ===========================================================
|
||||
|
||||
typedef struct dlight_s
|
||||
{
|
||||
int key; // so entities can reuse same entry
|
||||
vec3_t origin;
|
||||
typedef struct dlight_s {
|
||||
vec4f_t origin;
|
||||
vec4f_t color;
|
||||
float radius;
|
||||
float die; // stop lighting after this time
|
||||
float decay; // drop this each second
|
||||
float minlight; // don't add when contributing less
|
||||
float color[4];
|
||||
} dlight_t;
|
||||
|
||||
extern dlight_t *r_dlights;
|
||||
extern unsigned int r_maxdlights;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
int length;
|
||||
char map[MAX_STYLESTRING];
|
||||
char average;
|
||||
|
@ -180,8 +174,6 @@ void R_LoadModule (struct vid_internal_s *vid_internal);
|
|||
struct progs_s;
|
||||
void R_Progs_Init (struct progs_s *pr);
|
||||
|
||||
dlight_t *R_AllocDlight (int key);
|
||||
void R_DecayLights (double frametime);
|
||||
void Fog_Update (float density, float red, float green, float blue,
|
||||
float time);
|
||||
struct plitem_s;
|
||||
|
|
|
@ -68,5 +68,8 @@ void Light_ClearLights (lightingdata_t *ldata);
|
|||
void Light_AddLight (lightingdata_t *ldata, const light_t *light,
|
||||
uint32_t style);
|
||||
void Light_EnableSun (lightingdata_t *ldata);
|
||||
void Light_DecayLights (lightingdata_t *ldata, float frametime,
|
||||
double realtime);
|
||||
void Light_LinkLight (lightingdata_t *ldata, uint32_t entid);
|
||||
|
||||
#endif//__QF_scene_light_h
|
||||
|
|
|
@ -49,6 +49,8 @@ enum scene_components {
|
|||
scene_old_origin, //XXX FIXME XXX should not be here
|
||||
scene_colormap,
|
||||
|
||||
scene_dynlight,
|
||||
|
||||
scene_light,
|
||||
scene_efrags,
|
||||
scene_lightstyle,
|
||||
|
|
|
@ -35,13 +35,13 @@
|
|||
struct entity_s;
|
||||
struct entity_state_s;
|
||||
|
||||
void CL_NewDlight (int key, vec4f_t org, int effects, byte glow_size,
|
||||
byte glow_color, double time);
|
||||
void CL_ModelEffects (struct entity_s ent, int num, int glow_color,
|
||||
void CL_NewDlight (struct entity_s ent, vec4f_t org, int effects,
|
||||
byte glow_size, byte glow_color, double time);
|
||||
void CL_ModelEffects (struct entity_s ent, int glow_color,
|
||||
double time);
|
||||
void CL_EntityEffects (int num, struct entity_s ent,
|
||||
struct entity_state_s *state, double time);
|
||||
void CL_MuzzleFlash (vec4f_t position, vec4f_t fv, float zoffset, int num,
|
||||
double time);
|
||||
void CL_EntityEffects (struct entity_s ent, struct entity_state_s *state,
|
||||
double time);
|
||||
void CL_MuzzleFlash (struct entity_s ent, vec4f_t position, vec4f_t fv,
|
||||
float zoffset, double time);
|
||||
|
||||
#endif//__client_effects_h
|
||||
|
|
|
@ -45,7 +45,6 @@ typedef enum {
|
|||
|
||||
struct entity_s;
|
||||
|
||||
void R_MaxDlightsCheck (int max_dlights);
|
||||
void R_Particles_Init_Cvars (void);
|
||||
void R_InitBubble (void);
|
||||
|
||||
|
|
|
@ -77,9 +77,6 @@ void R_LoadSkys (const char *);
|
|||
void R_ClearEfrags (void);
|
||||
|
||||
int R_FindNearLights (vec4f_t pos, int count, dlight_t **lights);
|
||||
dlight_t *R_AllocDlight (int key);
|
||||
void R_DecayLights (double frametime);
|
||||
void R_ClearDlights (void);
|
||||
|
||||
int R_InitGraphTextures (int base);
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
#include "QF/plugin/vid_render.h" //FIXME
|
||||
#include "QF/scene/entity.h"
|
||||
#include "QF/scene/light.h"
|
||||
#include "QF/scene/scene.h"
|
||||
|
||||
#include "client/entities.h"
|
||||
|
@ -50,15 +51,13 @@
|
|||
#include "client/world.h"
|
||||
|
||||
void
|
||||
CL_NewDlight (int key, vec4f_t org, int effects, byte glow_size,
|
||||
CL_NewDlight (entity_t ent, vec4f_t org, int effects, byte glow_size,
|
||||
byte glow_color, double time)
|
||||
{
|
||||
float radius;
|
||||
dlight_t *dl;
|
||||
static quat_t normal = {0.4, 0.2, 0.05, 0.7};
|
||||
static quat_t red = {0.5, 0.05, 0.05, 0.7};
|
||||
static quat_t blue = {0.05, 0.05, 0.5, 0.7};
|
||||
static quat_t purple = {0.5, 0.05, 0.5, 0.7};
|
||||
static vec4f_t normal = {0.4, 0.2, 0.05, 0.7};
|
||||
static vec4f_t red = {0.5, 0.05, 0.05, 0.7};
|
||||
static vec4f_t blue = {0.05, 0.05, 0.5, 0.7};
|
||||
static vec4f_t purple = {0.5, 0.05, 0.5, 0.7};
|
||||
|
||||
effects &= EF_BLUE | EF_RED | EF_BRIGHTLIGHT | EF_DIMLIGHT;
|
||||
if (!effects) {
|
||||
|
@ -66,60 +65,56 @@ CL_NewDlight (int key, vec4f_t org, int effects, byte glow_size,
|
|||
return;
|
||||
}
|
||||
|
||||
dl = R_AllocDlight (key);
|
||||
if (!dl)
|
||||
return;
|
||||
VectorCopy (org, dl->origin);
|
||||
float radius = 0;
|
||||
float die = time + 0.1;
|
||||
vec4f_t color = normal;
|
||||
|
||||
if (effects & (EF_BLUE | EF_RED | EF_BRIGHTLIGHT | EF_DIMLIGHT)) {
|
||||
radius = 200 + (rand () & 31);
|
||||
if (effects & EF_BRIGHTLIGHT) {
|
||||
radius += 200;
|
||||
dl->origin[2] += 16;
|
||||
org[2] += 16;
|
||||
}
|
||||
if (effects & EF_DIMLIGHT)
|
||||
if (effects & ~EF_DIMLIGHT)
|
||||
radius -= 100;
|
||||
dl->radius = radius;
|
||||
dl->die = time + 0.1;
|
||||
radius = radius;
|
||||
|
||||
switch (effects & (EF_RED | EF_BLUE)) {
|
||||
case EF_RED | EF_BLUE:
|
||||
QuatCopy (purple, dl->color);
|
||||
break;
|
||||
case EF_RED:
|
||||
QuatCopy (red, dl->color);
|
||||
break;
|
||||
case EF_BLUE:
|
||||
QuatCopy (blue, dl->color);
|
||||
break;
|
||||
default:
|
||||
QuatCopy (normal, dl->color);
|
||||
break;
|
||||
case EF_RED | EF_BLUE: color = purple; break;
|
||||
case EF_RED: color = red; break;
|
||||
case EF_BLUE: color = blue; break;
|
||||
default: color = normal; break;
|
||||
}
|
||||
}
|
||||
|
||||
if (glow_size) {
|
||||
dl->radius += glow_size < 128 ? glow_size * 8.0 :
|
||||
(glow_size - 256) * 8.0;
|
||||
dl->die = time + 0.1;
|
||||
radius += glow_size < 128 ? glow_size * 8.0 : (glow_size - 256) * 8.0;
|
||||
if (glow_color) {
|
||||
if (glow_color == 255) {
|
||||
dl->color[0] = dl->color[1] = dl->color[2] = 1.0;
|
||||
color = (vec4f_t) { 1, 1, 1, 0.7 };
|
||||
} else {
|
||||
byte *tempcolor;
|
||||
|
||||
tempcolor = (byte *) &d_8to24table[glow_color];
|
||||
VectorScale (tempcolor, 1 / 255.0, dl->color);
|
||||
VectorScale (tempcolor, 1 / 255.0, color);
|
||||
color[3] = 0.7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ent_SetComponent (ent.id, scene_dynlight, ent.reg, &(dlight_t) {
|
||||
.origin = org,
|
||||
.color = color,
|
||||
.radius = radius,
|
||||
.die = die,
|
||||
});
|
||||
Light_LinkLight (cl_world.scene->lights, ent.id);
|
||||
}
|
||||
|
||||
void
|
||||
CL_ModelEffects (entity_t ent, int num, int glow_color, double time)
|
||||
CL_ModelEffects (entity_t ent, int glow_color, double time)
|
||||
{
|
||||
dlight_t *dl;
|
||||
transform_t transform = Entity_Transform (ent);
|
||||
renderer_t *renderer = Ent_GetComponent (ent.id, scene_renderer, cl_world.scene->reg);
|
||||
model_t *model = renderer->model;
|
||||
|
@ -128,15 +123,14 @@ CL_ModelEffects (entity_t ent, int num, int glow_color, double time)
|
|||
|
||||
// add automatic particle trails
|
||||
if (model->flags & EF_ROCKET) {
|
||||
dl = R_AllocDlight (num);
|
||||
if (dl) {
|
||||
VectorCopy (ent_origin, dl->origin);
|
||||
dl->radius = 200.0;
|
||||
dl->die = time + 0.1;
|
||||
Ent_SetComponent (ent.id, scene_dynlight, ent.reg, &(dlight_t) {
|
||||
.origin = ent_origin,
|
||||
//FIXME VectorCopy (r_firecolor, dl->color);
|
||||
VectorSet (0.9, 0.7, 0.0, dl->color);
|
||||
dl->color[3] = 0.7;
|
||||
}
|
||||
.color = { 0.9, 0.7, 0.0, 0.7 },
|
||||
.radius = 200,
|
||||
.die = time + 0.1,
|
||||
});
|
||||
Light_LinkLight (cl_world.scene->lights, ent.id);
|
||||
clp_funcs->RocketTrail (*old_origin, ent_origin);
|
||||
} else if (model->flags & EF_GRENADE)
|
||||
clp_funcs->GrenadeTrail (*old_origin, ent_origin);
|
||||
|
@ -155,26 +149,21 @@ CL_ModelEffects (entity_t ent, int num, int glow_color, double time)
|
|||
}
|
||||
|
||||
void
|
||||
CL_MuzzleFlash (vec4f_t position, vec4f_t fv, float zoffset, int num,
|
||||
CL_MuzzleFlash (entity_t ent, vec4f_t position, vec4f_t fv, float zoffset,
|
||||
double time)
|
||||
{
|
||||
dlight_t *dl = R_AllocDlight (num);
|
||||
if (dl) {
|
||||
position += 18 * fv;
|
||||
VectorCopy (position, dl->origin);
|
||||
dl->origin[2] += zoffset;
|
||||
dl->radius = 200 + (rand () & 31);
|
||||
dl->die = time + 0.1;
|
||||
dl->minlight = 32;
|
||||
dl->color[0] = 0.2;
|
||||
dl->color[1] = 0.1;
|
||||
dl->color[2] = 0.05;
|
||||
dl->color[3] = 0.7;
|
||||
}
|
||||
Ent_SetComponent (ent.id, scene_dynlight, ent.reg, &(dlight_t) {
|
||||
.origin = position + 18 * fv + zoffset * (vec4f_t) {0, 0, 1, 0},
|
||||
.color = { 0.2, 0.1, 0.05, 0.7 },
|
||||
.radius = 200 + (rand () & 31),
|
||||
.die = time + 0.1,
|
||||
.minlight = 32,
|
||||
});
|
||||
Light_LinkLight (cl_world.scene->lights, ent.id);
|
||||
}
|
||||
|
||||
void
|
||||
CL_EntityEffects (int num, entity_t ent, entity_state_t *state, double time)
|
||||
CL_EntityEffects (entity_t ent, entity_state_t *state, double time)
|
||||
{
|
||||
transform_t transform = Entity_Transform (ent);
|
||||
vec4f_t position = Transform_GetWorldPosition (transform);
|
||||
|
@ -182,6 +171,6 @@ CL_EntityEffects (int num, entity_t ent, entity_state_t *state, double time)
|
|||
clp_funcs->EntityParticles (position);
|
||||
if (state->effects & EF_MUZZLEFLASH) {
|
||||
vec4f_t fv = Transform_Forward (transform);
|
||||
CL_MuzzleFlash (position, fv, 16, num, time);
|
||||
CL_MuzzleFlash (ent, position, fv, 16, time);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "QF/darray.h"
|
||||
#include "QF/msg.h"
|
||||
#include "QF/progs.h" // for PR_RESMAP
|
||||
#include "QF/quakefs.h"
|
||||
|
@ -47,6 +48,7 @@
|
|||
#include "QF/plugin/vid_render.h" //FIXME
|
||||
//
|
||||
#include "QF/scene/entity.h"
|
||||
#include "QF/scene/light.h"
|
||||
#include "QF/scene/scene.h"
|
||||
|
||||
#include "client/effects.h"
|
||||
|
@ -325,15 +327,55 @@ CL_ParseBeam (qmsg_t *net_message, model_t *m, double time, TEntContext_t *ctx)
|
|||
}
|
||||
}
|
||||
|
||||
typedef struct tempent_s DARRAY_TYPE (entity_t) tempent_t;
|
||||
static tempent_t light_entities = DARRAY_STATIC_INIT (32);
|
||||
|
||||
static void
|
||||
free_stale_entities (void)
|
||||
{
|
||||
size_t i, j;
|
||||
for (i = 0, j = 0; i < light_entities.size; i++) {
|
||||
auto ent = light_entities.a[i];
|
||||
if (Ent_HasComponent (ent.id, scene_dynlight, ent.reg)) {
|
||||
if (j != i) {
|
||||
light_entities.a[j] = ent;
|
||||
}
|
||||
j++;
|
||||
} else {
|
||||
ECS_DelEntity (ent.reg, ent.id);
|
||||
}
|
||||
}
|
||||
light_entities.size = j;
|
||||
}
|
||||
|
||||
static void
|
||||
spawn_light (vec4f_t position, vec4f_t color, float radius, float die,
|
||||
float decay)
|
||||
{
|
||||
entity_t ent = {
|
||||
.reg = cl_world.scene->reg,
|
||||
.id = ECS_NewEntity (cl_world.scene->reg),
|
||||
};
|
||||
DARRAY_APPEND (&light_entities, ent);
|
||||
|
||||
Ent_SetComponent (ent.id, scene_dynlight, ent.reg, &(dlight_t) {
|
||||
.origin = position,
|
||||
.color = color,
|
||||
.radius = radius,
|
||||
.die = die,
|
||||
.decay = decay,
|
||||
});
|
||||
Light_LinkLight (cl_world.scene->lights, ent.id);
|
||||
}
|
||||
|
||||
static void
|
||||
parse_tent (qmsg_t *net_message, double time, TEntContext_t *ctx,
|
||||
TE_Effect type)
|
||||
{
|
||||
dlight_t *dl;
|
||||
tent_obj_t *to;
|
||||
explosion_t *ex;
|
||||
int colorStart, colorLength;
|
||||
quat_t color;
|
||||
vec4f_t color;
|
||||
vec4f_t position = {0, 0, 0, 1};
|
||||
int count;
|
||||
const char *name;
|
||||
|
@ -369,23 +411,16 @@ parse_tent (qmsg_t *net_message, double time, TEntContext_t *ctx,
|
|||
renderer_t *renderer = Ent_GetComponent (ex->tent->ent.id, scene_renderer, cl_world.scene->reg);
|
||||
renderer->model = cl_spr_explod;
|
||||
Transform_SetLocalPosition (transform, position);
|
||||
color = (vec4f_t) {0.86, 0.31, 0.24, 0.7};
|
||||
goto TE_Explosion_no_sprite;
|
||||
case TE_Explosion:
|
||||
MSG_ReadCoordV (net_message, (vec_t*)&position);//FIXME
|
||||
color = (vec4f_t) {1.0, 0.5, 0.25, 0.7};
|
||||
TE_Explosion_no_sprite:
|
||||
// particles
|
||||
clp_funcs->ParticleExplosion (position);
|
||||
|
||||
// light
|
||||
dl = R_AllocDlight (0);
|
||||
if (dl) {
|
||||
VectorCopy (position, dl->origin);
|
||||
dl->radius = 350;
|
||||
dl->die = time + 0.5;
|
||||
dl->decay = 300;
|
||||
QuatSet (0.86, 0.31, 0.24, 0.7, dl->color);
|
||||
//FIXME? nq: QuatSet (1.0, 0.5, 0.25, 0.7, dl->color);
|
||||
}
|
||||
spawn_light (position, color, 250, time + 0.5, 300);
|
||||
|
||||
// sound
|
||||
S_StartSound (-1, 0, cl_sfx_r_exp3, position, 1, 1);
|
||||
|
@ -396,32 +431,20 @@ TE_Explosion_no_sprite:
|
|||
colorLength = MSG_ReadByte (net_message);
|
||||
S_StartSound (-1, 0, cl_sfx_r_exp3, position, 1, 1);
|
||||
clp_funcs->ParticleExplosion2 (position, colorStart, colorLength);
|
||||
dl = R_AllocDlight (0);
|
||||
if (!dl)
|
||||
break;
|
||||
VectorCopy (position, dl->origin);
|
||||
dl->radius = 350;
|
||||
dl->die = time + 0.5;
|
||||
dl->decay = 300;
|
||||
|
||||
colorStart = (colorStart + (rand () % colorLength)) * 3;
|
||||
VectorScale (&r_data->vid->palette[colorStart], 1.0 / 255.0,
|
||||
dl->color);
|
||||
dl->color[3] = 0.7;
|
||||
VectorScale (&r_data->vid->palette[colorStart], 1.0 / 255.0, color);
|
||||
color[3] = 0.7;
|
||||
spawn_light (position, color, 350, time + 0.5, 300);
|
||||
break;
|
||||
case TE_Explosion3:
|
||||
MSG_ReadCoordV (net_message, (vec_t*)&position);//FIXME
|
||||
MSG_ReadCoordV (net_message, color); // OUCH!
|
||||
MSG_ReadCoordV (net_message, (vec_t*)&color); //FIXME OUCH!
|
||||
color[3] = 0.7;
|
||||
clp_funcs->ParticleExplosion (position);
|
||||
S_StartSound (-1, 0, cl_sfx_r_exp3, position, 1, 1);
|
||||
dl = R_AllocDlight (0);
|
||||
if (dl) {
|
||||
VectorCopy (position, dl->origin);
|
||||
dl->radius = 350;
|
||||
dl->die = time + 0.5;
|
||||
dl->decay = 300;
|
||||
QuatCopy (color, dl->color);
|
||||
}
|
||||
|
||||
spawn_light (position, color, 350, time + 0.5, 300);
|
||||
break;
|
||||
case TE_Gunshot1:
|
||||
MSG_ReadCoordV (net_message, (vec_t*)&position);//FIXME
|
||||
|
@ -457,15 +480,8 @@ TE_Explosion_no_sprite:
|
|||
case TE_LightningBlood:
|
||||
MSG_ReadCoordV (net_message, (vec_t*)&position);//FIXME
|
||||
|
||||
// light
|
||||
dl = R_AllocDlight (0);
|
||||
if (dl) {
|
||||
VectorCopy (position, dl->origin);
|
||||
dl->radius = 150;
|
||||
dl->die = time + 0.1;
|
||||
dl->decay = 200;
|
||||
QuatSet (0.25, 0.40, 0.65, 1, dl->color);
|
||||
}
|
||||
color = (vec4f_t) {0.25, 0.40, 0.65, 1};
|
||||
spawn_light (position, color, 150, time + 0.1, 200);
|
||||
|
||||
clp_funcs->LightningBloodEffect (position);
|
||||
break;
|
||||
|
@ -650,6 +666,7 @@ CL_UpdateExplosions (double time, TEntContext_t *ctx)
|
|||
void
|
||||
CL_UpdateTEnts (double time, TEntContext_t *ctx)
|
||||
{
|
||||
free_stale_entities ();
|
||||
CL_UpdateBeams (time, ctx);
|
||||
CL_UpdateExplosions (time, ctx);
|
||||
}
|
||||
|
|
|
@ -290,7 +290,6 @@ void
|
|||
locs_draw (double time, vec4f_t simorg)
|
||||
{
|
||||
//FIXME custom ent rendering code would be nice
|
||||
dlight_t *dl;
|
||||
location_t *nearloc;
|
||||
vec4f_t trueloc;
|
||||
vec4f_t zero = {};
|
||||
|
@ -298,16 +297,15 @@ locs_draw (double time, vec4f_t simorg)
|
|||
|
||||
nearloc = locs_find (simorg);
|
||||
if (nearloc) {
|
||||
dl = R_AllocDlight (4096);
|
||||
if (dl) {
|
||||
VectorCopy (nearloc->loc, dl->origin);
|
||||
dl->radius = 200;
|
||||
dl->die = time + 0.1;
|
||||
dl->color[0] = 0;
|
||||
dl->color[1] = 1;
|
||||
dl->color[2] = 0;
|
||||
dl->color[3] = 0.7;
|
||||
}
|
||||
#if 0//FIXME
|
||||
Ent_SetComponent (ent.id, scene_dynlight, ent.reg, &(dlight_t) {
|
||||
.origin = nearloc->loc,
|
||||
.color = { 0, 1, 0, 0.7 },
|
||||
.radius = 200,
|
||||
.die = time + 0.1,
|
||||
});
|
||||
Light_LinkLight (cl_world.scene->lights, ent.id);
|
||||
#endif
|
||||
trueloc = nearloc->loc;
|
||||
clp_funcs->Particle_New (pt_smokecloud, part_tex_smoke, trueloc, 2.0,
|
||||
zero, time + 9.0, 254,
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "QF/model.h"
|
||||
#include "QF/render.h"
|
||||
#include "QF/set.h"
|
||||
#include "QF/scene/entity.h"
|
||||
#include "QF/scene/light.h"
|
||||
|
@ -84,20 +85,12 @@ test_light_leaf (const light_t *light, const mleaf_t *leaf)
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Light_AddLight (lightingdata_t *ldata, const light_t *light, uint32_t style)
|
||||
static void
|
||||
link_light (lightingdata_t *ldata, const light_t *light, entity_t ent)
|
||||
{
|
||||
scene_t *scene = ldata->scene;
|
||||
model_t *model = scene->worldmodel;
|
||||
|
||||
entity_t ent = {
|
||||
.reg = scene->reg,
|
||||
.id = ECS_NewEntity (scene->reg),
|
||||
};
|
||||
|
||||
Ent_SetComponent (ent.id, scene_light, ent.reg, light);
|
||||
Ent_SetComponent (ent.id, scene_lightstyle, ent.reg, &style);
|
||||
|
||||
set_t _pvs = SET_STATIC_INIT (model->brush.visleafs, alloca);
|
||||
set_t *pvs = &_pvs;
|
||||
uint32_t leafnum = ~0u;
|
||||
|
@ -124,9 +117,51 @@ Light_AddLight (lightingdata_t *ldata, const light_t *light, uint32_t style)
|
|||
lastlink = R_LinkEfrag (leaf, ent, mod_light, lastlink);
|
||||
}
|
||||
}
|
||||
if (Ent_HasComponent (ent.id, scene_efrags, ent.reg)) {
|
||||
Ent_RemoveComponent (ent.id, scene_efrags, ent.reg);
|
||||
}
|
||||
Ent_SetComponent (ent.id, scene_efrags, ent.reg, &efrags);
|
||||
}
|
||||
|
||||
void
|
||||
Light_AddLight (lightingdata_t *ldata, const light_t *light, uint32_t style)
|
||||
{
|
||||
scene_t *scene = ldata->scene;
|
||||
|
||||
entity_t ent = {
|
||||
.reg = scene->reg,
|
||||
.id = ECS_NewEntity (scene->reg),
|
||||
};
|
||||
|
||||
Ent_SetComponent (ent.id, scene_light, ent.reg, light);
|
||||
Ent_SetComponent (ent.id, scene_lightstyle, ent.reg, &style);
|
||||
|
||||
link_light (ldata, light, ent);
|
||||
}
|
||||
|
||||
void
|
||||
Light_LinkLight (lightingdata_t *ldata, uint32_t entid)
|
||||
{
|
||||
scene_t *scene = ldata->scene;
|
||||
|
||||
entity_t ent = {
|
||||
.reg = scene->reg,
|
||||
.id = entid,
|
||||
};
|
||||
dlight_t *dlight = Ent_GetComponent (ent.id, scene_dynlight, ent.reg);
|
||||
if (!dlight) {
|
||||
Sys_Error ("no dlight on entity to link");
|
||||
}
|
||||
light_t light = {
|
||||
.color = dlight->color,
|
||||
.position = dlight->origin,
|
||||
.direction = {0, 0, 1, 1},
|
||||
.attenuation = {0, 0, 1, 1/dlight->radius},
|
||||
};
|
||||
|
||||
link_light (ldata, &light, ent);
|
||||
}
|
||||
|
||||
void
|
||||
Light_EnableSun (lightingdata_t *ldata)
|
||||
{
|
||||
|
@ -150,3 +185,25 @@ Light_EnableSun (lightingdata_t *ldata)
|
|||
// can receive shadows from the sun
|
||||
expand_pvs (ldata->sun_pvs, brush);
|
||||
}
|
||||
|
||||
void
|
||||
Light_DecayLights (lightingdata_t *ldata, float frametime, double realtime)
|
||||
{
|
||||
auto reg = ldata->scene->reg;
|
||||
auto dlight_pool = ®->comp_pools[scene_dynlight];
|
||||
auto dlight_data = (dlight_t *) dlight_pool->data;
|
||||
|
||||
for (uint32_t i = 0; i < dlight_pool->count; i++) {
|
||||
auto dlight = &dlight_data[i];
|
||||
dlight->radius -= frametime * dlight->decay;
|
||||
if (dlight->radius <= 0 || dlight->die < realtime) {
|
||||
uint32_t ent = dlight_pool->dense[i];
|
||||
Ent_RemoveComponent (ent, scene_dynlight, reg);
|
||||
if (!Ent_HasComponent (ent, scene_efrags, reg)) {
|
||||
Sys_Error ("dlight with no efrags");
|
||||
}
|
||||
Ent_RemoveComponent (ent, scene_efrags, reg);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -153,6 +153,11 @@ static const component_t scene_components[scene_comp_count] = {
|
|||
.name = "colormap",
|
||||
},
|
||||
|
||||
[scene_dynlight] = {
|
||||
.size = sizeof (dlight_t),
|
||||
.name = "dyn_light",
|
||||
},
|
||||
|
||||
[scene_light] = {
|
||||
.size = sizeof (light_t),
|
||||
.name = "light",
|
||||
|
|
|
@ -84,7 +84,7 @@ R_RenderDlight (dlight_t *light)
|
|||
|
||||
qfglBegin (GL_TRIANGLE_FAN);
|
||||
|
||||
qfglColor4fv (light->color);
|
||||
qfglColor4fv ((vec_t*)&light->color);
|
||||
|
||||
VectorNormalize (v);
|
||||
|
||||
|
@ -109,9 +109,6 @@ R_RenderDlight (dlight_t *light)
|
|||
void
|
||||
gl_R_RenderDlights (void)
|
||||
{
|
||||
unsigned int i;
|
||||
dlight_t *l;
|
||||
|
||||
if (!gl_dlight_polyblend)
|
||||
return;
|
||||
|
||||
|
@ -120,11 +117,11 @@ gl_R_RenderDlights (void)
|
|||
qfglBlendFunc (GL_ONE, GL_ONE);
|
||||
qfglShadeModel (GL_SMOOTH);
|
||||
|
||||
l = r_dlights;
|
||||
for (i = 0; i < r_maxdlights; i++, l++) {
|
||||
if (l->die < vr_data.realtime || !l->radius)
|
||||
continue;
|
||||
R_RenderDlight (l);
|
||||
auto dlight_pool = &r_refdef.registry->comp_pools[scene_dynlight];
|
||||
auto dlight_data = (dlight_t *) dlight_pool->data;
|
||||
for (uint32_t i = 0; i < dlight_pool->count; i++) {
|
||||
auto dlight = &dlight_data[i];
|
||||
R_RenderDlight (dlight);
|
||||
}
|
||||
|
||||
if (!gl_dlight_smooth)
|
||||
|
|
|
@ -98,7 +98,7 @@ R_AddDynamicLights_1 (const vec4f_t *transform, msurface_t *surf)
|
|||
unsigned int maxdist, maxdist2, maxdist3;
|
||||
int smax, smax_bytes, tmax,
|
||||
grey, s, t;
|
||||
unsigned int lnum, td, i, j;
|
||||
unsigned int td, j;
|
||||
unsigned int sdtable[18];
|
||||
unsigned int *bl;
|
||||
vec3_t impact, local;
|
||||
|
@ -113,16 +113,18 @@ R_AddDynamicLights_1 (const vec4f_t *transform, msurface_t *surf)
|
|||
entorigin = transform[3];
|
||||
}
|
||||
|
||||
for (lnum = 0; lnum < r_maxdlights; lnum++) {
|
||||
if (!(surf->dlightbits[lnum / 32] & (1 << (lnum % 32))))
|
||||
auto dlight_pool = &r_refdef.registry->comp_pools[scene_dynlight];
|
||||
auto dlight_data = (dlight_t *) dlight_pool->data;
|
||||
for (uint32_t i = 0; i < dlight_pool->count; i++) {
|
||||
auto dlight = &dlight_data[i];
|
||||
if (!(surf->dlightbits[i / 32] & (1 << (i % 32))))
|
||||
continue; // not lit by this light
|
||||
|
||||
VectorSubtract (r_dlights[lnum].origin, entorigin, local);
|
||||
VectorSubtract (dlight->origin, entorigin, local);
|
||||
dist = DotProduct (local, surf->plane->normal) - surf->plane->dist;
|
||||
if (dist > min (1024, r_dlights[lnum].radius))
|
||||
if (dist > min (1024, dlight->radius))
|
||||
continue;
|
||||
VectorMultSub (r_dlights[lnum].origin, dist, surf->plane->normal,
|
||||
impact);
|
||||
VectorMultSub (dlight->origin, dist, surf->plane->normal, impact);
|
||||
|
||||
i = DotProduct (impact, surf->texinfo->vecs[0]) +
|
||||
surf->texinfo->vecs[0][3] - surf->texturemins[0];
|
||||
|
@ -136,7 +138,7 @@ R_AddDynamicLights_1 (const vec4f_t *transform, msurface_t *surf)
|
|||
surf->texinfo->vecs[1][3] - surf->texturemins[1];
|
||||
|
||||
// for comparisons to minimum acceptable light
|
||||
maxdist = (int) (r_dlights[lnum].radius * r_dlights[lnum].radius);
|
||||
maxdist = (int) (dlight->radius * dlight->radius);
|
||||
|
||||
// clamp radius to avoid exceeding 8192 entry division table
|
||||
if (maxdist > 1048576)
|
||||
|
@ -144,8 +146,8 @@ R_AddDynamicLights_1 (const vec4f_t *transform, msurface_t *surf)
|
|||
maxdist3 = maxdist - t;
|
||||
|
||||
// convert to 8.8 blocklights format
|
||||
grey = (r_dlights[lnum].color[0] + r_dlights[lnum].color[1] +
|
||||
r_dlights[lnum].color[2]) * maxdist / 3.0;
|
||||
grey = (dlight->color[0] + dlight->color[1] + dlight->color[2])
|
||||
* maxdist / 3.0;
|
||||
bl = blocklights;
|
||||
for (t = 0; t < tmax; t++, i -= 16) {
|
||||
td = i * i;
|
||||
|
@ -171,7 +173,7 @@ R_AddDynamicLights_3 (const vec4f_t *transform, msurface_t *surf)
|
|||
unsigned int maxdist, maxdist2, maxdist3;
|
||||
int smax, smax_bytes, tmax,
|
||||
red, green, blue, s, t;
|
||||
unsigned int lnum, td, i, j;
|
||||
unsigned int td, j;
|
||||
unsigned int sdtable[18];
|
||||
unsigned int *bl;
|
||||
vec3_t impact, local;
|
||||
|
@ -185,18 +187,21 @@ R_AddDynamicLights_3 (const vec4f_t *transform, msurface_t *surf)
|
|||
entorigin = transform[3];
|
||||
}
|
||||
|
||||
for (lnum = 0; lnum < r_maxdlights; lnum++) {
|
||||
if (!(surf->dlightbits[lnum / 32] & (1 << (lnum % 32))))
|
||||
auto dlight_pool = &r_refdef.registry->comp_pools[scene_dynlight];
|
||||
auto dlight_data = (dlight_t *) dlight_pool->data;
|
||||
for (uint32_t k = 0; k < dlight_pool->count; k++) {
|
||||
auto dlight = &dlight_data[k];
|
||||
if (!(surf->dlightbits[k / 32] & (1 << (k % 32))))
|
||||
continue; // not lit by this light
|
||||
|
||||
VectorSubtract (r_dlights[lnum].origin, entorigin, local);
|
||||
VectorSubtract (dlight->origin, entorigin, local);
|
||||
dist = DotProduct (local, surf->plane->normal) - surf->plane->dist;
|
||||
if (dist > min (1024, r_dlights[lnum].radius))
|
||||
if (dist > min (1024, dlight->radius))
|
||||
continue;
|
||||
VectorMultSub (r_dlights[lnum].origin, dist, surf->plane->normal,
|
||||
impact);
|
||||
VectorMultSub (dlight->origin, dist, surf->plane->normal, impact);
|
||||
|
||||
i = DotProduct (impact, surf->texinfo->vecs[0]) +
|
||||
int i;
|
||||
i = DotProduct (impact, surf->texinfo->vecs[0]) +
|
||||
surf->texinfo->vecs[0][3] - surf->texturemins[0];
|
||||
|
||||
// reduce calculations
|
||||
|
@ -204,11 +209,11 @@ R_AddDynamicLights_3 (const vec4f_t *transform, msurface_t *surf)
|
|||
for (s = 0; s < smax; s++, i -= 16)
|
||||
sdtable[s] = i * i + t;
|
||||
|
||||
i = DotProduct (impact, surf->texinfo->vecs[1]) +
|
||||
i = DotProduct (impact, surf->texinfo->vecs[1]) +
|
||||
surf->texinfo->vecs[1][3] - surf->texturemins[1];
|
||||
|
||||
// for comparisons to minimum acceptable light
|
||||
maxdist = (int) (r_dlights[lnum].radius * r_dlights[lnum].radius);
|
||||
maxdist = (int) (dlight->radius * dlight->radius);
|
||||
|
||||
// clamp radius to avoid exceeding 8192 entry division table
|
||||
if (maxdist > 1048576)
|
||||
|
@ -216,9 +221,9 @@ R_AddDynamicLights_3 (const vec4f_t *transform, msurface_t *surf)
|
|||
maxdist3 = maxdist - t;
|
||||
|
||||
// convert to 8.8 blocklights format
|
||||
red = r_dlights[lnum].color[0] * maxdist;
|
||||
green = r_dlights[lnum].color[1] * maxdist;
|
||||
blue = r_dlights[lnum].color[2] * maxdist;
|
||||
red = dlight->color[0] * maxdist;
|
||||
green = dlight->color[1] * maxdist;
|
||||
blue = dlight->color[2] * maxdist;
|
||||
bl = blocklights;
|
||||
for (t = 0; t < tmax; t++, i -= 16) {
|
||||
td = i * i;
|
||||
|
|
|
@ -408,9 +408,7 @@ gl_R_DrawAliasModel (entity_t e)
|
|||
int gl_light, texture;
|
||||
int fb_texture = 0, used_lights = 0;
|
||||
bool is_fullbright = false;
|
||||
unsigned lnum;
|
||||
aliashdr_t *paliashdr;
|
||||
dlight_t *l;
|
||||
vec3_t dist, scale;
|
||||
vec4f_t origin;
|
||||
vert_order_t *vo;
|
||||
|
@ -459,44 +457,45 @@ gl_R_DrawAliasModel (entity_t e)
|
|||
}
|
||||
|
||||
if (gl_vector_light) {
|
||||
for (l = r_dlights, lnum = 0; lnum < r_maxdlights; lnum++, l++) {
|
||||
if (l->die >= vr_data.realtime) {
|
||||
VectorSubtract (l->origin, origin, dist);
|
||||
if ((d = DotProduct (dist, dist)) > // Out of range
|
||||
((l->radius + radius) * (l->radius + radius))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (used_lights >= gl_max_lights) {
|
||||
// For solid lighting, multiply by 0.5 since it's cos
|
||||
// 60 and 60 is a good guesstimate at the average
|
||||
// incident angle. Seems to match vector lighting
|
||||
// best, too.
|
||||
VectorMultAdd (emission,
|
||||
0.5 / ((d * 0.01 / l->radius) + 0.5),
|
||||
l->color, emission);
|
||||
continue;
|
||||
}
|
||||
|
||||
VectorCopy (l->origin, position);
|
||||
|
||||
VectorCopy (l->color, color);
|
||||
color[3] = 1.0;
|
||||
|
||||
gl_light = GL_LIGHT0 + used_lights;
|
||||
qfglEnable (gl_light);
|
||||
qfglLightfv (gl_light, GL_POSITION, position);
|
||||
qfglLightfv (gl_light, GL_AMBIENT, color);
|
||||
qfglLightfv (gl_light, GL_DIFFUSE, color);
|
||||
qfglLightfv (gl_light, GL_SPECULAR, color);
|
||||
// 0.01 is used here because it just seemed to match
|
||||
// the bmodel lighting best. it's over r instead of r*r
|
||||
// so that larger-radiused lights will be brighter
|
||||
qfglLightf (gl_light, GL_QUADRATIC_ATTENUATION,
|
||||
0.01 / (l->radius));
|
||||
used_lights++;
|
||||
auto dlight_pool = &r_refdef.registry->comp_pools[scene_dynlight];
|
||||
auto dlight_data = (dlight_t *) dlight_pool->data;
|
||||
for (uint32_t i = 0; i < dlight_pool->count; i++) {
|
||||
auto l = &dlight_data[i];
|
||||
VectorSubtract (l->origin, origin, dist);
|
||||
if ((d = DotProduct (dist, dist)) > // Out of range
|
||||
((l->radius + radius) * (l->radius + radius))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (used_lights >= gl_max_lights) {
|
||||
// For solid lighting, multiply by 0.5 since it's cos
|
||||
// 60 and 60 is a good guesstimate at the average
|
||||
// incident angle. Seems to match vector lighting
|
||||
// best, too.
|
||||
VectorMultAdd (emission,
|
||||
0.5 / ((d * 0.01 / l->radius) + 0.5),
|
||||
l->color, emission);
|
||||
continue;
|
||||
}
|
||||
|
||||
VectorCopy (l->origin, position);
|
||||
|
||||
VectorCopy (l->color, color);
|
||||
color[3] = 1.0;
|
||||
|
||||
gl_light = GL_LIGHT0 + used_lights;
|
||||
qfglEnable (gl_light);
|
||||
qfglLightfv (gl_light, GL_POSITION, position);
|
||||
qfglLightfv (gl_light, GL_AMBIENT, color);
|
||||
qfglLightfv (gl_light, GL_DIFFUSE, color);
|
||||
qfglLightfv (gl_light, GL_SPECULAR, color);
|
||||
// 0.01 is used here because it just seemed to match
|
||||
// the bmodel lighting best. it's over r instead of r*r
|
||||
// so that larger-radiused lights will be brighter
|
||||
qfglLightf (gl_light, GL_QUADRATIC_ATTENUATION,
|
||||
0.01 / (l->radius));
|
||||
used_lights++;
|
||||
}
|
||||
|
||||
VectorAdd (ambientcolor, emission, emission);
|
||||
|
@ -510,22 +509,23 @@ gl_R_DrawAliasModel (entity_t e)
|
|||
} else {
|
||||
VectorCopy (ambientcolor, emission);
|
||||
|
||||
for (l = r_dlights, lnum = 0; lnum < r_maxdlights; lnum++, l++) {
|
||||
if (l->die >= vr_data.realtime) {
|
||||
VectorSubtract (l->origin, origin, dist);
|
||||
auto dlight_pool = &r_refdef.registry->comp_pools[scene_dynlight];
|
||||
auto dlight_data = (dlight_t *) dlight_pool->data;
|
||||
for (uint32_t i = 0; i < dlight_pool->count; i++) {
|
||||
auto l = &dlight_data[i];
|
||||
VectorSubtract (l->origin, origin, dist);
|
||||
|
||||
if ((d = DotProduct (dist, dist)) > (l->radius + radius) *
|
||||
(l->radius + radius)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// For solid lighting, multiply by 0.5 since it's cos 60
|
||||
// and 60 is a good guesstimate at the average incident
|
||||
// angle. Seems to match vector lighting best, too.
|
||||
VectorMultAdd (emission,
|
||||
(0.5 / ((d * 0.01 / l->radius) + 0.5)),
|
||||
l->color, emission);
|
||||
if ((d = DotProduct (dist, dist)) > (l->radius + radius) *
|
||||
(l->radius + radius)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// For solid lighting, multiply by 0.5 since it's cos 60
|
||||
// and 60 is a good guesstimate at the average incident
|
||||
// angle. Seems to match vector lighting best, too.
|
||||
VectorMultAdd (emission,
|
||||
(0.5 / ((d * 0.01 / l->radius) + 0.5)),
|
||||
l->color, emission);
|
||||
}
|
||||
|
||||
d = max (emission[0], max (emission[1], emission[2]));
|
||||
|
|
|
@ -280,6 +280,5 @@ void
|
|||
gl_R_ClearState (void)
|
||||
{
|
||||
r_refdef.worldmodel = 0;
|
||||
R_ClearDlights ();
|
||||
R_ClearParticles ();
|
||||
}
|
||||
|
|
|
@ -550,15 +550,14 @@ gl_R_DrawBrushModel (entity_t e)
|
|||
|
||||
// calculate dynamic lighting for bmodel if it's not an instanced model
|
||||
if (brush->firstmodelsurface != 0 && r_dlight_lightmap) {
|
||||
for (unsigned k = 0; k < r_maxdlights; k++) {
|
||||
if ((r_dlights[k].die < vr_data.realtime)
|
||||
|| (!r_dlights[k].radius))
|
||||
continue;
|
||||
|
||||
auto dlight_pool = &r_refdef.registry->comp_pools[scene_dynlight];
|
||||
auto dlight_data = (dlight_t *) dlight_pool->data;
|
||||
for (uint32_t i = 0; i < dlight_pool->count; i++) {
|
||||
auto dlight = &dlight_data[i];
|
||||
vec4f_t lightorigin;
|
||||
VectorSubtract (r_dlights[k].origin, worldMatrix[3], lightorigin);
|
||||
VectorSubtract (dlight->origin, worldMatrix[3], lightorigin);
|
||||
lightorigin[3] = 1;
|
||||
R_RecursiveMarkLights (brush, lightorigin, &r_dlights[k], k,
|
||||
R_RecursiveMarkLights (brush, lightorigin, dlight, i,
|
||||
brush->hulls[0].firstclipnode);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,7 +152,6 @@ static void
|
|||
calc_lighting (entity_t ent, float *ambient, float *shadelight,
|
||||
vec3_t lightvec)
|
||||
{
|
||||
unsigned i;
|
||||
float add;
|
||||
vec3_t dist;
|
||||
int light;
|
||||
|
@ -167,13 +166,14 @@ calc_lighting (entity_t ent, float *ambient, float *shadelight,
|
|||
renderer->min_light) * 128);
|
||||
*shadelight = *ambient;
|
||||
|
||||
for (i = 0; i < r_maxdlights; i++) {
|
||||
if (r_dlights[i].die >= vr_data.realtime) {
|
||||
VectorSubtract (entorigin, r_dlights[i].origin, dist);
|
||||
add = r_dlights[i].radius - VectorLength (dist);
|
||||
if (add > 0)
|
||||
*ambient += add;
|
||||
}
|
||||
auto dlight_pool = &r_refdef.registry->comp_pools[scene_dynlight];
|
||||
auto dlight_data = (dlight_t *) dlight_pool->data;
|
||||
for (uint32_t i = 0; i < dlight_pool->count; i++) {
|
||||
auto dlight = &dlight_data[i];
|
||||
VectorSubtract (entorigin, dlight->origin, dist);
|
||||
add = dlight->radius - VectorLength (dist);
|
||||
if (add > 0)
|
||||
*ambient += add;
|
||||
}
|
||||
if (*ambient >= 128)
|
||||
*ambient = 128;
|
||||
|
|
|
@ -651,7 +651,6 @@ static void
|
|||
R_DrawBrushModel (entity_t e)
|
||||
{
|
||||
float dot, radius;
|
||||
unsigned k;
|
||||
renderer_t *renderer = Ent_GetComponent (e.id, scene_renderer, e.reg);
|
||||
model_t *model = renderer->model;
|
||||
mod_brush_t *brush = &model->brush;
|
||||
|
@ -695,16 +694,15 @@ R_DrawBrushModel (entity_t e)
|
|||
}
|
||||
|
||||
// calculate dynamic lighting for bmodel if it's not an instanced model
|
||||
auto dlight_pool = &r_refdef.registry->comp_pools[scene_dynlight];
|
||||
auto dlight_data = (dlight_t *) dlight_pool->data;
|
||||
if (brush->firstmodelsurface != 0 && r_dlight_lightmap) {
|
||||
for (k = 0; k < r_maxdlights; k++) {
|
||||
if ((r_dlights[k].die < vr_data.realtime)
|
||||
|| (!r_dlights[k].radius))
|
||||
continue;
|
||||
|
||||
for (uint32_t i = 0; i < dlight_pool->count; i++) {
|
||||
auto dlight = &dlight_data[i];
|
||||
vec4f_t lightorigin;
|
||||
VectorSubtract (r_dlights[k].origin, mat[3], lightorigin);
|
||||
VectorSubtract (dlight->origin, mat[3], lightorigin);
|
||||
lightorigin[3] = 1;
|
||||
R_RecursiveMarkLights (brush, lightorigin, &r_dlights[k], k,
|
||||
R_RecursiveMarkLights (brush, lightorigin, dlight, i,
|
||||
brush->hulls[0].firstclipnode);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -246,7 +246,7 @@ glsl_R_DrawIQM (entity_t ent)
|
|||
VectorSubtract (lights[i]->origin, entorigin, val);
|
||||
val[3] = lights[i]->radius;
|
||||
qfeglUniform4fv (l->position.location, 1, val);
|
||||
qfeglUniform4fv (l->color.location, 1, lights[i]->color);
|
||||
qfeglUniform4fv (l->color.location, 1, (vec_t*)&lights[i]->color);
|
||||
}
|
||||
for (; i < MAX_IQM_LIGHTS; i++) {
|
||||
lightpar_t *l = &iqm_shader.lights[i];
|
||||
|
|
|
@ -66,7 +66,6 @@ void (*glsl_R_BuildLightMap) (const vec4f_t *transform, mod_brush_t *brush,
|
|||
static void
|
||||
R_AddDynamicLights_1 (const vec4f_t *transform, msurface_t *surf)
|
||||
{
|
||||
unsigned lnum;
|
||||
int sd, td;
|
||||
float dist, rad, minlight;
|
||||
vec3_t impact, local, lightorigin;
|
||||
|
@ -84,16 +83,19 @@ R_AddDynamicLights_1 (const vec4f_t *transform, msurface_t *surf)
|
|||
entorigin = transform[3];
|
||||
}
|
||||
|
||||
for (lnum = 0; lnum < r_maxdlights; lnum++) {
|
||||
if (!(surf->dlightbits[lnum / 32] & (1 << (lnum % 32))))
|
||||
auto dlight_pool = &r_refdef.registry->comp_pools[scene_dynlight];
|
||||
auto dlight_data = (dlight_t *) dlight_pool->data;
|
||||
for (uint32_t i = 0; i < dlight_pool->count; i++) {
|
||||
auto dlight = &dlight_data[i];
|
||||
if (!(surf->dlightbits[i / 32] & (1 << (i % 32))))
|
||||
continue; // not lit by this light
|
||||
|
||||
VectorSubtract (r_dlights[lnum].origin, entorigin, lightorigin);
|
||||
rad = r_dlights[lnum].radius;
|
||||
VectorSubtract (dlight->origin, entorigin, lightorigin);
|
||||
rad = dlight->radius;
|
||||
dist = DotProduct (lightorigin, surf->plane->normal)
|
||||
- surf->plane->dist;
|
||||
rad -= fabs (dist);
|
||||
minlight = r_dlights[lnum].minlight;
|
||||
minlight = dlight->minlight;
|
||||
if (rad < minlight)
|
||||
continue;
|
||||
minlight = rad - minlight;
|
||||
|
|
|
@ -223,6 +223,5 @@ void
|
|||
glsl_R_ClearState (void)
|
||||
{
|
||||
r_refdef.worldmodel = 0;
|
||||
R_ClearDlights ();
|
||||
R_ClearParticles ();
|
||||
}
|
||||
|
|
|
@ -153,15 +153,6 @@ static cvar_t r_dlight_lightmap_cvar = {
|
|||
.flags = CVAR_ARCHIVE,
|
||||
.value = { .type = &cexpr_int, .value = &r_dlight_lightmap },
|
||||
};
|
||||
int r_dlight_max;
|
||||
static cvar_t r_dlight_max_cvar = {
|
||||
.name = "r_dlight_max",
|
||||
.description =
|
||||
"Number of dynamic lights.",
|
||||
.default_value = "32",
|
||||
.flags = CVAR_ARCHIVE,
|
||||
.value = { .type = &cexpr_int, .value = &r_dlight_max },
|
||||
};
|
||||
int r_drawentities;
|
||||
static cvar_t r_drawentities_cvar = {
|
||||
.name = "r_drawentities",
|
||||
|
@ -568,12 +559,6 @@ viewsize_f (void *data, const cvar_t *cvar)
|
|||
r_data->viewsize_callback (scr_viewsize);
|
||||
}
|
||||
|
||||
static void
|
||||
r_dlight_max_f (void *data, const cvar_t *cvar)
|
||||
{
|
||||
R_MaxDlightsCheck (r_dlight_max);
|
||||
}
|
||||
|
||||
void
|
||||
R_Init_Cvars (void)
|
||||
{
|
||||
|
@ -590,7 +575,6 @@ R_Init_Cvars (void)
|
|||
Cvar_Register (&r_aliastransbase_cvar, 0, 0);
|
||||
Cvar_Register (&r_clearcolor_cvar, 0, 0);
|
||||
Cvar_Register (&r_dlight_lightmap_cvar, 0, 0);
|
||||
Cvar_Register (&r_dlight_max_cvar, r_dlight_max_f, 0);
|
||||
Cvar_Register (&r_drawentities_cvar, 0, 0);
|
||||
Cvar_Register (&r_drawexplosions_cvar, 0, 0);
|
||||
Cvar_Register (&r_drawviewmodel_cvar, 0, 0);
|
||||
|
|
|
@ -77,7 +77,6 @@ static void
|
|||
R_shutdown (void *data)
|
||||
{
|
||||
R_ShutdownEfrags ();
|
||||
R_MaxDlightsCheck (0); // frees memory
|
||||
PI_UnloadPlugin (vidrendmodule);
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
#include "compat.h"
|
||||
#include "r_internal.h"
|
||||
|
||||
dlight_t *r_dlights;
|
||||
vec3_t ambientcolor;
|
||||
|
||||
unsigned int r_maxdlights;
|
||||
|
@ -57,44 +56,42 @@ R_FindNearLights (vec4f_t pos, int count, dlight_t **lights)
|
|||
{
|
||||
float *scores = alloca (count * sizeof (float));
|
||||
float score;
|
||||
dlight_t *dl;
|
||||
unsigned i;
|
||||
int num = 0, j;
|
||||
int num = 0;
|
||||
vec3_t d;
|
||||
|
||||
dl = r_dlights;
|
||||
for (i = 0; i < r_maxdlights; i++, dl++) {
|
||||
if (dl->die < r_data->realtime || !dl->radius)
|
||||
continue;
|
||||
VectorSubtract (dl->origin, pos, d);
|
||||
score = DotProduct (d, d) / dl->radius;
|
||||
auto dlight_pool = &r_refdef.registry->comp_pools[scene_dynlight];
|
||||
auto dlight_data = (dlight_t *) dlight_pool->data;
|
||||
for (uint32_t i = 0; i < dlight_pool->count; i++) {
|
||||
auto dlight = &dlight_data[i];
|
||||
VectorSubtract (dlight->origin, pos, d);
|
||||
score = DotProduct (d, d) / dlight->radius;
|
||||
if (!num) {
|
||||
scores[0] = score;
|
||||
lights[0] = dl;
|
||||
lights[0] = dlight;
|
||||
num = 1;
|
||||
} else if (score <= scores[0]) {
|
||||
memmove (&lights[1], &lights[0],
|
||||
(count - 1) * sizeof (dlight_t *));
|
||||
memmove (&scores[1], &scores[0], (count - 1) * sizeof (float));
|
||||
scores[0] = score;
|
||||
lights[0] = dl;
|
||||
lights[0] = dlight;
|
||||
if (num < count)
|
||||
num++;
|
||||
} else if (score > scores[num - 1]) {
|
||||
if (num < count) {
|
||||
scores[num] = score;
|
||||
lights[num] = dl;
|
||||
lights[num] = dlight;
|
||||
num++;
|
||||
}
|
||||
} else {
|
||||
for (j = num - 1; j > 0; j--) {
|
||||
for (int j = num - 1; j > 0; j--) {
|
||||
if (score > scores[j - 1]) {
|
||||
memmove (&lights[j + 1], &lights[j],
|
||||
(count - j) * sizeof (dlight_t *));
|
||||
memmove (&scores[j + 1], &scores[j],
|
||||
(count - j) * sizeof (float));
|
||||
scores[j] = score;
|
||||
lights[j] = dl;
|
||||
lights[j] = dlight;
|
||||
if (num < count)
|
||||
num++;
|
||||
break;
|
||||
|
@ -102,27 +99,11 @@ R_FindNearLights (vec4f_t pos, int count, dlight_t **lights)
|
|||
}
|
||||
}
|
||||
}
|
||||
for (j = num; j < count; j++)
|
||||
for (int j = num; j < count; j++)
|
||||
lights[j] = 0;
|
||||
return num;
|
||||
}
|
||||
|
||||
void
|
||||
R_MaxDlightsCheck (int max_dlights)
|
||||
{
|
||||
r_maxdlights = bound (0, max_dlights, MAX_DLIGHTS);
|
||||
|
||||
if (r_dlights)
|
||||
free (r_dlights);
|
||||
|
||||
r_dlights = 0;
|
||||
|
||||
if (r_maxdlights)
|
||||
r_dlights = (dlight_t *) calloc (r_maxdlights, sizeof (dlight_t));
|
||||
|
||||
R_ClearDlights();
|
||||
}
|
||||
|
||||
void
|
||||
R_AnimateLight (void)
|
||||
{
|
||||
|
@ -320,23 +301,19 @@ R_MarkLights (vec4f_t lightorigin, dlight_t *light, int lightnum,
|
|||
void
|
||||
R_PushDlights (const vec3_t entorigin, const visstate_t *visstate)
|
||||
{
|
||||
unsigned int i;
|
||||
dlight_t *l;
|
||||
|
||||
r_dlightframecount = r_framecount;
|
||||
|
||||
if (!r_dlight_lightmap)
|
||||
return;
|
||||
|
||||
l = r_dlights;
|
||||
|
||||
for (i = 0; i < r_maxdlights; i++, l++) {
|
||||
if (l->die < r_data->realtime || !l->radius)
|
||||
continue;
|
||||
auto dlight_pool = &r_refdef.registry->comp_pools[scene_dynlight];
|
||||
auto dlight_data = (dlight_t *) dlight_pool->data;
|
||||
for (uint32_t i = 0; i < dlight_pool->count; i++) {
|
||||
auto dlight = &dlight_data[i];
|
||||
vec4f_t lightorigin;
|
||||
VectorSubtract (l->origin, entorigin, lightorigin);
|
||||
VectorSubtract (dlight->origin, entorigin, lightorigin);
|
||||
lightorigin[3] = 1;
|
||||
R_MarkLights (lightorigin, l, i, visstate);
|
||||
R_MarkLights (lightorigin, dlight, i, visstate);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -496,66 +473,3 @@ R_LightPoint (mod_brush_t *brush, vec4f_t p)
|
|||
|
||||
return r;
|
||||
}
|
||||
|
||||
dlight_t *
|
||||
R_AllocDlight (int key)
|
||||
{
|
||||
unsigned int i;
|
||||
dlight_t *dl;
|
||||
|
||||
if (!r_maxdlights) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// first look for an exact key match
|
||||
if (key) {
|
||||
dl = r_dlights;
|
||||
for (i = 0; i < r_maxdlights; i++, dl++) {
|
||||
if (dl->key == key) {
|
||||
memset (dl, 0, sizeof (*dl));
|
||||
dl->key = key;
|
||||
dl->color[0] = dl->color[1] = dl->color[2] = 1;
|
||||
return dl;
|
||||
}
|
||||
}
|
||||
}
|
||||
// then look for anything else
|
||||
dl = r_dlights;
|
||||
for (i = 0; i < r_maxdlights; i++, dl++) {
|
||||
if (dl->die < r_data->realtime) {
|
||||
memset (dl, 0, sizeof (*dl));
|
||||
dl->key = key;
|
||||
dl->color[0] = dl->color[1] = dl->color[2] = 1;
|
||||
return dl;
|
||||
}
|
||||
}
|
||||
|
||||
dl = &r_dlights[0];
|
||||
memset (dl, 0, sizeof (*dl));
|
||||
dl->key = key;
|
||||
return dl;
|
||||
}
|
||||
|
||||
void
|
||||
R_DecayLights (double frametime)
|
||||
{
|
||||
unsigned int i;
|
||||
dlight_t *dl;
|
||||
|
||||
dl = r_dlights;
|
||||
for (i = 0; i < r_maxdlights; i++, dl++) {
|
||||
if (dl->die < r_data->realtime || !dl->radius)
|
||||
continue;
|
||||
|
||||
dl->radius -= frametime * dl->decay;
|
||||
if (dl->radius < 0)
|
||||
dl->radius = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
R_ClearDlights (void)
|
||||
{
|
||||
if (r_maxdlights)
|
||||
memset (r_dlights, 0, r_maxdlights * sizeof (dlight_t));
|
||||
}
|
||||
|
|
|
@ -332,7 +332,9 @@ SCR_UpdateScreen (transform_t camera, double realtime, SCR_Func *scr_funcs)
|
|||
R_MarkLeaves (&r_visstate, scr_scene->viewleaf);
|
||||
}
|
||||
r_framecount++;
|
||||
R_PushDlights (vec3_origin, &r_visstate);
|
||||
if (scr_scene) {
|
||||
R_PushDlights (vec3_origin, &r_visstate);
|
||||
}
|
||||
r_funcs->UpdateScreen (scr_funcs);
|
||||
}
|
||||
|
||||
|
@ -506,10 +508,12 @@ SCR_NewScene (scene_t *scene)
|
|||
.leaf_visframes = leaf_visframes,
|
||||
.face_visframes = face_visframes,
|
||||
};
|
||||
r_refdef.registry = scene->reg;
|
||||
r_funcs->set_fov (tan_fov_x, tan_fov_y);
|
||||
r_funcs->R_NewScene (scene);
|
||||
} else {
|
||||
r_visstate = (visstate_t) {};
|
||||
r_funcs->R_ClearState ();
|
||||
r_refdef.registry = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -197,7 +197,6 @@ 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;
|
||||
|
||||
if (brush->skytexture)
|
||||
|
@ -284,14 +283,15 @@ setup_lighting (entity_t ent, alight_t *lighting)
|
|||
|
||||
VectorCopy (lightvec, lighting->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);
|
||||
auto dlight_pool = &r_refdef.registry->comp_pools[scene_dynlight];
|
||||
auto dlight_data = (dlight_t *) dlight_pool->data;
|
||||
for (uint32_t i = 0; i < dlight_pool->count; i++) {
|
||||
auto dlight = &dlight_data[i];
|
||||
VectorSubtract (r_entorigin, dlight->origin, dist);
|
||||
add = dlight->radius - VectorLength (dist);
|
||||
|
||||
if (add > 0)
|
||||
lighting->ambientlight += add;
|
||||
}
|
||||
if (add > 0)
|
||||
lighting->ambientlight += add;
|
||||
}
|
||||
|
||||
// clamp lighting so it doesn't overbright as much
|
||||
|
@ -360,11 +360,9 @@ R_DrawViewModel (void)
|
|||
{
|
||||
// FIXME: remove and do real lighting
|
||||
int j;
|
||||
unsigned int lnum;
|
||||
vec3_t dist;
|
||||
float add;
|
||||
float minlight;
|
||||
dlight_t *dl;
|
||||
entity_t viewent;
|
||||
alight_t lighting;
|
||||
|
||||
|
@ -404,15 +402,10 @@ R_DrawViewModel (void)
|
|||
lighting.shadelight = j;
|
||||
|
||||
// add dynamic lights
|
||||
for (lnum = 0; lnum < r_maxdlights; lnum++) {
|
||||
dl = &r_dlights[lnum];
|
||||
if (!dl->radius)
|
||||
continue;
|
||||
if (!dl->radius)
|
||||
continue;
|
||||
if (dl->die < vr_data.realtime)
|
||||
continue;
|
||||
|
||||
auto dlight_pool = &r_refdef.registry->comp_pools[scene_dynlight];
|
||||
auto dlight_data = (dlight_t *) dlight_pool->data;
|
||||
for (uint32_t i = 0; i < dlight_pool->count; i++) {
|
||||
auto dl = &dlight_data[i];
|
||||
VectorSubtract (r_entorigin, dl->origin, dist);
|
||||
add = dl->radius - VectorLength (dist);
|
||||
if (add > 0)
|
||||
|
@ -494,6 +487,9 @@ R_DrawBrushEntitiesOnList (entqueue_t *queue)
|
|||
|
||||
insubmodel = true;
|
||||
|
||||
auto dlight_pool = &r_refdef.registry->comp_pools[scene_dynlight];
|
||||
auto dlight_data = (dlight_t *) dlight_pool->data;
|
||||
|
||||
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);
|
||||
|
@ -527,17 +523,13 @@ R_DrawBrushEntitiesOnList (entqueue_t *queue)
|
|||
// calculate dynamic lighting for bmodel if it's not an
|
||||
// instanced model
|
||||
if (brush->firstmodelsurface != 0) {
|
||||
for (k = 0; k < r_maxdlights; k++) {
|
||||
if ((r_dlights[k].die < vr_data.realtime) ||
|
||||
(!r_dlights[k].radius)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (k = 0; k < dlight_pool->count; k++) {
|
||||
auto dlight = &dlight_data[k];
|
||||
vec4f_t lightorigin;
|
||||
VectorSubtract (r_dlights[k].origin, origin, lightorigin);
|
||||
VectorSubtract (dlight->origin, origin, lightorigin);
|
||||
lightorigin[3] = 1;
|
||||
R_RecursiveMarkLights (brush, lightorigin,
|
||||
&r_dlights[k], k,
|
||||
dlight, k,
|
||||
brush->hulls[0].firstclipnode);
|
||||
}
|
||||
}
|
||||
|
@ -699,6 +691,5 @@ void
|
|||
R_ClearState (void)
|
||||
{
|
||||
r_refdef.worldmodel = 0;
|
||||
R_ClearDlights ();
|
||||
R_ClearParticles ();
|
||||
}
|
||||
|
|
|
@ -76,13 +76,11 @@ static void
|
|||
R_AddDynamicLights (uint32_t render_id)
|
||||
{
|
||||
msurface_t *surf;
|
||||
unsigned int lnum;
|
||||
int sd, td;
|
||||
float dist, rad, minlight;
|
||||
vec3_t impact, local, lightorigin;
|
||||
vec4f_t entorigin = { 0, 0, 0, 1 };
|
||||
int s, t;
|
||||
int i;
|
||||
int smax, tmax;
|
||||
mtexinfo_t *tex;
|
||||
|
||||
|
@ -97,21 +95,25 @@ R_AddDynamicLights (uint32_t render_id)
|
|||
entorigin = transform[3];
|
||||
}
|
||||
|
||||
for (lnum = 0; lnum < r_maxdlights; lnum++) {
|
||||
if (!(surf->dlightbits[lnum / 32] & (1 << (lnum % 32))))
|
||||
auto dlight_pool = &r_refdef.registry->comp_pools[scene_dynlight];
|
||||
auto dlight_data = (dlight_t *) dlight_pool->data;
|
||||
for (uint32_t k = 0; k < dlight_pool->count; k++) {
|
||||
auto dlight = &dlight_data[k];
|
||||
//FIXME
|
||||
if (!(surf->dlightbits[k / 32] & (1 << (k % 32))))
|
||||
continue; // not lit by this light
|
||||
|
||||
VectorSubtract (r_dlights[lnum].origin, entorigin, lightorigin);
|
||||
rad = r_dlights[lnum].radius;
|
||||
VectorSubtract (dlight->origin, entorigin, lightorigin);
|
||||
rad = dlight->radius;
|
||||
dist = DotProduct (lightorigin, surf->plane->normal) -
|
||||
surf->plane->dist;
|
||||
rad -= fabs (dist);
|
||||
minlight = r_dlights[lnum].minlight;
|
||||
minlight = dlight->minlight;
|
||||
if (rad < minlight)
|
||||
continue;
|
||||
minlight = rad - minlight;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
for (int i = 0; i < 3; i++)
|
||||
impact[i] = lightorigin[i] - surf->plane->normal[i] * dist;
|
||||
|
||||
local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3];
|
||||
|
|
|
@ -146,7 +146,6 @@ vulkan_R_ClearState (void)
|
|||
//FIXME clear scene correctly
|
||||
r_refdef.worldmodel = 0;
|
||||
EntQueue_Clear (r_ent_queue);
|
||||
R_ClearDlights ();
|
||||
R_ClearParticles ();
|
||||
Vulkan_LoadLights (0, vulkan_ctx);
|
||||
}
|
||||
|
|
|
@ -310,7 +310,7 @@ CL_RelinkEntities (void)
|
|||
angles[YAW] = bobjrotate;
|
||||
CL_TransformEntity (ent, new->scale / 16.0, angles, new->origin);
|
||||
}
|
||||
CL_EntityEffects (i, ent, new, cl.time);
|
||||
CL_EntityEffects (ent, new, cl.time);
|
||||
vec4f_t org = Transform_GetWorldPosition (transform);
|
||||
int effects = new->effects;
|
||||
if (cl.maxclients == 1 && effects) {
|
||||
|
@ -325,13 +325,13 @@ CL_RelinkEntities (void)
|
|||
effects |= (it & IT_INVULNERABILITY)
|
||||
>> (BITOP_LOG2(IT_INVULNERABILITY) - BITOP_LOG2 (EF_RED));
|
||||
}
|
||||
CL_NewDlight (i, org, effects, new->glow_size,
|
||||
CL_NewDlight (ent, org, effects, new->glow_size,
|
||||
new->glow_color, cl.time);
|
||||
if (VectorDistance_fast (old->origin, org) > (256 * 256)) {
|
||||
old->origin = org;
|
||||
}
|
||||
if (model_flags & ~EF_ROTATE)
|
||||
CL_ModelEffects (ent, i, new->glow_color, cl.time);
|
||||
CL_ModelEffects (ent, new->glow_color, cl.time);
|
||||
|
||||
SET_REMOVE (&cl_forcelink, i);
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "QF/plugin/console.h"
|
||||
#include "QF/plugin/vid_render.h"
|
||||
#include "QF/scene/entity.h"
|
||||
#include "QF/scene/light.h"
|
||||
#include "QF/scene/scene.h"
|
||||
#include "QF/ui/font.h"//FIXME
|
||||
|
||||
|
@ -659,7 +660,7 @@ CL_Frame (void)
|
|||
if (l)
|
||||
asl = l->ambient_sound_level;
|
||||
S_Update (cl.viewstate.camera_transform, asl);
|
||||
R_DecayLights (host_frametime);
|
||||
Light_DecayLights (cl_world.scene->lights, host_frametime, realtime);
|
||||
} else
|
||||
S_Update (nulltransform, 0);
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@ typedef struct player_state_s {
|
|||
int oldbuttons;
|
||||
int oldonground;
|
||||
|
||||
bool muzzle_flash;
|
||||
} player_state_t;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "QF/sys.h"
|
||||
|
||||
#include "QF/scene/entity.h"
|
||||
#include "QF/scene/light.h"
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
|
@ -194,7 +195,7 @@ CL_LinkPacketEntities (void)
|
|||
ent.reg);
|
||||
|
||||
// spawn light flashes, even ones coming from invisible objects
|
||||
CL_NewDlight (i, new->origin, new->effects, new->glow_size,
|
||||
CL_NewDlight (ent, new->origin, new->effects, new->glow_size,
|
||||
new->glow_color, cl.time);
|
||||
|
||||
if (forcelink)
|
||||
|
@ -298,7 +299,7 @@ CL_LinkPacketEntities (void)
|
|||
if (VectorDistance_fast (old->origin, org) > (256 * 256))
|
||||
old->origin = org;
|
||||
if (renderer->model->flags & ~EF_ROTATE) {
|
||||
CL_ModelEffects (ent, -new->number, new->glow_color, cl.time);
|
||||
CL_ModelEffects (ent, new->glow_color, cl.time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -385,6 +386,21 @@ CL_RemoveFlagModels (int key)
|
|||
Transform_SetParent (transform, nulltransform);
|
||||
}
|
||||
|
||||
static void
|
||||
muzzle_flash (entity_t ent, player_state_t *state, bool is_player)
|
||||
{
|
||||
vec3_t f, r, u;
|
||||
vec4f_t position = { 0, 0, 0, 1}, fv = {};
|
||||
if (is_player)
|
||||
AngleVectors (cl.viewstate.player_angles, f, r, u);
|
||||
else
|
||||
AngleVectors (state->viewangles, f, r, u);
|
||||
|
||||
VectorCopy (f, fv);
|
||||
VectorCopy (state->pls.es.origin, position);
|
||||
CL_MuzzleFlash (ent, position, fv, 0, cl.time);
|
||||
}
|
||||
|
||||
/*
|
||||
CL_LinkPlayers
|
||||
|
||||
|
@ -441,16 +457,19 @@ CL_LinkPlayers (void)
|
|||
clientplayer = false;
|
||||
}
|
||||
if (player->chat && player->chat->value[0] != '0') {
|
||||
dlight_t *dl = R_AllocDlight (j + 1);
|
||||
VectorCopy (org, dl->origin);
|
||||
dl->radius = 100;
|
||||
dl->die = cl.time + 0.1;
|
||||
QuatSet (0.0, 1.0, 0.0, 1.0, dl->color);
|
||||
Ent_SetComponent (ent.id, scene_dynlight, ent.reg, &(dlight_t) {
|
||||
.origin = org,
|
||||
.color = {0.0, 1.0, 0.0, 1.0},
|
||||
.radius = 100,
|
||||
.die = cl.time + 0.1,
|
||||
});
|
||||
Light_LinkLight (cl_world.scene->lights, ent.id);
|
||||
} else {
|
||||
CL_NewDlight (j + 1, org, state->pls.es.effects,
|
||||
CL_NewDlight (ent, org, state->pls.es.effects,
|
||||
state->pls.es.glow_size, state->pls.es.glow_color,
|
||||
cl.time);
|
||||
}
|
||||
muzzle_flash (ent, state, j == cl.playernum);
|
||||
|
||||
// Draw player?
|
||||
if (!Cam_DrawPlayer (j))
|
||||
|
|
|
@ -91,6 +91,7 @@
|
|||
#include "QF/gib.h"
|
||||
|
||||
#include "QF/plugin/console.h"
|
||||
#include "QF/scene/light.h"
|
||||
#include "QF/scene/transform.h"
|
||||
#include "QF/ui/font.h"//FIXME
|
||||
|
||||
|
@ -1969,7 +1970,7 @@ Host_Frame (float time)
|
|||
if (l)
|
||||
asl = l->ambient_sound_level;
|
||||
S_Update (cl.viewstate.camera_transform, asl);
|
||||
R_DecayLights (host_frametime);
|
||||
Light_DecayLights (cl_world.scene->lights, host_frametime, realtime);
|
||||
} else
|
||||
S_Update (nulltransform, 0);
|
||||
|
||||
|
|
|
@ -1184,12 +1184,8 @@ CL_SetStat (int stat, int value)
|
|||
static void
|
||||
CL_ParseMuzzleFlash (void)
|
||||
{
|
||||
//FIXME this should just enable the effect on the relevant entity and
|
||||
//then automatic entity updates take care of the rest
|
||||
int i;
|
||||
player_state_t *pl;
|
||||
vec3_t f, r, u;
|
||||
vec4f_t position = { 0, 0, 0, 1}, fv = {};
|
||||
|
||||
i = MSG_ReadShort (net_message);
|
||||
|
||||
|
@ -1197,15 +1193,7 @@ CL_ParseMuzzleFlash (void)
|
|||
return;
|
||||
|
||||
pl = &cl.frames[parsecountmod].playerstate[i - 1];
|
||||
|
||||
if (i - 1 == cl.playernum)
|
||||
AngleVectors (cl.viewstate.player_angles, f, r, u);
|
||||
else
|
||||
AngleVectors (pl->viewangles, f, r, u);
|
||||
|
||||
VectorCopy (f, fv);
|
||||
VectorCopy (pl->pls.es.origin, position);
|
||||
CL_MuzzleFlash (position, fv, 0, i, cl.time);
|
||||
pl->muzzle_flash = true;
|
||||
}
|
||||
|
||||
#define SHOWNET(x) \
|
||||
|
|
Loading…
Reference in a new issue