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,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