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