Pixel Bender Orbit Trap by subblue

by makc3d forked from Pixel Bender Mandelbrot by subblue (diff: 161)
♥3 | Line 173 | Modified 2010-03-01 11:40:15 | MIT License
play

ActionScript3 source code

/**
 * Copyright makc3d ( http://wonderfl.net/user/makc3d )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/96Qf
 */

<?xml version="1.0" encoding="utf-8"?>
<!-- 
	This is Tom Beddard (aka subblue) modified orbit trap kernel,
	http://www.subblue.com/projects/fractal_explorer
-->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
	horizontalAlign="left" paddingLeft="0" verticalAlign="top" paddingTop="0"
	creationComplete="init()">
	<mx:UIComponent id="uic" />
	<mx:VBox verticalAlign="bottom" height="100" horizontalScrollPolicy="off">

	<mx:Button label="Image" click="loadImage()" />

	<mx:HSlider id="centerX" minimum="-2" maximum="2" width="440" labels="['Re: -2','+2']" change="draw()" value="0" />
	<mx:HSlider id="centerY" minimum="-1" maximum="1" width="440" labels="['Im: -1','+1']" change="draw()" value="0" />
	<mx:HSlider id="centerXft" minimum="-1" maximum="1" width="440" labels="['Move to right','to left ']" change="draw()" value="0" />
	<mx:HSlider id="centerYft" minimum="-1" maximum="1" width="440" labels="['Move to bottom','to top ']" change="draw()" value="0" />

	<!-- these things are configured in kernel; cool, but too much code to type :( -->
	<mx:CheckBox id="mandel" change="draw()" />
	<mx:HSlider id="power" change="draw()" width="440" />
	<mx:HSlider id="muX" change="draw()" width="440" />
	<mx:HSlider id="muY" change="draw()" width="440" />
	<mx:HSlider id="iterations" change="draw()" width="440" snapInterval="1" />

	<mx:HSlider id="otScale" minimum="0.01" maximum="5.0" value="0.6" labels="['Scale: 0','5']" change="draw()" width="440" />
	<mx:HSlider id="otRotation" minimum="-180" maximum="180" value="0" labels="['Rot.: -180','+180']" change="draw()" width="440" />
	<mx:HSlider id="otSpin"     minimum="-180" maximum="180" value="0" labels="['Spin: -180','+180']" change="draw()" width="440" />
	<mx:HSlider id="otOffsetX" minimum="-2" maximum="2" width="440" labels="['Offset, x: -2','+2']" change="draw()" value="0" />
	<mx:HSlider id="otOffsetY" minimum="-2" maximum="2" width="440" labels="['Offset, y: -2','+2']" change="draw()" value="0" />

	<mx:HSlider id="zoom" minimum="-1" maximum="13" width="440" labels="['Zoom:']" change="draw()" value="0.1" />
	<mx:HSlider id="bailout" minimum="-1" maximum="5" width="440" labels="['Bailout:']" change="draw()" value="1.5" />

	<mx:HSlider id="imgSize" minimum="465" maximum="2048" width="440" value="465" snapInterval="1" labels="['Image size: 465','2048']" change="resizeAndDraw()" />
	<mx:Button label="Save result" click="save()" />
	</mx:VBox>
	<mx:Script>
	<![CDATA[
	import com.adobe.images.JPGEncoder;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.Shader;
	import flash.display.ShaderJob;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.net.FileReference;
	import flash.utils.ByteArray;
	import flash.utils.clearTimeout;
	import flash.utils.setTimeout;
	import mx.utils.Base64Decoder;
	public var bin:BitmapData;
	public var bout:BitmapData;
	public var j:ShaderJob;
	public var s:Shader;
	public var t:uint;
	public function init ():void {
		var decoder:Base64Decoder = new Base64Decoder; decoder.decode ("pQEAAACkGQBGcmFjdGFsRXhwbG9yZXJPcmJpdFRyYXBzoAxuYW1lc3BhY2UAY29tLnN1YmJsdWUuZmlsdGVycwCgDHZlbmRvcgBUb20gQmVkZGFyZACgCHZlcnNpb24AAQCgDGRlc2NyaXB0aW9uAEZyYWN0YWwgZXhwbG9yZXIgd2l0aCBvcmJpdCB0cmFwcwCgDGRpc3BsYXluYW1lAEZyYWN0YWwgRXhwbG9yZXIgd2l0aCBPcmJpdCBUcmFwcwCgDGNhdGVnb3J5AFBpeGVsIEJlbmRlcgChAQIAAAxfT3V0Q29vcmQAowAEc3JjAKECBAEAD2RzdAChAQIAAANjZW50ZXIAogJtaW5WYWx1ZQDAAAAAv4AAAKICbWF4VmFsdWUAQAAAAD+AAACiAmRlZmF1bHRWYWx1ZQAAAAAAAAAAAKIMZGVzY3JpcHRpb24AVGhlIGNlbnRlciBvZiB0aGUgZnJhY3RhbC4AoQECAgAMY2VudGVyRmluZVR1bmUAogJtaW5WYWx1ZQC/gAAAv4AAAKICbWF4VmFsdWUAP4AAAD+AAACiAmRlZmF1bHRWYWx1ZQAAAAAAAAAAAKIMZGVzY3JpcHRpb24ARmluZSB0dW5lIHRoZSBjZW50ZXIgcG9zaXRpb24uAKEBCQGADHNpemVJbnB1dACiCW1pblZhbHVlAGQAZACiCW1heFZhbHVlAAAQABCiCWRlZmF1bHRWYWx1ZQAsASwBogxkZXNjcmlwdGlvbgBUaGUgaW5wdXQgc2l6ZSBvZiB0aGUgc291cmNlIGltYWdlAKEBCQGAA3NpemVPdXRwdXQAogltaW5WYWx1ZQBkAGQAogltYXhWYWx1ZQAAEAAQoglkZWZhdWx0VmFsdWUAgALgAaIMZGVzY3JpcHRpb24AVGhlIG91dHB1dCBzaXplIG9mIHRoZSByZW5kZXJlZCBmcmFjdGFsLgChAQ0CgAhtYW5kZWxicm90AKINZGVmYXVsdFZhbHVlAAEAogxkZXNjcmlwdGlvbgBVc2UgdGhlIHN0YW5kYXJkIE1hbmRlbGJyb3QgZXF1YXRpb24uAKEBAQIAAnBvd2VyAKIBbWluVmFsdWUAwUAAAKIBbWF4VmFsdWUAQUAAAKIBZGVmYXVsdFZhbHVlAEAAAACiDGRlc2NyaXB0aW9uAFJhaXNlIHogdG8gdGhlIHBvd2VyIGUgaW4gdGhlIGZyYWN0YWwgZm9ybXVsYTogeicgPSB6XmUgKyBtdQChAQIDAAxtdQCiAm1pblZhbHVlAL+AAAC/gAAAogJtYXhWYWx1ZQA/gAAAP4AAAKICZGVmYXVsdFZhbHVlAD8AAAAAAAAAogxkZXNjcmlwdGlvbgBUaGUgY29tcGxleCBwYXJhbWV0ZXIgb2YgdGhlIGZyYWN0YWwgZm9ybXVsYTogeicgPSB6XmUgKyBtdQChAQgCgARpdGVyYXRpb25zAKIIbWluVmFsdWUAAQCiCG1heFZhbHVlAAoAoghkZWZhdWx0VmFsdWUABwCiDGRlc2NyaXB0aW9uAFRoZSBtYXhpbXVtIG51bWJlciBvZiBpdGVyYXRpb25zIGZvciBlYWNoIHBpeGVsIGJlZm9yZSBiYWlsb3V0LiBVc2UgdG8gaW5jcmVhc2UgZGV0YWlsIGF0IHRoZSBmcmFjdGFsIGVkZ2VzLgChAQECAAFvcmJpdFRyYXBTY2FsZQCiAW1pblZhbHVlADwj1wqiAW1heFZhbHVlAECgAACiAWRlZmF1bHRWYWx1ZQA/GZmaogxkZXNjcmlwdGlvbgBUaGUgcmVsYXRpdmUgc2NhbGUgb2YgdGhlIHNvdXJjZSBpbWFnZS4AoQEBAwACb3JiaXRUcmFwUm90YXRpb24AogFtaW5WYWx1ZQDDNAAAogFtYXhWYWx1ZQBDNAAAogFkZWZhdWx0VmFsdWUAAAAAAKIMZGVzY3JpcHRpb24AUm90YXRlIHRoZSBpbWFnZSBtYXAuAKEBAQMAAW9yYml0VHJhcFNwaW4AogFtaW5WYWx1ZQDDNAAAogFtYXhWYWx1ZQBDNAAAogFkZWZhdWx0VmFsdWUAAAAAAKIMZGVzY3JpcHRpb24AUm90YXRlIG1hcHBlZCBpbWFnZS4AoQECBAAMb3JiaXRUcmFwT2Zmc2V0AKICbWluVmFsdWUAwAAAAMAAAACiAm1heFZhbHVlAEAAAABAAAAAogJkZWZhdWx0VmFsdWUAPwAAAAAAAACiDGRlc2NyaXB0aW9uAFRoZSByZWxhdGl2ZSBwb3NpdGlvbiBvZiB0aGUgc291cmNlIGltYWdlLgChAQEEAAJyb3RhdGUAogFtaW5WYWx1ZQDDNAAAogFtYXhWYWx1ZQBDNAAAogFkZWZhdWx0VmFsdWUAAAAAAKIMZGVzY3JpcHRpb24AUm90YXRlIHRoZSBmcmFjdGFsLgChAQEEAAF6b29tAKIBbWluVmFsdWUAv4AAAKIBbWF4VmFsdWUAQVAAAKIBZGVmYXVsdFZhbHVlAD3MzM2iDGRlc2NyaXB0aW9uAFpvb20gZXhwb25lbnQuAKEBAQUACGJhaWxvdXQAogFtaW5WYWx1ZQC/gAAAogFtYXhWYWx1ZQBAoAAAogFkZWZhdWx0VmFsdWUAP8AAAKIMZGVzY3JpcHRpb24AQmFpbG91dCBleHBvbmVudC4AHQUAQAAAgAAdBQAgAADAABIFABAEAMAAHQYAgAUAwAAyBQAQQAAAAAQGAEAGAAAAAwYAQAUAwAAdBQAQBQBAAAIFABAGAEAAHQYAQAUAwAAyBQAQQAAAAAQGACAGAAAAAwYAIAUAwAAdBQAQBQBAAAEFABAGAIAAHQYAIAUAwAAdBQAQBgCAAAIFABAGAEAAHQYAEAUAwAAfBQAQAYDAAB8HAIABgIAABAcAQAcAAAADBwBABQDAAB0FABAGAMAAAwUAEAcAQAAdBwCABQDAADIFABBAAAAABAcAQAUAwAADBwBABwAAAB0FABAFAIAAAgUAEAcAQAAdBwBABQDAAB0FABACAAAAAwUAEAYAwAABBgBABQDAAB0FABACAEAAAwUAEAcAAAABBwBABQDAADIFABAAAAAAKQQAIAUAwAAdAoAgAIAAADQAAAACgIAAMgUAEDyO+jUDBQAQBACAAA0HACAFAMAAHQUAEAcAgAAyBwAgPI76NQMHACAEAIAADAcAEAcAgAAdBwAgBwDAAB0IAIAFAMAAHQgAQAcAgAAyBwAQAAAAAAIHABAHAIAAHQgAIAcAwAAdCAAQBQDAAB0JAAQIAAAAHQgAgAYAQAAdCABABwBAAB0IADEIABAAIQgANAkAAAAdCADBCACwAB0GAEAIAAAAHQcAQAgAQAA2AAAAAAAAAB8HABABgIAABAoAgAcAwAADCgCABgDAAB0IACAKAAAAHwcAEAGAwAAECgCABwDAAAMKAIAHAAAAHQgAEAoAAAAdCgDBCACwAB8HABABgAAAHwoAIAGAQAAdCgAQBwDAAAkKABAKAIAAMgcAEEAAAAAECgAgBwDAAAMKACAKAMAAHQgAIAoAgAAfBwAQAYAAAB8KACABgEAAHQoAEAcAwAAJCgAQCgCAADIHABBAAAAABAoAIAcAwAADCgAgCgDAAB0IABAKAIAAHQoAIAIAwAAdCgAQAgDAAAQLAMEKALAAAwsAwQgAsAAdCAAxCwAQADIHABA8jvo1AwcAEAMAgAANCgAgBwDAAB0HABAKAIAAMgoAIDyO+jUDCgAgAwCAAAwKABAKAIAAHQoAIAoAwAAdCwCABwDAAB0LAEAKAIAAMgoAEAAAAAACCgAQCgCAAB0LACAKAMAAHQsAEAcAwAAdDAAECwAAADIKABA8jvo1AwoAEAMAwAANCwCACgDAAB0KABALAAAAMgsAgDyO+jUDCwCAAwDAAAwLAEALAAAAHQsAgAsAQAAdDQCACgDAAB0NAEALAAAAMgsAQAAAAAACCwBACwAAAB0NACALAEAAHQ0AEAoAwAAdDgAEDQAAAB0LAGEAABAAMgsAEAAAAAApBAAgCwDAAB0CgCAAgAAANAAAAAKAgAAdDQCABgBAAB0NAEAHAEAAHQ0AMQsAYAADDQAxCgAQAB0PAMENALAAIQ8AxAkAAAAdDQAxDQAQAAENADEPABAAHQ0AwQ0AsAA1AAAAAAAAAB0NACAGAEAAHQ0AEAcAQAAdDwDBCwBgAAMPAMEKABAAHQ8AMQ0AsAABDwAxDwAQAB0NAMEPALAANgAAAAAAAAAdCwAQAgCAAB0NADEDABAANAAAAAKAAAAdDQAxDQAQADYAAAAAAAAAMgKAIAAAAAAyAoAQAgAAAB0DgIABgAAABQOAgAKAwAAfDwAgA4AAAB0PAIAPAIAAMgKAEAIAAAAdA4CAAYBAAAUDgIACgMAAHw8AIAOAAAAdDwBADwCAAB0PADEPABAAEg8AgAUAAAAdDwBADwAAACoCgCACgEAAHQKAEACAAAAkDwCBDQAQACoPAIAPAEAAHQOAgACAAAAdA4BAAoDAAC0DgEADgAAANAAAAAOAQAAkDwCBDQAQAB0QAIAPAAAABxAAgAsAwAAdDwCAEAAAAB0QAEANAEAABhAAQA0AAAAdEACAEABAAB0QAEALAMAAAxAAQBAAAAAdEACAEABAAA0QABAQAAAAHREAgBAAwAADEQCADwAAAB0QAEARAAAADBAAEBAAAAAdEQCAEADAAAMRAIAPAAAAHRAAIBEAAAAdEQDBEABgAAERAMENALAAHQ0AwREAEAAyAoAQAQAAAB0DgIACgIAAAQKAIAKAwAA2AAAAAAAAACoCgCACgEAAHQKAEACAAAAkEABBDQAQACoQAEAPAEAAHQOAgACAAAAdA4BAAoDAAC0DgEADgAAANAAAAAOAQAAkEABBDQAQAB0QACAQAEAABxAAIAsAwAAdDwCAEACAAB0QACANAEAABhAAIA0AAAAdEABAEACAAB0QACALAMAAAxAAIBAAQAAdEACAEACAAA0QABAQAAAAHREAgBAAwAADEQCADwAAAB0QAEARAAAADBAAEBAAAAAdEQCAEADAAAMRAIAPAAAAHRAAIBEAAAAdEQDBEABgAAERAMENALAAHQ0AwREAEAAyAoAQAQAAAB0DgIACgIAAAQKAIAKAwAA2AAAAAAAAACoCgCACgEAAHQKAEACAAAAkEABBDQAQACoQAEAPAEAAHQOAgACAAAAdA4BAAoDAAC0DgEADgAAANAAAAAOAQAAkEABBDQAQAB0QACAQAEAABxAAIAsAwAAdDwCAEACAAB0QACANAEAABhAAIA0AAAAdEABAEACAAB0QACALAMAAAxAAIBAAQAAdEACAEACAAA0QABAQAAAAHREAgBAAwAADEQCADwAAAB0QAEARAAAADBAAEBAAAAAdEQCAEADAAAMRAIAPAAAAHRAAIBEAAAAdEQDBEABgAAERAMENALAAHQ0AwREAEAAyAoAQAQAAAB0DgIACgIAAAQKAIAKAwAA2AAAAAAAAACoCgCACgEAAHQKAEACAAAAkEABBDQAQACoQAEAPAEAAHQOAgACAAAAdA4BAAoDAAC0DgEADgAAANAAAAAOAQAAkEABBDQAQAB0QACAQAEAABxAAIAsAwAAdDwCAEACAAB0QACANAEAABhAAIA0AAAAdEABAEACAAB0QACALAMAAAxAAIBAAQAAdEACAEACAAA0QABAQAAAAHREAgBAAwAADEQCADwAAAB0QAEARAAAADBAAEBAAAAAdEQCAEADAAAMRAIAPAAAAHRAAIBEAAAAdEQDBEABgAAERAMENALAAHQ0AwREAEAAyAoAQAQAAAB0DgIACgIAAAQKAIAKAwAA2AAAAAAAAACoCgCACgEAAHQKAEACAAAAkEABBDQAQACoQAEAPAEAAHQOAgACAAAAdA4BAAoDAAC0DgEADgAAANAAAAAOAQAAkEABBDQAQAB0QACAQAEAABxAAIAsAwAAdDwCAEACAAB0QACANAEAABhAAIA0AAAAdEABAEACAAB0QACALAMAAAxAAIBAAQAAdEACAEACAAA0QABAQAAAAHREAgBAAwAADEQCADwAAAB0QAEARAAAADBAAEBAAAAAdEQCAEADAAAMRAIAPAAAAHRAAIBEAAAAdEQDBEABgAAERAMENALAAHQ0AwREAEAAyAoAQAQAAAB0DgIACgIAAAQKAIAKAwAA2AAAAAAAAACoCgCACgEAAHQKAEACAAAAkEABBDQAQACoQAEAPAEAAHQOAgACAAAAdA4BAAoDAAC0DgEADgAAANAAAAAOAQAAkEABBDQAQAB0QACAQAEAABxAAIAsAwAAdDwCAEACAAB0QACANAEAABhAAIA0AAAAdEABAEACAAB0QACALAMAAAxAAIBAAQAAdEACAEACAAA0QABAQAAAAHREAgBAAwAADEQCADwAAAB0QAEARAAAADBAAEBAAAAAdEQCAEADAAAMRAIAPAAAAHRAAIBEAAAAdEQDBEABgAAERAMENALAAHQ0AwREAEAAyAoAQAQAAAB0DgIACgIAAAQKAIAKAwAA2AAAAAAAAACoCgCACgEAAHQKAEACAAAAkEABBDQAQACoQAEAPAEAAHQOAgACAAAAdA4BAAoDAAC0DgEADgAAANAAAAAOAQAAkEABBDQAQAB0QACAQAEAABxAAIAsAwAAdDwCAEACAAB0QACANAEAABhAAIA0AAAAdEABAEACAAB0QACALAMAAAxAAIBAAQAAdEACAEACAAA0QABAQAAAAHREAgBAAwAADEQCADwAAAB0QAEARAAAADBAAEBAAAAAdEQCAEADAAAMRAIAPAAAAHRAAIBEAAAAdEQDBEABgAAERAMENALAAHQ0AwREAEAAyAoAQAQAAAB0DgIACgIAAAQKAIAKAwAA2AAAAAAAAACoCgCACgEAAHQKAEACAAAAkEABBDQAQACoQAEAPAEAAHQOAgACAAAAdA4BAAoDAAC0DgEADgAAANAAAAAOAQAAkEABBDQAQAB0QACAQAEAABxAAIAsAwAAdDwCAEACAAB0QACANAEAABhAAIA0AAAAdEABAEACAAB0QACALAMAAAxAAIBAAQAAdEACAEACAAA0QABAQAAAAHREAgBAAwAADEQCADwAAAB0QAEARAAAADBAAEBAAAAAdEQCAEADAAAMRAIAPAAAAHRAAIBEAAAAdEQDBEABgAAERAMENALAAHQ0AwREAEAAyAoAQAQAAAB0DgIACgIAAAQKAIAKAwAA2AAAAAAAAACoCgCACgEAAHQKAEACAAAAkEABBDQAQACoQAEAPAEAAHQOAgACAAAAdA4BAAoDAAC0DgEADgAAANAAAAAOAQAAkEABBDQAQAB0QACAQAEAABxAAIAsAwAAdDwCAEACAAB0QACANAEAABhAAIA0AAAAdEABAEACAAB0QACALAMAAAxAAIBAAQAAdEACAEACAAA0QABAQAAAAHREAgBAAwAADEQCADwAAAB0QAEARAAAADBAAEBAAAAAdEQCAEADAAAMRAIAPAAAAHRAAIBEAAAAdEQDBEABgAAERAMENALAAHQ0AwREAEAAyAoAQAQAAAB0DgIACgIAAAQKAIAKAwAA2AAAAAAAAACoCgCACgEAAHQKAEACAAAAkEABBDQAQACoQAEAPAEAAHQOAgACAAAAdA4BAAoDAAC0DgEADgAAANAAAAAOAQAAkEABBDQAQAB0QACAQAEAABxAAIAsAwAAdDwCAEACAAB0QACANAEAABhAAIA0AAAAdEABAEACAAB0QACALAMAAAxAAIBAAQAAdEACAEACAAA0QABAQAAAAHREAgBAAwAADEQCADwAAAB0QAEARAAAADBAAEBAAAAAdEQCAEADAAAMRAIAPAAAAHRAAIBEAAAAdEQDBEABgAAERAMENALAAHQ0AwREAEAAyAoAQAQAAAB0DgIACgIAAAQKAIAKAwAA2AAAAAAAAADIQAEBAAAAABBAAMRAAUAADEAAxDQAQAB0RAMEQALAAHRAAYREAEAAhEABkDgAAAB0RADEQAGAAAREAMQQAEAAdEABhEQCwACEQAGQMAAAAHREAMRAAYAADEQAxCACwAB0QAGEPALAAARAAYREAsAAdEQAxEABgADIQAEAAAAAAKxAAQBEAgAAdAoAQAIAAADIQAEAAAAAAKxAAQBEAwAAdA4CAAIAAAB0DgEACgMAALQOAQAOAAAAfEABAAYAAACsRACAQAEAAHQKAEACAAAAdA4CAA4BAAC0DgIACgMAAHxAAQAGAQAArEQAQEABAAB0CgBAAgAAAHQOAQAOAAAAtA4BAAoDAADQAAAADgEAAMRIA8REAsAAdAQDzEgAbADUAAAAAAAAAMgEAgAAAAAAyAQBAAAAAADIBACAAAAAAMgEAEAAAAAA2AAAAAAAAAA==");
		s = new Shader (decoder.drain ());

		bin = new BitmapData (s.data ["sizeInput"] ["value"] [0], s.data ["sizeInput"] ["value"] [1], false, 0);
		drawCheckerBoard (bin, 0); s.data.src.input = bin;

		generateOutputBitmap (465, 465);

		// fill in all that shit and draw
		centerX.toolTip = s.data ["center"] ["description"];
		centerY.toolTip = s.data ["center"] ["description"];
		centerXft.toolTip = s.data ["centerFineTune"] ["description"];
		centerYft.toolTip = s.data ["centerFineTune"] ["description"];

		mandel.label = mandel.toolTip = s.data ["mandelbrot"] ["description"];
		mandel.selected = (s.data ["mandelbrot"] ["value"] == 1);

		power.minimum = s.data ["power"] ["minValue"] [0];
		power.maximum = s.data ["power"] ["maxValue"] [0];
		power.value = s.data ["power"] ["value"] [0];
		power.toolTip = s.data ["power"] ["description"];
		power.labels = ["e: " + power.minimum, power.maximum];

		muX.minimum = s.data ["mu"] ["minValue"] [0];
		muY.minimum = s.data ["mu"] ["minValue"] [1];
		muX.maximum = s.data ["mu"] ["maxValue"] [0];
		muY.maximum = s.data ["mu"] ["maxValue"] [1];
		muX.value = s.data ["mu"] ["value"] [0];
		muY.value = s.data ["mu"] ["value"] [1];
		muX.toolTip = s.data ["mu"] ["description"];
		muY.toolTip = muX.toolTip;
		muX.labels = ["mu.x: " + muX.minimum, muX.maximum];
		muY.labels = ["mu.x: " + muX.minimum, muX.maximum];

		iterations.minimum = s.data ["iterations"] ["minValue"] [0];
		iterations.maximum = s.data ["iterations"] ["maxValue"] [0];
		iterations.value = s.data ["iterations"] ["value"] [0];
		iterations.toolTip = s.data ["iterations"] ["description"];
		iterations.labels = ["Iterations: " + iterations.minimum, iterations.maximum];

		otScale.toolTip = s.data ["orbitTrapScale"] ["description"];
		otRotation.toolTip = s.data ["orbitTrapRotation"] ["description"];
		otSpin.toolTip = s.data ["orbitTrapSpin"] ["description"];
		otOffsetX.toolTip = s.data ["orbitTrapOffset"] ["description"];
		otOffsetY.toolTip = otOffsetX.toolTip;
		zoom.toolTip = s.data ["zoom"] ["description"];
		bailout.toolTip = s.data ["bailout"] ["description"];

		draw ();
	}
	public function draw ():void {
		clearTimeout (t);
		if (j != null) {
			j.cancel ();
			drawCheckerBoard (bout);
			// apparently cancelling takes some time...
			t = setTimeout (startShaderJob, 2000);
		} else {
			drawCheckerBoard (bout);
			startShaderJob ();
		}
	}
	public function startShaderJob ():void {
		s.data ["center"] ["value"] = [centerX.value, centerY.value];
		s.data ["centerFineTune"] ["value"] = [centerXft.value, centerYft.value];
		s.data ["mandelbrot"] ["value"] = [mandel.selected ? 1 : 0];
		s.data ["power"] ["value"] = [power.value];
		s.data ["mu"] ["value"] = [muX.value, muY.value];
		s.data ["iterations"] ["value"] = [int(iterations.value)];
		s.data ["orbitTrapScale"] ["value"] = [otScale.value];
		s.data ["orbitTrapRotation"] ["value"] = [otRotation.value];
		s.data ["orbitTrapSpin"] ["value"] = [otSpin.value];
		s.data ["orbitTrapOffset"] ["value"] = [otOffsetX.value, otOffsetY.value];
		s.data ["zoom"] ["value"] = [zoom.value];
		s.data ["bailout"] ["value"] = [bailout.value];

		s.data ["sizeInput"] ["value"] = [bin.width, bin.height];
		s.data ["sizeOutput"] ["value"] = [bout.width, bout.height];

		j = new ShaderJob (s, bout);
		j.start ();
	}
	public function resizeAndDraw ():void {
		generateOutputBitmap (imgSize.value, imgSize.value); draw();
	}
	public function drawCheckerBoard (b:BitmapData, c:uint = 0xcfcfcf):void {
		b.lock ();
		var w:int = b.width, h:int = b.height, k:int = w / 100;
		for (var i:int = 0; i < w; i++)
		for (var j:int = 0; j < h; j++)
			b.setPixel32 (i, j, ((int (i / k) % 2 + int (j / k) % 2) % 2) * (0xffffff - c) + c + 0xff000000);
		b.unlock ();
	}
	public function generateOutputBitmap (w:int, h:int):void {
		if (bout != null) {
			uic.removeChildAt (0); bout.dispose ();
		}

		bout = new BitmapData (w, h, true, 0); var bm:Bitmap = new Bitmap (bout);
		uic.addChild (bm); bm.scaleX = Math.min (465.0 / w, 465.0 / h); bm.scaleY = bm.scaleX;
	}
	public var file:FileReference;
	public var loader:Loader;
	public function loadImage ():void {
		// load better map, yeah...
		file = new FileReference;
		file.addEventListener (Event.SELECT, onFileSelected);
		file.addEventListener (Event.COMPLETE, onFileLoaded);
		file.browse ();
	}
	public function onFileSelected (e:Event):void { file.load (); }
	public function onFileLoaded (e:Event):void {
		loader = new Loader;
		loader.contentLoaderInfo.addEventListener (Event.COMPLETE, onImageReady);
		loader.contentLoaderInfo.addEventListener (IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {});
		loader.loadBytes (file.data);
	}
	public function onImageReady (e:Event):void {
		try {
			bin.dispose ();
			bin = Bitmap (loader.content).bitmapData;
			s.data.src.input = bin;
			draw ();
		} catch (e:*) {
			;
		}
	}
	public function save ():void {
		// TODO: save as PNG
		var jpgEncoder:JPGEncoder = new JPGEncoder (99);
		var jpgData:ByteArray = jpgEncoder.encode (bout);
		var fileRef:FileReference = new FileReference;
		fileRef.save (jpgData, "result.jpg");
	}
	]]>
	</mx:Script>
</mx:Application>