ray 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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;