Monday, May 25, 2009

Mirror of Confusion...



I've been experimenting with recursion a bit - not recursive programming but image recursion. In this sketch I'm grabbing the contents of the window as an image and then using it in the next animation frame as the texture for the fudged 'mirror'. The resulting feedback loop creates the deep 'reflections' from a 2nd mirror somewhere off screen.

ß e n


import processing.opengl.*;


//
// Dimensions of screen.
//
int kWidth = 480 ;
int kHeight = 320 ;

//
// Dimensions of texture.
// For fast PCs reduce or remove the denominator.
//
int kTextureWidth = kWidth / 2 ;
int kTextureHeight = kHeight / 2 ;

//
// Used to store the current frame buffer as a texture.
//
PImage history ;

void setup()
{
//
// P3D doesn't work well in this sketch!
//
size( kWidth, kHeight, OPENGL ) ;

colorMode( RGB, 255 ) ;
smooth() ;

history = createImage( kTextureWidth, kTextureHeight, RGB ) ;

textureMode( NORMALIZED ) ;
}

void draw()
{

background( 255 ) ;

translate( width/2, height/2 ) ;

//
// Draw the ground - use a simple grid for detail.
//
// All numbers are fudged to make the grid and ground look about right.
//
hint(DISABLE_DEPTH_TEST) ;

noStroke() ;
fill( 240, 189, 180 ) ;
rect( -width/2, 24, width/2, 200 ) ;

fill( 200, 220, 255 ) ;
rect( 0, 24, width, 200 ) ;

stroke( 0 ) ;
strokeWeight( 1.0 ) ;

for ( int i = 0 ; i < 10 ; ++ i )
{
float z = -2000 + i * 200 ;
line( -width*10, 200, z, width* 10, 200, z ) ;

float x = i* 200 ;

line( -x, 200, -2000, -x, 200, 200 ) ;
line( x, 200, -2000, x, 200, 200 ) ;
}

hint(ENABLE_DEPTH_TEST) ;

//
// Draw the mirror.
//
// The mirror is animated by rotating around the y-axis.
// The mirror is drawn using the last frame buffer as the reflection in the mirror.
// The view in the mirror is dimmed slightly by drawing an alpha rectangle over it.
// Also, the mirror is oultined to make it stand out a bit.
//
pushMatrix() ;

// rotateX( 0.03 * sin( millis() * 0.0023f ) ) ;
rotateY( 0.3 * sin( millis() * 0.001f ) ) ;
translate( -width/2, -height/2, -200 ) ;

noStroke() ;
beginShape() ;
texture( history ) ;
vertex( 0.0, 0.0, 0, 0 ) ;
vertex( width, 0, 1, 0 ) ;
vertex( width, height, 1, 1 ) ;
vertex( 0, height, 0, 1 ) ;
endShape() ;

fill( 0, 0, 0, 30 ) ;
beginShape() ;
vertex( 0.0, 0.0 ) ;
vertex( width, 0 ) ;
vertex( width, height ) ;
vertex( 0, height ) ;
endShape() ;

stroke( 200, 200, 200 ) ;
strokeWeight( 2 ) ;
noFill() ;
beginShape() ;
vertex( 0, 0 ) ;
vertex( width, 0 ) ;
vertex( width, height ) ;
vertex( 0, height ) ;
endShape(CLOSE) ;

popMatrix() ;

//
// Draw the foreground scene.
//
translate( 200 * sin( millis() * .001 ), 200 * sin( millis()* 0.0013 ) ) ;

lights() ;
noStroke() ;
fill( 238, 80, 70 ) ;
sphere( 100 ) ;

//
// Use the current frame as the texture for the
// mirror in the next frame.
//
// if ( frameCount % 4 == 0 )
history.copy( get(), 0, 0, width, height, 0, 0, kTextureWidth, kTextureHeight ) ;
}

No comments: