ashton 0.0.1alpha → 0.0.2alpha

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.
Files changed (116) hide show
  1. data/LICENSE +21 -21
  2. data/README.md +95 -68
  3. data/Rakefile +41 -23
  4. data/examples/bloom_example.rb +59 -0
  5. data/examples/lighting_example.rb +127 -0
  6. data/examples/media/SmallStar.png +0 -0
  7. data/examples/media/Starfighter.png +0 -0
  8. data/examples/media/simple.png +0 -0
  9. data/examples/noise_example.rb +94 -0
  10. data/examples/outline_example.rb +86 -0
  11. data/examples/particle_emitter_example.rb +114 -0
  12. data/examples/pixelate_example.rb +51 -49
  13. data/examples/pixelated_texture_example.rb +69 -0
  14. data/examples/radial_blur_example.rb +60 -62
  15. data/examples/shader_image_example.rb +74 -41
  16. data/examples/{shockwave2_example.rb → shockwave_example.rb} +74 -75
  17. data/examples/stencil_shader_example.rb +104 -0
  18. data/examples/{framebuffer_example.rb → texture_render_example.rb} +53 -49
  19. data/examples/{tv_screen_and_noise_example.rb → tv_screen_and_static_example.rb} +59 -59
  20. data/ext/ashton/GLee.c +18170 -0
  21. data/ext/ashton/GLee.h +17647 -0
  22. data/ext/ashton/ashton.c +42 -0
  23. data/ext/ashton/ashton.h +31 -0
  24. data/ext/ashton/color.c +45 -0
  25. data/ext/ashton/color.h +25 -0
  26. data/ext/ashton/common.h +41 -0
  27. data/ext/ashton/extconf.rb +42 -0
  28. data/ext/ashton/fast_math.c +30 -0
  29. data/ext/ashton/fast_math.h +30 -0
  30. data/ext/ashton/font.c +8 -0
  31. data/ext/ashton/font.h +16 -0
  32. data/ext/ashton/gosu.c +18 -0
  33. data/ext/ashton/gosu.h +19 -0
  34. data/ext/ashton/image.c +8 -0
  35. data/ext/ashton/image.h +16 -0
  36. data/ext/ashton/particle_emitter.c +788 -0
  37. data/ext/ashton/particle_emitter.h +171 -0
  38. data/ext/ashton/pixel_cache.c +237 -0
  39. data/ext/ashton/pixel_cache.h +58 -0
  40. data/ext/ashton/shader.c +9 -0
  41. data/ext/ashton/shader.h +16 -0
  42. data/ext/ashton/texture.c +442 -0
  43. data/ext/ashton/texture.h +63 -0
  44. data/ext/ashton/window.c +8 -0
  45. data/ext/ashton/window.h +16 -0
  46. data/lib/ashton.rb +38 -26
  47. data/lib/ashton/1.9/ashton.so +0 -0
  48. data/lib/ashton/gosu_ext/color.rb +24 -11
  49. data/lib/ashton/gosu_ext/font.rb +58 -0
  50. data/lib/ashton/gosu_ext/gosu_module.rb +16 -0
  51. data/lib/ashton/gosu_ext/image.rb +95 -31
  52. data/lib/ashton/gosu_ext/window.rb +78 -35
  53. data/lib/ashton/image_stub.rb +32 -36
  54. data/lib/ashton/lighting/light_source.rb +146 -0
  55. data/lib/ashton/lighting/manager.rb +98 -0
  56. data/lib/ashton/mixins/version_checking.rb +23 -0
  57. data/lib/ashton/particle_emitter.rb +87 -0
  58. data/lib/ashton/pixel_cache.rb +24 -0
  59. data/lib/ashton/shader.rb +353 -35
  60. data/lib/ashton/shaders/bloom.frag +41 -0
  61. data/lib/ashton/shaders/color_inversion.frag +11 -0
  62. data/lib/ashton/{post_process → shaders}/contrast.frag +16 -16
  63. data/lib/ashton/{shader → shaders}/default.frag +22 -19
  64. data/lib/ashton/{shader → shaders}/default.vert +13 -13
  65. data/lib/ashton/shaders/fade.frag +14 -0
  66. data/lib/ashton/shaders/grayscale.frag +15 -0
  67. data/lib/ashton/shaders/include/classicnoise2d.glsl +113 -0
  68. data/lib/ashton/shaders/include/classicnoise3d.glsl +177 -0
  69. data/lib/ashton/shaders/include/classicnoise4d.glsl +302 -0
  70. data/lib/ashton/{include/simplex.glsl → shaders/include/noise2d.glsl} +70 -63
  71. data/lib/ashton/shaders/include/noise3d.glsl +102 -0
  72. data/lib/ashton/shaders/include/noise4d.glsl +128 -0
  73. data/lib/ashton/shaders/include/rand.glsl +5 -0
  74. data/lib/ashton/shaders/lighting/distort.frag +57 -0
  75. data/lib/ashton/shaders/lighting/draw_shadows.frag +60 -0
  76. data/lib/ashton/shaders/lighting/shadow_blur.frag +60 -0
  77. data/lib/ashton/shaders/mezzotint.frag +22 -0
  78. data/lib/ashton/shaders/multitexture2.vert +19 -0
  79. data/lib/ashton/shaders/outline.frag +45 -0
  80. data/lib/ashton/{post_process → shaders}/pixelate.frag +48 -48
  81. data/lib/ashton/shaders/radial_blur.frag +63 -0
  82. data/lib/ashton/shaders/sepia.frag +26 -0
  83. data/lib/ashton/{post_process/shockwave2.frag → shaders/shockwave.frag} +38 -35
  84. data/lib/ashton/shaders/signed_distance_field.frag +80 -0
  85. data/lib/ashton/{post_process/noise.frag → shaders/static.frag} +25 -27
  86. data/lib/ashton/shaders/stencil.frag +27 -0
  87. data/lib/ashton/shaders/tv_screen.frag +23 -0
  88. data/lib/ashton/signed_distance_field.rb +151 -0
  89. data/lib/ashton/texture.rb +186 -0
  90. data/lib/ashton/version.rb +2 -2
  91. data/lib/ashton/window_buffer.rb +16 -0
  92. data/spec/ashton/ashton_spec.rb +22 -0
  93. data/spec/ashton/gosu_ext/color_spec.rb +34 -0
  94. data/spec/ashton/gosu_ext/font_spec.rb +57 -0
  95. data/spec/ashton/gosu_ext/gosu_spec.rb +11 -0
  96. data/spec/ashton/gosu_ext/image_spec.rb +66 -0
  97. data/spec/ashton/gosu_ext/window_spec.rb +71 -0
  98. data/spec/ashton/image_stub_spec.rb +46 -0
  99. data/spec/ashton/particle_emitter_spec.rb +123 -0
  100. data/spec/ashton/pixel_cache_spec.rb +153 -0
  101. data/spec/ashton/shader_spec.rb +152 -0
  102. data/spec/ashton/signed_distance_field_spec.rb +163 -0
  103. data/spec/ashton/texture_spec.rb +347 -0
  104. data/spec/helper.rb +12 -0
  105. metadata +159 -28
  106. data/examples/output/README.txt +0 -1
  107. data/lib/ashton/base_shader.rb +0 -172
  108. data/lib/ashton/framebuffer.rb +0 -183
  109. data/lib/ashton/post_process.rb +0 -83
  110. data/lib/ashton/post_process/default.vert +0 -9
  111. data/lib/ashton/post_process/fade.frag +0 -11
  112. data/lib/ashton/post_process/mezzotint.frag +0 -24
  113. data/lib/ashton/post_process/radial_blur.frag +0 -31
  114. data/lib/ashton/post_process/sepia.frag +0 -19
  115. data/lib/ashton/post_process/shockwave.frag +0 -40
  116. 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