Navigation Menu

Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Evan Wallace committed Apr 10, 2011
0 parents commit b25b896
Show file tree
Hide file tree
Showing 32 changed files with 2,617 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
@@ -0,0 +1,2 @@
.DS_Store
www/generated.js
36 changes: 36 additions & 0 deletions build.py
@@ -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()
137 changes: 137 additions & 0 deletions src/core/main.js
@@ -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;
56 changes: 56 additions & 0 deletions src/filter/blur.js
@@ -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();
});
};
38 changes: 38 additions & 0 deletions src/filter/brightnesscontrast.js
@@ -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();
});
};
43 changes: 43 additions & 0 deletions src/filter/dotscreen.js
@@ -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();
});
};

0 comments on commit b25b896

Please sign in to comment.