//---------------------------------------------------------------------------
#pragma hdrstop
#include "WEAPON_FLAMETHROWER.h"
//#include "FC_OPENGL.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
void __fastcall drawbillboardF(float cx, float cy, float cz, float size)
{
double m_PickInfo_ModelView[16];// of ;
t3dpoint Pos;
glGetDoublev(GL_MODELVIEW_MATRIX, m_PickInfo_ModelView);
BillboardX.x = m_PickInfo_ModelView[0];
BillboardX.y = m_PickInfo_ModelView[4];
BillboardX.z = m_PickInfo_ModelView[8];
BillboardY.x = m_PickInfo_ModelView[1];
BillboardY.y = m_PickInfo_ModelView[5];
BillboardY.z = m_PickInfo_ModelView[9];
glBegin(GL_QUADS);
glTexCoord2f(0.0, 1.0);
Pos.x = cx-BillboardX.x*size+BillboardY.x*size;
Pos.y = cy-BillboardX.y*size+BillboardY.y*size;
Pos.z = cz-BillboardX.z*size+BillboardY.z*size;
glVertex3f(Pos.x,Pos.y,Pos.z);
glTexCoord2f(1.0, 1.0);
Pos.x = cx+BillboardX.x*size+BillboardY.x*size;
Pos.y = cy+BillboardX.y*size+BillboardY.y*size;
Pos.z = cz+BillboardX.z*size+BillboardY.z*size;
glVertex3f(Pos.x,Pos.y,Pos.z);
glTexCoord2f(1.0, 0.0);
Pos.x = cx+BillboardX.x*size-BillboardY.x*size;
Pos.y = cy+BillboardX.y*size-BillboardY.y*size;
Pos.z = cz+BillboardX.z*size-BillboardY.z*size;
glVertex3f(Pos.x,Pos.y,Pos.z);
glTexCoord2f(0.0, 0.0);
Pos.x = cx-BillboardX.x*size-BillboardY.x*size;
Pos.y = cy-BillboardX.y*size-BillboardY.y*size;
Pos.z = cz-BillboardX.z*size-BillboardY.z*size;
glVertex3f(Pos.x,Pos.y,Pos.z);
glEnd();
}
void __fastcall tflamethrower::DRAW()
{
int i;
float d; t3dpoint v;
make_next_frame();
//glpushmatrix();
glColor4f(1,1,1,0.7);
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
//
glBlendFunc(GL_ONE,GL_ONE);
//glEnable(GL_TEXTURE_2D);
for (i = 0; i < 129; i++)
if (particles[i].draw == true)
{
// glbindtexture(GL_TEXTURE_2D,sprite.animtextures[particles[i].frame]);
// particles[i].size = 300.0f;
drawbillboardF(particles[i].pos.x,particles[i].pos.y,particles[i].pos.z,particles[i].size);
//glrotate(-angle,1,0,0);
// glmatrixmode(GL_TEXTURE);glrotate(-angle,0,1,0); glmatrixmode(GL_MODELVIEW);
//glpopmatrix();
}
//glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
}
__fastcall tflamethrower::tflamethrower()
{
sprite = new tglanimtexture;
}
__fastcall tflamethrower::~tflamethrower()
{
sprite->free();
delete sprite;
}
void __fastcall tflamethrower::load(AnsiString filename)
{
sprite->loadtex(filename);
}
void __fastcall tflamethrower::make_next_frame()
{
try {
int i;
t3dpoint k;
for (i = 0; i < 129; i++)
if (particles[i].draw == true)
{
k.x = 100000000.0f*(sin(particles[i].glop*imopi)*cos(particles[i].heading*imopi));
k.z = 100000000.0f*(cos(particles[i].glop*imopi)*cos(particles[i].heading*imopi));
k.y = 100000000.0f*(sin(particles[i].heading*imopi));
particles[i].size = (float(GetTickCount())-particles[i].time)/100.0f;
k=Normalize(k);
if (NORMAL_TIME == 0) { //czyli jak false
particles[i].pos = vectors_frontadd(particles[i].startpos,vector_multiple(k,power*(GetTickCount()-particles[i].time)/1000.0f));
} else {
particles[i].pos = vectors_frontadd(particles[i].pos,vector_multiple(k,2.00*power*(GetTickCount()-particles[i].time)/1000.0f)); //end else
}
particles[i].time = GetTickCount();
// particles[i].rotate = particles[i].rotate +1;
/*if (GetTickCount()-particles[i].frametime >= sprite.speed ) {
particles[i].frametime = GetTickCount();
//particles[i].frame = particles[i].frame + 1; odkomentowac
//if (particles[i].frame > high(sprite.animtextures) )then begin particles[i].frame := 0; particles[i].draw := false; end; odkomenotwac
}
*/
checkparticle(i);
}
} catch (...) {
}
}
//tutaj jak wielkosc przekracza maks wielkosc to usuwamy z rysowania particle
void __fastcall tflamethrower::checkparticle(int index)
{
//if ( particles[index].size >= 5000.0f ) particles[index].draw = false;
if (n3ddistance(particles[index].startpos,particles[index].pos) > 1000.0f)
particles[index].draw = false;
}
void __fastcall tflamethrower::throw_next_free(t3dpoint pos, float glop, float heading)
{
int i;
bool found;
if ( (GetTickCount()-shot_time) < SHOT_SPEED ) return;
shot_time = GetTickCount();
already_shot = true;
found = false;
for (i = 0; i < 129; i++)
if (particles[i].draw == false)
{
found = true;
last_fired_particle = i; break;
}
if (found == false){ last_fired_particle = 0; }
particles[last_fired_particle].draw = true;
particles[last_fired_particle].size = 300;
particles[last_fired_particle].startpos = pos;
particles[last_fired_particle].pos = pos;
particles[last_fired_particle].frame = 0;
particles[last_fired_particle].time = GetTickCount();
particles[last_fired_particle].glop = glop;
particles[last_fired_particle].heading = heading;
particles[last_fired_particle].frametime = GetTickCount();
// particles[last_fired_particle].hitpos = shot_pos;
// particles[last_fired_particle].hitindex = shot_index;
particles[last_fired_particle].rotate = random(359);
particles[last_fired_particle].rot_time = GetTickCount();
particles[last_fired_particle].stan = 1;
}
void __fastcall tflamethrower::reset()
{
int i;
//RYSOWALEM_swiatlo[0] = false;
//RYSOWALEM_swiatlo[1] = false;
//RYSOWALEM_swiatlo[2] = false;
for (i = 0; i < 129; i++) particles[i].draw = false;
}
void __fastcall tflamethrower::setallinpos(t3dpoint pos)
{
int i;
for (i = 0; i < 129; i++) particles[i].startpos = pos;
}
//---------------------------------------------------------------------------
#ifndef WEAPON_FLAMETHROWERH
#define WEAPON_FLAMETHROWERH
//---------------------------------------------------------------------------
#include "DxcMath.h"
#include "glAnimTexture.h"
//const
//MAX_FLAME_SPRITE_SIZE = 5000;
t3dpoint BillboardX;// : t3dpoint;
t3dpoint BillboardY;// : t3dpoint;
struct tflame_part {
float size;
t3dpoint pos;
t3dpoint startpos;
bool draw;
int frame;
int time;
int frametime;
float glop;
float heading;
float rotate;
int rot_time;
t3dpoint hitpos;
int stan;
bool stanC;
int hitindex;
t3dpoint odbity_wektor;
};
class tflamethrower {
public:
int NORMAL_TIME;
tglanimtexture * sprite;
float power;
tflame_part particles[129];
int last_fired_particle;
int SHOT_SPEED;
bool already_shot;
int shot_time;
//RYSOWALEM_swiatlo : array[0..2] of boolean;
__fastcall tflamethrower();
__fastcall ~tflamethrower();
void __fastcall reset();
void __fastcall setallinpos(t3dpoint pos);
void __fastcall throw_next_free(t3dpoint pos, float glop, float heading);
void __fastcall checkparticle(int index);
void __fastcall load(AnsiString filename);
void __fastcall DRAW();
private:
void __fastcall make_next_frame();
};
#endif
here is a sample what i did, uses time, works as intended.