ray 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (167) hide show
  1. data/README.md +9 -6
  2. data/Rakefile +1 -5
  3. data/ext/audio.c +25 -19
  4. data/ext/audio_source.c +67 -39
  5. data/ext/color.c +19 -19
  6. data/ext/drawable.c +190 -31
  7. data/ext/extconf.rb +16 -14
  8. data/ext/gl.c +310 -30
  9. data/ext/gl_buffer.c +223 -2
  10. data/ext/gl_index_buffer.c +11 -0
  11. data/ext/gl_int_array.c +24 -22
  12. data/ext/gl_vertex.c +84 -49
  13. data/ext/image.c +115 -51
  14. data/ext/image_target.c +58 -10
  15. data/ext/input.c +73 -6
  16. data/ext/mo.c +583 -0
  17. data/ext/mo.h +189 -0
  18. data/ext/music.c +9 -8
  19. data/ext/pixel_bus.c +349 -0
  20. data/ext/polygon.c +68 -45
  21. data/ext/ray.c +1 -0
  22. data/ext/ray.h +19 -1
  23. data/ext/rect.c +9 -47
  24. data/ext/say.h +1 -2
  25. data/ext/say_all.h +6 -0
  26. data/ext/say_audio.h +3 -0
  27. data/ext/say_audio_context.c +1 -4
  28. data/ext/say_basic_type.c +24 -0
  29. data/ext/say_basic_type.h +4 -0
  30. data/ext/say_buffer.c +217 -88
  31. data/ext/say_buffer.h +20 -5
  32. data/ext/say_buffer_renderer.c +10 -7
  33. data/ext/say_buffer_renderer.h +1 -1
  34. data/ext/say_buffer_slice.c +70 -76
  35. data/ext/say_context.c +109 -22
  36. data/ext/say_context.h +14 -0
  37. data/ext/say_drawable.c +113 -25
  38. data/ext/say_drawable.h +23 -2
  39. data/ext/say_error.c +7 -2
  40. data/ext/say_font.c +30 -27
  41. data/ext/say_font.h +3 -6
  42. data/ext/say_get_proc.c +35 -0
  43. data/ext/say_image.c +102 -27
  44. data/ext/say_image.h +11 -4
  45. data/ext/say_image_target.c +88 -34
  46. data/ext/say_image_target.h +3 -2
  47. data/ext/say_index_buffer.c +31 -19
  48. data/ext/say_index_buffer.h +4 -2
  49. data/ext/say_index_buffer_slice.c +78 -70
  50. data/ext/say_music.c +4 -2
  51. data/ext/say_osx.h +3 -2
  52. data/ext/say_osx_context.h +37 -4
  53. data/ext/say_osx_window.h +32 -37
  54. data/ext/say_pixel_bus.c +163 -0
  55. data/ext/say_pixel_bus.h +44 -0
  56. data/ext/say_polygon.c +2 -2
  57. data/ext/say_shader.c +66 -62
  58. data/ext/say_shader.h +2 -0
  59. data/ext/say_sprite.c +1 -2
  60. data/ext/say_target.c +14 -23
  61. data/ext/say_target.h +3 -1
  62. data/ext/say_text.c +45 -7
  63. data/ext/say_text.h +12 -3
  64. data/ext/say_thread.c +13 -6
  65. data/ext/say_thread.h +1 -1
  66. data/ext/say_thread_variable.c +5 -5
  67. data/ext/say_vertex_type.c +79 -41
  68. data/ext/say_vertex_type.h +6 -2
  69. data/ext/say_view.c +10 -31
  70. data/ext/say_view.h +1 -5
  71. data/ext/say_win.h +2 -2
  72. data/ext/say_win_context.h +49 -11
  73. data/ext/say_win_window.h +30 -27
  74. data/ext/say_window.c +3 -3
  75. data/ext/say_x11.h +3 -1
  76. data/ext/say_x11_context.h +64 -10
  77. data/ext/say_x11_window.h +22 -17
  78. data/ext/shader.c +9 -0
  79. data/ext/sprite.c +7 -1
  80. data/ext/target.c +80 -28
  81. data/ext/text.c +43 -1
  82. data/ext/view.c +53 -1
  83. data/ext/window.c +4 -0
  84. data/lib/ray/animation_list.rb +17 -2
  85. data/lib/ray/audio_source.rb +11 -0
  86. data/lib/ray/color.rb +14 -0
  87. data/lib/ray/drawable.rb +23 -0
  88. data/lib/ray/dsl/event.rb +1 -9
  89. data/lib/ray/dsl/event_runner.rb +3 -4
  90. data/lib/ray/dsl/matcher.rb +20 -1
  91. data/lib/ray/effect.rb +116 -0
  92. data/lib/ray/effect/black_and_white.rb +38 -0
  93. data/lib/ray/effect/color_inversion.rb +16 -0
  94. data/lib/ray/effect/generator.rb +145 -0
  95. data/lib/ray/effect/grayscale.rb +32 -0
  96. data/lib/ray/game.rb +25 -5
  97. data/lib/ray/gl/vertex.rb +105 -26
  98. data/lib/ray/helper.rb +5 -0
  99. data/lib/ray/image.rb +54 -13
  100. data/lib/ray/image_target.rb +7 -0
  101. data/lib/ray/matrix.rb +26 -0
  102. data/lib/ray/music.rb +4 -0
  103. data/lib/ray/pixel_bus.rb +22 -0
  104. data/lib/ray/polygon.rb +17 -0
  105. data/lib/ray/pp.rb +28 -0
  106. data/lib/ray/ray.rb +7 -1
  107. data/lib/ray/rect.rb +7 -13
  108. data/lib/ray/scene.rb +24 -5
  109. data/lib/ray/scene_list.rb +9 -0
  110. data/lib/ray/shader.rb +11 -2
  111. data/lib/ray/sound.rb +4 -0
  112. data/lib/ray/sprite.rb +23 -62
  113. data/lib/ray/target.rb +25 -0
  114. data/lib/ray/text.rb +10 -0
  115. data/lib/ray/turtle.rb +9 -3
  116. data/lib/ray/vector.rb +18 -0
  117. data/lib/ray/vertex.rb +6 -0
  118. data/lib/ray/view.rb +22 -0
  119. data/samples/animation/sprite_motion.rb +0 -60
  120. data/samples/audio/{spacial.rb → spatial.rb} +1 -1
  121. data/samples/buffer/buffer.rb +1 -0
  122. data/samples/buffer/index_buffer.rb +2 -0
  123. data/samples/cptn_ruby/cptn_ruby.rb +6 -7
  124. data/samples/effects/effect.rb +39 -0
  125. data/samples/effects/grayscale.rb +27 -0
  126. data/samples/opengl/image.rb +7 -5
  127. data/samples/opengl/instancing.rb +159 -0
  128. data/samples/opengl/instancing.rbc +3231 -0
  129. data/samples/opengl/obj_loader.rb +9 -8
  130. data/samples/opengl/shader.rb +1 -3
  131. data/samples/shaders/geometry.rb +108 -38
  132. data/samples/shaders/geometry.rbc +2074 -0
  133. data/samples/shaders/shape.rb +2 -2
  134. data/samples/starfighter/starfighter.rb +5 -5
  135. data/samples/window/get_pixel.rb +1 -1
  136. data/test/animation_list_test.rb +18 -4
  137. data/test/drawable_test.rb +70 -1
  138. data/test/effect_generator_test.rb +63 -0
  139. data/test/effect_test.rb +61 -0
  140. data/test/game_test.rb +18 -0
  141. data/test/gl_buffer_test.rb +43 -1
  142. data/test/gl_index_buffer_test.rb +5 -0
  143. data/test/gl_vertex_test.rb +28 -1
  144. data/test/image_test.rb +5 -5
  145. data/test/input_test.rb +49 -0
  146. data/test/pixel_bus_test.rb +28 -0
  147. data/test/rect_test.rb +4 -0
  148. data/{samples/_media → test/res}/Beep.wav +0 -0
  149. data/samples/_media/CptnRuby Gem.png b/data/test/res/CptnRuby → Gem.png +0 -0
  150. data/samples/_media/CptnRuby Map.txt b/data/test/res/CptnRuby → Map.txt +0 -0
  151. data/samples/_media/CptnRuby Tileset.png b/data/test/res/CptnRuby → Tileset.png +0 -0
  152. data/{samples/_media → test/res}/CptnRuby.png +0 -0
  153. data/{samples/_media → test/res}/Space.png +0 -0
  154. data/{samples/_media → test/res}/Star.png +0 -0
  155. data/{samples/_media → test/res}/Starfighter.png +0 -0
  156. data/test/res/cube.obj +28 -0
  157. data/test/res/light3d.c +2 -2
  158. data/test/res/stone.png +0 -0
  159. data/test/scene_test.rb +3 -0
  160. data/test/sprite_test.rb +10 -0
  161. data/test/text_test.rb +31 -2
  162. data/test/view_test.rb +13 -1
  163. metadata +38 -17
  164. data/ext/say_array.c +0 -124
  165. data/ext/say_array.h +0 -34
  166. data/ext/say_table.c +0 -86
  167. data/ext/say_table.h +0 -24
