aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Weissflog <floooh@gmail.com>2022-11-16 18:35:00 +0100
committerGitHub <noreply@github.com>2022-11-16 18:35:00 +0100
commit02f39b3f3fd07cf12403a80e8ef933aa27d08a99 (patch)
tree5e7caea0ba46887c9ed5df27a5cd8be3097ad441
parentbba1d39476abc719f8737f962d75ba590c37eeb8 (diff)
parent18179b2d7d2a034a8962887707c4b1b27dbfd283 (diff)
Merge pull request #744 from floooh/sokol-debugtext-layers
Implement layered rendering for sokol_debugtext.h ...also some code cleanup in sokol_gl.h and sokol_spine.h.
-rw-r--r--CHANGELOG.md8
-rw-r--r--README.md2
-rw-r--r--tests/functional/sokol_debugtext_test.c109
-rw-r--r--tests/functional/sokol_gl_test.c96
-rw-r--r--util/sokol_debugtext.h324
-rw-r--r--util/sokol_gl.h146
-rw-r--r--util/sokol_spine.h88
7 files changed, 529 insertions, 244 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6284bebf..c07529aa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
## Updates
+- **16-Nov-2022**: Render layer support has been added to sokol_debugtext.h,
+ same general changes as in sokol_gl.h with two new functions:
+ sdtx_layer(layer_id) to select the layer to record text into, and
+ sdtx_draw_layer(layer_id) to draw the recorded text in that layer inside a
+ sokol-gfx render pass. The new sample [debugtext-layers-sapp](https://floooh.github.io/sokol-html5/debugtext-layers-sapp) demonstrates the feature together with
+ sokol-gl.
+
+
- **11-Nov-2022**: sokol_gl.h has 2 new public API functions which enable
layered rendering: sgl_layer(), sgl_draw_layer() (technically it's three
functions: there's also sgl_context_draw_layer(), but that's just a variant of
diff --git a/README.md b/README.md
index 24ce0713..c120e3f5 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@ Simple
[STB-style](https://github.com/nothings/stb/blob/master/docs/stb_howto.txt)
cross-platform libraries for C and C++, written in C.
-[**See what's new**](https://github.com/floooh/sokol/blob/master/CHANGELOG.md) (**11-Nov-2022** sokol_gl.h learned layered rendering)
+[**See what's new**](https://github.com/floooh/sokol/blob/master/CHANGELOG.md) (**16-Nov-2022** sokol_debugtext.h learned layered rendering)
[![Build](/../../actions/workflows/main.yml/badge.svg)](/../../actions/workflows/main.yml) [![Bindings](/../../actions/workflows/gen_bindings.yml/badge.svg)](/../../actions/workflows/gen_bindings.yml) [![build](https://github.com/floooh/sokol-zig/actions/workflows/main.yml/badge.svg)](https://github.com/floooh/sokol-zig/actions/workflows/main.yml) [![build](https://github.com/floooh/sokol-nim/actions/workflows/main.yml/badge.svg)](https://github.com/floooh/sokol-nim/actions/workflows/main.yml) [![Odin](https://github.com/floooh/sokol-odin/actions/workflows/main.yml/badge.svg)](https://github.com/floooh/sokol-odin/actions/workflows/main.yml)
diff --git a/tests/functional/sokol_debugtext_test.c b/tests/functional/sokol_debugtext_test.c
index ce1bb5e0..d2523502 100644
--- a/tests/functional/sokol_debugtext_test.c
+++ b/tests/functional/sokol_debugtext_test.c
@@ -57,11 +57,12 @@ UTEST(sokol_debugtext, default_init_shutdown) {
T(_sdtx.cur_ctx->desc.color_format == 0);
T(_sdtx.cur_ctx->desc.depth_format == 0);
T(_sdtx.cur_ctx->desc.sample_count == 0);
- T(_sdtx.cur_ctx->cur_vertex_ptr);
- T(_sdtx.cur_ctx->max_vertex_ptr);
- T(_sdtx.cur_ctx->vertices);
- T(_sdtx.cur_ctx->vertices == _sdtx.cur_ctx->cur_vertex_ptr);
- T(_sdtx.cur_ctx->max_vertex_ptr == (_sdtx.cur_ctx->vertices + _SDTX_DEFAULT_CHAR_BUF_SIZE * 6));
+ T(_sdtx.cur_ctx->vertices.cap == _SDTX_DEFAULT_CHAR_BUF_SIZE * 6);
+ T(_sdtx.cur_ctx->vertices.next == 0);
+ T(_sdtx.cur_ctx->vertices.ptr);
+ T(_sdtx.cur_ctx->commands.cap == _SDTX_DEFAULT_MAX_COMMANDS);
+ T(_sdtx.cur_ctx->commands.next == 1);
+ T(_sdtx.cur_ctx->commands.ptr);
T(_sdtx.cur_ctx->vbuf.id != 0);
T(_sdtx.cur_ctx->pip.id != 0);
TFLT(_sdtx.cur_ctx->canvas_size.x, 640.0f);
@@ -112,7 +113,7 @@ UTEST(sokol_debugtext, init_with_params) {
T(_sdtx.cur_ctx->desc.color_format == SG_PIXELFORMAT_RGBA8);
T(_sdtx.cur_ctx->desc.depth_format == SG_PIXELFORMAT_DEPTH_STENCIL);
T(_sdtx.cur_ctx->desc.sample_count == 4);
- T(_sdtx.cur_ctx->max_vertex_ptr == (_sdtx.cur_ctx->vertices + 256 * 6));
+ T(_sdtx.cur_ctx->vertices.cap == (256 * 6));
TFLT(_sdtx.cur_ctx->canvas_size.x, 320.0f);
TFLT(_sdtx.cur_ctx->canvas_size.y, 200.0f);
TFLT(_sdtx.cur_ctx->glyph_size.x, 8.0f / 320.0f);
@@ -144,9 +145,9 @@ UTEST(sokol_debugtext, make_destroy_context) {
T(ctx->desc.color_format == SG_PIXELFORMAT_RGBA32F);
T(ctx->desc.depth_format == 0);
T(ctx->desc.sample_count == 2);
- T(ctx->vertices);
- T(ctx->cur_vertex_ptr == ctx->vertices);
- T(ctx->max_vertex_ptr == ctx->vertices + 64 * 6);
+ T(ctx->vertices.ptr);
+ T(ctx->vertices.next == 0);
+ T(ctx->vertices.cap == (64 * 6));
TFLT(ctx->canvas_size.x, 1024.0f);
TFLT(ctx->canvas_size.y, 768.0f);
TFLT(ctx->glyph_size.x, 8.0f / 1024.0f);
@@ -155,7 +156,7 @@ UTEST(sokol_debugtext, make_destroy_context) {
sdtx_destroy_context(ctx_id);
T(0 == _sdtx_lookup_context(ctx_id.id));
T(ctx->desc.char_buf_size == 0);
- T(ctx->vertices == 0);
+ T(ctx->vertices.ptr == 0);
shutdown();
}
@@ -336,7 +337,7 @@ UTEST(sokol_debugtext, vertex_overflow) {
sdtx_puts("1234567890");
sdtx_putr("1234567890", 5);
sdtx_printf("Hello World %d!\n", 12);
- T(_sdtx.cur_ctx->cur_vertex_ptr == _sdtx.cur_ctx->max_vertex_ptr);
+ T(_sdtx.cur_ctx->vertices.next == _sdtx.cur_ctx->vertices.cap);
shutdown();
}
@@ -399,7 +400,7 @@ UTEST(sokol_debugtext, rewind_after_draw) {
sdtx_font(3);
T(_sdtx.cur_ctx->cur_font == 3);
sdtx_printf("Hello World!\n");
- T(_sdtx.cur_ctx->cur_vertex_ptr != _sdtx.cur_ctx->vertices);
+ T(_sdtx.cur_ctx->vertices.next != 0);
sg_begin_default_pass(&(sg_pass_action){ 0 }, 256, 256);
sdtx_draw();
sg_end_pass();
@@ -411,21 +412,21 @@ UTEST(sokol_debugtext, rewind_after_draw) {
TFLT(_sdtx.cur_ctx->pos.x, 0);
TFLT(_sdtx.cur_ctx->pos.x, 0);
T(_sdtx.cur_ctx->cur_font == 0);
- T(_sdtx.cur_ctx->cur_vertex_ptr == _sdtx.cur_ctx->vertices);
+ T(_sdtx.cur_ctx->vertices.next == 0);
shutdown();
}
UTEST(sokol_debugtext, putr) {
// test if sdtx_putr() draws the right amount of characters
init();
- _sdtx_vertex_t* start_ptr = _sdtx.cur_ctx->cur_vertex_ptr;
+ int start_index = _sdtx.cur_ctx->vertices.next;
sdtx_putr("Hello World!", 5);
- T((5 * 6) == (_sdtx.cur_ctx->cur_vertex_ptr - start_ptr));
+ T((5 * 6) == (_sdtx.cur_ctx->vertices.next - start_index));
- start_ptr = _sdtx.cur_ctx->cur_vertex_ptr;
+ start_index = _sdtx.cur_ctx->vertices.next;
sdtx_putr("Hello!\n\n\n\n\n\n\n\n\n\n\n", 10);
// NOTE: the \n's don't result in rendered vertices
- T((6 * 6) == (_sdtx.cur_ctx->cur_vertex_ptr - start_ptr));
+ T((6 * 6) == (_sdtx.cur_ctx->vertices.next - start_index));
shutdown();
}
@@ -434,3 +435,77 @@ UTEST(sokol_debugtext, default_context) {
T(sdtx_default_context().id == SDTX_DEFAULT_CONTEXT.id);
shutdown();
}
+
+// switching layers without any text inbetween should not advance the current draw command
+UTEST(sokol_debug_text, empty_layers) {
+ init();
+ T(_sdtx.cur_ctx->commands.next == 1);
+ T(_sdtx.cur_ctx->commands.ptr[0].layer_id == 0);
+ sdtx_layer(1);
+ T(_sdtx.cur_ctx->commands.next == 1);
+ T(_sdtx.cur_ctx->commands.ptr[0].layer_id == 1);
+ sdtx_layer(2);
+ T(_sdtx.cur_ctx->commands.next == 1);
+ T(_sdtx.cur_ctx->commands.ptr[0].layer_id == 2);
+ sdtx_layer(0);
+ T(_sdtx.cur_ctx->commands.next == 1);
+ T(_sdtx.cur_ctx->commands.ptr[0].layer_id == 0);
+ shutdown();
+}
+
+// switching layers with text inbetween should advance the current draw command
+UTEST(sokol_debug_text, non_empty_layers) {
+ init();
+ T(_sdtx.cur_ctx->commands.next == 1);
+ T(_sdtx.cur_ctx->commands.ptr[0].layer_id == 0);
+ T(_sdtx.cur_ctx->commands.ptr[0].first_vertex == 0);
+ T(_sdtx.cur_ctx->commands.ptr[0].num_vertices == 0);
+ sdtx_puts("123");
+ T(_sdtx.cur_ctx->commands.next == 1);
+ T(_sdtx.cur_ctx->commands.ptr[0].layer_id == 0);
+ T(_sdtx.cur_ctx->commands.ptr[0].first_vertex == 0);
+ T(_sdtx.cur_ctx->commands.ptr[0].num_vertices == (3 * 6));
+ sdtx_layer(1);
+ sdtx_puts("1234");
+ T(_sdtx.cur_ctx->commands.next == 2);
+ T(_sdtx.cur_ctx->commands.ptr[1].layer_id == 1);
+ T(_sdtx.cur_ctx->commands.ptr[1].first_vertex == (3 * 6));
+ T(_sdtx.cur_ctx->commands.ptr[1].num_vertices == (4 * 6));
+ // switching to same layer should not start a new draw commands
+ sdtx_layer(1);
+ sdtx_puts("12345");
+ T(_sdtx.cur_ctx->commands.next == 2);
+ T(_sdtx.cur_ctx->commands.ptr[1].layer_id == 1);
+ T(_sdtx.cur_ctx->commands.ptr[1].first_vertex == (3 * 6));
+ T(_sdtx.cur_ctx->commands.ptr[1].num_vertices == (9 * 6));
+ sdtx_layer(0);
+ sdtx_puts("123456");
+ T(_sdtx.cur_ctx->commands.next == 3);
+ T(_sdtx.cur_ctx->commands.ptr[2].layer_id == 0);
+ T(_sdtx.cur_ctx->commands.ptr[2].first_vertex == (12 * 6));
+ T(_sdtx.cur_ctx->commands.ptr[2].num_vertices == (6 * 6));
+ shutdown();
+}
+
+UTEST(sokol_debug_text, command_buffer_overflow) {
+ init_with(&(sdtx_desc_t){
+ .context = {
+ .max_commands = 4
+ }
+ });
+ sdtx_puts("0");
+ T(_sdtx.cur_ctx->commands.next == 1);
+ sdtx_layer(1);
+ sdtx_puts("1");
+ T(_sdtx.cur_ctx->commands.next == 2);
+ sdtx_layer(2);
+ sdtx_puts("2");
+ T(_sdtx.cur_ctx->commands.next == 3);
+ sdtx_layer(3);
+ sdtx_puts("3");
+ T(_sdtx.cur_ctx->commands.next == 4);
+ // from here on should fail
+ sdtx_layer(4);
+ sdtx_puts("4");
+ T(_sdtx.cur_ctx->commands.next == 4);
+} \ No newline at end of file
diff --git a/tests/functional/sokol_gl_test.c b/tests/functional/sokol_gl_test.c
index 656181ed..1310e440 100644
--- a/tests/functional/sokol_gl_test.c
+++ b/tests/functional/sokol_gl_test.c
@@ -26,15 +26,15 @@ UTEST(sokol_gl, default_init_shutdown) {
T(_sgl.def_ctx_id.id == SGL_DEFAULT_CONTEXT.id);
T(_sgl.cur_ctx_id.id == _sgl.def_ctx_id.id);
T(_sgl.cur_ctx);
- T(_sgl.cur_ctx->num_vertices == 65536);
- T(_sgl.cur_ctx->num_commands == 16384);
- T(_sgl.cur_ctx->num_uniforms == 16384);
- T(_sgl.cur_ctx->cur_vertex == 0);
- T(_sgl.cur_ctx->cur_command == 0);
- T(_sgl.cur_ctx->cur_uniform == 0);
- T(_sgl.cur_ctx->vertices != 0);
- T(_sgl.cur_ctx->uniforms != 0);
- T(_sgl.cur_ctx->commands != 0);
+ T(_sgl.cur_ctx->vertices.cap == 65536);
+ T(_sgl.cur_ctx->commands.cap == 16384);
+ T(_sgl.cur_ctx->uniforms.cap == 16384);
+ T(_sgl.cur_ctx->vertices.next == 0);
+ T(_sgl.cur_ctx->commands.next == 0);
+ T(_sgl.cur_ctx->uniforms.next == 0);
+ T(_sgl.cur_ctx->vertices.ptr != 0);
+ T(_sgl.cur_ctx->uniforms.ptr != 0);
+ T(_sgl.cur_ctx->commands.ptr != 0);
T(_sgl.cur_ctx->error == SGL_NO_ERROR);
T(!_sgl.cur_ctx->in_begin);
T(_sgl.cur_ctx->def_pip.id != SG_INVALID_ID);
@@ -49,42 +49,42 @@ UTEST(sokol_gl, default_init_shutdown) {
UTEST(sokol_gl, viewport) {
init();
sgl_viewport(1, 2, 3, 4, true);
- T(_sgl.cur_ctx->cur_command == 1);
- T(_sgl.cur_ctx->commands[0].cmd == SGL_COMMAND_VIEWPORT);
- T(_sgl.cur_ctx->commands[0].args.viewport.x == 1);
- T(_sgl.cur_ctx->commands[0].args.viewport.y == 2);
- T(_sgl.cur_ctx->commands[0].args.viewport.w == 3);
- T(_sgl.cur_ctx->commands[0].args.viewport.h == 4);
- T(_sgl.cur_ctx->commands[0].args.viewport.origin_top_left);
+ T(_sgl.cur_ctx->commands.next == 1);
+ T(_sgl.cur_ctx->commands.ptr[0].cmd == SGL_COMMAND_VIEWPORT);
+ T(_sgl.cur_ctx->commands.ptr[0].args.viewport.x == 1);
+ T(_sgl.cur_ctx->commands.ptr[0].args.viewport.y == 2);
+ T(_sgl.cur_ctx->commands.ptr[0].args.viewport.w == 3);
+ T(_sgl.cur_ctx->commands.ptr[0].args.viewport.h == 4);
+ T(_sgl.cur_ctx->commands.ptr[0].args.viewport.origin_top_left);
sgl_viewport(5, 6, 7, 8, false);
- T(_sgl.cur_ctx->cur_command == 2);
- T(_sgl.cur_ctx->commands[1].cmd == SGL_COMMAND_VIEWPORT);
- T(_sgl.cur_ctx->commands[1].args.viewport.x == 5);
- T(_sgl.cur_ctx->commands[1].args.viewport.y == 6);
- T(_sgl.cur_ctx->commands[1].args.viewport.w == 7);
- T(_sgl.cur_ctx->commands[1].args.viewport.h == 8);
- T(!_sgl.cur_ctx->commands[1].args.viewport.origin_top_left);
+ T(_sgl.cur_ctx->commands.next == 2);
+ T(_sgl.cur_ctx->commands.ptr[1].cmd == SGL_COMMAND_VIEWPORT);
+ T(_sgl.cur_ctx->commands.ptr[1].args.viewport.x == 5);
+ T(_sgl.cur_ctx->commands.ptr[1].args.viewport.y == 6);
+ T(_sgl.cur_ctx->commands.ptr[1].args.viewport.w == 7);
+ T(_sgl.cur_ctx->commands.ptr[1].args.viewport.h == 8);
+ T(!_sgl.cur_ctx->commands.ptr[1].args.viewport.origin_top_left);
shutdown();
}
UTEST(sokol_gl, scissor_rect) {
init();
sgl_scissor_rect(10, 20, 30, 40, true);
- T(_sgl.cur_ctx->cur_command == 1);
- T(_sgl.cur_ctx->commands[0].cmd == SGL_COMMAND_SCISSOR_RECT);
- T(_sgl.cur_ctx->commands[0].args.scissor_rect.x == 10);
- T(_sgl.cur_ctx->commands[0].args.scissor_rect.y == 20);
- T(_sgl.cur_ctx->commands[0].args.scissor_rect.w == 30);
- T(_sgl.cur_ctx->commands[0].args.scissor_rect.h == 40);
- T(_sgl.cur_ctx->commands[0].args.scissor_rect.origin_top_left);
+ T(_sgl.cur_ctx->commands.next == 1);
+ T(_sgl.cur_ctx->commands.ptr[0].cmd == SGL_COMMAND_SCISSOR_RECT);
+ T(_sgl.cur_ctx->commands.ptr[0].args.scissor_rect.x == 10);
+ T(_sgl.cur_ctx->commands.ptr[0].args.scissor_rect.y == 20);
+ T(_sgl.cur_ctx->commands.ptr[0].args.scissor_rect.w == 30);
+ T(_sgl.cur_ctx->commands.ptr[0].args.scissor_rect.h == 40);
+ T(_sgl.cur_ctx->commands.ptr[0].args.scissor_rect.origin_top_left);
sgl_scissor_rect(50, 60, 70, 80, false);
- T(_sgl.cur_ctx->cur_command == 2);
- T(_sgl.cur_ctx->commands[1].cmd == SGL_COMMAND_SCISSOR_RECT);
- T(_sgl.cur_ctx->commands[1].args.scissor_rect.x == 50);
- T(_sgl.cur_ctx->commands[1].args.scissor_rect.y == 60);
- T(_sgl.cur_ctx->commands[1].args.scissor_rect.w == 70);
- T(_sgl.cur_ctx->commands[1].args.scissor_rect.h == 80);
- T(!_sgl.cur_ctx->commands[1].args.scissor_rect.origin_top_left);
+ T(_sgl.cur_ctx->commands.next == 2);
+ T(_sgl.cur_ctx->commands.ptr[1].cmd == SGL_COMMAND_SCISSOR_RECT);
+ T(_sgl.cur_ctx->commands.ptr[1].args.scissor_rect.x == 50);
+ T(_sgl.cur_ctx->commands.ptr[1].args.scissor_rect.y == 60);
+ T(_sgl.cur_ctx->commands.ptr[1].args.scissor_rect.w == 70);
+ T(_sgl.cur_ctx->commands.ptr[1].args.scissor_rect.h == 80);
+ T(!_sgl.cur_ctx->commands.ptr[1].args.scissor_rect.origin_top_left);
shutdown();
}
@@ -111,14 +111,14 @@ UTEST(sokol_gl, begin_end) {
sgl_v3f(7.0f, 8.0f, 9.0f);
sgl_end();
T(_sgl.cur_ctx->base_vertex == 0);
- T(_sgl.cur_ctx->cur_vertex == 3);
- T(_sgl.cur_ctx->cur_command == 1);
- T(_sgl.cur_ctx->cur_uniform == 1);
- T(_sgl.cur_ctx->commands[0].cmd == SGL_COMMAND_DRAW);
- T(_sgl.cur_ctx->commands[0].args.draw.pip.id == _sgl_pipeline_at(_sgl.cur_ctx->def_pip.id)->pip[SGL_PRIMITIVETYPE_TRIANGLES].id);
- T(_sgl.cur_ctx->commands[0].args.draw.base_vertex == 0);
- T(_sgl.cur_ctx->commands[0].args.draw.num_vertices == 3);
- T(_sgl.cur_ctx->commands[0].args.draw.uniform_index == 0);
+ T(_sgl.cur_ctx->vertices.next == 3);
+ T(_sgl.cur_ctx->commands.next == 1);
+ T(_sgl.cur_ctx->uniforms.next == 1);
+ T(_sgl.cur_ctx->commands.ptr[0].cmd == SGL_COMMAND_DRAW);
+ T(_sgl.cur_ctx->commands.ptr[0].args.draw.pip.id == _sgl_pipeline_at(_sgl.cur_ctx->def_pip.id)->pip[SGL_PRIMITIVETYPE_TRIANGLES].id);
+ T(_sgl.cur_ctx->commands.ptr[0].args.draw.base_vertex == 0);
+ T(_sgl.cur_ctx->commands.ptr[0].args.draw.num_vertices == 3);
+ T(_sgl.cur_ctx->commands.ptr[0].args.draw.uniform_index == 0);
shutdown();
}
@@ -223,9 +223,9 @@ UTEST(sokol_gl, make_destroy_contexts) {
// creating a context should not change the current context
T(ctx.id != _sgl.cur_ctx_id.id);
sgl_set_context(ctx);
- T(_sgl.cur_ctx->num_vertices == 1024);
- T(_sgl.cur_ctx->num_commands == 256);
- T(_sgl.cur_ctx->num_uniforms == 256);
+ T(_sgl.cur_ctx->vertices.cap == 1024);
+ T(_sgl.cur_ctx->commands.cap == 256);
+ T(_sgl.cur_ctx->uniforms.cap == 256);
T(ctx.id == _sgl.cur_ctx_id.id);
T(sgl_get_context().id == ctx.id);
sgl_set_context(SGL_DEFAULT_CONTEXT);
diff --git a/util/sokol_debugtext.h b/util/sokol_debugtext.h
index 89f141db..85321f3a 100644
--- a/util/sokol_debugtext.h
+++ b/util/sokol_debugtext.h
@@ -93,6 +93,11 @@
be active right after sdtx_setup(), or when calling
sdtx_set_context(SDTX_DEFAULT_CONTEXT):
+ .max_commands (default: 4096)
+ The max number of render commands that can be recorded
+ into the internal command buffer. This directly translates
+ to the number of render layer changes in a single frame.
+
.char_buf_size (default: 4096)
The number of characters that can be rendered per frame in this
context, defines the size of an internal fixed-size vertex
@@ -220,14 +225,36 @@
\n - carriage return + line feed (same as stdx_crlf())
\t - a tab character
+ --- You can 'record' text into render layers, this allows to mix/interleave
+ sokol-debugtext rendering with other rendering operations inside
+ sokol-gfx render passes. To start recording text into a different render
+ layer, call:
+
+ sdtx_layer(int layer_id)
+
+ ...outside a sokol-gfx render pass.
+
--- finally, from within a sokol-gfx render pass, call:
sdtx_draw()
- ...to actually render the text. Calling sdtx_draw() will also rewind
- the text context:
+ ...for non-layered rendering, or to draw a specific layer:
+
+ sdtx_draw_layer(int layer_id)
+
+ NOTE that sdtx_draw() is equivalent to:
- - the internal vertex buffer pointer is reset to the beginning
+ sdtx_draw_layer(0)
+
+ ...so sdtx_draw() will *NOT* render all text layers, instead it will
+ only render the 'default layer' 0.
+
+ --- at the end of a frame (defined by the call to sg_commit()), sokol-debugtext
+ will rewind all contexts:
+
+ - the internal vertex index is set to 0
+ - the internal command index is set to 0
+ - the current layer id is set to 0
- the current font is set to 0
- the cursor position is reset
@@ -268,7 +295,8 @@
- the origin position
- the current cursor position
- the current tab width
- - and the current color
+ - the current color
+ - and the current layer-id
You can get the currently active context with:
@@ -291,6 +319,12 @@
If a context is set as active that no longer exists, all sokol-debugtext
functions that require an active context will silently fail.
+ You can directly draw the recorded text in a specific context without
+ setting the active context:
+
+ sdtx_context_draw(ctx)
+ sdtx_context_draw_layer(ctx, layer_id)
+
USING YOUR OWN FONT DATA
========================
@@ -540,6 +574,7 @@ typedef struct sdtx_font_desc_t {
of text.
*/
typedef struct sdtx_context_desc_t {
+ int max_commands; // max number of draw commands, each layer transition counts as a command, default: 4096
int char_buf_size; // max number of characters rendered in one frame, default: 4096
float canvas_width; // the initial virtual canvas width, default: 640
float canvas_height; // the initial virtual canvas height, default: 400
@@ -618,8 +653,14 @@ SOKOL_DEBUGTEXT_API_DECL void sdtx_set_context(sdtx_context ctx);
SOKOL_DEBUGTEXT_API_DECL sdtx_context sdtx_get_context(void);
SOKOL_DEBUGTEXT_API_DECL sdtx_context sdtx_default_context(void);
-/* draw and rewind the current context */
+/* drawing functions (call inside sokol-gfx render pass) */
SOKOL_DEBUGTEXT_API_DECL void sdtx_draw(void);
+SOKOL_DEBUGTEXT_API_DECL void sdtx_context_draw(sdtx_context ctx);
+SOKOL_DEBUGTEXT_API_DECL void sdtx_draw_layer(int layer_id);
+SOKOL_DEBUGTEXT_API_DECL void sdtx_context_draw_layer(sdtx_context ctx, int layer_id);
+
+/* switch render layer */
+SOKOL_DEBUGTEXT_API_DECL void sdtx_layer(int layer_id);
/* switch to a different font */
SOKOL_DEBUGTEXT_API_DECL void sdtx_font(int font_index);
@@ -718,9 +759,10 @@ inline sdtx_context sdtx_make_context(const sdtx_context_desc_t& desc) { return
#define _sdtx_def(val, def) (((val) == 0) ? (def) : (val))
#define _SDTX_INIT_COOKIE (0xACBAABCA)
+#define _SDTX_DEFAULT_MAX_COMMANDS (4096)
#define _SDTX_DEFAULT_CONTEXT_POOL_SIZE (8)
-#define _SDTX_DEFAULT_CHAR_BUF_SIZE (1<<12)
-#define _SDTX_DEFAULT_PRINTF_BUF_SIZE (1<<12)
+#define _SDTX_DEFAULT_CHAR_BUF_SIZE (4096)
+#define _SDTX_DEFAULT_PRINTF_BUF_SIZE (4096)
#define _SDTX_DEFAULT_CANVAS_WIDTH (640)
#define _SDTX_DEFAULT_CANVAS_HEIGHT (480)
#define _SDTX_DEFAULT_TAB_WIDTH (4)
@@ -3479,14 +3521,30 @@ typedef struct {
} _sdtx_vertex_t;
typedef struct {
+ int layer_id;
+ int first_vertex;
+ int num_vertices;
+} _sdtx_command_t;
+
+typedef struct {
_sdtx_slot_t slot;
sdtx_context_desc_t desc;
- _sdtx_vertex_t* cur_vertex_ptr;
- const _sdtx_vertex_t* max_vertex_ptr;
- _sdtx_vertex_t* vertices;
+ uint32_t frame_id;
+ uint32_t update_frame_id;
+ struct {
+ int cap;
+ int next;
+ _sdtx_vertex_t* ptr;
+ } vertices;
+ struct {
+ int cap;
+ int next;
+ _sdtx_command_t* ptr;
+ } commands;
sg_buffer vbuf;
sg_pipeline pip;
int cur_font;
+ int cur_layer_id;
_sdtx_float2_t canvas_size;
_sdtx_float2_t glyph_size;
_sdtx_float2_t origin;
@@ -3704,6 +3762,7 @@ static sdtx_context _sdtx_alloc_context(void) {
static sdtx_context_desc_t _sdtx_context_desc_defaults(const sdtx_context_desc_t* desc) {
sdtx_context_desc_t res = *desc;
+ res.max_commands = _sdtx_def(res.max_commands, _SDTX_DEFAULT_MAX_COMMANDS);
res.char_buf_size = _sdtx_def(res.char_buf_size, _SDTX_DEFAULT_CHAR_BUF_SIZE);
res.canvas_width = _sdtx_def(res.canvas_width, _SDTX_DEFAULT_CANVAS_WIDTH);
res.canvas_height = _sdtx_def(res.canvas_height, _SDTX_DEFAULT_CANVAS_HEIGHT);
@@ -3715,6 +3774,30 @@ static sdtx_context_desc_t _sdtx_context_desc_defaults(const sdtx_context_desc_t
return res;
}
+static void _sdtx_set_layer(_sdtx_context_t* ctx, int layer_id);
+static void _sdtx_rewind(_sdtx_context_t* ctx) {
+ SOKOL_ASSERT(ctx);
+ ctx->frame_id++;
+ ctx->vertices.next = 0;
+ ctx->commands.next = 0;
+ _sdtx_set_layer(ctx, 0);
+ ctx->cur_font = 0;
+ ctx->pos.x = 0.0f;
+ ctx->pos.y = 0.0f;
+}
+
+static void _sdtx_commit_listener(void* userdata) {
+ _sdtx_context_t* ctx = _sdtx_lookup_context((uint32_t)(uintptr_t)userdata);
+ if (ctx) {
+ _sdtx_rewind(ctx);
+ }
+}
+
+static sg_commit_listener _sdtx_make_commit_listener(_sdtx_context_t* ctx) {
+ sg_commit_listener listener = { _sdtx_commit_listener, (void*)(uintptr_t)(ctx->slot.id) };
+ return listener;
+}
+
static void _sdtx_init_context(sdtx_context ctx_id, const sdtx_context_desc_t* in_desc) {
sg_push_debug_group("sokol-debugtext");
@@ -3722,12 +3805,16 @@ static void _sdtx_init_context(sdtx_context ctx_id, const sdtx_context_desc_t* i
_sdtx_context_t* ctx = _sdtx_lookup_context(ctx_id.id);
SOKOL_ASSERT(ctx);
ctx->desc = _sdtx_context_desc_defaults(in_desc);
+ // NOTE: frame_id must be non-zero, so that updates trigger in first frame
+ ctx->frame_id = 1;
+
+ ctx->vertices.cap = 6 * ctx->desc.char_buf_size;
+ const size_t vbuf_size = (size_t)ctx->vertices.cap * sizeof(_sdtx_vertex_t);
+ ctx->vertices.ptr = (_sdtx_vertex_t*) _sdtx_malloc(vbuf_size);
- const int max_vertices = 6 * ctx->desc.char_buf_size;
- const size_t vbuf_size = (size_t)max_vertices * sizeof(_sdtx_vertex_t);
- ctx->vertices = (_sdtx_vertex_t*) _sdtx_malloc(vbuf_size);
- ctx->cur_vertex_ptr = ctx->vertices;
- ctx->max_vertex_ptr = ctx->vertices + max_vertices;
+ ctx->commands.cap = ctx->desc.max_commands;
+ ctx->commands.ptr = (_sdtx_command_t*) _sdtx_malloc((size_t)ctx->commands.cap * sizeof(_sdtx_command_t));
+ _sdtx_set_layer(ctx, 0);
sg_buffer_desc vbuf_desc;
_sdtx_clear(&vbuf_desc, sizeof(vbuf_desc));
@@ -3765,21 +3852,33 @@ static void _sdtx_init_context(sdtx_context ctx_id, const sdtx_context_desc_t* i
ctx->tab_width = (float) ctx->desc.tab_width;
ctx->color = _SDTX_DEFAULT_COLOR;
+ if (!sg_add_commit_listener(_sdtx_make_commit_listener(ctx))) {
+ // FIXME: this should actually result in an invalid context,
+ // fix this when proper error logging/reporting is added
+ SDTX_LOG("sokol_debugtext.h: failed to add sokol-gfx commit listener");
+ }
sg_pop_debug_group();
}
static void _sdtx_destroy_context(sdtx_context ctx_id) {
_sdtx_context_t* ctx = _sdtx_lookup_context(ctx_id.id);
if (ctx) {
- if (ctx->vertices) {
- _sdtx_free(ctx->vertices);
- ctx->vertices = 0;
- ctx->cur_vertex_ptr = 0;
- ctx->max_vertex_ptr = 0;
+ if (ctx->vertices.ptr) {
+ _sdtx_free(ctx->vertices.ptr);
+ ctx->vertices.ptr = 0;
+ ctx->vertices.cap = 0;
+ ctx->vertices.next = 0;
+ }
+ if (ctx->commands.ptr) {
+ _sdtx_free(ctx->commands.ptr);
+ ctx->commands.ptr = 0;
+ ctx->commands.cap = 0;
+ ctx->commands.next = 0;
}
sg_push_debug_group("sokol_debugtext");
sg_destroy_buffer(ctx->vbuf);
sg_destroy_pipeline(ctx->pip);
+ sg_remove_commit_listener(_sdtx_make_commit_listener(ctx));
sg_pop_debug_group();
_sdtx_clear(ctx, sizeof(*ctx));
_sdtx_pool_free_index(&_sdtx.context_pool.pool, _sdtx_slot_index(ctx_id.id));
@@ -3869,7 +3968,7 @@ static void _sdtx_setup_common(void) {
/* unpack font data */
memset(_sdtx.font_pixels, 0xFF, sizeof(_sdtx.font_pixels));
- const int unpacked_font_size = 256 * 8 * 8;
+ const int unpacked_font_size = (int) (sizeof(_sdtx.font_pixels) / SDTX_MAX_FONTS);
for (int i = 0; i < SDTX_MAX_FONTS; i++) {
if (_sdtx.desc.fonts[i].data.ptr) {
_sdtx_unpack_font(&_sdtx.desc.fonts[i], &_sdtx.font_pixels[i * unpacked_font_size]);
@@ -3887,6 +3986,7 @@ static void _sdtx_setup_common(void) {
img_desc.wrap_u = SG_WRAP_CLAMP_TO_EDGE;
img_desc.wrap_v = SG_WRAP_CLAMP_TO_EDGE;
img_desc.data.subimage[0][0] = SG_RANGE(_sdtx.font_pixels);
+ img_desc.label = "sdtx-font-texture";
_sdtx.font_img = sg_make_image(&img_desc);
SOKOL_ASSERT(SG_INVALID_ID != _sdtx.font_img.id);
@@ -3904,17 +4004,17 @@ static void _sdtx_discard_common(void) {
sg_pop_debug_group();
}
-static inline uint32_t _sdtx_pack_rgbab(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
+static uint32_t _sdtx_pack_rgbab(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
return (uint32_t)(((uint32_t)a<<24)|((uint32_t)b<<16)|((uint32_t)g<<8)|r);
}
-static inline float _sdtx_clamp(float v, float lo, float hi) {
+static float _sdtx_clamp(float v, float lo, float hi) {
if (v < lo) return lo;
else if (v > hi) return hi;
else return v;
}
-static inline uint32_t _sdtx_pack_rgbaf(float r, float g, float b, float a) {
+static uint32_t _sdtx_pack_rgbaf(float r, float g, float b, float a) {
uint8_t r_u8 = (uint8_t) (_sdtx_clamp(r, 0.0f, 1.0f) * 255.0f);
uint8_t g_u8 = (uint8_t) (_sdtx_clamp(g, 0.0f, 1.0f) * 255.0f);
uint8_t b_u8 = (uint8_t) (_sdtx_clamp(b, 0.0f, 1.0f) * 255.0f);
@@ -3922,7 +4022,7 @@ static inline uint32_t _sdtx_pack_rgbaf(float r, float g, float b, float a) {
return _sdtx_pack_rgbab(r_u8, g_u8, b_u8, a_u8);
}
-static inline void _sdtx_ctrl_char(_sdtx_context_t* ctx, uint8_t c) {
+static void _sdtx_ctrl_char(_sdtx_context_t* ctx, uint8_t c) {
switch (c) {
case '\r':
ctx->pos.x = 0.0f;
@@ -3940,31 +4040,88 @@ static inline void _sdtx_ctrl_char(_sdtx_context_t* ctx, uint8_t c) {
}
}
-static inline void _sdtx_draw_char(_sdtx_context_t* ctx, uint8_t c) {
- if ((ctx->cur_vertex_ptr + 6) <= ctx->max_vertex_ptr) {
+static _sdtx_vertex_t* _sdtx_next_vertex(_sdtx_context_t* ctx) {
+ if ((ctx->vertices.next + 6) <= ctx->vertices.cap) {
+ _sdtx_vertex_t* vx = &ctx->vertices.ptr[ctx->vertices.next];
+ ctx->vertices.next += 6;
+ return vx;
+ }
+ else {
+ return 0;
+ }
+}
+
+static _sdtx_command_t* _sdtx_cur_command(_sdtx_context_t* ctx) {
+ if (ctx->commands.next > 0) {
+ return &ctx->commands.ptr[ctx->commands.next - 1];
+ }
+ else {
+ return 0;
+ }
+}
+
+static _sdtx_command_t* _sdtx_next_command(_sdtx_context_t* ctx) {
+ if (ctx->commands.next < ctx->commands.cap) {
+ return &ctx->commands.ptr[ctx->commands.next++];
+ }
+ else {
+ SDTX_LOG("sokol_debugtext.h: command buffer full");
+ return 0;
+ }
+}
+
+static void _sdtx_set_layer(_sdtx_context_t* ctx, int layer_id) {
+ ctx->cur_layer_id = layer_id;
+ _sdtx_command_t* cur_cmd = _sdtx_cur_command(ctx);
+ if (cur_cmd) {
+ if ((cur_cmd->num_vertices == 0) || (cur_cmd->layer_id == layer_id)) {
+ // no vertices recorded in current draw command, or layer hasn't changed, can just reuse this
+ cur_cmd->layer_id = layer_id;
+ }
+ else {
+ // layer has changed, need to start a new draw command
+ _sdtx_command_t* next_cmd = _sdtx_next_command(ctx);
+ if (next_cmd) {
+ next_cmd->layer_id = layer_id;
+ next_cmd->first_vertex = cur_cmd->first_vertex + cur_cmd->num_vertices;
+ next_cmd->num_vertices = 0;
+ }
+ }
+ }
+ else {
+ // first draw command in frame
+ _sdtx_command_t* next_cmd = _sdtx_next_command(ctx);
+ if (next_cmd) {
+ next_cmd->layer_id = layer_id;
+ next_cmd->first_vertex = 0;
+ next_cmd->num_vertices = 0;
+ }
+ }
+}
+
+static void _sdtx_render_char(_sdtx_context_t* ctx, uint8_t c) {
+ _sdtx_vertex_t* vx = _sdtx_next_vertex(ctx);
+ _sdtx_command_t* cmd = _sdtx_cur_command(ctx);
+ if (vx && cmd) {
+ // update vertex count in current draw command
+ cmd->num_vertices += 6;
+
const float x0 = (ctx->origin.x + ctx->pos.x) * ctx->glyph_size.x;
const float y0 = (ctx->origin.y + ctx->pos.y) * ctx->glyph_size.y;
const float x1 = x0 + ctx->glyph_size.x;
const float y1 = y0 + ctx->glyph_size.y;
// glyph width and heigth in font texture space
+ // NOTE: the '+1' and '-2' fixes texture bleeding into the neighboring font texture cell
const uint16_t uvw = 0x10000 / 0x100;
const uint16_t uvh = 0x10000 / SDTX_MAX_FONTS;
- const uint16_t u0 = ((uint16_t)c) * uvw;
- const uint16_t v0 = ((uint16_t)ctx->cur_font) * uvh;
- uint16_t u1 = u0 + uvw;
- uint16_t v1 = v0 + uvh;
- if (u1 == 0x0000) {
- u1 = 0xFFFF;
- }
- if (v1 == 0x0000) {
- v1 = 0xFFFF;
- }
+ const uint16_t u0 = (((uint16_t)c) * uvw) + 1;
+ const uint16_t v0 = (((uint16_t)ctx->cur_font) * uvh) + 1;
+ uint16_t u1 = (u0 + uvw) - 2;
+ uint16_t v1 = (v0 + uvh) - 2;
const uint32_t color = ctx->color;
// write 6 vertices
- _sdtx_vertex_t* vx = ctx->cur_vertex_ptr;
-
vx->x=x0; vx->y=y0; vx->u = u0; vx->v = v0; vx->color = color; vx++;
vx->x=x1; vx->y=y0; vx->u = u1; vx->v = v0; vx->color = color; vx++;
vx->x=x1; vx->y=y1; vx->u = u1; vx->v = v1; vx->color = color; vx++;
@@ -3972,22 +4129,51 @@ static inline void _sdtx_draw_char(_sdtx_context_t* ctx, uint8_t c) {
vx->x=x0; vx->y=y0; vx->u = u0; vx->v = v0; vx->color = color; vx++;
vx->x=x1; vx->y=y1; vx->u = u1; vx->v = v1; vx->color = color; vx++;
vx->x=x0; vx->y=y1; vx->u = u0; vx->v = v1; vx->color = color; vx++;
-
- ctx->cur_vertex_ptr = vx;
}
ctx->pos.x += 1.0f;
}
-static inline void _sdtx_put_char(_sdtx_context_t* ctx, char c) {
+static void _sdtx_put_char(_sdtx_context_t* ctx, char c) {
uint8_t c_u8 = (uint8_t)c;
if (c_u8 <= 32) {
_sdtx_ctrl_char(ctx, c_u8);
}
else {
- _sdtx_draw_char(ctx, c_u8);
+ _sdtx_render_char(ctx, c_u8);
}
}
+SOKOL_API_IMPL void _sdtx_draw_layer(_sdtx_context_t* ctx, int layer_id) {
+ SOKOL_ASSERT(_SDTX_INIT_COOKIE == _sdtx.init_cookie);
+ SOKOL_ASSERT(ctx);
+ if ((ctx->vertices.next > 0) && (ctx->commands.next > 0)) {
+ sg_push_debug_group("sokol-debugtext");
+
+ if (ctx->update_frame_id != ctx->frame_id) {
+ ctx->update_frame_id = ctx->frame_id;
+ const sg_range range = { ctx->vertices.ptr, (size_t)ctx->vertices.next * sizeof(_sdtx_vertex_t) };
+ sg_update_buffer(ctx->vbuf, &range);
+ }
+
+ sg_apply_pipeline(ctx->pip);
+ sg_bindings bindings;
+ _sdtx_clear(&bindings, sizeof(bindings));
+ bindings.vertex_buffers[0] = ctx->vbuf;
+ bindings.fs_images[0] = _sdtx.font_img;
+ sg_apply_bindings(&bindings);
+ for (int cmd_index = 0; cmd_index < ctx->commands.next; cmd_index++) {
+ const _sdtx_command_t* cmd = &ctx->commands.ptr[cmd_index];
+ if (cmd->layer_id != layer_id) {
+ continue;
+ }
+ SOKOL_ASSERT((cmd->num_vertices % 6) == 0);
+ sg_draw(cmd->first_vertex, cmd->num_vertices, 1);
+ }
+ sg_pop_debug_group();
+ }
+}
+
+
static sdtx_desc_t _sdtx_desc_defaults(const sdtx_desc_t* desc) {
SOKOL_ASSERT((desc->allocator.alloc && desc->allocator.free) || (!desc->allocator.alloc && !desc->allocator.free));
sdtx_desc_t res = *desc;
@@ -4106,6 +4292,14 @@ SOKOL_API_IMPL sdtx_context sdtx_default_context(void) {
return SDTX_DEFAULT_CONTEXT;
}
+SOKOL_API_IMPL void sdtx_layer(int layer_id) {
+ SOKOL_ASSERT(_SDTX_INIT_COOKIE == _sdtx.init_cookie);
+ _sdtx_context_t* ctx = _sdtx.cur_ctx;
+ if (ctx) {
+ _sdtx_set_layer(ctx, layer_id);
+ }
+}
+
SOKOL_API_IMPL void sdtx_font(int font_index) {
SOKOL_ASSERT(_SDTX_INIT_COOKIE == _sdtx.init_cookie);
SOKOL_ASSERT((font_index >= 0) && (font_index < SDTX_MAX_FONTS));
@@ -4308,27 +4502,31 @@ SOKOL_API_IMPL void sdtx_draw(void) {
SOKOL_ASSERT(_SDTX_INIT_COOKIE == _sdtx.init_cookie);
_sdtx_context_t* ctx = _sdtx.cur_ctx;
if (ctx) {
- const int num_verts = (int) (ctx->cur_vertex_ptr - ctx->vertices);
- if (num_verts > 0) {
- SOKOL_ASSERT((num_verts % 6) == 0);
- sg_push_debug_group("sokol-debugtext");
- const sg_range range = { ctx->vertices, (size_t)num_verts * sizeof(_sdtx_vertex_t) };
- int vbuf_offset = sg_append_buffer(ctx->vbuf, &range);
- sg_apply_pipeline(ctx->pip);
- sg_bindings bindings;
- _sdtx_clear(&bindings, sizeof(bindings));
- bindings.vertex_buffers[0] = ctx->vbuf;
- bindings.vertex_buffer_offsets[0] = vbuf_offset;
- bindings.fs_images[0] = _sdtx.font_img;
- sg_apply_bindings(&bindings);
- sg_draw(0, num_verts, 1);
- sg_pop_debug_group();
- }
- ctx->cur_vertex_ptr = ctx->vertices;
- ctx->cur_font = 0;
- ctx->pos.x = 0.0f;
- ctx->pos.y = 0.0f;
+ _sdtx_draw_layer(ctx, 0);
+ }
+}
+
+SOKOL_API_IMPL void sdtx_context_draw(sdtx_context ctx_id) {
+ SOKOL_ASSERT(_SDTX_INIT_COOKIE == _sdtx.init_cookie);
+ _sdtx_context_t* ctx = _sdtx_lookup_context(ctx_id.id);
+ if (ctx) {
+ _sdtx_draw_layer(ctx, 0);
}
}
+SOKOL_API_IMPL void sdtx_draw_layer(int layer_id) {
+ SOKOL_ASSERT(_SDTX_INIT_COOKIE == _sdtx.init_cookie);
+ _sdtx_context_t* ctx = _sdtx.cur_ctx;
+ if (ctx) {
+ _sdtx_draw_layer(ctx, layer_id);
+ }
+}
+
+SOKOL_API_IMPL void sdtx_context_draw_layer(sdtx_context ctx_id, int layer_id) {
+ SOKOL_ASSERT(_SDTX_INIT_COOKIE == _sdtx.init_cookie);
+ _sdtx_context_t* ctx = _sdtx_lookup_context(ctx_id.id);
+ if (ctx) {
+ _sdtx_draw_layer(ctx, layer_id);
+ }
+}
#endif /* SOKOL_DEBUGTEXT_IMPL */
diff --git a/util/sokol_gl.h b/util/sokol_gl.h
index af2ac3e6..eeb0ad70 100644
--- a/util/sokol_gl.h
+++ b/util/sokol_gl.h
@@ -2321,16 +2321,21 @@ typedef struct {
sgl_context_desc_t desc;
uint32_t frame_id;
uint32_t update_frame_id;
-
- int num_vertices;
- int num_uniforms;
- int num_commands;
- int cur_vertex;
- int cur_uniform;
- int cur_command;
- _sgl_vertex_t* vertices;
- _sgl_uniform_t* uniforms;
- _sgl_command_t* commands;
+ struct {
+ int cap;
+ int next;
+ _sgl_vertex_t* ptr;
+ } vertices;
+ struct {
+ int cap;
+ int next;
+ _sgl_uniform_t* ptr;
+ } uniforms;
+ struct {
+ int cap;
+ int next;
+ _sgl_command_t* ptr;
+ } commands;
/* state tracking */
int base_vertex;
@@ -2483,9 +2488,9 @@ static void _sgl_pool_free_index(_sgl_pool_t* pool, int slot_index) {
static void _sgl_reset_context(_sgl_context_t* ctx) {
SOKOL_ASSERT(ctx);
- SOKOL_ASSERT(0 == ctx->vertices);
- SOKOL_ASSERT(0 == ctx->uniforms);
- SOKOL_ASSERT(0 == ctx->commands);
+ SOKOL_ASSERT(0 == ctx->vertices.ptr);
+ SOKOL_ASSERT(0 == ctx->uniforms.ptr);
+ SOKOL_ASSERT(0 == ctx->commands.ptr);
_sgl_clear(ctx, sizeof(_sgl_context_t));
}
@@ -2763,18 +2768,18 @@ static void _sgl_init_context(sgl_context ctx_id, const sgl_context_desc_t* in_d
ctx->cur_img = _sgl.def_img;
// allocate buffers and pools
- ctx->num_vertices = ctx->desc.max_vertices;
- ctx->num_commands = ctx->num_uniforms = ctx->desc.max_commands;
- ctx->vertices = (_sgl_vertex_t*) _sgl_malloc((size_t)ctx->num_vertices * sizeof(_sgl_vertex_t));
- ctx->uniforms = (_sgl_uniform_t*) _sgl_malloc((size_t)ctx->num_uniforms * sizeof(_sgl_uniform_t));
- ctx->commands = (_sgl_command_t*) _sgl_malloc((size_t)ctx->num_commands * sizeof(_sgl_command_t));
+ ctx->vertices.cap = ctx->desc.max_vertices;
+ ctx->commands.cap = ctx->uniforms.cap = ctx->desc.max_commands;
+ ctx->vertices.ptr = (_sgl_vertex_t*) _sgl_malloc((size_t)ctx->vertices.cap * sizeof(_sgl_vertex_t));
+ ctx->uniforms.ptr = (_sgl_uniform_t*) _sgl_malloc((size_t)ctx->uniforms.cap * sizeof(_sgl_uniform_t));
+ ctx->commands.ptr = (_sgl_command_t*) _sgl_malloc((size_t)ctx->commands.cap * sizeof(_sgl_command_t));
// create sokol-gfx resource objects
sg_push_debug_group("sokol-gl");
sg_buffer_desc vbuf_desc;
_sgl_clear(&vbuf_desc, sizeof(vbuf_desc));
- vbuf_desc.size = (size_t)ctx->num_vertices * sizeof(_sgl_vertex_t);
+ vbuf_desc.size = (size_t)ctx->vertices.cap * sizeof(_sgl_vertex_t);
vbuf_desc.type = SG_BUFFERTYPE_VERTEXBUFFER;
vbuf_desc.usage = SG_USAGE_STREAM;
vbuf_desc.label = "sgl-vertex-buffer";
@@ -2818,17 +2823,16 @@ static sgl_context _sgl_make_context(const sgl_context_desc_t* desc) {
static void _sgl_destroy_context(sgl_context ctx_id) {
_sgl_context_t* ctx = _sgl_lookup_context(ctx_id.id);
if (ctx) {
- SOKOL_ASSERT(ctx->vertices);
- SOKOL_ASSERT(ctx->uniforms);
- SOKOL_ASSERT(ctx->commands);
-
- _sgl_free(ctx->vertices);
- _sgl_free(ctx->uniforms);
- _sgl_free(ctx->commands);
+ SOKOL_ASSERT(ctx->vertices.ptr);
+ SOKOL_ASSERT(ctx->uniforms.ptr);
+ SOKOL_ASSERT(ctx->commands.ptr);
- ctx->vertices = 0;
- ctx->uniforms = 0;
- ctx->commands = 0;
+ _sgl_free(ctx->vertices.ptr);
+ _sgl_free(ctx->uniforms.ptr);
+ _sgl_free(ctx->commands.ptr);
+ ctx->vertices.ptr = 0;
+ ctx->uniforms.ptr = 0;
+ ctx->commands.ptr = 0;
sg_push_debug_group("sokol-gl");
sg_destroy_buffer(ctx->vbuf);
@@ -2841,18 +2845,18 @@ static void _sgl_destroy_context(sgl_context ctx_id) {
}
}
-static inline void _sgl_begin(_sgl_context_t* ctx, _sgl_primitive_type_t mode) {
+static void _sgl_begin(_sgl_context_t* ctx, _sgl_primitive_type_t mode) {
ctx->in_begin = true;
- ctx->base_vertex = ctx->cur_vertex;
+ ctx->base_vertex = ctx->vertices.next;
ctx->vtx_count = 0;
ctx->cur_prim_type = mode;
}
static void _sgl_rewind(_sgl_context_t* ctx) {
ctx->frame_id++;
- ctx->cur_vertex = 0;
- ctx->cur_uniform = 0;
- ctx->cur_command = 0;
+ ctx->vertices.next = 0;
+ ctx->uniforms.next = 0;
+ ctx->commands.next = 0;
ctx->base_vertex = 0;
ctx->error = SGL_NO_ERROR;
ctx->layer_id = 0;
@@ -2872,9 +2876,9 @@ static sg_commit_listener _sgl_make_commit_listener(_sgl_context_t* ctx) {
return listener;
}
-static inline _sgl_vertex_t* _sgl_next_vertex(_sgl_context_t* ctx) {
- if (ctx->cur_vertex < ctx->num_vertices) {
- return &ctx->vertices[ctx->cur_vertex++];
+static _sgl_vertex_t* _sgl_next_vertex(_sgl_context_t* ctx) {
+ if (ctx->vertices.next < ctx->vertices.cap) {
+ return &ctx->vertices.ptr[ctx->vertices.next++];
}
else {
ctx->error = SGL_ERROR_VERTICES_FULL;
@@ -2882,9 +2886,9 @@ static inline _sgl_vertex_t* _sgl_next_vertex(_sgl_context_t* ctx) {
}
}
-static inline _sgl_uniform_t* _sgl_next_uniform(_sgl_context_t* ctx) {
- if (ctx->cur_uniform < ctx->num_uniforms) {
- return &ctx->uniforms[ctx->cur_uniform++];
+static _sgl_uniform_t* _sgl_next_uniform(_sgl_context_t* ctx) {
+ if (ctx->uniforms.next < ctx->uniforms.cap) {
+ return &ctx->uniforms.ptr[ctx->uniforms.next++];
}
else {
ctx->error = SGL_ERROR_UNIFORMS_FULL;
@@ -2892,18 +2896,18 @@ static inline _sgl_uniform_t* _sgl_next_uniform(_sgl_context_t* ctx) {
}
}
-static inline _sgl_command_t* _sgl_prev_command(_sgl_context_t* ctx) {
- if (ctx->cur_command > 0) {
- return &ctx->commands[ctx->cur_command - 1];
+static _sgl_command_t* _sgl_cur_command(_sgl_context_t* ctx) {
+ if (ctx->commands.next > 0) {
+ return &ctx->commands.ptr[ctx->commands.next - 1];
}
else {
return 0;
}
}
-static inline _sgl_command_t* _sgl_next_command(_sgl_context_t* ctx) {
- if (ctx->cur_command < ctx->num_commands) {
- return &ctx->commands[ctx->cur_command++];
+static _sgl_command_t* _sgl_next_command(_sgl_context_t* ctx) {
+ if (ctx->commands.next < ctx->commands.cap) {
+ return &ctx->commands.ptr[ctx->commands.next++];
}
else {
ctx->error = SGL_ERROR_COMMANDS_FULL;
@@ -2911,17 +2915,17 @@ static inline _sgl_command_t* _sgl_next_command(_sgl_context_t* ctx) {
}
}
-static inline uint32_t _sgl_pack_rgbab(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
+static uint32_t _sgl_pack_rgbab(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
return (uint32_t)(((uint32_t)a<<24)|((uint32_t)b<<16)|((uint32_t)g<<8)|r);
}
-static inline float _sgl_clamp(float v, float lo, float hi) {
+static float _sgl_clamp(float v, float lo, float hi) {
if (v < lo) return lo;
else if (v > hi) return hi;
else return v;
}
-static inline uint32_t _sgl_pack_rgbaf(float r, float g, float b, float a) {
+static uint32_t _sgl_pack_rgbaf(float r, float g, float b, float a) {
uint8_t r_u8 = (uint8_t) (_sgl_clamp(r, 0.0f, 1.0f) * 255.0f);
uint8_t g_u8 = (uint8_t) (_sgl_clamp(g, 0.0f, 1.0f) * 255.0f);
uint8_t b_u8 = (uint8_t) (_sgl_clamp(b, 0.0f, 1.0f) * 255.0f);
@@ -2929,7 +2933,7 @@ static inline uint32_t _sgl_pack_rgbaf(float r, float g, float b, float a) {
return _sgl_pack_rgbab(r_u8, g_u8, b_u8, a_u8);
}
-static inline void _sgl_vtx(_sgl_context_t* ctx, float x, float y, float z, float u, float v, uint32_t rgba) {
+static void _sgl_vtx(_sgl_context_t* ctx, float x, float y, float z, float u, float v, uint32_t rgba) {
SOKOL_ASSERT(ctx->in_begin);
_sgl_vertex_t* vtx;
/* handle non-native primitive types */
@@ -3143,22 +3147,22 @@ static void _sgl_lookat(_sgl_matrix_t* dst,
}
/* current top-of-stack projection matrix */
-static inline _sgl_matrix_t* _sgl_matrix_projection(_sgl_context_t* ctx) {
+static _sgl_matrix_t* _sgl_matrix_projection(_sgl_context_t* ctx) {
return &ctx->matrix_stack[SGL_MATRIXMODE_PROJECTION][ctx->matrix_tos[SGL_MATRIXMODE_PROJECTION]];
}
/* get top-of-stack modelview matrix */
-static inline _sgl_matrix_t* _sgl_matrix_modelview(_sgl_context_t* ctx) {
+static _sgl_matrix_t* _sgl_matrix_modelview(_sgl_context_t* ctx) {
return &ctx->matrix_stack[SGL_MATRIXMODE_MODELVIEW][ctx->matrix_tos[SGL_MATRIXMODE_MODELVIEW]];
}
/* get top-of-stack texture matrix */
-static inline _sgl_matrix_t* _sgl_matrix_texture(_sgl_context_t* ctx) {
+static _sgl_matrix_t* _sgl_matrix_texture(_sgl_context_t* ctx) {
return &ctx->matrix_stack[SGL_MATRIXMODE_TEXTURE][ctx->matrix_tos[SGL_MATRIXMODE_TEXTURE]];
}
/* get pointer to current top-of-stack of current matrix mode */
-static inline _sgl_matrix_t* _sgl_matrix(_sgl_context_t* ctx) {
+static _sgl_matrix_t* _sgl_matrix(_sgl_context_t* ctx) {
return &ctx->matrix_stack[ctx->cur_matrix_mode][ctx->matrix_tos[ctx->cur_matrix_mode]];
}
@@ -3272,7 +3276,7 @@ static bool _sgl_is_default_context(sgl_context ctx_id) {
static void _sgl_draw(_sgl_context_t* ctx, int layer_id) {
SOKOL_ASSERT(ctx);
- if ((ctx->error == SGL_NO_ERROR) && (ctx->cur_vertex > 0) && (ctx->cur_command > 0)) {
+ if ((ctx->error == SGL_NO_ERROR) && (ctx->vertices.next > 0) && (ctx->commands.next > 0)) {
sg_push_debug_group("sokol-gl");
uint32_t cur_pip_id = SG_INVALID_ID;
@@ -3281,12 +3285,12 @@ static void _sgl_draw(_sgl_context_t* ctx, int layer_id) {
if (ctx->update_frame_id != ctx->frame_id) {
ctx->update_frame_id = ctx->frame_id;
- const sg_range range = { ctx->vertices, (size_t)ctx->cur_vertex * sizeof(_sgl_vertex_t) };
+ const sg_range range = { ctx->vertices.ptr, (size_t)ctx->vertices.next * sizeof(_sgl_vertex_t) };
sg_update_buffer(ctx->vbuf, &range);
}
- for (int i = 0; i < ctx->cur_command; i++) {
- const _sgl_command_t* cmd = &ctx->commands[i];
+ for (int i = 0; i < ctx->commands.next; i++) {
+ const _sgl_command_t* cmd = &ctx->commands.ptr[i];
if (cmd->layer_id != layer_id) {
continue;
}
@@ -3319,7 +3323,7 @@ static void _sgl_draw(_sgl_context_t* ctx, int layer_id) {
cur_img_id = args->img.id;
}
if (cur_uniform_index != args->uniform_index) {
- const sg_range ub_range = { &ctx->uniforms[args->uniform_index], sizeof(_sgl_uniform_t) };
+ const sg_range ub_range = { &ctx->uniforms.ptr[args->uniform_index], sizeof(_sgl_uniform_t) };
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, &ub_range);
cur_uniform_index = args->uniform_index;
}
@@ -3698,7 +3702,7 @@ SOKOL_API_IMPL void sgl_end(void) {
return;
}
SOKOL_ASSERT(ctx->in_begin);
- SOKOL_ASSERT(ctx->cur_vertex >= ctx->base_vertex);
+ SOKOL_ASSERT(ctx->vertices.next >= ctx->base_vertex);
ctx->in_begin = false;
bool matrix_dirty = ctx->matrix_dirty;
if (matrix_dirty) {
@@ -3709,39 +3713,39 @@ SOKOL_API_IMPL void sgl_end(void) {
uni->tm = *_sgl_matrix_texture(ctx);
}
}
- /* check if command can be merged with previous command */
+ /* check if command can be merged with current command */
sg_pipeline pip = _sgl_get_pipeline(ctx->pip_stack[ctx->pip_tos], ctx->cur_prim_type);
sg_image img = ctx->texturing_enabled ? ctx->cur_img : _sgl.def_img;
- _sgl_command_t* prev_cmd = _sgl_prev_command(ctx);
+ _sgl_command_t* cur_cmd = _sgl_cur_command(ctx);
bool merge_cmd = false;
- if (prev_cmd) {
- if ((prev_cmd->cmd == SGL_COMMAND_DRAW) &&
- (prev_cmd->layer_id == ctx->layer_id) &&
+ if (cur_cmd) {
+ if ((cur_cmd->cmd == SGL_COMMAND_DRAW) &&
+ (cur_cmd->layer_id == ctx->layer_id) &&
(ctx->cur_prim_type != SGL_PRIMITIVETYPE_LINE_STRIP) &&
(ctx->cur_prim_type != SGL_PRIMITIVETYPE_TRIANGLE_STRIP) &&
!matrix_dirty &&
- (prev_cmd->args.draw.img.id == img.id) &&
- (prev_cmd->args.draw.pip.id == pip.id))
+ (cur_cmd->args.draw.img.id == img.id) &&
+ (cur_cmd->args.draw.pip.id == pip.id))
{
merge_cmd = true;
}
}
if (merge_cmd) {
/* draw command can be merged with the previous command */
- prev_cmd->args.draw.num_vertices += ctx->cur_vertex - ctx->base_vertex;
+ cur_cmd->args.draw.num_vertices += ctx->vertices.next - ctx->base_vertex;
}
else {
/* append a new draw command */
_sgl_command_t* cmd = _sgl_next_command(ctx);
if (cmd) {
- SOKOL_ASSERT(ctx->cur_uniform > 0);
+ SOKOL_ASSERT(ctx->uniforms.next > 0);
cmd->cmd = SGL_COMMAND_DRAW;
cmd->layer_id = ctx->layer_id;
cmd->args.draw.img = img;
cmd->args.draw.pip = _sgl_get_pipeline(ctx->pip_stack[ctx->pip_tos], ctx->cur_prim_type);
cmd->args.draw.base_vertex = ctx->base_vertex;
- cmd->args.draw.num_vertices = ctx->cur_vertex - ctx->base_vertex;
- cmd->args.draw.uniform_index = ctx->cur_uniform - 1;
+ cmd->args.draw.num_vertices = ctx->vertices.next - ctx->base_vertex;
+ cmd->args.draw.uniform_index = ctx->uniforms.next - 1;
}
}
}
diff --git a/util/sokol_spine.h b/util/sokol_spine.h
index 670e5737..157b681a 100644
--- a/util/sokol_spine.h
+++ b/util/sokol_spine.h
@@ -2619,7 +2619,7 @@ typedef struct {
spSkeletonData* sp_skel_data;
spAnimationStateData* sp_anim_data;
struct {
- int num;
+ int cap;
sspine_vec2* ptr;
} tform_buf;
} _sspine_skeleton_t;
@@ -2696,20 +2696,20 @@ typedef struct {
_sspine_slot_t slot;
float transform[16];
struct {
- int num;
- int cur;
+ int cap;
+ int next;
uint32_t rewind_frame_id;
_sspine_vertex_t* ptr;
} vertices;
struct {
- int num;
- int cur;
+ int cap;
+ int next;
uint32_t rewind_frame_id;
uint32_t* ptr;
} indices;
struct {
- int num;
- int cur;
+ int cap;
+ int next;
uint32_t rewind_frame_id;
_sspine_command_t* ptr;
} commands;
@@ -3114,13 +3114,13 @@ static sspine_resource_state _sspine_init_context(_sspine_context_t* ctx, const
SOKOL_ASSERT(desc);
// setup vertex, index and command storage
- ctx->vertices.num = desc->max_vertices;
- ctx->indices.num = ctx->vertices.num * 3;
- ctx->commands.num = desc->max_commands;
+ ctx->vertices.cap = desc->max_vertices;
+ ctx->indices.cap = ctx->vertices.cap * 3;
+ ctx->commands.cap = desc->max_commands;
- const size_t vbuf_size = (size_t)ctx->vertices.num * sizeof(_sspine_vertex_t);
- const size_t ibuf_size = (size_t)ctx->indices.num * sizeof(uint32_t);
- const size_t cbuf_size = (size_t)ctx->commands.num * sizeof(_sspine_command_t);
+ const size_t vbuf_size = (size_t)ctx->vertices.cap * sizeof(_sspine_vertex_t);
+ const size_t ibuf_size = (size_t)ctx->indices.cap * sizeof(uint32_t);
+ const size_t cbuf_size = (size_t)ctx->commands.cap * sizeof(_sspine_command_t);
ctx->vertices.ptr = (_sspine_vertex_t*) _sspine_malloc(vbuf_size);
ctx->indices.ptr = (uint32_t*) _sspine_malloc(ibuf_size);
@@ -3483,8 +3483,8 @@ static sspine_resource_state _sspine_init_skeleton(_sspine_skeleton_t* skeleton,
}
// allocate a shared vertex transform buffer (big enough to hold vertices for biggest mesh attachment)
- skeleton->tform_buf.num = max_vertex_count;
- skeleton->tform_buf.ptr = (sspine_vec2*) _sspine_malloc((size_t)skeleton->tform_buf.num * sizeof(sspine_vec2));
+ skeleton->tform_buf.cap = max_vertex_count;
+ skeleton->tform_buf.ptr = (sspine_vec2*) _sspine_malloc((size_t)skeleton->tform_buf.cap * sizeof(sspine_vec2));
return SSPINE_RESOURCESTATE_VALID;
}
@@ -4035,15 +4035,15 @@ static void _sspine_init_image_info(const _sspine_atlas_t* atlas, int index, ssp
static void _sspine_check_rewind_commands(_sspine_context_t* ctx) {
if (_sspine.frame_id != ctx->commands.rewind_frame_id) {
- ctx->commands.cur = 0;
+ ctx->commands.next = 0;
ctx->commands.rewind_frame_id = _sspine.frame_id;
}
}
static _sspine_command_t* _sspine_next_command(_sspine_context_t* ctx) {
_sspine_check_rewind_commands(ctx);
- if ((ctx->commands.cur + 1) <= ctx->commands.num) {
- return &(ctx->commands.ptr[ctx->commands.cur++]);
+ if (ctx->commands.next < ctx->commands.cap) {
+ return &(ctx->commands.ptr[ctx->commands.next++]);
}
else {
_SSPINE_ERROR(COMMAND_BUFFER_OVERFLOW);
@@ -4051,10 +4051,10 @@ static _sspine_command_t* _sspine_next_command(_sspine_context_t* ctx) {
}
}
-static _sspine_command_t* _sspine_prev_command(_sspine_context_t* ctx) {
+static _sspine_command_t* _sspine_cur_command(_sspine_context_t* ctx) {
_sspine_check_rewind_commands(ctx);
- if ((ctx->commands.cur > 0) && (ctx->commands.cur <= ctx->commands.num)) {
- return &ctx->commands.ptr[ctx->commands.cur - 1];
+ if (ctx->commands.next > 0) {
+ return &ctx->commands.ptr[ctx->commands.next - 1];
}
else {
return 0;
@@ -4063,7 +4063,7 @@ static _sspine_command_t* _sspine_prev_command(_sspine_context_t* ctx) {
static void _sspine_check_rewind_vertices(_sspine_context_t* ctx) {
if (_sspine.frame_id != ctx->vertices.rewind_frame_id) {
- ctx->vertices.cur = 0;
+ ctx->vertices.next = 0;
ctx->vertices.rewind_frame_id = _sspine.frame_id;
}
}
@@ -4072,10 +4072,10 @@ static _sspine_alloc_vertices_result_t _sspine_alloc_vertices(_sspine_context_t*
_sspine_check_rewind_vertices(ctx);
_sspine_alloc_vertices_result_t res;
_sspine_clear(&res, sizeof(res));
- if ((ctx->vertices.cur + num) <= ctx->vertices.num) {
- res.ptr = &(ctx->vertices.ptr[ctx->vertices.cur]);
- res.index = ctx->vertices.cur;
- ctx->vertices.cur += num;
+ if ((ctx->vertices.next + num) <= ctx->vertices.cap) {
+ res.ptr = &(ctx->vertices.ptr[ctx->vertices.next]);
+ res.index = ctx->vertices.next;
+ ctx->vertices.next += num;
}
else {
_SSPINE_ERROR(VERTEX_BUFFER_OVERFLOW);
@@ -4085,7 +4085,7 @@ static _sspine_alloc_vertices_result_t _sspine_alloc_vertices(_sspine_context_t*
static void _sspine_check_rewind_indices(_sspine_context_t* ctx) {
if (_sspine.frame_id != ctx->indices.rewind_frame_id) {
- ctx->indices.cur = 0;
+ ctx->indices.next = 0;
ctx->indices.rewind_frame_id = _sspine.frame_id;
}
}
@@ -4094,10 +4094,10 @@ static _sspine_alloc_indices_result_t _sspine_alloc_indices(_sspine_context_t* c
_sspine_check_rewind_indices(ctx);
_sspine_alloc_indices_result_t res;
_sspine_clear(&res, sizeof(res));
- if ((ctx->indices.cur + num) <= ctx->indices.num) {
- res.ptr = &(ctx->indices.ptr[ctx->indices.cur]);
- res.index = ctx->indices.cur;
- ctx->indices.cur += num;
+ if ((ctx->indices.next + num) <= ctx->indices.cap) {
+ res.ptr = &(ctx->indices.ptr[ctx->indices.next]);
+ res.index = ctx->indices.next;
+ ctx->indices.next += num;
}
else {
_SSPINE_ERROR(INDEX_BUFFER_OVERFLOW);
@@ -4114,7 +4114,7 @@ static void _sspine_draw_instance(_sspine_context_t* ctx, _sspine_instance_t* in
// see: https://github.com/EsotericSoftware/spine-runtimes/blob/4.1/spine-sdl/src/spine-sdl-c.c
const spSkeleton* sp_skel = instance->sp_skel;
float* tform_buf = (float*)instance->skel.ptr->tform_buf.ptr;
- const int max_tform_buf_verts = instance->skel.ptr->tform_buf.num;
+ const int max_tform_buf_verts = instance->skel.ptr->tform_buf.cap;
SOKOL_UNUSED(max_tform_buf_verts); // only used in asserts
const int tform_buf_stride = 2; // each element is 2 floats
spSkeletonClipping* sp_clip = instance->sp_clip;
@@ -4254,11 +4254,11 @@ static void _sspine_draw_instance(_sspine_context_t* ctx, _sspine_instance_t* in
break;
}
- // write new draw command, or merge with previous draw command
- _sspine_command_t* prev_cmd = _sspine_prev_command(ctx);
- if (prev_cmd && (prev_cmd->layer == layer) && (prev_cmd->pip.id == pip.id) && (prev_cmd->img.id == img.id) && (prev_cmd->pma == pma)) {
- // merge with previous command
- prev_cmd->num_elements += num_indices;
+ // write new draw command, or merge with current draw command
+ _sspine_command_t* cur_cmd = _sspine_cur_command(ctx);
+ if (cur_cmd && (cur_cmd->layer == layer) && (cur_cmd->pip.id == pip.id) && (cur_cmd->img.id == img.id) && (cur_cmd->pma == pma)) {
+ // merge with current command
+ cur_cmd->num_elements += num_indices;
}
else {
// record a new command
@@ -4311,14 +4311,14 @@ static _sspine_vsparams_t _sspine_compute_vsparams(const sspine_layer_transform*
}
static void _sspine_draw_layer(_sspine_context_t* ctx, int layer, const sspine_layer_transform* tform) {
- if ((ctx->vertices.cur > 0) && (ctx->commands.cur > 0)) {
+ if ((ctx->vertices.next > 0) && (ctx->commands.next > 0)) {
sg_push_debug_group("sokol-spine");
if (ctx->update_frame_id != _sspine.frame_id) {
ctx->update_frame_id = _sspine.frame_id;
- const sg_range vtx_range = { ctx->vertices.ptr, (size_t)ctx->vertices.cur * sizeof(_sspine_vertex_t) };
+ const sg_range vtx_range = { ctx->vertices.ptr, (size_t)ctx->vertices.next * sizeof(_sspine_vertex_t) };
sg_update_buffer(ctx->vbuf, &vtx_range);
- const sg_range idx_range = { ctx->indices.ptr, (size_t)ctx->indices.cur * sizeof(uint32_t) };
+ const sg_range idx_range = { ctx->indices.ptr, (size_t)ctx->indices.next * sizeof(uint32_t) };
sg_update_buffer(ctx->ibuf, &idx_range);
}
@@ -4331,7 +4331,7 @@ static void _sspine_draw_layer(_sspine_context_t* ctx, int layer, const sspine_l
uint32_t cur_pip_id = SG_INVALID_ID;
uint32_t cur_img_id = SG_INVALID_ID;
float cur_pma = -1.0f;
- for (int i = 0; i < ctx->commands.cur; i++) {
+ for (int i = 0; i < ctx->commands.next; i++) {
const _sspine_command_t* cmd = &ctx->commands.ptr[i];
if ((layer == cmd->layer) && (sg_query_image_state(cmd->img) == SG_RESOURCESTATE_VALID)) {
if (cur_pip_id != cmd->pip.id) {
@@ -4542,9 +4542,9 @@ SOKOL_API_IMPL sspine_context_info sspine_get_context_info(sspine_context ctx_id
_sspine_clear(&res, sizeof(res));
const _sspine_context_t* ctx = _sspine_lookup_context(ctx_id.id);
if (ctx) {
- res.num_vertices = ctx->vertices.cur;
- res.num_indices = ctx->indices.cur;
- res.num_commands = ctx->commands.cur;
+ res.num_vertices = ctx->vertices.next;
+ res.num_indices = ctx->indices.next;
+ res.num_commands = ctx->commands.next;
}
return res;
}