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
@@ -2,8 +2,6 @@
2
2
  #define SAY_BUFFER_H_
3
3
 
4
4
  #include "say_basic_type.h"
5
- #include "say_array.h"
6
- #include "say_table.h"
7
5
 
8
6
  #define SAY_STATIC GL_STATIC_DRAW_ARB
9
7
  #define SAY_STREAM GL_STREAM_DRAW_ARB
@@ -12,21 +10,28 @@
12
10
  typedef struct {
13
11
  size_t vtype;
14
12
 
15
- GLuint vbo;
13
+ GLuint vbo, instance_vbo;
16
14
  GLenum type;
17
15
 
18
- say_table *vaos;
16
+ mo_hash *vaos;
19
17
 
20
- say_array *buffer;
18
+ mo_array buffer, *instance_buffer;
21
19
  } say_buffer;
22
20
 
23
21
  say_buffer *say_buffer_create(size_t vtype, GLenum type, size_t size);
24
22
  void say_buffer_free(say_buffer *buf);
25
23
 
24
+ bool say_buffer_has_instance(say_buffer *buf);
25
+
26
26
  void *say_buffer_get_vertex(say_buffer *buf, size_t id);
27
+ void *say_buffer_get_instance(say_buffer *buf, size_t id);
27
28
 
28
29
  void say_buffer_bind(say_buffer *buf);
30
+ void say_buffer_bind_vbo(say_buffer *buf);
31
+ void say_buffer_bind_instance_vbo(say_buffer *buf);
32
+
29
33
  void say_buffer_unbind();
34
+ void say_buffer_unbind_vbo();
30
35
 
31
36
  void say_buffer_update_part(say_buffer *buf, size_t index, size_t size);
32
37
  void say_buffer_update(say_buffer *buf);
@@ -34,4 +39,14 @@ void say_buffer_update(say_buffer *buf);
34
39
  size_t say_buffer_get_size(say_buffer *buf);
35
40
  void say_buffer_resize(say_buffer *buf, size_t size);
36
41
 
42
+ void say_buffer_update_instance_part(say_buffer *buf, size_t index,
43
+ size_t size);
44
+ void say_buffer_update_instance(say_buffer *buf);
45
+
46
+ size_t say_buffer_get_instance_size(say_buffer *buf);
47
+ void say_buffer_resize_instance(say_buffer *buf, size_t size);
48
+
49
+ GLuint say_buffer_get_vbo(say_buffer *buf);
50
+ GLuint say_buffer_get_instance_vbo(say_buffer *buf);
51
+
37
52
  #endif
