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
@@ -10,6 +10,10 @@ module Ray
10
10
  end
11
11
  end
12
12
 
13
+ def pretty_print(q)
14
+ super q, ["time", "duration", "looping?", "buffer"]
15
+ end
16
+
13
17
  alias time= seek
14
18
 
15
19
  alias position pos
@@ -44,74 +44,20 @@ module Ray
44
44
  # @sprite_sheet_pos = Ray::Vector2[0, 0]
45
45
  end
46
46
 
47
- # # Sets the size of the sprite sheet. For instance,
48
- # # sprite.sheet_size = [3, 4]
49
- # # would mean there are 4 rows and 3 columns in the sprite (and each cell
50
- # # has the same size).
51
- # def sheet_size=(ary)
52
- # @uses_sprite_sheet = true
53
- # @sprite_sheet_size = ary.to_vector2
54
-
55
- # self.sheet_pos = [0, 0]
56
- # end
57
-
58
- # # Sets which cell of the sprite sheet should be displayed.
59
- # # sprite.sheet_pos = [0, 1] # Uses the first cell of the second line.
60
- # #
61
- # # pos.x and pos.y are rounded to floor.
62
- # # Passing a too high value will make the sprite use the previous cells.
63
- # # sprite.sheet_size = [4, 4]
64
- # # sprite.sheet_size = [5, 5]
65
- # # sprite.sheet_size == [1, 1] # => true
66
- # def sheet_pos=(pos)
67
- # pos = pos.to_vector2.dup
68
- # pos.x = pos.x.floor % @sprite_sheet_size.w
69
- # pos.y = pos.y.floor % @sprite_sheet_size.h
70
-
71
- # self.sub_rect = Ray::Rect.new(pos.x * sprite_width,
72
- # pos.y * sprite_height,
73
- # sprite_width, sprite_height)
74
-
75
- # @sheet_pos = pos
76
- # end
77
-
78
- # # @return [Ray::Vector2] the position of the cell which is being used.
79
- # attr_reader :sheet_pos
80
-
81
- # # @return [Integer, nil] The width of each cell in the sprite sheet
82
- # def sprite_width
83
- # if uses_sprite_sheet?
84
- # image.w / @sprite_sheet_size.w
85
- # end
86
- # end
87
-
88
- # # @return [Integer, nil] The height of each cell in the sprite sheet
89
- # def sprite_height
90
- # if uses_sprite_sheet?
91
- # image.h / @sprite_sheet_size.h
92
- # end
93
- # end
94
-
95
- # # Disables the sprite sheet
96
- # def disable_sprite_sheet
97
- # self.sub_rect = Ray::Rect.new(0, 0, image.w, image.h) if image
98
-
99
- # @sprite_sheet_size = nil
100
- # @uses_sprite_sheet = false
101
- # end
102
-
103
- # def uses_sprite_sheet?
104
- # @uses_sprite_sheet
105
- # end
106
-
107
47
  # @return [Ray::Rect] The rect where this sprite will be drawn, taking
108
48
  # position and scale in account.
109
49
  def rect
110
50
  pos = self.pos
111
51
  sub_rect = self.sub_rect
112
- scade = self.scale
52
+ origin = self.origin
53
+ scale = self.scale
54
+
55
+ top_left = (-origin * scale) + pos
113
56
 
114
- Ray::Rect.new(pos.x, pos.y, sub_rect.w * scale.w, sub_rect.h * scale.h)
57
+ Ray::Rect.new(top_left.x,
58
+ top_left.y,
59
+ sub_rect.w * scale.w,
60
+ sub_rect.h * scale.h)
115
61
  end
116
62
 
117
63
  # @param [Ray::Rect, #to_rect] An object with which the receiver may collide
@@ -132,5 +78,20 @@ module Ray
132
78
  def to_rect
133
79
  rect
134
80
  end
81
+
82
+ def pretty_print(q, other_attr = [])
83
+ attr = [
84
+ "image",
85
+ "color",
86
+ "x_flipped?", "y_flipped?",
87
+ "sub_rect", "rect"
88
+ ]
89
+
90
+ if uses_sprite_sheet?
91
+ attr.concat ["sheet_size", "sheet_pos", "sprite_width", "sprite_height"]
92
+ end
93
+
94
+ super q, attr + other_attr
95
+ end
135
96
  end
