Permalink
Browse files

initial commit

  • Loading branch information...
0 parents commit b25b8963b0c45159a4d9acedabd3b11da8008d31 Evan Wallace committed Apr 10, 2011
@@ -0,0 +1,2 @@
+.DS_Store
+www/generated.js
@@ -0,0 +1,36 @@
+#!/usr/bin/python
+
+module = 'hackny'
+input_path = 'src/'
+output_path = 'www/generated.js'
+
+import re, os, sys, time
+
+def sources():
+ return [os.path.join(base, f) for base, folders, files in \
+ os.walk(input_path) for f in files if f.endswith('.js')]
+
+def compile(sources):
+ return '\n'.join('// %s\n%s' % (path, open(path).read()) for path in sources)
+
+def build():
+ data = 'var ' + module + ' = (function() {\nvar exports = {};\n\n' + compile(sources()) + '\nreturn exports;\n})();\n'
+ print 'built %s (%u lines)' % (output_path, len(data.split('\n')))
+ open(output_path, 'w').write(data)
+
+def stat():
+ return [os.stat(file).st_mtime for file in sources()]
+
+def monitor():
+ a = stat()
+ while True:
+ time.sleep(0.5)
+ b = stat()
+ if a != b:
+ a = b
+ build()
+
+if __name__ == '__main__':
+ build()
+ if 'debug' in sys.argv:
+ monitor()
@@ -0,0 +1,137 @@
+var gl;
+var original;
+var texture;
+var filter;
+var filters;
+var displayShader;
+
+function initGL() {
+ var canvas3d = $('#canvas')[0];
+ gl = canvas3d.getContext('experimental-webgl');
+ displayShader = new Shader(null, '\
+ uniform sampler2D texture;\
+ varying vec2 texCoord;\
+ void main() {\
+ gl_FragColor = texture2D(texture, vec2(texCoord.x, 1.0 - texCoord.y));\
+ }\
+ ');
+}
+
+function reloadImage(image) {
+ gl.canvas.width = image.width;
+ gl.canvas.height = image.height;
+ gl.viewport(0, 0, image.width, image.height);
+ __delete__(original);
+ __delete__(texture);
+ Texture.emptyCache();
+ original = Texture.fromImage(image);
+ texture = new Texture(image.width, image.height, gl.RGB, gl.UNSIGNED_BYTE);
+ drawGL();
+
+ $('#load-image-overlay').fadeOut();
+}
+
+function drawGL() {
+ if (original) {
+ filter.drawTo(original, texture);
+
+ texture.use();
+ displayShader.drawRect();
+ }
+}
+
+function startLoading() {
+ var image = new Image();
+ image.onload = function() {
+ reloadImage(image);
+ };
+ // image.src = 'samples/Copenhagen_small.jpg';
+ image.src = 'samples/Flowers_small.jpg';
+
+ // sample images
+ $('.sample-image').click(function() {
+ var image = document.createElement('img');
+ image.onload = function() {
+ reloadImage(image);
+ };
+ image.src = this.src;
+ });
+
+ // image load
+ $('#load-image').click(function() {
+ $('#load-image-overlay').fadeIn();
+ });
+ $('#close-overlay').click(function() {
+ $('#load-image-overlay').fadeOut();
+ });
+ $('#use-chosen-file').click(function() {
+ var files = $('#file').attr('files');
+ var reader = new FileReader();
+
+ reader.onload = function(event) {
+ var image = document.createElement('img');
+ image.onload = function() {
+ reloadImage(image);
+ };
+ image.src = event.target.result;
+ };
+
+ reader.readAsDataURL(files[0]);
+ });
+
+ // image save
+ $('#save-image').click(function() {
+ var array = new Uint8Array(texture.width * texture.height * 4);
+ texture.drawTo(function() {
+ gl.readPixels(0, 0, texture.width, texture.height, gl.RGBA, gl.UNSIGNED_BYTE, array);
+ });
+
+ // copy texture data to the canvas
+ var canvas2d = document.createElement('canvas');
+ var c = canvas2d.getContext('2d');
+ canvas2d.width = texture.width;
+ canvas2d.height = texture.height;
+ var data = c.createImageData(texture.width, texture.height);
+ for (var i = 0; i < array.length; i++) {
+ data.data[i] = array[i];
+ }
+ c.putImageData(data, 0, 0);
+ dataURL = canvas2d.toDataURL('image/png');
+
+ // TODO: bounce request off of server
+ window.open(dataURL);
+ });
+}
+
+function switchToFilter(index) {
+ filter = filters[index];
+ $('#markers').html(filter.markerHTML || '');
+ $('#controls').html('<table>' + filter.sliderHTML + '</table>');
+ filter.initUI();
+ drawGL();
+}
+
+function main() {
+ initGL();
+ startLoading();
+
+ filters = [
+ new BrightnessContrastFilter(),
+ new BlurFilter(),
+ new HueSaturationFilter(),
+ new SwirlFilter(),
+ new ZoomBlurFilter(),
+ new DotScreenFilter(),
+ new EdgeWorkFilter()
+ ];
+ for (var i = 0; i < filters.length; i++) {
+ $('select').append('<option>' + filters[i].name + '</option>');
+ }
+ $('select').bind('change', function() {
+ var index = $('select')[0].selectedIndex;
+ switchToFilter(index);
+ });
+ switchToFilter(0);
+}
+
+exports.main = main;
@@ -0,0 +1,56 @@
+function BlurFilter() {
+ this.shader = new Shader(null, '\
+ uniform sampler2D texture;\
+ uniform float radius;\
+ uniform vec2 delta;\
+ varying vec2 texCoord;\
+ \
+ /* random number between 0 and 1 */\
+ float random(vec3 scale, float seed) {\
+ /* use the fragment position for randomness */\
+ return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);\
+ }\
+ \
+ void main() {\
+ vec3 color = vec3(0.0);\
+ float total = 0.0;\
+ \
+ /* randomize the lookup values to hide the fixed number of samples */\
+ float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);\
+ \
+ for (float t = -30.0; t <= 30.0; t++) {\
+ float percent = (t + offset - 0.5) / 30.0;\
+ float weight = 1.0 - abs(percent);\
+ color += texture2D(texture, texCoord + delta * percent * radius).rgb * weight;\
+ total += weight;\
+ }\
+ gl_FragColor = vec4(color / total, 1.0);\
+ }\
+ ');
+
+ slider(this, 'Radius', 0, 100, 50, 1, function(value) {
+ this.radius = value;
+ });
+
+ this.tempTexture = null;
+}
+
+BlurFilter.prototype.name = 'Blur';
+
+BlurFilter.prototype.drawTo = function(original, texture) {
+ var this_ = this;
+ texture.drawTo(function() {
+ original.use();
+ this_.shader.uniforms({
+ delta: [1 / 800, 0],
+ radius: this_.radius
+ }).drawRect();
+ });
+ texture.drawToUsingSelf(function() {
+ texture.use();
+ this_.shader.uniforms({
+ delta: [0, 1 / 600],
+ radius: this_.radius
+ }).drawRect();
+ });
+};
@@ -0,0 +1,38 @@
+function BrightnessContrastFilter() {
+ this.shader = new Shader(null, '\
+ uniform sampler2D texture;\
+ uniform float brightness;\
+ uniform float contrast;\
+ varying vec2 texCoord;\
+ void main() {\
+ vec3 color = texture2D(texture, texCoord).rgb;\
+ color += brightness;\
+ if (contrast > 0.0) {\
+ color = (color - 0.5) / (1.0 - contrast) + 0.5;\
+ } else {\
+ color = (color - 0.5) * (1.0 + contrast) + 0.5;\
+ }\
+ gl_FragColor = vec4(color, 1.0);\
+ }\
+ ');
+
+ slider(this, 'Brightness', -1, 1, 0, 0.02, function(value) {
+ this.brightness = value;
+ });
+ slider(this, 'Contrast', -1, 1, 0, 0.02, function(value) {
+ this.contrast = value;
+ });
+}
+
+BrightnessContrastFilter.prototype.name = 'Brightness / Contrast';
+
+BrightnessContrastFilter.prototype.drawTo = function(original, texture) {
+ var this_ = this;
+ texture.drawTo(function() {
+ original.use();
+ this_.shader.uniforms({
+ brightness: this_.brightness,
+ contrast: this_.contrast
+ }).drawRect();
+ });
+};
@@ -0,0 +1,43 @@
+function DotScreenFilter() {
+ this.shader = new Shader(null, '\
+ uniform sampler2D texture;\
+ uniform float angle;\
+ uniform float size;\
+ uniform vec2 texSize;\
+ varying vec2 texCoord;\
+ void main() {\
+ vec3 color = texture2D(texture, texCoord).rgb;\
+ float s = sin(angle), c = cos(angle);\
+ vec2 tex = texCoord * texSize;\
+ vec2 point = vec2(\
+ c * tex.x - s * tex.y,\
+ s * tex.x + c * tex.y\
+ ) * size;\
+ float weight = (sin(point.x) * sin(point.y)) * 2.0;\
+ float average = (color.r + color.g + color.b) / 3.0;\
+ color = vec3(average + (average - 0.6) * 4.0 + weight);\
+ gl_FragColor = vec4(color, 1.0);\
+ }\
+ ');
+
+ slider(this, 'Angle', -1, 1, 0.5, 0.02, function(value) {
+ this.angle = value;
+ });
+ slider(this, 'Size', 0, 1, 0.75, 0.02, function(value) {
+ this.size = value;
+ });
+}
+
+DotScreenFilter.prototype.name = 'Dot Screen';
+
+DotScreenFilter.prototype.drawTo = function(original, texture) {
+ var this_ = this;
+ texture.drawTo(function() {
+ original.use();
+ this_.shader.uniforms({
+ angle: this_.angle,
+ size: this_.size,
+ texSize: [original.width, original.height]
+ }).drawRect();
+ });
+};
Oops, something went wrong.

0 comments on commit b25b896

Please sign in to comment.