Just a massive speedup to gl particles. Enjoy.

(Thanks to LordHavoc for prodding me to use glDrawElements, and munge all the particle textures into 1. Code mine, suggestions his)
This commit is contained in:
Ragnvald Maartmann-Moe IV 2001-12-19 04:03:57 +00:00
parent 0c4d220e8e
commit c764ddc64a
13 changed files with 233 additions and 70 deletions

View file

@ -120,7 +120,7 @@ QFGL_NEED (void, glDisable, (GLenum cap));
QFGL_NEED (void, glDisableClientState, (GLenum cap));
QFGL_NEED (void, glDrawArrays, (GLenum mode, GLint first, GLsizei count));
QFGL_NEED (void, glDrawBuffer, (GLenum mode));
QFGL_DONT_NEED (void, glDrawElements, (GLenum mode, GLsizei count, GLenum type, const GLvoid * indices));
QFGL_NEED (void, glDrawElements, (GLenum mode, GLsizei count, GLenum type, const GLvoid * indices));
QFGL_DONT_NEED (void, glDrawPixels, (GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * pixels));
QFGL_DONT_NEED (void, glDrawRangeElements, (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid * indices));
QFGL_DONT_NEED (void, glEdgeFlag, (GLboolean flag));

View file

@ -39,9 +39,12 @@ extern int gl_lightmap_format;
extern int gl_filter_min;
extern int gl_filter_max;
extern int part_tex;
/*
extern int part_tex_dot;
extern int part_tex_smoke;
extern int part_tex_spark;
*/
void GL_Upload8 (byte *data, int width, int height, qboolean mipmap, qboolean alpha);
void GL_Upload8_EXT (byte *data, int width, int height, qboolean mipmap, qboolean alpha);

View file

@ -56,6 +56,7 @@ extern void R_DrawLine (polyvert_t *polyvert0, polyvert_t *polyvert1);
extern int cachewidth;
extern byte *cacheblock;
extern int screenwidth;
extern int r_init;
extern float pixelAspect;

View file

