ray 0.2.0 → 0.2.1

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.
@@ -18,6 +18,29 @@ struct say_window;
18
18
  typedef struct {
19
19
  uint32_t count;
20
20
  say_imp_context context;
21
+
22
+ int texture_unit;
23
+ GLuint textures[32];
24
+
25
+ GLuint vao;
26
+ GLuint vbo;
27
+ void *buffer_obj;
28
+
29
+ GLuint program;
30
+
31
+ GLuint ibo;
32
+
33
+ GLuint pack_pbo;
34
+ GLuint unpack_pbo;
35
+
36
+ void *target;
37
+
38
+ bool blend_enabled;
39
+ GLenum src_blend_func;
40
+ GLenum dst_blend_func;
41
+
42
+ GLuint fbo;
43
+ GLuint rbo;
21
44
  } say_context;
22
45
 
23
46
  say_context_config *say_context_get_config();
@@ -27,6 +50,7 @@ void say_context_free_el(void *context);
27
50
  void say_context_ensure();
28
51
 
29
52
  say_context *say_context_current();
53
+ mo_array *say_context_get_all();
30
54
 
31
55
  say_context *say_context_create_for_window(struct say_window *window);
32
56
  say_context *say_context_create();
@@ -8,55 +8,52 @@ static void say_drawable_update_matrix(say_drawable *drawable) {
8
8
  drawable->matrix_proc(drawable->data, drawable->matrix);
9
9
  }
10
10
  else {
11
- say_matrix_reset(drawable->matrix);
12
-
13
- say_matrix_translate_by(drawable->matrix,
14
- drawable->pos.x,
15
- drawable->pos.y,
16
- drawable->z_order);
17
- say_matrix_rotate(drawable->matrix, drawable->angle, 0, 0, 1);
18
- say_matrix_scale_by(drawable->matrix, drawable->scale.x, drawable->scale.y,
19
- 1);
20
- say_matrix_translate_by(drawable->matrix,
21
- -drawable->origin.x,
22
- -drawable->origin.y,
23
- 0);
11
+ say_matrix_set_transformation(drawable->matrix,
12
+ drawable->origin,
13
+ drawable->pos, drawable->z_order,
14
+ drawable->scale,
15
+ drawable->angle);
24
16
  }
25
17
 
26
18
  drawable->matrix_updated = true;
27
19
  }
28
20
 
29
- static say_context *say_blend_last_context = NULL;
30
- static say_blend_mode say_last_blend = SAY_BLEND_NO;
31
-
32
21
  static void say_drawable_enable_blend_mode(say_blend_mode mode) {
33
22
  say_context *context = say_context_current();
34
23
 
35
- if (mode != say_last_blend || context != say_blend_last_context) {
36
- if (context != say_blend_last_context)
37
- say_last_blend = SAY_BLEND_NO;
24
+ bool must_be_enabled = mode != SAY_BLEND_NO;
25
+ if (context->blend_enabled != must_be_enabled) {
26
+ context->blend_enabled = must_be_enabled;
38
27
 
39
- if (mode == SAY_BLEND_NO)
40
- glDisable(GL_BLEND);
41
- else if (say_last_blend == SAY_BLEND_NO)
28
+ if (must_be_enabled)
42
29
  glEnable(GL_BLEND);
43
-
44
- switch (mode) {
45
- case SAY_BLEND_NO:
46
- break;
47
- case SAY_BLEND_ALPHA:
48
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
49
- break;
50
- case SAY_BLEND_ADD:
51
- glBlendFunc(GL_SRC_ALPHA, GL_ONE);
52
- break;
53
- case SAY_BLEND_MULTIPLY:
54
- glBlendFunc(GL_DST_COLOR, GL_ZERO);
55
- break;
30
+ else {
31
+ glDisable(GL_BLEND);
32
+ return; /* No need to check depth function */
56
33
  }
34
+ }
57
35
 
58
- say_last_blend = mode;
59
- say_blend_last_context = context;
36
+ GLenum src, dst;
37
+ switch (mode) {
38
+ case SAY_BLEND_ALPHA:
39
+ src = GL_SRC_ALPHA;
40
+ dst = GL_ONE_MINUS_SRC_ALPHA;
41
+ break;
42
+ case SAY_BLEND_ADD:
43
+ src = GL_SRC_ALPHA;
44
+ dst = GL_ONE;
45
+ break;
46
+ case SAY_BLEND_MULTIPLY:
47
+ src = GL_DST_COLOR;
48
+ dst = GL_ZERO;
49
+ break;
50
+ default: return;
51
+ }
52
+
53
+ if (context->src_blend_func != src || context->dst_blend_func != dst) {
54
+ glBlendFunc(src, dst);
55
+ context->src_blend_func = src;
56
+ context->dst_blend_func = dst;
60
57
  }
61
58
  }
62
59
 
@@ -410,6 +407,17 @@ say_matrix *say_drawable_get_matrix(say_drawable *drawable) {
410
407
  return drawable->matrix;
411
408
  }
412
409
 
410
+ say_matrix *say_drawable_get_default_matrix(say_drawable *drawable) {
411
+ say_matrix *ret = say_matrix_identity();
412
+ say_matrix_set_transformation(ret,
413
+ drawable->origin,
414
+ drawable->pos, drawable->z_order,
415
+ drawable->scale,
416
+ drawable->angle);
417
+
418
+ return ret;
419
+ }
420
+
413
421
  void say_drawable_set_matrix(say_drawable *drawable, say_matrix *matrix) {
414
422
  if (matrix) {
415
423
  drawable->custom_matrix = true;
@@ -428,7 +436,6 @@ say_vector3 say_drawable_transform(say_drawable *drawable, say_vector3 point) {
428
436
  return say_matrix_transform(drawable->matrix, point);
429
437
  }
430
438
 
431
-
432
439
  say_blend_mode say_drawable_get_blend_mode(say_drawable *drawable) {
433
440
  return drawable->blend_mode;
434
441
  }
@@ -112,6 +112,7 @@ float say_drawable_get_z(say_drawable *drawable);
112
112
  float say_drawable_get_angle(say_drawable *drawable);
113
113
 
114
114
  say_matrix *say_drawable_get_matrix(say_drawable *drawable);
115
+ say_matrix *say_drawable_get_default_matrix(say_drawable *drawable);
115
116
  void say_drawable_set_matrix(say_drawable *drawable, say_matrix *matrix);
116
117
  say_vector3 say_drawable_transform(say_drawable *drawable, say_vector3 point);
117
118
 
@@ -5,31 +5,37 @@
5
5
  #define STB_IMAGE_WRITE_IMPLEMENTATION 1
6
6
  #include "stb_image_write.h"
7
7
 
8
- static GLuint say_current_texture = 0;
9
- static say_context *say_texture_last_context = NULL;
10
-
11
- static void say_texture_make_current(GLuint texture) {
8
+ static void say_texture_make_current(GLuint texture, int unit) {
12
9
  say_context *context = say_context_current();
13
10
 
14
- if (texture != say_current_texture ||
15
- context != say_texture_last_context) {
16
- say_texture_last_context = context;
17
- say_current_texture = texture;
11
+ if (context->texture_unit != unit) {
12
+ glActiveTexture(GL_TEXTURE0 + unit);
13
+ context->texture_unit = unit;
14
+ }
18
15
 
16
+ if (context->textures[unit] != texture) {
19
17
  glBindTexture(GL_TEXTURE_2D, texture);
18
+ context->textures[unit] = texture;
20
19
  }
21
20
  }
22
21
 
23
22
  static void say_texture_will_delete(GLuint texture) {
24
- if (say_current_texture == texture)
25
- say_current_texture = 0;
23
+ mo_array *contexts = say_context_get_all();
24
+ for (size_t i = 0; i < contexts->size; i++) {
25
+ say_context *context = mo_array_get_as(contexts, i, say_context*);
26
+
27
+ for (size_t i = 0; i < SAY_MAX_TEXTURE_UNIT; i++) {
28
+ if (context->textures[i] == texture)
29
+ context->textures[i] = 0;
30
+ }
31
+ }
26
32
  }
27
33
 
28
34
  static void say_image_update_buffer(say_image *img) {
29
35
  if (img->buffer_updated)
30
36
  return;
31
37
 
32
- say_texture_make_current(img->texture);
38
+ say_texture_make_current(img->texture, 0);
33
39
  say_pixel_bus_unbind_pack();
34
40
  glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE,
35
41
  img->pixels);
@@ -138,7 +144,7 @@ bool say_image_create_with_size(say_image *img, size_t w, size_t h) {
138
144
 
139
145
  img->pixels = malloc(sizeof(say_color) * w * h);
140
146
 
141
- say_texture_make_current(img->texture);
147
+ say_texture_make_current(img->texture, 0);
142
148
  say_pixel_bus_unbind_unpack();
143
149
  glGetError(); /* Ignore potential previous errors */
144
150
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0,
@@ -289,7 +295,7 @@ void say_image_set_smooth(say_image *img, bool val) {
289
295
  img->smooth = val;
290
296
 
291
297
  say_context_ensure();
292
- say_texture_make_current(img->texture);
298
+ say_texture_make_current(img->texture, 0);
293
299
 
294
300
  GLenum interp = val ? GL_LINEAR : GL_NEAREST;
295
301
 
@@ -328,8 +334,12 @@ void say_image_set(say_image *img, size_t x, size_t y, say_color color) {
328
334
  }
329
335
 
330
336
  void say_image_bind(say_image *img) {
337
+ say_image_bind_to(img, 0);
338
+ }
339
+
340
+ void say_image_bind_to(say_image *img, int unit) {
331
341
  say_context_ensure();
332
- say_texture_make_current(img->texture);
342
+ say_texture_make_current(img->texture, unit);
333
343
 
334
344
  if (!img->texture_updated)
335
345
  say_image_update_texture(img);
@@ -339,7 +349,7 @@ void say_image_update_texture(say_image *img) {
339
349
  if (!img->pixels)
340
350
  return;
341
351
 
342
- say_texture_make_current(img->texture);
352
+ say_texture_make_current(img->texture, 0);
343
353
  say_pixel_bus_unbind_unpack();
344
354
  glTexSubImage2D(GL_TEXTURE_2D, 0,
345
355
  0, 0,
@@ -350,7 +360,14 @@ void say_image_update_texture(say_image *img) {
350
360
  }
351
361
 
352
362
  void say_image_unbind() {
353
- say_texture_make_current(0);
363
+ say_context_ensure();
364
+ for (size_t i = 0; i < SAY_MAX_TEXTURE_UNIT; i++)
365
+ say_texture_make_current(0, i);
366
+ }
367
+
368
+ void say_image_unbind_from(int unit) {
369
+ say_context_ensure();
370
+ say_texture_make_current(0, unit);
354
371
  }
355
372
 
356
373
  GLuint say_image_get_texture(say_image *img) {
@@ -3,6 +3,8 @@
3
3
 
4
4
  #include "say_basic_type.h"
5
5
 
6
+ #define SAY_MAX_TEXTURE_UNIT 32
7
+
6
8
  typedef struct say_image {
7
9
  GLuint texture;
8
10
 
@@ -50,7 +52,9 @@ say_color *say_image_get_buffer(say_image *img);
50
52
  void say_image_mark_out_of_date(say_image *img);
51
53
 
52
54
  void say_image_bind(say_image *img);
55
+ void say_image_bind_to(say_image *img, int unit);
53
56
  void say_image_unbind();
57
+ void say_image_unbind_from(int unit);
54
58
 
55
59
  void say_image_update_texture(say_image *img);
56
60
 
@@ -44,48 +44,37 @@ static void say_fbo_build(say_image_target *target, say_fbo *fbo) {
44
44
  fbo->img = target->img;
45
45
  }
46
46
 
47
- static GLuint say_current_fbo = 0;
48
- static say_context *say_fbo_last_context = NULL;
49
-
50
47
  void say_fbo_make_current(GLuint fbo) {
51
48
  say_context *context = say_context_current();
52
49
 
53
- if (context != say_fbo_last_context ||
54
- fbo != say_current_fbo) {
55
- say_current_fbo = fbo;
56
- say_fbo_last_context = context;
57
-
50
+ if (context->fbo != fbo) {
58
51
  glBindFramebuffer(GL_FRAMEBUFFER, fbo);
52
+ context->fbo = fbo;
59
53
  }
60
54
  }
61
55
 
62
- static GLuint say_current_rbo = 0;
63
- static say_context *say_rbo_last_context = NULL;
64
-
65
56
  void say_rbo_make_current(GLuint rbo) {
66
57
  say_context *context = say_context_current();
67
58
 
68
- if (context != say_rbo_last_context ||
69
- rbo != say_current_rbo) {
70
- say_current_rbo = rbo;
71
- say_rbo_last_context = context;
72
-
59
+ if (context->rbo != rbo) {
73
60
  glBindRenderbuffer(GL_RENDERBUFFER, rbo);
61
+ context->rbo = rbo;
74
62
  }
75
63
  }
76
64
 
77
65
  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
- }
66
+ mo_array *contexts = say_context_get_all();
67
+
68
+ for (size_t i = 0; i < contexts->size; i++) {
69
+ say_context *context = mo_array_get_as(contexts, i, say_context*);
86
70
 
87
- if (say_current_rbo == rbo)
88
- say_current_rbo = 0;
71
+ say_fbo *fbo = mo_hash_get_ptr(fbos, &context, say_fbo);
72
+ if (fbo && fbo->id == context->fbo)
73
+ context->fbo = 0;
74
+
75
+ if (context->rbo == rbo)
76
+ context->rbo = 0;
77
+ }
89
78
  }
90
79
 
91
80
  bool say_image_target_is_available() {
@@ -1,23 +1,20 @@
1
1
  #include "say.h"
2
2
 
3
- static GLuint say_current_ibo = 0;
4
- static say_context *say_ibo_last_context = NULL;
5
-
6
3
  static void say_ibo_make_current(GLuint ibo) {
7
4
  say_context *context = say_context_current();
8
5
 
9
- if (context != say_ibo_last_context ||
10
- ibo != say_current_ibo) {
11
- say_current_ibo = ibo;
12
- say_ibo_last_context = context;
13
-
6
+ if (context->ibo != ibo) {
14
7
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
8
+ context->ibo = ibo;
15
9
  }
16
10
  }
17
11
 
18
12
  static void say_ibo_will_delete(GLuint ibo) {
19
- if (ibo == say_current_ibo) {
20
- say_current_ibo = 0;
13
+ mo_array *contexts = say_context_get_all();
14
+ for (size_t i = 0; i < contexts->size; i++) {
15
+ say_context *context = mo_array_get_as(contexts, i, say_context*);
16
+ if (context->ibo == ibo)
17
+ context->ibo = 0;
21
18
  }
22
19
  }
23
20
 
@@ -59,8 +56,7 @@ void say_index_buffer_unbind() {
59
56
  }
60
57
 
61
58
  void say_index_buffer_rebind() {
62
- if (say_ibo_last_context == say_context_current())
63
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, say_current_ibo);
59
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, say_context_current()->ibo);
64
60
  }
65
61
 
66
62
  void say_index_buffer_update_part(say_index_buffer *buf, size_t index,
@@ -12,7 +12,7 @@ typedef struct {
12
12
 
13
13
  typedef struct {
14
14
  say_index_buffer *buf;
15
- mo_list *ranges;
15
+ mo_list ranges;
16
16
  } say_global_ibo;
17
17
 
18
18
  static mo_array *say_index_buffers = NULL;
@@ -20,7 +20,7 @@ static mo_array *say_index_buffers = NULL;
20
20
  static say_global_ibo say_global_ibo_create(size_t size) {
21
21
  say_global_ibo ret;
22
22
  ret.buf = say_index_buffer_create(SAY_STREAM, size);
23
- ret.ranges = NULL;
23
+ mo_list_init(&ret.ranges, sizeof(say_range));
24
24
 
25
25
  return ret;
26
26
  }
@@ -29,7 +29,7 @@ static void say_global_ibo_free(void *data) {
29
29
  say_global_ibo *ibo = (say_global_ibo*)data;
30
30
 
31
31
  say_index_buffer_free(ibo->buf);
32
- if (ibo->ranges) mo_list_free(ibo->ranges);
32
+ mo_list_release(&ibo->ranges);
33
33
  }
34
34
 
35
35
  static say_global_ibo *say_global_ibo_at(size_t index) {
@@ -60,51 +60,49 @@ static bool say_global_ibo_fit_into(say_global_ibo *ibo, size_t used,
60
60
 
61
61
  static size_t say_global_ibo_prepend(say_global_ibo *ibo, size_t size) {
62
62
  say_range range = say_make_range(0, size);
63
- ibo->ranges = mo_list_prepend(ibo->ranges, &range);
63
+ mo_list_prepend(&ibo->ranges, ibo->ranges.head, &range);
64
64
  return 0;
65
65
  }
66
66
 
67
- static size_t say_global_ibo_insert(mo_list *list, size_t size) {
68
- say_range *range = mo_list_data_ptr(list, say_range);
67
+ static size_t say_global_ibo_insert(mo_list *list, mo_list_it *it,
68
+ size_t size) {
69
+ say_range *range = mo_list_it_data_ptr(it, say_range);
69
70
  say_range tmp = say_make_range(range->loc + range->size, size);
70
71
 
71
- mo_list_insert(list, &tmp);
72
+ mo_list_insert(list, it, &tmp);
72
73
  return tmp.loc;
73
74
  }
74
75
 
75
76
  static size_t say_global_ibo_find_in(say_global_ibo *ibo, size_t size) {
76
- if (!ibo->ranges && say_global_ibo_fit_into(ibo, 0, size)) {
77
- ibo->ranges = mo_list_create(sizeof(say_range));
78
- say_range *range = mo_list_data_ptr(ibo->ranges, say_range);
79
- *range = say_make_range(0, size);
80
- return 0;
77
+ if (!ibo->ranges.head && say_global_ibo_fit_into(ibo, 0, size)) {
78
+ return say_global_ibo_prepend(ibo, size);
81
79
  }
82
80
 
83
- say_range *first = mo_list_data_ptr(ibo->ranges, say_range);
81
+ say_range *first = mo_list_it_data_ptr(ibo->ranges.head, say_range);
84
82
 
85
83
  /* There's room at the begin of the buffer */
86
84
  if (first->loc >= size) {
87
85
  return say_global_ibo_prepend(ibo, size);
88
86
  }
89
87
 
90
- mo_list *it = ibo->ranges;
88
+ mo_list_it *it = ibo->ranges.head;
91
89
  for (; it->next; it = it->next) {
92
- say_range *current = mo_list_data_ptr(it, say_range);
93
- say_range *next = mo_list_data_ptr(it->next, say_range);
90
+ say_range *current = mo_list_it_data_ptr(it, say_range);
91
+ say_range *next = mo_list_it_data_ptr(it->next, say_range);
94
92
 
95
93
  size_t begin = current->loc + current->size;
96
94
  size_t end = next->loc;
97
95
 
98
96
  /* There's enough room between those two elements */
99
97
  if (end - begin >= size)
100
- return say_global_ibo_insert(it, size);
98
+ return say_global_ibo_insert(&ibo->ranges, it, size);
101
99
  }
102
100
 
103
- say_range *last = mo_list_data_ptr(it, say_range);
101
+ say_range *last = mo_list_it_data_ptr(it, say_range);
104
102
 
105
103
  /* There's enough room at the end of the buffer */
106
104
  if (say_global_ibo_fit_into(ibo, last->loc + last->size, size))
107
- return say_global_ibo_insert(it, size);
105
+ return say_global_ibo_insert(&ibo->ranges, it, size);
108
106
  else
109
107
  return SAY_MAX_SIZE;
110
108
  }
@@ -148,14 +146,10 @@ static void say_global_ibo_delete_at(say_global_ibo *ibo, size_t loc,
148
146
  if (!ibo)
149
147
  return;
150
148
 
151
- for (mo_list *it = ibo->ranges; it; it = it->next) {
152
- say_range *range = mo_list_data_ptr(it, say_range);
149
+ for (mo_list_it *it = ibo->ranges.head; it; it = it->next) {
150
+ say_range *range = mo_list_it_data_ptr(it, say_range);
153
151
  if (range->loc == loc && range->size == range_size) {
154
- mo_list *next = it->next;
155
- mo_list_delete(it);
156
-
157
- if (it == ibo->ranges) ibo->ranges = next;
158
-
152
+ mo_list_delete(&ibo->ranges, it);
159
153
  return;
160
154
  }
161
155
  }
@@ -163,8 +157,8 @@ static void say_global_ibo_delete_at(say_global_ibo *ibo, size_t loc,
163
157
 
164
158
  static void say_global_ibo_reduce_size(say_global_ibo *ibo, size_t loc,
165
159
  size_t old_size, size_t size) {
166
- for (mo_list *it = ibo->ranges; it; it = it->next) {
167
- say_range *range = mo_list_data_ptr(it, say_range);
160
+ for (mo_list_it *it = ibo->ranges.head; it; it = it->next) {
161
+ say_range *range = mo_list_it_data_ptr(it, say_range);
168
162
  if (range->loc == loc && range->size == old_size) {
169
163
  range->size = size;
170
164
  return;