[particles] Create a psystem object

This takes care of the global variables to a point (there is still the
global struct shared between the non-vulkan renderers), but it also
takes care of glsl's points-only rendering.
This commit is contained in:
Bill Currie 2021-12-19 14:47:25 +09:00
parent 372c89b479
commit d70d72e6e4
17 changed files with 124 additions and 133 deletions

View file

@ -55,12 +55,14 @@ typedef struct particlectx_s {
VkPipelineLayout physics_layout; VkPipelineLayout physics_layout;
VkPipelineLayout update_layout; VkPipelineLayout update_layout;
VkPipelineLayout draw_layout; VkPipelineLayout draw_layout;
psystem_t psystem;
} particlectx_t; } particlectx_t;
struct cvar_s; struct cvar_s;
struct vulkan_ctx_s;; struct vulkan_ctx_s;;
struct r_particle_ctx_s *Vulkan_ParticleContext (struct vulkan_ctx_s *ctx); struct psystem_s *Vulkan_ParticleSystem (struct vulkan_ctx_s *ctx);
void Vulkan_Particles_Init (struct vulkan_ctx_s *ctx); void Vulkan_Particles_Init (struct vulkan_ctx_s *ctx);
void Vulkan_Particles_Shutdown (struct vulkan_ctx_s *ctx); void Vulkan_Particles_Shutdown (struct vulkan_ctx_s *ctx);
void Vulkan_DrawParticles (struct vulkan_ctx_s *ctx); void Vulkan_DrawParticles (struct vulkan_ctx_s *ctx);

View file

@ -109,6 +109,7 @@ typedef struct vid_render_funcs_s {
float time); float time);
void (*Fog_ParseWorldspawn) (struct plitem_s *worldspawn); void (*Fog_ParseWorldspawn) (struct plitem_s *worldspawn);
struct psystem_s *(*ParticleSystem) (void);
void (*R_Init) (void); void (*R_Init) (void);
void (*R_RenderFrame) (SCR_Func *scr_funcs); void (*R_RenderFrame) (SCR_Func *scr_funcs);
void (*R_ClearState) (void); void (*R_ClearState) (void);

View file

@ -90,12 +90,15 @@ typedef struct partparm_s {
float alpha_rate; float alpha_rate;
} partparm_t; } partparm_t;
// FIXME these really shouldn't be global, but they speed up particle creation typedef struct psystem_s {
extern unsigned int r_maxparticles; uint32_t maxparticles;
extern unsigned int numparticles; uint32_t numparticles;
extern struct particle_s *particles; particle_t *particles;
extern struct partparm_s *partparams; partparm_t *partparams;
extern const int **partramps; const int **partramps;
int points_only;
} psystem_t;
extern struct vid_render_funcs_s *r_funcs; extern struct vid_render_funcs_s *r_funcs;
extern struct vid_render_data_s *r_data; extern struct vid_render_data_s *r_data;

View file

@ -51,11 +51,17 @@ void R_InitEfrags (void);
void R_ClearState (void); void R_ClearState (void);
void R_InitSky (struct texture_s *mt); // called at level load void R_InitSky (struct texture_s *mt); // called at level load
void R_Textures_Init (void); void R_Textures_Init (void);
void R_RunParticles (float dT);
void R_RenderView (void); // must set r_refdef first void R_RenderView (void); // must set r_refdef first
void R_ViewChanged (void); // must set r_refdef first void R_ViewChanged (void); // must set r_refdef first
// called whenever r_refdef or vid change // called whenever r_refdef or vid change
extern struct psystem_s r_psystem;
struct psystem_s *gl_ParticleSystem (void);
struct psystem_s *glsl_ParticleSystem (void);
struct psystem_s *sw_ParticleSystem (void);
struct psystem_s *sw32_ParticleSystem (void);
void R_RunParticles (float dT);
void R_AddEfrags (mod_brush_t *, entity_t *ent); void R_AddEfrags (mod_brush_t *, entity_t *ent);
void R_RemoveEfrags (entity_t *ent); void R_RemoveEfrags (entity_t *ent);

View file

