ray 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
  }