136
97
  end
@@ -1,12 +1,31 @@
1
1
  module Ray
2
2
  class Target
3
+ include Ray::PP
4
+
5
+ # Shader used when drawing on this target
6
+ #
7
+ # Notice this method will always return the same object, and that modifying
8
+ # this object will modify the shader used internally be the target.
9
+ #
3
10
  # @return [Ray::Shader] Shader used when drawing on this target
4
11
  def shader
5
12
  @shader ||= simple_shader # must always remain the same object
6
13
  end
7
14
 
15
+ # @group Manipulating views
16
+
17
+ # Changes the view temporarily
18
+ #
8
19
  # @param [Ray::View] view A new view
9
20
  # @yield a block where the view has been changed
21
+ #
22
+ # @example
23
+ # old_view = target.view
24
+ # target.with_view new_view do
25
+ # target.view == new_view # => true
26
+ # end
27
+ #
28
+ # target.view == old_view # => true
10
29
  def with_view(view)
11
30
  old_view = self.view
12
31
  self.view = view
@@ -14,5 +33,11 @@ module Ray
14
33
  ensure
15
34
  self.view = old_view
16
35
  end
36
+
37
+ # @endgroup
38
+
39
+ def pretty_print(q, other_attr = [])
40
+ pretty_print_attributes q, ["view", "shader", "size"] + other_attr
41
+ end
17
42
  end
18
43
  end
@@ -97,6 +97,16 @@ module Ray
97
97
 
98
98
  alias :to_s :string
99
99
 
100
+ def pretty_print(q, other_attributes = [])
101
+ attr = [
102
+ "string",
103
+ "font", "color", "size", "style",
104
+ "rect", "auto_center"
105
+ ]
106
+
107
+ super q, (attr + other_attributes)
108
+ end
109
+
100
110
  private
101
111
  def parse_style(style)
102
112
  case style
@@ -210,9 +210,15 @@ module Ray
210
210
  end
211
211
 
212
212
  class Target
213
- # Creates a turtle operating on the receiver.
214
- # Instance evaluates the block it is given if any.
215
- # @return [Ray::Turtle] The turtle it created.
213
+ # Creates a turtle operating on the receiver
214
+ #
215
+ # If a block is passed, it is instance-evaluated (self becoming the turtle)
216
+ # and the receiver gets updated automatically.
217
+ #
218
+ # @yield Optionally perform drawing in the block
219
+ #
220
+ # @return [Ray::Turtle] The turtle it created
221
+ # @see Ray::Turtle
216
222
  def turtle(&block)
217
223
  turtle = Ray::Turtle.new(self)
218
224
  if block
@@ -141,6 +141,14 @@ module Ray
141
141
  "(%g, %g)" % [x, y]
142
142
  end
143
143
 
144
+ def pretty_print(q)
145
+ q.text "("
146
+ q.pp(("%g" % x).to_f) # hides simple-precision inacurracy
147
+ q.text ", "
148
+ q.pp(("%g" % y).to_f)
149
+ q.text ")"
150
+ end
151
+
144
152
  alias :w :x
145
153
  alias :h :y
146
154
 
@@ -278,6 +286,16 @@ module Ray
278
286
  "(%g, %g, %g)" % [x, y, z]
279
287
  end
280
288
 
289
+ def pretty_print(q)
290
+ q.text "("
291
+ q.pp(("%g" % x).to_f) # hides simple-precision inacurracy
292
+ q.text ", "
293
+ q.pp(("%g" % y).to_f)
294
+ q.text ", "
295
+ q.pp(("%g" % z).to_f)
296
+ q.text ")"
297
+ end
298
+
281
299
  def to_a
282
300
  [x, y, z]
283
301
  end
@@ -3,6 +3,8 @@ module Ray
3
3
  # Important settings
4
4
  @vertex_type_id = 0
5
5
 
6
+ include Ray::PP
7
+
6
8
  def x; pos.x; end
7
9
  def y; pos.y; end
8
10
 
@@ -15,6 +17,10 @@ module Ray
15
17
  def tex_x=(val); self.tex = [val, tex_y]; end
16
18
  def tex_y=(val); self.tex = [tex_x, val]; end
17
19
 