@@ -19,11 +19,11 @@ Ray::Game.new("Shaders test") do
19
19
  @shape.shader = Ray::Shader.new :frag => StringIO.new(<<-SHADER)
20
20
  #version 110
21
21
 
22
- uniform vec3 ratio[2];
22
+ uniform vec3 ratio;
23
23
  varying vec4 var_Color;
24
24
 
25
25
  void main() {
26
- float gray = dot(var_Color.rgb, ratio[0]);
26
+ float gray = dot(var_Color.rgb, ratio);
27
27
  gl_FragColor = vec4(gray, gray, gray, 1.0);
28
28
  }
29
29
  SHADER
@@ -7,7 +7,7 @@ require 'ray'
7
7
  require 'forwardable'
8
8
 
9
9
  def path_of(resource)
10
- File.expand_path File.join(File.dirname(File.dirname(__FILE__)), resource)
10
+ File.join(File.dirname(__FILE__), "../../test/res", resource)
11
11
  end
12
12
 
13
13
  class Player
@@ -20,10 +20,10 @@ class Player
20
20
 
21
21
  def initialize(stars)
22
22
  @stars = stars
23
- @sprite = Ray::Sprite.new path_of("_media/Starfighter.png")
23
+ @sprite = Ray::Sprite.new path_of("Starfighter.png")
24
24
  @sprite.origin = @sprite.image.size / 2
