import processing.opengl.*; // OPENGL Voodoo for additive rendering import processing.opengl.*; import javax.media.opengl.*; PGraphicsOpenGL pgl; GL gl; // PImage glowKernel; // generated glow kernel for each particle int n=4000; Ball[] b=new Ball[n]; Ball m; int S=400; float ax,ay; int deadCount; void setup(){ size(800,800,OPENGL); hint( ENABLE_OPENGL_4X_SMOOTH ); background(0); for(int i=0;iPI) tay-=TWO_PI; if((tay-ay)<-PI) tay+=TWO_PI; ay=0.9*ay+0.1*tay; rotateY(ay); pgl=(PGraphicsOpenGL)g; gl=pgl.gl; pgl.beginGL(); gl.glDepthMask(true); gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); pgl.endGL(); gl.glClear(GL.GL_DEPTH_BUFFER_BIT); drawFrame(); pgl.beginGL(); gl.glDepthMask(false); gl.glBlendFunc( GL.GL_SRC_ALPHA, GL.GL_ONE); pgl.endGL(); if(m!=null){ m.draw(); m.update(); } for(int i=0;i34){ state=DECAYING; //stateCounter=0; } break; case DECAYING: size+=.1; stateCounter+=50; if (stateCounter>510){ state=DEAD; stateCounter=0; deadCount++; } break; } } void constrain(){ if(pos.x<-S){ pos.x=-2*S-pos.x; vel.x*=-1; } if(pos.y<-S){ pos.y=-2*S-pos.y; vel.y*=-1; } if(pos.z<-S){ pos.z=-2*S-pos.z; vel.z*=-1; } if(pos.x>=S){ pos.x=2*S-pos.x; vel.x*=-1; } if(pos.z>=S){ pos.z=2*S-pos.z; vel.z*=-1; } if(pos.y>=S){ pos.y=2*S-pos.y; vel.y*=-1; } } void draw(){ if(state!=DEAD){ pushMatrix(); translate(pos.x,pos.y,pos.z);// offset to bead position rotateY(-ay); scale(size);// rescale image translate(-glowKernel.width/2,-glowKernel.height/2);// offset from left-top corner to center of image, apply before rescaling image tint(red(c),green(c),blue(c),255-0.5*stateCounter); image(glowKernel,0,0); popMatrix(); } } }