Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

loading .pex file, displaying texture

  • Loading branch information...
commit fc2836a651cf1e1862a8954325e7a37c4bde6d05 1 parent 182a808
Shawn Roske authored
3  .gitignore
... ... @@ -1,3 +1,4 @@
1 1 sroske.*
2 2 build
3   -.DS_Store
  3 +.DS_Store
  4 +particleExample*.app
35 bin/data/circles.pex
... ... @@ -0,0 +1,35 @@
  1 +<?xml version="1.0"?>
  2 +<particleEmitterConfig>
  3 + <texture name="circles.png"/>
  4 + <sourcePosition x="160.00" y="211.72"/>
  5 + <sourcePositionVariance x="7.00" y="7.00"/>
  6 + <speed value="98.00"/>
  7 + <speedVariance value="211.00"/>
  8 + <particleLifeSpan value="3.0000"/>
  9 + <particleLifespanVariance value="5.0000"/>
  10 + <angle value="357.00"/>
  11 + <angleVariance value="190.00"/>
  12 + <gravity x="0.70" y="1.43"/>
  13 + <radialAcceleration value="0.00"/>
  14 + <tangentialAcceleration value="0.00"/>
  15 + <radialAccelVariance value="0.00"/>
  16 + <tangentialAccelVariance value="0.00"/>
  17 + <startColor red="0.32" green="0.39" blue="0.58" alpha="0.76"/>
  18 + <startColorVariance red="0.42" green="0.75" blue="0.88" alpha="0.08"/>
  19 + <finishColor red="0.79" green="0.85" blue="0.42" alpha="0.57"/>
  20 + <finishColorVariance red="0.45" green="0.51" blue="0.26" alpha="0.46"/>
  21 + <maxParticles value="643"/>
  22 + <startParticleSize value="49.00"/>
  23 + <startParticleSizeVariance value="60.00"/>
  24 + <finishParticleSize value="31.00"/>
  25 + <FinishParticleSizeVariance value="0.00"/>
  26 + <duration value="-1.00"/>
  27 + <emitterType value="0"/>
  28 + <maxRadius value="100.00"/>
  29 + <maxRadiusVariance value="0.00"/>
  30 + <minRadius value="0.00"/>
  31 + <rotatePerSecond value="0.00"/>
  32 + <rotatePerSecondVariance value="0.00"/>
  33 + <blendFuncSource value="1"/>
  34 + <blendFuncDestination value="1"/>
  35 +</particleEmitterConfig>
BIN  bin/data/circles.png
61 particleExample.xcodeproj/project.pbxproj
@@ -7,6 +7,11 @@
7 7 objects = {
8 8
9 9 /* Begin PBXBuildFile section */
  10 + A914CC5311DE47F60038D13C /* tinyxml.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A914CC4C11DE47F60038D13C /* tinyxml.cpp */; };
  11 + A914CC5411DE47F60038D13C /* tinyxmlerror.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A914CC4E11DE47F60038D13C /* tinyxmlerror.cpp */; };
  12 + A914CC5511DE47F60038D13C /* tinyxmlparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A914CC4F11DE47F60038D13C /* tinyxmlparser.cpp */; };
  13 + A914CC5611DE47F60038D13C /* ofxXmlSettings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A914CC5111DE47F60038D13C /* ofxXmlSettings.cpp */; };
  14 + A914CC5C11DE4AB30038D13C /* ofxParticleEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A914CC5B11DE4AB30038D13C /* ofxParticleEmitter.cpp */; };
