ashton 0.0.1alpha → 0.0.2alpha
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +21 -21
- data/README.md +95 -68
- data/Rakefile +41 -23
- data/examples/bloom_example.rb +59 -0
- data/examples/lighting_example.rb +127 -0
- data/examples/media/SmallStar.png +0 -0
- data/examples/media/Starfighter.png +0 -0
- data/examples/media/simple.png +0 -0
- data/examples/noise_example.rb +94 -0
- data/examples/outline_example.rb +86 -0
- data/examples/particle_emitter_example.rb +114 -0
- data/examples/pixelate_example.rb +51 -49
- data/examples/pixelated_texture_example.rb +69 -0
- data/examples/radial_blur_example.rb +60 -62
- data/examples/shader_image_example.rb +74 -41
- data/examples/{shockwave2_example.rb → shockwave_example.rb} +74 -75
- data/examples/stencil_shader_example.rb +104 -0
- data/examples/{framebuffer_example.rb → texture_render_example.rb} +53 -49
- data/examples/{tv_screen_and_noise_example.rb → tv_screen_and_static_example.rb} +59 -59
- data/ext/ashton/GLee.c +18170 -0
- data/ext/ashton/GLee.h +17647 -0
- data/ext/ashton/ashton.c +42 -0
- data/ext/ashton/ashton.h +31 -0
- data/ext/ashton/color.c +45 -0
- data/ext/ashton/color.h +25 -0
- data/ext/ashton/common.h +41 -0
- data/ext/ashton/extconf.rb +42 -0
- data/ext/ashton/fast_math.c +30 -0
- data/ext/ashton/fast_math.h +30 -0
- data/ext/ashton/font.c +8 -0
- data/ext/ashton/font.h +16 -0
- data/ext/ashton/gosu.c +18 -0
- data/ext/ashton/gosu.h +19 -0
- data/ext/ashton/image.c +8 -0
- data/ext/ashton/image.h +16 -0
- data/ext/ashton/particle_emitter.c +788 -0
- data/ext/ashton/particle_emitter.h +171 -0
- data/ext/ashton/pixel_cache.c +237 -0
- data/ext/ashton/pixel_cache.h +58 -0
- data/ext/ashton/shader.c +9 -0
- data/ext/ashton/shader.h +16 -0
- data/ext/ashton/texture.c +442 -0
- data/ext/ashton/texture.h +63 -0
- data/ext/ashton/window.c +8 -0
- data/ext/ashton/window.h +16 -0
- data/lib/ashton.rb +38 -26
- data/lib/ashton/1.9/ashton.so +0 -0
- data/lib/ashton/gosu_ext/color.rb +24 -11
- data/lib/ashton/gosu_ext/font.rb +58 -0
- data/lib/ashton/gosu_ext/gosu_module.rb +16 -0
- data/lib/ashton/gosu_ext/image.rb +95 -31
- data/lib/ashton/gosu_ext/window.rb +78 -35
- data/lib/ashton/image_stub.rb +32 -36
- data/lib/ashton/lighting/light_source.rb +146 -0
- data/lib/ashton/lighting/manager.rb +98 -0
- data/lib/ashton/mixins/version_checking.rb +23 -0
- data/lib/ashton/particle_emitter.rb +87 -0
- data/lib/ashton/pixel_cache.rb +24 -0
- data/lib/ashton/shader.rb +353 -35
- data/lib/ashton/shaders/bloom.frag +41 -0
- data/lib/ashton/shaders/color_inversion.frag +11 -0
- data/lib/ashton/{post_process → shaders}/contrast.frag +16 -16
- data/lib/ashton/{shader → shaders}/default.frag +22 -19
- data/lib/ashton/{shader → shaders}/default.vert +13 -13
- data/lib/ashton/shaders/fade.frag +14 -0
- data/lib/ashton/shaders/grayscale.frag +15 -0
- data/lib/ashton/shaders/include/classicnoise2d.glsl +113 -0
- data/lib/ashton/shaders/include/classicnoise3d.glsl +177 -0
- data/lib/ashton/shaders/include/classicnoise4d.glsl +302 -0
- data/lib/ashton/{include/simplex.glsl → shaders/include/noise2d.glsl} +70 -63
- data/lib/ashton/shaders/include/noise3d.glsl +102 -0
- data/lib/ashton/shaders/include/noise4d.glsl +128 -0
- data/lib/ashton/shaders/include/rand.glsl +5 -0
- data/lib/ashton/shaders/lighting/distort.frag +57 -0
- data/lib/ashton/shaders/lighting/draw_shadows.frag +60 -0
- data/lib/ashton/shaders/lighting/shadow_blur.frag +60 -0
- data/lib/ashton/shaders/mezzotint.frag +22 -0
- data/lib/ashton/shaders/multitexture2.vert +19 -0
- data/lib/ashton/shaders/outline.frag +45 -0
- data/lib/ashton/{post_process → shaders}/pixelate.frag +48 -48
- data/lib/ashton/shaders/radial_blur.frag +63 -0
- data/lib/ashton/shaders/sepia.frag +26 -0
- data/lib/ashton/{post_process/shockwave2.frag → shaders/shockwave.frag} +38 -35
- data/lib/ashton/shaders/signed_distance_field.frag +80 -0
- data/lib/ashton/{post_process/noise.frag → shaders/static.frag} +25 -27
- data/lib/ashton/shaders/stencil.frag +27 -0
- data/lib/ashton/shaders/tv_screen.frag +23 -0
- data/lib/ashton/signed_distance_field.rb +151 -0
- data/lib/ashton/texture.rb +186 -0
- data/lib/ashton/version.rb +2 -2
- data/lib/ashton/window_buffer.rb +16 -0
- data/spec/ashton/ashton_spec.rb +22 -0
- data/spec/ashton/gosu_ext/color_spec.rb +34 -0
- data/spec/ashton/gosu_ext/font_spec.rb +57 -0
- data/spec/ashton/gosu_ext/gosu_spec.rb +11 -0
- data/spec/ashton/gosu_ext/image_spec.rb +66 -0
- data/spec/ashton/gosu_ext/window_spec.rb +71 -0
- data/spec/ashton/image_stub_spec.rb +46 -0
- data/spec/ashton/particle_emitter_spec.rb +123 -0
- data/spec/ashton/pixel_cache_spec.rb +153 -0
- data/spec/ashton/shader_spec.rb +152 -0
- data/spec/ashton/signed_distance_field_spec.rb +163 -0
- data/spec/ashton/texture_spec.rb +347 -0
- data/spec/helper.rb +12 -0
- metadata +159 -28
- data/examples/output/README.txt +0 -1
- data/lib/ashton/base_shader.rb +0 -172
- data/lib/ashton/framebuffer.rb +0 -183
- data/lib/ashton/post_process.rb +0 -83
- data/lib/ashton/post_process/default.vert +0 -9
- data/lib/ashton/post_process/fade.frag +0 -11
- data/lib/ashton/post_process/mezzotint.frag +0 -24
- data/lib/ashton/post_process/radial_blur.frag +0 -31
- data/lib/ashton/post_process/sepia.frag +0 -19
- data/lib/ashton/post_process/shockwave.frag +0 -40
- data/lib/ashton/post_process/tv_screen.frag +0 -32
@@ -0,0 +1,153 @@
|
|
1
|
+
require_relative "../helper.rb"
|
2
|
+
|
3
|
+
describe Ashton::PixelCache do
|
4
|
+
before :all do
|
5
|
+
$window ||= Gosu::Window.new 16, 16, false
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:testcard_image) { @testcard_image ||= Gosu::Image.new $window, media_path("simple.png") }
|
9
|
+
let(:texture) { Ashton::Texture.new testcard_image }
|
10
|
+
let(:subject) { described_class.new texture }
|
11
|
+
|
12
|
+
describe "owner" do
|
13
|
+
it "should remember the owner it was created for" do
|
14
|
+
subject.owner.should eq texture
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "refresh" do
|
19
|
+
it "should respond to refresh" do
|
20
|
+
subject.should respond_to :refresh
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "initialize" do
|
25
|
+
it "should cache for a texture class" do
|
26
|
+
->{ described_class.new texture }.should_not raise_error TypeError
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should cache for an image class" do
|
30
|
+
pending "it not freezing :/"
|
31
|
+
->{ described_class.new testcard_image }.should_not raise_error TypeError
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should fail passed an unexpected class" do
|
35
|
+
->{ described_class.new "frog" }.should raise_error TypeError
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "[]" do
|
40
|
+
it "should return the color of the pixel" do
|
41
|
+
subject[0, 0].should eq Gosu::Color::WHITE
|
42
|
+
subject[0, 1].should eq Gosu::Color::RED
|
43
|
+
subject[0, 2].should eq Gosu::Color::GREEN
|
44
|
+
subject[0, 3].should eq Gosu::Color::BLUE
|
45
|
+
subject[0, 4].should eq Gosu::Color.rgba(255, 255, 255, 153)
|
46
|
+
subject[0, 8].should eq Gosu::Color.rgba(0, 0, 0, 0)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should return a null colour outside the texture" do
|
50
|
+
subject[0, -1].should eq Gosu::Color.new 0
|
51
|
+
subject[-1, 0].should eq Gosu::Color.new 0
|
52
|
+
subject[16, 0].should eq Gosu::Color.new 0
|
53
|
+
subject[0, 12].should eq Gosu::Color.new 0
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "rgba" do
|
58
|
+
it "should return the appropriate array of values" do
|
59
|
+
subject.rgba(0, 0).should eq [255, 255, 255, 255]
|
60
|
+
subject.rgba(0, 1).should eq [255, 0, 0, 255]
|
61
|
+
subject.rgba(0, 2).should eq [0, 255, 0, 255]
|
62
|
+
subject.rgba(0, 3).should eq [0, 0, 255, 255]
|
63
|
+
subject.rgba(0, 4).should eq [255, 255, 255, 153]
|
64
|
+
subject.rgba(0, 8).should eq [0, 0, 0, 0]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "red" do
|
69
|
+
it "should return the appropriate value" do
|
70
|
+
subject.red(0, 0).should eq 255
|
71
|
+
subject.red(0, 1).should eq 255
|
72
|
+
subject.red(0, 2).should eq 0
|
73
|
+
subject.red(0, 3).should eq 0
|
74
|
+
subject.red(0, 8).should eq 0
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "green" do
|
79
|
+
it "should return the appropriate value" do
|
80
|
+
subject.green(0, 0).should eq 255
|
81
|
+
subject.green(0, 1).should eq 0
|
82
|
+
subject.green(0, 2).should eq 255
|
83
|
+
subject.green(0, 3).should eq 0
|
84
|
+
subject.green(0, 8).should eq 0
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "blue" do
|
89
|
+
it "should return the appropriate value" do
|
90
|
+
subject.blue(0, 0).should eq 255
|
91
|
+
subject.blue(0, 1).should eq 0
|
92
|
+
subject.blue(0, 2).should eq 0
|
93
|
+
subject.blue(0, 3).should eq 255
|
94
|
+
subject.blue(0, 8).should eq 0
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "alpha" do
|
99
|
+
it "should return the appropriate value" do
|
100
|
+
subject.alpha(0, 0).should eq 255
|
101
|
+
subject.alpha(0, 1).should eq 255
|
102
|
+
subject.alpha(0, 2).should eq 255
|
103
|
+
subject.alpha(0, 3).should eq 255
|
104
|
+
subject.alpha(0, 8).should eq 0
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "transparent?" do
|
109
|
+
it "should be false where the buffer is opaque or semi-transparent" do
|
110
|
+
subject.transparent?(0, 1).should eq false
|
111
|
+
subject.transparent?(0, 5).should eq false
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should be true where the buffer is transparent" do
|
115
|
+
subject.transparent?(0, 8).should eq true
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe "width" do
|
120
|
+
it "should be initially set" do
|
121
|
+
subject.width.should eq testcard_image.width
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe "height" do
|
126
|
+
it "should be initially set" do
|
127
|
+
subject.height.should eq testcard_image.height
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "to_blob" do
|
132
|
+
it "should create a blob identical to one an equivalent image would create" do
|
133
|
+
subject.to_blob.should eq testcard_image.to_blob
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "to_image" do
|
138
|
+
let(:image) { subject.to_image }
|
139
|
+
|
140
|
+
it "should create a Gosu::Image" do
|
141
|
+
image.should be_kind_of Gosu::Image
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should create an image of the appropriate size" do
|
145
|
+
image.width.should eq testcard_image.width
|
146
|
+
image.height.should eq testcard_image.height
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should create an image identical to the one that was drawn into it originally" do
|
150
|
+
image.to_blob.should eq testcard_image.to_blob
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
require_relative "../helper.rb"
|
2
|
+
|
3
|
+
describe Ashton::Shader do
|
4
|
+
before :all do
|
5
|
+
$window = Gosu::Window.new 16, 16, false
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:subject) { described_class.new}
|
9
|
+
let(:program) { subject.instance_variable_get :@program }
|
10
|
+
|
11
|
+
after :each do
|
12
|
+
glUseProgram 0
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "initialize" do
|
16
|
+
it "should fail if the built-in fragment shader doesn't exist" do
|
17
|
+
->{ described_class.new fragment: :fish }.should raise_error Ashton::ShaderLoadError
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should fail if the built-in vertex shader doesn't exist" do
|
21
|
+
->{ described_class.new vertex: :fish }.should raise_error Ashton::ShaderLoadError
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should fail if the file-based fragment shader doesn't exist or is bad source" do
|
25
|
+
->{ described_class.new fragment: "/fish.frag" }.should raise_error Ashton::ShaderCompileError
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should fail if the file-based fragment shader doesn't exist or is bad source" do
|
29
|
+
->{ described_class.new vertex: "/fish.vert" }.should raise_error Ashton::ShaderCompileError
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should set uniform values from the options hash" do
|
33
|
+
any_instance_of described_class do |shader|
|
34
|
+
mock(shader, :[]=).with :frog, 12
|
35
|
+
mock(shader, :[]=).with :fish_paste, 15.0
|
36
|
+
end
|
37
|
+
|
38
|
+
described_class.new uniforms: { frog: 12, fish_paste: 15.0 }
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should fail if requested to set nonexistent uniform values in the options hash" do
|
42
|
+
->{ described_class.new uniforms: { frog: 12 }} .should raise_error Ashton::ShaderUniformError
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "dup" do
|
47
|
+
it "should create a new object containing the same source" do
|
48
|
+
new_shader = subject.dup
|
49
|
+
new_shader.vertex_source.should eq subject.vertex_source
|
50
|
+
new_shader.fragment_source.should eq subject.fragment_source
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "enable" do
|
55
|
+
context "with a block" do
|
56
|
+
it "should fail if the shader is already active" do
|
57
|
+
glUseProgram program
|
58
|
+
|
59
|
+
->{ subject.enable {} }.should raise_error Ashton::ShaderError
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should pass itself into the block" do
|
63
|
+
shader = nil
|
64
|
+
subject.enable do |s|
|
65
|
+
shader = s
|
66
|
+
end
|
67
|
+
|
68
|
+
shader.should eq subject
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should be current within the block?" do
|
72
|
+
subject.enable do
|
73
|
+
subject.should be_current
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should be not current after the block" do
|
78
|
+
subject.enable do
|
79
|
+
end
|
80
|
+
|
81
|
+
subject.should_not be_current
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "without a block" do
|
86
|
+
it "should fail if the shader is already active" do
|
87
|
+
glUseProgram program
|
88
|
+
|
89
|
+
->{ subject.enable }.should raise_error Ashton::ShaderError
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should toggle current?" do
|
93
|
+
->{ subject.enable }.should change(subject, :current?).from(false).to true
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "disable" do
|
99
|
+
it "should fail if the shader is not active" do
|
100
|
+
-> { subject.disable }.should raise_error Ashton::ShaderError
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should toggle current?" do
|
104
|
+
subject.enable
|
105
|
+
->{ subject.disable }.should change(subject, :current?).from(true).to false
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "current?" do
|
110
|
+
it "should be true if the program is current" do
|
111
|
+
glUseProgram program
|
112
|
+
subject.should be_current
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should be false if the program isn't current" do
|
116
|
+
glUseProgram 0
|
117
|
+
subject.should_not be_current
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe "image=" do
|
122
|
+
pending
|
123
|
+
end
|
124
|
+
|
125
|
+
describe "color=" do
|
126
|
+
pending
|
127
|
+
end
|
128
|
+
|
129
|
+
describe "[]=" do
|
130
|
+
pending
|
131
|
+
end
|
132
|
+
|
133
|
+
describe "[]" do
|
134
|
+
pending "implementation"
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "uniform_location" do
|
138
|
+
pending
|
139
|
+
end
|
140
|
+
|
141
|
+
describe "attribute_location" do
|
142
|
+
pending
|
143
|
+
end
|
144
|
+
|
145
|
+
describe "compile" do
|
146
|
+
pending
|
147
|
+
end
|
148
|
+
|
149
|
+
describe "link" do
|
150
|
+
pending
|
151
|
+
end
|
152
|
+
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
require_relative "../helper.rb"
|
2
|
+
|
3
|
+
|
4
|
+
describe Ashton::SignedDistanceField do
|
5
|
+
before :all do
|
6
|
+
Gosu::enable_undocumented_retrofication
|
7
|
+
|
8
|
+
$window ||= Gosu::Window.new 16, 16, false
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:max_distance) { 3 }
|
12
|
+
let(:width) { 9 }
|
13
|
+
let(:height) { 10 }
|
14
|
+
|
15
|
+
let(:subject) do
|
16
|
+
described_class.new width, height, max_distance do
|
17
|
+
# ---------
|
18
|
+
# -XXX-----
|
19
|
+
# -XXXX----
|
20
|
+
# -XXXX----
|
21
|
+
# ---------
|
22
|
+
# ---------
|
23
|
+
# ---------
|
24
|
+
# ---------
|
25
|
+
# ---------
|
26
|
+
# ---------
|
27
|
+
$window.pixel.draw 1, 1, 0, 3, 3
|
28
|
+
$window.pixel.draw 4, 2, 0, 1, 2
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "initialize" do
|
33
|
+
it "should accept a block and yield itself" do
|
34
|
+
yielded = nil
|
35
|
+
field = described_class.new width, height, max_distance do |value|
|
36
|
+
yielded = value
|
37
|
+
end
|
38
|
+
|
39
|
+
yielded.should eq field
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should initialize itself to max_distance if not given a block" do
|
43
|
+
field = described_class.new width, height, max_distance
|
44
|
+
field.to_a.flatten.uniq.should eq [max_distance]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "width" do
|
49
|
+
it "should give the width" do
|
50
|
+
subject.width.should eq width
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "height" do
|
55
|
+
it "should give the height" do
|
56
|
+
subject.height.should eq height
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "position_clear?" do
|
61
|
+
it "should be true if there is room" do
|
62
|
+
subject.position_clear?(8, 4, 2).should be_true
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should be false if there is no room" do
|
66
|
+
subject.position_clear?(8, 4, 4).should be_false
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should be false inside a solid" do
|
70
|
+
subject.position_clear?(2, 2, 1).should be_false
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "sample_distance" do
|
75
|
+
it "should give the appropriate distance" do
|
76
|
+
subject.sample_distance(1, 0).should eq 1
|
77
|
+
subject.sample_distance(7, 4).should eq 3
|
78
|
+
subject.sample_distance(1, 1).should eq 0
|
79
|
+
subject.sample_distance(2, 2).should eq -1
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should max out at the specified limit" do
|
83
|
+
subject.sample_distance(8, 9).should eq max_distance
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "line_of_sight?" do
|
88
|
+
it "should be false if the sight line is blocked" do
|
89
|
+
subject.line_of_sight?(2, 0, 2, 9).should be_false
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should be true if the sight line is uninterrupted" do
|
93
|
+
subject.line_of_sight?(0, 0, 0, 9).should be_true
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "line_of_sight_blocked_at" do
|
98
|
+
it "should be false if the sight line is blocked" do
|
99
|
+
subject.line_of_sight_blocked_at(2, 0, 2, 9).should eq [2, 1]
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should be nil if the sight line is uninterrupted" do
|
103
|
+
subject.line_of_sight_blocked_at(0, 0, 0, 9).should be_nil
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "sample_gradient" do
|
108
|
+
it "should give expected values" do
|
109
|
+
subject.sample_gradient(1, 0).should eq [0, -1]
|
110
|
+
subject.sample_gradient(0, 1).should eq [-1, 0]
|
111
|
+
|
112
|
+
subject.sample_gradient(5, 3).should eq [2, 0]
|
113
|
+
subject.sample_gradient(1, 4).should eq [0, 2]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "sample_normal" do
|
118
|
+
it "should give expected values" do
|
119
|
+
subject.sample_normal(1, 0).should eq [0.0, -1.0]
|
120
|
+
subject.sample_normal(0, 1).should eq [-1.0, 0.0]
|
121
|
+
|
122
|
+
subject.sample_normal(5, 3).should eq [1.0, 0.0]
|
123
|
+
subject.sample_normal(1, 4).should eq [0.0, 1.0]
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "render_field" do
|
128
|
+
it "should yield the field" do
|
129
|
+
field = nil
|
130
|
+
subject.render_field do |value|
|
131
|
+
field = value
|
132
|
+
end
|
133
|
+
field.should eq subject
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should fail without a block" do
|
137
|
+
->{ subject.render_field }.should raise_error ArgumentError
|
138
|
+
end
|
139
|
+
|
140
|
+
pending
|
141
|
+
end
|
142
|
+
|
143
|
+
describe "draw" do
|
144
|
+
pending
|
145
|
+
end
|
146
|
+
|
147
|
+
describe "to_a" do
|
148
|
+
it "should generate the expected array" do
|
149
|
+
# Remember this is rotated so array[x][y] works.
|
150
|
+
subject.to_a.should eq [
|
151
|
+
[1, 1, 1, 1, 1, 2, 3, 3, 3, 3],
|
152
|
+
[1, 0, 0, 0, 1, 2, 3, 3, 3, 3],
|
153
|
+
[1, 0, -1, 0, 1, 2, 3, 3, 3, 3],
|
154
|
+
[1, 0, 0, 0, 1, 2, 3, 3, 3, 3],
|
155
|
+
[1, 1, 0, 0, 1, 2, 3, 3, 3, 3],
|
156
|
+
[2, 1, 1, 1, 1, 2, 3, 3, 3, 3],
|
157
|
+
[3, 2, 2, 2, 2, 3, 3, 3, 3, 3],
|
158
|
+
[3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
|
159
|
+
[3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
|
160
|
+
]
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|