Cube  Artifact [21833af7d6]

Artifact 21833af7d6f54f6344b7fc494a7a07c68057e8bd6890cb29d74cece36cef549e:


// 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; };
particle particles[MAXPARTICLES], *parlist = NULL, *parempty = NULL;
bool parinit = false;

VARP(maxparticles, 100, 2000, MAXPARTICLES-500);

void newparticle(vec &o, vec &d, int fade, int type)
{
    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;
        parlist = p;
    };
};

VAR(demotracking, 0, 0, 1);
VARP(particlesize, 20, 100, 500); 

vec right, up;

void setorient(vec &r, vec &u) { right = r; up = u; };

void render_particles(int time)
{
	if(demoplayback && demotracking)
	{
		vec nom = { 0, 0, 0 };
		newparticle(player1->o, nom, 100000000, 8);
	};

    glDepthMask(GL_FALSE);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_SRC_ALPHA);
    glDisable(GL_FOG);
    
    struct parttype { float r, g, b; int gr, tex; float sz; } parttypes[] =
    {
        { 0.7f, 0.6f, 0.3f, 2,  3, 0.06f }, // yellow: sparks 
        { 0.5f, 0.5f, 0.5f, 20, 7, 0.15f }, // grey:   small smoke
        { 0.2f, 0.2f, 1.0f, 20, 3, 0.08f }, // blue:   edit mode entities
        { 1.0f, 0.1f, 0.1f, 1,  7, 0.06f }, // red:    blood spats
        { 1.0f, 0.8f, 0.8f, 20, 6, 1.2f  }, // yellow: fireball1
        { 0.5f, 0.5f, 0.5f, 20, 7, 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, 0.1f, 0.1f, 0,  7, 0.2f  }, // red:    demotrack
    };
    
    int numrender = 0;
    
    for(particle *p, **pp = &parlist; p = *pp;)
    {       
        parttype *pt = &parttypes[p->type];

        glBindTexture(GL_TEXTURE_2D, pt->tex);  
        glBegin(GL_QUADS);
        
        glColor3d(pt->r, pt->g, pt->b);
        float sz = pt->sz*particlesize/100.0f; 
        // perf varray?
        glTexCoord2f(0.0, 1.0); glVertex3d(p->o.x+(-right.x+up.x)*sz, p->o.z+(-right.y+up.y)*sz, p->o.y+(-right.z+up.z)*sz);
        glTexCoord2f(1.0, 1.0); glVertex3d(p->o.x+( right.x+up.x)*sz, p->o.z+( right.y+up.y)*sz, p->o.y+( right.z+up.z)*sz);
        glTexCoord2f(1.0, 0.0); glVertex3d(p->o.x+( right.x-up.x)*sz, p->o.z+( right.y-up.y)*sz, p->o.y+( right.z-up.z)*sz);
        glTexCoord2f(0.0, 0.0); glVertex3d(p->o.x+(-right.x-up.x)*sz, p->o.z+(-right.y-up.y)*sz, p->o.y+(-right.z-up.z)*sz);
        glEnd();
        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;
            vmul(a,time);
            vdiv(a,20000.0f);
            vadd(p->o, a);
            pp = &p->next;
        };
    };

    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)
{
    vdist(d, v, s, e);
    vdiv(v, d*2+0.1f);
    vec p = s;
    loopi((int)d*2)
    {
        vadd(p, v);
        vec d = { float(rnd(11)-5), float(rnd(11)-5), float(rnd(11)-5) };
        newparticle(p, d, rnd(fade)+fade, type);
    };
};