Processing für Geeks

Nibble: "Processing für Geeks" von Nikolaus Gradwohl, gehalten am Abend der Eroeffnungsveranstaltung am 10. April 2010

Code des gezeigten Processing Audio Visualizers

Datei:Particle.pde:

public class Particle {
  float x, y, z;
  float vx, vy, vz;
  boolean alive;
  PImage tex;
  color ti;
  
  public Particle( float x, float y, float z,  float vx, float vy, float vz, PImage tex, color ti ) {
    this.tex = tex;  
    this.x = x;
    this.y = y;
    this.z = z;
    this.vx = vx;
    this.vy = vy;
    this.vz = vz;
    this.ti = ti;
    alive = true;
  }

  public Particle( float x, float y, float z,  float vx, float vy, float vz, PImage tex ) {
    this( x, y, z, vx, vy, vz, tex, color( 255, 255, 255 ));
  }
  
  public void update() {
    x += vx * 0.1f;
    y += vy * 0.1f;
    z += vz * 0.1f;
    
    vy += 0.1;
    
    if (y > 600) {
      alive = false;
    }
  }
  
  public void draw( float alph ) {
    pushMatrix();
    translate( x, y, z );
    rotateY( alph );
    textureMode(NORMALIZED);
    tint(ti);
    beginShape();
    texture( tex );
    vertex( -20, -20, 0, 0, 0 );
    vertex( -20, 20, 0, 0, 1 );
    vertex( 20, 20, 0, 1, 1 );
    vertex( 20, -20, 0, 1, 0 );
    endShape(CLOSE);
    popMatrix();
  }
  
  public boolean isAlive() {
    return alive;
  }
}

Datei:Particledemo.pde:

/**
a 3d particle audio vizualizer by Guru
http://www.local-guru.net/blog

press any key to emit a new burst of particles
*/

import processing.opengl.*;
import javax.media.opengl.*;
import ddf.minim.*;
import ddf.minim.analysis.*;
//Particle[] p;
ArrayList p = new ArrayList();
Particle[] burst;
PImage tex;
boolean present = false;
Minim minim;
AudioInput in;
FFT fft;

void setup() {
  for ( int i = 0; i < args.length; i ++ ) {
    if ("--present".equals(args[i])) {
      present = true;
      break;
    }
  }
  if (present) {
    size(screen.width,screen.height, OPENGL);
  } else {
    size(600,600, OPENGL);
  }
 
  tex = makeTexture( 10 );
  burst = new Particle[100];
  
  minim = new Minim(this);
  in = minim.getLineIn( Minim.MONO, 512 );
  fft = new FFT( in.bufferSize(), in.sampleRate());
}

float alph = 0;

void draw() {
  background(0);

  alph += 0.01f;
  PGraphicsOpenGL pgl = (PGraphicsOpenGL) g;
  GL gl = pgl.gl;
  pgl.beginGL();
  
  gl.glDepthMask(false);  
  gl.glDisable(GL.GL_DEPTH_TEST); 
  gl.glEnable(GL.GL_BLEND); 
  gl.glBlendFunc(GL.GL_SRC_ALPHA,GL.GL_ONE); 
  
  pushMatrix();
  translate( width, 0, -300 );
  scale( min( width, height) /150 );

  rotateY( alph );

  fft.forward( in.mix );
  
  for( int i = 0; i < fft.specSize(); i++) {
     float val = fft.getBand(i)*(i+1)/75;
     if( val > 2  && random(1000) > 800 + p.size()  ) {
       colorMode(HSB,fft.specSize(),100,100);
       p.add( new Particle( 0, 300, 0 , random( -5, 5 ), random( -20, -5), random( -5, 5 ), tex, color( i, 40,100)));
     }
  }
  
  ArrayList dead = new ArrayList();
  for( Iterator i = p.iterator(); i.hasNext(); ) {
    Particle par = (Particle)i.next();
    par.update();
    par.draw( - alph );
    if (!par.isAlive()) {
      dead.add( par );
    }
  }
  
  for( Iterator i = dead.iterator(); i.hasNext(); ) {
    p.remove( i.next());
  }

  for( int i = 0; i < burst.length; i ++ ) {
    if ( burst[i] != null && burst[i].isAlive()) {
       burst[i].update();
       burst[i].draw( -alph );
    }
  }
  
  pgl.endGL();
  popMatrix();
}


PGraphics makeTexture( int r ) {
  PGraphics res = createGraphics( r * 6, r * 6, P2D);
  res.beginDraw();
  res.loadPixels();
    for ( int x = 0; x < res.width; x++) {   
      for( int y = 0; y < res.height; y++ ) {
        float d = min( 512, 50*  sq( r / sqrt( sq( x - 3 * r) + sq( y - 3 * r))));
        res.pixels[y * res.width + x] = color( min(255,d), min(255, d*0.8), d* 0.5 );
      }
    }
  res.updatePixels();
  res.endDraw();
  
  return res;  
}