20
+ def pretty_print(q)
21
+ pretty_print_attributes q, ["pos", "col", "tex"]
22
+ end
23
+
18
24
  alias color col
19
25
  alias color= col=
20
26
 
@@ -1,5 +1,23 @@
1
1
  module Ray
2
2
  class View
3
+ include Ray::PP
4
+
5
+ # @param [Ray::Rect] rect Rect to show, in pixels.
6
+ # @param [Ray::Vector2] target_size Size of the complete target, in pixels.
7
+ #
8
+ # @return [Ray::View] A view that allows to clip rendering to a given region
9
+ # of the target, without scaling.
10
+ def self.clip(rect, target_size)
11
+ rect, target_size = rect.to_rect, target_size.to_vector2
12
+
13
+ viewport = Ray::Rect[rect.x / target_size.w,
14
+ rect.y / target_size.h,
15
+ rect.w / target_size.w,
16
+ rect.h / target_size.y]
17
+
18
+ Ray::View.new(rect.center, rect.size, viewport)
19
+ end
20
+
3
21
  def ==(other)
4
22
  other.is_a?(Ray::View) && self.matrix == other.matrix
5
23
  end
@@ -43,5 +61,9 @@ module Ray
43
61
  def inspect
44
62
  "#<#{self.class} center=#{center} size=#{size} viewport=#{viewport}>"
45
63
  end
64
+
65
+ def pretty_print(q)
66
+ pretty_print_attributes q, ["center", "size", "matrix", "viewport"]
67
+ end
46
68
  end
47
69
  end
@@ -7,66 +7,6 @@ def path_of(res)
7
7
  File.expand_path File.join(File.dirname(__FILE__), '../../test/res', res)
8
8
  end
9
9
 
10
- class SpriteAnimation < Ray::Animation
11
- register_for :sprite_animation
12
-
13
- # @option opts [Ray::Vector2] :from First sprite position
14
- # @option opts [Ray::Vector2] :to Last sprite position
15
- # @option opts [true, false] :loop Whether to reset to the first step at the
16
- # end of the animation.
17
- # @option opts [Float] :duration Duration of the animation, in seconds.
18
- def setup(opts)
19
- self.duration = opts[:duration]
20
-
21
- @initial_value = opts[:from].to_vector2.dup
22
-
23
- delta = opts[:to].to_vector2 - opts[:from].to_vector2
24
-
25
- @x_steps = delta.x.to_i.abs + 1
26
- @y_steps = delta.y.to_i.abs + 1
27
-
28
- @negative_x = delta.x < 0
29
- @negative_y = delta.y < 0
30
-
31
- @loop = opts[:loop]
32
- end
33
-
34
- def update_target
35
- progress = progression
36
-
37
- x_prog = ((progress / 100) * @x_steps).floor
38
- y_prog = ((progress / 100) * @y_steps).floor
39
-
40
- x_prog = @x_steps - 1 if x_prog == @x_steps
41
- y_prog = @y_steps - 1 if y_prog == @y_steps
42
-
43
- target.sheet_pos = @initial_value + variation(x_prog, y_prog)
44
- end
45
-
46
- def end_animation
47
- target.sheet_pos = @initial_value if @loop
48
- end
49
-
50
- def variation(x, y)
51
- Ray::Vector2[@negative_x ? -x : x, @negative_y ? -y : y]
52
- end
53
-
54
- def -@
55
- last_value = @initial_value + variation(@x_steps - 1, @y_steps - 1)
56
-
57
- sprite_animation(:from => @initial_value,
58
- :to => last_value,
59
- :loop => @loop,
60
- :duration => @duration)
61
- end
62
-
63
- attr_reader :current_value
64
-
65
- attr_reader :initial_value
66
- attr_reader :x_steps, :y_steps
67
- attr_reader :negative_x, :negative_y
68
- end
69
-
70
10
  Ray.game "Sprite motion" do
71
11
  register { add_hook :quit, method(:exit!) }
72
12
 
@@ -9,7 +9,7 @@ require 'ray'
9
9
 
10
10
  SPEED = 5
11
11
 
12
- Ray.game "Spacial sounds" do
12
+ Ray.game "Spatialization" do
13
13
  register do
14
14
  add_hook :quit, method(:exit!)
15
15
  end
@@ -20,6 +20,7 @@ Ray.game "My Own Buffer" do
20
20
 