25
25
 
26
- @beep = sound path_of("_media/Beep.wav")
26
+ @beep = sound path_of("Beep.wav")
27
27
 
28
28
  @vel_x = @vel_y = 0.0
29
29
 
@@ -89,7 +89,7 @@ class Star
89
89
  attr_reader :sprite
90
90
 
91
91
  def initialize(position)
92
- @sprite = Ray::Sprite.new path_of("_media/Star.png"), :at => position
92
+ @sprite = Ray::Sprite.new path_of("Star.png"), :at => position
93
93
  @sprite.sheet_size = [10, 1]
94
94
  @sprite.origin = (@sprite.image.size / @sprite.sheet_size) / 2
95
95
  @animation = sprite_animation(:from => [0, 0], :to => [9, 0],
@@ -122,7 +122,7 @@ Ray::Game.new("Starfighter --- [LEFT/RIGHT/UP to move; collect the stars]") do
122
122
  end
123
123
 
124
124
  scene :game do
125
- @background_image = sprite path_of("_media/Space.png")
125
+ @background_image = sprite path_of("Space.png")
126
126
  @score_text = text("", :at => [10, 10], :size => 20,
127
127
  :color => Ray::Color.yellow)
128
128
 
@@ -14,7 +14,7 @@ Ray.game "Get Pixels" do
14
14
  end
15
15
 
16
16
  on :key_press, key(:p) do
17
- window.to_image.write "screenshot.png"
17
+ window.to_image.write "screenshot.tga"
18
18
  end
19
19
 
20
20
  @obj = Ray::Polygon.circle([50, 50], 10, Ray::Color.blue)
@@ -40,8 +40,15 @@ context "an animation list" do
40
40
  context "after #update" do
41
41
  hookup { topic.update }
42
42
 
43
- asserts :empty?
44
- asserts(:to_a).equals []
43
+ denies :empty?
44
+ asserts(:to_a).equals { [@anim] }
45
+
46
+ context "and #remove_unused" do
47
+ hookup { topic.remove_unused }
48
+
49
+ asserts :empty?
50
+ asserts(:to_a).equals []
51
+ end
45
52
  end
46
53
  end
47
54
 
@@ -77,8 +84,15 @@ context "an animation list" do
77
84
  context "after #update" do
78
85
  hookup { topic.update }
79
86
 
80
- asserts :empty?
81
- asserts(:to_a).equals []
87
+ denies :empty?
88
+ asserts(:to_a).equals { [@anim] }
89
+
90
+ context "and #remove_unused" do
91
+ hookup { topic.remove_unused }
92
+
93
+ asserts :empty?
94
+ asserts(:to_a).equals []
95
+ end
82
96
  end
83
97
  end
84
98
 
@@ -9,6 +9,14 @@ context "a drawable" do
9
9
  asserts(:z).equals 0
10
10
  asserts(:angle).equals 0
11
11
  asserts(:shader).nil
12
+ asserts(:shader_attributes).nil
13
+ asserts(:matrix_proc).nil
14
+ asserts(:blend_mode).equals :alpha
15
+
16
+ context "after changing blend mode" do
17
+ hookup { topic.blend_mode = :add }
18
+ asserts(:blend_mode).equals :add
19
+ end
12
20
 
13
21
  context "after changing origin" do
14
22
  hookup { topic.origin = Ray::Vector2[10, 20] }
@@ -61,12 +69,16 @@ context "a drawable" do
61
69
  end
62
70
 
63
71
  context "with several transformations" do
72
+ attr = {:foo => 3}
73
+
64
74
  hookup do
65
75
  topic.origin = [30, 40]
66
76
  topic.pos = [10, 20]
67
77
  topic.angle = 90
68
78
  topic.scale = [2, 0.5]
69
79
  topic.z = 9
80
+
81
+ topic.shader_attributes = attr
70
82
  end
71
83
 
72
84
  # (10, 30) => (-20, -10) (origin)
@@ -88,6 +100,11 @@ context "a drawable" do
88
100
  asserts(:angle).equals 90
89
101
  asserts(:scale).equals Ray::Vector2[2, 0.5]
90
102
  asserts(:z).equals 9
103
+
104
+ asserts(:shader_attributes).equals attr
105
+ asserts("shader_attributes are copied") do
106
+ !(topic.shader_attributes.equal? attr)
107
+ end
91
108
  end
92
109
 
93
110
  context "and a custom matrix" do
@@ -107,6 +124,35 @@ context "a drawable" do
107
124
  1e-6)
