Click here to Skip to main content
Click here to Skip to main content
Articles » Multimedia » OpenGL » General » Downloads
 
Add your own
alternative version
Go to top

Quagmire Particle Engine

, 23 Feb 2005
An object oriented OpenGL particle engine, for the simple creation of advanced particle effects.
particleengine_demo.zip
FireEngine.exe
FireEngine.dsp
FireEngine.dsw
glut32.dll
particle.bmp
particleengine_src.zip
/*	Ken Mazaika
	February 23, 2005
	Quagmire Particle Engine
	Copyright 2005
	http://home.comcast.net/~kjmaz
  */


#include "Particle.h"
#include <fstream.h>

//Global texture to be accessed by each particle individually.  If the texture
//was in each QdParticle object the memory wasted would be very great.
QdTexture g;



/*  The Particle Object */
QdParticle::QdParticle()
{
	//Assumed values if none are initiated
	m_fAge = 0;
	m_nFrames = 0;
	m_fLife = 1.0f;
	m_fGravityFactor=.025f;
	
}

//Draws the particle to the screen
void QdParticle::draw()
{
	//Set color
	glColor4f(m_clrCurrent.m_fR, m_clrCurrent.m_fG, m_clrCurrent.m_fB, m_clrCurrent.m_fA);

	//Dont display particle on first frame of it's life
	if(m_fLife ==1.0f)
	{
		glColor4f(0,0,0,0);
	}




	//draw the square
	g.SelectTexture();
	glBegin(GL_QUADS);
	//Texture coordinates make the texture pointed upwards without being twisted
		glTexCoord2f(1,1); glVertex3f(m_ptUL.m_fX, m_ptUL.m_fY, m_ptUL.m_fZ);
		glTexCoord2f(0,1); glVertex3f(m_ptLR.m_fX, m_ptUL.m_fY, m_ptUL.m_fZ);
		glTexCoord2f(0,0); glVertex3f(m_ptLR.m_fX, m_ptLR.m_fY, m_ptUL.m_fZ);
		glTexCoord2f(1,0); glVertex3f(m_ptUL.m_fX, m_ptLR.m_fY, m_ptUL.m_fZ);
	glEnd();
}

void QdParticle::advance()
{

	//Move the quad in the direction it should be headed
	m_ptUL.m_fX  += m_ptDirection.m_fX;
	m_ptUL.m_fY  += m_ptDirection.m_fY;
	m_ptUL.m_fZ  += m_ptDirection.m_fZ;

	m_ptLR.m_fX  += m_ptDirection.m_fX;
	m_ptLR.m_fY  += m_ptDirection.m_fY;
	m_ptLR.m_fZ  += m_ptDirection.m_fZ;

	//Add the force of gravity
	//The formula for the force of gravity (without factoring friction from
	//the air) is something like:  h = vit + 1/2 a t^2
	m_ptUL.m_fX += m_ptGravity.m_fX * m_fAge *m_fAge;
	m_ptUL.m_fY += m_ptGravity.m_fY* m_fAge *m_fAge;
	m_ptUL.m_fZ += m_ptGravity.m_fZ* m_fAge *m_fAge;

	m_ptLR.m_fX += m_ptGravity.m_fX* m_fAge *m_fAge;
	m_ptLR.m_fY += m_ptGravity.m_fY* m_fAge *m_fAge;
	m_ptLR.m_fZ += m_ptGravity.m_fZ* m_fAge *m_fAge;

	//Slowly fade the color
	m_clrCurrent.m_fR+= m_clrFade.m_fR;
	m_clrCurrent.m_fG+= m_clrFade.m_fG;
	m_clrCurrent.m_fB+= m_clrFade.m_fB;
	m_clrCurrent.m_fA+= m_clrFade.m_fA;
	
	m_fLife+= m_fFadeLife;

	m_nFrames++;
	m_fAge = m_nFrames * m_fGravityFactor;

}


/* The Particle Engine */

QdParticleEngine::QdParticleEngine()
{
	m_bLimit = 0;
	m_bEngineActive = 0;
	m_nAge = 0;
	m_szImgPath = &m_szImgPathA[0];
	strcpy(m_szImgPath, "particle.bmp");
}

QdParticleEngine::~QdParticleEngine()
{
	if(m_bEngineActive)
	{
		destroy();
	}
	m_bEngineActive = 0;
}

int QdParticleEngine::init(int nParticles)
{
	g.SetMode(QD_NO_AUTO_TEXTURE);


	g.LoadFromBitmap(m_szImgPath);

	m_bEngineActive=1;
	m_pParticles = new QdParticle[nParticles];
	m_nParticles= nParticles;


	int nCount =0;
	while(nCount<nParticles)
	{
		m_pParticles[nCount].m_nParticle=nCount;
		nCount++;
	}
	resetParticles();
	return nParticles;
}


