Skip to content
Browse files

loading .pex file, displaying texture

  • Loading branch information...
1 parent 182a808 commit fc2836a651cf1e1862a8954325e7a37c4bde6d05 @sroske committed Jul 2, 2010
View
3 .gitignore
@@ -1,3 +1,4 @@
sroske.*
build
-.DS_Store
+.DS_Store
+particleExample*.app
View
35 bin/data/circles.pex
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<particleEmitterConfig>
+ <texture name="circles.png"/>
+ <sourcePosition x="160.00" y="211.72"/>
+ <sourcePositionVariance x="7.00" y="7.00"/>
+ <speed value="98.00"/>
+ <speedVariance value="211.00"/>
+ <particleLifeSpan value="3.0000"/>
+ <particleLifespanVariance value="5.0000"/>
+ <angle value="357.00"/>
+ <angleVariance value="190.00"/>
+ <gravity x="0.70" y="1.43"/>
+ <radialAcceleration value="0.00"/>
+ <tangentialAcceleration value="0.00"/>
+ <radialAccelVariance value="0.00"/>
+ <tangentialAccelVariance value="0.00"/>
+ <startColor red="0.32" green="0.39" blue="0.58" alpha="0.76"/>
+ <startColorVariance red="0.42" green="0.75" blue="0.88" alpha="0.08"/>
+ <finishColor red="0.79" green="0.85" blue="0.42" alpha="0.57"/>
+ <finishColorVariance red="0.45" green="0.51" blue="0.26" alpha="0.46"/>
+ <maxParticles value="643"/>
+ <startParticleSize value="49.00"/>
+ <startParticleSizeVariance value="60.00"/>
+ <finishParticleSize value="31.00"/>
+ <FinishParticleSizeVariance value="0.00"/>
+ <duration value="-1.00"/>
+ <emitterType value="0"/>
+ <maxRadius value="100.00"/>
+ <maxRadiusVariance value="0.00"/>
+ <minRadius value="0.00"/>
+ <rotatePerSecond value="0.00"/>
+ <rotatePerSecondVariance value="0.00"/>
+ <blendFuncSource value="1"/>
+ <blendFuncDestination value="1"/>
+</particleEmitterConfig>
View
BIN bin/data/circles.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
61 particleExample.xcodeproj/project.pbxproj
@@ -7,6 +7,11 @@
objects = {
/* Begin PBXBuildFile section */
+ A914CC5311DE47F60038D13C /* tinyxml.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A914CC4C11DE47F60038D13C /* tinyxml.cpp */; };
+ A914CC5411DE47F60038D13C /* tinyxmlerror.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A914CC4E11DE47F60038D13C /* tinyxmlerror.cpp */; };
+ A914CC5511DE47F60038D13C /* tinyxmlparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A914CC4F11DE47F60038D13C /* tinyxmlparser.cpp */; };
+ A914CC5611DE47F60038D13C /* ofxXmlSettings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A914CC5111DE47F60038D13C /* ofxXmlSettings.cpp */; };
+ A914CC5C11DE4AB30038D13C /* ofxParticleEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A914CC5B11DE4AB30038D13C /* ofxParticleEmitter.cpp */; };
E45BE0AA0E8CC67C009D7055 /* GLee.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E45BE0A90E8CC67C009D7055 /* GLee.a */; };
E45BE2E40E8CC69C009D7055 /* rtAudio.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E45BE2E30E8CC69C009D7055 /* rtAudio.a */; };
E45BE97B0E8CC7DD009D7055 /* AGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E45BE9710E8CC7DD009D7055 /* AGL.framework */; };
@@ -78,6 +83,15 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
+ A914CC4A11DE47F60038D13C /* install.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = install.xml; sourceTree = "<group>"; };
+ A914CC4C11DE47F60038D13C /* tinyxml.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinyxml.cpp; sourceTree = "<group>"; };
+ A914CC4D11DE47F60038D13C /* tinyxml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tinyxml.h; sourceTree = "<group>"; };
+ A914CC4E11DE47F60038D13C /* tinyxmlerror.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinyxmlerror.cpp; sourceTree = "<group>"; };
+ A914CC4F11DE47F60038D13C /* tinyxmlparser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinyxmlparser.cpp; sourceTree = "<group>"; };
+ A914CC5111DE47F60038D13C /* ofxXmlSettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ofxXmlSettings.cpp; sourceTree = "<group>"; };
+ A914CC5211DE47F60038D13C /* ofxXmlSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ofxXmlSettings.h; sourceTree = "<group>"; };
+ A914CC5A11DE4AB30038D13C /* ofxParticleEmitter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ofxParticleEmitter.h; sourceTree = "<group>"; };
+ A914CC5B11DE4AB30038D13C /* ofxParticleEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ofxParticleEmitter.cpp; sourceTree = "<group>"; };
E45BE0390E8CC647009D7055 /* FreeImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FreeImage.h; path = ../../../libs/freeimage/include/FreeImage.h; sourceTree = SOURCE_ROOT; };
E45BE03F0E8CC650009D7055 /* fmod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fmod.h; path = ../../../libs/fmodex/include/fmod.h; sourceTree = SOURCE_ROOT; };
E45BE0400E8CC650009D7055 /* fmod.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = fmod.hpp; path = ../../../libs/fmodex/include/fmod.hpp; sourceTree = SOURCE_ROOT; };
@@ -154,6 +168,45 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
+ A914CC4711DE47DB0038D13C /* addons */ = {
+ isa = PBXGroup;
+ children = (
+ A914CC4911DE47F60038D13C /* ofxXmlSettings */,
+ );
+ name = addons;
+ sourceTree = "<group>";
+ };
+ A914CC4911DE47F60038D13C /* ofxXmlSettings */ = {
+ isa = PBXGroup;
+ children = (
+ A914CC4A11DE47F60038D13C /* install.xml */,
+ A914CC4B11DE47F60038D13C /* libs */,
+ A914CC5011DE47F60038D13C /* src */,
+ );
+ name = ofxXmlSettings;
+ path = ../../../addons/ofxXmlSettings;
+ sourceTree = SOURCE_ROOT;
+ };
+ A914CC4B11DE47F60038D13C /* libs */ = {
+ isa = PBXGroup;
+ children = (
+ A914CC4C11DE47F60038D13C /* tinyxml.cpp */,
+ A914CC4D11DE47F60038D13C /* tinyxml.h */,
+ A914CC4E11DE47F60038D13C /* tinyxmlerror.cpp */,
+ A914CC4F11DE47F60038D13C /* tinyxmlparser.cpp */,
+ );
+ path = libs;
+ sourceTree = "<group>";
+ };
+ A914CC5011DE47F60038D13C /* src */ = {
+ isa = PBXGroup;
+ children = (
+ A914CC5111DE47F60038D13C /* ofxXmlSettings.cpp */,
+ A914CC5211DE47F60038D13C /* ofxXmlSettings.h */,
+ );
+ path = src;
+ sourceTree = "<group>";
+ };
E45BE0360E8CC5DE009D7055 /* libs */ = {
isa = PBXGroup;
children = (
@@ -334,6 +387,7 @@
E4B69B4A0A3A1720003C02F2 = {
isa = PBXGroup;
children = (
+ A914CC4711DE47DB0038D13C /* addons */,
E4B69B5B0A3A1756003C02F2 /* particleExampleDebug.app */,
E4B6FCAD0C3E899E008CF71C /* openFrameworks-Info.plist */,
E4B69E1C0A3A1BDC003C02F2 /* src */,
@@ -348,6 +402,8 @@
E4B69E1D0A3A1BDC003C02F2 /* main.cpp */,
E4B69E1E0A3A1BDC003C02F2 /* testApp.cpp */,
E4B69E1F0A3A1BDC003C02F2 /* testApp.h */,
+ A914CC5A11DE4AB30038D13C /* ofxParticleEmitter.h */,
+ A914CC5B11DE4AB30038D13C /* ofxParticleEmitter.cpp */,
);
path = src;
sourceTree = SOURCE_ROOT;
@@ -515,6 +571,11 @@
files = (
E4B69E200A3A1BDC003C02F2 /* main.cpp in Sources */,
E4B69E210A3A1BDC003C02F2 /* testApp.cpp in Sources */,
+ A914CC5311DE47F60038D13C /* tinyxml.cpp in Sources */,
+ A914CC5411DE47F60038D13C /* tinyxmlerror.cpp in Sources */,
+ A914CC5511DE47F60038D13C /* tinyxmlparser.cpp in Sources */,
+ A914CC5611DE47F60038D13C /* ofxXmlSettings.cpp in Sources */,
+ A914CC5C11DE4AB30038D13C /* ofxParticleEmitter.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
413 src/ofxParticleEmitter.cpp
@@ -0,0 +1,413 @@
+//
+// ofxParticleEmitter.cpp
+//
+// Copyright (c) 2010 71Squared, ported to Openframeworks by Shawn Roske
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include "ofxParticleEmitter.h"
+
+// ------------------------------------------------------------------------
+// Lifecycle
+// ------------------------------------------------------------------------
+
+ofxParticleEmitter::ofxParticleEmitter()
+{
+ settings = NULL;
+
+ emitterType = kParticleTypeGravity;
+ texture = NULL;
+ sourcePosition.x = sourcePosition.y = 0.0f;
+ sourcePositionVariance.x = sourcePositionVariance.y = 0.0f;
+ angle = angleVariance = 0.0f;
+ speed = speedVariance = 0.0f;
+ radialAcceleration = tangentialAcceleration = 0.0f;
+ radialAccelVariance = tangentialAccelVariance = 0.0f;
+ gravity.x = gravity.y = 0.0f;
+ particleLifespan = particleLifespanVariance = 0.0f;
+ startColor.red = startColor.green = startColor.blue = startColor.alpha = 1.0f;
+ startColorVariance.red = startColorVariance.green = startColorVariance.blue = startColorVariance.alpha = 1.0f;
+ finishColor.red = finishColor.green = finishColor.blue = finishColor.alpha = 1.0f;
+ finishColorVariance.red = finishColorVariance.green = finishColorVariance.blue = finishColorVariance.alpha = 1.0f;
+ startParticleSize = startParticleSizeVariance = 0.0f;
+ finishParticleSize = finishParticleSizeVariance = 0.0f;
+ maxParticles = 0.0f;
+ particleCount = 0;
+ emissionRate = 0.0f;
+ emitCounter = 0.0f;
+ elapsedTime = 0.0f;
+ duration = -1;
+
+ blendFuncSource = blendFuncDestination = 0;
+
+ maxRadius = maxRadiusVariance = radiusSpeed = minRadius = 0.0f;
+ rotatePerSecond = rotatePerSecondVariance = 0.0f;
+
+ active = useTexture = false;
+ particleIndex = 0;
+
+ verticesID = 0;
+ particles = NULL;
+ vertices = NULL;
+}
+
+ofxParticleEmitter::~ofxParticleEmitter()
+{
+ exit();
+}
+
+void ofxParticleEmitter::exit()
+{
+ if ( texture != NULL )
+ delete texture;
+ texture = NULL;
+
+ if ( particles != NULL )
+ delete particles;
+ particles = NULL;
+
+ if ( vertices != NULL )
+ delete vertices;
+ vertices = NULL;
+
+ glDeleteBuffers( 1, &verticesID );
+}
+
+bool ofxParticleEmitter::loadFromXml( const std::string& filename )
+{
+ bool ok = false;
+
+ settings = new ofxXmlSettings();
+
+ ok = settings->loadFile( filename );
+ if ( ok )
+ {
+ parseParticleConfig();
+ setupArrays();
+
+ ok = active = true;
+ }
+
+ delete settings;
+ settings = NULL;
+
+ return ok;
+}
+
+void ofxParticleEmitter::parseParticleConfig()
+{
+ if ( settings == NULL )
+ {
+ ofLog( OF_LOG_ERROR, "ofxParticleEmitter::parseParticleConfig() - XML settings is invalid!" );
+ return;
+ }
+
+ settings->pushTag( "particleEmitterConfig" );
+
+ std::string imageFilename = settings->getAttribute( "texture", "name", "" );
+ std::string imageData = settings->getAttribute( "texture", "data", "" );
+
+ if ( imageFilename != "" )
+ {
+ ofLog( OF_LOG_WARNING, "ofxParticleEmitter::parseParticleConfig() - loading image file" );
+
+ texture = new ofImage();
+ texture->loadImage( imageFilename );
+ texture->setUseTexture( true );
+ }
+ else if ( imageData != "" )
+ {
+ // TODO
+
+ ofLog( OF_LOG_ERROR, "ofxParticleEmitter::parseParticleConfig() - image data found but not yet implemented!" );
+ return;
+ }
+
+ emitterType = settings->getAttribute( "emitterType", "value", emitterType );
+
+ sourcePosition.x = settings->getAttribute( "sourcePosition", "x", sourcePosition.x );
+ sourcePosition.y = settings->getAttribute( "sourcePosition", "y", sourcePosition.y );
+
+ speed = settings->getAttribute( "speed", "value", speed );
+ speedVariance = settings->getAttribute( "speedVariance", "value", speedVariance );
+ particleLifespan = settings->getAttribute( "particleLifespan", "value", particleLifespan );
+ particleLifespanVariance = settings->getAttribute( "particleLifespanVariance", "value", particleLifespanVariance );
+ angle = settings->getAttribute( "angle", "value", angle );
+ angleVariance = settings->getAttribute( "angleVariance", "value", angleVariance );
+
+ gravity.x = settings->getAttribute( "gravity", "x", gravity.x );
+ gravity.y = settings->getAttribute( "gravity", "y", gravity.y );
+
+ radialAcceleration = settings->getAttribute( "radialAcceleration", "value", radialAcceleration );
+ tangentialAcceleration = settings->getAttribute( "tangentialAcceleration", "value", tangentialAcceleration );
+
+ startColor.red = settings->getAttribute( "startColor", "red", startColor.red );
+ startColor.green = settings->getAttribute( "startColor", "green", startColor.green );
+ startColor.blue = settings->getAttribute( "startColor", "blue", startColor.blue );
+ startColor.alpha = settings->getAttribute( "startColor", "alpha", startColor.alpha );
+
+ startColorVariance.red = settings->getAttribute( "startColorVariance", "red", startColorVariance.red );
+ startColorVariance.green = settings->getAttribute( "startColorVariance", "green", startColorVariance.green );
+ startColorVariance.blue = settings->getAttribute( "startColorVariance", "blue", startColorVariance.blue );
+ startColorVariance.alpha = settings->getAttribute( "startColorVariance", "alpha", startColorVariance.alpha );
+
+ finishColor.red = settings->getAttribute( "finishColor", "red", finishColor.red );
+ finishColor.green = settings->getAttribute( "finishColor", "green", finishColor.green );
+ finishColor.blue = settings->getAttribute( "finishColor", "blue", finishColor.blue );
+ finishColor.alpha = settings->getAttribute( "finishColor", "alpha", finishColor.alpha );
+
+ finishColorVariance.red = settings->getAttribute( "finishColorVariance", "red", finishColorVariance.red );
+ finishColorVariance.green = settings->getAttribute( "finishColorVariance", "green", finishColorVariance.green );
+ finishColorVariance.blue = settings->getAttribute( "finishColorVariance", "blue", finishColorVariance.blue );
+ finishColorVariance.alpha = settings->getAttribute( "finishColorVariance", "alpha", finishColorVariance.alpha );
+
+ maxParticles = settings->getAttribute( "maxParticles", "value", maxParticles );
+ startParticleSize = settings->getAttribute( "startParticleSize", "value", startParticleSize );
+ startParticleSizeVariance = settings->getAttribute( "startParticleSizeVariance", "value", startParticleSizeVariance );
+ finishParticleSize = settings->getAttribute( "finishParticleSize", "value", finishParticleSize );
+ finishParticleSizeVariance = settings->getAttribute( "finishParticleSizeVariance", "value", finishParticleSizeVariance );
+ duration = settings->getAttribute( "duration", "value", duration );
+ blendFuncSource = settings->getAttribute( "blendFuncSource", "value", blendFuncSource );
+ blendFuncDestination = settings->getAttribute( "blendFuncDestination", "value", blendFuncDestination );
+
+ maxRadius = settings->getAttribute( "maxRadius", "value", maxRadius );
+ maxRadiusVariance = settings->getAttribute( "maxRadiusVariance", "value", maxRadiusVariance );
+ radiusSpeed = settings->getAttribute( "radiusSpeed", "value", radiusSpeed );
+ minRadius = settings->getAttribute( "minRadius", "value", minRadius );
+
+ rotatePerSecond = settings->getAttribute( "rotatePerSecond", "value", rotatePerSecond );
+ rotatePerSecondVariance = settings->getAttribute( "rotatePerSecondVariance", "value", rotatePerSecondVariance );
+
+ // Calculate the emission rate
+ emissionRate = maxParticles / particleLifespan;
+}
+
+void ofxParticleEmitter::setupArrays()
+{
+ // Allocate the memory necessary for the particle emitter arrays
+ particles = (Particle*)malloc( sizeof( Particle ) * maxParticles );
+ vertices = (PointSprite*)malloc( sizeof( PointSprite ) * maxParticles );
+
+ // If one of the arrays cannot be allocated throw an assertion as this is bad
+ assert( particles && vertices );
+
+ // Generate the vertices VBO
+ glGenBuffers( 1, &verticesID );
+
+ // Set the particle count to zero
+ particleCount = 0;
+
+ // Reset the elapsed time
+ elapsedTime = 0;
+}
+
+// ------------------------------------------------------------------------
+// Update
+// ------------------------------------------------------------------------
+
+void ofxParticleEmitter::update()
+{
+ if ( !active ) return;
+
+ // TODO
+
+ // need delta
+
+ /*
+
+ // If the emitter is active and the emission rate is greater than zero then emit
+ // particles
+ if(active && emissionRate) {
+ float rate = 1.0f/emissionRate;
+ emitCounter += aDelta;
+ while(particleCount < maxParticles && emitCounter > rate) {
+ [self addParticle];
+ emitCounter -= rate;
+ }
+
+ elapsedTime += aDelta;
+ if(duration != -1 && duration < elapsedTime)
+ [self stopParticleEmitter];
+ }
+
+ // Reset the particle index before updating the particles in this emitter
+ particleIndex = 0;
+
+ // Loop through all the particles updating their location and color
+ while(particleIndex < particleCount) {
+
+ // Get the particle for the current particle index
+ Particle *currentParticle = &particles[particleIndex];
+
+ // FIX 1
+ // Reduce the life span of the particle
+ currentParticle->timeToLive -= aDelta;
+
+ // If the current particle is alive then update it
+ if(currentParticle->timeToLive > 0) {
+
+ // If maxRadius is greater than 0 then the particles are going to spin otherwise
+ // they are effected by speed and gravity
+ if (emitterType == kParticleTypeRadial) {
+
+ // FIX 2
+ // Update the angle of the particle from the sourcePosition and the radius. This is only
+ // done of the particles are rotating
+ currentParticle->angle += currentParticle->degreesPerSecond * aDelta;
+ currentParticle->radius -= currentParticle->radiusDelta;
+
+ Vector2f tmp;
+ tmp.x = sourcePosition.x - cosf(currentParticle->angle) * currentParticle->radius;
+ tmp.y = sourcePosition.y - sinf(currentParticle->angle) * currentParticle->radius;
+ currentParticle->position = tmp;
+
+ if (currentParticle->radius < minRadius)
+ currentParticle->timeToLive = 0;
+ } else {
+ Vector2f tmp, radial, tangential;
+
+ radial = Vector2fZero;
+ Vector2f diff = Vector2fSub(currentParticle->startPos, Vector2fZero);
+
+ currentParticle->position = Vector2fSub(currentParticle->position, diff);
+
+ if (currentParticle->position.x || currentParticle->position.y)
+ radial = Vector2fNormalize(currentParticle->position);
+
+ tangential.x = radial.x;
+ tangential.y = radial.y;
+ radial = Vector2fMultiply(radial, currentParticle->radialAcceleration);
+
+ GLfloat newy = tangential.x;
+ tangential.x = -tangential.y;
+ tangential.y = newy;
+ tangential = Vector2fMultiply(tangential, currentParticle->tangentialAcceleration);
+
+ tmp = Vector2fAdd( Vector2fAdd(radial, tangential), gravity);
+ tmp = Vector2fMultiply(tmp, aDelta);
+ currentParticle->direction = Vector2fAdd(currentParticle->direction, tmp);
+ tmp = Vector2fMultiply(currentParticle->direction, aDelta);
+ currentParticle->position = Vector2fAdd(currentParticle->position, tmp);
+ currentParticle->position = Vector2fAdd(currentParticle->position, diff);
+ }
+
+ // Update the particles color
+ currentParticle->color.red += currentParticle->deltaColor.red;
+ currentParticle->color.green += currentParticle->deltaColor.green;
+ currentParticle->color.blue += currentParticle->deltaColor.blue;
+ currentParticle->color.alpha += currentParticle->deltaColor.alpha;
+
+ // Place the position of the current particle into the vertices array
+ vertices[particleIndex].x = currentParticle->position.x;
+ vertices[particleIndex].y = currentParticle->position.y;
+
+ // Place the size of the current particle in the size array
+ currentParticle->particleSize += currentParticle->particleSizeDelta;
+ vertices[particleIndex].size = MAX(0, currentParticle->particleSize);
+
+ // Place the color of the current particle into the color array
+ vertices[particleIndex].color = currentParticle->color;
+
+ // Update the particle counter
+ particleIndex++;
+ } else {
+
+ // As the particle is not alive anymore replace it with the last active particle
+ // in the array and reduce the count of particles by one. This causes all active particles
+ // to be packed together at the start of the array so that a particle which has run out of
+ // life will only drop into this clause once
+ if(particleIndex != particleCount - 1)
+ particles[particleIndex] = particles[particleCount - 1];
+ particleCount--;
+ }
+ }
+
+ */
+}
+
+// ------------------------------------------------------------------------
+// Render
+// ------------------------------------------------------------------------
+
+void ofxParticleEmitter::draw(int x /* = 0 */, int y /* = 0 */)
+{
+ if ( !active ) return;
+
+ ofSetColor( 255, 255, 255 );
+
+ ofEnableAlphaBlending();
+ texture->draw( x, y );
+ ofDisableAlphaBlending();
+
+ /*
+ // Disable the texture coord array so that texture information is not copied over when rendering
+ // the point sprites.
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ // Bind to the verticesID VBO and popuate it with the necessary vertex & color informaiton
+ glBindBuffer(GL_ARRAY_BUFFER, verticesID);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(PointSprite) * maxParticles, vertices, GL_DYNAMIC_DRAW);
+
+ // Configure the vertex pointer which will use the currently bound VBO for its data
+ glVertexPointer(2, GL_FLOAT, sizeof(PointSprite), 0);
+ glColorPointer(4,GL_FLOAT,sizeof(PointSprite),(GLvoid*) (sizeof(GLfloat)*3));
+
+ // Bind to the particles texture
+ glBindTexture(GL_TEXTURE_2D, texture.name);
+
+ // Enable the point size array
+ glEnableClientState(GL_POINT_SIZE_ARRAY_OES);
+
+ // Configure the point size pointer which will use the currently bound VBO. PointSprite contains
+ // both the location of the point as well as its size, so the config below tells the point size
+ // pointer where in the currently bound VBO it can find the size for each point
+ glPointSizePointerOES(GL_FLOAT,sizeof(PointSprite),(GLvoid*) (sizeof(GL_FLOAT)*2));
+
+ // Change the blend function used if blendAdditive has been set
+
+ // Set the blend function based on the configuration
+ glBlendFunc(blendFuncSource, blendFuncDestination);
+
+ // Enable and configure point sprites which we are going to use for our particles
+ glEnable(GL_POINT_SPRITE_OES);
+ glTexEnvi( GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_TRUE );
+
+ // Now that all of the VBOs have been used to configure the vertices, pointer size and color
+ // use glDrawArrays to draw the points
+ glDrawArrays(GL_POINTS, 0, particleIndex);
+
+ // Unbind the current VBO
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ // Disable the client states which have been used incase the next draw function does
+ // not need or use them
+ glDisableClientState(GL_POINT_SIZE_ARRAY_OES);
+ glDisable(GL_POINT_SPRITE_OES);
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ // Re-enable the texture coordinates as we use them elsewhere in the game and it is expected that
+ // its on
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ */
+}
+
+
+
View
144 src/ofxParticleEmitter.h
@@ -0,0 +1,144 @@
+//
+// ofxParticleEmitter.h
+//
+// Copyright (c) 2010 71Squared, ported to Openframeworks by Shawn Roske
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#ifndef _OFX_PARTICLE_EMITTER
+#define _OFX_PARTICLE_EMITTER
+
+#include "ofMain.h"
+#include "ofxXmlSettings.h"
+
+// Structure that defines the elements which make up a color
+typedef struct {
+ GLfloat red;
+ GLfloat green;
+ GLfloat blue;
+ GLfloat alpha;
+} Color4f;
+
+// Structure that defines a vector using x and y
+typedef struct {
+ GLfloat x;
+ GLfloat y;
+} Vector2f;
+
+// Particle type
+enum kParticleTypes
+{
+ kParticleTypeGravity,
+ kParticleTypeRadial
+};
+
+// Structure that holds the location and size for each point sprite
+typedef struct
+{
+ GLfloat x;
+ GLfloat y;
+ GLfloat size;
+ Color4f color;
+} PointSprite;
+
+// Structure used to hold particle specific information
+typedef struct
+{
+ Vector2f position;
+ Vector2f direction;
+ Vector2f startPos;
+ Color4f color;
+ Color4f deltaColor;
+ GLfloat radialAcceleration;
+ GLfloat tangentialAcceleration;
+ GLfloat radius;
+ GLfloat radiusDelta;
+ GLfloat angle;
+ GLfloat degreesPerSecond;
+ GLfloat particleSize;
+ GLfloat particleSizeDelta;
+ GLfloat timeToLive;
+} Particle;
+
+#define MAXIMUM_UPDATE_RATE 90.0f // The maximum number of updates that occur per frame
+
+class ofxParticleEmitter
+{
+
+public:
+
+ ofxParticleEmitter();
+ ~ofxParticleEmitter();
+
+ bool loadFromXml( const std::string& filename );
+ void update();
+ void draw( int x = 0, int y = 0 );
+ void exit();
+
+protected:
+
+ void parseParticleConfig();
+ void setupArrays();
+
+ ofxXmlSettings* settings;
+
+ int emitterType;
+ ofImage* texture;
+ Vector2f sourcePosition, sourcePositionVariance;
+ GLfloat angle, angleVariance;
+ GLfloat speed, speedVariance;
+ GLfloat radialAcceleration, tangentialAcceleration;
+ GLfloat radialAccelVariance, tangentialAccelVariance;
+ Vector2f gravity;
+ GLfloat particleLifespan, particleLifespanVariance;
+ Color4f startColor, startColorVariance;
+ Color4f finishColor, finishColorVariance;
+ GLfloat startParticleSize, startParticleSizeVariance;
+ GLfloat finishParticleSize, finishParticleSizeVariance;
+ GLint maxParticles;
+ GLint particleCount;
+ GLfloat emissionRate;
+ GLfloat emitCounter;
+ GLfloat elapsedTime;
+ GLfloat duration;
+
+ int blendFuncSource, blendFuncDestination;
+
+ //////////////////// Particle ivars only used when a maxRadius value is provided. These values are used for
+ //////////////////// the special purpose of creating the spinning portal emitter
+ GLfloat maxRadius; // Max radius at which particles are drawn when rotating
+ GLfloat maxRadiusVariance; // Variance of the maxRadius
+ GLfloat radiusSpeed; // The speed at which a particle moves from maxRadius to minRadius
+ GLfloat minRadius; // Radius from source below which a particle dies
+ GLfloat rotatePerSecond; // Numeber of degress to rotate a particle around the source pos per second
+ GLfloat rotatePerSecondVariance; // Variance in degrees for rotatePerSecond
+
+ //////////////////// Particle Emitter iVars
+ bool active, useTexture;
+ GLint particleIndex; // Stores the number of particles that are going to be rendered
+
+
+ ///////////////////// Render
+ GLuint verticesID; // Holds the buffer name of the VBO that stores the color and vertices info for the particles
+ Particle* particles; // Array of particles that hold the particle emitters particle details
+ PointSprite* vertices; // Array of vertices and color information for each particle to be rendered
+
+};
+
+#endif
View
128 src/testApp.cpp
@@ -4,120 +4,76 @@
//--------------------------------------------------------------
void testApp::setup()
{
- counter = 0;
- ofSetCircleResolution(50);
- ofBackground(255,255,255);
- bSmooth = false;
- ofSetWindowTitle("particle example");
-
- ofSetFrameRate(60); // if vertical sync is off, we can go a bit fast... this caps the framerate at 60fps.
+ ofSetWindowTitle( "particle example" );
+ ofBackground( 120, 120, 120 );
+
+ if ( !m_emitter.loadFromXml( "circles.pex" ) )
+ {
+ ofLog( OF_LOG_ERROR, "testApp::setup() - failed to load emitter config" );
+ }
}
//--------------------------------------------------------------
-void testApp::update(){
- counter = counter + 0.033f;
+void testApp::exit()
+{
+ // TODO
}
//--------------------------------------------------------------
-void testApp::draw(){
-
- //--------------------------- circles
- //let's draw a circle:
- ofSetColor(255,130,0);
- float radius = 50 + 10 * sin(counter);
- ofFill(); // draw "filled shapes"
- ofCircle(100,400,radius);
-
- // now just an outline
- ofNoFill();
- ofSetColor(0xCCCCCC);
- ofCircle(100,400,80);
-
- // use the bitMap type
- // note, this can be slow on some graphics cards
- // because it is using glDrawPixels which varies in
- // speed from system to system. try using ofTrueTypeFont
- // if this bitMap type slows you down.
- ofSetColor(0x000000);
- ofDrawBitmapString("circle", 75,500);
-
-
- //--------------------------- rectangles
- ofFill();
- for (int i = 0; i < 200; i++){
- ofSetColor((int)ofRandom(0,255),(int)ofRandom(0,255),(int)ofRandom(0,255));
- ofRect(ofRandom(250,350),ofRandom(350,450),ofRandom(10,20),ofRandom(10,20));
- }
- ofSetColor(0x000000);
- ofDrawBitmapString("rectangles", 275,500);
-
- //--------------------------- transparency
- ofSetColor(0x00FF33);
- ofRect(400,350,100,100);
- // alpha is usually turned off - for speed puposes. let's turn it on!
- ofEnableAlphaBlending();
- ofSetColor(255,0,0,127); // red, 50% transparent
- ofRect(450,430,100,33);
- ofSetColor(255,0,0,(int)(counter * 10.0f) % 255); // red, variable transparent
- ofRect(450,370,100,33);
- ofDisableAlphaBlending();
-
- ofSetColor(0x000000);
- ofDrawBitmapString("transparency", 410,500);
-
- //--------------------------- lines
- // a bunch of red lines, make them smooth if the flag is set
-
- if (bSmooth){
- ofEnableSmoothing();
- }
-
- ofSetColor(0xFF0000);
- for (int i = 0; i < 20; i++){
- ofLine(600,300 + (i*5),800, 250 + (i*10));
- }
-
- if (bSmooth){
- ofDisableSmoothing();
- }
-
- ofSetColor(0x000000);
- ofDrawBitmapString("lines\npress 's' to toggle smoothness", 600,500);
+void testApp::update()
+{
+ m_emitter.update();
+}
+//--------------------------------------------------------------
+void testApp::draw()
+{
+ m_emitter.draw( ofGetScreenWidth()*0.5f, ofGetScreenHeight()*0.5f );
+
+ ofSetColor( 255, 255, 255 );
+ ofDrawBitmapString( "fps: " + ofToString( ofGetFrameRate(), 2 ), 20, 20 );
}
//--------------------------------------------------------------
-void testApp::keyPressed (int key){
- if (key == 's'){
- bSmooth = !bSmooth;
- }
+void testApp::keyPressed (int key)
+{
+ // nothing
}
//--------------------------------------------------------------
-void testApp::keyReleased (int key){
-
+void testApp::keyReleased (int key)
+{
+ // nothing
}
//--------------------------------------------------------------
-void testApp::mouseMoved(int x, int y ){
+void testApp::mouseMoved(int x, int y )
+{
+ // nothing
}
//--------------------------------------------------------------
-void testApp::mouseDragged(int x, int y, int button){
+void testApp::mouseDragged(int x, int y, int button)
+{
+ // nothing
}
//--------------------------------------------------------------
-void testApp::mousePressed(int x, int y, int button){
+void testApp::mousePressed(int x, int y, int button)
+{
+ // nothing
}
//--------------------------------------------------------------
-void testApp::mouseReleased(int x, int y, int button){
-
+void testApp::mouseReleased(int x, int y, int button)
+{
+ // nothing
}
//--------------------------------------------------------------
-void testApp::windowResized(int w, int h){
-
+void testApp::windowResized(int w, int h)
+{
+ // nothing
}
View
39 src/testApp.h
@@ -3,25 +3,30 @@
#include "ofMain.h"
+#include "ofxParticleEmitter.h"
-class testApp : public ofBaseApp{
+class testApp : public ofBaseApp
+{
+
+public:
+
+ void setup();
+ void update();
+ void draw();
+ void exit();
+
+ void keyPressed( int key );
+ void keyReleased( int key );
+ void mouseMoved( int x, int y );
+ void mouseDragged( int x, int y, int button );
+ void mousePressed( int x, int y, int button );
+ void mouseReleased( int x, int y, int button );
+ void windowResized( int w, int h );
+
+protected:
+
+ ofxParticleEmitter m_emitter;
- public:
-
- void setup();
- void update();
- void draw();
-
- void keyPressed(int key);
- void keyReleased(int key);
- void mouseMoved(int x, int y );
- void mouseDragged(int x, int y, int button);
- void mousePressed(int x, int y, int button);
- void mouseReleased(int x, int y, int button);
- void windowResized(int w, int h);
-
- float counter;
- bool bSmooth;
};
#endif

0 comments on commit fc2836a

Please sign in to comment.
Something went wrong with that request. Please try again.