Tunnel
c.f. http://benryves.com/tutorials/tunnel/
borrowed texture from http://webglplayground.net/documentation
/**
* Copyright tai2 ( http://wonderfl.net/user/tai2 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/AwcH
*/
package {
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;
import flash.utils.getTimer;
import flash.system.LoaderContext;
public class Tunnel extends Sprite {
private const TEXTURE_URL:String = "http://tai2.net/img/steel.jpg";
private const TEXTURE_SIZE:int = 512;
private const V_DEPTH:Number = 250.0;
private const V_RAD:Number = 200.0;
private var canvas:BitmapData;
private var texture:BitmapData;
private var loader:Loader;
private var radtbl:Array;
private var radtbl_voffset:int;
private var radtbl_hoffset:int;
public function Tunnel()
{
Wonderfl.capture_delay(10);
canvas = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0x000000);
addChild(new Bitmap(canvas));
radtbl = makeRadTable(2 * canvas.width, 2 * canvas.height);
radtbl_hoffset = canvas.width;
radtbl_voffset = canvas.height;
var context:LoaderContext = new LoaderContext;
context.checkPolicyFile = true;
loader = new Loader();
loader.load(new URLRequest(TEXTURE_URL), context);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoaded);
}
private function makeRadTable(w:int, h:int) : Array
{
var table:Array = new Array(h);
for (var y:int = 0; y < h; y++) {
table[y] = new Array(w);
for (var x:int = 0; x < w; x++) {
var tx:int = x - w / 2;
var ty:int = y - h / 2;
var rad:Number;
if (tx == 0) {
if (0 < ty) {
rad = Math.PI / 2;
} else {
rad = 3 * Math.PI / 4;
}
} else {
rad = Math.atan(Number(ty) / Number(tx));
if (0 > tx) {
rad += Math.PI;
}
}
rad += Math.PI / 2;
rad *= 6;
table[y][x] = rad;
}
}
return table;
}
private function onImageLoaded(event:Event) : void
{
texture = Bitmap(loader.content).bitmapData;
addEventListener(Event.ENTER_FRAME, enterFrame);
}
private function enterFrame(event:Event) : void
{
var t:Number = getTimer() * 0.001;
var distance_max:Number =
(canvas.width - 1) * (canvas.width - 1) + (canvas.height - 1) * (canvas.height - 1);
var x_offset:int = canvas.width * 0.5 + ((canvas.width * 0.1) * Math.sin(0.6 * t));
var y_offset:int = canvas.height * 0.5 + ((canvas.height * 0.25) * Math.cos(0.5 * t));
var depth_offset:Number = V_DEPTH * t + V_DEPTH * Math.cos(0.5 * t);
canvas.lock();
texture.lock();
for (var y:int = 0; y < canvas.height; y++) {
for (var x:int = 0; x < canvas.width; x++) {
var tx:int = x - x_offset;
var ty:int = y - y_offset;
var distance:int = tx * tx + ty * ty;
var depth:int = distance == 0 ? 8388608 : 8388608 / distance;
var rad:Number = radtbl[ty + radtbl_voffset][tx + radtbl_hoffset];
var u:int = (int(TEXTURE_SIZE * rad / (2 * Math.PI) + V_RAD * t)) % TEXTURE_SIZE;
var v:int = (int(depth + depth_offset)) % TEXTURE_SIZE;
var brightness:Number = Math.min(1.0, 0.05 + distance / distance_max);
var c:uint = texture.getPixel(u,v);
var r:uint = (c>>>16) & 0xFF;
var g:uint = (c>>> 8) & 0xFF;
var b:uint = (c>>> 0) & 0xFF;
r = uint(r * brightness);
g = uint(g * brightness);
b = uint(b * brightness);
canvas.setPixel(x, y, (r<<16) | (g<<8) | (b<<0));
}
}
texture.unlock();
canvas.unlock();
}
}
}