int QdParticleEngine::draw()
{
	int nCount=0;
	while(nCount != m_nParticles)
	{
		m_pParticles[nCount].draw();
		m_pParticles[nCount].advance();
		if(m_pParticles[nCount].m_fLife<0.0f)
		{
			particleDead(nCount);
		}

		nCount++;
	}

	if(m_bLimit)
	{
		nCount =0;
		while(nCount!=m_nParticles)
		{
			if(m_pParticles[nCount].m_ptUL.m_fX<m_fLimitL)
			{
				particleDead(nCount);
			}
			else if(m_pParticles[nCount].m_ptLR.m_fX>m_fLimitR)
			{
				particleDead(nCount);
			}
			else if(m_pParticles[nCount].m_ptLR.m_fY<m_fLimitB)
			{
				particleDead(nCount);
			}
			else if(m_pParticles[nCount].m_ptUL.m_fY>m_fLimitT)
			{
				particleDead(nCount);
			}

			nCount++;
		}

	}
	m_nAge++;

nCount = 0;


	return nCount;
}
int QdParticleEngine::destroy()
{
	m_nAge = 0;
	delete[] m_pParticles;
	return 4;

}


int QdParticleEngine::resetParticles()
{
	return 0;
}
int QdParticleEngine::particleDead(int nParticle)
{
	return 0;
}


int QdParticleEngine::setCurrentColor(int nParticle, float fRed, float fGreen, float fBlue, float fAlpha)
{
	m_pParticles[nParticle].m_clrCurrent.m_fR=fRed;
	m_pParticles[nParticle].m_clrCurrent.m_fG=fGreen;
	m_pParticles[nParticle].m_clrCurrent.m_fB=fBlue;
	m_pParticles[nParticle].m_clrCurrent.m_fA=fAlpha;

	return QD_SUCCESS;
}


int QdParticleEngine::setImgPath(char *szImgPath)
{
	strcpy(m_szImgPath,szImgPath);
	return QD_SUCCESS;

}

int QdParticleEngine::setFadeColor(int nParticle, float fRed, float fGreen, float fBlue, float fAlpha)
{
	m_pParticles[nParticle].m_clrFade.m_fR=fRed;
	m_pParticles[nParticle].m_clrFade.m_fG=fGreen;
	m_pParticles[nParticle].m_clrFade.m_fB=fBlue;
	m_pParticles[nParticle].m_clrFade.m_fA=fAlpha;

	return QD_SUCCESS;
}


int QdParticleEngine::setDirection(int nParticle, float fX, float fY, float fZ)
{
	m_pParticles[nParticle].m_ptDirection.m_fX=fX;
	m_pParticles[nParticle].m_ptDirection.m_fY=fY;
	m_pParticles[nParticle].m_ptDirection.m_fZ=fZ;
	return QD_SUCCESS;

}

int QdParticleEngine::setGravity(int nParticle, float fX, float fY, float fZ)
{
	m_pParticles[nParticle].m_ptGravity.m_fX=fX;
	m_pParticles[nParticle].m_ptGravity.m_fY=fY;
	m_pParticles[nParticle].m_ptGravity.m_fZ=fZ;
	return QD_SUCCESS;
}

int QdParticleEngine::setLR(int nParticle, float fX, float fY, float fZ)
{
	m_pParticles[nParticle].m_ptLR.m_fX=fX;
	m_pParticles[nParticle].m_ptLR.m_fY=fY;
	m_pParticles[nParticle].m_ptLR.m_fZ=fZ;
	return QD_SUCCESS;
}

int QdParticleEngine::setUL(int nParticle, float fX, float fY, float fZ)
{
	m_pParticles[nParticle].m_ptUL.m_fX=fX;
	m_pParticles[nParticle].m_ptUL.m_fY=fY;
	m_pParticles[nParticle].m_ptUL.m_fZ=fZ;
	return QD_SUCCESS;
}

int QdParticleEngine::setAge(int nParticle, float fAge)
{
	m_pParticles[nParticle].m_fAge=fAge;
	return QD_SUCCESS;
}

int QdParticleEngine::setFrame(int nParticle, int nFrame)
{
	m_pParticles[nParticle].m_nFrames=nFrame;
	return QD_SUCCESS;
}

int QdParticleEngine::setGravityFactor(int nParticle, float fGravityFactor)
{
	m_pParticles[nParticle].m_fGravityFactor=fGravityFactor;
	return QD_SUCCESS;
}

int QdParticleEngine::setLife(int nParticle, float fLife)
{
	m_pParticles[nParticle].m_fLife=fLife;
	return QD_SUCCESS;
}


int QdParticleEngine::setFadeLife(int nParticle, float fFadeLife)
{
	m_pParticles[nParticle].m_fFadeLife=fFadeLife;
	return QD_SUCCESS;
}


//Set Limit Function used to disable limits after the boundaries are set
int QdParticleEngine::setLimit(bool bLimit)
{
	m_bLimit = bLimit;
	return QD_SUCCESS;
}

int QdParticleEngine::setLimit(float fLimitL, float fLimitR, float fLimitB, float fLimitT)
{
	//Enable limit
	m_bLimit = 1;

	m_fLimitL = fLimitL;
	m_fLimitR = fLimitR;
	m_fLimitT = fLimitT;
	m_fLimitB = fLimitB;

	return QD_SUCCESS;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Ken Mazaika

United States United States
No Biography provided

| Advertise | Privacy | Mobile
Web02 | 2.8.140916.1 | Last Updated 23 Feb 2005
Article Copyright 2005 by Ken Mazaika
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid