Skip to content

Commit

Permalink
use new video_event library in examples
Browse files Browse the repository at this point in the history
  • Loading branch information
monkstone committed Jun 6, 2015
1 parent 336a6ea commit ba4a714
Show file tree
Hide file tree
Showing 13 changed files with 352 additions and 38 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ Example-Sketches
================

Many of the vanilla processing example sketches have been translated to ruby-processing, and they are mainly written as 'bare' sketches (ie not class wrapped) in keeping with the original processing. At runtime these sketches the get wrapped into a Sketch class. Should you prefer you can still write class wrapped sketches, these will work equally well with ruby-processing. Certain sketches must be run with JRuby-Complete (mainly `load_image` and `shader` sketches), this is a [java permissions thing with jruby][]. You should also checkout the [Nature of Code Examples in ruby][] and for the beginner [Learning Processing with Ruby][] for even more examples.
Includes autorun Rakefiles, in a console cd outer directory and 'rake' to run all autorun examples or eg 'rake shaders' to just run the shader examples.

### Partial Catalogue (for the lazy)

Expand Down
9 changes: 8 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@
root = File.expand_path(__dir__)

desc 'run contributed samples'
task :default => [:contributed]
task :default => [:all]

desc 'run all autorun samples'
task :all do
Rake::Task[:contributed].execute
Rake::Task[:vecmath].execute
Rake::Task[:shaders].execute
end

desc 'run contributed samples'
task :contributed do
Expand Down
11 changes: 5 additions & 6 deletions samples/processing_app/library/video/capture/ascii_capture.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,20 @@
# This sketch is a simple homage that re-interprets live video as ASCII text.
# See the key_pressed function for more options, like changing the font size.
#
load_library :video
load_library :video, :video_event
include_package 'processing.video'

attr_reader :bright, :char, :cheat_screen, :font, :font_size, :letters, :video