@@ -11,7 +11,8 @@ say_buffer_renderer *say_buffer_renderer_create(GLenum type,
11
11
 
12
12
  renderer->buffer = say_buffer_create(vtype, type, 256);
13
13
  renderer->index_buffer = say_index_buffer_create(type, 128);
14
- renderer->drawables = say_array_create(sizeof(say_drawable*), NULL, NULL);
14
+
15
+ mo_array_init(&renderer->drawables, sizeof(say_drawable*));
15
16
 
16
17
  renderer->vtype = vtype;
17
18
 
@@ -23,14 +24,15 @@ say_buffer_renderer *say_buffer_renderer_create(GLenum type,
23
24
 
24
25
  void say_buffer_renderer_free(say_buffer_renderer *renderer) {
25
26
  say_buffer_free(renderer->buffer);
26
- say_array_free(renderer->drawables);
27
+ say_index_buffer_free(renderer->index_buffer);
28
+ mo_array_release(&renderer->drawables);
27
29
  free(renderer);
28
30
  }
29
31
 
30
32
  void say_buffer_renderer_clear(say_buffer_renderer *renderer) {
31
33
  renderer->current_vertex = 0;
32
34
  renderer->current_index = 0;
33
- say_array_resize(renderer->drawables, 0);
35
+ mo_array_resize(&renderer->drawables, 0);
34
36
  }
35
37
 
36
38
  bool say_buffer_renderer_push(say_buffer_renderer *renderer,
@@ -58,7 +60,7 @@ bool say_buffer_renderer_push(say_buffer_renderer *renderer,
58
60
  else if (current_size < index_new_size)
59
61
  say_index_buffer_resize(renderer->index_buffer, current_size * 2);
60
62
 
61
- say_array_push(renderer->drawables, &drawable);
63
+ mo_array_push(&renderer->drawables, &drawable);
62
64
 
63
65
  say_drawable_fill_buffer(drawable,
64
66
  say_buffer_get_vertex(renderer->buffer,
@@ -83,14 +85,15 @@ void say_buffer_renderer_update(say_buffer_renderer *renderer) {
83
85
  void say_buffer_renderer_render(say_buffer_renderer *renderer,
84
86
  say_shader *shader) {
85
87
  say_buffer_bind(renderer->buffer);
88
+ say_index_buffer_bind(renderer->index_buffer);
86
89
 
87
90
  int using_texture = 0;
88
91
  say_shader_set_int_id(shader, SAY_TEXTURE_ENABLED_LOC_ID, 0);
89
92
 
90
93
  size_t current_vertex = 0, current_index = 0;
91
- for (size_t i = 0; i < say_array_get_size(renderer->drawables); i++) {
92
- say_drawable **e = say_array_get(renderer->drawables, i);
93
- say_drawable *drawable = *e;
94
+ for (size_t i = 0; i < renderer->drawables.size; i++) {
95
+ say_drawable *drawable = mo_array_get_as(&renderer->drawables, i,
96
+ say_drawable*);
94
97
 
95
98
  if (!drawable->shader &&
96
99
  using_texture != say_drawable_is_textured(drawable)) {
@@ -8,7 +8,7 @@
8
8
  typedef struct {
9
9
  say_buffer *buffer;
10
10
  say_index_buffer *index_buffer;
11
- say_array *drawables;
11
+ mo_array drawables;
12
12
 
13
13
  size_t vtype;
14
14
 
@@ -13,53 +13,51 @@ typedef struct {
13
13
 
14
14
  typedef struct {
15
15
  say_buffer *buf;
16
- say_array *ranges;
16
+ mo_list *ranges;
17
17
  } say_global_buffer;
18
18
 
19
- static say_array *say_global_buffers = NULL;
19
+ static mo_array *say_global_buffers = NULL;
20
20
 
21
21
  static void say_global_buffer_free(say_global_buffer *buf) {
22
22
  say_buffer_free(buf->buf);
23
- say_array_free(buf->ranges);
23
+ if (buf->ranges) mo_list_free(buf->ranges);
24
24
  }
25
25
 
26
- static say_global_buffer *say_global_buffer_create(say_array *bufs,
26
+ static say_global_buffer *say_global_buffer_create(mo_array *bufs,
27
27
  size_t vtype, size_t size) {
28
28
  say_global_buffer buffer;
29
29
 
30
30
  buffer.buf = say_buffer_create(vtype, SAY_STREAM, size);
31
- buffer.ranges = say_array_create(sizeof(say_range), NULL, NULL);
31
+ buffer.ranges = NULL;
32
32
 
33
- say_array_push(bufs, &buffer);
33
+ mo_array_push(bufs, &buffer);
34
34
 
35
- return say_array_get(bufs, say_array_get_size(bufs) - 1);
35
+ return mo_array_at(bufs, bufs->size - 1);
36
36
  }
37
37
 
38
38
 
39
- static void say_global_buffer_array_alloc(say_array **ary) {
40
- *ary = say_array_create(sizeof(say_global_buffer),
41
- (say_destructor)say_global_buffer_free,
42
- NULL);
39
+ static void say_global_buffer_array_alloc(mo_array *ary) {
40
+ mo_array_init(ary, sizeof(say_global_buffer));
41
+ ary->release = (say_destructor)say_global_buffer_free;
43
42
  }
44
43
 
45
- static void say_global_buffer_array_free(say_array **ary) {
46
- if (*ary)
47
- say_array_free(*ary);
44
+ static void say_global_buffer_array_free(mo_array *ary) {
45
+ mo_array_release(ary);
48
46
  }
49
47
 
50
- static size_t say_global_buffer_add_range_before(say_global_buffer *buf,
51
- size_t before, size_t n) {
52
- say_range tmp = say_make_range(0, n);
53
- say_array_insert(buf->ranges, before, &tmp);
48
+ static size_t say_global_buffer_prepend(say_global_buffer *buf, size_t n) {
49
+ say_range range = say_make_range(0, n);
50
+ buf->ranges = mo_list_prepend(buf->ranges, &range);
51
+ return 0;
52
+ }
54
53
 
55
- say_range *range = say_array_get(buf->ranges, before);
54
+ static size_t say_global_buffer_insert(mo_list *list, size_t n) {
55
+ say_range *previous = mo_list_data_ptr(list, say_range);
56
56
 
57
- if (before != 0) {
58
- say_range *prev = say_array_get(buf->ranges, before - 1);
59
- range->loc = prev->loc + prev->size;
60
- }
57
+ say_range range = say_make_range(previous->loc + previous->size, n);
58
+ mo_list_insert(list, &range);
61
59
 
62
- return range->loc;
60
+ return range.loc;
63
61
  }
64
62
 
65
63
  static size_t say_global_buffer_find(say_global_buffer *buf, size_t n) {
@@ -67,95 +65,92 @@ static size_t say_global_buffer_find(say_global_buffer *buf, size_t n) {
67
65
  if (n > say_buffer_get_size(buf->buf))
68
66
  return SAY_MAX_SIZE;
69
67
 
70
- size_t ary_size = say_array_get_size(buf->ranges);
71
- say_range *first = say_array_get(buf->ranges, 0);
72
-
73
- /* There's room at the begin of the buffer */
74
- if (ary_size == 0 || first->loc >= n) {
75
- return say_global_buffer_add_range_before(buf, 0, n);
68
+ if (!buf->ranges) {
69
+ buf->ranges = mo_list_create(sizeof(say_range));
70
+ say_range *range = mo_list_data_ptr(buf->ranges, say_range);
71
+ *range = say_make_range(0, n);
76
72
  }
77
73
 
78
- say_range *current = first, *next = NULL;
74
+ say_range *first = mo_list_data_ptr(buf->ranges, say_range);
79
75
 
80
- for (size_t i = 0; i < ary_size - 1; i++) {
81
- next = say_array_get(buf->ranges, i + 1);
76
+ /* There's room at the begin of the buffer */
77
+ if (first->loc >= n)
78
+ return say_global_buffer_prepend(buf, 0);
79
+
80
+ mo_list *it = buf->ranges;
81
+ for (; it->next; it = it->next) { /* stop before last element */
82
+ say_range *current = mo_list_data_ptr(it, say_range);
83
+ say_range *next = mo_list_data_ptr(it->next, say_range);
82
84
 
83
85
  size_t begin = current->loc + current->size;
84
86
  size_t end = next->loc;
85
87
 
86
88
  /* There's enough room between those two elements */
87
- if (end - begin >= n) {
88
- return say_global_buffer_add_range_before(buf, i + 1, n);
89
- }
90
-
91
- current = next;
89
+ if (end - begin >= n)
90
+ return say_global_buffer_insert(it, n);
92
91
  }
93
92
 
94
- say_range *last = say_array_get(buf->ranges, ary_size - 1);
93
+ say_range *last = mo_list_data_ptr(it, say_range);
95
94
 
96
95
  /* There's enough room at the end of the buffer */
97
96
  if ((last->loc + last->size + n) < say_buffer_get_size(buf->buf)) {
98
- return say_global_buffer_add_range_before(buf, ary_size, n);
97
+ return say_global_buffer_insert(it, n);
99
98
  }
100
99
 
101
100
  /* Not enough room here */
102
101
  return SAY_MAX_SIZE;
103
102
  }
104
103
 
105
- static void say_global_buffer_delete_at(say_global_buffer *buf, size_t loc) {
104
+ static void say_global_buffer_delete_at(say_global_buffer *buf, size_t loc,
105
+ size_t range_size) {
106
106
  if (!buf)
107
107
  return;
108
108
 
109
- size_t n = 0, size = say_array_get_size(buf->ranges);
110
- for (; n < size; n++) {
111
- say_range *range = say_array_get(buf->ranges, n);
112
- if (range->loc == loc)
113
- break;
114
- }
109
+ for (mo_list *it = buf->ranges; it; it = it->next) {
110
+ say_range *range = mo_list_data_ptr(it, say_range);
111
+ if (range->loc == loc && range->size == range_size) {
112
+ mo_list *next = it->next;
113
+ mo_list_delete(it);
115
114
 
116
- if (n == size)
117
- return; /* Element could not be found */
115
+ if (it == buf->ranges) buf->ranges = next;
118
116
 
119
- say_array_delete(buf->ranges, n);
117
+ return;
118
+ }
119
+ }
120
120
  }
121
121
 
122
122
  static void say_global_buffer_reduce_size(say_global_buffer *buf, size_t loc,
123
- size_t size) {
124
- for (say_range *range = say_array_get(buf->ranges, 0); range;
125
- say_array_next(buf->ranges, (void**)&range)) {
126
- if (range->loc == loc) {
123
+ size_t old_size, size_t size) {
124
+ for (mo_list *it = buf->ranges; it; it = it->next) {
125
+ say_range *range = mo_list_data_ptr(it, say_range);
126
+ if (range->loc == loc && range->size == size) {
127
127
  range->size = size;
128
128
  return;
129
129
  }
130
130
  }
131
131
  }
132
132
 
133
- static size_t say_global_buffer_reserve(size_t vtype, size_t size, size_t *ret_id) {
133
+ static size_t say_global_buffer_reserve(size_t vtype, size_t size,
134
+ size_t *ret_id) {
134
135
  if (!say_global_buffers) {
135
- say_global_buffers = say_array_create(sizeof(say_array*),
136
- (say_destructor)say_global_buffer_array_free,
137
- (say_creator)say_global_buffer_array_alloc);
136
+ say_global_buffers = mo_array_create(sizeof(mo_array));
137
+ say_global_buffers->init = (mo_init)say_global_buffer_array_alloc;
138
+ say_global_buffers->release = (mo_release)say_global_buffer_array_free;
138
139
  }
139
140
 
140
- if (say_array_get_size(say_global_buffers) <= vtype) {
141
- say_array_resize(say_global_buffers, vtype + 1);
141
+ if (say_global_buffers->size <= vtype) {
142
+ mo_array_resize(say_global_buffers, vtype + 1);
142
143
  }
143
144
 
144
- say_array *global_bufs = *(say_array**)say_array_get(say_global_buffers,
145
- vtype);
145
+ mo_array *global_bufs = mo_array_get_ptr(say_global_buffers, vtype, mo_array);
146
146
 
147
- size_t i = 0;
148
- for (say_global_buffer *buf = say_array_get(global_bufs, 0);
149
- buf;
150
- say_array_next(global_bufs, (void**)&buf)) {
151
- size_t res = say_global_buffer_find(buf, size);
147
+ for (size_t i = 0; i < global_bufs->size; i++) {
148
+ size_t res = say_global_buffer_find(mo_array_at(global_bufs, i), size);
152
149
 
153
150
  if (res != SAY_MAX_SIZE) {
154
151
  *ret_id = i;
155
152
  return res;
156
153
  }
157
-
158
- i++;
159
154
  }
160
155
 
161
156
  /* Existing buffers can't store this object, save it somewhere else */
@@ -169,7 +164,7 @@ static size_t say_global_buffer_reserve(size_t vtype, size_t size, size_t *ret_i
169
164
  say_global_buffer *buf = say_global_buffer_create(global_bufs,
170
165
  vtype,
171
166
  buf_size);
172
- *ret_id = say_array_get_size(global_bufs) - 1;
167
+ *ret_id = global_bufs->size - 1;
173
168
  return say_global_buffer_find(buf, size);
174
169
  }
175
170
 
@@ -177,8 +172,7 @@ static say_global_buffer *say_global_buffer_at(size_t vtype, size_t id) {
177
172
  if (!say_global_buffers)
178
173
  return NULL;
179
174
 
180
- return say_array_get(*(say_array**)say_array_get(say_global_buffers, vtype),
181
- id);
175
+ return mo_array_at(mo_array_at(say_global_buffers, vtype), id);
182
176
  }
183
177
 
184
178
  say_buffer_slice *say_buffer_slice_create(size_t vtype, size_t size) {
@@ -191,7 +185,7 @@ say_buffer_slice *say_buffer_slice_create(size_t vtype, size_t size) {
191
185
 
192
186
  void say_buffer_slice_free(say_buffer_slice *slice) {
193
187
  say_global_buffer_delete_at(say_global_buffer_at(slice->vtype, slice->buf_id),
194
- slice->loc);
188
+ slice->loc, slice->size);
195
189
  free(slice);
196
190
  }
197
191
 
@@ -203,14 +197,14 @@ void say_buffer_slice_recreate(say_buffer_slice *slice, size_t size) {
203
197
  if (size > slice->size) {
204
198
  say_global_buffer_delete_at(say_global_buffer_at(slice->vtype,
205
199
  slice->buf_id),
206
- slice->loc);
200
+ slice->loc, slice->size);
207
201
 
208
202
  slice->loc = say_global_buffer_reserve(slice->vtype, size, &slice->buf_id);
209
203
  }
210
204
  else {
211
205
  say_global_buffer_reduce_size(say_global_buffer_at(slice->vtype,
212
206
  slice->buf_id),
213
- slice->loc, size);
207
+ slice->loc, slice->size, size);
214
208
  }
215
209
 
216
210
  slice->size = size;
@@ -241,7 +235,7 @@ void say_buffer_slice_bind(say_buffer_slice *slice) {
241
235
 
242
236
  void say_buffer_slice_clean_up() {
243
237
  if (say_global_buffers) {
244
- say_array_free(say_global_buffers);
238
+ mo_array_free(say_global_buffers);
245
239
  say_global_buffers = NULL;
246
240
  }
247
241
  }
@@ -17,6 +17,8 @@ static say_context *say_shared_context = NULL;
17
17
  static say_thread_variable *say_current_context = NULL;
18
18
  static say_thread_variable *say_ensured_context = NULL;
19
19
 
20
+ static mo_array *say_all_ensured_contexts = NULL;
21
+
20
22
  static void say_context_create_initial();
21
23
  static void say_context_setup(say_context *context);
22
24
  static void say_context_setup_states(say_context *context);
@@ -24,18 +26,36 @@ static void say_context_glew_init();
24
26
 
25
27
  static uint32_t say_context_count = 0;
26
28
 
29
+ say_context_config *say_context_get_config() {
30
+ static say_context_config conf = {
31
+ 24, 0, /* 24 bit depth buffer, no stencil buffer */
32
+ 2, 1, /* Anything older than 3.x doesn't matter */
33
+ false, /* Let user call deprecated features */
34
+ false /* Disable debugging */
35
+ };
36
+
37
+ return &conf;
38
+ }
39
+
40
+ void say_context_free_el(void *context) {
41
+ say_context_free(*(say_context**)context);
42
+ }
43
+
27
44
  say_context *say_context_current() {
28
45
  if (!say_current_context) {
29
- say_current_context = say_thread_variable_create(NULL);
46
+ say_current_context = say_thread_variable_create();
30
47
  }
31
48
 
32
49
  return (say_context*)say_thread_variable_get(say_current_context);
33
50
  }
34
51
 
35
52
  void say_context_ensure() {
36
- if (!say_ensured_context) {
37
- say_ensured_context =
38
- say_thread_variable_create((say_destructor)say_context_free);
53
+ if (!say_ensured_context)
54
+ say_ensured_context = say_thread_variable_create();
55
+
56
+ if (!say_all_ensured_contexts) {
57
+ say_all_ensured_contexts = mo_array_create(sizeof(say_context*));
58
+ say_all_ensured_contexts->release = say_context_free_el;
39
59
  }
40
60
 
41
61
  if (!say_context_current()) {
@@ -44,6 +64,7 @@ void say_context_ensure() {
44
64
  if (!context) {
45
65
  context = say_context_create();
46
66
  say_thread_variable_set(say_ensured_context, context);
67
+ mo_array_push(say_all_ensured_contexts, &context);
47
68
  }
48
69
 
49
70
  say_context_make_current(context);
@@ -103,19 +124,14 @@ static void say_context_create_initial() {
103
124
  say_shared_context = (say_context*)malloc(sizeof(say_context));
104
125
 
105
126
  say_context_setup(say_shared_context);
106
- say_context_setup_states(say_shared_context);
107
-
108
127
  say_context_make_current(say_shared_context);
109
128
  say_context_glew_init();
110
129
 
111
130
  /* Identify GLSL version to be used */
112
131
  const GLubyte *str = glGetString(GL_SHADING_LANGUAGE_VERSION);
113
-
114
- /* if GLSL 1.40 and GL_EXT_gpu_shader4 are supported */
115
- if (__GLEW_EXT_gpu_shader4) {
116
- if (str && (str[0] > (GLubyte)'1' || str[2] >= (GLubyte)'4')) {
117
- say_shader_enable_new_glsl();
118
- }
132
+ if (str && (str[0] > (GLubyte)'1' || str[2] >= (GLubyte)'3') &&
133
+ glBindFragDataLocation) {
134
+ say_shader_enable_new_glsl();
119
135
  }
120
136
  }
121
137
 
@@ -141,23 +157,94 @@ static void say_context_setup_states(say_context *context) {
141
157
  }
142
158
 
143
159
  void say_context_clean_up() {
144
- if (say_current_context)
145
- say_thread_variable_free(say_current_context);
160
+ if (say_all_ensured_contexts)
161
+ mo_array_free(say_all_ensured_contexts);
146
162
 
147
163
  if (say_ensured_context)
148
164
  say_thread_variable_free(say_ensured_context);
149
165
 
150
- say_current_context = NULL;
151
- say_ensured_context = NULL;
166
+ if (say_current_context)
167
+ say_thread_variable_free(say_current_context);
168
+
169
+ say_current_context = NULL;
170
+ say_ensured_context = NULL;
171
+ say_all_ensured_contexts = NULL;
152
172
  }
153
173
 
154
174
  static void say_context_glew_init() {
175
+ /*
176
+ * Fetch any proc we can.
177
+ */
178
+ glewExperimental = true;
155
179
  glewInit();
156
180
 
157
- if (__GLEW_APPLE_vertex_array_object &&
158
- !__GLEW_ARB_vertex_array_object) {
159
- glBindVertexArray = glBindVertexArrayAPPLE;
160
- glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)glGenVertexArraysAPPLE;
161
- glDeleteVertexArrays = glDeleteVertexArraysAPPLE;
162
- }
181
+ /**
182
+ * Load needed extensions.
183
+ *
184
+ * We need to replace pointers for code to work both using OpenGL core
185
+ * features and extensions.
186
+ */
187
+
188
+ #define replace(old, new) \
189
+ if (!new && old) \
190
+ new = old;
191
+
192
+ /* Shaders */
193
+ replace(glCreateShaderObjectARB, glCreateShader);
194
+ replace(glShaderSourceARB, glShaderSource);
195
+ replace(glCompileShaderARB, glCompileShader);
196
+ replace(glGetObjectParameterivARB, glGetShaderiv);
197
+ replace(glGetObjectParameterivARB, glGetProgramiv);
198
+ replace(glGetInfoLogARB, glGetShaderInfoLog);
199
+ replace(glGetInfoLogARB, glGetProgramInfoLog);
200
+ replace(glGetUniformLocationARB, glGetUniformLocation);
201
+ replace(glCreateProgramObjectARB, glCreateProgram)
202
+ replace(glAttachObjectARB, glAttachShader);
203
+ replace(glDetachObjectARB, glDetachShader);
204
+ replace(glBindAttribLocationARB, glBindAttribLocation);
205
+ replace(glBindFragDataLocationEXT, glBindFragDataLocation);
206
+ replace(glLinkProgramARB, glLinkProgram);
207
+ replace(glUseProgramObjectARB, glUseProgram);
208
+ replace(glDeleteObjectARB, glDeleteShader);
209
+ replace(glDeleteObjectARB, glDeleteProgram);
210
+ replace(glUniform1iARB, glUniform1i);
211
+ replace(glUniform1fARB, glUniform1f);
212
+ replace(glUniform2fARB, glUniform2f);
213
+ replace(glUniform3fARB, glUniform3f);
214
+ replace(glUniform1fvARB, glUniform1fv);
215
+ replace(glUniform2fvARB, glUniform2fv);
216
+ replace(glUniform3fvARB, glUniform3fv);
217
+ replace(glUniform4fvARB, glUniform4fv);
218
+ replace(glUniformMatrix4fvARB, glUniformMatrix4fv);
219
+
220
+ /* Buffers */
221
+ replace(glGenBuffersARB, glGenBuffers);
222
+ replace(glDeleteBuffersARB, glDeleteBuffersARB);
223
+ replace(glBindBufferARB, glBindBuffer);
224
+ replace(glBufferDataARB, glBufferData);
225
+ replace(glBufferSubDataARB, glBufferSubData);
226
+ replace(glGetBufferSubDataARB, glGetBufferSubData);
227
+
228
+ /* Vertex attribs */
229
+ replace(glVertexAttribPointerARB, glVertexAttribPointer);
230
+ replace(glEnableVertexAttribArrayARB, glEnableVertexAttribArray);
231
+ replace(glVertexAttribDivisorARB, glVertexAttribDivisor);
232
+ replace(glGetVertexAttribivARB, glGetVertexAttribiv);
233
+ replace(glDisableVertexAttribArrayARB, glDisableVertexAttribArray);
234
+
235
+ /* Framebuffer objects */
236
+ replace(glGenFramebuffersEXT, glGenFramebuffers);
237
+ replace(glDeleteFramebuffersEXT, glDeleteFramebuffers);
238
+ replace(glBindFramebufferEXT, glBindFramebuffer);
239
+ replace(glFramebufferTexture2DEXT, glFramebufferTexture2D);
240
+ replace(glFramebufferRenderbufferEXT, glFramebufferRenderbuffer);
241
+
242
+ /* Renderbuffer objects */
243
+ replace(glGenRenderbuffersEXT, glGenRenderbuffers);
244
+ replace(glDeleteRenderbuffersEXT, glDeleteRenderbuffers);
245
+ replace(glBindRenderbufferEXT, glBindRenderbuffer);
246
+ replace(glRenderbufferStorageEXT, glRenderbufferStorage);
247
+
248
+ /* Mipmaps */
249
+ replace(glGenerateMipmapEXT, glGenerateMipmap);
163
250
  }