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
data/README.md CHANGED
@@ -8,7 +8,8 @@ to be easy and fun to use (à la Shoes), and still flexible and powerful.
8
8
  Tutorial & Installation
9
9
  =======================
10
10
 
11
- See [on this page](http://mon-ouie.github.com/projects/ray.html).
11
+ See [on this page](http://mon-ouie.github.com/projects/ray.html). Also notice
12
+ there's an IRC channel on freenode: #ray.
12
13
 
13
14
  Features
14
15
  ========
@@ -128,11 +129,13 @@ Ray. In fact, ``Ray::Drawable`` can simply be used for OpenGL rendering:
128
129
 
129
130
  # return an array of vertices
130
131
  def fill_vertices
132
+ rect = @img.tex_rect [0, 0, @img.w, @img.h]
133
+
131
134
  [
132
- Ray::Vertex.new([0, 0], Ray::Color.white, [0, 0]),
133
- Ray::Vertex.new([@img.w, 0], Ray::Color.white, [1, 0]),
134
- Ray::Vertex.new([@img.w, @img.h], Ray::Color.white, [1, 1]),
135
- Ray::Vertex.new([0, @img.h], Ray::Color.white, [0, 1]),
135
+ Ray::Vertex.new([0, 0], Ray::Color.white, rect.top_left),
136
+ Ray::Vertex.new([@img.w, 0], Ray::Color.white, rect.top_right),
137
+ Ray::Vertex.new([0, @img.h], Ray::Color.white, rect.bottom_left),
138
+ Ray::Vertex.new([@img.w, @img.h], Ray::Color.white, rect.bottom_right),
136
139
  ]
137
140
  end
138
141
 
@@ -143,7 +146,7 @@ Ray. In fact, ``Ray::Drawable`` can simply be used for OpenGL rendering:
143
146
  @image.bind
144
147
 
145
148
  # Some low level OpenGL calls are available
146
- Ray::GL.draw_arrays :triangle_fan, first, 4
149
+ Ray::GL.draw_arrays :triangle_strip, first, 4
147
150
  end
148
151
  end
149
152
 
data/Rakefile CHANGED
@@ -39,11 +39,7 @@ task :test do
39
39
  test_file = File.expand_path("test/run_all.rb", File.dirname(__FILE__))
40
40
 
41
41
  begin
42
- if defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
43
- ruby "-X+O", test_file
44
- else
45
- ruby test_file
46
- end
42
+ ruby test_file
47
43
  rescue
48
44
  exit 1
49
45
  end
@@ -3,18 +3,18 @@
3
3
  VALUE ray_mAudio = Qnil;
4
4
 
5
5
  /*
6
- @return [Float] The global volume. 0 is the minimum volume, whereas 100
7
- is the maximum.
8
- */
6
+ * @see volume=
7
+ */
9
8
  VALUE ray_audio_volume(VALUE self) {
10
9
  return rb_float_new(say_audio_get_volume());
11
10
  }
12
11
 
13
12
  /*
14
- @overload volume=(val)
15
- Sets the global volume.
16
- @param [Float] val The new value for the volume.
17
- */
13
+ * @overload volume=(val)
14
+ * Sets the global volume
15
+ * @param [Float] val The new value for the volume, 0 being the minimum and
16
+ * 100 the maximum as well as the default.
17
+ */
18
18
  VALUE ray_audio_set_volume(VALUE self, VALUE value) {
19
19
  float volume = (float)NUM2DBL(value);
20
20
  say_audio_set_volume(volume);
@@ -23,17 +23,17 @@ VALUE ray_audio_set_volume(VALUE self, VALUE value) {
23
23
  }
24
24
 
25
25
  /*
26
- @return [Ray::Vector3] The position of the listener.
27
- */
26
+ * @see pos=
27
+ */
28
28
  VALUE ray_audio_pos(VALUE self) {
29
29
  return ray_vector3_to_rb(say_audio_get_pos());
30
30
  }
31
31
 
32
32
  /*
33
- @overload pos=(pos)
34
- Sets the position of the listener.
35
- @param [Ray::Vector3, #to_vector3] pos The new position of the
36
- listener.
33
+ * @overload pos=(pos)
34
+ * Sets the position of the listener
35
+ * @param [Ray::Vector3, #to_vector3] pos The new position of the
36
+ * listener.
37
37
  */
38
38
  VALUE ray_audio_set_pos(VALUE self, VALUE pos) {
39
39
  say_audio_set_pos(ray_convert_to_vector3(pos));
@@ -41,22 +41,28 @@ VALUE ray_audio_set_pos(VALUE self, VALUE pos) {
41
41
  }
42
42
 
43
43
  /*
44
- @return [Ray::Vector3] The orientation of the listener.
45
- */
44
+ * @see direction=
45
+ */
46
46
  VALUE ray_audio_direction(VALUE self) {
47
47
  return ray_vector3_to_rb(say_audio_get_direction());
48
48
  }
49
49
 
50
50
  /*
51
- @overload direction=(dir)
52
- Sets the orientation of the listener.
53
- @param [Ray::Vector3, #to_vector3] dir The new orientation of the listener.
54
- */
51
+ * @overload direction=(dir)
52
+ * Sets the orientation of the listener
53
+ * @param [Ray::Vector3, #to_vector3] dir The new orientation of the listener.
54
+ */
55
55
  VALUE ray_audio_set_direction(VALUE self, VALUE dir) {
56
56
  say_audio_set_direction(ray_convert_to_vector3(dir));
57
57
  return dir;
58
58
  }
59
59
 
60
+ /*
61
+ * Document-class: Ray::Audio
62
+ *
63
+ * Ray.:Audio is used to manipulate the state of the listener, through global
64
+ * parameters such as volume or position in the 3D world.
65
+ */
60
66
  void Init_ray_audio() {
61
67
  ray_mAudio = rb_define_module_under(ray_mRay, "Audio");
62
68
  rb_define_module_function(ray_mAudio, "volume", ray_audio_volume, 0);
@@ -15,8 +15,7 @@ say_audio_source *ray_rb2audio_source(VALUE obj) {
15
15
  return NULL;
16
16
  }
17
17
 
18
-
19
- /* @return [Float] Volume of the source, between 0 and 100. */
18
+ /* @see volume= */
20
19
  static
21
20
  VALUE ray_audio_source_volume(VALUE self) {
22
21
  say_audio_source *source = ray_rb2audio_source(self);
@@ -24,10 +23,14 @@ VALUE ray_audio_source_volume(VALUE self) {
24
23
  }
25
24
 
26
25
  /*
27
- @overload volume=(vol)
28
- Sets the volume of the source.
29
- @param [Float] vol The new volume of the source.
30
- */
26
+ * @overload volume=(vol)
27
+ * Sets the volume of the source
28
+ *
29
+ * The volume is a number between 0 and 100. When it is set to 100, the
30
+ * volume is maximal.
31
+ *
32
+ * @param [Float] vol The new volume of the source
33
+ */
31
34
  static
32
35
  VALUE ray_audio_source_set_volume(VALUE self, VALUE value) {
33
36
  rb_check_frozen(self);
@@ -38,7 +41,7 @@ VALUE ray_audio_source_set_volume(VALUE self, VALUE value) {
38
41
  return value;
39
42
  }
40
43
 
41
- /* @return [Float] The pitch of the source. */
44
+ /* @see ptich= */
42
45
  static
43
46
  VALUE ray_audio_source_pitch(VALUE self) {
44
47
  say_audio_source *source = ray_rb2audio_source(self);
@@ -46,11 +49,14 @@ VALUE ray_audio_source_pitch(VALUE self) {
46
49
  }
47
50
 
48
51
  /*
49
- @overload pitch=(pitch)
50
- Sets the pitch of the sound.
51
- @param [Float] pitch the pitch value, which makes a sound more acute
52
- or grave and also affects playing speed. Defaulted to 1.
53
- */
52
+ * @overload pitch=(pitch)
53
+ * Sets the pitch of the sound
54
+ *
55
+ * Pitch makes the sound more acute or grave, and affcets playing speed. It is
56
+ * defaulted to 1.
57
+ *
58
+ * @param [Float] pitch The new pitch value
59
+ */
54
60
  static
55
61
  VALUE ray_audio_source_set_pitch(VALUE self, VALUE pitch) {
56
62
  rb_check_frozen(self);
@@ -61,7 +67,7 @@ VALUE ray_audio_source_set_pitch(VALUE self, VALUE pitch) {
61
67
  return pitch;
62
68
  }
63
69
 
64
- /* @return [Ray::Vector3] The position of the source. */
70
+ /* @see pos= */
65
71
  static
66
72
  VALUE ray_audio_source_pos(VALUE self) {
67
73
  say_audio_source *source = ray_rb2audio_source(self);
@@ -69,10 +75,10 @@ VALUE ray_audio_source_pos(VALUE self) {
69
75
  }
70
76
 
71
77
  /*
72
- @overload pos=(pos)
73
- Sets the position of the sound.
74
- @param [Ray::Vector3, #to_vector3] pos The position of the source.
75
- */
78
+ * @overload pos=(pos)
79
+ * Sets the position of the sound
80
+ * @param [Ray::Vector3] pos The new position of the source
81
+ */
76
82
  static
77
83
  VALUE ray_audio_source_set_pos(VALUE self, VALUE pos) {
78
84
  rb_check_frozen(self);
@@ -84,9 +90,8 @@ VALUE ray_audio_source_set_pos(VALUE self, VALUE pos) {
84
90
  }
85
91
 
86
92
  /*
87
- @return [true, false] True if the source position is relative to the listener,
88
- as opposed to being absolute.
89
- */
93
+ * @see relative=
94
+ */
90
95
  static
91
96
  VALUE ray_audio_source_is_relative(VALUE self) {
92
97
  say_audio_source *source = ray_rb2audio_source(self);
@@ -94,11 +99,13 @@ VALUE ray_audio_source_is_relative(VALUE self) {
94
99
  }
95
100
 
96
101
  /*
97
- @overload relative=(rel)
98
- Sets whether the sound should be relative.
99
- @param [true, false] rel Whether the source position should be relative
100
- to the listener's.
101
- */
102
+ *@overload relative=(rel)
103
+ * Sets whether the sound position is relative to the listener's
104
+ *
105
+ * This is false by default, meaning the position is absolute.
106
+ *
107
+ * @param [true, false] rel True to make the sound become relative
108
+ */
102
109
  static
103
110
  VALUE ray_audio_source_set_relative(VALUE self, VALUE val) {
104
111
  rb_check_frozen(self);
@@ -109,7 +116,7 @@ VALUE ray_audio_source_set_relative(VALUE self, VALUE val) {
109
116
  return val;
110
117
  }
111
118
 
112
- /* @return [Float] the source's minimal distance. */
119
+ /* @see min_distance= */
113
120
  static
114
121
  VALUE ray_audio_source_min_distance(VALUE self) {
115
122
  say_audio_source *source = ray_rb2audio_source(self);
@@ -117,11 +124,14 @@ VALUE ray_audio_source_min_distance(VALUE self) {
117
124
  }
118
125
 
119
126
  /*
120
- @overload min_distance=(dist)
121
- Sets the sounds minimal distance.
122
- @param [Float] dist the distance beyond which the source's volume will
123
- decrease. Defaulted to 1.
124
- */
127
+ * @overload min_distance=(dist)
128
+ * Sets the sounds minimal distance
129
+ *
130
+ * The minimal distance is the distance beyound which a source's volume will
131
+ * start decreasing. It is defaulted to one.
132
+ *
133
+ * @param [Float] dist The new default value
134
+ */
125
135
  static
126
136
  VALUE ray_audio_source_set_min_distance(VALUE self, VALUE dist) {
127
137
  rb_check_frozen(self);
@@ -132,7 +142,7 @@ VALUE ray_audio_source_set_min_distance(VALUE self, VALUE dist) {
132
142
  return dist;
133
143
  }
134
144
 
135
- /* @return [Float] The source's attenuation */
145
+ /* @see attenuation= */
136
146
  static
137
147
  VALUE ray_audio_source_attenuation(VALUE self) {
138
148
  say_audio_source *source = ray_rb2audio_source(self);
@@ -140,12 +150,14 @@ VALUE ray_audio_source_attenuation(VALUE self) {
140
150
  }
141
151
 
142
152
  /*
143
- @overload attenuation=(attenuation)
144
- Sets the attenuation of a sound.
145
- @param [Float] atenuation New attenuation factor of the sound.
146
- 0 will prevent the sound from being attenuated, 100 would
147
- make the sound be attenuated much more quickly.
148
- */
153
+ * @overload attenuation=(attenuation)
154
+ * Sets the attenuation of a sound
155
+ *
156
+ * When set to 0, the sound will not be attenuated at all. 100 makes
157
+ * attenuation very quick.
158
+ *
159
+ * @param [Float] atenuation New attenuation factor of the sound
160
+ */
149
161
  static
150
162
  VALUE ray_audio_source_set_attenuation(VALUE self, VALUE att) {
151
163
  rb_check_frozen(self);
@@ -153,7 +165,13 @@ VALUE ray_audio_source_set_attenuation(VALUE self, VALUE att) {
153
165
  return att;
154
166
  }
155
167
 
156
- /* @return [Symbol] Playing status. One of playing, paused, stopped. */
168
+ /*
169
+ * Playing status
170
+ *
171
+ * The status can be +:playing+, +:paused+, or +:stopped+.
172
+ *
173
+ * @return [Symbol] Playing status
174
+ */
157
175
  static
158
176
  VALUE ray_audio_source_status(VALUE self) {
159
177
  switch (say_audio_source_get_status(ray_rb2audio_source(self))) {
@@ -165,6 +183,14 @@ VALUE ray_audio_source_status(VALUE self) {
165
183
  return Qnil; /* should never happen */
166
184
  }
167
185
 
186
+ /*
187
+ * Document-class: Ray::AudioSource
188
+ *
189
+ * Audio sources are objects able to produce sound, either by directly passing
190
+ * them to a buffer or by streaming audio data.
191
+ *
192
+ * This class holds generic methods to manipulate a source.
193
+ */
168
194
  void Init_ray_audio_source() {
169
195
  ray_cAudioSource = rb_define_class_under(ray_mRay, "AudioSource", rb_cObject);
170
196
 
@@ -174,6 +200,7 @@ void Init_ray_audio_source() {
174
200
  rb_define_method(ray_cAudioSource, "pitch", ray_audio_source_pitch, 0);
175
201
  rb_define_method(ray_cAudioSource, "pitch=", ray_audio_source_set_pitch, 1);
176
202
 
203
+ /* @group Spatialization */
177
204
  rb_define_method(ray_cAudioSource, "pos", ray_audio_source_pos, 0);
178
205
  rb_define_method(ray_cAudioSource, "pos=",
179
206
  ray_audio_source_set_pos, 1);
@@ -192,6 +219,7 @@ void Init_ray_audio_source() {
192
219
  ray_audio_source_attenuation, 0);
193
220
  rb_define_method(ray_cAudioSource, "attenuation=",
194
221
  ray_audio_source_set_attenuation, 1);
222
+ /* @endgroup */
195
223
 
196
224
  rb_define_method(ray_cAudioSource, "status", ray_audio_source_status, 0);
197
225
  }
@@ -29,10 +29,10 @@ VALUE ray_color_alloc(VALUE self) {
29
29
  }
30
30
 
31
31
  /*
32
- @overload initialize(red, green, blue, alpha = 255)
33
- Creates a new color. All the parameters must be integers between
34
- 0 and 255. Alpha is the transparency (255: opaque, 0: invisible).
35
- */
32
+ * @overload initialize(red, green, blue, alpha = 255)
33
+ * Creates a new color. All the parameters must be integers between
34
+ * 0 and 255. Alpha is the transparency (255: opaque, 0: invisible).
35
+ */
36
36
  static
37
37
  VALUE ray_color_init(int argc, VALUE *argv, VALUE self) {
38
38
  VALUE r, g, b, a;
@@ -98,10 +98,10 @@ VALUE ray_color_a(VALUE self) {
98
98
  }
99
99
 
100
100
  /*
101
- @overload r=(val)
102
- Sets the red intensity.
103
- @param [Integer] The new red intensity.
104
- */
101
+ * @overload r=(val)
102
+ * Sets the red intensity
103
+ * @param [Integer] The new red intensity.
104
+ */
105
105
  static
106
106
  VALUE ray_color_set_r(VALUE self, VALUE val) {
107
107
  rb_check_frozen(self);
@@ -114,9 +114,9 @@ VALUE ray_color_set_r(VALUE self, VALUE val) {
114
114
  }
115
115
 
116
116
  /*
117
- @overload r=(val)
118
- Sets the red intensity.
119
- @param [Integer] The new red intensity.
117
+ * @overload g=(val)
118
+ * Sets the green intensity
119
+ * @param [Integer] The new green intensity.
120
120
  */
121
121
  static
122
122
  VALUE ray_color_set_g(VALUE self, VALUE val) {
@@ -130,10 +130,10 @@ VALUE ray_color_set_g(VALUE self, VALUE val) {
130
130
  }
131
131
 
132
132
  /*
133
- @overload b=(val)
134
- Sets the blue intensity.
135
- @param [Integer] The new blue intensity.
136
- */
133
+ * @overload blue=(val)
134
+ * Sets the blue intensity
135
+ * @param [Integer] The new blue intensity.
136
+ */
137
137
  static
138
138
  VALUE ray_color_set_b(VALUE self, VALUE val) {
139
139
  rb_check_frozen(self);
@@ -146,10 +146,10 @@ VALUE ray_color_set_b(VALUE self, VALUE val) {
146
146
  }
147
147
 
148
148
  /*
149
- @overload a=(val)
150
- Sets the alpha opacity.
151
- @param [Integer] The new alpha opacity.
152
- */
149
+ * @overload a=(val)
150
+ * Sets the alpha opacity
151
+ * @param [Integer] The new alpha opacity.
152
+ */
153
153
  static
154
154
  VALUE ray_color_set_a(VALUE self, VALUE val) {
155
155
  rb_check_frozen(self);
@@ -2,6 +2,19 @@
2
2
 
3
3
  VALUE ray_cDrawable = Qnil;
4
4
 
5
+ static
6
+ void ray_drawable_actual_matrix_proc(void *data, say_matrix *matrix) {
7
+ say_drawable *drawable = ((ray_drawable*)data)->drawable;
8
+
9
+ VALUE rb_obj = (VALUE)say_drawable_get_other_data(drawable);
10
+ VALUE proc = rb_iv_get(rb_obj, "@matrix_proc");
11
+
12
+ VALUE rb_matrix = rb_funcall(proc, RAY_METH("call"), 1, rb_obj);
13
+
14
+ memcpy(matrix->content, ray_rb2matrix(rb_matrix)->content,
15
+ sizeof(say_matrix));
16
+ }
17
+
5
18
  static
6
19
  void ray_drawable_fill_proc(void *drawable_ptr, void *vertex_ptr) {
7
20
  ray_drawable *drawable = drawable_ptr;
@@ -27,9 +40,22 @@ void ray_drawable_fill_proc(void *drawable_ptr, void *vertex_ptr) {
27
40
  }
28
41
  }
29
42
 
43
+ void ray_drawable_shader_proc(void *data, say_shader *shader) {
44
+ /* Works because the offset will be the same anyway */
45
+ say_drawable *drawable = ((ray_drawable*)data)->drawable;
46
+
47
+ VALUE rb_obj = (VALUE)say_drawable_get_other_data(drawable);
48
+ VALUE hash = rb_iv_get(rb_obj, "@shader_attributes");
49
+
50
+ if (!NIL_P(hash)) {
51
+ /* Create a ruby shader object to call merge */
52
+ VALUE rb_shader = ray_shader2rb(shader, Qnil);
53
+ rb_funcall(rb_shader, RAY_METH("merge"), 1, hash);
54
+ }
55
+ }
56
+
30
57
  static
31
- void ray_drawable_render_proc(void *data, size_t first, size_t index,
32
- say_shader *shader) {
58
+ void ray_drawable_render_proc(void *data, size_t first, size_t index) {
33
59
  ray_drawable *drawable = (ray_drawable*)data;
34
60
  rb_funcall(drawable->obj, RAY_METH("render"), 2,
35
61
  ULONG2NUM(first), ULONG2NUM(index));
@@ -60,16 +86,16 @@ void ray_drawable_indices_fill_proc(void *data, GLuint *ptr, size_t first) {
60
86
  VALUE array = rb_funcall(drawable->obj, RAY_METH("fill_indices"), 1,
61
87
  ULONG2NUM(first));
62
88
 
63
- say_array *c_array = ray_rb2int_array(array);
89
+ mo_array *c_array = ray_rb2int_array(array);
64
90
  size_t size = say_drawable_get_index_count(drawable->drawable);
65
- size_t actual_size = say_array_get_size(c_array);
91
+ size_t actual_size = c_array->size;
66
92
 
67
- if (say_array_get_size(c_array) < size) {
93
+ if (actual_size < size) {
68
94
  rb_raise(rb_eRuntimeError, "received %zu indices, expected %zu",
69
95
  actual_size, size);
70
96
  }
71
97
 
72
- memcpy(ptr, say_array_get(ray_rb2int_array(array), 0), sizeof(GLuint) * size);
98
+ memcpy(ptr, mo_array_at(c_array, 0), sizeof(GLuint) * size);
73
99
  }
74
100
 
75
101
  say_drawable *ray_rb2drawable(VALUE obj) {
@@ -126,7 +152,9 @@ VALUE ray_drawable_init(int argc, VALUE *argv, VALUE self) {
126
152
 
127
153
  obj->drawable = say_drawable_create(id);
128
154
  say_drawable_set_custom_data(obj->drawable, obj);
155
+ say_drawable_set_other_data(obj->drawable, (void*)self);
129
156
  say_drawable_set_fill_proc(obj->drawable, ray_drawable_fill_proc);
157
+ say_drawable_set_shader_proc(obj->drawable, ray_drawable_shader_proc);
130
158
  say_drawable_set_render_proc(obj->drawable, ray_drawable_render_proc);
131
159
  say_drawable_set_index_fill_proc(obj->drawable,
132
160
  ray_drawable_indices_fill_proc);
@@ -140,6 +168,12 @@ VALUE ray_drawable_init(int argc, VALUE *argv, VALUE self) {
140
168
  return self;
141
169
  }
142
170
 
171
+ void ray_drawable_copy_attr(VALUE self, VALUE orig) {
172
+ VALUE attr = rb_iv_get(orig, "@shader_attributes");
173
+ if (!NIL_P(attr))
174
+ rb_iv_set(self, "@shader_attributes", rb_obj_dup(attr));
175
+ }
176
+
143
177
  static
144
178
  VALUE ray_drawable_init_copy(VALUE self, VALUE orig) {
145
179
  if (rb_obj_is_kind_of(self, rb_path2class("Ray::Text")) ||
@@ -157,12 +191,15 @@ VALUE ray_drawable_init_copy(VALUE self, VALUE orig) {
157
191
  size_t vid = say_drawable_get_vertex_type(other->drawable);
158
192
  obj->drawable = say_drawable_create(vid);
159
193
  say_drawable_set_custom_data(obj->drawable, obj);
194
+ say_drawable_set_other_data(obj->drawable, (void*)self);
160
195
  say_drawable_copy(obj->drawable, other->drawable);
161
196
  say_drawable_set_changed(obj->drawable);
162
197
 
163
198
  rb_iv_set(self, "@vertex_type_class", rb_iv_get(orig, "@vertex_type_class"));
164
199
  obj->vsize = other->vsize;
165
200
 
201
+ ray_drawable_copy_attr(self, orig);
202
+
166
203
  return self;
167
204
  }
168
205
 
@@ -261,28 +298,67 @@ VALUE ray_drawable_set_z(VALUE self, VALUE val) {
261
298
  }
262
299
 
263
300
  /*
264
- Angle is a rotation applied to a drawable. It is expressed in degrees, in the
265
- counter-clockwise direction.
266
-
267
- @return [Float] The rotation applied to the drawable
268
- */
301
+ * Angle is a rotation applied to a drawable. It is expressed in degrees, in the
302
+ * counter-clockwise direction.
303
+ *
304
+ * @return [Float] The rotation applied to the drawable
305
+ */
269
306
  static
270
307
  VALUE ray_drawable_angle(VALUE self) {
271
308
  return rb_float_new(say_drawable_get_angle(ray_rb2drawable(self)));
272
309
  }
273
310
 
274
311
  /*
275
- @overload angle=(val)
276
- Sets the rotation applied to the drawable.
277
- @see #angle=
278
- @param [Float] val The rotation applied to the drawable.
279
- */
312
+ * @overload angle=(val)
313
+ * Sets the rotation applied to the drawable.
314
+ * @see #angle=
315
+ * @param [Float] val The rotation applied to the drawable.
316
+ */
280
317
  static
281
318
  VALUE ray_drawable_set_angle(VALUE self, VALUE val) {
282
319
  say_drawable_set_angle(ray_rb2drawable(self), NUM2DBL(val));
283
320
  return val;
284
321
  }
285
322
 
323
+ /*
324
+ * @return [Proc, nil] Proc used to generate matrices, if any.
325
+ */
326
+ static
327
+ VALUE ray_drawable_matrix_proc(VALUE self) {
328
+ return rb_iv_get(self, "@matrix_proc");
329
+ }
330
+
331
+ /*
332
+ * @overload matrix_proc=(val)
333
+ * Sets the proc used to generate matrices. When set to nil, disables
334
+ * custom proc. The proc is called with the drawable to generate a matrix
335
+ * for, and should return that matrix.
336
+ *
337
+ * @param [Proc, nil] val
338
+ */
339
+ static
340
+ VALUE ray_drawable_set_matrix_proc(VALUE self, VALUE val) {
341
+ say_drawable *drawable = ray_rb2drawable(self);
342
+
343
+ if (NIL_P(val))
344
+ say_drawable_set_matrix_proc(drawable, NULL);
345
+ else
346
+ say_drawable_set_matrix_proc(drawable, ray_drawable_actual_matrix_proc);
347
+
348
+ rb_iv_set(self, "@matrix_proc", val);
349
+ return val;
350
+ }
351
+
352
+ /*
353
+ * Marks the drawable's matrix as changed. This is meant to be called when you
354
+ * want your matrix proc to be called the next time the matrix is accessed.
355
+ */
356
+ static
357
+ VALUE ray_drawable_matrix_changed(VALUE self) {
358
+ say_drawable_set_matrix_changed(ray_rb2drawable(self));
359
+ return self;
360
+ }
361
+
286
362
  /*
287
363
  @return [Ray::Matrix] The transformation matrix used by this object.
288
364
  */
@@ -292,15 +368,15 @@ VALUE ray_drawable_matrix(VALUE self) {
292
368
  }
293
369
 
294
370
  /*
295
- @overload matrix=(val)
296
- Sets the current matrix to a custom one, making Ray ignore attributes
297
- setting that change the transformation matrix.
298
-
299
- Setting this to nil will cause Ray to start using the actual transformation
300
- matrix.
301
-
302
- @param [Ray::Matrix, nil] val
303
- */
371
+ * @overload matrix=(val)
372
+ * Sets the current matrix to a custom one, making Ray ignore attributes
373
+ * setting that change the transformation matrix.
374
+ *
375
+ * Setting this to nil will cause Ray to start using the actual
376
+ * transformation matrix.
377
+ *
378
+ * @param [Ray::Matrix, nil] val
379
+ */
304
380
  static
305
381
  VALUE ray_drawable_set_matrix(VALUE self, VALUE val) {
306
382
  say_drawable *drawable = ray_rb2drawable(self);
@@ -314,12 +390,12 @@ VALUE ray_drawable_set_matrix(VALUE self, VALUE val) {
314
390
  }
315
391
 
316
392
  /*
317
- @overload transform(point)
318
- Applies the transformations to a point.
319
-
320
- @param [Ray::Vector3] point Point to transform.
321
- @return [Ray::Vector3] Transformed point
322
- */
393
+ * @overload transform(point)
394
+ * Applies the transformations to a point
395
+ *
396
+ * @param [Ray::Vector3] point Point to transform.
397
+ * @return [Ray::Vector3] Transformed point
398
+ */
323
399
  static
324
400
  VALUE ray_drawable_transform(VALUE self, VALUE point) {
325
401
  say_vector3 res = say_drawable_transform(ray_rb2drawable(self),
@@ -402,12 +478,81 @@ VALUE ray_drawable_set_textured(VALUE self, VALUE val) {
402
478
  return self;
403
479
  }
404
480
 
481
+ /*
482
+ * @overload blend_mode=(mode)
483
+ * Sets blend mode
484
+ *
485
+ * Ray supports 3 differents blend mode: :add, :multiply, and :alpha (also the
486
+ * default). Blending can also be disabled using :none.
487
+ *
488
+ * @param [Symbol] mode New blend mode
489
+ */
490
+ static
491
+ VALUE ray_drawable_set_blend_mode(VALUE self, VALUE mode) {
492
+ say_blend_mode c_mode = SAY_BLEND_NO;
493
+ if (mode == RAY_SYM("alpha"))
494
+ c_mode = SAY_BLEND_ALPHA;
495
+ else if (mode == RAY_SYM("add"))
496
+ c_mode = SAY_BLEND_ADD;
497
+ else if (mode == RAY_SYM("multiply"))
498
+ c_mode = SAY_BLEND_MULTIPLY;
499
+
500
+ say_drawable_set_blend_mode(ray_rb2drawable(self), c_mode);
501
+ return mode;
502
+ }
503
+
504
+ /* @see blend_mode= */
505
+ static
506
+ VALUE ray_drawable_blend_mode(VALUE self) {
507
+ say_blend_mode mode = say_drawable_get_blend_mode(ray_rb2drawable(self));
508
+
509
+ switch (mode) {
510
+ case SAY_BLEND_NO: return RAY_SYM("none");
511
+ case SAY_BLEND_ALPHA: return RAY_SYM("alpha");
512
+ case SAY_BLEND_ADD: return RAY_SYM("add");
513
+ case SAY_BLEND_MULTIPLY: return RAY_SYM("multiply");
514
+ }
515
+
516
+ return Qnil; /* should never happen */
517
+ }
518
+
519
+ /*
520
+ * Document-class: Ray::Drawable
521
+ *
522
+ * A drawable object represents anything that can be rendered on a target. This
523
+ * class allows to define transformations for any drawable and to set states to
524
+ * create your own drawable.
525
+ *
526
+ * A subclass of Ray::Drawable must implement ``render`` to draw the object,
527
+ * using OpenGL calls:
528
+ *
529
+ * # vertex_id is the index of the first vertex of this object; index_id is
530
+ * # the index of the first index of this object in the element buffer. One
531
+ * # of those variables at least will be ignored in the implementation
532
+ * def render(vertex_id, index_id)
533
+ * # do work
534
+ * end
535
+ *
536
+ * Also, it will often use Ray's system to store vertices and sometimes indices:
537
+ *
538
+ * def fill_vertices
539
+ * # returns an array of vertices
540
+ * end
541
+ *
542
+ * Same with indices:
543
+ *
544
+ * def fill_indices(vertex_id)
545
+ * # returns a Ray::GL::IntArray
546
+ * end
547
+ *
548
+ */
405
549
  void Init_ray_drawable() {
406
550
  ray_cDrawable = rb_define_class_under(ray_mRay, "Drawable", rb_cObject);
407
551
  rb_define_alloc_func(ray_cDrawable, ray_drawable_alloc);
408
552
  rb_define_method(ray_cDrawable, "initialize", ray_drawable_init, -1);
409
553
  rb_define_method(ray_cDrawable, "initialize_copy", ray_drawable_init_copy, 1);
410
554
 
555
+ /* @group Transformations */
411
556
  rb_define_method(ray_cDrawable, "origin", ray_drawable_origin, 0);
412
557
  rb_define_method(ray_cDrawable, "origin=", ray_drawable_set_origin, 1);
413
558
 
@@ -423,10 +568,19 @@ void Init_ray_drawable() {
423
568
  rb_define_method(ray_cDrawable, "angle", ray_drawable_angle, 0);
424
569
  rb_define_method(ray_cDrawable, "angle=", ray_drawable_set_angle, 1);
425
570
 
571
+ rb_define_method(ray_cDrawable, "matrix_proc", ray_drawable_matrix_proc, 0);
572
+ rb_define_method(ray_cDrawable, "matrix_proc=", ray_drawable_set_matrix_proc,
573
+ 1);
574
+
575
+ rb_define_method(ray_cDrawable, "matrix_changed!",
576
+ ray_drawable_matrix_changed, 0);
577
+
426
578
  rb_define_method(ray_cDrawable, "matrix", ray_drawable_matrix, 0);
427
579
  rb_define_method(ray_cDrawable, "matrix=", ray_drawable_set_matrix, 1);
428
580
  rb_define_method(ray_cDrawable, "transform", ray_drawable_transform, 1);
581
+ /* @endgroup */
429
582
 
583
+ /* @group Rendering options */
430
584
  rb_define_method(ray_cDrawable, "shader", ray_drawable_shader, 0);
431
585
  rb_define_method(ray_cDrawable, "shader=", ray_drawable_set_shader, 1);
432
586
 
@@ -443,4 +597,9 @@ void Init_ray_drawable() {
443
597
 
444
598
  rb_define_method(ray_cDrawable, "textured=", ray_drawable_set_textured, 1);
445
599
  rb_define_method(ray_cDrawable, "textured?", ray_drawable_is_textured, 0);
600
+
601
+ rb_define_method(ray_cDrawable, "blend_mode=", ray_drawable_set_blend_mode,
602
+ 1);
603
+ rb_define_method(ray_cDrawable, "blend_mode", ray_drawable_blend_mode, 0);
604
+ /* @endgroup */
446
605
  }