@ -39,11 +39,11 @@
#include "QF/GL/types.h"
typedef struct varray_t2f_c4f_v3f_s {
typedef struct varray_t2f_c4ub_v2f_s {
GLfloat texcoord[2];
GLfloat color[4];
GLfloat vertex[3];
} varray_t2f_c4f_v3f_t;
GLubyte color[4];
GLfloat vertex[2];
} varray_t2f_c4ub_v2f_t;
typedef struct varray_t2f_c4ub_v3f_s {
GLfloat texcoord[2];
@ -58,7 +58,14 @@ typedef struct varray_t2f_c4f_n3f_v3f_s {
GLfloat vertex[3];
} varray_t2f_c4f_n3f_v3f_t;
#define MAX_VARRAY_VERTS 10000
extern varray_t2f_c4ub_v3f_t varray[MAX_VARRAY_VERTS];
//#define MAX_VARRAY_VERTS 10000
extern int vaelements;
extern varray_t2f_c4ub_v3f_t *particleVertexArray;
extern int pVAsize;
//extern varray_t2f_c4ub_v3f_t *modelVertexArray
//extern varray_t2f_v2f_t *textVertexArray;
#endif // __qf_varrays_h

View file

@ -59,6 +59,14 @@ static const char rcsid[] =
int ramp[8] = { 0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x65, 0x63, 0x61 };
int part_tex_dot = 0;
int part_tex_spark = 1;
int part_tex_smoke = 2;
int pVAsize;
int *pVAindices;
varray_t2f_c4ub_v3f_t *particleVertexArray;
inline static void
particle_new (ptype_t type, int texnum, vec3_t org, float scale, vec3_t vel,
@ -108,6 +116,41 @@ R_ClearParticles (void)
numparticles = 0;
}
void
R_InitParticles (void)
{
int i;
if (r_maxparticles && r_init) {
if (vaelements > 3)
pVAsize = min (vaelements - (vaelements % 4), r_maxparticles * 4);
else
pVAsize = r_maxparticles * 4;
Con_Printf ("%i maximum vertex elements.\n", pVAsize);
if (particleVertexArray)
free (particleVertexArray);
particleVertexArray = (varray_t2f_c4ub_v3f_t *)
calloc (pVAsize, sizeof (varray_t2f_c4ub_v3f_t));
qfglInterleavedArrays (GL_T2F_C4UB_V3F, 0, particleVertexArray);
if (pVAindices)
free (pVAindices);
pVAindices = (int *) calloc (pVAsize, sizeof (int));
for (i = 0; i < pVAsize; i++)
pVAindices[i] = i;
} else {
if (particleVertexArray) {
free (particleVertexArray);
particleVertexArray = 0;
}
if (pVAindices) {
free (pVAindices);
pVAindices = 0;
}
}
}
void
R_ReadPointFile_f (void)
{
@ -694,6 +737,43 @@ R_ParticleExplosion_EE (vec3_t org)
128 + (rand () & 63));
}
void
R_TeleportSplash_EE (vec3_t org)
{
float vel;
int rnd, i, j, k;
int l = 896;
vec3_t dir, porg, pvel;
if (numparticles + l >= r_maxparticles) {
return;
} // else if (numparticles + l >= r_maxparticles) {
// l = r_maxparticles - numparticles;
// }
for (i = -16; i < 16; i += 4) {
dir[1] = i * 8;
for (j = -16; j < 16; j += 4) {
dir[0] = j * 8;
for (k = -24; k < 32; k += 4) {
dir[2] = k * 8;
rnd = rand ();
porg[0] = org[0] + i + (rnd & 3);
porg[1] = org[1] + j + ((rnd >> 2) & 3);
porg[2] = org[2] + k + ((rnd >> 4) & 3);
VectorNormalize (dir);
vel = 50 + ((rnd >> 6) & 63);
VectorScale (dir, vel, pvel);
particle_new (pt_grav, part_tex_spark, porg, 0.6, pvel,
(r_realtime + 0.2 + (rand () & 15) * 0.01),
rand () & 255, 255);
}
}
}
}
void
R_RocketTrail_EE (entity_t *ent)
{
@ -796,6 +876,8 @@ R_DrawParticles (void)
fire_alpha, fire_scale, smoke_alpha, smoke_scale,
smokecloud_alpha, smokecloud_org, smokecloud_scale;
int activeparticles, maxparticle, j, k;
unsigned int vacount;
varray_t2f_c4ub_v3f_t *VA;
particle_t *part;
vec3_t up_scale, right_scale, up_right_scale, down_right_scale;
@ -804,15 +886,7 @@ R_DrawParticles (void)
// LordHavoc: particles should not affect zbuffer
qfglDepthMask (GL_FALSE);
varray[0].texcoord[0] = 0;
varray[0].texcoord[1] = 1;
varray[1].texcoord[0] = 0;
varray[1].texcoord[1] = 0;
varray[2].texcoord[0] = 1;
varray[2].texcoord[1] = 0;
varray[3].texcoord[0] = 1;
varray[3].texcoord[1] = 1;
qfglBindTexture (GL_TEXTURE_2D, part_tex);
grav = (fast_grav = r_frametime * 800.0) * 0.05;
dvel = bloodcloud_scale = smoke_scale = r_frametime * 4.0;
@ -828,6 +902,8 @@ R_DrawParticles (void)
minparticledist = DotProduct (r_refdef.vieworg, vpn) + 32.0;
activeparticles = 0;
vacount = 0;
VA = particleVertexArray;
maxparticle = -1;
j = 0;
@ -836,15 +912,46 @@ R_DrawParticles (void)
// Note, we must still do physics and such on them.
if (!(DotProduct (part->org, vpn) < minparticledist)) {
at = (byte *) & d_8to24table[(byte) part->color];
VA[0].color[0] = at[0];
VA[0].color[1] = at[1];
VA[0].color[2] = at[2];
VA[0].color[3] = part->alpha;
memcpy (VA[1].color, VA[0].color, sizeof(VA[0].color));
memcpy (VA[2].color, VA[0].color, sizeof(VA[0].color));
memcpy (VA[3].color, VA[0].color, sizeof(VA[0].color));
varray[0].color[0] = at[0];
varray[0].color[1] = at[1];
varray[0].color[2] = at[2];
varray[0].color[3] = part->alpha;
memcpy (varray[1].color, varray[0].color, sizeof(varray[0].color));
memcpy (varray[2].color, varray[0].color, sizeof(varray[0].color));
memcpy (varray[3].color, varray[0].color, sizeof(varray[0].color));
switch (part->tex) {
case 0:
VA[0].texcoord[0] = 0;
VA[0].texcoord[1] = 0.5;
VA[1].texcoord[0] = 0;
VA[1].texcoord[1] = 0;
VA[2].texcoord[0] = 0.5;
VA[2].texcoord[1] = 0;
VA[3].texcoord[0] = 0.5;
VA[3].texcoord[1] = 0.5;
break;
case 1:
VA[0].texcoord[0] = 0.5;
VA[0].texcoord[1] = 0.5;
VA[1].texcoord[0] = 0.5;
VA[1].texcoord[1] = 0;
VA[2].texcoord[0] = 1;
VA[2].texcoord[1] = 0;
VA[3].texcoord[0] = 1;
VA[3].texcoord[1] = 0.5;
break;
case 2:
VA[0].texcoord[0] = 0;
VA[0].texcoord[1] = 1;
VA[1].texcoord[0] = 0;
VA[1].texcoord[1] = 0.5;
VA[2].texcoord[0] = 0.5;
VA[2].texcoord[1] = 0.5;
VA[3].texcoord[0] = 0.5;
VA[3].texcoord[1] = 1;
break;
}
scale = part->scale;
@ -854,13 +961,19 @@ R_DrawParticles (void)
VectorAdd (right_scale, up_scale, up_right_scale);
VectorSubtract (right_scale, up_scale, down_right_scale);
VectorAdd (part->org, up_right_scale, varray[0].vertex);
VectorAdd (part->org, down_right_scale, varray[1].vertex);
VectorSubtract (part->org, up_right_scale, varray[2].vertex);
VectorSubtract (part->org, down_right_scale, varray[3].vertex);
VectorAdd (part->org, up_right_scale, VA[0].vertex);
VectorAdd (part->org, down_right_scale, VA[1].vertex);
VectorSubtract (part->org, up_right_scale, VA[2].vertex);
VectorSubtract (part->org, down_right_scale, VA[3].vertex);
qfglBindTexture (GL_TEXTURE_2D, part->tex);
qfglDrawArrays (GL_QUADS, 0, 4);
VA += 4;
vacount += 4;
if (vacount + 4 > pVAsize) {
qfglDrawElements (GL_QUADS, vacount, GL_UNSIGNED_INT,
pVAindices);
vacount = 0;
VA = particleVertexArray;
}
}
VectorMA (part->org, r_frametime, part->vel, part->org);
@ -925,10 +1038,13 @@ R_DrawParticles (void)
activeparticles++;
}
}
if (vacount)
qfglDrawElements (GL_QUADS, vacount, GL_UNSIGNED_INT, pVAindices);
k = 0;
while (maxparticle >= activeparticles) {
*freeparticles[k++] = particles[maxparticle--];
while (maxparticle >= activeparticles &&
while (maxparticle >= activeparticles &&
particles[maxparticle].die <= r_realtime)
maxparticle--;
}
@ -944,10 +1060,12 @@ r_easter_eggs_f (cvar_t *var)
if (easter_eggs) {
if (easter_eggs->int_val) {
R_ParticleExplosion = R_ParticleExplosion_EE;
R_TeleportSplash = R_TeleportSplash_EE;
R_RocketTrail = R_RocketTrail_EE;
R_GrenadeTrail = R_GrenadeTrail_EE;
} else {
R_ParticleExplosion = R_ParticleExplosion_QF;
R_TeleportSplash = R_TeleportSplash_QF;
R_RocketTrail = R_RocketTrail_QF;
R_GrenadeTrail = R_GrenadeTrail_QF;
}

View file

@ -30,6 +30,12 @@ static const char rcsid[] =
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include <stdlib.h>
@ -39,23 +45,42 @@ static const char rcsid[] =
#include "QF/GL/qf_noisetextures.h"
#include "QF/GL/qf_vid.h"
/*
int part_tex_dot;
int part_tex_smoke;
int part_tex_spark;
*/
int part_tex;
static void
GDT_InitParticleTexture (void)
{
byte data[64][64][2];
memset (data, 0, sizeof (data));
part_tex = texture_extension_number++;
qfglBindTexture (GL_TEXTURE_2D, part_tex);
qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
qfglTexImage2D (GL_TEXTURE_2D, 0, 2, 64, 64, 0, GL_LUMINANCE_ALPHA,
GL_UNSIGNED_BYTE, data);
}
static void
GDT_InitDotParticleTexture (void)
{
byte data[16][16][2];
byte data[32][32][2];
int x, y, dx2, dy, d;
for (x = 0; x < 16; x++) {
dx2 = x - 8;
for (x = 0; x < 32; x++) {
dx2 = x - 16;
dx2 *= dx2;
for (y = 0; y < 16; y++) {
dy = y - 8;
d = 255 - 4 * (dx2 + (dy * dy));
for (y = 0; y < 32; y++) {
dy = y - 16;
d = 255 - (dx2 + (dy * dy));
if (d <= 0) {
d = 0;
data[y][x][0] = 0;
@ -65,26 +90,22 @@ GDT_InitDotParticleTexture (void)
data[y][x][1] = (byte) d;
}
}
part_tex_dot = texture_extension_number++;
qfglBindTexture (GL_TEXTURE_2D, part_tex_dot);
qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
qfglTexImage2D (GL_TEXTURE_2D, 0, 2, 16, 16, 0, GL_LUMINANCE_ALPHA,
GL_UNSIGNED_BYTE, data);
qfglTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, 32, 32, GL_LUMINANCE_ALPHA,
GL_UNSIGNED_BYTE, data);
}
static void
GDT_InitSparkParticleTexture (void)
{
byte data[16][16][2];
byte data[32][32][2];
int x, y, dx2, dy, d;
for (x = 0; x < 16; x++) {
dx2 = 8 - abs (x - 8);
for (x = 0; x < 32; x++) {
dx2 = 16 - abs (x - 16);
dx2 *= dx2;
for (y = 0; y < 16; y++) {
dy = 8 - abs (y - 8);
d = 3 * (dx2 + dy * dy) - 100;
for (y = 0; y < 32; y++) {
dy = 16 - abs (y - 16);
d = (dx2 + dy * dy) - 200;
if (d > 255)
d = 255;
if (d < 1) {
@ -96,12 +117,8 @@ GDT_InitSparkParticleTexture (void)
data[y][x][1] = (byte) d;
}
}
part_tex_spark = texture_extension_number++;
qfglBindTexture (GL_TEXTURE_2D, part_tex_spark);
qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
qfglTexImage2D (GL_TEXTURE_2D, 0, 2, 16, 16, 0, GL_LUMINANCE_ALPHA,
GL_UNSIGNED_BYTE, data);
qfglTexSubImage2D (GL_TEXTURE_2D, 0, 32, 0, 32, 32, GL_LUMINANCE_ALPHA,
GL_UNSIGNED_BYTE, data);
}
static void
@ -133,17 +150,14 @@ GDT_InitSmokeParticleTexture (void)
}
}
}
part_tex_smoke = texture_extension_number++;
qfglBindTexture (GL_TEXTURE_2D, part_tex_smoke);
qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
qfglTexImage2D (GL_TEXTURE_2D, 0, 2, 32, 32, 0, GL_LUMINANCE_ALPHA,
GL_UNSIGNED_BYTE, data);
qfglTexSubImage2D (GL_TEXTURE_2D, 0, 0, 32, 32, 32, GL_LUMINANCE_ALPHA,
GL_UNSIGNED_BYTE, data);
}
void
GDT_Init (void)
{
GDT_InitParticleTexture ();
GDT_InitDotParticleTexture ();
GDT_InitSparkParticleTexture ();
GDT_InitSmokeParticleTexture ();

View file

@ -59,7 +59,7 @@ static const char rcsid[] =
#include "r_local.h"
#include "varrays.h"
varray_t2f_c4ub_v3f_t varray[MAX_VARRAY_VERTS];
int r_init = 0;
qboolean VID_Is8bit (void);
void R_InitBubble (void);
@ -159,15 +159,12 @@ R_Init (void)
texture_extension_number = Skin_Init_Textures (texture_extension_number);
r_init = 1;
R_InitParticles ();
qfglEnableClientState (GL_COLOR_ARRAY);
qfglEnableClientState (GL_VERTEX_ARRAY);
qfglEnableClientState (GL_TEXTURE_COORD_ARRAY);
// qfglInterleavedArrays (GL_T2F_C4UB_N3F_V3F, 0, varray); // Models w/normals
// qfglInterleavedArrays (GL_T2F_C4UB_V3F, 0, varray); // Polys w/o normals
qfglTexCoordPointer (2, GL_FLOAT, sizeof(varray[0]), varray[0].texcoord);
qfglColorPointer (4, GL_UNSIGNED_BYTE, sizeof(varray[0]), varray[0].color);
qfglVertexPointer (3, GL_FLOAT, sizeof(varray[0]), varray[0].vertex);
}
void

View file

@ -106,7 +106,10 @@ R_MaxParticlesCheck (cvar_t *r_particles, cvar_t *r_particles_max)
sizeof (particle_t *));
}
R_ClearParticles();
R_ClearParticles ();
if (r_init)
R_InitParticles ();
}
void

