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
@@ -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
  }