10 15 E45BE0AA0E8CC67C009D7055 /* GLee.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E45BE0A90E8CC67C009D7055 /* GLee.a */; };
11 16 E45BE2E40E8CC69C009D7055 /* rtAudio.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E45BE2E30E8CC69C009D7055 /* rtAudio.a */; };
12 17 E45BE97B0E8CC7DD009D7055 /* AGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E45BE9710E8CC7DD009D7055 /* AGL.framework */; };
@@ -78,6 +83,15 @@
78 83 /* End PBXCopyFilesBuildPhase section */
79 84
80 85 /* Begin PBXFileReference section */
  86 + A914CC4A11DE47F60038D13C /* install.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = install.xml; sourceTree = "<group>"; };
  87 + A914CC4C11DE47F60038D13C /* tinyxml.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinyxml.cpp; sourceTree = "<group>"; };
  88 + A914CC4D11DE47F60038D13C /* tinyxml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tinyxml.h; sourceTree = "<group>"; };
  89 + A914CC4E11DE47F60038D13C /* tinyxmlerror.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinyxmlerror.cpp; sourceTree = "<group>"; };
  90 + A914CC4F11DE47F60038D13C /* tinyxmlparser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinyxmlparser.cpp; sourceTree = "<group>"; };
  91 + A914CC5111DE47F60038D13C /* ofxXmlSettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ofxXmlSettings.cpp; sourceTree = "<group>"; };
  92 + A914CC5211DE47F60038D13C /* ofxXmlSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ofxXmlSettings.h; sourceTree = "<group>"; };
  93 + A914CC5A11DE4AB30038D13C /* ofxParticleEmitter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ofxParticleEmitter.h; sourceTree = "<group>"; };
  94 + A914CC5B11DE4AB30038D13C /* ofxParticleEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ofxParticleEmitter.cpp; sourceTree = "<group>"; };
81 95 E45BE0390E8CC647009D7055 /* FreeImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FreeImage.h; path = ../../../libs/freeimage/include/FreeImage.h; sourceTree = SOURCE_ROOT; };
82 96 E45BE03F0E8CC650009D7055 /* fmod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fmod.h; path = ../../../libs/fmodex/include/fmod.h; sourceTree = SOURCE_ROOT; };
83 97 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 @@
154 168 /* End PBXFrameworksBuildPhase section */
155 169
156 170 /* Begin PBXGroup section */
  171 + A914CC4711DE47DB0038D13C /* addons */ = {
  172 + isa = PBXGroup;
  173 + children = (
  174 + A914CC4911DE47F60038D13C /* ofxXmlSettings */,
  175 + );
  176 + name = addons;
  177 + sourceTree = "<group>";
  178 + };
  179 + A914CC4911DE47F60038D13C /* ofxXmlSettings */ = {
  180 + isa = PBXGroup;
  181 + children = (
  182 + A914CC4A11DE47F60038D13C /* install.xml */,
  183 + A914CC4B11DE47F60038D13C /* libs */,
  184 + A914CC5011DE47F60038D13C /* src */,
  185 + );
  186 + name = ofxXmlSettings;
  187 + path = ../../../addons/ofxXmlSettings;
  188 + sourceTree = SOURCE_ROOT;
  189 + };
  190 + A914CC4B11DE47F60038D13C /* libs */ = {
  191 + isa = PBXGroup;
  192 + children = (
  193 + A914CC4C11DE47F60038D13C /* tinyxml.cpp */,
  194 + A914CC4D11DE47F60038D13C /* tinyxml.h */,
  195 + A914CC4E11DE47F60038D13C /* tinyxmlerror.cpp */,
  196 + A914CC4F11DE47F60038D13C /* tinyxmlparser.cpp */,
  197 + );
  198 + path = libs;
  199 + sourceTree = "<group>";
  200 + };
  201 + A914CC5011DE47F60038D13C /* src */ = {
  202 + isa = PBXGroup;
  203 + children = (
  204 + A914CC5111DE47F60038D13C /* ofxXmlSettings.cpp */,
  205 + A914CC5211DE47F60038D13C /* ofxXmlSettings.h */,
  206 + );
  207 + path = src;
  208 + sourceTree = "<group>";
  209 + };
