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,16 @@
1
+ module Ashton
2
+ # A texture that is the same size as the Gosu::Window.
3
+ class WindowBuffer < Texture
4
+ def initialize
5
+ super $window.width, $window.height
6
+ end
7
+
8
+ public
9
+ # Copy the window contents into the buffer.
10
+ def capture
11
+ glBindTexture GL_TEXTURE_2D, id
12
+ glCopyTexImage2D GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, width, height, 0
13
+ self
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,22 @@
1
+
2
+ require_relative "../helper.rb"
3
+
4
+ describe Ashton do
5
+ let(:accuracy) { 0.000001 }
6
+
7
+ describe "fast_sin" do
8
+ it "should give the same result as Math.sin" do
9
+ (-360..360).step 90 do |angle|
10
+ Ashton.fast_sin(angle).should be_within(accuracy).of Math.sin(angle.gosu_to_radians)
11
+ end
12
+ end
13
+ end
14
+
15
+ describe "fast_cos" do
16
+ it "should give the same result as Math.cos" do
17
+ (-360..360).step 90 do |angle|
18
+ Ashton.fast_cos(angle).should be_within(accuracy).of Math.cos(angle.gosu_to_radians)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,34 @@
1
+ require_relative "../../helper.rb"
2
+
3
+ describe Gosu::Color do
4
+ let :conversions do
5
+ [
6
+ [Gosu::Color::RED, [1.0, 0.0, 0.0, 1.0]],
7
+ [Gosu::Color::GREEN, [0.0, 1.0, 0.0, 1.0]],
8
+ [Gosu::Color::BLUE, [0.0, 0.0, 1.0, 1.0]],
9
+ [Gosu::Color.rgba(25, 50, 75, 125), [0.09803921568627451, 0.19607843137254902, 0.29411764705882354, 0.49019607843137253]],
10
+ ]
11
+ end
12
+
13
+ describe "to_opengl" do
14
+ it "should convert from Color to float array" do
15
+ conversions.each do |gosu, opengl|
16
+ gosu.to_opengl.should eq opengl
17
+ end
18
+ end
19
+ end
20
+
21
+ describe ".from_opengl" do
22
+ it "should create the expected Colors from a float array" do
23
+ conversions.each do |gosu, opengl|
24
+ Gosu::Color.from_opengl(opengl).should eq gosu
25
+ end
26
+ end
27
+ end
28
+
29
+ describe "to_i" do
30
+ it "should convert to an ARGB8 value" do
31
+ Gosu::Color.new(0x01234567).to_i.should eq 0x01234567
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,57 @@
1
+ require_relative "../../helper.rb"
2
+
3
+ describe Gosu::Font do
4
+ before :each do
5
+ $window = Gosu::Window.new 16, 16, false
6
+ end
7
+ let(:subject) { described_class.new $window, Gosu::default_font_name, 20 }
8
+ let(:shader) { Ashton::Shader.new }
9
+
10
+ describe "draw" do
11
+ it "should pass parameters through normally, without a hash" do
12
+ mock(subject).draw_without_hash "bleh", 1, 2, 3, 4, 5, 6, 7
13
+
14
+ subject.draw "bleh", 1, 2, 3, 4, 5, 6, 7
15
+ end
16
+
17
+ it "should pass parameters through normally, without :shader in the hash" do
18
+ mock(subject).draw_without_hash "bleh", 1, 2, 3, 4, 5, 6, 7
19
+
20
+ subject.draw "bleh", 1, 2, 3, 4, 5, 6, 7, shader: shader
21
+ end
22
+
23
+ it "should use the shader if supplied" do
24
+ mock(shader) do |m|
25
+ m.enable 3
26
+ m.disable 3
27
+ end
28
+ mock(subject).draw_without_hash "bleh", 1, 2, 3, 4, 5, 6, 7
29
+
30
+ subject.draw "bleh", 1, 2, 3, 4, 5, 6, 7, shader: shader
31
+ end
32
+ end
33
+
34
+ describe "draw_rel" do
35
+ it "should pass parameters through normally, without a hash" do
36
+ mock(subject).draw_rel_without_hash "bleh", 1, 2, 3, 4, 5, 6, 7, 8, 9
37
+
38
+ subject.draw_rel "bleh", 1, 2, 3, 4, 5, 6, 7, 8, 9
39
+ end
40
+
41
+ it "should pass parameters through normally, without :shader in the hash" do
42
+ mock(subject).draw_rel_without_hash "bleh", 1, 2, 3, 4, 5, 6, 7, 8, 9
43
+
44
+ subject.draw_rel "bleh", 1, 2, 3, 4, 5, 6, 7, 8, 9, shader: shader
45
+ end
46
+
47
+ it "should use the shader if supplied" do
48
+ mock(shader) do |m|
49
+ m.enable 3
50
+ m.disable 3
51
+ end
52
+ mock(subject).draw_rel_without_hash "bleh", 1, 2, 3, 4, 5, 6, 7, 8, 9
53
+
54
+ subject.draw_rel "bleh", 1, 2, 3, 4, 5, 6, 7, 8, 9, shader: shader
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,11 @@
1
+ require_relative "../../helper.rb"
2
+
3
+ describe Gosu do
4
+ describe "enable_undocumented_retrofication" do
5
+ it "should set Texture.pixelated? true" do
6
+ Ashton::Texture.should_not be_pixelated
7
+ Gosu.enable_undocumented_retrofication
8
+ Ashton::Texture.should be_pixelated
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,66 @@
1
+ require_relative "../../helper.rb"
2
+
3
+ describe Gosu::Image do
4
+ before :each do
5
+ $window = Gosu::Window.new 16, 16, false
6
+ end
7
+
8
+ let(:subject) { described_class.new $window, media_path("LargeStar.png") }
9
+
10
+ describe "draw" do
11
+ it "should pass parameters through normally, without a hash" do
12
+ mock(subject).draw_without_hash 0, 1, 2, 3, 4, 5
13
+
14
+ subject.draw 0, 1, 2, 3, 4, 5
15
+ end
16
+
17
+ it "should pass parameters through normally, without :shader in the hash" do
18
+ mock(subject).draw_without_hash 0, 1, 2, 3, 4, 5
19
+
20
+ subject.draw 0, 1, 2, 3, 4, 5, {}
21
+ end
22
+
23
+ it "should use the shader if supplied" do
24
+ mock(shader = Ashton::Shader.new) do |m|
25
+ m.enable 2
26
+ m.image = subject
27
+ m.disable 2
28
+ end
29
+ mock(subject).draw_without_hash 0, 1, 2, 3, 4, 5
30
+
31
+ subject.draw 0, 1, 2, 3, 4, 5, :shader => shader
32
+ end
33
+ end
34
+
35
+ describe "draw_rot" do
36
+ it "should pass parameters through normally, without a hash" do
37
+ mock(subject).draw_rot_without_hash 0, 1, 2, 3, 4, 5, 6, 7, 8
38
+
39
+ subject.draw_rot 0, 1, 2, 3, 4, 5, 6, 7, 8
40
+ end
41
+
42
+ it "should pass parameters through normally, without :shader in the hash" do
43
+ mock(subject).draw_rot_without_hash 0, 1, 2, 3, 4, 5, 6, 7, 8
44
+
45
+ subject.draw_rot 0, 1, 2, 3, 4, 5, 6, 7, 8, {}
46
+ end
47
+
48
+ it "should use the shader if supplied" do
49
+ mock(shader = Ashton::Shader.new) do |m|
50
+ m.enable 2
51
+ m.image = subject
52
+ m.disable 2
53
+ end
54
+ mock(subject).draw_rot_without_hash 0, 1, 2, 3, 4, 5, 6, 7, 8
55
+
56
+ subject.draw_rot 0, 1, 2, 3, 4, 5, 6, 7, 8, :shader => shader
57
+ end
58
+ end
59
+
60
+ describe "to_texture" do
61
+ it "should create a texture identical to the image" do
62
+ texture = subject.to_texture
63
+ texture.to_blob.should eq subject.to_blob
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,71 @@
1
+ require_relative "../../helper.rb"
2
+
3
+ describe Gosu::Window do
4
+ before :all do
5
+ $window ||= Gosu::Window.new 16, 16, false
6
+ end
7
+
8
+ # Class methods.
9
+
10
+ describe "Window.pixel" do
11
+ it "should be a 1x1 image" do
12
+ described_class.pixel.should be_kind_of Gosu::Image
13
+ described_class.pixel.width.should eq 1
14
+ described_class.pixel.height.should eq 1
15
+ end
16
+
17
+ it "should be white" do
18
+ described_class.pixel[0, 0].should eq [1.0, 1.0, 1.0, 1.0]
19
+ end
20
+ end
21
+
22
+ describe "Window.primary_buffer" do
23
+ it "should be a window sized buffer" do
24
+ described_class.primary_buffer.should be_kind_of Ashton::WindowBuffer
25
+ end
26
+ end
27
+
28
+ describe "Window.secondary_buffer" do
29
+ it "should be a window sized buffer" do
30
+ described_class.secondary_buffer.should be_kind_of Ashton::WindowBuffer
31
+ end
32
+
33
+ it "should not be the same as the primary buffer" do
34
+ described_class.secondary_buffer.should_not eq described_class.primary_buffer
35
+ end
36
+ end
37
+
38
+ # Instance methods
39
+
40
+ describe "post_process" do
41
+ pending
42
+ end
43
+
44
+ describe "pixel" do
45
+ it "should be a 1x1 image" do
46
+ $window.pixel.should be_kind_of Gosu::Image
47
+ $window.pixel.width.should eq 1
48
+ $window.pixel.height.should eq 1
49
+ end
50
+
51
+ it "should be white" do
52
+ $window.pixel[0, 0].should eq [1.0, 1.0, 1.0, 1.0]
53
+ end
54
+ end
55
+
56
+ describe "primary_buffer" do
57
+ it "should be a window sized buffer" do
58
+ $window.primary_buffer.should be_kind_of Ashton::WindowBuffer
59
+ end
60
+ end
61
+
62
+ describe "secondary_buffer" do
63
+ it "should be a window sized buffer" do
64
+ $window.secondary_buffer.should be_kind_of Ashton::WindowBuffer
65
+ end
66
+
67
+ it "should not be the same as the primary buffer" do
68
+ $window.secondary_buffer.should_not eq $window.primary_buffer
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,46 @@
1
+ require_relative "../helper.rb"
2
+
3
+ describe Ashton::ImageStub do
4
+ describe "#initialize" do
5
+ it "should fail if the blob data is not the expected size" do
6
+ lambda do
7
+ described_class.new "\0\0\0", 2, 3
8
+ end.should raise_error ArgumentError, /Expected blob to be 24 bytes/
9
+ end
10
+
11
+ it "should fail width <= 0" do
12
+ lambda do
13
+ described_class.new "\0\0\0\0", 0, 2
14
+ end.should raise_error ArgumentError, /Width must be >= 1 pixel/
15
+ end
16
+
17
+ it "should fail height <= 0" do
18
+ lambda do
19
+ described_class.new "\0\0\0\0", 2, 0
20
+ end.should raise_error ArgumentError, /Height must be >= 1 pixel/
21
+ end
22
+ end
23
+
24
+ context "instantiated" do
25
+ let(:two_by_three_blob) { 24.times.to_a.pack("C*") }
26
+ let(:subject) { described_class.new two_by_three_blob, 2, 3 }
27
+
28
+ describe "#to_blob" do
29
+ it "should return the blob given" do
30
+ subject.to_blob.should eq two_by_three_blob
31
+ end
32
+ end
33
+
34
+ describe "#columns" do
35
+ it "should equal the width of the blob" do
36
+ subject.columns.should eq 2
37
+ end
38
+ end
39
+
40
+ describe "#rows" do
41
+ it "should equal the height of the blob" do
42
+ subject.rows.should eq 3
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,123 @@
1
+ require_relative "../helper.rb"
2
+
3
+ # Values and their defaults. The deviations default to 0.
4
+ FLOATS_WITH_RANGE = {
5
+ angular_velocity: 0.0..0.0,
6
+ center_x: 0.5..0.5,
7
+ center_y: 0.5..0.5,
8
+ fade: 0.0..0.0,
9
+ friction: 0.0..0.0,
10
+ interval: Float::INFINITY..Float::INFINITY,
11
+ scale: 1.0..1.0,
12
+ speed: 0.0..0.0,
13
+ time_to_live: Float::INFINITY..Float::INFINITY,
14
+ zoom: 0.0..0.0,
15
+ }
16
+
17
+ describe Ashton::ParticleEmitter do
18
+ before :all do
19
+ $window ||= Gosu::Window.new 16, 16, false
20
+ # Need not to create a large number of these.
21
+ @emitter = described_class.new 1, 2, 3
22
+ end
23
+
24
+ let(:default_max) { 1000 }
25
+ let(:subject) { @emitter }
26
+
27
+ describe "initialize" do
28
+ [:x, :y, :z].each.with_index(1) do |attr, value|
29
+ it "should set #{attr}" do
30
+ subject.send(attr).should be_kind_of Float
31
+ subject.send(attr).should eq value
32
+ end
33
+ end
34
+
35
+ FLOATS_WITH_RANGE.each_pair do |attr, expected|
36
+ it "should set #{attr}" do
37
+ subject.send(attr).should be_kind_of Range
38
+ subject.send(attr).should eq expected
39
+ end
40
+ end
41
+
42
+ it "should be set max_particles" do
43
+ subject.max_particles.should be_kind_of Fixnum
44
+ subject.max_particles.should eq default_max
45
+ end
46
+
47
+ it "should not have any particles" do
48
+ subject.count.should eq 0
49
+ end
50
+
51
+ it "should have color set to white" do
52
+ subject.color.should eq Gosu::Color::WHITE
53
+ end
54
+ end
55
+
56
+ [:x, :y, :z].each.with_index(1) do |attr, value|
57
+ describe "#{attr}=" do
58
+ it "should set the value of #{attr}" do
59
+ ->{ subject.send "#{attr}=", value + 5.0 }.should change(subject, attr).from(value).to(value + 5)
60
+ end
61
+ end
62
+ end
63
+
64
+ FLOATS_WITH_RANGE.keys.each do |attr|
65
+ describe "#{attr}=" do
66
+ it "should set #{attr} with a number" do
67
+ subject.send("#{attr}=", 42.0).should eq 42.0
68
+ subject.send("#{attr}").should eq 42.0..42.0
69
+ end
70
+
71
+ it "should set #{attr} with a range" do
72
+ subject.send("#{attr}=", 42.0..99.0).should eq 42.0..99.0
73
+ subject.send("#{attr}").should eq 42.0..99.0
74
+ end
75
+ end
76
+ end
77
+
78
+ describe "color=" do
79
+ it "should set color" do
80
+ (subject.color = Gosu::Color::BLACK).should eq Gosu::Color::BLACK
81
+ subject.color.should eq Gosu::Color::BLACK
82
+ end
83
+ end
84
+
85
+ describe "draw" do
86
+ it "should respond to #draw" do
87
+ subject.draw
88
+ end
89
+ end
90
+
91
+ describe "emit" do
92
+ it "should create one more particle" do
93
+ ->{ subject.emit }.should change(subject, :count).from(0).to(1)
94
+ end
95
+
96
+ it "should replace a particle if we are already at max particles" do
97
+ (default_max + 1).times { subject.emit }
98
+ subject.count.should eq default_max
99
+ end
100
+ end
101
+
102
+ describe "update" do
103
+ it "should an appropriate number of particles" do
104
+ subject = described_class.new 1, 2, 3, interval: 0.001
105
+ mock(subject).emit.times 16
106
+ subject.update 1.0 / 60.0 # 16.66667 ms
107
+ end
108
+
109
+ it "should not emit a particle if delta is less than interval" do
110
+ subject = described_class.new 1, 2, 3, interval: 0.020
111
+ dont_allow(subject).emit
112
+ subject.update 1.0 / 60.0 # 16.66667 ms
113
+ end
114
+
115
+ it "should fail given a negative delta" do
116
+ ->{ subject.update -1 }.should raise_error ArgumentError, "delta must be >= 0"
117
+ end
118
+
119
+ it "should fail for a bad delta type" do
120
+ ->{ subject.update "fred" }.should raise_error TypeError
121
+ end
122
+ end
123
+ end