summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Spilsbury <smspillaz@XPS-FEDORA.(none)>2009-08-22 11:42:59 +0800
committerSam Spilsbury <smspillaz@XPS-FEDORA.(none)>2009-08-22 11:42:59 +0800
commit076e08583e675314fb65ada0bdb5b1013b3bb3cc (patch)
tree9a40ec78a12e7faec92f0c7a972e51717e493ab1
downloadparticlesystem-076e08583e675314fb65ada0bdb5b1013b3bb3cc.tar.gz
particlesystem-076e08583e675314fb65ada0bdb5b1013b3bb3cc.tar.bz2
Initial commit of libparticlesystem
-rw-r--r--CMakeLists.txt5
-rw-r--r--compiz-particlesystem.pc.in12
-rw-r--r--include/particlesystem/particlesystem.h99
-rw-r--r--particlesystem.xml.in14
-rw-r--r--src/particlesystem.cpp344
-rw-r--r--src/private.h49
6 files changed, 523 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..24ce768
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,5 @@
+find_package (Compiz REQUIRED)
+
+include (CompizPlugin)
+
+compiz_plugin (particlesystem PLUGINDEPS composite opengl)
diff --git a/compiz-particlesystem.pc.in b/compiz-particlesystem.pc.in
new file mode 100644
index 0000000..aa2d72d
--- /dev/null
+++ b/compiz-particlesystem.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: compiz-particlesystem
+Description: Particlesystem plugin for compiz
+Version: @VERSION@
+
+Requires: compiz
+Libs: -L${libdir}/compiz -lparticlesystem
+Cflags: @COMPIZ_CFLAGS@ -I${includedir}/compiz
diff --git a/include/particlesystem/particlesystem.h b/include/particlesystem/particlesystem.h
new file mode 100644
index 0000000..08add7b
--- /dev/null
+++ b/include/particlesystem/particlesystem.h
@@ -0,0 +1,99 @@
+/*
+ * Compiz particlesystem plugin
+ *
+ * particlesystem.h
+ *
+ * Copyright : (C) 2007 by Dennis Kasprzyk
+ * E-mail : onestone@beryl-project.org
+ *
+ * Factorised into a separate plugin by:
+ * Copyright : (C) 2009 by Sam Spilsbury
+ * E-mail : smspillaz@gmail.com
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <opengl/opengl.h>
+
+#define COMPIZ_PARTICLESYSTEM_ABI 1
+
+/* ===================== Particle engine ========================= */
+
+class Particle
+{
+ public:
+ float life; /* particle life */
+ float fade; /* fade speed */
+ float width; /* particle width */
+ float height; /* particle height */
+ float w_mod; /* particle size modification during life */
+ float h_mod; /* particle size modification during life */
+ float r; /* red value */
+ float g; /* green value */
+ float b; /* blue value */
+ float a; /* alpha value */
+ float x; /* X position */
+ float y; /* Y position */
+ float z; /* Z position */
+ float xi; /* X direction */
+ float yi; /* Y direction */
+ float zi; /* Z direction */
+ float xg; /* X gravity */
+ float yg; /* Y gravity */
+ float zg; /* Z gravity */
+ float xo; /* orginal X position */
+ float yo; /* orginal Y position */
+ float zo; /* orginal Z position */
+};
+
+class ParticleSystem
+{
+ public:
+
+ ParticleSystem (int);
+ ParticleSystem ();
+ ~ParticleSystem ();
+
+ std::vector <Particle *> particles;
+ float slowdown;
+ GLuint tex;
+ Bool active;
+ int x, y;
+ float darken;
+ GLuint blendMode;
+
+ /* Moved from drawParticles to get rid of spurious malloc's */
+ GLfloat *vertices_cache;
+ GLfloat *coords_cache;
+ GLfloat *colors_cache;
+ GLfloat *dcolors_cache;
+
+ int coords_cache_count;
+ int vertex_cache_count;
+ int color_cache_count;
+ int dcolors_cache_count;
+
+ void
+ initParticles (int f_numParticles);
+
+ void
+ drawParticles ();
+
+ void
+ updateParticles (float time);
+
+ void
+ finiParticles ();
+};
+
+#define NUM_ADD_POINTS 1000
diff --git a/particlesystem.xml.in b/particlesystem.xml.in
new file mode 100644
index 0000000..3c5566a
--- /dev/null
+++ b/particlesystem.xml.in
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<compiz>
+ <plugin name="particlesystem" useBcop="true">
+ <deps>
+ <requirement>
+ <plugin>composite</plugin>
+ <plugin>opengl</plugin>
+ </requirement>
+ </deps>
+ <_short>Particle System</_short>
+ <_long>Used by plugins to create particles on screen</_long>
+ <category>Utility</category>
+ </plugin>
+</compiz>
diff --git a/src/particlesystem.cpp b/src/particlesystem.cpp
new file mode 100644
index 0000000..274b319
--- /dev/null
+++ b/src/particlesystem.cpp
@@ -0,0 +1,344 @@
+/*
+ * Compiz particlesystem plugin
+ *
+ * particlesystem.cpp
+ *
+ * Copyright : (C) 2007 by Dennis Kasprzyk
+ * E-mail : onestone@beryl-project.org
+ *
+ * Factorised into a separate plugin by:
+ * Copyright : (C) 2009 by Sam Spilsbury
+ * E-mail : smspillaz@gmail.com
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "private.h"
+
+COMPIZ_PLUGIN_20090315 (particlesystem, ParticleSystemPluginVTable);
+
+ParticleSystem::ParticleSystem (int n) :
+ particles (NULL),
+ vertices_cache (NULL),
+ coords_cache (NULL),
+ colors_cache (NULL),
+ dcolors_cache (NULL)
+{
+ initParticles (n);
+}
+
+ParticleSystem::ParticleSystem () :
+ particles (NULL),
+ vertices_cache (NULL),
+ coords_cache (NULL),
+ colors_cache (NULL),
+ dcolors_cache (NULL)
+{
+}
+
+ParticleSystem::~ParticleSystem ()
+{
+ finiParticles ();
+}
+
+void
+ParticleSystem::initParticles (int f_numParticles)
+{
+ particles.clear ();
+
+ tex = 0;
+ slowdown = 1;
+ active = FALSE;
+
+ // Initialize cache
+ vertices_cache = NULL;
+ colors_cache = NULL;
+ coords_cache = NULL;
+ dcolors_cache = NULL;
+
+ vertex_cache_count = 0;
+ color_cache_count = 0;
+ coords_cache_count = 0;
+ dcolors_cache_count = 0;
+
+ int i;
+
+ for (i = 0; i < f_numParticles; i++)
+ {
+ Particle *p = new Particle ();
+ p->life = 0.0f;
+ particles.push_back (p);
+ }
+}
+
+void
+ParticleSystem::drawParticles ()
+{
+ GLfloat *dcolors;
+ GLfloat *vertices;
+ GLfloat *coords;
+ GLfloat *colors;
+
+ glPushMatrix ();
+
+ glEnable (GL_BLEND);
+
+ if (tex)
+ {
+ glBindTexture (GL_TEXTURE_2D, tex);
+ glEnable (GL_TEXTURE_2D);
+ }
+
+ glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+ /* Check that the cache is big enough */
+
+ if (particles.size () > vertex_cache_count)
+ {
+ vertices_cache = (GLfloat *) realloc (vertices_cache,
+ particles.size () * 4 * 3 *
+ sizeof (GLfloat));
+ vertex_cache_count = particles.size ();
+ }
+
+ if (particles.size () > coords_cache_count)
+ {
+ coords_cache = (GLfloat *) realloc (coords_cache,
+ particles.size () * 4 * 2 *
+ sizeof (GLfloat));
+ coords_cache_count = particles.size ();
+ }
+
+ if (particles.size () > color_cache_count)
+ {
+ colors_cache = (GLfloat *) realloc (colors_cache,
+ particles.size () * 4 * 4 *
+ sizeof (GLfloat));
+ color_cache_count = particles.size ();
+ }
+
+ if (darken > 0)
+ {
+ if (dcolors_cache_count < particles.size ())
+ {
+ dcolors_cache = (GLfloat *) realloc (dcolors_cache,
+ particles.size () * 4 * 4 *
+ sizeof (GLfloat));
+ dcolors_cache_count = particles.size ();
+ }
+ }
+
+ dcolors = dcolors_cache;
+ vertices = vertices_cache;
+ coords = coords_cache;
+ colors = colors_cache;
+
+ int numActive = 0;
+
+ foreach (Particle *part, particles)
+ {
+ if (part->life > 0.0f)
+ {
+ numActive += 4;
+
+ float w = part->width / 2;
+ float h = part->height / 2;
+
+ w += (w * part->w_mod) * part->life;
+ h += (h * part->h_mod) * part->life;
+
+ vertices[0] = part->x - w;
+ vertices[1] = part->y - h;
+ vertices[2] = part->z;
+
+ vertices[3] = part->x - w;
+ vertices[4] = part->y + h;
+ vertices[5] = part->z;
+
+ vertices[6] = part->x + w;
+ vertices[7] = part->y + h;
+ vertices[8] = part->z;
+
+ vertices[9] = part->x + w;
+ vertices[10] = part->y - h;
+ vertices[11] = part->z;
+
+ vertices += 12;
+
+ coords[0] = 0.0;
+ coords[1] = 0.0;
+
+ coords[2] = 0.0;
+ coords[3] = 1.0;
+
+ coords[4] = 1.0;
+ coords[5] = 1.0;
+
+ coords[6] = 1.0;
+ coords[7] = 0.0;
+
+ coords += 8;
+
+ colors[0] = part->r;
+ colors[1] = part->g;
+ colors[2] = part->b;
+ colors[3] = part->life * part->a;
+ colors[4] = part->r;
+ colors[5] = part->g;
+ colors[6] = part->b;
+ colors[7] = part->life * part->a;
+ colors[8] = part->r;
+ colors[9] = part->g;
+ colors[10] = part->b;
+ colors[11] = part->life * part->a;
+ colors[12] = part->r;
+ colors[13] = part->g;
+ colors[14] = part->b;
+ colors[15] = part->life * part->a;
+
+ colors += 16;
+
+ if (darken > 0)
+ {
+
+ dcolors[0] = part->r;
+ dcolors[1] = part->g;
+ dcolors[2] = part->b;
+ dcolors[3] = part->life * part->a * darken;
+ dcolors[4] = part->r;
+ dcolors[5] = part->g;
+ dcolors[6] = part->b;
+ dcolors[7] = part->life * part->a * darken;
+ dcolors[8] = part->r;
+ dcolors[9] = part->g;
+ dcolors[10] = part->b;
+ dcolors[11] = part->life * part->a * darken;
+ dcolors[12] = part->r;
+ dcolors[13] = part->g;
+ dcolors[14] = part->b;
+ dcolors[15] = part->life * part->a * darken;
+
+ dcolors += 16;
+ }
+ }
+ }
+
+ glEnableClientState (GL_COLOR_ARRAY);
+
+ glTexCoordPointer (2, GL_FLOAT, 2 * sizeof (GLfloat), coords_cache);
+ glVertexPointer (3, GL_FLOAT, 3 * sizeof (GLfloat), vertices_cache);
+
+ // darken the background
+
+ if (darken > 0)
+ {
+ glBlendFunc (GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
+ glColorPointer (4, GL_FLOAT, 4 * sizeof (GLfloat), dcolors_cache);
+ glDrawArrays (GL_QUADS, 0, numActive);
+ }
+
+ // draw particles
+ glBlendFunc (GL_SRC_ALPHA, blendMode);
+
+ glColorPointer (4, GL_FLOAT, 4 * sizeof (GLfloat), colors_cache);
+ glDrawArrays (GL_QUADS, 0, numActive);
+ glDisableClientState (GL_COLOR_ARRAY);
+
+ glPopMatrix ();
+ glColor4usv (defaultColor);
+
+ GLScreen::get(screen)->setTexEnvMode (GL_REPLACE); // ???
+
+ glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ glDisable (GL_TEXTURE_2D);
+ glDisable (GL_BLEND);
+}
+
+void
+ParticleSystem::updateParticles (float time)
+{
+ int i;
+ float speed = (time / 50.0);
+ float slowdown = slowdown * (1 - MAX (0.99, time / 1000.0) ) * 1000;
+
+ active = FALSE;
+
+ foreach (Particle *part, particles)
+ {
+ if (part->life > 0.0f)
+ {
+ // move particle
+ part->x += part->xi / slowdown;
+ part->y += part->yi / slowdown;
+ part->z += part->zi / slowdown;
+
+ // modify speed
+ part->xi += part->xg * speed;
+ part->yi += part->yg * speed;
+ part->zi += part->zg * speed;
+
+ // modify life
+ part->life -= part->fade * speed;
+ active = TRUE;
+ }
+ }
+}
+
+void
+ParticleSystem::finiParticles ()
+{
+ particles.clear ();
+
+ if (tex)
+ glDeleteTextures (1, &tex);
+
+ if (vertices_cache)
+ free (vertices_cache);
+
+ if (colors_cache)
+ free (colors_cache);
+
+ if (coords_cache)
+ free (coords_cache);
+
+ if (dcolors_cache)
+ free (dcolors_cache);
+}
+
+ParticleSystemScreen::ParticleSystemScreen (CompScreen *) :
+ PluginClassHandler <ParticleSystemScreen, CompScreen,
+ COMPIZ_PARTICLESYSTEM_ABI> (screen)
+{
+}
+
+bool
+ParticleSystemPluginVTable::init ()
+{
+ if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) ||
+ !CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) ||
+ !CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI))
+ return false;
+
+ CompPrivate p;
+ p.uval = COMPIZ_PARTICLESYSTEM_ABI;
+ screen->storeValue ("particlesystem_ABI", p);
+
+ return true;
+}
+
+void
+ParticleSystemPluginVTable::fini ()
+{
+ screen->eraseValue ("particlesystem_ABI");
+}
+
diff --git a/src/private.h b/src/private.h
new file mode 100644
index 0000000..5de8dbc
--- /dev/null
+++ b/src/private.h
@@ -0,0 +1,49 @@
+/*
+ * Compiz particlesystem plugin
+ *
+ * private.h
+ *
+ * Copyright : (C) 2007 by Dennis Kasprzyk
+ * E-mail : onestone@beryl-project.org
+ *
+ * Factorised into a separate plugin by:
+ * Copyright : (C) 2009 by Sam Spilsbury
+ * E-mail : smspillaz@gmail.com
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <core/core.h>
+#include <composite/composite.h>
+#include <particlesystem/particlesystem.h>
+
+#include "particlesystem_options.h"
+
+class ParticleSystemScreen :
+ public PluginClassHandler <ParticleSystemScreen, CompScreen,
+ COMPIZ_PARTICLESYSTEM_ABI>,
+ public ParticlesystemOptions
+{
+ public:
+
+ ParticleSystemScreen (CompScreen *);
+};
+
+class ParticleSystemPluginVTable :
+ public CompPlugin::VTableForScreen <ParticleSystemScreen>
+{
+ public:
+
+ bool init ();
+ void fini ();
+};