# All ASCII characters, sorted according to their visual density
LETTER_STRING = %q{ .`-_':,;^=+/\"|)\\<>)iv%xclrs{*}I?!][1taeo7zjLunT#JCwfy325Fp6mqSghVd4EgXPGZbYkOA&8U$@KHDBWNMR0Q}
LETTER_ORDER = LETTER_STRING.scan(/./)

def setup
size(640, 480)
init_video
@font_size = 1.5
@font = load_font(data_path('UniversLTStd-Light-48.vlw'))
@font = load_font('UniversLTStd-Light-48.vlw')
# for the 256 levels of brightness, distribute the letters across
# the an array of 256 elements to use for the lookup
@letters = (0...256).map do |i|
Expand All @@ -38,14 +39,12 @@ def init_video
@cheat_screen = false
end

def capture_event(c)
def captureEvent(c)
c.read
background 0
end

def draw
return unless (video.available == true)
capture_event(video)
background 0
push_matrix
hgap = width / video.width
vgap = height / video.height
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# background-subtraction technique. To initialize the background, press a key.
#

load_library :video
load_libraries :video, :video_event
include_package 'processing.video'

attr_reader :background_pixels, :number_of_pixels, :video
Expand Down Expand Up @@ -35,8 +35,6 @@ def capture # captureEvent does not work like vanilla processing
end

def draw
return unless (video.available == true)
capture
video.load_pixels # Make the pixels of video available
# Difference between the current frame and the stored background
# current_sum = 0
Expand Down Expand Up @@ -66,6 +64,10 @@ def draw
# p current_sum # Print out the total amount of movement
end

def captureEvent(c)
c.read
end

def key_pressed
video.load_pixels
@background_pixels = video.pixels.clone
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Because this sketch uses a glsl shader it needs to run using
# jruby-complete (typically rp5 --nojruby sketch.rb)
# hold down mouse to see unfiltered output
load_libraries :video, :video_event
include_package 'processing.video'
attr_reader :cam, :my_shader

def setup
size(640, 480, P2D)
@my_shader = load_shader('bwfrag.glsl')
start_capture(width, height)
end

def start_capture(w, h)
@cam = Capture.new(self, w, h)
cam.start
end

def draw
image(cam, 0, 0)
return if mouse_pressed?
filter(my_shader)
end

# using snake case to match java reflect method
def captureEvent(c)
c.read
end
23 changes: 23 additions & 0 deletions samples/processing_app/library/video/capture/data/bwfrag.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif

#define PROCESSING_TEXTURE_SHADER

uniform sampler2D texture;

varying vec4 vertColor;
varying vec4 vertTexCoord;

const vec4 lumcoeff = vec4(0.299, 0.587, 0.114, 0);

void main() {
vec4 col = texture2D(texture, vertTexCoord.st);
float lum = dot(col, lumcoeff);
if (0.5 < lum) {
gl_FragColor = vertColor;
} else {
gl_FragColor = vec4(0, 0, 0, 1);
}
}
220 changes: 220 additions & 0 deletions samples/processing_app/library/video/capture/data/edge_detect.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@

// Original shader by Ken Slade
// https://www.shadertoy.com/view/ldsSWr

// Ported to Processing by Raphaël de Courville <twitter: @sableRaph>

#ifdef GL_ES
precision highp float;
#endif

// This line is optional from Processing 2.1 and up
#define PROCESSING_TEXTURE_SHADER

uniform sampler2D texture; // iChannel0 in Shadertoy
uniform vec2 sketchSize; // iResolution in Shadertoy



// * Code from Shadertoy *

// Note: Uniforms have been renamed (see above)

// Note 2: void mainImage( out vec4 fragColor, in vec2 fragCoord )
// was changed into
// void main( void )

// Note 3: fragCoord and fragColor had to be renamed into
// gl_FragCoord and gl_FragColor




// Basic edge detection via convolution
// Ken Slade - ken.slade@gmail.com
// at https://www.shadertoy.com/view/ldsSWr

// Based on original Sobel shader by:
// Jeroen Baert - jeroen.baert@cs.kuleuven.be (www.forceflow.be)
// at https://www.shadertoy.com/view/Xdf3Rf

//options are edge, colorEdge, or trueColorEdge
#define EDGE_FUNC edge

//options are KAYYALI_NESW, KAYYALI_SENW, PREWITT, ROBERTSCROSS, SCHARR, or SOBEL
#define SOBEL

// Use these parameters to fiddle with settings
#ifdef SCHARR
#define STEP 0.15
#else
#define STEP 1.0
#endif


#ifdef KAYYALI_NESW
const mat3 kayyali_NESW = mat3(-6.0, 0.0, 6.0,
0.0, 0.0, 0.0,
6.0, 0.0, -6.0);
#endif
#ifdef KAYYALI_SENW
const mat3 kayyali_SENW = mat3(6.0, 0.0, -6.0,
0.0, 0.0, 0.0,
-6.0, 0.0, 6.0);
#endif
#ifdef PREWITT
// Prewitt masks (see http://en.wikipedia.org/wiki/Prewitt_operator)
const mat3 prewittKernelX = mat3(-1.0, 0.0, 1.0,
-1.0, 0.0, 1.0,
-1.0, 0.0, 1.0);

const mat3 prewittKernelY = mat3(1.0, 1.0, 1.0,
0.0, 0.0, 0.0,
-1.0, -1.0, -1.0);
#endif
#ifdef ROBERTSCROSS
// Roberts Cross masks (see http://en.wikipedia.org/wiki/Roberts_cross)
const mat3 robertsCrossKernelX = mat3(1.0, 0.0, 0.0,
0.0, -1.0, 0.0,
0.0, 0.0, 0.0);
const mat3 robertsCrossKernelY = mat3(0.0, 1.0, 0.0,
-1.0, 0.0, 0.0,
0.0, 0.0, 0.0);
#endif
#ifdef SCHARR
// Scharr masks (see http://en.wikipedia.org/wiki/Sobel_operator#Alternative_operators)
const mat3 scharrKernelX = mat3(3.0, 10.0, 3.0,
0.0, 0.0, 0.0,
-3.0, -10.0, -3.0);

const mat3 scharrKernelY = mat3(3.0, 0.0, -3.0,
10.0, 0.0, -10.0,
3.0, 0.0, -3.0);
#endif
#ifdef SOBEL
// Sobel masks (see http://en.wikipedia.org/wiki/Sobel_operator)
const mat3 sobelKernelX = mat3(1.0, 0.0, -1.0,
2.0, 0.0, -2.0,
1.0, 0.0, -1.0);

const mat3 sobelKernelY = mat3(-1.0, -2.0, -1.0,
0.0, 0.0, 0.0,
1.0, 2.0, 1.0);
#endif

//performs a convolution on an image with the given kernel
float convolve(mat3 kernel, mat3 image) {
float result = 0.0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
result += kernel[i][j]*image[i][j];
}
}
return result;
}

//helper function for colorEdge()
float convolveComponent(mat3 kernelX, mat3 kernelY, mat3 image) {
vec2 result;
result.x = convolve(kernelX, image);
result.y = convolve(kernelY, image);
return clamp(length(result), 0.0, 255.0);
}

//returns color edges using the separated color components for the measure of intensity
//for each color component instead of using the same intensity for all three. This results
//in false color edges when transitioning from one color to another, but true colors when
//the transition is from black to color (or color to black).
vec4 colorEdge(float stepx, float stepy, vec2 center, mat3 kernelX, mat3 kernelY) {
//get samples around pixel
vec4 colors[9];
colors[0] = texture2D(texture,center + vec2(-stepx,stepy));
colors[1] = texture2D(texture,center + vec2(0,stepy));
colors[2] = texture2D(texture,center + vec2(stepx,stepy));
colors[3] = texture2D(texture,center + vec2(-stepx,0));
colors[4] = texture2D(texture,center);
colors[5] = texture2D(texture,center + vec2(stepx,0));
colors[6] = texture2D(texture,center + vec2(-stepx,-stepy));
colors[7] = texture2D(texture,center + vec2(0,-stepy));
colors[8] = texture2D(texture,center + vec2(stepx,-stepy));

mat3 imageR, imageG, imageB, imageA;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
imageR[i][j] = colors[i*3+j].r;
imageG[i][j] = colors[i*3+j].g;
imageB[i][j] = colors[i*3+j].b;
imageA[i][j] = colors[i*3+j].a;
}
}

vec4 color;
color.r = convolveComponent(kernelX, kernelY, imageR);
color.g = convolveComponent(kernelX, kernelY, imageG);
color.b = convolveComponent(kernelX, kernelY, imageB);
color.a = convolveComponent(kernelX, kernelY, imageA);

return color;
}

//finds edges where fragment intensity changes from a higher value to a lower one (or
//vice versa).
vec4 edge(float stepx, float stepy, vec2 center, mat3 kernelX, mat3 kernelY){
// get samples around pixel
mat3 image = mat3(length(texture2D(texture,center + vec2(-stepx,stepy)).rgb),
length(texture2D(texture,center + vec2(0,stepy)).rgb),
length(texture2D(texture,center + vec2(stepx,stepy)).rgb),
length(texture2D(texture,center + vec2(-stepx,0)).rgb),
length(texture2D(texture,center).rgb),
length(texture2D(texture,center + vec2(stepx,0)).rgb),
length(texture2D(texture,center + vec2(-stepx,-stepy)).rgb),
length(texture2D(texture,center + vec2(0,-stepy)).rgb),
length(texture2D(texture,center + vec2(stepx,-stepy)).rgb));
vec2 result;
result.x = convolve(kernelX, image);
result.y = convolve(kernelY, image);

float color = clamp(length(result), 0.0, 255.0);
return vec4(color);
}

//Colors edges using the actual color for the fragment at this location
vec4 trueColorEdge(float stepx, float stepy, vec2 center, mat3 kernelX, mat3 kernelY) {
vec4 edgeVal = edge(stepx, stepy, center, kernelX, kernelY);
return edgeVal * texture2D(texture,center);
}

void main( void ){
vec2 uv = gl_FragCoord.xy / sketchSize.xy;
vec4 color = texture2D(texture, uv.xy);
#ifdef KAYYALI_NESW
gl_FragColor = EDGE_FUNC(STEP/sketchSize[0], STEP/sketchSize[1],
uv,
kayyali_NESW, kayyali_NESW);
#endif
#ifdef KAYYALI_SENW
gl_FragColor = EDGE_FUNC(STEP/sketchSize[0], STEP/sketchSize[1],
uv,
kayyali_SENW, kayyali_SENW);
#endif
#ifdef PREWITT
gl_FragColor = EDGE_FUNC(STEP/sketchSize[0], STEP/sketchSize[1],
uv,
prewittKernelX, prewittKernelY);
#endif
#ifdef ROBERTSCROSS
gl_FragColor = EDGE_FUNC(STEP/sketchSize[0], STEP/sketchSize[1],
uv,
robertsCrossKernelX, robertsCrossKernelY);
#endif
#ifdef SOBEL
gl_FragColor = EDGE_FUNC(STEP/sketchSize[0], STEP/sketchSize[1],
uv,
sobelKernelX, sobelKernelY);
#endif
#ifdef SCHARR
gl_FragColor = EDGE_FUNC(STEP/sketchSize[0], STEP/sketchSize[1],
uv,
scharrKernelX, scharrKernelY);
#endif
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
load_library :video, :video_event
include_package 'processing.video'
attr_reader :cam, :my_shader

def setup
size(640, 480, P2D)
@my_shader = load_shader('edge_detect.glsl')
my_shader.set('sketchSize', width.to_f, height.to_f)
start_capture(width, height)
end

def start_capture(w, h)
@cam = Capture.new(self, w, h)
cam.start
end

def draw
image(cam, 0, 0)
return if mouse_pressed?
filter(my_shader)
end

# use snake case here to match java reflect method
def captureEvent(c)
c.read
end
Loading

0 comments on commit ba4a714

Please sign in to comment.