157 210 E45BE0360E8CC5DE009D7055 /* libs */ = {
158 211 isa = PBXGroup;
159 212 children = (
@@ -334,6 +387,7 @@
334 387 E4B69B4A0A3A1720003C02F2 = {
335 388 isa = PBXGroup;
336 389 children = (
  390 + A914CC4711DE47DB0038D13C /* addons */,
337 391 E4B69B5B0A3A1756003C02F2 /* particleExampleDebug.app */,
338 392 E4B6FCAD0C3E899E008CF71C /* openFrameworks-Info.plist */,
339 393 E4B69E1C0A3A1BDC003C02F2 /* src */,
@@ -348,6 +402,8 @@
348 402 E4B69E1D0A3A1BDC003C02F2 /* main.cpp */,
349 403 E4B69E1E0A3A1BDC003C02F2 /* testApp.cpp */,
350 404 E4B69E1F0A3A1BDC003C02F2 /* testApp.h */,
  405 + A914CC5A11DE4AB30038D13C /* ofxParticleEmitter.h */,
  406 + A914CC5B11DE4AB30038D13C /* ofxParticleEmitter.cpp */,
351 407 );
352 408 path = src;
353 409 sourceTree = SOURCE_ROOT;
@@ -515,6 +571,11 @@
515 571 files = (
516 572 E4B69E200A3A1BDC003C02F2 /* main.cpp in Sources */,
517 573 E4B69E210A3A1BDC003C02F2 /* testApp.cpp in Sources */,
  574 + A914CC5311DE47F60038D13C /* tinyxml.cpp in Sources */,
  575 + A914CC5411DE47F60038D13C /* tinyxmlerror.cpp in Sources */,
  576 + A914CC5511DE47F60038D13C /* tinyxmlparser.cpp in Sources */,
  577 + A914CC5611DE47F60038D13C /* ofxXmlSettings.cpp in Sources */,
  578 + A914CC5C11DE4AB30038D13C /* ofxParticleEmitter.cpp in Sources */,
518 579 );
519 580 runOnlyForDeploymentPostprocessing = 0;
520 581 };
413 src/ofxParticleEmitter.cpp
... ... @@ -0,0 +1,413 @@
  1 +//
  2 +// ofxParticleEmitter.cpp
  3 +//
  4 +// Copyright (c) 2010 71Squared, ported to Openframeworks by Shawn Roske
  5 +//
  6 +// Permission is hereby granted, free of charge, to any person obtaining a copy
  7 +// of this software and associated documentation files (the "Software"), to deal
  8 +// in the Software without restriction, including without limitation the rights
  9 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 +// copies of the Software, and to permit persons to whom the Software is
  11 +// furnished to do so, subject to the following conditions:
  12 +//
  13 +// The above copyright notice and this permission notice shall be included in
  14 +// all copies or substantial portions of the Software.
  15 +//
  16 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 +// THE SOFTWARE.
  23 +
  24 +#include "ofxParticleEmitter.h"
  25 +
  26 +// ------------------------------------------------------------------------
  27 +// Lifecycle
  28 +// ------------------------------------------------------------------------
  29 +
  30 +ofxParticleEmitter::ofxParticleEmitter()
  31 +{
  32 + settings = NULL;
  33 +
  34 + emitterType = kParticleTypeGravity;
  35 + texture = NULL;
  36 + sourcePosition.x = sourcePosition.y = 0.0f;
  37 + sourcePositionVariance.x = sourcePositionVariance.y = 0.0f;
  38 + angle = angleVariance = 0.0f;
  39 + speed = speedVariance = 0.0f;
  40 + radialAcceleration = tangentialAcceleration = 0.0f;
  41 + radialAccelVariance = tangentialAccelVariance = 0.0f;
  42 + gravity.x = gravity.y = 0.0f;
  43 + particleLifespan = particleLifespanVariance = 0.0f;
  44 + startColor.red = startColor.green = startColor.blue = startColor.alpha = 1.0f;
  45 + startColorVariance.red = startColorVariance.green = startColorVariance.blue = startColorVariance.alpha = 1.0f;
  46 + finishColor.red = finishColor.green = finishColor.blue = finishColor.alpha = 1.0f;
  47 + finishColorVariance.red = finishColorVariance.green = finishColorVariance.blue = finishColorVariance.alpha = 1.0f;
  48 + startParticleSize = startParticleSizeVariance = 0.0f;
  49 + finishParticleSize = finishParticleSizeVariance = 0.0f;
  50 + maxParticles = 0.0f;
  51 + particleCount = 0;
  52 + emissionRate = 0.0f;
  53 + emitCounter = 0.0f;
  54 + elapsedTime = 0.0f;
  55 + duration = -1;
  56 +
  57 + blendFuncSource = blendFuncDestination = 0;
  58 +
  59 + maxRadius = maxRadiusVariance = radiusSpeed = minRadius = 0.0f;
  60 + rotatePerSecond = rotatePerSecondVariance = 0.0f;
  61 +
  62 + active = useTexture = false;
  63 + particleIndex = 0;
  64 +
  65 + verticesID = 0;
  66 + particles = NULL;
  67 + vertices = NULL;
  68 +}
  69 +
  70 +ofxParticleEmitter::~ofxParticleEmitter()
  71 +{
  72 + exit();
  73 +}
  74 +
  75 +void ofxParticleEmitter::exit()
  76 +{
  77 + if ( texture != NULL )
  78 + delete texture;
  79 + texture = NULL;
  80 +
  81 + if ( particles != NULL )
  82 + delete particles;
  83 + particles = NULL;
  84 +
  85 + if ( vertices != NULL )
  86 + delete vertices;
  87 + vertices = NULL;
  88 +
  89 + glDeleteBuffers( 1, &verticesID );
  90 +}
  91 +
  92 +bool ofxParticleEmitter::loadFromXml( const std::string& filename )
  93 +{
  94 + bool ok = false;
  95 +
  96 + settings = new ofxXmlSettings();
  97 +
  98 + ok = settings->loadFile( filename );
  99 + if ( ok )
  100 + {
  101 + parseParticleConfig();
  102 + setupArrays();
  103 +
  104 + ok = active = true;
  105 + }
  106 +
  107 + delete settings;
  108 + settings = NULL;
  109 +
  110 + return ok;
  111 +}
  112 +
  113 +void ofxParticleEmitter::parseParticleConfig()
  114 +{
  115 + if ( settings == NULL )
  116 + {
  117 + ofLog( OF_LOG_ERROR, "ofxParticleEmitter::parseParticleConfig() - XML settings is invalid!" );
  118 + return;
  119 + }
  120 +
  121 + settings->pushTag( "particleEmitterConfig" );
  122 +
  123 + std::string imageFilename = settings->getAttribute( "texture", "name", "" );
  124 + std::string imageData = settings->getAttribute( "texture", "data", "" );
  125 +
  126 + if ( imageFilename != "" )
  127 + {
  128 + ofLog( OF_LOG_WARNING, "ofxParticleEmitter::parseParticleConfig() - loading image file" );
  129 +
  130 + texture = new ofImage();
  131 + texture->loadImage( imageFilename );
  132 + texture->setUseTexture( true );
  133 + }
  134 + else if ( imageData != "" )
  135 + {
  136 + // TODO
  137 +
  138 + ofLog( OF_LOG_ERROR, "ofxParticleEmitter::parseParticleConfig() - image data found but not yet implemented!" );
  139 + return;
  140 + }
  141 +
  142 + emitterType = settings->getAttribute( "emitterType", "value", emitterType );
  143 +
  144 + sourcePosition.x = settings->getAttribute( "sourcePosition", "x", sourcePosition.x );
  145 + sourcePosition.y = settings->getAttribute( "sourcePosition", "y", sourcePosition.y );
  146 +
  147 + speed = settings->getAttribute( "speed", "value", speed );
  148 + speedVariance = settings->getAttribute( "speedVariance", "value", speedVariance );
  149 + particleLifespan = settings->getAttribute( "particleLifespan", "value", particleLifespan );
  150 + particleLifespanVariance = settings->getAttribute( "particleLifespanVariance", "value", particleLifespanVariance );
  151 + angle = settings->getAttribute( "angle", "value", angle );
  152 + angleVariance = settings->getAttribute( "angleVariance", "value", angleVariance );
  153 +
  154 + gravity.x = settings->getAttribute( "gravity", "x", gravity.x );
  155 + gravity.y = settings->getAttribute( "gravity", "y", gravity.y );
  156 +
  157 + radialAcceleration = settings->getAttribute( "radialAcceleration", "value", radialAcceleration );
  158 + tangentialAcceleration = settings->getAttribute( "tangentialAcceleration", "value", tangentialAcceleration );
  159 +
  160 + startColor.red = settings->getAttribute( "startColor", "red", startColor.red );
  161 + startColor.green = settings->getAttribute( "startColor", "green", startColor.green );
  162 + startColor.blue = settings->getAttribute( "startColor", "blue", startColor.blue );
  163 + startColor.alpha = settings->getAttribute( "startColor", "alpha", startColor.alpha );
  164 +
  165 + startColorVariance.red = settings->getAttribute( "startColorVariance", "red", startColorVariance.red );
  166 + startColorVariance.green = settings->getAttribute( "startColorVariance", "green", startColorVariance.green );
  167 + startColorVariance.blue = settings->getAttribute( "startColorVariance", "blue", startColorVariance.blue );
  168 + startColorVariance.alpha = settings->getAttribute( "startColorVariance", "alpha", startColorVariance.alpha );
  169 +
  170 + finishColor.red = settings->getAttribute( "finishColor", "red", finishColor.red );
  171 + finishColor.green = settings->getAttribute( "finishColor", "green", finishColor.green );
  172 + finishColor.blue = settings->getAttribute( "finishColor", "blue", finishColor.blue );
  173 + finishColor.alpha = settings->getAttribute( "finishColor", "alpha", finishColor.alpha );
  174 +
  175 + finishColorVariance.red = settings->getAttribute( "finishColorVariance", "red", finishColorVariance.red );
  176 + finishColorVariance.green = settings->getAttribute( "finishColorVariance", "green", finishColorVariance.green );
  177 + finishColorVariance.blue = settings->getAttribute( "finishColorVariance", "blue", finishColorVariance.blue );
  178 + finishColorVariance.alpha = settings->getAttribute( "finishColorVariance", "alpha", finishColorVariance.alpha );
  179 +
  180 + maxParticles = settings->getAttribute( "maxParticles", "value", maxParticles );
  181 + startParticleSize = settings->getAttribute( "startParticleSize", "value", startParticleSize );
  182 + startParticleSizeVariance = settings->getAttribute( "startParticleSizeVariance", "value", startParticleSizeVariance );
  183 + finishParticleSize = settings->getAttribute( "finishParticleSize", "value", finishParticleSize );
  184 + finishParticleSizeVariance = settings->getAttribute( "finishParticleSizeVariance", "value", finishParticleSizeVariance );
  185 + duration = settings->getAttribute( "duration", "value", duration );
  186 + blendFuncSource = settings->getAttribute( "blendFuncSource", "value", blendFuncSource );
  187 + blendFuncDestination = settings->getAttribute( "blendFuncDestination", "value", blendFuncDestination );
  188 +
  189 + maxRadius = settings->getAttribute( "maxRadius", "value", maxRadius );
  190 + maxRadiusVariance = settings->getAttribute( "maxRadiusVariance", "value", maxRadiusVariance );
  191 + radiusSpeed = settings->getAttribute( "radiusSpeed", "value", radiusSpeed );
  192 + minRadius = settings->getAttribute( "minRadius", "value", minRadius );
  193 +
  194 + rotatePerSecond = settings->getAttribute( "rotatePerSecond", "value", rotatePerSecond );
  195 + rotatePerSecondVariance = settings->getAttribute( "rotatePerSecondVariance", "value", rotatePerSecondVariance );
  196 +
  197 + // Calculate the emission rate
  198 + emissionRate = maxParticles / particleLifespan;
  199 +}
  200 +
  201 +void ofxParticleEmitter::setupArrays()
  202 +{
  203 + // Allocate the memory necessary for the particle emitter arrays
  204 + particles = (Particle*)malloc( sizeof( Particle ) * maxParticles );
  205 + vertices = (PointSprite*)malloc( sizeof( PointSprite ) * maxParticles );
  206 +
  207 + // If one of the arrays cannot be allocated throw an assertion as this is bad
  208 + assert( particles && vertices );
  209 +
  210 + // Generate the vertices VBO
  211 + glGenBuffers( 1, &verticesID );
  212 +
  213 + // Set the particle count to zero
  214 + particleCount = 0;
  215 +
  216 + // Reset the elapsed time
  217 + elapsedTime = 0;
  218 +}
  219 +
  220 +// ------------------------------------------------------------------------
  221 +// Update
  222 +// ------------------------------------------------------------------------
  223 +
  224 +void ofxParticleEmitter::update()
  225 +{
  226 + if ( !active ) return;
  227 +
  228 + // TODO
  229 +
  230 + // need delta
  231 +
  232 + /*
  233 +
  234 + // If the emitter is active and the emission rate is greater than zero then emit
  235 + // particles
  236 + if(active && emissionRate) {
  237 + float rate = 1.0f/emissionRate;
  238 + emitCounter += aDelta;
  239 + while(particleCount < maxParticles && emitCounter > rate) {
  240 + [self addParticle];
  241 + emitCounter -= rate;
  242 + }
  243 +
  244 + elapsedTime += aDelta;
  245 + if(duration != -1 && duration < elapsedTime)
  246 + [self stopParticleEmitter];
  247 + }
  248 +
  249 + // Reset the particle index before updating the particles in this emitter
  250 + particleIndex = 0;
  251 +
  252 + // Loop through all the particles updating their location and color
  253 + while(particleIndex < particleCount) {
  254 +
  255 + // Get the particle for the current particle index
  256 + Particle *currentParticle = &particles[particleIndex];
  257 +
  258 + // FIX 1
  259 + // Reduce the life span of the particle
  260 + currentParticle->timeToLive -= aDelta;
  261 +
  262 + // If the current particle is alive then update it
  263 + if(currentParticle->timeToLive > 0) {
  264 +
  265 + // If maxRadius is greater than 0 then the particles are going to spin otherwise
  266 + // they are effected by speed and gravity
  267 + if (emitterType == kParticleTypeRadial) {
  268 +
  269 + // FIX 2
  270 + // Update the angle of the particle from the sourcePosition and the radius. This is only
  271 + // done of the particles are rotating
  272 + currentParticle->angle += currentParticle->degreesPerSecond * aDelta;
  273 + currentParticle->radius -= currentParticle->radiusDelta;
  274 +
  275 + Vector2f tmp;
  276 + tmp.x = sourcePosition.x - cosf(currentParticle->angle) * currentParticle->radius;
  277 + tmp.y = sourcePosition.y - sinf(currentParticle->angle) * currentParticle->radius;
  278 + currentParticle->position = tmp;
  279 +
  280 + if (currentParticle->radius < minRadius)
  281 + currentParticle->timeToLive = 0;
  282 + } else {
  283 + Vector2f tmp, radial, tangential;
  284 +
  285 + radial = Vector2fZero;
  286 + Vector2f diff = Vector2fSub(currentParticle->startPos, Vector2fZero);
  287 +
  288 + currentParticle->position = Vector2fSub(currentParticle->position, diff);
  289 +
  290 + if (currentParticle->position.x || currentParticle->position.y)
  291 + radial = Vector2fNormalize(currentParticle->position);
  292 +
  293 + tangential.x = radial.x;
  294 + tangential.y = radial.y;
  295 + radial = Vector2fMultiply(radial, currentParticle->radialAcceleration);
  296 +
  297 + GLfloat newy = tangential.x;
  298 + tangential.x = -tangential.y;
  299 + tangential.y = newy;
  300 + tangential = Vector2fMultiply(tangential, currentParticle->tangentialAcceleration);
  301 +
  302 + tmp = Vector2fAdd( Vector2fAdd(radial, tangential), gravity);
  303 + tmp = Vector2fMultiply(tmp, aDelta);
  304 + currentParticle->direction = Vector2fAdd(currentParticle->direction, tmp);
  305 + tmp = Vector2fMultiply(currentParticle->direction, aDelta);
  306 + currentParticle->position = Vector2fAdd(currentParticle->position, tmp);
  307 + currentParticle->position = Vector2fAdd(currentParticle->position, diff);
  308 + }
  309 +
  310 + // Update the particles color
  311 + currentParticle->color.red += currentParticle->deltaColor.red;
  312 + currentParticle->color.green += currentParticle->deltaColor.green;
  313 + currentParticle->color.blue += currentParticle->deltaColor.blue;
  314 + currentParticle->color.alpha += currentParticle->deltaColor.alpha;
  315 +
  316 + // Place the position of the current particle into the vertices array
  317 + vertices[particleIndex].x = currentParticle->position.x;
  318 + vertices[particleIndex].y = currentParticle->position.y;
  319 +
  320 + // Place the size of the current particle in the size array
  321 + currentParticle->particleSize += currentParticle->particleSizeDelta;
  322 + vertices[particleIndex].size = MAX(0, currentParticle->particleSize);
  323 +
  324 + // Place the color of the current particle into the color array
  325 + vertices[particleIndex].color = currentParticle->color;
  326 +
  327 + // Update the particle counter
  328 + particleIndex++;
  329 + } else {
  330 +
  331 + // As the particle is not alive anymore replace it with the last active particle
  332 + // in the array and reduce the count of particles by one. This causes all active particles
  333 + // to be packed together at the start of the array so that a particle which has run out of
  334 + // life will only drop into this clause once
  335 + if(particleIndex != particleCount - 1)
  336 + particles[particleIndex] = particles[particleCount - 1];
  337 + particleCount--;
  338 + }
  339 + }
  340 +
  341 + */
  342 +}
  343 +
  344 +// ------------------------------------------------------------------------
  345 +// Render
  346 +// ------------------------------------------------------------------------
  347 +
  348 +void ofxParticleEmitter::draw(int x /* = 0 */, int y /* = 0 */)
  349 +{
  350 + if ( !active ) return;
  351 +
  352 + ofSetColor( 255, 255, 255 );
  353 +
  354 + ofEnableAlphaBlending();
  355 + texture->draw( x, y );
  356 + ofDisableAlphaBlending();
  357 +
  358 + /*
  359 + // Disable the texture coord array so that texture information is not copied over when rendering
  360 + // the point sprites.
  361 + glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  362 +
  363 + // Bind to the verticesID VBO and popuate it with the necessary vertex & color informaiton
  364 + glBindBuffer(GL_ARRAY_BUFFER, verticesID);
  365 + glBufferData(GL_ARRAY_BUFFER, sizeof(PointSprite) * maxParticles, vertices, GL_DYNAMIC_DRAW);
  366 +
  367 + // Configure the vertex pointer which will use the currently bound VBO for its data
  368 + glVertexPointer(2, GL_FLOAT, sizeof(PointSprite), 0);
  369 + glColorPointer(4,GL_FLOAT,sizeof(PointSprite),(GLvoid*) (sizeof(GLfloat)*3));
  370 +
  371 + // Bind to the particles texture
  372 + glBindTexture(GL_TEXTURE_2D, texture.name);
  373 +
  374 + // Enable the point size array
  375 + glEnableClientState(GL_POINT_SIZE_ARRAY_OES);
  376 +
  377 + // Configure the point size pointer which will use the currently bound VBO. PointSprite contains
  378 + // both the location of the point as well as its size, so the config below tells the point size
  379 + // pointer where in the currently bound VBO it can find the size for each point
  380 + glPointSizePointerOES(GL_FLOAT,sizeof(PointSprite),(GLvoid*) (sizeof(GL_FLOAT)*2));
  381 +
  382 + // Change the blend function used if blendAdditive has been set
  383 +
  384 + // Set the blend function based on the configuration
  385 + glBlendFunc(blendFuncSource, blendFuncDestination);
  386 +
  387 + // Enable and configure point sprites which we are going to use for our particles
  388 + glEnable(GL_POINT_SPRITE_OES);
  389 + glTexEnvi( GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_TRUE );
  390 +
  391 + // Now that all of the VBOs have been used to configure the vertices, pointer size and color
  392 + // use glDrawArrays to draw the points
  393 + glDrawArrays(GL_POINTS, 0, particleIndex);
  394 +
  395 + // Unbind the current VBO
  396 + glBindBuffer(GL_ARRAY_BUFFER, 0);
  397 +
  398 + // Disable the client states which have been used incase the next draw function does
  399 + // not need or use them
  400 + glDisableClientState(GL_POINT_SIZE_ARRAY_OES);
  401 + glDisable(GL_POINT_SPRITE_OES);
  402 +
  403 + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  404 +
  405 + // Re-enable the texture coordinates as we use them elsewhere in the game and it is expected that
  406 + // its on
  407 + glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  408 +
  409 + */
  410 +}
  411 +
  412 +
  413 +
144 src/ofxParticleEmitter.h
... ... @@ -0,0 +1,144 @@
  1 +//
  2 +// ofxParticleEmitter.h
  3 +//
  4 +// Copyright (c) 2010 71Squared, ported to Openframeworks by Shawn Roske
  5 +//
  6 +// Permission is hereby granted, free of charge, to any person obtaining a copy
  7 +// of this software and associated documentation files (the "Software"), to deal
  8 +// in the Software without restriction, including without limitation the rights
  9 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 +// copies of the Software, and to permit persons to whom the Software is
  11 +// furnished to do so, subject to the following conditions:
  12 +//
  13 +// The above copyright notice and this permission notice shall be included in
  14 +// all copies or substantial portions of the Software.
  15 +//
  16 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 +// THE SOFTWARE.
  23 +
  24 +#ifndef _OFX_PARTICLE_EMITTER
  25 +#define _OFX_PARTICLE_EMITTER
  26 +
  27 +#include "ofMain.h"
  28 +#include "ofxXmlSettings.h"
  29 +
  30 +// Structure that defines the elements which make up a color
  31 +typedef struct {
  32 + GLfloat red;
  33 + GLfloat green;
  34 + GLfloat blue;
  35 + GLfloat alpha;
  36 +} Color4f;
  37 +
  38 +// Structure that defines a vector using x and y
  39 +typedef struct {
  40 + GLfloat x;
  41 + GLfloat y;
  42 +} Vector2f;
  43 +
  44 +// Particle type
  45 +enum kParticleTypes
  46 +{
  47 + kParticleTypeGravity,
  48 + kParticleTypeRadial
  49 +};
  50 +
  51 +// Structure that holds the location and size for each point sprite
  52 +typedef struct
  53 +{
  54 + GLfloat x;
  55 + GLfloat y;
  56 + GLfloat size;
  57 + Color4f color;
  58 +} PointSprite;
  59 +
  60 +// Structure used to hold particle specific information
  61 +typedef struct
  62 +{
  63 + Vector2f position;
  64 + Vector2f direction;
  65 + Vector2f startPos;
  66 + Color4f color;
  67 + Color4f deltaColor;
  68 + GLfloat radialAcceleration;
  69 + GLfloat tangentialAcceleration;
  70 + GLfloat radius;
  71 + GLfloat radiusDelta;
  72 + GLfloat angle;
  73 + GLfloat degreesPerSecond;
  74 + GLfloat particleSize;
  75 + GLfloat particleSizeDelta;
  76 + GLfloat timeToLive;
  77 +} Particle;
  78 +
  79 +#define MAXIMUM_UPDATE_RATE 90.0f // The maximum number of updates that occur per frame
  80 +
  81 +class ofxParticleEmitter
  82 +{
  83 +
  84 +public:
  85 +
  86 + ofxParticleEmitter();
  87 + ~ofxParticleEmitter();
  88 +
  89 + bool loadFromXml( const std::string& filename );
  90 + void update();
  91 + void draw( int x = 0, int y = 0 );
  92 + void exit();
  93 +
  94 +protected:
  95 +
  96 + void parseParticleConfig();
  97 + void setupArrays();
  98 +
  99 + ofxXmlSettings* settings;
  100 +
  101 + int emitterType;
  102 + ofImage* texture;
  103 + Vector2f sourcePosition, sourcePositionVariance;
  104 + GLfloat angle, angleVariance;
  105 + GLfloat speed, speedVariance;
  106 + GLfloat radialAcceleration, tangentialAcceleration;
  107 + GLfloat radialAccelVariance, tangentialAccelVariance;
  108 + Vector2f gravity;
  109 + GLfloat particleLifespan, particleLifespanVariance;
  110 + Color4f startColor, startColorVariance;
  111 + Color4f finishColor, finishColorVariance;
  112 + GLfloat startParticleSize, startParticleSizeVariance;
  113 + GLfloat finishParticleSize, finishParticleSizeVariance;
  114 + GLint maxParticles;
  115 + GLint particleCount;
  116 + GLfloat emissionRate;
  117 + GLfloat emitCounter;
  118 + GLfloat elapsedTime;
  119 + GLfloat duration;
  120 +
  121 + int blendFuncSource, blendFuncDestination;
  122 +
  123 + //////////////////// Particle ivars only used when a maxRadius value is provided. These values are used for
  124 + //////////////////// the special purpose of creating the spinning portal emitter
  125 + GLfloat maxRadius; // Max radius at which particles are drawn when rotating
  126 + GLfloat maxRadiusVariance; // Variance of the maxRadius
  127 + GLfloat radiusSpeed; // The speed at which a particle moves from maxRadius to minRadius
  128 + GLfloat minRadius; // Radius from source below which a particle dies
  129 + GLfloat rotatePerSecond; // Numeber of degress to rotate a particle around the source pos per second
  130 + GLfloat rotatePerSecondVariance; // Variance in degrees for rotatePerSecond
  131 +
  132 + //////////////////// Particle Emitter iVars
  133 + bool active, useTexture;
  134 + GLint particleIndex; // Stores the number of particles that are going to be rendered
  135 +
  136 +
  137 + ///////////////////// Render
  138 + GLuint verticesID; // Holds the buffer name of the VBO that stores the color and vertices info for the particles
  139 + Particle* particles; // Array of particles that hold the particle emitters particle details
  140 + PointSprite* vertices; // Array of vertices and color information for each particle to be rendered
  141 +
  142 +};
  143 +
  144 +#endif
128 src/testApp.cpp
@@ -4,120 +4,76 @@
4 4 //--------------------------------------------------------------
5 5 void testApp::setup()
6 6 {
7   - counter = 0;
8   - ofSetCircleResolution(50);
9   - ofBackground(255,255,255);
10   - bSmooth = false;
11   - ofSetWindowTitle("particle example");
12   -
13   - ofSetFrameRate(60); // if vertical sync is off, we can go a bit fast... this caps the framerate at 60fps.
  7 + ofSetWindowTitle( "particle example" );
  8 + ofBackground( 120, 120, 120 );
  9 +
  10 + if ( !m_emitter.loadFromXml( "circles.pex" ) )
  11 + {
  12 + ofLog( OF_LOG_ERROR, "testApp::setup() - failed to load emitter config" );
  13 + }
14 14 }
15 15
16 16 //--------------------------------------------------------------
17   -void testApp::update(){
18   - counter = counter + 0.033f;
  17 +void testApp::exit()
  18 +{
  19 + // TODO
19 20 }
20 21
21 22 //--------------------------------------------------------------
22   -void testApp::draw(){
23   -
24   - //--------------------------- circles
25   - //let's draw a circle:
26   - ofSetColor(255,130,0);
27   - float radius = 50 + 10 * sin(counter);
28   - ofFill(); // draw "filled shapes"
29   - ofCircle(100,400,radius);
30   -
31   - // now just an outline
32   - ofNoFill();
33   - ofSetColor(0xCCCCCC);
34   - ofCircle(100,400,80);
35   -
36   - // use the bitMap type
37   - // note, this can be slow on some graphics cards
38   - // because it is using glDrawPixels which varies in
39   - // speed from system to system. try using ofTrueTypeFont
40   - // if this bitMap type slows you down.
41   - ofSetColor(0x000000);
42   - ofDrawBitmapString("circle", 75,500);
43   -
44   -
45   - //--------------------------- rectangles
46   - ofFill();
47   - for (int i = 0; i < 200; i++){
48   - ofSetColor((int)ofRandom(0,255),(int)ofRandom(0,255),(int)ofRandom(0,255));
49   - ofRect(ofRandom(250,350),ofRandom(350,450),ofRandom(10,20),ofRandom(10,20));
50   - }
51   - ofSetColor(0x000000);
52   - ofDrawBitmapString("rectangles", 275,500);
53   -
54   - //--------------------------- transparency
55   - ofSetColor(0x00FF33);
56   - ofRect(400,350,100,100);
57   - // alpha is usually turned off - for speed puposes. let's turn it on!
58   - ofEnableAlphaBlending();
59   - ofSetColor(255,0,0,127); // red, 50% transparent
60   - ofRect(450,430,100,33);
61   - ofSetColor(255,0,0,(int)(counter * 10.0f) % 255); // red, variable transparent
62   - ofRect(450,370,100,33);
63   - ofDisableAlphaBlending();
64   -
65   - ofSetColor(0x000000);
66   - ofDrawBitmapString("transparency", 410,500);
67   -
68   - //--------------------------- lines
69   - // a bunch of red lines, make them smooth if the flag is set
70   -
71   - if (bSmooth){
72   - ofEnableSmoothing();
73   - }
74   -
75   - ofSetColor(0xFF0000);
76   - for (int i = 0; i < 20; i++){
77   - ofLine(600,300 + (i*5),800, 250 + (i*10));
78   - }
79   -
80   - if (bSmooth){
81   - ofDisableSmoothing();
82   - }
83   -
84   - ofSetColor(0x000000);
85   - ofDrawBitmapString("lines\npress 's' to toggle smoothness", 600,500);
  23 +void testApp::update()
  24 +{
  25 + m_emitter.update();
  26 +}
86 27
  28 +//--------------------------------------------------------------
  29 +void testApp::draw()
  30 +{
  31 + m_emitter.draw( ofGetScreenWidth()*0.5f, ofGetScreenHeight()*0.5f );
  32 +
  33 + ofSetColor( 255, 255, 255 );
  34 + ofDrawBitmapString( "fps: " + ofToString( ofGetFrameRate(), 2 ), 20, 20 );
87 35 }
88 36
89 37
90 38 //--------------------------------------------------------------
91   -void testApp::keyPressed (int key){
92   - if (key == 's'){
93   - bSmooth = !bSmooth;
94   - }
  39 +void testApp::keyPressed (int key)
  40 +{
  41 + // nothing
95 42 }
96 43
97 44 //--------------------------------------------------------------
98   -void testApp::keyReleased (int key){
99   -
  45 +void testApp::keyReleased (int key)
  46 +{
  47 + // nothing
100 48 }
101 49
102 50 //--------------------------------------------------------------
103   -void testApp::mouseMoved(int x, int y ){
  51 +void testApp::mouseMoved(int x, int y )
  52 +{
  53 + // nothing
104 54 }
105 55
106 56 //--------------------------------------------------------------
107   -void testApp::mouseDragged(int x, int y, int button){
  57 +void testApp::mouseDragged(int x, int y, int button)
  58 +{
  59 + // nothing
108 60 }
109 61
110 62 //--------------------------------------------------------------
111   -void testApp::mousePressed(int x, int y, int button){
  63 +void testApp::mousePressed(int x, int y, int button)
  64 +{
  65 + // nothing
112 66 }
113 67
114 68
115 69 //--------------------------------------------------------------
116   -void testApp::mouseReleased(int x, int y, int button){
117   -
  70 +void testApp::mouseReleased(int x, int y, int button)
  71 +{
  72 + // nothing
118 73 }
119 74
120 75 //--------------------------------------------------------------
121   -void testApp::windowResized(int w, int h){
122   -
  76 +void testApp::windowResized(int w, int h)
  77 +{
  78 + // nothing
123 79 }
39 src/testApp.h
@@ -3,25 +3,30 @@
3 3
4 4
5 5 #include "ofMain.h"
  6 +#include "ofxParticleEmitter.h"
6 7
7   -class testApp : public ofBaseApp{
  8 +class testApp : public ofBaseApp
  9 +{
  10 +
  11 +public:
  12 +
  13 + void setup();
  14 + void update();
  15 + void draw();
  16 + void exit();
  17 +
  18 + void keyPressed( int key );
  19 + void keyReleased( int key );
  20 + void mouseMoved( int x, int y );
  21 + void mouseDragged( int x, int y, int button );
  22 + void mousePressed( int x, int y, int button );
  23 + void mouseReleased( int x, int y, int button );
  24 + void windowResized( int w, int h );
  25 +
  26 +protected:
  27 +
  28 + ofxParticleEmitter m_emitter;
8 29
9   - public:
10   -
11   - void setup();
12   - void update();
13   - void draw();
14   -
15   - void keyPressed(int key);
16   - void keyReleased(int key);
17   - void mouseMoved(int x, int y );
18   - void mouseDragged(int x, int y, int button);
19   - void mousePressed(int x, int y, int button);
20   - void mouseReleased(int x, int y, int button);
21   - void windowResized(int w, int h);
22   -
23   - float counter;
24   - bool bSmooth;
25 30 };
26 31
27 32 #endif

0 comments on commit fc2836a

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