diff --git a/platform/msvc2008/graphics/graphics.vcproj b/platform/msvc2008/graphics/graphics.vcproj index f5edfdd0e..a2a5d9c73 100644 --- a/platform/msvc2008/graphics/graphics.vcproj +++ b/platform/msvc2008/graphics/graphics.vcproj @@ -172,6 +172,18 @@ + + + + + @@ -269,6 +281,22 @@ RelativePath="..\..\..\src\modules\graphics\opengl\ImageFont.h" > + + + + + + + @@ -373,6 +401,22 @@ RelativePath="..\..\..\src\modules\graphics\opengl\wrap_Image.h" > + + + + + + + @@ -398,18 +442,6 @@ > - - - - - diff --git a/platform/msvc2008/love.vcproj b/platform/msvc2008/love.vcproj index b406fa9e3..77b3c0991 100644 --- a/platform/msvc2008/love.vcproj +++ b/platform/msvc2008/love.vcproj @@ -925,6 +925,22 @@ RelativePath="..\..\src\modules\graphics\opengl\ImageFont.h" > + + + + + + + @@ -1045,6 +1061,22 @@ RelativePath="..\..\src\modules\graphics\opengl\wrap_Image.h" > + + + + + + + diff --git a/src/modules/graphics/opengl/ParticleSystem.cpp b/src/modules/graphics/opengl/ParticleSystem.cpp new file mode 100644 index 000000000..fef667741 --- /dev/null +++ b/src/modules/graphics/opengl/ParticleSystem.cpp @@ -0,0 +1,498 @@ +/** +* Copyright (c) 2006-2009 LOVE Development Team +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +**/ + +#include "ParticleSystem.h" + +#include +#include +#include +#include + +namespace love +{ +namespace graphics +{ +namespace opengl +{ + + float calculate_variation(float inner, float outer, float var) + { + float low = inner - (outer/2.0f)*var; + float high = inner + (outer/2.0f)*var; + float r = (rand() / (float(RAND_MAX)+1)); + return low*(1-r)+high*r; + } + + + ParticleSystem::ParticleSystem(Image * sprite, unsigned int buffer) : pStart(0), pLast(0), pEnd(0), active(true), emissionRate(0), + emitCounter(0), lifetime(-1), life(0), particleLifeMin(0), particleLifeMax(0), + direction(0), spread(0), relative(false), speedMin(0), speedMax(0), gravityMin(0), + gravityMax(0), radialAccelerationMin(0), radialAccelerationMax(0), + tangentialAccelerationMin(0), tangentialAccelerationMax(0), + sizeStart(1), sizeEnd(1), sizeVariation(0), rotationMin(0), rotationMax(0), + spinStart(0), spinEnd(0), spinVariation(0) + { + this->sprite = sprite; + sprite->retain(); + memset(colorStart, 255, 4); + memset(colorEnd, 255, 4); + setBufferSize(buffer); + } + + ParticleSystem::~ParticleSystem() + { + if(this->sprite != 0) + { + this->sprite->release(); + this->sprite = 0; + } + + if(pStart != 0) + delete [] pStart; + } + + void ParticleSystem::add() + { + if(isFull()) return; + + float min,max; + + min = particleLifeMin; + max = particleLifeMax; + if(min == max) + pLast->life = min; + else + pLast->life = (rand() / (float(RAND_MAX)+1)) * (max - min) + min; + pLast->lifetime = pLast->life; + + pLast->position[0] = position.getX(); + pLast->position[1] = position.getY(); + + min = direction - spread/2.0f; + max = direction + spread/2.0f; + pLast->direction = (rand() / (float(RAND_MAX)+1)) * (max - min) + min; + + min = speedMin; + max = speedMax; + float speed = (rand() / (float(RAND_MAX)+1)) * (max - min) + min; + pLast->speed = love::Vector(cos(pLast->direction), sin(pLast->direction)); + pLast->speed *= speed; + + min = gravityMin; + max = gravityMax; + pLast->gravity = (rand() / (float(RAND_MAX)+1)) * (max - min) + min; + + min = radialAccelerationMin; + max = radialAccelerationMax; + pLast->radialAcceleration = (rand() / (float(RAND_MAX)+1)) * (max - min) + min; + + min = tangentialAccelerationMin; + max = tangentialAccelerationMax; + pLast->tangentialAcceleration = (rand() / (float(RAND_MAX)+1)) * (max - min) + min; + + pLast->sizeStart = calculate_variation(sizeStart, sizeEnd, sizeVariation); + pLast->sizeEnd = calculate_variation(sizeEnd, sizeStart, sizeVariation); + pLast->size = pLast->sizeStart; + + min = rotationMin; + max = rotationMax; + pLast->spinStart = calculate_variation(spinStart, spinEnd, spinVariation); + pLast->spinEnd = calculate_variation(spinEnd, spinStart, spinVariation); + pLast->rotation = (rand() / (float(RAND_MAX)+1)) * (max - min) + min;; + + pLast->color[0] = (float)colorStart[0] / 255; + pLast->color[1] = (float)colorStart[1] / 255; + pLast->color[2] = (float)colorStart[2] / 255; + pLast->color[3] = (float)colorStart[3] / 255; + + pLast++; + } + + void ParticleSystem::remove(particle * p) + { + if(!isEmpty()) + { + *p = *(--pLast); + } + } + + void ParticleSystem::setSprite(Image * image) + { + if(this->sprite != 0) + { + this->sprite->release(); + this->sprite = 0; + } + + this->sprite = image; + } + + void ParticleSystem::setBufferSize(unsigned int size) + { + // delete previous data + delete [] pStart; + + pLast = pStart = new particle[size]; + + pEnd = pStart + size; + } + + void ParticleSystem::setEmissionRate(int rate) + { + emissionRate = rate; + } + + void ParticleSystem::setLifetime(float life) + { + this->life = lifetime = life; + } + + void ParticleSystem::setParticleLife(float min, float max) + { + particleLifeMin = min; + if(max == 0) + particleLifeMax = min; + else + particleLifeMax = max; + } + + void ParticleSystem::setPosition(float x, float y) + { + position = love::Vector(x, y); + } + + void ParticleSystem::setDirection(float direction) + { + this->direction = direction * LOVE_M_TORAD; + } + + void ParticleSystem::setSpread(float spread) + { + this->spread = spread * LOVE_M_TORAD; + } + + void ParticleSystem::setRelativeDirection(bool relative) + { + this->relative = relative; + } + + void ParticleSystem::setSpeed(float speed) + { + speedMin = speedMax = speed; + } + + void ParticleSystem::setSpeed(float min, float max) + { + speedMin = min; + speedMax = max; + } + + void ParticleSystem::setGravity(float gravity) + { + gravityMin = gravityMax = gravity; + } + + void ParticleSystem::setGravity(float min, float max) + { + gravityMin = min; + gravityMax = max; + } + + void ParticleSystem::setRadialAcceleration(float acceleration) + { + radialAccelerationMin = radialAccelerationMax = acceleration; + } + + void ParticleSystem::setRadialAcceleration(float min, float max) + { + radialAccelerationMin = min; + radialAccelerationMax = max; + } + + void ParticleSystem::setTangentialAcceleration(float acceleration) + { + tangentialAccelerationMin = tangentialAccelerationMax = acceleration; + } + + void ParticleSystem::setTangentialAcceleration(float min, float max) + { + tangentialAccelerationMin = min; + tangentialAccelerationMax = max; + } + + void ParticleSystem::setSize(float size) + { + sizeStart = size; + sizeEnd = size; + } + + void ParticleSystem::setSize(float start, float end) + { + sizeStart = start; + sizeEnd = end; + } + + void ParticleSystem::setSize(float start, float end, float variation) + { + sizeStart = start; + sizeEnd = end; + sizeVariation = variation; + } + + void ParticleSystem::setSizeVariation(float variation) + { + sizeVariation = variation; + } + + void ParticleSystem::setRotation(float rotation) + { + rotationMin = rotationMax = rotation; + } + + void ParticleSystem::setRotation(float min, float max) + { + rotationMin = min; + rotationMax = max; + } + + void ParticleSystem::setSpin(float spin) + { + spinStart = spin * LOVE_M_TORAD; + spinEnd = spin * LOVE_M_TORAD; + } + + void ParticleSystem::setSpin(float start, float end) + { + spinStart = start * LOVE_M_TORAD; + spinEnd = end * LOVE_M_TORAD; + } + + void ParticleSystem::setSpin(float start, float end, float variation) + { + spinStart = start * LOVE_M_TORAD; + spinEnd = end * LOVE_M_TORAD; + spinVariation = variation * LOVE_M_TORAD; + } + + void ParticleSystem::setSpinVariation(float variation) + { + spinVariation = variation * LOVE_M_TORAD; + } + + void ParticleSystem::setColor(unsigned char * color) + { + memcpy(colorStart, color, 4); + memcpy(colorEnd, color, 4); + } + + void ParticleSystem::setColor(unsigned char * start, unsigned char * end) + { + memcpy(colorStart, start, 4); + memcpy(colorEnd, end, 4); + } + + float ParticleSystem::getX() const + { + return position.getX(); + } + + float ParticleSystem::getY() const + { + return position.getY(); + } + + float ParticleSystem::getDirection() const + { + return direction * LOVE_M_TODEG; + } + + float ParticleSystem::getSpread() const + { + return spread * LOVE_M_TODEG; + } + + int ParticleSystem::count() const + { + return (int)(pLast - pStart); + } + + void ParticleSystem::start() + { + active = true; + } + + void ParticleSystem::stop() + { + active = false; + life = lifetime; + emitCounter = 0; + } + + void ParticleSystem::pause() + { + active = false; + } + + void ParticleSystem::reset() + { + pLast = pStart; + life = lifetime; + emitCounter = 0; + } + + bool ParticleSystem::isActive() const + { + return active; + } + + bool ParticleSystem::isEmpty() const + { + return pStart == pLast; + } + + bool ParticleSystem::isFull() const + { + return pLast == pEnd; + } + + void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, float ox, float oy) const + { + if(sprite == 0) return; // just in case of failure + + glPushMatrix(); + glPushAttrib(GL_CURRENT_BIT); + + glTranslatef(x, y, 0); + glRotatef(angle, 0, 0, 1.0f); + glScalef(sx, sy, 1.0f); + glTranslatef( ox, oy, 0); + + particle * p = pStart; + while(p != pLast) + { + glPushMatrix(); + + glColor4f(p->color[0],p->color[1],p->color[2],p->color[3]); + glTranslatef(p->position[0],p->position[1],0.0f); + glRotatef(p->rotation * 57.29578f, 0.0f, 0.0f, 1.0f); // rad * (180 / pi) + glScalef(p->size,p->size,1.0f); + sprite->draw(0,0, 0, 1, 1, 0, 0); + + glPopMatrix(); + p++; + } + + glPopAttrib(); + glPopMatrix(); + } + + void ParticleSystem::update(float dt) + { + // Traverse all particles and update. + particle * p = pStart; + + // Make some more particles. + if(active) + { + float rate = 1.0f / emissionRate; // the amount of time between each particle emit + emitCounter += dt; + while(emitCounter > rate) + { + add(); + emitCounter -= rate; + } + /*int particles = (int)(emissionRate * dt); + for(int i = 0; i != particles; i++) + add();*/ + + life -= dt; + if(lifetime != -1 && life < 0) + stop(); + } + + while(p != pLast) + { + // Decrease lifespan. + p->life -= dt; + + if(p->life > 0) + { + + // Temp variables. + love::Vector radial, tangential, gravity(0, p->gravity); + love::Vector ppos(p->position[0], p->position[1]); + + // Get vector from particle center to particle. + radial = ppos - position; + radial.normalize(); + tangential = radial; + + // Resize radial acceleration. + radial *= p->radialAcceleration; + + // Calculate tangential acceleration. + { + float a = tangential.getX(); + tangential.setX(-tangential.getY()); + tangential.setY(a); + } + + // Resize tangential. + tangential *= p->tangentialAcceleration; + + // Update position. + p->speed += (radial+tangential+gravity)*dt; + + // Modify position. + ppos += p->speed * dt; + + p->position[0] = ppos.getX(); + p->position[1] = ppos.getY(); + + const float t = p->life / p->lifetime; + + // Change size. + p->size = p->sizeEnd - ((p->sizeEnd - p->sizeStart) * t); + + // Rotate. + p->rotation += (p->spinStart*(1-t) + p->spinEnd*t)*dt; + + // Update color. + p->color[0] = (float)(colorEnd[0]*(1.0f-t) + colorStart[0] * t)/255.0f; + p->color[1] = (float)(colorEnd[1]*(1.0f-t) + colorStart[1] * t)/255.0f; + p->color[2] = (float)(colorEnd[2]*(1.0f-t) + colorStart[2] * t)/255.0f; + p->color[3] = (float)(colorEnd[3]*(1.0f-t) + colorStart[3] * t)/255.0f; + + // Next particle. + p++; + } + else + { + remove(p); + + if(p >= pLast) + return; + } // else + } // while + } + +} // opengl +} // graphics +} // love diff --git a/src/modules/graphics/opengl/ParticleSystem.h b/src/modules/graphics/opengl/ParticleSystem.h new file mode 100644 index 000000000..936a38b1a --- /dev/null +++ b/src/modules/graphics/opengl/ParticleSystem.h @@ -0,0 +1,429 @@ +/** +* Copyright (c) 2006-2009 LOVE Development Team +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +**/ + +#ifndef LOVE_GRAPHICS_OPENGL_PARTICLE_SYSTEM_H +#define LOVE_GRAPHICS_OPENGL_PARTICLE_SYSTEM_H + +// LOVE + +#include +#include +#include +#include "Image.h" + +namespace love +{ +namespace graphics +{ +namespace opengl +{ + + // Represents a single particle. + struct particle + { + float lifetime; + float life; + + float position[2]; + float direction; + + love::Vector speed; + float gravity; + float radialAcceleration; + float tangentialAcceleration; + + float size; + float sizeStart; + float sizeEnd; + + float rotation; + float spinStart; + float spinEnd; + + float color[4]; + }; + + /** + * A class for creating, moving and drawing particles. + * A big thanks to bobthebloke.org + **/ + class ParticleSystem : public Drawable + { + protected: + + // The max amount of particles. + unsigned int bufferSize; + + // Pointer to the first particle. + particle * pStart; + + // Pointer to the next available free space. + particle * pLast; + + // Pointer to the end of the memory allocation. + particle * pEnd; + + // The sprite to be drawn. + Image * sprite; + + // Whether the particle emitter is active. + bool active; + + // The emission rate (particles/sec). + int emissionRate; + + // Used to determine when a particle should be emitted. + float emitCounter; + + // The relative position of the particle emitter. + love::Vector position; + + // The lifetime of the particle emitter (-1 means infinite) and the life it has left. + float lifetime; + float life; + + // The particle life. + float particleLifeMin; + float particleLifeMax; + + // The direction (and spread) the particles will be emitted in. Measured in radians. + float direction; + float spread; + + // Whether the direction should be relative to the emitter's movement. + bool relative; + + // The speed. + float speedMin; + float speedMax; + + // Acceleration towards the bottom of the screen + float gravityMin; + float gravityMax; + + // Acceleration towards the emitter's center + float radialAccelerationMin; + float radialAccelerationMax; + + // Acceleration perpendicular to the particle's direction. + float tangentialAccelerationMin; + float tangentialAccelerationMax; + + // Size. + float sizeStart; + float sizeEnd; + float sizeVariation; + + // Rotation + float rotationMin; + float rotationMax; + + // Spin. + float spinStart; + float spinEnd; + float spinVariation; + + // Color. + unsigned char colorStart[4]; + unsigned char colorEnd[4]; + + void add(); + void remove(particle * p); + + public: + + /** + * Creates a particle system with the specified buffersize and sprite. + **/ + ParticleSystem(Image * sprite, unsigned int buffer); + + /** + * Deletes any allocated memory. + **/ + virtual ~ParticleSystem(); + + /** + * Sets the sprite used in the particle system. + * @param sprite The new sprite. + **/ + void setSprite(Image * image); + + /** + * Clears the current buffer and allocates the appropriate amount of space for the buffer. + * @param size The new buffer size. + **/ + void setBufferSize(unsigned int size); + + /** + * Sets the emission rate. + * @param rate The amount of particles per second. + **/ + void setEmissionRate(int rate); + + /** + * Sets the lifetime of the particle emitter (-1 means eternal) + * @param life The lifetime (in seconds). + **/ + void setLifetime(float life); + + /** + * Sets the life range of the particles. + * @param lifeMin The minimum life. + * @param lifeMax The maximum life (if 0, then becomes the same as minimum life). + **/ + void setParticleLife(float min, float max = 0); + + /** + * Sets the position of the center of the emitter and the direction (if set to relative). + * Used to move the emitter without changing the position of already existing particles. + * @param x The x-coordinate. + * @param y The y-coordinate. + **/ + void setPosition(float x, float y); + + /** + * Sets the direction and the spread of the particle emitter. + * @param direction The direction (in degrees). + **/ + void setDirection(float direction); + + /** + * Sets the spread of the particle emitter. + * @param spread The spread (in degrees). + **/ + void setSpread(float spread); + + /** + * Sets whether the direction should be relative to the particle emitters movement. Used in conjunction with setPosition. + * @param relative Whether to have relative direction. + **/ + void setRelativeDirection(bool relative); + + /** + * Sets the speed of the particles. + * @param speed The speed. + **/ + void setSpeed(float speed); + + /** + * Sets the speed of the particles. + * @param min The minimum speed. + * @param max The maximum speed. + **/ + void setSpeed(float min, float max); + + /** + * Sets the gravity of the particles (the acceleration along the y-axis). + * @param gravity The amount of gravity. + **/ + void setGravity(float gravity); + + /** + * Sets the gravity of the particles (the acceleration along the y-axis). + * @param min The minimum gravity. + * @param max The maximum gravity. + **/ + void setGravity(float min, float max); + + /** + * Sets the radial acceleration (the acceleration towards the particle emitter). + * @param acceleration The amount of acceleration. + **/ + void setRadialAcceleration(float acceleration); + + /** + * Sets the radial acceleration (the acceleration towards the particle emitter). + * @param min The minimum acceleration. + * @param max The maximum acceleration. + **/ + void setRadialAcceleration(float min, float max); + + /** + * Sets the tangential acceleration (the acceleration perpendicular to the particle's direction). + * @param acceleration The amount of acceleration. + **/ + void setTangentialAcceleration(float acceleration); + + /** + * Sets the tangential acceleration (the acceleration perpendicular to the particle's direction). + * @param min The minimum acceleration. + * @param max The maximum acceleration. + **/ + void setTangentialAcceleration(float min, float max); + + /** + * Sets the size of the sprite (1.0 being the default size). + * @param size The size of the sprite. + **/ + void setSize(float size); + + /** + * Sets the size of the sprite upon creation and upon death (1.0 being the default size). + * @param start The size of the sprite upon creation + * @param end The size of the sprite upon death. + **/ + void setSize(float start, float end); + + /** + * Sets the size of the sprite upon creation and upon death (1.0 being the default size) and any variation. + * @param start The size of the sprite upon creation + * @param end The size of the sprite upon death. + * @param variation The amount of variation on the starting size (0 being no variation and 1.0 a random size between start and end). + **/ + void setSize(float start, float end, float variation); + + /** + * Sets the amount of variation to the sprite's beginning size (0 being no variation and 1.0 a random size between start and end). + * @param variation The amount of variation. + **/ + void setSizeVariation(float variation); + + /** + * Sets the amount of rotation a sprite starts out with. + * @param rotation The amount of rotation. + **/ + void setRotation(float rotation); + + /** + * Sets the amount of rotation a sprite starts out with (a random value between min and max). + * @param min The minimum amount of rotation. + * @param max The maximum amount of rotation. + **/ + void setRotation(float min, float max); + + /** + * Sets the spin of the sprite. + * @param spin The spin of the sprite (in degrees). + **/ + void setSpin(float spin); + + /** + * Sets the spin of the sprite upon particle creation and death. + * @param start The spin of the sprite upon creation (in degrees). + * @param end The spin of the sprite upon death (in degrees). + **/ + void setSpin(float start, float end); + + /** + * Sets the spin of the sprite upon particle creation and death and the variation. + * @param start The spin of the sprite upon creation (in degrees). + * @param end The spin of the sprite upon death (in degrees). + * @param variation The variation of the start spin (0 being no variation and 1 beign a random spin between start and end). + **/ + void setSpin(float start, float end, float variation); + + /** + * Sets the variation of the start spin (0 being no variation and 1 beign a random spin between start and end). + * @param variation The variation in degrees. + **/ + void setSpinVariation(float variation); + + /** + * Sets the color of the particles. + * @param color The color. + **/ + void setColor(unsigned char * color); + + /** + * Sets the color of the particles. + * @param start The color of the particle when created. + * @param end The color of the particle upon death. + **/ + void setColor(unsigned char * start, unsigned char * end); + + /** + * Returns the x-coordinate of the emitter's position. + **/ + float getX() const; + + /** + * Returns the y-coordinate of the emitter's position. + **/ + float getY() const; + + /** + * Returns the direction of the emitter (in degrees). + **/ + float getDirection() const; + + /** + * Returns the directional spread of the emitter (in degrees). + **/ + float getSpread() const; + + /** + * Returns the amount of particles that are currently active in the system. + **/ + int count() const; + + /** + * Starts/resumes the particle emitter. + **/ + void start(); + + /** + * Stops the particle emitter and resets. + **/ + void stop(); + + /** + * Pauses the particle emitter. + **/ + void pause(); + + /** + * Resets the particle emitter. + **/ + void reset(); + + /** + * Returns whether the particle emitter is active. + **/ + bool isActive() const; + + /** + * Returns whether the particle system is empty of particles or not. + **/ + bool isEmpty() const; + + /** + * Returns whether the amount of particles has reached the buffer limit or not. + **/ + bool isFull() const; + + /** + * Draws the particle emitter at the specified position. + * @param x The x-coordinate. + * @param y The y-coordinate. + **/ + virtual void draw(float x, float y, float angle, float sx, float sy, float ox, float oy) const; + + /** + * Updates the particle system. + * @param dt Time since last update. + **/ + void update(float dt); + }; + +} // opengl +} // graphics +} // love + +#endif // LOVE_GRAPHICS_OPENGL_PARTICLE_SYSTEM_H diff --git a/src/modules/graphics/opengl/wrap_Graphics.cpp b/src/modules/graphics/opengl/wrap_Graphics.cpp index 277587a10..c273e2578 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.cpp +++ b/src/modules/graphics/opengl/wrap_Graphics.cpp @@ -758,7 +758,8 @@ namespace opengl luaopen_image, luaopen_glyph, luaopen_frame, - luaopen_spritebatch, + luaopen_spritebatch, + luaopen_particlesystem, 0 }; diff --git a/src/modules/graphics/opengl/wrap_Graphics.h b/src/modules/graphics/opengl/wrap_Graphics.h index 9e668ba61..604ab6a20 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.h +++ b/src/modules/graphics/opengl/wrap_Graphics.h @@ -27,6 +27,7 @@ #include "wrap_Glyph.h" #include "wrap_Quad.h" #include "wrap_SpriteBatch.h" +#include "wrap_ParticleSystem.h" #include "Graphics.h" namespace love diff --git a/src/modules/graphics/opengl/wrap_ParticleSystem.cpp b/src/modules/graphics/opengl/wrap_ParticleSystem.cpp new file mode 100644 index 000000000..3193e92f8 --- /dev/null +++ b/src/modules/graphics/opengl/wrap_ParticleSystem.cpp @@ -0,0 +1,352 @@ +/** +* Copyright (c) 2006-2009 LOVE Development Team +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +**/ + +#include "wrap_ParticleSystem.h" + +#include + +namespace love +{ +namespace graphics +{ +namespace opengl +{ + ParticleSystem * luax_checkparticlesystem(lua_State * L, int idx) + { + return luax_checktype(L, idx, "ParticleSystem", GRAPHICS_PARTICLE_SYSTEM_T); + } + + int w_ParticleSystem_setSprite(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + Image * i = luax_checkimage(L, 2); + t->setSprite(i); + return 0; + } + + int w_ParticleSystem_setBufferSize(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + int arg1 = luaL_checkint(L, 2); + t->setBufferSize((unsigned int)arg1); + return 0; + } + + int w_ParticleSystem_setEmissionRate(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + int arg1 = luaL_checkint(L, 2); + t->setEmissionRate((unsigned int)arg1); + return 0; + } + + int w_ParticleSystem_setLifetime(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + float arg1 = (float)luaL_checknumber(L, 2); + t->setLifetime(arg1); + return 0; + } + + int w_ParticleSystem_setParticleLife(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + float arg1 = (float)luaL_checknumber(L, 2); + float arg2 = (float)luaL_checknumber(L, 3); + t->setParticleLife(arg1, arg2); + return 0; + } + + int w_ParticleSystem_setPosition(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + float arg1 = (float)luaL_checknumber(L, 2); + float arg2 = (float)luaL_checknumber(L, 3); + t->setPosition(arg1, arg2); + return 0; + } + + int w_ParticleSystem_setDirection(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + float arg1 = (float)luaL_checknumber(L, 2); + t->setDirection(arg1); + return 0; + } + + int w_ParticleSystem_setSpread(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + float arg1 = (float)luaL_checknumber(L, 2); + t->setSpread(arg1); + return 0; + } + + int w_ParticleSystem_setRelativeDirection(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + bool arg1 = (bool)luax_toboolean(L, 2); + t->setRelativeDirection(arg1); + return 0; + } + + int w_ParticleSystem_setSpeed(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + float arg1 = (float)luaL_checknumber(L, 2); + float arg2 = (float)luaL_optnumber(L, 3, arg1); + t->setSpeed(arg1, arg2); + return 0; + } + + int w_ParticleSystem_setGravity(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + float arg1 = (float)luaL_checknumber(L, 2); + float arg2 = (float)luaL_optnumber(L, 3, arg1); + t->setGravity(arg1, arg2); + return 0; + } + + int w_ParticleSystem_setRadialAcceleration(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + float arg1 = (float)luaL_checknumber(L, 2); + float arg2 = (float)luaL_optnumber(L, 3, arg1); + t->setRadialAcceleration(arg1, arg2); + return 0; + } + + int w_ParticleSystem_setTangentialAcceleration(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + float arg1 = (float)luaL_checknumber(L, 2); + float arg2 = (float)luaL_optnumber(L, 3, arg1); + t->setTangentialAcceleration(arg1, arg2); + return 0; + } + + int w_ParticleSystem_setSize(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + float arg1 = (float)luaL_checknumber(L, 2); + float arg2 = (float)luaL_optnumber(L, 3, arg1); + float arg3 = (float)luaL_optnumber(L, 3, 0); + t->setSize(arg1, arg2, arg3); + return 0; + } + + int w_ParticleSystem_setSizeVariation(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + float arg1 = (float)luaL_checknumber(L, 2); + t->setSizeVariation(arg1); + return 0; + } + + int w_ParticleSystem_setRotation(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + float arg1 = (float)luaL_checknumber(L, 2); + float arg2 = (float)luaL_optnumber(L, 3, arg1); + t->setRotation(arg1, arg2); + return 0; + } + + int w_ParticleSystem_setSpin(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + float arg1 = (float)luaL_checknumber(L, 2); + float arg2 = (float)luaL_optnumber(L, 3, arg1); + float arg3 = (float)luaL_optnumber(L, 3, 0); + t->setSpin(arg1, arg2, arg3); + return 0; + } + + int w_ParticleSystem_setSpinVariation(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + float arg1 = (float)luaL_checknumber(L, 2); + t->setSpinVariation(arg1); + return 0; + } + + int w_ParticleSystem_setColor(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + + unsigned char start[4]; + + start[0] = (unsigned char)luaL_checkint(L, 2); + start[1] = (unsigned char)luaL_checkint(L, 3); + start[2] = (unsigned char)luaL_checkint(L, 4); + start[3] = (unsigned char)luaL_checkint(L, 5); + + if(lua_gettop(L) > 5) + { + unsigned char end[4]; + end[0] = (unsigned char)luaL_checkint(L, 6); + end[1] = (unsigned char)luaL_checkint(L, 7); + end[2] = (unsigned char)luaL_checkint(L, 8); + end[3] = (unsigned char)luaL_checkint(L, 9); + t->setColor(start, end); + } + else + t->setColor(start); + + return 0; + } + + int w_ParticleSystem_getX(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + lua_pushnumber(L, t->getX()); + return 1; + } + + int w_ParticleSystem_getY(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + lua_pushnumber(L, t->getY()); + return 1; + } + + int w_ParticleSystem_getDirection(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + lua_pushnumber(L, t->getDirection()); + return 1; + } + + int w_ParticleSystem_getSpread(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + lua_pushnumber(L, t->getSpread()); + return 1; + } + + int w_ParticleSystem_count(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + lua_pushnumber(L, t->count()); + return 1; + } + + int w_ParticleSystem_start(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + t->start(); + return 0; + } + + int w_ParticleSystem_stop(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + t->stop(); + return 0; + } + + int w_ParticleSystem_pause(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + t->pause(); + return 0; + } + + int w_ParticleSystem_reset(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + t->reset(); + return 0; + } + + int w_ParticleSystem_isActive(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + luax_pushboolean(L, t->isActive()); + return 1; + } + + int w_ParticleSystem_isEmpty(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + luax_pushboolean(L, t->isEmpty()); + return 1; + } + + int w_ParticleSystem_isFull(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + luax_pushboolean(L, t->isFull()); + return 1; + } + + int w_ParticleSystem_update(lua_State * L) + { + ParticleSystem * t = luax_checkparticlesystem(L, 1); + float dt = (float)luaL_checknumber(L, 2); + t->update(dt); + return 0; + } + + static const luaL_Reg functions[] = { + { "setSprite", w_ParticleSystem_setSprite }, + { "setBufferSize", w_ParticleSystem_setBufferSize }, + { "setEmissionRate", w_ParticleSystem_setEmissionRate }, + { "setLifeTime", w_ParticleSystem_setLifetime }, + { "setParticleLife", w_ParticleSystem_setParticleLife }, + { "setPosition", w_ParticleSystem_setPosition }, + { "setDirection", w_ParticleSystem_setDirection }, + { "setSpread", w_ParticleSystem_setSpread }, + { "setRelativeDirection", w_ParticleSystem_setRelativeDirection }, + { "setSpeed", w_ParticleSystem_setSpeed }, + { "setGravity", w_ParticleSystem_setGravity }, + { "setRadialAcceleration", w_ParticleSystem_setRadialAcceleration }, + { "setTangentialAcceleration", w_ParticleSystem_setTangentialAcceleration }, + { "setSize", w_ParticleSystem_setSize }, + { "setSizeVariation", w_ParticleSystem_setSizeVariation }, + { "setRotation", w_ParticleSystem_setRotation }, + { "setSpin", w_ParticleSystem_setSpin }, + { "setSpinVariation", w_ParticleSystem_setSpinVariation }, + { "setColor", w_ParticleSystem_setColor }, + { "getX", w_ParticleSystem_getX }, + { "getY", w_ParticleSystem_getY }, + { "getDirection", w_ParticleSystem_getDirection }, + { "getSpread", w_ParticleSystem_getSpread }, + { "count", w_ParticleSystem_count }, + { "start", w_ParticleSystem_start }, + { "stop", w_ParticleSystem_stop }, + { "pause", w_ParticleSystem_pause }, + { "reset", w_ParticleSystem_reset }, + { "isActive", w_ParticleSystem_isActive }, + { "isEmpty", w_ParticleSystem_isEmpty }, + { "isFull", w_ParticleSystem_isFull }, + { "update", w_ParticleSystem_update }, + { 0, 0 } + }; + + int luaopen_particlesystem(lua_State * L) + { + return luax_register_type(L, "ParticleSystem", functions); + } + +} // opengl +} // graphics +} // love diff --git a/src/modules/graphics/opengl/wrap_ParticleSystem.h b/src/modules/graphics/opengl/wrap_ParticleSystem.h new file mode 100644 index 000000000..d42c020d3 --- /dev/null +++ b/src/modules/graphics/opengl/wrap_ParticleSystem.h @@ -0,0 +1,74 @@ +/** +* Copyright (c) 2006-2009 LOVE Development Team +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +**/ + +#ifndef LOVE_GRAPHICS_OPENGL_WRAP_PARTICLE_SYSTEM_H +#define LOVE_GRAPHICS_OPENGL_WRAP_PARTICLE_SYSTEM_H + +// LOVE +#include +#include "wrap_Image.h" +#include "ParticleSystem.h" + +namespace love +{ +namespace graphics +{ +namespace opengl +{ + ParticleSystem * luax_checkparticlesystem(lua_State * L, int idx); + int w_ParticleSystem_setSprite(lua_State * L); + int w_ParticleSystem_setBufferSize(lua_State * L); + int w_ParticleSystem_setEmissionRate(lua_State * L); + int w_ParticleSystem_setLifetime(lua_State * L); + int w_ParticleSystem_setParticleLife(lua_State * L); + int w_ParticleSystem_setPosition(lua_State * L); + int w_ParticleSystem_setDirection(lua_State * L); + int w_ParticleSystem_setSpread(lua_State * L); + int w_ParticleSystem_setRelativeDirection(lua_State * L); + int w_ParticleSystem_setSpeed(lua_State * L); + int w_ParticleSystem_setGravity(lua_State * L); + int w_ParticleSystem_setRadialAcceleration(lua_State * L); + int w_ParticleSystem_setTangentialAcceleration(lua_State * L); + int w_ParticleSystem_setSize(lua_State * L); + int w_ParticleSystem_setSizeVariation(lua_State * L); + int w_ParticleSystem_setRotation(lua_State * L); + int w_ParticleSystem_setSpin(lua_State * L); + int w_ParticleSystem_setSpinVariation(lua_State * L); + int w_ParticleSystem_setColor(lua_State * L); + int w_ParticleSystem_getX(lua_State * L); + int w_ParticleSystem_getY(lua_State * L); + int w_ParticleSystem_getDirection(lua_State * L); + int w_ParticleSystem_getSpread(lua_State * L); + int w_ParticleSystem_count(lua_State * L); + int w_ParticleSystem_start(lua_State * L); + int w_ParticleSystem_stop(lua_State * L); + int w_ParticleSystem_pause(lua_State * L); + int w_ParticleSystem_reset(lua_State * L); + int w_ParticleSystem_isActive(lua_State * L); + int w_ParticleSystem_isEmpty(lua_State * L); + int w_ParticleSystem_isFull(lua_State * L); + int w_ParticleSystem_update(lua_State * L); + int luaopen_particlesystem(lua_State * L); + +} // opengl +} // graphics +} // love + +#endif // LOVE_GRAPHICS_OPENGL_WRAP_PARTICLE_SYSTEM_H