108
125
  end
109
126
  end
127
+
128
+ context "and a custom matrix proc" do
129
+ matrix_proc = proc { Ray::Matrix.identity }
130
+
131
+ hookup do
132
+ proxy(matrix_proc).call
133
+
134
+ topic.matrix_proc = matrix_proc
135
+ topic.matrix # calls proc
136
+ end
137
+
138
+ asserts(:matrix).equals Ray::Matrix.new
139
+ asserts(:matrix_proc).equals matrix_proc
140
+ asserts(:matrix_proc).received(:call) { topic }
141
+
142
+ context "when matrix is accessed twice" do
143
+ hookup { topic.matrix }
144
+ denies(:matrix_proc).received(:call => 2) { topic }
145
+ end
146
+
147
+ context "when matrix is accessed after a change" do
148
+ hookup do
149
+ topic.matrix_changed!
150
+ topic.matrix
151
+ end
152
+
153
+ asserts(:matrix_proc).received(:call => 2) { topic }
154
+ end
155
+ end
110
156
  end
111
157
 
112
158
  context "after changing shader" do
@@ -194,15 +240,38 @@ context "a custom drawable" do
194
240
  end
195
241
  end
196
242
 
197
- context "with indices" do
243
+ context "drawn with indices" do
198
244
  hookup do