View file

@ -66,6 +66,7 @@ int r_pixbytes = 1;
float r_aliasuvscale = 1.0;
int r_outofsurfaces;
int r_outofedges;
int r_init = 0;
qboolean r_dowarp, r_dowarpold, r_viewchanged;

View file

@ -49,6 +49,10 @@ int ramp2[8] = { 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66 };
int ramp3[8] = { 0x6d, 0x6b, 6, 5, 4, 3 };
void
R_InitParticles (void)
{
}
void
R_ClearParticles (void)

View file

@ -67,6 +67,7 @@ int r_pixbytes = 1;
float r_aliasuvscale = 1.0;
int r_outofsurfaces;
int r_outofedges;
int r_init = 0;
qboolean r_dowarp, r_dowarpold, r_viewchanged;

View file

@ -49,6 +49,11 @@ int ramp2[8] = { 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66 };
int ramp3[8] = { 0x6d, 0x6b, 6, 5, 4, 3 };
void
R_InitParticles (void)
{
}
void
R_ClearParticles (void)
{

View file

@ -69,6 +69,7 @@ const char *gl_renderer;
const char *gl_vendor;
const char *gl_version;
int vaelements;
int texture_extension_number = 1;
int gl_filter_min = GL_LINEAR_MIPMAP_NEAREST;
int gl_filter_max = GL_LINEAR;
@ -88,7 +89,6 @@ cvar_t *vid_mode;
cvar_t *vid_use8bit;
static void
gl_multitexture_f (cvar_t *var)
{
@ -155,6 +155,13 @@ CheckMultiTextureExtensions (void)
}
}
void
CheckVertexArraySize (void)
{
qfglGetIntegerv (GL_MAX_ELEMENTS_VERTICES, &vaelements);
// qfglGetIntegerv (MAX_ELEMENTS_INDICES, *vaindices);
}
void
VID_SetPalette (unsigned char *palette)
{
@ -280,6 +287,8 @@ GL_Init_Common (void)
qfglTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
CheckMultiTextureExtensions ();
CheckVertexArraySize ();
GL_Common_Init_Cvars ();
}