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
@@ -0,0 +1,189 @@
1
+ #ifndef MY_OWN_HEADER_GUARD
2
+ #define MY_OWN_HEADER_GUARD 1
3
+
4
+ /**
5
+ * My Own utilities.
6
+ * (Depending on My Own mood, may mean "Mon_Ouie's utilities")
7
+ *
8
+ * Includes the data stuctures that I usually need when programming in C.
9
+ */
10
+
11
+ #include <stdlib.h>
12
+ #include <stdint.h>
13
+ #include <stdbool.h>
14
+ #include <assert.h>
15
+ #include <string.h>
16
+ #include <stdio.h>
17
+
18
+ /**
19
+ * Function pointer types
20
+ */
21
+
22
+ typedef void (*mo_init)(void *dst);
23
+ typedef void (*mo_release)(void *dst);
24
+ typedef void (*mo_copy)(void *dst, void *src);
25
+ typedef int (*mo_cmp)(const void *a, const void *b);
26
+ typedef int (*mo_hash_func)(void *obj);
27
+
28
+ /**
29
+ * Dynamic array.
30
+ */
31
+
32
+ typedef struct mo_array {
33
+ void *buffer;
34
+ size_t size;
35
+ size_t capa;
36
+ size_t el_size;
37
+
38
+ mo_init init;
39
+ mo_release release;
40
+ mo_copy copy;
41
+ } mo_array;
42
+
43
+ mo_array *mo_array_create(size_t el_size);
44
+ void mo_array_free(mo_array *ary);
45
+
46
+ void mo_array_init(mo_array *ary, size_t el_size);
47
+ void mo_array_release(mo_array *ary);
48
+
49
+ void *mo_array_quick_at(mo_array *ary, size_t i);
50
+ void *mo_array_at(mo_array *ary, size_t i);
51
+
52
+ #define mo_array_get_ptr(ary, i, type) ( (type*)mo_array_at(ary, i))
53
+ #define mo_array_get_as(ary, i, type) (*(type*)mo_array_at(ary, i))
54
+
55
+ void *mo_array_begin(mo_array *ary);
56
+ void *mo_array_end(mo_array *ary);
57
+
58
+ void mo_array_next(mo_array *ary, void **ptr);
59
+
60
+ void mo_array_set(mo_array *ary, size_t i, void *obj);
61
+
62
+ void mo_array_insert(mo_array *ary, size_t i, void *obj);
63
+ void mo_array_push(mo_array *ary, void *obj);
64
+ void mo_array_delete(mo_array *ary, size_t i);
65
+
66
+ mo_array mo_array_dup(mo_array *ary);
67
+ void mo_array_copy(mo_array *dst, mo_array *src);
68
+
69
+ mo_array *mo_array_qsort(mo_array *ary, mo_cmp cmp);
70
+
71
+ void mo_array_resize(mo_array *ary, size_t size);
72
+ void mo_array_reserve(mo_array *ary, size_t size);
73
+ void mo_array_shrink(mo_array *ary);
74
+
75
+ /**
76
+ * Doubly linked list.
77
+ */
78
+
79
+ typedef struct mo_list {
80
+ struct mo_list *prev, *next;
81
+
82
+ mo_release release;
83
+ mo_copy copy;
84
+
85
+ size_t el_size;
86
+ uint8_t data[];
87
+ } mo_list;
88
+
89
+ mo_list *mo_list_create(size_t el_size);
90
+ void mo_list_free(mo_list *list);
91
+
92
+ mo_list *mo_list_prepend(mo_list *list, void *data);
93
+ mo_list *mo_list_insert(mo_list *list, void *data);
94
+ mo_list *mo_list_delete(mo_list *list);
95
+
96
+ void mo_list_set(mo_list *list, void *data);
97
+
98
+ #define mo_list_data_ptr(list, type) ( (type*)list->data)
99
+ #define mo_list_data_as(list, type) (*(type*)list->data)
100
+
101
+ /**
102
+ * Hash table.
103
+ */
104
+
105
+ typedef struct mo_hash {
106
+ mo_array buffer;
107
+
108
+ mo_release release;
109
+ mo_copy copy;
110
+
111
+ mo_release key_release;
112
+ mo_copy key_copy;
113
+ mo_cmp key_cmp;
114
+
115
+ size_t size;
116
+
117
+ size_t el_size;
118
+ size_t key_size;
119
+
120
+ mo_hash_func hash_of;
121
+ } mo_hash;
122
+
123
+ typedef struct mo_hash_it {
124
+ mo_hash *hash;
125
+ mo_list *list;
126
+ size_t id;
127
+ } mo_hash_it;
128
+
129
+ int mo_hash_of_pointer(void *ptr);
130
+ int mo_hash_pointer_cmp(const void *a, const void *b);
131
+
132
+ int mo_hash_of_u32(void *ptr);
133
+ int mo_hash_u32_cmp(const void *a, const void *b);
134
+
135
+ int mo_hash_of_size(void *ptr);
136
+ int mo_hash_size_cmp(const void *a, const void *b);
137
+
138
+ mo_hash *mo_hash_create(size_t key_size, size_t el_size);
139
+ void mo_hash_free(mo_hash *hash);
140
+
141
+ bool mo_hash_has_key(mo_hash *hash, void *key);
142
+
143
+ void *mo_hash_get(mo_hash *hash, void *key);
144
+ void mo_hash_set(mo_hash *hash, void *key, void *data);
145
+ void mo_hash_del(mo_hash *hash, void *key);
146
+
147
+ #define mo_hash_get_ptr(hash, key, type) ( (type*)mo_hash_get(hash, key))
148
+ #define mo_hash_get_as(hash, key, type) (*(type*)mo_hash_get(hash, key))
149
+
150
+ mo_hash_it mo_hash_begin(mo_hash *hash);
151
+
152
+ bool mo_hash_it_is_end(mo_hash_it *it);
153
+
154
+ void *mo_hash_it_key(mo_hash_it *it);
155
+ void *mo_hash_it_val(mo_hash_it *it);
156
+
157
+ #define mo_hash_it_key_ptr(it, type) ( (type*)mo_hash_it_key(it))
158
+ #define mo_hash_it_key_as(it, type) (*(type*)mo_hash_it_key(it))
159
+
160
+ #define mo_hash_it_val_ptr(it, type) ( (type*)mo_hash_it_val(it))
161
+ #define mo_hash_it_val_as(it, type) (*(type*)mo_hash_it_val(it))
162
+
163
+ void mo_hash_it_next(mo_hash_it *it);
164
+
165
+ /**
166
+ * Set (macros atop a hash table).
167
+ */
168
+
169
+ typedef mo_hash mo_set;
170
+ typedef mo_hash_it mo_set_it;
171
+
172
+ #define mo_set_create(size) mo_hash_create(size, 0)
173
+ #define mo_set_free(set) mo_hash_delete(set)
174
+
175
+ #define mo_set_includes(set) mo_hash_has_key(set)
176
+
177
+ #define mo_set_add(set, el) mo_hash_set(set, el, NULL)
178
+ #define mo_set_del(set, el) mo_hash_del(set, el)
179
+
180
+ #define mo_set_begin(set) mo_hash_begin(set)
181
+
182
+ #define mo_set_it_is_end(it) mo_hash_it_is_end(it)
183
+ #define mo_set_it_val(it) mo_hash_it_key(it)
184
+ #define mo_set_it_next(it) mo_hash_it_next(it)
185
+
186
+ #define mo_set_it_val_ptr(it, type) mo_hash_it_key_ptr(it, type)
187
+ #define mo_set_it_val_as(it, type) mo_hash_it_key_as(it, type)
188
+
189
+ #endif /* MY OWN HEADER'S GUARD! */
@@ -21,9 +21,9 @@ VALUE ray_music_alloc(VALUE self) {
21
21
  }