@ -46,6 +46,7 @@
#include "QF/sys.h" #include "QF/sys.h"
#include "QF/va.h" #include "QF/va.h"
#include "QF/plugin/vid_render.h" //FIXME
#include "QF/scene/entity.h" #include "QF/scene/entity.h"
#include "compat.h" #include "compat.h"
@ -57,6 +58,7 @@ float cl_realtime;
cl_particle_funcs_t *clp_funcs; cl_particle_funcs_t *clp_funcs;
static mtstate_t mt; // private PRNG state static mtstate_t mt; // private PRNG state
static psystem_t *cl_psystem;
static cvar_t *easter_eggs; static cvar_t *easter_eggs;
static cvar_t *particles_style; static cvar_t *particles_style;
@ -116,12 +118,15 @@ inline static int
particle_new (ptype_t type, int texnum, vec4f_t pos, float scale, particle_new (ptype_t type, int texnum, vec4f_t pos, float scale,
vec4f_t vel, float live, int color, float alpha, float ramp) vec4f_t vel, float live, int color, float alpha, float ramp)
{ {
if (numparticles >= r_maxparticles) if (cl_psystem->numparticles >= cl_psystem->maxparticles) {
return 0; return 0;
particle_t *p = &particles[numparticles]; }
partparm_t *parm = &partparams[numparticles];
const int **rampptr = &partramps[numparticles]; __auto_type ps = cl_psystem;
numparticles += 1; particle_t *p = &ps->particles[ps->numparticles];
partparm_t *parm = &ps->partparams[ps->numparticles];
const int **rampptr = &ps->partramps[ps->numparticles];
ps->numparticles += 1;
p->pos = pos; p->pos = pos;
p->vel = vel; p->vel = vel;
@ -216,14 +221,6 @@ add_particle (ptype_t type, vec4f_t pos, vec4f_t vel, float live, int color,
{ {
particle_new (type, part_tex_dot, pos, 1, vel, live, color, 1, ramp); particle_new (type, part_tex_dot, pos, 1, vel, live, color, 1, ramp);
} }
/*
void
CL_ClearParticles (void)
{
numparticles = 0;
}
*/
static void static void
pointfile_f (void) pointfile_f (void)
@ -260,12 +257,10 @@ pointfile_f (void)
break; break;
c++; c++;
if (numparticles >= r_maxparticles) { if (!particle_new (pt_static, part_tex_dot, org, 1.5, zero,
99999, (-c) & 15, 1.0, 0.0)) {
Sys_MaskPrintf (SYS_dev, "Not enough free particles\n"); Sys_MaskPrintf (SYS_dev, "Not enough free particles\n");
break; break;
} else {
particle_new (pt_static, part_tex_dot, org, 1.5, zero,
99999, (-c) & 15, 1.0, 0.0);
} }
} }
Qclose (f); Qclose (f);
@ -276,8 +271,6 @@ static void
CL_ParticleExplosion_QF (vec4f_t org) CL_ParticleExplosion_QF (vec4f_t org)
{ {
// CL_NewExplosion (org); // CL_NewExplosion (org);
if (numparticles >= r_maxparticles)
return;
particle_new_random (pt_smokecloud, part_tex_smoke, org, 4, 30, 8, particle_new_random (pt_smokecloud, part_tex_smoke, org, 4, 30, 8,
5.0, (mtwist_rand (&mt) & 7) + 8, 5.0, (mtwist_rand (&mt) & 7) + 8,
0.5 + qfrandom (0.25), 0.0); 0.5 + qfrandom (0.25), 0.0);
@ -288,11 +281,6 @@ CL_ParticleExplosion2_QF (vec4f_t org, int colorStart, int colorLength)
{ {
unsigned int i, j = 512; unsigned int i, j = 512;
if (numparticles >= r_maxparticles)
return;
else if (numparticles + j >= r_maxparticles)
j = r_maxparticles - numparticles;
for (i = 0; i < j; i++) { for (i = 0; i < j; i++) {
particle_new_random (pt_blob, part_tex_dot, org, 16, 2, 256, particle_new_random (pt_blob, part_tex_dot, org, 16, 2, 256,
0.3, 0.3,
@ -306,11 +294,6 @@ CL_BlobExplosion_QF (vec4f_t org)
unsigned int i; unsigned int i;
unsigned int j = 1024; unsigned int j = 1024;
if (numparticles >= r_maxparticles)
return;
else if (numparticles + j >= r_maxparticles)
j = r_maxparticles - numparticles;
for (i = 0; i < j >> 1; i++) { for (i = 0; i < j >> 1; i++) {
particle_new_random (pt_blob, part_tex_dot, org, 12, 2, 256, particle_new_random (pt_blob, part_tex_dot, org, 12, 2, 256,
1.0 + (mtwist_rand (&mt) & 7) * 0.05, 1.0 + (mtwist_rand (&mt) & 7) * 0.05,
@ -486,9 +469,6 @@ CL_TeleportSplash_QF (vec4f_t org)
static void static void
CL_RocketTrail_QF (vec4f_t start, vec4f_t end) CL_RocketTrail_QF (vec4f_t start, vec4f_t end)
{ {
if (numparticles >= r_maxparticles)
return;
vec4f_t vec = end - start; vec4f_t vec = end - start;
float maxlen = magnitudef (vec)[0]; float maxlen = magnitudef (vec)[0];
vec = normalf (vec); vec = normalf (vec);
@ -511,8 +491,6 @@ CL_RocketTrail_QF (vec4f_t start, vec4f_t end)
2.0 - percent * 2.0, 2.0 - percent * 2.0,
12 + (mtwist_rand (&mt) & 3), 12 + (mtwist_rand (&mt) & 3),
0.5 + qfrandom (0.125) - percent * 0.40, 0.0); 0.5 + qfrandom (0.125) - percent * 0.40, 0.0);
if (numparticles >= r_maxparticles)
break;
len += dist; len += dist;
pos += step; pos += step;
pscale = pscalenext; pscale = pscalenext;
@ -522,9 +500,6 @@ CL_RocketTrail_QF (vec4f_t start, vec4f_t end)
static void static void
CL_GrenadeTrail_QF (vec4f_t start, vec4f_t end) CL_GrenadeTrail_QF (vec4f_t start, vec4f_t end)
{ {
if (numparticles >= r_maxparticles)
return;
vec4f_t vec = end - start; vec4f_t vec = end - start;
float maxlen = magnitudef (vec)[0]; float maxlen = magnitudef (vec)[0];
vec = normalf (vec); vec = normalf (vec);
@ -547,8 +522,6 @@ CL_GrenadeTrail_QF (vec4f_t start, vec4f_t end)
2.0 - percent * 2.0, 2.0 - percent * 2.0,
1 + (mtwist_rand (&mt) & 3), 1 + (mtwist_rand (&mt) & 3),
0.625 + qfrandom (0.125) - percent * 0.40, 0.0); 0.625 + qfrandom (0.125) - percent * 0.40, 0.0);
if (numparticles >= r_maxparticles)
break;
len += dist; len += dist;
pos += step; pos += step;
pscale = pscalenext; pscale = pscalenext;
@ -558,9 +531,6 @@ CL_GrenadeTrail_QF (vec4f_t start, vec4f_t end)
static void static void
CL_BloodTrail_QF (vec4f_t start, vec4f_t end) CL_BloodTrail_QF (vec4f_t start, vec4f_t end)
{ {
if (numparticles >= r_maxparticles)
return;
vec4f_t vec = end - start; vec4f_t vec = end - start;
float maxlen = magnitudef (vec)[0]; float maxlen = magnitudef (vec)[0];
vec = normalf (vec); vec = normalf (vec);
@ -582,8 +552,6 @@ CL_BloodTrail_QF (vec4f_t start, vec4f_t end)
particle_new (pt_grav, part_tex_smoke, pos + roffs (4), pscale, vel, particle_new (pt_grav, part_tex_smoke, pos + roffs (4), pscale, vel,
2.0 - percent * 2.0, 2.0 - percent * 2.0,
68 + (mtwist_rand (&mt) & 3), 1.0, 0.0); 68 + (mtwist_rand (&mt) & 3), 1.0, 0.0);
if (numparticles >= r_maxparticles)
break;
len += dist; len += dist;
pos += step; pos += step;
pscale = pscalenext; pscale = pscalenext;
@ -593,9 +561,6 @@ CL_BloodTrail_QF (vec4f_t start, vec4f_t end)
static void static void
CL_SlightBloodTrail_QF (vec4f_t start, vec4f_t end) CL_SlightBloodTrail_QF (vec4f_t start, vec4f_t end)
{ {
if (numparticles >= r_maxparticles)
return;
vec4f_t vec = end - start; vec4f_t vec = end - start;
float maxlen = magnitudef (vec)[0]; float maxlen = magnitudef (vec)[0];
vec = normalf (vec); vec = normalf (vec);
@ -616,8 +581,6 @@ CL_SlightBloodTrail_QF (vec4f_t start, vec4f_t end)
particle_new (pt_grav, part_tex_smoke, pos + roffs (4), pscale, vel, particle_new (pt_grav, part_tex_smoke, pos + roffs (4), pscale, vel,
1.5 - percent * 1.5, 1.5 - percent * 1.5,
68 + (mtwist_rand (&mt) & 3), 0.75, 0.0); 68 + (mtwist_rand (&mt) & 3), 0.75, 0.0);
if (numparticles >= r_maxparticles)
break;
len += dist; len += dist;
pos += step; pos += step;
pscale = pscalenext; pscale = pscalenext;
@ -629,9 +592,6 @@ CL_WizTrail_QF (vec4f_t start, vec4f_t end)
{ {
float dist = 3.0; float dist = 3.0;
if (numparticles >= r_maxparticles)
return;
vec4f_t vec = end - start; vec4f_t vec = end - start;
float maxlen = magnitudef (vec)[0]; float maxlen = magnitudef (vec)[0];
vec = normalf (vec); vec = normalf (vec);
@ -650,8 +610,6 @@ CL_WizTrail_QF (vec4f_t start, vec4f_t end)
30 * tracer_vel (tracercount++, vec), 30 * tracer_vel (tracercount++, vec),
0.5 - percent * 0.5, 0.5 - percent * 0.5,
52 + (mtwist_rand (&mt) & 4), 1.0 - percent * 0.125, 0.0); 52 + (mtwist_rand (&mt) & 4), 1.0 - percent * 0.125, 0.0);
if (numparticles >= r_maxparticles)
break;
len += dist; len += dist;
pos += step; pos += step;
} }
@ -662,9 +620,6 @@ CL_FlameTrail_QF (vec4f_t start, vec4f_t end)
{ {
float dist = 3.0; float dist = 3.0;
if (numparticles >= r_maxparticles)
return;
vec4f_t vec = end - start; vec4f_t vec = end - start;
float maxlen = magnitudef (vec)[0]; float maxlen = magnitudef (vec)[0];
vec = normalf (vec); vec = normalf (vec);
@ -693,9 +648,6 @@ CL_VoorTrail_QF (vec4f_t start, vec4f_t end)
{ {
float dist = 3.0; float dist = 3.0;
if (numparticles >= r_maxparticles)
return;
vec4f_t vec = end - start; vec4f_t vec = end - start;
float maxlen = magnitudef (vec)[0]; float maxlen = magnitudef (vec)[0];
vec = normalf (vec); vec = normalf (vec);
@ -723,9 +675,6 @@ CL_GlowTrail_QF (vec4f_t start, vec4f_t end, int glow_color)
{ {
float dist = 3.0; float dist = 3.0;
if (numparticles >= r_maxparticles)
return;
vec4f_t vec = end - start; vec4f_t vec = end - start;
float maxlen = magnitudef (vec)[0]; float maxlen = magnitudef (vec)[0];
vec = normalf (vec); vec = normalf (vec);
@ -741,8 +690,6 @@ CL_GlowTrail_QF (vec4f_t start, vec4f_t end, int glow_color)
particle_new (pt_smoke, part_tex_dot, pos + roffs (5), 1.0, zero, particle_new (pt_smoke, part_tex_dot, pos + roffs (5), 1.0, zero,
2.0 - percent * 0.2, glow_color, 1.0, 0.0); 2.0 - percent * 0.2, glow_color, 1.0, 0.0);
if (numparticles >= r_maxparticles)
break;
len += dist; len += dist;
pos += step; pos += step;
} }
@ -754,8 +701,6 @@ CL_ParticleExplosion_EE (vec4f_t org)
/* /*
CL_NewExplosion (org); CL_NewExplosion (org);
*/ */
if (numparticles >= r_maxparticles)
return;
particle_new_random (pt_smokecloud, part_tex_smoke, org, 4, 30, 8, particle_new_random (pt_smokecloud, part_tex_smoke, org, 4, 30, 8,
5.0, mtwist_rand (&mt) & 255, 5.0, mtwist_rand (&mt) & 255,
0.5 + qfrandom (0.25), 0.0); 0.5 + qfrandom (0.25), 0.0);
@ -788,9 +733,6 @@ CL_TeleportSplash_EE (vec4f_t org)
static void static void
CL_RocketTrail_EE (vec4f_t start, vec4f_t end) CL_RocketTrail_EE (vec4f_t start, vec4f_t end)
{ {
if (numparticles >= r_maxparticles)
return;
vec4f_t vec = end - start; vec4f_t vec = end - start;
float maxlen = magnitudef (vec)[0]; float maxlen = magnitudef (vec)[0];
vec = normalf (vec); vec = normalf (vec);
@ -811,8 +753,6 @@ CL_RocketTrail_EE (vec4f_t start, vec4f_t end)
2.0 - percent * 2.0, 2.0 - percent * 2.0,
mtwist_rand (&mt) & 255, mtwist_rand (&mt) & 255,
0.5 + qfrandom (0.125) - percent * 0.40, 0.0); 0.5 + qfrandom (0.125) - percent * 0.40, 0.0);
if (numparticles >= r_maxparticles)
break;
len += dist; len += dist;
pos += len * vec; pos += len * vec;
pscale = pscalenext; pscale = pscalenext;
@ -1169,8 +1109,6 @@ CL_Particle_New (ptype_t type, int texnum, vec4f_t org, float scale,
vec4f_t vel, float live, int color, float alpha, vec4f_t vel, float live, int color, float alpha,
float ramp) float ramp)
{ {
if (numparticles >= r_maxparticles)
return;
particle_new (type, texnum, org, scale, vel, live, color, alpha, ramp); particle_new (type, texnum, org, scale, vel, live, color, alpha, ramp);
} }
@ -1179,8 +1117,6 @@ CL_Particle_NewRandom (ptype_t type, int texnum, vec4f_t org,
int org_fuzz, float scale, int vel_fuzz, float live, int org_fuzz, float scale, int vel_fuzz, float live,
int color, float alpha, float ramp) int color, float alpha, float ramp)
{ {
if (numparticles >= r_maxparticles)
return;
particle_new_random (type, texnum, org, org_fuzz, scale, vel_fuzz, live, particle_new_random (type, texnum, org, org_fuzz, scale, vel_fuzz, live,
color, alpha, ramp); color, alpha, ramp);
} }
@ -1321,6 +1257,7 @@ static void
particles_style_f (cvar_t *var) particles_style_f (cvar_t *var)
{ {
easter_eggs_f (easter_eggs); easter_eggs_f (easter_eggs);
cl_psystem->points_only = !var->int_val;
} }
static void static void
@ -1330,12 +1267,11 @@ CL_ParticleFunctionInit (void)
easter_eggs_f (easter_eggs); easter_eggs_f (easter_eggs);
} }
/*
*/
void void
CL_Particles_Init (void) CL_Particles_Init (void)
{ {
mtwist_seed (&mt, 0xdeadbeef); mtwist_seed (&mt, 0xdeadbeef);
cl_psystem = r_funcs->ParticleSystem ();
Cmd_AddCommand ("pointfile", pointfile_f, Cmd_AddCommand ("pointfile", pointfile_f,
"Load a pointfile to determine map leaks."); "Load a pointfile to determine map leaks.");
easter_eggs = Cvar_Get ("easter_eggs", "0", CVAR_NONE, easter_eggs_f, easter_eggs = Cvar_Get ("easter_eggs", "0", CVAR_NONE, easter_eggs_f,

View file

@ -71,18 +71,18 @@ gl_R_InitParticles (void)
{ {
int i; int i;
if (r_maxparticles && r_init) { if (r_psystem.maxparticles && r_init) {
if (vaelements) { if (vaelements) {
partUseVA = 0; partUseVA = 0;
pVAsize = r_maxparticles * 4; pVAsize = r_psystem.maxparticles * 4;
Sys_MaskPrintf (SYS_dev, Sys_MaskPrintf (SYS_dev,
"Particles: Vertex Array use disabled.\n"); "Particles: Vertex Array use disabled.\n");
} else { } else {
if (vaelements > 3) if (vaelements > 3)
pVAsize = min ((unsigned int) (vaelements - (vaelements % 4)), pVAsize = min ((unsigned int) (vaelements - (vaelements % 4)),
r_maxparticles * 4); r_psystem.maxparticles * 4);
else if (vaelements >= 0) else if (vaelements >= 0)
pVAsize = r_maxparticles * 4; pVAsize = r_psystem.maxparticles * 4;
Sys_MaskPrintf (SYS_dev, Sys_MaskPrintf (SYS_dev,
"Particles: %i maximum vertex elements.\n", "Particles: %i maximum vertex elements.\n",
pVAsize); pVAsize);
@ -137,8 +137,8 @@ gl_R_DrawParticles (void)
vacount = 0; vacount = 0;
VA = particleVertexArray; VA = particleVertexArray;
for (unsigned i = 0; i < numparticles; i++) { for (unsigned i = 0; i < r_psystem.numparticles; i++) {
particle_t *p = &particles[i]; particle_t *p = &r_psystem.particles[i];
// Don't render particles too close to us. // Don't render particles too close to us.
// Note, we must still do physics and such on them. // Note, we must still do physics and such on them.
if (!(DotProduct (p->pos, vpn) < minparticledist)) { if (!(DotProduct (p->pos, vpn) < minparticledist)) {
@ -263,3 +263,9 @@ gl_R_Particles_Init_Cvars (void)
"Distance of the particle near clipping " "Distance of the particle near clipping "
"plane from the player."); "plane from the player.");
} }
psystem_t * __attribute__((const))//FIXME
gl_ParticleSystem (void)
{
return &r_psystem;
}

View file

@ -250,7 +250,7 @@ gl_R_RenderFrame (SCR_Func *scr_funcs)
time2 = Sys_DoubleTime (); time2 = Sys_DoubleTime ();
Sys_MaskPrintf (SYS_dev, "%3i ms %4i wpoly %4i epoly %4i parts\n", Sys_MaskPrintf (SYS_dev, "%3i ms %4i wpoly %4i epoly %4i parts\n",
(int) ((time2 - time1) * 1000), gl_c_brush_polys, (int) ((time2 - time1) * 1000), gl_c_brush_polys,
gl_c_alias_polys, numparticles); gl_c_alias_polys, r_psystem.numparticles);
} }
GL_FlushText (); GL_FlushText ();

View file

@ -1,5 +1,5 @@
/* /*
gl_dyn_part.c glsl_particles.c
OpenGL particle system. OpenGL particle system.
@ -201,12 +201,13 @@ glsl_R_InitParticles (void)
if (particleVertexArray) if (particleVertexArray)
free (particleVertexArray); free (particleVertexArray);
particleVertexArray = calloc (r_maxparticles * 4, sizeof (partvert_t)); particleVertexArray = calloc (r_psystem.maxparticles * 4,
sizeof (partvert_t));
if (pVAindices) if (pVAindices)
free (pVAindices); free (pVAindices);
pVAindices = calloc (r_maxparticles * 6, sizeof (GLushort)); pVAindices = calloc (r_psystem.maxparticles * 6, sizeof (GLushort));
for (i = 0; i < r_maxparticles; i++) { for (i = 0; i < r_psystem.maxparticles; i++) {
pVAindices[i * 6 + 0] = i * 4 + 0; pVAindices[i * 6 + 0] = i * 4 + 0;
pVAindices[i * 6 + 1] = i * 4 + 1; pVAindices[i * 6 + 1] = i * 4 + 1;
pVAindices[i * 6 + 2] = i * 4 + 2; pVAindices[i * 6 + 2] = i * 4 + 2;
@ -256,8 +257,8 @@ draw_qf_particles (void)
vacount = 0; vacount = 0;
VA = particleVertexArray; VA = particleVertexArray;
for (unsigned i = 0; i < numparticles; i++) { for (unsigned i = 0; i < r_psystem.numparticles; i++) {
particle_t *p = &particles[i]; particle_t *p = &r_psystem.particles[i];
// Don't render particles too close to us. // Don't render particles too close to us.
// Note, we must still do physics and such on them. // Note, we must still do physics and such on them.
if (!(DotProduct (p->pos, vpn) < minparticledist)) { if (!(DotProduct (p->pos, vpn) < minparticledist)) {
@ -375,8 +376,8 @@ draw_id_particles (void)
vacount = 0; vacount = 0;
VA = particleVertexArray; VA = particleVertexArray;
for (unsigned i = 0; i < numparticles; i++) { for (unsigned i = 0; i < r_psystem.numparticles; i++) {
particle_t *p = &particles[i]; particle_t *p = &r_psystem.particles[i];
// Don't render particles too close to us. // Don't render particles too close to us.
// Note, we must still do physics and such on them. // Note, we must still do physics and such on them.
if (!(DotProduct (p->pos, vpn) < minparticledist)) { if (!(DotProduct (p->pos, vpn) < minparticledist)) {
@ -405,10 +406,10 @@ draw_id_particles (void)
void void
glsl_R_DrawParticles (void) glsl_R_DrawParticles (void)
{ {
if (!r_particles->int_val || !numparticles) if (!r_particles->int_val || !r_psystem.numparticles)
return; return;
R_RunParticles (vr_data.frametime); R_RunParticles (vr_data.frametime);
if (0/*FIXME r_particles_style->int_val*/) { if (!r_psystem.points_only) {
draw_qf_particles (); draw_qf_particles ();
} else { } else {
draw_id_particles (); draw_id_particles ();
@ -448,3 +449,9 @@ glsl_R_Particles_Init_Cvars (void)
"Distance of the particle near clipping " "Distance of the particle near clipping "
"plane from the player."); "plane from the player.");
} }
psystem_t * __attribute__((const))//FIXME
glsl_ParticleSystem (void)
{
return &r_psystem;
}

View file

@ -36,10 +36,8 @@
#include "compat.h" #include "compat.h"
#include "r_internal.h" #include "r_internal.h"
unsigned int r_maxparticles, numparticles; psystem_t r_psystem; //FIXME singleton
particle_t *particles;
partparm_t *partparams;
const int **partramps;
vec3_t r_pright, r_pup, r_ppn; vec3_t r_pright, r_pup, r_ppn;
/* /*
@ -52,30 +50,31 @@ vec3_t r_pright, r_pup, r_ppn;
void void
R_MaxParticlesCheck (cvar_t *r_particles, cvar_t *r_particles_max) R_MaxParticlesCheck (cvar_t *r_particles, cvar_t *r_particles_max)
{ {
psystem_t *ps = &r_psystem;//FIXME
unsigned maxparticles = 0; unsigned maxparticles = 0;
if (r_particles && r_particles->int_val) { if (r_particles && r_particles->int_val) {
maxparticles = r_particles_max ? r_particles_max->int_val : 0; maxparticles = r_particles_max ? r_particles_max->int_val : 0;
} }
if (r_maxparticles == maxparticles) { if (ps->maxparticles == maxparticles) {
return; return;
} }
size_t size = sizeof (particle_t) + sizeof (partparm_t) size_t size = sizeof (particle_t) + sizeof (partparm_t)
+ sizeof (int *); + sizeof (int *);
if (particles) { if (ps->particles) {
Sys_Free (particles, r_maxparticles * size); Sys_Free (ps->particles, ps->maxparticles * size);
particles = 0; ps->particles = 0;
partparams = 0; ps->partparams = 0;
partramps = 0; ps->partramps = 0;
} }
r_maxparticles = maxparticles; ps->maxparticles = maxparticles;
if (r_maxparticles) { if (ps->maxparticles) {
particles = Sys_Alloc (r_maxparticles * size); ps->particles = Sys_Alloc (ps->maxparticles * size);
partparams = (partparm_t *) &particles[r_maxparticles]; ps->partparams = (partparm_t *) &ps->particles[ps->maxparticles];
partramps = (const int **) &partparams[r_maxparticles]; ps->partramps = (const int **) &ps->partparams[ps->maxparticles];
} }
R_ClearParticles (); R_ClearParticles ();
} }
@ -83,30 +82,32 @@ R_MaxParticlesCheck (cvar_t *r_particles, cvar_t *r_particles_max)
void void
R_ClearParticles (void) R_ClearParticles (void)
{ {
numparticles = 0; psystem_t *ps = &r_psystem;//FIXME
ps->numparticles = 0;
} }
void void
R_RunParticles (float dT) R_RunParticles (float dT)
{ {
psystem_t *ps = &r_psystem;//FIXME
vec4f_t gravity = {0, 0, -vr_data.gravity, 0}; vec4f_t gravity = {0, 0, -vr_data.gravity, 0};
unsigned j = 0; unsigned j = 0;
for (unsigned i = 0; i < numparticles; i++) { for (unsigned i = 0; i < ps->numparticles; i++) {
particle_t *p = &particles[i]; particle_t *p = &ps->particles[i];
partparm_t *parm = &partparams[i]; partparm_t *parm = &ps->partparams[i];
if (p->live <= 0 || p->ramp >= parm->ramp_max) { if (p->live <= 0 || p->ramp >= parm->ramp_max) {
continue; continue;
} }
const int *ramp = partramps[j]; const int *ramp = ps->partramps[j];
if (i > j) { if (i > j) {
particles[j] = *p; ps->particles[j] = *p;
partparams[j] = *parm; ps->partparams[j] = *parm;
partramps[j] = ramp; ps->partramps[j] = ramp;
} }
p = &particles[j]; p = &ps->particles[j];
parm = &partparams[j]; parm = &ps->partparams[j];
j += 1; j += 1;
p->pos += dT * p->vel; p->pos += dT * p->vel;
@ -117,5 +118,5 @@ R_RunParticles (float dT)
p->icolor = ramp[(int)p->ramp]; p->icolor = ramp[(int)p->ramp];
} }
} }
numparticles = j; ps->numparticles = j;
} }

View file

@ -58,8 +58,8 @@ R_DrawParticles (void)
R_RunParticles (vr_data.frametime); R_RunParticles (vr_data.frametime);
for (unsigned i = 0; i < numparticles; i++) { for (unsigned i = 0; i < r_psystem.numparticles; i++) {
particle_t *p = &particles[i]; particle_t *p = &r_psystem.particles[i];
D_DrawParticle (p); D_DrawParticle (p);
} }
} }
@ -97,3 +97,9 @@ R_Particles_Init_Cvars (void)
"Distance of the particle near clipping " "Distance of the particle near clipping "
"plane from the player."); "plane from the player.");
} }
psystem_t * __attribute__((const))//FIXME
sw_ParticleSystem (void)
{
return &r_psystem;
}

View file

@ -61,8 +61,8 @@ sw32_R_DrawParticles (void)
R_RunParticles (vr_data.frametime); R_RunParticles (vr_data.frametime);
for (unsigned i = 0; i < numparticles; i++) { for (unsigned i = 0; i < r_psystem.numparticles; i++) {
particle_t *p = &particles[i]; particle_t *p = &r_psystem.particles[i];
sw32_D_DrawParticle (p); sw32_D_DrawParticle (p);
} }
} }
@ -100,3 +100,9 @@ sw32_R_Particles_Init_Cvars (void)
"Distance of the particle near clipping " "Distance of the particle near clipping "
"plane from the player."); "plane from the player.");
} }
psystem_t * __attribute__((const))//FIXME
sw32_ParticleSystem (void)
{
return &r_psystem;
}

View file

@ -142,6 +142,7 @@ vid_render_funcs_t gl_vid_render_funcs = {
gl_Fog_Update, gl_Fog_Update,
gl_Fog_ParseWorldspawn, gl_Fog_ParseWorldspawn,
gl_ParticleSystem,
gl_R_Init, gl_R_Init,
gl_R_RenderFrame, gl_R_RenderFrame,
gl_R_ClearState, gl_R_ClearState,

View file

@ -141,6 +141,7 @@ vid_render_funcs_t glsl_vid_render_funcs = {
glsl_Fog_Update, glsl_Fog_Update,
glsl_Fog_ParseWorldspawn, glsl_Fog_ParseWorldspawn,
glsl_ParticleSystem,
glsl_R_Init, glsl_R_Init,
glsl_R_RenderFrame, glsl_R_RenderFrame,
glsl_R_ClearState, glsl_R_ClearState,

View file

@ -138,6 +138,7 @@ vid_render_funcs_t sw_vid_render_funcs = {
0, 0,
0, 0,
sw_ParticleSystem,
sw_R_Init, sw_R_Init,
R_RenderFrame, R_RenderFrame,
R_ClearState, R_ClearState,

View file

@ -143,6 +143,7 @@ vid_render_funcs_t sw32_vid_render_funcs = {
0, 0,
0, 0,
sw32_ParticleSystem,
sw32_R_Init, sw32_R_Init,
sw32_R_RenderFrame, sw32_R_RenderFrame,
sw32_R_ClearState, sw32_R_ClearState,

View file

@ -91,6 +91,12 @@ vulkan_Fog_ParseWorldspawn (struct plitem_s *worldspawn)
{ {
} }
static struct psystem_s *
vulkan_ParticleSystem (void)
{
return Vulkan_ParticleSystem (vulkan_ctx);
}
static void static void
vulkan_R_Init (void) vulkan_R_Init (void)
{ {
@ -663,6 +669,7 @@ vid_render_funcs_t vulkan_vid_render_funcs = {
vulkan_Fog_Update, vulkan_Fog_Update,
vulkan_Fog_ParseWorldspawn, vulkan_Fog_ParseWorldspawn,
vulkan_ParticleSystem,
vulkan_R_Init, vulkan_R_Init,
vulkan_R_RenderFrame, vulkan_R_RenderFrame,
vulkan_R_ClearState, vulkan_R_ClearState,

View file

@ -125,3 +125,9 @@ Vulkan_Particles_Shutdown (vulkan_ctx_t *ctx)
free (pctx->frames.a); free (pctx->frames.a);
free (pctx); free (pctx);
} }
psystem_t *__attribute__((pure))//FIXME?
Vulkan_ParticleSystem (vulkan_ctx_t *ctx)
{
return &ctx->particle_context->psystem; //FIXME support more
}