21
21
  render do |win|
22
22
  win.make_current
23
+ @buffer.bind
23
24
  Ray::GL.draw_arrays :triangles, 0, 3
24
25
  end
25
26
  end
@@ -28,6 +28,8 @@ Ray.game "My Own Index Buffer" do
28
28
 
29
29
  render do |win|
30
30
  win.make_current
31
+ @buffer.bind
32
+ @index_buffer.bind
31
33
  Ray::GL.draw_elements :triangles, 3, 0
32
34
  end
33
35
  end
@@ -30,10 +30,9 @@ $:.unshift File.expand_path(File.dirname(__FILE__) + "/../../ext")
30
30
  require 'ray'
31
31
 
32
32
  def path_of(resource)
33
- File.expand_path File.join(File.dirname(File.dirname(__FILE__)), resource)
33
+ File.join(File.dirname(__FILE__), "../../test/res", resource)
34
34
  end
35
35
 
36
-
37
36
  class CptnRuby
38
37
  include Ray::Helper
39
38
 
@@ -51,7 +50,7 @@ class CptnRuby
51
50
  @map = map
52
51
  @vy = 0
53
52
 
54
- @sprite = Ray::Sprite.new path_of("_media/CptnRuby.png"), :at => pos
53
+ @sprite = Ray::Sprite.new path_of("CptnRuby.png"), :at => pos
55
54
  @sprite.sheet_size = [4, 1]
56
55
 
57
56
  @size = Ray::Vector2[@sprite.sprite_width, @sprite.sprite_height]
@@ -151,7 +150,7 @@ class CollectibleGem
151
150
  include Ray::Helper
152
151
 
153
152
  def initialize(pos)
154
- @sprite = Ray::Sprite.new path_of("_media/CptnRuby Gem.png"), :at => pos
153
+ @sprite = Ray::Sprite.new path_of("CptnRuby Gem.png"), :at => pos
155
154
  @sprite.origin = @sprite.image.size / 2
156
155
 
157
156
  @animation = rotation(:from => -30, :to => 30, :duration => 0.6)
@@ -182,7 +181,7 @@ class CollectibleGem
182
181
  end
183
182
 
184
183
  class Map
185
- Tileset = path_of("_media/CptnRuby Tileset.png")
184
+ Tileset = path_of("CptnRuby Tileset.png")
186
185
  PartSize = 60
187
186
  TileSize = 50
188
187
 
@@ -241,9 +240,9 @@ Ray.game "Captain Ruby" do
241
240
  scene :game do
242
241
  @half_size = window.size / 2
243
242
 
244
- @sky = sprite path_of("_media/Space.png")
243
+ @sky = sprite path_of("Space.png")
245
244
 
246
- @map = Map.new path_of("_media/CptnRuby Map.txt")
245
+ @map = Map.new path_of("CptnRuby Map.txt")
247
246
  @cptn = CptnRuby.new(@map, [400, 100])
248
247
 
249
248
  @camera = Ray::View.new @cptn.pos, window.size
@@ -0,0 +1,39 @@
1
+ $:.unshift File.expand_path(File.dirname(__FILE__) + "/../../lib")
2
+ $:.unshift File.expand_path(File.dirname(__FILE__) + "/../../ext")
3
+
4
+ def path_of(res)
5
+ File.expand_path(File.dirname(__FILE__) + "/../../test/res/#{res}")
6
+ end
7
+
8
+ require 'ray'
9
+
10
+ Ray.game "Some effects" do
11
+ register { add_hook :quit, method(:exit!) }
12
+
13
+ scene :shader do
14
+ @obj = sprite path_of("sprite.png")
15
+
16
+ effect_generator do |gen|
17
+ gen << color_inversion << grayscale
18
+ gen.build window.shader
19
+ end
20
+
21
+ @states = Hash.new(true)
22
+
23
+ {
24
+ :color_inversion => :i,
25
+ :grayscale => :g
26
+ }.each do |state, key_name|
27
+ on :key_press, key(key_name) do
28
+ @states[state] = !@states[state]
29
+ window.shader["#{state}.enabled"] = @states[state]
30
+ end
31
+ end
32
+
33
+ render do |win|
34
+ win.draw @obj
35
+ end
36
+ end
37
+
38
+ scenes << :shader
39
+ end