22
22
 
23
23
  /*
24
- @overload open(filename)
25
- @param [String] filename Name of the file containing the music to load.
26
- */
24
+ * @overload open(filename)
25
+ * @param [String] filename Name of the file containing the music to load.
26
+ */
27
27
  static
28
28
  VALUE ray_music_open(VALUE self, VALUE arg) {
29
29
  say_music *music = ray_rb2music(self);
@@ -48,10 +48,10 @@ VALUE ray_music_set_looping(VALUE self, VALUE val) {
48
48
  }
49
49
 
50
50
  /*
51
- @overload seek(time)
52
- Seeks to a specific time in the music.
53
- @param [Float] time Time in seconds
54
- */
51
+ * @overload seek(time)
52
+ * Seeks to a specific time in the music
53
+ * @param [Float] time Time in seconds
54
+ */
55
55
  static
56
56
  VALUE ray_music_seek(VALUE self, VALUE time) {
57
57
  say_music_seek(ray_rb2music(self), NUM2DBL(time));
@@ -64,7 +64,8 @@ VALUE ray_music_time(VALUE self) {
64
64
  return rb_float_new(say_music_get_time(ray_rb2music(self)));
65
65
  }
66
66
 
67
- /* @return [Float] Duration of the music. 0 when no buffer is attached to the
67
+ /*
68
+ * @return [Float] Duration of the music. 0 when no buffer is attached to the
68
69
  * music.
69
70
  */
70
71
  static
@@ -0,0 +1,349 @@
1
+ #include "ray.h"
2
+
3
+ VALUE ray_cPixelBus = Qnil;
4
+
5
+ say_pixel_bus *ray_rb2pixel_bus(VALUE obj) {
6
+ if (!rb_obj_is_kind_of(obj, rb_path2class("Ray::PixelBus"))) {
7
+ rb_raise(rb_eTypeError, "can't convert %s into Ray::PixelBus",
8
+ RAY_OBJ_CLASSNAME(obj));
9
+ }
10
+
11
+ say_pixel_bus **ptr = NULL;
12
+ Data_Get_Struct(obj, say_pixel_bus*, ptr);
13
+
14
+ if (!*ptr)
15
+ rb_raise(rb_eRuntimeError, "trying to use uninitialized pixel bus");
16
+
17
+ return *ptr;
18
+ }
19
+
20
+ static
21
+ void ray_pixel_bus_free(say_pixel_bus **ptr) {
22
+ if (*ptr) say_pixel_bus_free(*ptr);
23
+ }
24
+
25
+ static
26
+ VALUE ray_pixel_bus_alloc(VALUE self) {
27
+ say_pixel_bus **obj = malloc(sizeof(say_pixel_bus*));
28
+ *obj = NULL;
29
+
30
+ return Data_Wrap_Struct(self, NULL, ray_pixel_bus_free, obj);
31
+ }
32
+
33
+ /*
34
+ * @overload initialize(type = :stream)
35
+ * @param type (see Ray::BufferRenderer#initialize)
36
+ */
37
+ static
38
+ VALUE ray_pixel_bus_init(int argc, VALUE *argv, VALUE self) {
39
+ if (!say_pixel_bus_is_available())
40
+ rb_raise(rb_eRuntimeError, "pixel buses aren't available on this platform");
41
+
42
+ GLenum mode = SAY_STREAM;
43
+
44
+ VALUE rb_mode = Qnil;
45
+ rb_scan_args(argc, argv, "01", &rb_mode);
46
+
47
+ if (!NIL_P(rb_mode)) mode = ray_buf_type(rb_mode);
48
+
49
+ say_pixel_bus **ptr = NULL;
50
+ Data_Get_Struct(self, say_pixel_bus*, ptr);
51
+
52
+ *ptr = say_pixel_bus_create(mode);
53
+
54
+ return self;
55
+ }
56
+
57
+ /*
58
+ * @return [Boolean] True if pixel buses are available on this platform
59
+ */
60
+ static
61
+ VALUE ray_pixel_bus_available(VALUE self) {
62
+ return say_pixel_bus_is_available() ? Qtrue : Qfalse;
63
+ }
64
+
65
+ /*
66
+ * @return [Integer] The capacity of the pixel bus, in pixels
67
+ */
68
+ static
69
+ VALUE ray_pixel_bus_size(VALUE self) {
70
+ return ULONG2NUM(say_pixel_bus_get_size(ray_rb2pixel_bus(self)));
71
+ }
72
+
73
+ /*
74
+ * @overload resize(new_size)
75
+ * Changes the capacity of the buffer
76
+ *
77
+ * This method needs to copy the buffers content onto client memory, and is
78
+ * thus signinficantly slower than {#resize!}. It should not be called if the
79
+ * current content of the buffer doesn't need to be read anymore.
80
+ *
81
+ * @param [Integer] new_size New capacity of the buffer
82
+ * @see PixelBus#resize!
83
+ */
84
+ static
85
+ VALUE ray_pixel_bus_resize(VALUE self, VALUE size) {
86
+ say_pixel_bus_resize(ray_rb2pixel_bus(self), NUM2ULONG(size));
87
+ return self;
88
+ }
89
+
90
+ /*
91
+ * @overload resize!(new_size)
92
+ * Changes the capacity of the buffer without preserving content
93
+ *
94
+ * This method allows to quickly resize the buffer used by the pixel bus. The
95
+ * content of the buffer is however undefined after this call.
96
+ *
97
+ * @param new_size (see #resize)
98
+ * @see PixelBus#resize
99
+ */
100
+ static
101
+ VALUE ray_pixel_bus_resize_fast(VALUE self, VALUE size) {
102
+ say_pixel_bus_resize_fast(ray_rb2pixel_bus(self), NUM2ULONG(size));
103
+ return self;
104
+ }
105
+
106
+ /*
107
+ * @overload pull(object, opts = {})
108
+ * Pulls data from an object
109
+ *
110
+ * This method reads a rectangle from an image on a target and stores it in
111
+ * the buffer, at a given offset. A rect can optionally be specified for
112
+ * targets. Otherwise, the whole object will be copied.
113
+ *
114
+ * @param [Ray::Image, Ray::Target] object Object to read pixels from
115
+ * @option opts [Integer] :offset (0) Offset from the buffer
116
+ * @option opts [Ray::Rect, nil] :rect Rect of pixels to read for targets
117
+ *
118
+ * @raise [RangeError] If this method attempts to write outside of the buffer
119
+ * boundaries.
120
+ *
121
+ * @return [Integer] Offset of the last read element, plus one.
122
+ */
123
+ static
124
+ VALUE ray_pixel_bus_pull(int argc, VALUE *argv, VALUE self) {
125
+ say_pixel_bus *bus = ray_rb2pixel_bus(self);
126
+
127
+ VALUE object, opts = Qnil;
128
+ rb_scan_args(argc, argv, "11", &object, &opts);
129
+
130
+ say_rect rect = say_make_rect(0, 0, 0, 0);
131
+ size_t offset = 0;
132
+
133
+ say_target *target = NULL;
134
+ say_image *image = NULL;
135
+
136
+ if (RAY_IS_A(object, rb_path2class("Ray::Target")))
137
+ target = ray_rb2target(object);
138
+ else
139
+ image = ray_rb2image(object);
140
+
141
+ say_vector2 size;
142
+
143
+ if (target)
144
+ size = say_target_get_size(target);
145
+ else
146
+ size = say_image_get_size(image);
147
+
148
+ if (!NIL_P(opts)) {
149
+ if (!RAY_IS_A(opts, rb_cHash)) {
150
+ rb_raise(rb_eTypeError, "can't convert %s into Hash",
151
+ RAY_OBJ_CLASSNAME(opts));
152
+ }
153
+
154
+ VALUE rb_rect = rb_hash_aref(opts, RAY_SYM("rect"));
155
+ VALUE rb_offset = rb_hash_aref(opts, RAY_SYM("offset"));
156
+
157
+ if (target) {
158
+ if (!NIL_P(rb_rect))
159
+ rect = ray_convert_to_rect(rb_rect);
160
+ else
161
+ rect = say_make_rect(0, 0, size.x, size.y);
162
+ }
163
+
164
+ if (!NIL_P(rb_offset))
165
+ offset = NUM2ULONG(rb_offset);
166
+ }
167
+ else if (target) {
168
+ say_vector2 size = say_target_get_size(target);
169
+ rect = say_make_rect(0, 0, size.x, size.y);
170
+ }
171
+
172
+ size_t ret = offset + (size_t)size.x * (size_t)size.y;
173
+ if (ret > say_pixel_bus_get_size(bus))
174
+ rb_raise(rb_eRangeError, "trying to write outside of buffer boundaries");
175
+
176
+ if (target) {
177
+ say_pixel_bus_pull_target(bus, target, offset,
178
+ rect.x, rect.y, rect.w, rect.h);
179
+ }
180
+ else {
181
+ say_pixel_bus_pull_image(bus, image, offset);
182
+ }
183
+
184
+ return ULONG2NUM(ret);
185
+ }
186
+
187
+ /*
188
+ * @overload push(image, opts = {})
189
+ * Pushes data from the buffer onto an image
190
+ *
191
+ * This method reads pixels from the buffer at a given offset, and copies them
192
+ * onto an image. A rect of pixels that must be replaced can be
193
+ * specifed. Otherwise, the whole texture will be replaced.
194
+ *
195
+ * @param [Ray::Image] image Image to copy the rect to
196
+ * @option opts :offset (see #pull)
197
+ * @option opts [Ray::Rect] :rect Rect of pixels to replace in the image
198
+ *
199
+ * @return [Ray::PixelBus] self
200
+ *
201
+ * @raise [RangeError] If this method tries to read pixels outside of the
202
+ * buffer boundaries or to write oustide of the image boundaries.
203
+ */
204
+ static
205
+ VALUE ray_pixel_bus_push(int argc, VALUE *argv, VALUE self) {
206
+ say_pixel_bus *bus = ray_rb2pixel_bus(self);
207
+
208
+ VALUE object, opts = Qnil;
209
+ rb_scan_args(argc, argv, "11", &object, &opts);
210
+
211
+ say_image *image = ray_rb2image(object);
212
+
213
+ say_vector2 size = say_image_get_size(image);
214
+
215
+ size_t offset = 0;
216
+ say_rect rect = say_make_rect(0, 0, size.x, size.y);
217
+
218
+ if (!NIL_P(opts)) {
219
+ if (!RAY_IS_A(opts, rb_cHash)) {
220
+ rb_raise(rb_eTypeError, "can't convert %s into Hash",
221
+ RAY_OBJ_CLASSNAME(opts));
222
+ }
223
+
224
+ VALUE rb_rect = rb_hash_aref(opts, RAY_SYM("rect"));
225
+ VALUE rb_offset = rb_hash_aref(opts, RAY_SYM("offset"));
226
+
227
+ if (!NIL_P(rb_rect))
228
+ rect = ray_convert_to_rect(rb_rect);
229
+
230
+ if (!NIL_P(rb_offset))
231
+ offset = NUM2ULONG(rb_offset);
232
+ }
233
+
234
+ size_t ret = offset + ((size_t)rect.w * (size_t)rect.h);
235
+ if (ret > say_pixel_bus_get_size(bus))
236
+ rb_raise(rb_eRangeError, "trying to read outside of pixel bus boundaries");
237
+
238
+ if (rect.x + rect.w > size.x || rect.y + rect.h > size.y)
239
+ rb_raise(rb_eRangeError, "trying to write outsied of image boundaries");
240
+
241
+ say_pixel_bus_push_image(bus, image, offset, rect.x, rect.y, rect.w, rect.h);
242
+ return self;
243
+ }
244
+
245
+ /*
246
+ * Binds the pixel bus for packing and unpacking
247
+ */
248
+ static
249
+ VALUE ray_pixel_bus_bind(VALUE self) {
250
+ say_pixel_bus_bind(ray_rb2pixel_bus(self));
251
+ return self;
252
+ }
253
+
254
+ /*
255
+ * Binds the pixel bus for packing
256
+ */
257
+ static
258
+ VALUE ray_pixel_bus_bind_pack(VALUE self) {
259
+ say_pixel_bus_bind_pack(ray_rb2pixel_bus(self));
260
+ return self;
261
+ }
262
+
263
+ /*
264
+ * Binds the pixel bus for unpacking
265
+ */
266
+ static
267
+ VALUE ray_pixel_bus_bind_unpack(VALUE self) {
268
+ say_pixel_bus_bind_unpack(ray_rb2pixel_bus(self));
269
+ return self;
270
+ }
271
+
272
+ /*
273
+ * Unbinds any pixel bus bound for either packing or unpacking
274
+ */
275
+ static
276
+ VALUE ray_pixel_bus_unbind(VALUE self) {
277
+ say_pixel_bus_unbind();
278
+ return Qnil;
279
+ }
280
+
281
+ /*
282
+ * Unbinds any pixel bus bound for packing
283
+ */
284
+ static
285
+ VALUE ray_pixel_bus_unbind_pack(VALUE self) {
286
+ say_pixel_bus_unbind_pack();
287
+ return Qnil;
288
+ }
289
+
290
+ /*
291
+ * Unbinds any pixel bus bound for unpacking
292
+ */
293
+ static
294
+ VALUE ray_pixel_bus_unbind_unpack(VALUE self) {
295
+ say_pixel_bus_unbind_unpack();
296
+ return Qnil;
297
+ }
298
+
299
+ /*
300
+ * @return [Integer] The identifier of the OpenGL buffer used by the PixelBus.
301
+ */
302
+ static
303
+ VALUE ray_pixel_bus_pbo(VALUE self) {
304
+ return ULONG2NUM(say_pixel_bus_get_pbo(ray_rb2pixel_bus(self)));
305
+ }
306
+
307
+ /*
308
+ * Document-class: Ray::PixelBus
309
+ *
310
+ * Pixel buses are a way to copy pixels from a target or an image onto an image
311
+ * without having to copy them to client memory, and possibly
312
+ * asynchronously. They may unfortunately not be available on some platforms.
313
+ *
314
+ * Notice that pixels are stored from bottom to top in the buffer. You may have
315
+ * to rely on this when computing offsets manually.
316
+ */
317
+ void Init_ray_pixel_bus() {
318
+ ray_cPixelBus = rb_define_class_under(ray_mRay, "PixelBus", rb_cObject);
319
+
320
+ rb_define_alloc_func(ray_cPixelBus, ray_pixel_bus_alloc);
321
+ rb_define_method(ray_cPixelBus, "initialize", ray_pixel_bus_init, -1);
322
+
323
+ rb_define_singleton_method(ray_cPixelBus, "available?",
324
+ ray_pixel_bus_available, 0);
325
+
326
+ /* @group Manipulating buffer size */
327
+ rb_define_method(ray_cPixelBus, "size", ray_pixel_bus_size, 0);
328
+ rb_define_method(ray_cPixelBus, "resize", ray_pixel_bus_resize, 1);
329
+ rb_define_method(ray_cPixelBus, "resize!", ray_pixel_bus_resize_fast, 1);
330
+ /* @endgroup */
331
+
332
+ /* @group Copying data */
333
+ rb_define_method(ray_cPixelBus, "pull", ray_pixel_bus_pull, -1);
334
+ rb_define_method(ray_cPixelBus, "push", ray_pixel_bus_push, -1);
335
+ /* @endgroup */
336
+
337
+ /* @group OpenGL access */
338
+ rb_define_method(ray_cPixelBus, "bind", ray_pixel_bus_bind, 0);
339
+ rb_define_method(ray_cPixelBus, "bind_pack", ray_pixel_bus_bind_pack, 0);
340
+ rb_define_method(ray_cPixelBus, "bind_unpack", ray_pixel_bus_bind_unpack, 0);
341
+ rb_define_method(ray_cPixelBus, "pbo", ray_pixel_bus_pbo, 0);
342
+
343
+ rb_define_singleton_method(ray_cPixelBus, "unbind", ray_pixel_bus_unbind, 0);
344
+ rb_define_singleton_method(ray_cPixelBus, "unbind_pack",
345
+ ray_pixel_bus_unbind_pack, 0);
346
+ rb_define_singleton_method(ray_cPixelBus, "unbind_unpack",
347
+ ray_pixel_bus_unbind_unpack, 0);
348
+ /* @endgroup */
349
+ }