From 25e6865fa5fd7f26c6201b4a2974361c7dc3a1a6 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 25 Mar 2022 14:48:01 +0900 Subject: [PATCH] [glsl] Update particle arrays when maximum changes The cvar setup for particles is a bit wonky in that the arrays get initialized using the default max particle count but never updated. Though things could be improved some more, this solution works (and has been more or less copied to gl, but I couldn't reproduce the crash there, or even the valgrind error). --- libs/video/renderer/gl/gl_dyn_part.c | 20 +++++++--- libs/video/renderer/glsl/glsl_particles.c | 45 ++++++++++++++--------- 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/libs/video/renderer/gl/gl_dyn_part.c b/libs/video/renderer/gl/gl_dyn_part.c index b64cd9481..151a2ed72 100644 --- a/libs/video/renderer/gl/gl_dyn_part.c +++ b/libs/video/renderer/gl/gl_dyn_part.c @@ -63,23 +63,23 @@ static int pVAsize; static int *pVAindices; static varray_t2f_c4ub_v3f_t *particleVertexArray; -void -gl_R_InitParticles (void) +static void +alloc_arrays (psystem_t *ps) { int i; - if (r_psystem.maxparticles && r_init) { + if (ps->maxparticles && r_init) { if (vaelements) { partUseVA = 0; - pVAsize = r_psystem.maxparticles * 4; + pVAsize = ps->maxparticles * 4; Sys_MaskPrintf (SYS_dev, "Particles: Vertex Array use disabled.\n"); } else { if (vaelements > 3) pVAsize = min ((unsigned int) (vaelements - (vaelements % 4)), - r_psystem.maxparticles * 4); + ps->maxparticles * 4); else if (vaelements >= 0) - pVAsize = r_psystem.maxparticles * 4; + pVAsize = ps->maxparticles * 4; Sys_MaskPrintf (SYS_dev, "Particles: %i maximum vertex elements.\n", pVAsize); @@ -109,6 +109,12 @@ gl_R_InitParticles (void) } } +void +gl_R_InitParticles (void) +{ + alloc_arrays (&r_psystem); +} + void gl_R_DrawParticles (psystem_t *psystem) { @@ -238,12 +244,14 @@ static void r_particles_f (cvar_t *var) { R_MaxParticlesCheck (var, r_particles_max); + alloc_arrays (&r_psystem); } static void r_particles_max_f (cvar_t *var) { R_MaxParticlesCheck (r_particles, var); + alloc_arrays (&r_psystem); } void diff --git a/libs/video/renderer/glsl/glsl_particles.c b/libs/video/renderer/glsl/glsl_particles.c index 74957ce3e..89645e72c 100644 --- a/libs/video/renderer/glsl/glsl_particles.c +++ b/libs/video/renderer/glsl/glsl_particles.c @@ -63,6 +63,7 @@ # define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 #endif +static uint32_t maxparticles; static GLushort *pVAindices; static partvert_t *particleVertexArray; @@ -130,11 +131,34 @@ static struct { {"fog", 1}, }; +static void +alloc_arrays (psystem_t *ps) +{ + if (ps->maxparticles > maxparticles) { + maxparticles = ps->maxparticles; + if (particleVertexArray) + free (particleVertexArray); + particleVertexArray = calloc (ps->maxparticles * 4, + sizeof (partvert_t)); + + if (pVAindices) + free (pVAindices); + pVAindices = calloc (ps->maxparticles * 6, sizeof (GLushort)); + for (uint32_t i = 0; i < ps->maxparticles; i++) { + pVAindices[i * 6 + 0] = i * 4 + 0; + pVAindices[i * 6 + 1] = i * 4 + 1; + pVAindices[i * 6 + 2] = i * 4 + 2; + pVAindices[i * 6 + 3] = i * 4 + 0; + pVAindices[i * 6 + 4] = i * 4 + 2; + pVAindices[i * 6 + 5] = i * 4 + 3; + } + } +} + void glsl_R_InitParticles (void) { shader_t *vert_shader, *frag_shader; - unsigned i; int vert; int frag; float v[2] = {0, 0}; @@ -196,22 +220,7 @@ glsl_R_InitParticles (void) GL_UNSIGNED_BYTE, tex->data); free (tex); - if (particleVertexArray) - free (particleVertexArray); - particleVertexArray = calloc (r_psystem.maxparticles * 4, - sizeof (partvert_t)); - - if (pVAindices) - free (pVAindices); - pVAindices = calloc (r_psystem.maxparticles * 6, sizeof (GLushort)); - for (i = 0; i < r_psystem.maxparticles; i++) { - pVAindices[i * 6 + 0] = i * 4 + 0; - pVAindices[i * 6 + 1] = i * 4 + 1; - pVAindices[i * 6 + 2] = i * 4 + 2; - pVAindices[i * 6 + 3] = i * 4 + 0; - pVAindices[i * 6 + 4] = i * 4 + 2; - pVAindices[i * 6 + 5] = i * 4 + 3; - } + alloc_arrays (&r_psystem); } static void @@ -426,12 +435,14 @@ static void r_particles_f (cvar_t *var) { R_MaxParticlesCheck (var, r_particles_max); + alloc_arrays (&r_psystem); } static void r_particles_max_f (cvar_t *var) { R_MaxParticlesCheck (r_particles, var); + alloc_arrays (&r_psystem); } void