199
245
  proxy(topic).fill_indices
246
+ proxy(topic).render
247
+
200
248
  topic.index_count = 3
201
249
 
202
250
  target.draw topic
203
251
  end
204
252
 
205
253
  asserts_topic.received :fill_indices, is_a(Integer)
254
+ asserts_topic.received :render, is_a(Integer), is_a(Integer)
255
+
256
+ context "but no vertices" do
257
+ hookup do
258
+ topic.vertex_count = 0
259
+ target.draw topic
260
+ end
261
+
262
+ asserts_topic.received({:render => 2}, is_a(Integer), is_a(Integer))
263
+ end
264
+ end
265
+
266
+ context "drawn without vertices" do
267
+ hookup do
268
+ topic.vertex_count = 0
269
+
270
+ proxy(topic).render
271
+ target.draw topic
272
+ end
273
+
274
+ asserts_topic.received :render, 0, 0
206
275
  end
207
276
 
208
277
  context "with more indices than it gives" do
@@ -0,0 +1,63 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + '/helpers.rb'
2
+
3
+ context "an effect generator" do
4
+ setup do
5
+ gen = Ray::Effect::Generator.new
6
+ gen << (@effect = Ray::Effect::Grayscale.new([3, 5, 2]))
7
+ end
8
+
9
+ asserts(:effects).equals { [@effect] }
10
+
11
+ asserts(:version).equals 110
12
+
13
+ asserts(:input).matches "vec4 var_Color"
14
+ asserts(:input).matches "vec2 var_TexCoord"
15
+ asserts(:input).matches "varying "
16
+ denies(:input).matches "in "
17
+
18
+ asserts(:uniforms).matches "uniform sampler2D in_Texture"
19
+ asserts(:uniforms).matches "uniform bool in_TextureEnabled"
20
+
21
+ context "code" do
22
+ setup do
23
+ @struct = @effect.struct
24
+ @code = @effect.code
25
+ stub(@effect).header { "HEADER" }
26
+ topic.code
27
+ end
28
+
29
+ asserts_topic.matches "gl_FragColor"
30
+ denies_topic.matches "out_FragColor"
31
+
32
+ asserts_topic.matches "uniform ray_grayscale grayscale;"
33
+
34
+ asserts("headers are before structs") {
35
+ topic.index("HEADER") < topic.index(@struct)
36
+ }
37
+
38
+ asserts("structs are before functions") {
39
+ topic.index(@struct) < topic.index(@code)
40
+ }
41
+
42
+ asserts_topic.matches "if (grayscale.enabled)"
43
+ end
44
+
45
+ context "built shader" do
46
+ setup do
47
+ shader = Ray::Shader.new
48
+
49
+ proxy(shader).compile
50
+ proxy(shader).__send__(:[]=)
51
+
52
+ topic.build shader
53
+
54
+ shader
55
+ end
56
+
57
+ asserts_topic.received(:compile, is_a(Hash))
58
+ asserts_topic.received(:[]=, "grayscale.enabled", true)
59
+ asserts_topic.received(:[]=, "grayscale.ratio", [3, 5, 2])
60
+ end
61
+ end
62
+
63
+ run_tests if __FILE__ == $0
@@ -0,0 +1,61 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + '/helpers.rb'
2
+
3
+ class SomeEffect < Ray::Effect
4
+ Code = %{
5
+ vec4 effect(ray_some_effect args, vec4 color) {
6
+ return color;
7
+ }
8
+ }
9
+
10
+ Header = %{
11
+ foo bar;
12
+ }
13
+
14
+ effect_name :some_effect
15
+ attribute :thing, "vec4"
16
+ attribute :array, "vec2[10]"
17
+
18
+ def code
19
+ Code
20
+ end
21
+
22
+ def header
23
+ Header
24
+ end
25
+
26
+ def defaults
27
+ {
28
+ :thing => [4, 3, 2, 1],
29
+ "array[0]" => [10, 20]
30
+ }
31
+ end
32
+ end
33
+
34
+ context "an effect" do
35
+ setup { SomeEffect.new }
36
+
37
+ asserts(:name).equals :some_effect
38
+
39
+ asserts(:header).equals SomeEffect::Header
40
+
41
+ asserts(:struct).matches "struct ray_some_effect"
42
+ asserts(:struct).matches "bool enabled;"
43
+ asserts(:struct).matches "vec4 thing;"
44
+ asserts(:struct).matches "vec2 array[10];"
45
+
46
+ asserts(:code).equals SomeEffect::Code
47
+
48
+ context "default elements" do
49
+ setup do
50
+ hash = {}
51
+ topic.apply_defaults hash
52
+ hash
53
+ end
54
+
55
+ asserts_topic.equals("some_effect.enabled" => true,
56
+ "some_effect.thing" => [4, 3, 2, 1],
57
+ "some_effect.array[0]" => [10, 20])
58
+ end
59
+ end
60
+
61
+ run_tests if __FILE__ == $0
@@ -60,6 +60,24 @@ context "a game" do
60
60
  end
