ashton 0.0.1alpha → 0.0.2alpha

Sign up to get free protection for your applications and to get access to all the features.
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