git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@681 e016b1c5-ed68-44aa-a2f7-31cac88cffde
158 lines
4.6 KiB
C++
158 lines
4.6 KiB
C++
// renderparticles.cpp
|
|
|
|
#include "cube.h"
|
|
|
|
const int MAXPARTICLES = 10500;
|
|
const int NUMPARTCUTOFF = 20;
|
|
struct particle { vec o, d; int fade, type; int millis; particle *next; int tex; }; // EDIT: AH
|
|
particle particles[MAXPARTICLES], *parlist = NULL, *parempty = NULL;
|
|
bool parinit = false;
|
|
|
|
VAR(maxparticles, 100, 2000, MAXPARTICLES-500);
|
|
|
|
void newparticle(vec &o, vec &d, int fade, int type, int tex = -1)
|
|
{
|
|
if(!parinit)
|
|
{
|
|
loopi(MAXPARTICLES)
|
|
{
|
|
particles[i].next = parempty;
|
|
parempty = &particles[i];
|
|
};
|
|
parinit = true;
|
|
};
|
|
if(parempty)
|
|
{
|
|
particle *p = parempty;
|
|
parempty = p->next;
|
|
p->o = o;
|
|
p->d = d;
|
|
p->fade = fade;
|
|
p->type = type;
|
|
p->millis = lastmillis;
|
|
p->next = parlist;
|
|
p->tex = tex;
|
|
parlist = p;
|
|
};
|
|
};
|
|
|
|
VAR(demotracking, 0, 0, 1);
|
|
VAR(particlesize, 20, 100, 500);
|
|
|
|
void render_particles(int time)
|
|
{
|
|
if(demoplayback && demotracking)
|
|
{
|
|
vec nom(0, 0, 0);
|
|
newparticle(player1->o, nom, 100000000, 4);
|
|
};
|
|
|
|
if(!parlist) return;
|
|
|
|
glDepthMask(GL_FALSE);
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_SRC_ALPHA);
|
|
glDisable(GL_FOG);
|
|
|
|
static Texture *parttex[2] = {NULL, NULL};
|
|
if(!parttex[0]) parttex[0] = textureload("packages/misc/base.png");
|
|
if(!parttex[1]) parttex[1] = textureload("packages/misc/smoke.png");
|
|
static struct parttype { float r, g, b; int gr, tex; float sz; } parttypes[] =
|
|
{
|
|
{ 0.2f, 0.2f, 0.2f, 2, 0, 0.06f }, // yellow: sparks
|
|
{ 0.5f, 0.5f, 0.5f, 20, 1, 0.15f }, // grey: small smoke
|
|
{ 0.2f, 0.2f, 1.0f, 20, 0, 0.08f }, // blue: edit mode entities
|
|
{ 1.0f, 0.1f, 0.1f, 1, 1, 0.06f }, // red: blood spats
|
|
{ 1.0f, 0.1f, 0.1f, 0, 1, 0.2f }, // red: demotrack
|
|
|
|
// { 1.0f, 0.8f, 0.8f, 20, 6, 1.2f }, // yellow: fireball1
|
|
// { 0.5f, 0.5f, 0.5f, 20, 1, 0.6f }, // grey: big smoke
|
|
// { 1.0f, 1.0f, 1.0f, 20, 8, 1.2f }, // blue: fireball2
|
|
// { 1.0f, 1.0f, 1.0f, 20, 9, 1.2f }, // green: fireball3
|
|
// { 1.0f, 1.0f, 1.0f, 2, 3, 0.06f }, //
|
|
};
|
|
|
|
int numrender = 0;
|
|
|
|
parttype *lastpt = NULL;
|
|
for(particle *p, **pp = &parlist; (p = *pp);)
|
|
{
|
|
// if(p->type==9 && p->tex!=-1) parttypes[9].tex = p->tex; // hack, AH
|
|
parttype &pt = parttypes[p->type];
|
|
|
|
if(&pt!=lastpt)
|
|
{
|
|
if(!lastpt || pt.tex!=lastpt->tex)
|
|
{
|
|
if(lastpt) glEnd();
|
|
glBindTexture(GL_TEXTURE_2D, parttex[pt.tex]->id);
|
|
glBegin(GL_QUADS);
|
|
};
|
|
if(!lastpt || pt.r!=lastpt->r || pt.g!=lastpt->g || pt.b!=lastpt->b)
|
|
glColor3f(pt.r, pt.g, pt.b);
|
|
lastpt = &pt;
|
|
};
|
|
|
|
float sz = pt.sz*particlesize/100.0f;
|
|
// perf varray?
|
|
glTexCoord2i(0, 1); glVertex3f(p->o.x+(-camright.x+camup.x)*sz, p->o.z+(-camright.y+camup.y)*sz, p->o.y+(-camright.z+camup.z)*sz);
|
|
glTexCoord2i(1, 1); glVertex3f(p->o.x+( camright.x+camup.x)*sz, p->o.z+( camright.y+camup.y)*sz, p->o.y+( camright.z+camup.z)*sz);
|
|
glTexCoord2i(1, 0); glVertex3f(p->o.x+( camright.x-camup.x)*sz, p->o.z+( camright.y-camup.y)*sz, p->o.y+( camright.z-camup.z)*sz);
|
|
glTexCoord2i(0, 0); glVertex3f(p->o.x+(-camright.x-camup.x)*sz, p->o.z+(-camright.y-camup.y)*sz, p->o.y+(-camright.z-camup.z)*sz);
|
|
xtraverts += 4;
|
|
|
|
if(numrender++>maxparticles || (p->fade -= time)<0)
|
|
{
|
|
*pp = p->next;
|
|
p->next = parempty;
|
|
parempty = p;
|
|
}
|
|
else
|
|
{
|
|
if(pt.gr) p->o.z -= ((lastmillis-p->millis)/3.0f)*curtime/(pt.gr*10000);
|
|
vec a = p->d;
|
|
a.mul(time/20000.0f);
|
|
p->o.add(a);
|
|
pp = &p->next;
|
|
};
|
|
};
|
|
|
|
if(lastpt) glEnd();
|
|
|
|
glEnable(GL_FOG);
|
|
glDisable(GL_BLEND);
|
|
glDepthMask(GL_TRUE);
|
|
};
|
|
|
|
void particle_splash(int type, int num, int fade, vec &p)
|
|
{
|
|
loopi(num)
|
|
{
|
|
const int radius = type==5 ? 50 : 150;
|
|
int x, y, z;
|
|
do
|
|
{
|
|
x = rnd(radius*2)-radius;
|
|
y = rnd(radius*2)-radius;
|
|
z = rnd(radius*2)-radius;
|
|
}
|
|
while(x*x+y*y+z*z>radius*radius);
|
|
vec d((float)x, (float)y, (float)z);
|
|
newparticle(p, d, rnd(fade*3), type);
|
|
};
|
|
};
|
|
|
|
void particle_trail(int type, int fade, vec &s, vec &e)
|
|
{
|
|
vec v;
|
|
float d = e.dist(s, v);
|
|
v.div(d*2+0.1f);
|
|
vec p = s;
|
|
loopi((int)d*2)
|
|
{
|
|
p.add(v);
|
|
vec d((float)(rnd(11)-5), (float)(rnd(11)-5), (float)(rnd(11)-5));
|
|
newparticle(p, d, rnd(fade)+fade, type);
|
|
};
|
|
};
|