61
61
  end
62
62
 
63
+ context "with several scenes" do
64
+ hookup { topic.scenes << :scene_0 << :scene_1 << :scene_2 }
65
+
66
+ asserts :running?
67
+ asserts("current_scene") { topic.scenes.current }.equals {
68
+ topic.registered_scene(:scene_2)
69
+ }
70
+
71
+ context "after removing a few scenes" do
72
+ hookup { topic.pop_scene_while { |scene| scene.name != :scene_0 } }
73
+
74
+ asserts :running?
75
+ asserts("current_scene") { topic.scenes.current }.equals {
76
+ topic.registered_scene(:scene_0)
77
+ }
78
+ end
79
+ end
80
+
63
81
  context "after changing event_runner" do
64
82
  hookup do
65
83
  topic.event_runner = @runner = Ray::DSL::EventRunner.new
@@ -1,6 +1,9 @@
1
1
  require File.expand_path("helpers.rb", File.dirname(__FILE__))
2
2
 
3
- MagicVertex = Ray::GL::Vertex.make [[:foo, "bar", :float]]
3
+ MagicVertex = Ray::GL::Vertex.make [
4
+ [:vertex, "bar", :float],
5
+ [:instance, "baz", :float, true],
6
+ ]
4
7
 
5
8
  context "a buffer" do
6
9
  setup { Ray::GL::Buffer.new :static, Ray::Vertex }
@@ -11,8 +14,16 @@ context "a buffer" do
11
14
  asserts(:[], 256).nil
12
15
  asserts(:[]=, 257, Ray::Vertex.new).raises_kind_of RangeError
13
16
 
