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
@@ -1,9 +1,6 @@
1
1
  #ifndef SAY_FONT_H_
2
2
  #define SAY_FONT_H_
3
3
 
4
- #include "say_table.h"
5
- #include "say_array.h"
6
-
7
4
  #include "say_image.h"
8
5
 
9
6
  typedef struct {
@@ -16,8 +13,8 @@ typedef struct {
16
13
  } say_font_row;
17
14
 
18
15
  typedef struct {
19
- say_table *glyphs;
20
- say_array *rows;
16
+ mo_hash *glyphs;
17
+ mo_array rows;
21
18
 
22
19
  say_image *image;
23
20
 
@@ -28,7 +25,7 @@ typedef struct {
28
25
  FT_Library library;
29
26
  FT_Face face;
30
27
 
31
- say_table *pages;
28
+ mo_hash *pages;
32
29
  } say_font;
33
30
 
34
31
  say_font *say_font_create();
@@ -0,0 +1,35 @@
1
+ /*
2
+ * Code stolen from GLEW, to do what GLEW should be doing.
3
+ */
4
+ #include "say.h"
5
+
6
+ #ifdef SAY_WIN
7
+ void *say_get_proc(const char *name) {
8
+ return (void*)wglGetProcAddress((LPCSTR)name);
9
+ }
10
+ #else
11
+ # ifdef SAY_OSX
12
+
13
+ #include <dlfcn.h>
14
+ void *say_get_proc(const char *name) {
15
+ static void *handle = NULL;
16
+ if (!handle) {
17
+ handle = dlopen("/System/Library/Frameworks/OpenGL.framework/"
18
+ "Versions/Current/OpenGL", RTLD_LAZY);
19
+ }
20
+
21
+ /* prepend a '_' for the Unix C symbol mangling convention */
22
+ char *symbol_name = malloc(strlen(name) + 2);
23
+ strcpy(symbol_name + 1, name);
24
+ symbol_name[0] = '_';
25
+
26
+ void *ptr = dlsym(handle, symbol_name);
27
+ free(symbol_name);
28
+ return ptr;
29
+ }
30
+ # else
31
+ void *say_get_proc(const char *name) {
32
+ return (void*)glXGetProcAddress((GLubyte*)name);
33
+ }
34
+ # endif
35
+ #endif
@@ -25,6 +25,19 @@ static void say_texture_will_delete(GLuint texture) {
25
25
  say_current_texture = 0;
26
26
  }
27
27
 
28
+ static void say_image_update_buffer(say_image *img) {
29
+ if (img->buffer_updated)
30
+ return;
31
+
32
+ say_texture_make_current(img->texture);
33
+ say_pixel_bus_unbind_pack();
34
+ glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE,
35
+ img->pixels);
36
+
37
+ img->buffer_updated = true;
38
+ img->texture_updated = true;
39
+ }
40
+
28
41
  say_image *say_image_create() {
29
42
  say_context_ensure();
30
43
 
@@ -34,13 +47,14 @@ say_image *say_image_create() {
34
47
  glGenTextures(1, &(img->texture));
35
48
 
36
49
  img->pixels = NULL;
37
- img->texture_updated = 1;
50
+ img->texture_updated = true;
51
+ img->buffer_updated = true;
38
52
 
39
53
  img->width = 0;
40
54
  img->height = 0;
41
55
 
42
- img->smooth = 1;
43
- say_image_set_smooth(img, 0);
56
+ img->smooth = true;
57
+ say_image_set_smooth(img, false);
44
58
 
45
59
  return img;
46
60
  }
@@ -57,12 +71,29 @@ void say_image_free(say_image *img) {
57
71
  free(img);
58
72
  }
59
73
 
60
- bool say_image_load_raw(say_image *img, size_t width, size_t height,
61
- say_color *pixels) {
62
- if (!say_image_create_with_size(img, width, height))
74
+ bool say_image_load_raw(say_image *img, size_t w, size_t h, say_color *pixels) {
75
+ if (!say_image_create_with_size(img, w, h))
63
76
  return false;
64
77
 
65
- memcpy(img->pixels, pixels, sizeof(say_color) * width * height);
78
+ img->texture_updated = false;
79
+
80
+ memcpy(img->pixels, pixels, sizeof(say_color) * w * h);
81
+
82
+ /*
83
+ * Vertical flip to fit OpenGL convention.
84
+ */
85
+ say_flip_color_buffer(img->pixels, w, h);
86
+
87
+ return true;
88
+ }
89
+
90
+ bool say_image_load_flipped_raw(say_image *img, size_t w, size_t h,
91
+ say_color *pixels) {
92
+ if (!say_image_create_with_size(img, w, h))
93
+ return false;
94
+
95
+ img->texture_updated = false;
96
+ memcpy(img->pixels, pixels, sizeof(say_color) * w * h);
66
97
  return true;
67
98
  }
68
99
 
@@ -104,9 +135,11 @@ bool say_image_create_with_size(say_image *img, size_t w, size_t h) {
104
135
 
105
136
  if (img->width != w || img->height != h) {
106
137
  if (img->pixels) free(img->pixels);
138
+
107
139
  img->pixels = malloc(sizeof(say_color) * w * h);
108
140
 
109
141
  say_texture_make_current(img->texture);
142
+ say_pixel_bus_unbind_unpack();
110
143
  glGetError(); /* Ignore potential previous errors */
111
144
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0,
112
145
  GL_RGBA, GL_UNSIGNED_BYTE, NULL);
@@ -120,7 +153,8 @@ bool say_image_create_with_size(say_image *img, size_t w, size_t h) {
120
153
  img->width = w;
121
154
  img->height = h;
122
155
 
123
- img->texture_updated = 0;
156
+ img->texture_updated = true;
157
+ img->buffer_updated = true;
124
158
 
125
159
  return true;
126
160
  }
@@ -134,11 +168,19 @@ static bool say_image_assert_non_empty(say_image *img) {
134
168
  return true;
135
169
  }
136
170
 
171
+ static say_color *say_image_reversed_buffer(say_image *img) {
172
+ return say_flip_color_buffer_copy(img->pixels, img->width,
173
+ img->height);
174
+ }
175
+
137
176
  bool say_image_write_bmp(say_image *img, const char *filename) {
138
177
  if (!say_image_assert_non_empty(img))
139
178
  return false;
140
179
 
141
- stbi_write_bmp(filename, img->width, img->height, 4, img->pixels);
180
+ say_image_update_buffer(img);
181
+ say_color *buf = say_image_reversed_buffer(img);
182
+ stbi_write_bmp(filename, img->width, img->height, 4, buf);
183
+ free(buf);
142
184
 
143
185
  return true;
144
186
  }
@@ -147,7 +189,15 @@ bool say_image_write_png(say_image *img, const char *filename) {
147
189
  if (!say_image_assert_non_empty(img))
148
190
  return false;
149
191
 
150
- stbi_write_png(filename, img->width, img->height, 4, img->pixels, 0);
192
+ #ifdef SAY_WIN
193
+ say_error_set("can't save image as a PNG on windows");
194
+ return false;
195
+ #endif
196
+
197
+ say_image_update_buffer(img);
198
+ say_color *buf = say_image_reversed_buffer(img);
199
+ stbi_write_png(filename, img->width, img->height, 4, buf, 0);
200
+ free(buf);
151
201
 
152
202
  return true;
153
203
  }
@@ -156,7 +206,10 @@ bool say_image_write_tga(say_image *img, const char *filename) {
156
206
  if (!say_image_assert_non_empty(img))
157
207
  return false;
158
208
 
159
- stbi_write_tga(filename, img->width, img->height, 4, img->pixels);
209
+ say_image_update_buffer(img);
210
+ say_color *buf = say_image_reversed_buffer(img);
211
+ stbi_write_tga(filename, img->width, img->height, 4, buf);
212
+ free(buf);
160
213
 
161
214
  return true;
162
215
  }
@@ -170,10 +223,10 @@ bool say_image_write(say_image *img, const char *filename) {
170
223
  const char *ext = (filename + len - 4);
171
224
  if (strcmp(ext, ".png") == 0 || strcmp(ext, ".PNG") == 0)
172
225
  return say_image_write_png(img, filename);
173
- else if (strcmp(ext, ".tga") == 0 || strcmp(ext, ".TGA") == 0)
174
- return say_image_write_tga(img, filename);
226
+ else if (strcmp(ext, ".bmp") == 0 || strcmp(ext, ".BMP") == 0)
227
+ return say_image_write_bmp(img, filename);
175
228
  else
176
- say_image_write_bmp(img, filename);
229
+ say_image_write_tga(img, filename);
177
230
  }
178
231
 
179
232
  return true;
@@ -192,6 +245,8 @@ say_vector2 say_image_get_size(say_image *img) {
192
245
  }
193
246
 
194
247
  bool say_image_resize(say_image *img, size_t w, size_t h) {
248
+ say_image_update_buffer(img);
249
+
195
250
  size_t old_w = img->width, old_h = img->height;
196
251
 
197
252
  say_color *cpy = malloc(sizeof(say_color) * img->width * img->height);
@@ -200,17 +255,24 @@ bool say_image_resize(say_image *img, size_t w, size_t h) {
200
255
  if (!say_image_create_with_size(img, w, h))
201
256
  return false;
202
257
 
258
+ img->texture_updated = false;
259
+
203
260
  size_t row_size = sizeof(say_color) * old_h;
204
261
 
205
262
  for (size_t y = 0; y < old_h; y++) {
206
- memcpy(&img->pixels[y * img->width], &cpy[y * old_h], row_size);
207
- for (size_t x = old_w; x < img->width; x++)
208
- img->pixels[y * img->height + x] = say_make_color(255, 255, 255, 0);
263
+ memcpy(&img->pixels[(h - y - 1) * img->width],
264
+ &cpy[(old_h - y - 1) * old_h], row_size);
265
+ for (size_t x = old_w; x < img->width; x++) {
266
+ img->pixels[(h - y - 1) * img->height + x] =
267
+ say_make_color(255, 255, 255, 0);
268
+ }
209
269
  }
210
270
 
211
271
  for (size_t y = old_h; y < img->height; y++) {
212
- for (size_t x = 0; x < img->width; x++)
213
- img->pixels[y * img->height + x] = say_make_color(255, 255, 255, 0);
272
+ for (size_t x = 0; x < img->width; x++) {
273
+ img->pixels[(h - y - 1) * img->height + x] =
274
+ say_make_color(255, 255, 255, 0);
275
+ }
214
276
  }
215
277
 
216
278
  free(cpy);
@@ -218,11 +280,11 @@ bool say_image_resize(say_image *img, size_t w, size_t h) {
218
280
  return true;
219
281
  }
220
282
 
221
- uint8_t say_image_is_smooth(say_image *img) {
283
+ bool say_image_is_smooth(say_image *img) {
222
284
  return img->smooth;
223
285
  }
224
286
 
225
- void say_image_set_smooth(say_image *img, uint8_t val) {
287
+ void say_image_set_smooth(say_image *img, bool val) {
226
288
  if (img->smooth != val) {
227
289
  img->smooth = val;
228
290
 
@@ -240,21 +302,29 @@ say_rect say_image_get_tex_rect(say_image *img, say_rect rect) {
240
302
  if (img->width == 0 || img->height == 0)
241
303
  return say_make_rect(0, 0, 0, 0);
242
304
 
243
- return say_make_rect(rect.x / img->width, rect.y / img->height,
244
- rect.w / img->width, rect.h / img->height);
305
+ return say_make_rect(rect.x / img->width, 1 - (rect.y / img->height),
306
+ rect.w / img->width, -(rect.h / img->height));
245
307
  }
246
308
 
247
309
  say_color *say_image_get_buffer(say_image *img) {
310
+ say_image_update_buffer(img);
248
311
  return img->pixels;
249
312
  }
250
313
 
314
+ void say_image_mark_out_of_date(say_image *img) {
315
+ img->buffer_updated = false;
316
+ }
317
+
251
318
  say_color say_image_get(say_image *img, size_t x, size_t y) {
252
- return img->pixels[y * img->width + x];
319
+ say_image_update_buffer(img);
320
+ return img->pixels[(img->height - y - 1) * img->width + x];
253
321
  }
254
322
 
255
323
  void say_image_set(say_image *img, size_t x, size_t y, say_color color) {
256
- img->pixels[y * img->width + x] = color;
257
- img->texture_updated = 0;
324
+ say_image_update_buffer(img);
325
+
326
+ img->pixels[(img->height - y - 1) * img->width + x] = color;
327
+ img->texture_updated = false;
258
328
  }
259
329
 
260
330
  void say_image_bind(say_image *img) {
@@ -270,14 +340,19 @@ void say_image_update_texture(say_image *img) {
270
340
  return;
271
341
 
272
342
  say_texture_make_current(img->texture);
343
+ say_pixel_bus_unbind_unpack();
273
344
  glTexSubImage2D(GL_TEXTURE_2D, 0,
274
345
  0, 0,
275
346
  img->width, img->height,
276
347
  GL_RGBA, GL_UNSIGNED_BYTE, img->pixels);
277
348
 
278
- img->texture_updated = 1;
349
+ img->texture_updated = true;
279
350
  }
280
351
 
281
352
  void say_image_unbind() {
282
353
  say_texture_make_current(0);
283
354
  }
355
+
356
+ GLuint say_image_get_texture(say_image *img) {
357
+ return img->texture;
358
+ }
@@ -7,11 +7,12 @@ typedef struct say_image {
7
7
  GLuint texture;
8
8
 
9
9
  say_color *pixels;
10
- uint8_t texture_updated;
10
+ bool texture_updated;
11
+ bool buffer_updated;
11
12
 
12
13
  size_t width, height;
13
14
 
14
- uint8_t smooth;
15
+ bool smooth;
15
16
  } say_image;
16
17
 
17
18
  say_image *say_image_create();
@@ -25,6 +26,8 @@ bool say_image_resize(say_image *img, size_t w, size_t h);
25
26
 
26
27
  bool say_image_load_raw(say_image *img, size_t width, size_t height,
27
28
  say_color *pixels);
29
+ bool say_image_load_flipped_raw(say_image *img, size_t width, size_t height,
30
+ say_color *pixels);
28
31
  bool say_image_load_file(say_image *img, const char *filename);
29
32
  bool say_image_load_from_memory(say_image *img, size_t size, const char *buffer);
30
33
  bool say_image_create_with_size(say_image *img, size_t w, size_t h);
@@ -34,8 +37,8 @@ bool say_image_write_png(say_image *img, const char *filename);
34
37
  bool say_image_write_tga(say_image *img, const char *filename);
35
38
  bool say_image_write(say_image *img, const char *filename);
36
39
 
37
- uint8_t say_image_is_smooth(say_image *img);
38
- void say_image_set_smooth(say_image *img, uint8_t val);
40
+ bool say_image_is_smooth(say_image *img);
41
+ void say_image_set_smooth(say_image *img, bool val);
39
42
 
40
43
  say_color say_image_get(say_image *img, size_t x, size_t y);
41
44
  void say_image_set(say_image *img, size_t x, size_t y, say_color color);
@@ -44,9 +47,13 @@ say_rect say_image_get_tex_rect(say_image *img, say_rect rect);
44
47
 
45
48
  say_color *say_image_get_buffer(say_image *img);
46
49
 
50
+ void say_image_mark_out_of_date(say_image *img);
51
+
47
52
  void say_image_bind(say_image *img);
48
53
  void say_image_unbind();
49
54
 
50
55
  void say_image_update_texture(say_image *img);
51
56
 
57
+ GLuint say_image_get_texture(say_image *img);
58
+
52
59
  #endif
@@ -1,9 +1,49 @@
1
1
  #include "say.h"
2
2
 
3
+ typedef struct {
4
+ GLuint id;
5
+ say_image *img;
6
+ say_context *ctxt;
7
+ } say_fbo;
8
+
3
9
  static say_context *say_image_target_make_context(void *data) {
4
10
  return say_context_create();
5
11
  }
6
12
 
13
+ static void say_fbo_delete_current(void *data) {
14
+ say_fbo *fbo = (say_fbo*)data;
15
+
16
+ if (fbo->ctxt == say_context_current() && fbo->id) {
17
+ glDeleteFramebuffers(1, &fbo->id);
18
+ }
19
+ }
20
+
21
+ void say_fbo_make_current(GLuint fbo);
22
+ void say_rbo_make_current(GLuint rbo);
23
+
24
+ static void say_fbo_build(say_image_target *target, say_fbo *fbo) {
25
+ if (!fbo->id)
26
+ glGenFramebuffers(1, &fbo->id);
27
+
28
+ say_fbo_make_current(fbo->id);
29
+
30
+ say_image_bind(target->img);
31
+ glGenerateMipmap(GL_TEXTURE_2D);
32
+
33
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
34
+ GL_TEXTURE_2D, target->img->texture, 0);
35
+
36
+ say_rbo_make_current(target->rbo);
37
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT,
38
+ say_image_get_width(target->img),
39
+ say_image_get_height(target->img));
40
+
41
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
42
+ GL_RENDERBUFFER, target->rbo);
43
+
44
+ fbo->img = target->img;
45
+ }
46
+
7
47
  static GLuint say_current_fbo = 0;
8
48
  static say_context *say_fbo_last_context = NULL;
9
49
 
@@ -15,7 +55,7 @@ void say_fbo_make_current(GLuint fbo) {
15
55
  say_current_fbo = fbo;
16
56
  say_fbo_last_context = context;
17
57
 
18
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
58
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
19
59
  }
20
60
  }
21
61
 
@@ -30,13 +70,19 @@ void say_rbo_make_current(GLuint rbo) {
30
70
  say_current_rbo = rbo;
31
71
  say_rbo_last_context = context;
32
72
 
33
- glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rbo);
73
+ glBindRenderbuffer(GL_RENDERBUFFER, rbo);
34
74
  }
35
75
  }
36
76
 
37
- void say_image_target_will_delete(GLuint fbo, GLuint rbo) {
38
- if (say_current_fbo == fbo)
39
- say_current_fbo = 0;
77
+ void say_image_target_will_delete(mo_hash *fbos, GLuint rbo) {
78
+ mo_hash_it it = mo_hash_begin(fbos);
79
+ for (; !mo_hash_it_is_end(&it); mo_hash_it_next(&it)) {
80
+ say_fbo *fbo = mo_hash_it_val_ptr(&it, say_fbo);
81
+ if (fbo->id == say_current_fbo) {
82
+ say_current_fbo = 0;
83
+ break;
84
+ }
85
+ }
40
86
 
41
87
  if (say_current_rbo == rbo)
42
88
  say_current_rbo = 0;
@@ -44,7 +90,7 @@ void say_image_target_will_delete(GLuint fbo, GLuint rbo) {
44
90
 
45
91
  bool say_image_target_is_available() {
46
92
  say_context_ensure();
47
- return __GLEW_EXT_framebuffer_object != 0;
93
+ return GLEW_EXT_framebuffer_object || GLEW_VERSION_3_0;
48
94
  }
49
95
 
50
96
  say_image_target *say_image_target_create() {
@@ -54,18 +100,22 @@ say_image_target *say_image_target_create() {
54
100
  target->target = say_target_create();
55
101
  target->img = NULL;
56
102
 
57
- glGenFramebuffersEXT(1, &(target->fbo));
58
- glGenRenderbuffersEXT(1, &(target->rbo));
103
+ target->fbos = mo_hash_create(sizeof(say_context*), sizeof(say_fbo));
104
+ target->fbos->release = say_fbo_delete_current;
105
+ target->fbos->hash_of = mo_hash_of_pointer;
106
+ target->fbos->key_cmp = mo_hash_pointer_cmp;
107
+
108
+ glGenRenderbuffers(1, &target->rbo);
59
109
 
60
110
  return target;
61
111
  }
62
112
 
63
113
  void say_image_target_free(say_image_target *target) {
64
114
  say_context_ensure();
65
- say_image_target_will_delete(target->fbo, target->rbo);
115
+ say_image_target_will_delete(target->fbos, target->rbo);
66
116
 
67
- glDeleteRenderbuffersEXT(1, &(target->rbo));
68
- glDeleteFramebuffersEXT(1, &(target->fbo));
117
+ glDeleteRenderbuffers(1, &target->rbo);
118
+ mo_hash_free(target->fbos);
69
119
 
70
120
  say_target_free(target->target);
71
121
  free(target);
@@ -77,7 +127,6 @@ void say_image_target_set_image(say_image_target *target, say_image *image) {
77
127
 
78
128
  if (target->img) {
79
129
  say_target_set_custom_data(target->target, target);
80
- //say_target_need_own_contxt(target->target, 0);
81
130
  say_target_set_context_proc(target->target, say_image_target_make_context);
82
131
  say_target_set_bind_hook(target->target, (say_bind_hook)say_image_target_bind);
83
132
 
@@ -87,24 +136,8 @@ void say_image_target_set_image(say_image_target *target, say_image *image) {
87
136
  say_view_set_size(target->target->view, size);
88
137
  say_view_set_center(target->target->view, say_make_vector2(size.x / 2.0,
89
138
  size.y / 2.0));
90
- say_view_flip_y(target->target->view, 0);
91
-
92
- say_fbo_make_current(target->fbo);
93
-
94
- say_image_bind(image);
95
- glGenerateMipmapEXT(GL_TEXTURE_2D);
96
-
97
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
98
- GL_TEXTURE_2D, image->texture, 0);
99
-
100
- say_rbo_make_current(target->rbo);
101
- glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,
102
- say_image_get_width(image),
103
- say_image_get_height(image));
104
-
105
- glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
106
- GL_RENDERBUFFER_EXT, target->rbo);
107
139
 
140
+ say_target_make_current(target->target);
108
141
  }
109
142
  }
110
143
 
@@ -115,16 +148,37 @@ say_image *say_image_target_get_image(say_image_target *target) {
115
148
  void say_image_target_update(say_image_target *target) {
116
149
  if (target->img) {
117
150
  say_target_update(target->target);
118
-
119
- say_image_bind(target->img);
120
- glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE,
121
- say_image_get_buffer(target->img));
151
+ say_image_mark_out_of_date(target->img);
122
152
  }
123
153
  }
124
154
 
125
155
  void say_image_target_bind(say_image_target *target) {
126
156
  say_context_ensure();
127
- say_fbo_make_current(target->fbo);
157
+
158
+ /*
159
+ * As FBOs aren't shared, we need to fetch the FBO for the current context. If
160
+ * we don't find one, we need to build it.
161
+ */
162
+ say_context *ctxt = say_context_current();
163
+
164
+ if (!mo_hash_has_key(target->fbos, &ctxt)) {
165
+ say_fbo tmp = {0, NULL, NULL};
166
+ mo_hash_set(target->fbos, &ctxt, &tmp);
167
+
168
+ say_fbo_build(target, mo_hash_get(target->fbos, &ctxt));
169
+ }
170
+ else {
171
+ say_fbo *fbo = mo_hash_get(target->fbos, &ctxt);
172
+
173
+ if (fbo->img != target->img && target->img)
174
+ say_fbo_build(target, fbo);
175
+ else
176
+ say_fbo_make_current(fbo->id);
177
+ }
178
+
179
+ /*
180
+ * Needed to avoid having garbage data there.
181
+ */
128
182
  glClear(GL_DEPTH_BUFFER_BIT);
129
183
  }
130
184