processing 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/{release.yml → release-gem.yml} +21 -21
- data/.github/workflows/tag.yml +35 -0
- data/.github/workflows/test.yml +8 -9
- data/.github/workflows/utils.rb +55 -0
- data/ChangeLog.md +40 -28
- data/LICENSE +1 -1
- data/Rakefile +9 -34
- data/RubyProcessing.podspec +1 -1
- data/VERSION +1 -1
- data/examples/breakout.rb +2 -1
- data/examples/camera.rb +2 -1
- data/examples/clock.rb +3 -1
- data/examples/delay_camera.rb +2 -1
- data/examples/hello.rb +2 -1
- data/examples/image.rb +2 -1
- data/examples/shapes.rb +2 -1
- data/lib/processing/all.rb +20 -0
- data/lib/processing/capture.rb +119 -0
- data/lib/processing/context.rb +471 -0
- data/lib/processing/{module.rb → extension.rb} +3 -3
- data/lib/processing/font.rb +62 -0
- data/lib/processing/graphics.rb +40 -0
- data/lib/processing/graphics_context.rb +1676 -0
- data/lib/processing/image.rb +128 -0
- data/lib/processing/shader.rb +157 -0
- data/lib/processing/touch.rb +28 -0
- data/lib/processing/vector.rb +559 -0
- data/lib/processing.rb +30 -11
- data/lib/rubysketch-processing.rb +2 -1
- data/lib/rubysketch.rb +1 -1
- data/processing.gemspec +12 -6
- data/src/RubyProcessing.mm +1 -1
- data/test/helper.rb +8 -2
- data/test/{processing/test_graphics.rb → test_graphics.rb} +3 -3
- data/test/{processing/test_shader.rb → test_shader.rb} +3 -3
- data/test/{processing/test_utility.rb → test_utility.rb} +3 -3
- data/test/{processing/test_vector.rb → test_vector.rb} +8 -4
- metadata +112 -20
- data/lib/processing/include.rb +0 -25
- data/lib/processing/processing.rb +0 -3211
- data/test/processing/helper.rb +0 -11
@@ -0,0 +1,128 @@
|
|
1
|
+
module Processing
|
2
|
+
|
3
|
+
|
4
|
+
# Image object.
|
5
|
+
#
|
6
|
+
class Image
|
7
|
+
|
8
|
+
# @private
|
9
|
+
def initialize(image)
|
10
|
+
@image = image
|
11
|
+
end
|
12
|
+
|
13
|
+
# Gets width of image.
|
14
|
+
#
|
15
|
+
# @return [Numeric] width of image
|
16
|
+
#
|
17
|
+
def width()
|
18
|
+
@image.width
|
19
|
+
end
|
20
|
+
|
21
|
+
# Gets height of image.
|
22
|
+
#
|
23
|
+
# @return [Numeric] height of image
|
24
|
+
#
|
25
|
+
def height()
|
26
|
+
@image.height
|
27
|
+
end
|
28
|
+
|
29
|
+
# Applies an image filter.
|
30
|
+
#
|
31
|
+
# overload filter(shader)
|
32
|
+
# overload filter(type)
|
33
|
+
# overload filter(type, param)
|
34
|
+
#
|
35
|
+
# @param shader [Shader] a fragment shader to apply
|
36
|
+
# @param type [THRESHOLD, GRAY, INVERT, BLUR] filter type
|
37
|
+
# @param param [Numeric] a parameter for each filter
|
38
|
+
#
|
39
|
+
def filter(*args)
|
40
|
+
@filter = Shader.createFilter__(*args)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Resizes image.
|
44
|
+
#
|
45
|
+
# @param width [Numeric] width for resized image
|
46
|
+
# @param height [Numeric] height for resized image
|
47
|
+
#
|
48
|
+
# @return [nil] nil
|
49
|
+
#
|
50
|
+
def resize(width, height)
|
51
|
+
@image = Rays::Image.new(width, height).paint do |painter|
|
52
|
+
painter.image @image, 0, 0, width, height
|
53
|
+
end
|
54
|
+
nil
|
55
|
+
end
|
56
|
+
|
57
|
+
# Copies image.
|
58
|
+
#
|
59
|
+
# @overload copy(sx, sy, sw, sh, dx, dy, dw, dh)
|
60
|
+
# @overload copy(img, sx, sy, sw, sh, dx, dy, dw, dh)
|
61
|
+
#
|
62
|
+
# @param img [Image] image for copy source
|
63
|
+
# @param sx [Numrtic] x position of source region
|
64
|
+
# @param sy [Numrtic] y position of source region
|
65
|
+
# @param sw [Numrtic] width of source region
|
66
|
+
# @param sh [Numrtic] height of source region
|
67
|
+
# @param dx [Numrtic] x position of destination region
|
68
|
+
# @param dy [Numrtic] y position of destination region
|
69
|
+
# @param dw [Numrtic] width of destination region
|
70
|
+
# @param dh [Numrtic] height of destination region
|
71
|
+
#
|
72
|
+
# @return [nil] nil
|
73
|
+
#
|
74
|
+
def copy(img = nil, sx, sy, sw, sh, dx, dy, dw, dh)
|
75
|
+
blend img, sx, sy, sw, sh, dx, dy, dw, dh, :normal
|
76
|
+
end
|
77
|
+
|
78
|
+
# Blends image.
|
79
|
+
#
|
80
|
+
# @overload blend(sx, sy, sw, sh, dx, dy, dw, dh, mode)
|
81
|
+
# @overload blend(img, sx, sy, sw, sh, dx, dy, dw, dh, mode)
|
82
|
+
#
|
83
|
+
# @param img [Image] image for blend source
|
84
|
+
# @param sx [Numeric] x position of source region
|
85
|
+
# @param sy [Numeric] y position of source region
|
86
|
+
# @param sw [Numeric] width of source region
|
87
|
+
# @param sh [Numeric] height of source region
|
88
|
+
# @param dx [Numeric] x position of destination region
|
89
|
+
# @param dy [Numeric] y position of destination region
|
90
|
+
# @param dw [Numeric] width of destination region
|
91
|
+
# @param dh [Numeric] height of destination region
|
92
|
+
# @param mode [BLEND, ADD, SUBTRACT, LIGHTEST, DARKEST, EXCLUSION, MULTIPLY, SCREEN, REPLACE] blend mode
|
93
|
+
#
|
94
|
+
# @return [nil] nil
|
95
|
+
#
|
96
|
+
def blend(img = nil, sx, sy, sw, sh, dx, dy, dw, dh, mode)
|
97
|
+
img ||= self
|
98
|
+
@image.paint do |painter|
|
99
|
+
img.drawImage__ painter, sx, sy, sw, sh, dx, dy, dw, dh, blend_mode: mode
|
100
|
+
end
|
101
|
+
nil
|
102
|
+
end
|
103
|
+
|
104
|
+
# Saves image to file.
|
105
|
+
#
|
106
|
+
# @param filename [String] file name to save image
|
107
|
+
#
|
108
|
+
def save(filename)
|
109
|
+
@image.save filename
|
110
|
+
end
|
111
|
+
|
112
|
+
# @private
|
113
|
+
def getInternal__()
|
114
|
+
@image
|
115
|
+
end
|
116
|
+
|
117
|
+
# @private
|
118
|
+
def drawImage__(painter, *args, **states)
|
119
|
+
shader = painter.shader || @filter&.getInternal__
|
120
|
+
painter.push shader: shader, **states do |_|
|
121
|
+
painter.image getInternal__, *args
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
end# Image
|
126
|
+
|
127
|
+
|
128
|
+
end# Processing
|
@@ -0,0 +1,157 @@
|
|
1
|
+
module Processing
|
2
|
+
|
3
|
+
|
4
|
+
# Shader object.
|
5
|
+
#
|
6
|
+
class Shader
|
7
|
+
|
8
|
+
# Initialize shader object.
|
9
|
+
#
|
10
|
+
# @param vertSrc [String] vertex shader source
|
11
|
+
# @param fragSrc [String] fragment shader source
|
12
|
+
#
|
13
|
+
def initialize(vertSrc, fragSrc)
|
14
|
+
@shader = Rays::Shader.new fragSrc, vertSrc, ENV__
|
15
|
+
end
|
16
|
+
|
17
|
+
# Sets uniform variables.
|
18
|
+
#
|
19
|
+
# @overload set(name, a)
|
20
|
+
# @overload set(name, a, b)
|
21
|
+
# @overload set(name, a, b, c)
|
22
|
+
# @overload set(name, a, b, c, d)
|
23
|
+
# @overload set(name, nums)
|
24
|
+
# @overload set(name, vec)
|
25
|
+
# @overload set(name, vec, ncoords)
|
26
|
+
# @overload set(name, tex)
|
27
|
+
#
|
28
|
+
# @param name [String] uniform variable name
|
29
|
+
# @param a [Numeric] int or float value
|
30
|
+
# @param b [Numeric] int or float value
|
31
|
+
# @param c [Numeric] int or float value
|
32
|
+
# @param d [Numeric] int or float value
|
33
|
+
# @param nums [Array] int or float array
|
34
|
+
# @param vec [Vector] vector
|
35
|
+
# @param ncoords [Integer] number of coordinates, max 4
|
36
|
+
# @param tex [Image] texture image
|
37
|
+
#
|
38
|
+
def setUniform(name, *args)
|
39
|
+
arg = args.first
|
40
|
+
case
|
41
|
+
when Array === arg
|
42
|
+
@shader.uniform name, *arg
|
43
|
+
when Numeric === arg
|
44
|
+
@shader.uniform name, *args
|
45
|
+
when Vector === arg
|
46
|
+
vec, ncoords = args
|
47
|
+
@shader.uniform name, vec.getInternal__.to_a(ncoords || 3)
|
48
|
+
when arg.respond_to?(:getInternal__)
|
49
|
+
@shader.uniform name, arg.getInternal__
|
50
|
+
else
|
51
|
+
raise ArgumentError
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
alias set setUniform
|
56
|
+
|
57
|
+
# @private
|
58
|
+
def getInternal__()
|
59
|
+
@shader
|
60
|
+
end
|
61
|
+
|
62
|
+
# @private
|
63
|
+
ENV__ = {
|
64
|
+
attribute_position: [:vertex, :position],
|
65
|
+
attribute_texcoord: :texCoord,
|
66
|
+
attribute_color: :color,
|
67
|
+
varying_position: :vertPosition,
|
68
|
+
varying_texcoord: :vertTexCoord,
|
69
|
+
varying_color: :vertColor,
|
70
|
+
uniform_position_matrix: [:transform, :transformMatrix],
|
71
|
+
uniform_texcoord_matrix: :texMatrix,
|
72
|
+
uniform_texcoord_min: :texMin,
|
73
|
+
uniform_texcoord_max: :texMax,
|
74
|
+
uniform_texcoord_offset: :texOffset,
|
75
|
+
uniform_texture: [:texMap, :texture]
|
76
|
+
}.freeze
|
77
|
+
|
78
|
+
# @private
|
79
|
+
def self.createFilter__(*args)
|
80
|
+
case arg = args.shift
|
81
|
+
when Shader
|
82
|
+
arg
|
83
|
+
when :threshold
|
84
|
+
self.new(nil, <<~END).tap {|sh| sh.set :threshold, (args.shift || 0.5)}
|
85
|
+
uniform float threshold;
|
86
|
+
uniform sampler2D texMap;
|
87
|
+
varying vec4 vertTexCoord;
|
88
|
+
varying vec4 vertColor;
|
89
|
+
void main() {
|
90
|
+
vec4 col = texture2D(texMap, vertTexCoord.xy) * vertColor;
|
91
|
+
float gray = col.r * 0.3 + col.g * 0.59 + col.b * 0.11;
|
92
|
+
gl_FragColor = vec4(vec3(gray > threshold ? 1.0 : 0.0), 1.0);
|
93
|
+
}
|
94
|
+
END
|
95
|
+
when :gray
|
96
|
+
self.new nil, <<~END
|
97
|
+
uniform sampler2D texMap;
|
98
|
+
varying vec4 vertTexCoord;
|
99
|
+
varying vec4 vertColor;
|
100
|
+
void main() {
|
101
|
+
vec4 col = texture2D(texMap, vertTexCoord.xy);
|
102
|
+
float gray = col.r * 0.3 + col.g * 0.59 + col.b * 0.11;
|
103
|
+
gl_FragColor = vec4(vec3(gray), 1.0) * vertColor;
|
104
|
+
}
|
105
|
+
END
|
106
|
+
when :invert
|
107
|
+
self.new nil, <<~END
|
108
|
+
uniform sampler2D texMap;
|
109
|
+
varying vec4 vertTexCoord;
|
110
|
+
varying vec4 vertColor;
|
111
|
+
void main() {
|
112
|
+
vec4 col = texture2D(texMap, vertTexCoord.xy);
|
113
|
+
gl_FragColor = vec4(vec3(1.0 - col.rgb), 1.0) * vertColor;
|
114
|
+
}
|
115
|
+
END
|
116
|
+
when :blur
|
117
|
+
self.new(nil, <<~END).tap {|sh| sh.set :radius, (args.shift || 1).to_f}
|
118
|
+
#define PI 3.1415926538
|
119
|
+
uniform float radius;
|
120
|
+
uniform sampler2D texMap;
|
121
|
+
uniform vec3 texMin;
|
122
|
+
uniform vec3 texMax;
|
123
|
+
uniform vec3 texOffset;
|
124
|
+
varying vec4 vertTexCoord;
|
125
|
+
varying vec4 vertColor;
|
126
|
+
float gaussian(vec2 pos, float sigma) {
|
127
|
+
float s2 = sigma * sigma;
|
128
|
+
return 1.0 / (2.0 * PI * s2) * exp(-(dot(pos, pos) / (2.0 * s2)));
|
129
|
+
}
|
130
|
+
void main() {
|
131
|
+
float sigma = radius * 0.5;
|
132
|
+
vec3 color = vec3(0.0);
|
133
|
+
float total_weight = 0.0;
|
134
|
+
for (float y = -radius; y < radius; y += 1.0)
|
135
|
+
for (float x = -radius; x < radius; x += 1.0) {
|
136
|
+
vec2 offset = vec2(x, y);
|
137
|
+
float weight = gaussian(offset, sigma);
|
138
|
+
vec2 texcoord = vertTexCoord.xy + offset * texOffset.xy;
|
139
|
+
if (
|
140
|
+
texcoord.x < texMin.x || texMax.x < texcoord.x ||
|
141
|
+
texcoord.y < texMin.y || texMax.y < texcoord.y
|
142
|
+
) continue;
|
143
|
+
color += texture2D(texMap, texcoord).rgb * weight;
|
144
|
+
total_weight += weight;
|
145
|
+
}
|
146
|
+
gl_FragColor = vec4(color / total_weight, 1.0) * vertColor;
|
147
|
+
}
|
148
|
+
END
|
149
|
+
else
|
150
|
+
nil
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
end# Shader
|
155
|
+
|
156
|
+
|
157
|
+
end# Processing
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Processing
|
2
|
+
|
3
|
+
|
4
|
+
# Touch object.
|
5
|
+
#
|
6
|
+
class Touch
|
7
|
+
|
8
|
+
# Identifier of each touch
|
9
|
+
#
|
10
|
+
attr_reader :id
|
11
|
+
|
12
|
+
# Horizontal position of touch
|
13
|
+
#
|
14
|
+
attr_reader :x
|
15
|
+
|
16
|
+
# Vertical position of touch
|
17
|
+
#
|
18
|
+
attr_reader :y
|
19
|
+
|
20
|
+
# @private
|
21
|
+
def initialize(id, x, y)
|
22
|
+
@id, @x, @y = id, x, y
|
23
|
+
end
|
24
|
+
|
25
|
+
end# Touch
|
26
|
+
|
27
|
+
|
28
|
+
end# Processing
|