// Synthetic Lights // // Scott "Jerry" Lawrence // 2003-10-14 // // Based on the research of Paul Haeberli, as shown in his/SGI's "Grafica Obscura" // Uses images from the Synthetic Lighting demonsttration found here: // http://www.sgi.com/grafica/synth BImage ambient; BImage left; BImage right; BImage all[]; vSlider r1, g1, b1; vSlider r2, g2, b2; RectButton ll, rr, lm, rm; boolean locked; final int vs = 100; void setup() { size( 315, 239 ); all = new BImage[ 3 ]; all[0] = ambient = loadImage( "amb.gif" ); all[1] = left = loadImage( "left.gif" ); all[2] = right = loadImage( "right.gif" ); r1 = new vSlider( 1, height-6-vs, vs, color( 255, 0, 0) ); g1 = new vSlider( 12, height-6-vs, vs, color( 0, 255, 0) ); b1 = new vSlider( 23, height-6-vs, vs, color( 0, 0, 255) ); r2 = new vSlider( 281, height-6-vs, vs, color( 255, 0, 0) ); g2 = new vSlider( 292, height-6-vs, vs, color( 0, 255, 0) ); b2 = new vSlider( 303, height-6-vs, vs, color( 0, 0, 255) ); ll = new RectButton( 0, 0, 15, color( 0, 0, 0 ), color( 255, 255, 255 ) ); rr = new RectButton( width-16, 0, 15, color( 0, 0, 0 ), color( 255, 255, 255 ) ); lm = new RectButton( 0, 15, 15, color( 0, 0, 0 ), color( 255, 255, 255 ) ); rm = new RectButton( width-16, 15, 15, color( 0, 0, 0 ), color( 255, 255, 255 ) ); } int c = 0; int mil; int a1, a2, a3; void loop() { ll.update(); rr.update(); lm.update(); rm.update(); if( keyPressed && ( key == 'r')) { r1.rnd(); g1.rnd(); b1.rnd(); r2.rnd(); g2.rnd(); b2.rnd(); } r1.update(); g1.update(); b1.update(); r2.update(); g2.update(); b2.update(); if( millis() > mil+500 ) { // update the image selector a1 = (int)random( 3 ); //*(c+0)%3 a2 = (int)random( 3 ); a3 = (int)random( 3 ); // update the counter c = (c+1) % 3; // and the trigger mil = millis(); } if( ll.pressed() ) { // display just the left image( left, 0, 0 ); } else if ( rr.pressed() ) { // display just the right image( right, 0, 0 ); } else { // show a mixture for( int p = 0 ; p < width*height ; p++ ) { int r,g,b,px; int rr = 0; int gg = 0; int bb = 0; if( !rm.pressed() ) { px = left.pixels[p]; r = (px >> 16) & 0x000000ff; g = (px >> 8) & 0x000000ff; b = px & 0x000000ff; rr += (int)( r * r1.getValue() ); gg += (int)( g * g1.getValue() ); bb += (int)( b * b1.getValue() ); } if( !lm.pressed() ) { px = right.pixels[p]; r = (px >> 16) & 0x000000ff; g = (px >> 8) & 0x000000ff; b = px & 0x000000ff; rr += (int)( r * r2.getValue() ); gg += (int)( g * g2.getValue() ); bb += (int)( b * b2.getValue() ); } rr = constrain( rr, 0, 255 ); gg = constrain( gg, 0, 255 ); bb = constrain( bb, 0, 255 ); color pc = color( rr, gg, bb ); pixels[ p ] = pc; } } r1.draw(); g1.draw(); b1.draw(); r2.draw(); g2.draw(); b2.draw(); ll.draw(); rr.draw(); lm.draw(); rm.draw(); if( keyPressed && ( key == 'G')) saveFrame(); } class vSlider { int x, y, h, vpos; final int w2 = 5; color sc; vSlider( int _x, int _y, int _h, color _sc ) { this.x = _x; this.y = _y; this.h = _h; this.vpos = 0; this.sc = _sc; } boolean isOver() { if (mouseX >= this.x && mouseX <= this.x+(this.w2*2) && mouseY >= this.y && mouseY <= this.y+this.h) { return true; } else { return false; } } void rnd() { this.vpos = (int) random( this.h ); } float getValue() { return( 1.0 - ((float)this.vpos / (float)this.h ) ); } void update() { if( this.isOver() && mousePressed ) { this.vpos = mouseY-this.y-this.w2; } } void draw() { stroke( 100 ); line( this.x + this.w2, this.y, this.w2+this.x, this.y+this.vpos ); line( this.x + this.w2-1, this.y+this.vpos, this.w2+this.x-1, this.y+this.h ); line( this.x + this.w2+1, this.y+this.vpos, this.w2+this.x+1, this.y+this.h ); if( this.isOver() ) fill( sc ); else fill( 0 ); rect( this.x, this.y+this.vpos, this.w2*2, this.w2*2 ); } } class Button { int x, y; int size; color basecolor, highlightcolor; color currentcolor; boolean over = false; boolean pressed = false; void update() { if(over()) { currentcolor = highlightcolor; } else { currentcolor = basecolor; } } boolean pressed() { if(over) { locked = true; return true; } else { locked = false; return false; } } boolean over() { return true; } void draw() { } } class RectButton extends Button { RectButton(int _x, int _y, int _size, color _color, color _highlight) { x = _x; y = _y; size = _size; basecolor = _color; highlightcolor = _highlight; currentcolor = basecolor; } boolean over() { if( overRect(x, y, size, size) ) { over = true; return true; } else { over = false; return false; } } void draw() { stroke(255); fill(currentcolor); rect(x, y, size, size); } } boolean overRect(int x, int y, int width, int height) { if (mouseX >= x && mouseX <= x+width && mouseY >= y && mouseY <= y+height) { return true; } else { return false; } }