17
+ denies :has_instance?
18
+ asserts(:instance_size).nil
19
+ asserts(:resize_instance, 300).raises_kind_of RuntimeError
20
+ asserts(:get_instance, 0).raises_kind_of RuntimeError
21
+ asserts(:set_instance, 0, MagicVertex::Instance.new).
22
+ raises_kind_of RuntimeError
23
+
14
24
  context "nth vertex after setting it" do
15
25
  setup do
26
+ @buf = topic
16
27
  topic[34] = Ray::Vertex.new([10, 20], Ray::Color.red, [30, 40])
17
28
  topic[34]
18
29
  end
@@ -20,6 +31,37 @@ context "a buffer" do
20
31
  asserts(:pos).equals Ray::Vector2[10, 20]
21
32
  asserts(:col).equals Ray::Color.red
22
33
  asserts(:tex).equals Ray::Vector2[30, 40]
34
+
35
+ context "and resizing the buffer" do
36
+ setup do
37
+ @buf.resize 300
38
+ @buf[34]
39
+ end
40
+
41
+ asserts(:pos).equals Ray::Vector2[10, 20]
42
+ asserts(:col).equals Ray::Color.red
43
+ asserts(:tex).equals Ray::Vector2[30, 40]
44
+ end
45
+ end
46
+ end
47
+
48
+ context "a buffer with per-instance data" do
49
+ setup { Ray::GL::Buffer.new :static, MagicVertex }
50
+
51
+ asserts :has_instance?
52
+ asserts(:instance_size).equals 0
53
+ asserts(:get_instance, 0).nil
54
+ asserts(:set_instance, 0, MagicVertex::Instance.new).
55
+ raises_kind_of RangeError
56
+
57
+ context "resized" do
58
+ hookup { topic.resize_instance 300 }
59
+ asserts(:instance_size).equals 300
60
+
61
+ context "nth instance" do
62
+ setup { topic.set_instance 10, MagicVertex::Instance.new(42) }
63
+ asserts(:instance).equals 42
64
+ end
23
65
  end
24
66
  end
25
67
 
@@ -11,6 +11,11 @@ context "an index buffer" do
11
11
  context "after changing an element" do
12
12
  hookup { topic[34] = 30 }
13
13
  asserts(:[], 34).equals 30
14
+
15
+ context "and resizing the buffer" do
16
+ hookup { topic.resize 300 }
17
+ asserts(:[], 34).equals 30
18
+ end
14
19
  end
15
20
  end
16
21
 
@@ -7,7 +7,10 @@ TestVertex = Ray::GL::Vertex.make [
7
7
  [:bool, "in_Bool", :bool],
8
8
  [:color, "in_Color", :color],
9
9
  [:vector2, "in_Vector2", :vector2],
10
- [:vector3, "in_Vector3", :vector3]
10
+ [:vector3, "in_Vector3", :vector3],
11
+
12
+ [:magic, "in_Magic", :vector3, true],
13
+ [:foo, "in_Foo", :bool, true],
11
14
  ]
12
15
 
13
16
  context "a custom vertex" do
@@ -114,4 +117,28 @@ context "a custom vertex" do
114
117
  end
115
118
  end
116
119
 
120
+ context "an instance block" do
121
+ setup { TestVertex::Instance.new([1, 2, 3]) }
122
+
123
+ asserts(:magic).equals Ray::Vector3[1, 2, 3]
124
+ asserts(:foo)
125
+ asserts(:foo?)
126
+
127
+ context "after changing magic" do
128
+ hookup { topic.magic = [3, 2, 1] }
129
+
130
+ asserts(:magic).equals Ray::Vector3[3, 2, 1]
131
+ asserts(:foo)
132
+ asserts(:foo?)
133
+ end
134
+
135
+ context "after changing foo" do
136
+ hookup { topic.foo = false }
137
+
138
+ asserts(:magic).equals Ray::Vector3[1, 2, 3]
139
+ denies(:foo)
140
+ denies(:foo?)
141
+ end
142
+ end
143
+
117
144
  run_tests if __FILE__ == $0