From 4f2b8ccd01b6ebeac9eff3169909d17af3f7821d Mon Sep 17 00:00:00 2001 From: veclavtalica Date: Fri, 3 Jan 2025 21:59:00 +0300 Subject: [PATCH] separate the rest of general drawing code --- include/twn_draw.h | 4 +- include/twn_types.h | 2 +- src/rendering/twn_draw.c | 307 +++++++++++++++++++++++ src/rendering/twn_draw_c.h | 67 +++++ src/rendering/twn_gl_15_rendering.c | 374 ---------------------------- 5 files changed, 378 insertions(+), 376 deletions(-) diff --git a/include/twn_draw.h b/include/twn_draw.h index 1e1de69..319424c 100644 --- a/include/twn_draw.h +++ b/include/twn_draw.h @@ -68,7 +68,9 @@ TWN_API void draw_triangle(char const *texture, TWN_API void draw_billboard(const char *path, Vec3 position, - Vec2 size); + Vec2 size, + Color color, /* optional, default: all 255 */ + bool cylindrical); /* optional, default: false */ /* sets a perspective 3d camera to be used for all 3d commands */ TWN_API void draw_camera(Vec3 position, float fov, Vec3 up, Vec3 direction); diff --git a/include/twn_types.h b/include/twn_types.h index 667237c..b95fb17 100644 --- a/include/twn_types.h +++ b/include/twn_types.h @@ -49,7 +49,7 @@ typedef struct Rect { float h; } Rect; - +/* TODO: remove from here? */ typedef struct Matrix4 { Vec4 row[4]; } Matrix4; diff --git a/src/rendering/twn_draw.c b/src/rendering/twn_draw.c index 0852a81..b1695b1 100644 --- a/src/rendering/twn_draw.c +++ b/src/rendering/twn_draw.c @@ -574,3 +574,310 @@ void render_circle(const CirclePrimitive *circle) { arrpush(deferred_commands, final_command); } + + +void finally_render_quads(const Primitive2D primitives[], + const struct QuadBatch batch, + const VertexBuffer buffer) +{ + DeferredCommandDraw command = {0}; + + GLsizei off = 0, voff = 0, uvoff = 0, coff = 0; + + if (!batch.constant_colored && batch.textured) { + off = offsetof(ElementIndexedQuad, v1); + voff = offsetof(ElementIndexedQuad, v0); + uvoff = offsetof(ElementIndexedQuad, uv0); + coff = offsetof(ElementIndexedQuad, c0); + } else if (batch.constant_colored && batch.textured) { + off = offsetof(ElementIndexedQuadWithoutColor, v1); + voff = offsetof(ElementIndexedQuadWithoutColor, v0); + uvoff = offsetof(ElementIndexedQuadWithoutColor, uv0); + } else if (!batch.constant_colored && !batch.textured) { + off = offsetof(ElementIndexedQuadWithoutTexture, v1); + voff = offsetof(ElementIndexedQuadWithoutTexture, v0); + coff = offsetof(ElementIndexedQuad, c0); + } else if (batch.constant_colored && !batch.textured) { + off = offsetof(ElementIndexedQuadWithoutColorWithoutTexture, v1); + voff = offsetof(ElementIndexedQuadWithoutColorWithoutTexture, v0); + } + + command.vertices = (AttributeArrayPointer) { + .arity = 2, + .type = GL_FLOAT, + .stride = off, + .offset = voff, + .buffer = buffer + }; + + if (batch.textured) + command.texcoords = (AttributeArrayPointer) { + .arity = 2, + .type = GL_FLOAT, + .stride = off, + .offset = uvoff, + .buffer = buffer + }; + + if (!batch.constant_colored) { + command.colors = (AttributeArrayPointer) { + .arity = 4, + .type = GL_UNSIGNED_BYTE, + .stride = off, + .offset = coff, + .buffer = buffer + }; + } else { + command.constant_colored = true; + command.color = primitives[0].sprite.color; + } + + if (batch.textured) { + command.textured = true; + command.texture_key = batch.texture_key; + command.texture_repeat = batch.repeat; + } + + command.element_buffer = get_quad_element_buffer(); + command.element_count = 6 * (GLsizei)batch.size; + command.range_end = 6 * (GLsizei)batch.size; + + use_texture_mode(batch.mode); + + DeferredCommand final_command = { + .type = DEFERRED_COMMAND_TYPE_DRAW, + .draw = command + }; + + arrpush(deferred_commands, final_command); +} + + +size_t get_quad_payload_size(struct QuadBatch batch) { + if (batch.constant_colored && batch.textured) + return sizeof (ElementIndexedQuadWithoutColor); + else if (!batch.constant_colored && batch.textured) + return sizeof (ElementIndexedQuad); + else if (batch.constant_colored && !batch.textured) + return sizeof (ElementIndexedQuadWithoutColorWithoutTexture); + else if (!batch.constant_colored && !batch.textured) + return sizeof (ElementIndexedQuadWithoutTexture); + + SDL_assert(false); + return 0; +} + + +bool push_quad_payload_to_vertex_buffer_builder(struct QuadBatch batch, + VertexBufferBuilder *builder, + Vec2 v0, Vec2 v1, Vec2 v2, Vec2 v3, + Vec2 uv0, Vec2 uv1, Vec2 uv2, Vec2 uv3, + Color color) +{ + if (!batch.constant_colored && batch.textured) { + ElementIndexedQuad const buffer_element = { + .v0 = v0, + .v1 = v1, + .v2 = v2, + .v3 = v3, + + .uv0 = uv0, + .uv1 = uv1, + .uv2 = uv2, + .uv3 = uv3, + + /* equal for all (flat shaded) */ + .c0 = color, + // .c1 = color, + .c2 = color, + // .c3 = color, + }; + + return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element); + + } else if (batch.constant_colored && batch.textured) { + ElementIndexedQuadWithoutColor const buffer_element = { + .v0 = v0, + .v1 = v1, + .v2 = v2, + .v3 = v3, + + .uv0 = uv0, + .uv1 = uv1, + .uv2 = uv2, + .uv3 = uv3, + }; + + return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element); + + } else if (!batch.constant_colored && !batch.textured) { + ElementIndexedQuadWithoutTexture const buffer_element = { + .v0 = v0, + .v1 = v1, + .v2 = v2, + .v3 = v3, + + /* equal for all (flat shaded) */ + .c0 = color, + // .c1 = color, + .c2 = color, + // .c3 = color, + }; + + return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element); + + } else if (batch.constant_colored && !batch.textured) { + ElementIndexedQuadWithoutColorWithoutTexture const buffer_element = { + .v0 = v0, + .v1 = v1, + .v2 = v2, + .v3 = v3, + }; + + return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element); + } + + SDL_assert(false); + return false; +} + + +void finally_draw_uncolored_space_traingle_batch(const MeshBatch *batch, + const TextureKey texture_key, + const VertexBuffer buffer) +{ + const size_t primitives_len = arrlenu(batch->primitives); + + /* nothing to do */ + if (primitives_len == 0) + return; + + const Rect srcrect = textures_get_srcrect(&ctx.texture_cache, texture_key); + const Rect dims = textures_get_dims(&ctx.texture_cache, texture_key); + + const float wr = srcrect.w / dims.w; + const float hr = srcrect.h / dims.h; + const float xr = srcrect.x / dims.w; + const float yr = srcrect.y / dims.h; + + /* update pixel-based uvs to correspond with texture atlases */ + for (size_t i = 0; i < primitives_len; ++i) { + UncoloredSpaceTriangle *payload = + &((UncoloredSpaceTriangle *)(void *)batch->primitives)[i]; + + payload->uv0.x = xr + ((float)payload->uv0.x / srcrect.w) * wr; + payload->uv0.y = yr + ((float)payload->uv0.y / srcrect.h) * hr; + payload->uv1.x = xr + ((float)payload->uv1.x / srcrect.w) * wr; + payload->uv1.y = yr + ((float)payload->uv1.y / srcrect.h) * hr; + payload->uv2.x = xr + ((float)payload->uv2.x / srcrect.w) * wr; + payload->uv2.y = yr + ((float)payload->uv2.y / srcrect.h) * hr; + } + + specify_vertex_buffer(buffer, batch->primitives, primitives_len * sizeof (UncoloredSpaceTriangle)); + + DeferredCommandDraw command = {0}; + + command.vertices = (AttributeArrayPointer) { + .arity = 3, + .type = GL_FLOAT, + .stride = offsetof(UncoloredSpaceTriangle, v1), + .offset = offsetof(UncoloredSpaceTriangle, v0), + .buffer = buffer + }; + + command.texcoords = (AttributeArrayPointer) { + .arity = 2, + .type = GL_FLOAT, + .stride = offsetof(UncoloredSpaceTriangle, v1), + .offset = offsetof(UncoloredSpaceTriangle, uv0), + .buffer = buffer + }; + + command.textured = true; + command.texture_key = texture_key; + + command.primitive_count = (GLsizei)(3 * primitives_len); + + DeferredCommand final_command = { + .type = DEFERRED_COMMAND_TYPE_DRAW, + .draw = command + }; + + arrpush(deferred_commands, final_command); +} + + + +bool push_text_payload_to_vertex_buffer_builder(FontData const *font_data, + VertexBufferBuilder *builder, + stbtt_aligned_quad quad) +{ + (void)font_data; + + ElementIndexedQuadWithoutColor buffer_element = { + .v0 = (Vec2){ quad.x0, quad.y0 }, + .v1 = (Vec2){ quad.x1, quad.y0 }, + .v2 = (Vec2){ quad.x1, quad.y1 }, + .v3 = (Vec2){ quad.x0, quad.y1 }, + + .uv0 = (Vec2){ quad.s0, quad.t0 }, + .uv1 = (Vec2){ quad.s1, quad.t0 }, + .uv2 = (Vec2){ quad.s1, quad.t1 }, + .uv3 = (Vec2){ quad.s0, quad.t1 }, + }; + + return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element); +} + + +void finally_draw_text(FontData const *font_data, + size_t len, + Color color, + VertexBuffer buffer) +{ + DeferredCommandDraw command = {0}; + + command.vertices = (AttributeArrayPointer) { + .arity = 2, + .type = GL_FLOAT, + .stride = offsetof(ElementIndexedQuadWithoutColor, v1), + .offset = offsetof(ElementIndexedQuadWithoutColor, v0), + .buffer = buffer + }; + + command.texcoords = (AttributeArrayPointer) { + .arity = 2, + .type = GL_FLOAT, + .stride = offsetof(ElementIndexedQuadWithoutColor, v1), + .offset = offsetof(ElementIndexedQuadWithoutColor, uv0), + .buffer = buffer + }; + + command.constant_colored = true; + command.color = color; + + command.gpu_texture = font_data->texture; + command.uses_gpu_key = true; + command.textured = true; + + command.element_buffer = get_quad_element_buffer(); + command.element_count = 6 * (GLsizei)len; + command.range_end = 6 * (GLsizei)len; + + use_texture_mode(TEXTURE_MODE_GHOSTLY); + + DeferredCommand final_command = { + .type = DEFERRED_COMMAND_TYPE_DRAW, + .draw = command + }; + + arrpush(deferred_commands, final_command); + + /* TODO: why doesn't it get restored if not placed here? */ + // glDepthMask(GL_TRUE); +} + + +size_t get_text_payload_size(void) { + return sizeof (ElementIndexedQuadWithoutColor); +} diff --git a/src/rendering/twn_draw_c.h b/src/rendering/twn_draw_c.h index 66447e0..a37dbae 100644 --- a/src/rendering/twn_draw_c.h +++ b/src/rendering/twn_draw_c.h @@ -113,6 +113,73 @@ typedef struct TextCache { } TextCache; +/* TODO: try using the fact we utilize edge coloring and step virtual color attributes to bogus points */ +/* this is only doable is we take out color attribute to separate array or a portion of it */ +/* interleaved vertex array data */ +typedef struct ElementIndexedQuad { + /* upper-left */ + Vec2 v0; + Vec2 uv0; + Color c0; + /* bottom-left */ + Vec2 v1; + Vec2 uv1; + Color c1; + /* bottom-right */ + Vec2 v2; + Vec2 uv2; + Color c2; + /* upper-right */ + Vec2 v3; + Vec2 uv3; + Color c3; +} ElementIndexedQuad; + + +typedef struct ElementIndexedQuadWithoutColor { + /* upper-left */ + Vec2 v0; + Vec2 uv0; + /* bottom-left */ + Vec2 v1; + Vec2 uv1; + /* bottom-right */ + Vec2 v2; + Vec2 uv2; + /* upper-right */ + Vec2 v3; + Vec2 uv3; +} ElementIndexedQuadWithoutColor; + + +typedef struct ElementIndexedQuadWithoutTexture { + /* upper-left */ + Vec2 v0; + Color c0; + /* bottom-left */ + Vec2 v1; + Color c1; + /* bottom-right */ + Vec2 v2; + Color c2; + /* upper-right */ + Vec2 v3; + Color c3; +} ElementIndexedQuadWithoutTexture; + + +typedef struct ElementIndexedQuadWithoutColorWithoutTexture { + /* upper-left */ + Vec2 v0; + /* bottom-left */ + Vec2 v1; + /* bottom-right */ + Vec2 v2; + /* upper-right */ + Vec2 v3; +} ElementIndexedQuadWithoutColorWithoutTexture; + + /* renders the background, then the primitives in all render queues */ void render(void); diff --git a/src/rendering/twn_gl_15_rendering.c b/src/rendering/twn_gl_15_rendering.c index d9e61f2..d5cc083 100644 --- a/src/rendering/twn_gl_15_rendering.c +++ b/src/rendering/twn_gl_15_rendering.c @@ -2,7 +2,6 @@ #include "twn_util.h" #include "twn_util_c.h" #include "twn_engine_context_c.h" -#include "twn_text_c.h" #include "twn_types.h" #include "twn_deferred_commands.h" #include "twn_gl_any_rendering_c.h" @@ -11,73 +10,6 @@ #include -/* TODO: try using the fact we utilize edge coloring and step virtual color attributes to bogus points */ -/* this is only doable is we take out color attribute to separate array or a portion of it */ -/* interleaved vertex array data */ -typedef struct ElementIndexedQuad { - /* upper-left */ - Vec2 v0; - Vec2 uv0; - Color c0; - /* bottom-left */ - Vec2 v1; - Vec2 uv1; - Color c1; - /* bottom-right */ - Vec2 v2; - Vec2 uv2; - Color c2; - /* upper-right */ - Vec2 v3; - Vec2 uv3; - Color c3; -} ElementIndexedQuad; - - -typedef struct ElementIndexedQuadWithoutColor { - /* upper-left */ - Vec2 v0; - Vec2 uv0; - /* bottom-left */ - Vec2 v1; - Vec2 uv1; - /* bottom-right */ - Vec2 v2; - Vec2 uv2; - /* upper-right */ - Vec2 v3; - Vec2 uv3; -} ElementIndexedQuadWithoutColor; - - -typedef struct ElementIndexedQuadWithoutTexture { - /* upper-left */ - Vec2 v0; - Color c0; - /* bottom-left */ - Vec2 v1; - Color c1; - /* bottom-right */ - Vec2 v2; - Color c2; - /* upper-right */ - Vec2 v3; - Color c3; -} ElementIndexedQuadWithoutTexture; - - -typedef struct ElementIndexedQuadWithoutColorWithoutTexture { - /* upper-left */ - Vec2 v0; - /* bottom-left */ - Vec2 v1; - /* bottom-right */ - Vec2 v2; - /* upper-right */ - Vec2 v3; -} ElementIndexedQuadWithoutColorWithoutTexture; - - static TextureMode texture_mode_last_used = TEXTURE_MODE_UNKNOWN; static Pipeline pipeline_last_used = PIPELINE_NO; @@ -268,312 +200,6 @@ bool push_to_vertex_buffer_builder(VertexBufferBuilder *builder, } -void finally_render_quads(const Primitive2D primitives[], - const struct QuadBatch batch, - const VertexBuffer buffer) -{ - DeferredCommandDraw command = {0}; - - GLsizei off = 0, voff = 0, uvoff = 0, coff = 0; - - if (!batch.constant_colored && batch.textured) { - off = offsetof(ElementIndexedQuad, v1); - voff = offsetof(ElementIndexedQuad, v0); - uvoff = offsetof(ElementIndexedQuad, uv0); - coff = offsetof(ElementIndexedQuad, c0); - } else if (batch.constant_colored && batch.textured) { - off = offsetof(ElementIndexedQuadWithoutColor, v1); - voff = offsetof(ElementIndexedQuadWithoutColor, v0); - uvoff = offsetof(ElementIndexedQuadWithoutColor, uv0); - } else if (!batch.constant_colored && !batch.textured) { - off = offsetof(ElementIndexedQuadWithoutTexture, v1); - voff = offsetof(ElementIndexedQuadWithoutTexture, v0); - coff = offsetof(ElementIndexedQuad, c0); - } else if (batch.constant_colored && !batch.textured) { - off = offsetof(ElementIndexedQuadWithoutColorWithoutTexture, v1); - voff = offsetof(ElementIndexedQuadWithoutColorWithoutTexture, v0); - } - - command.vertices = (AttributeArrayPointer) { - .arity = 2, - .type = GL_FLOAT, - .stride = off, - .offset = voff, - .buffer = buffer - }; - - if (batch.textured) - command.texcoords = (AttributeArrayPointer) { - .arity = 2, - .type = GL_FLOAT, - .stride = off, - .offset = uvoff, - .buffer = buffer - }; - - if (!batch.constant_colored) { - command.colors = (AttributeArrayPointer) { - .arity = 4, - .type = GL_UNSIGNED_BYTE, - .stride = off, - .offset = coff, - .buffer = buffer - }; - } else { - command.constant_colored = true; - command.color = primitives[0].sprite.color; - } - - if (batch.textured) { - command.textured = true; - command.texture_key = batch.texture_key; - command.texture_repeat = batch.repeat; - } - - command.element_buffer = get_quad_element_buffer(); - command.element_count = 6 * (GLsizei)batch.size; - command.range_end = 6 * (GLsizei)batch.size; - - use_texture_mode(batch.mode); - - DeferredCommand final_command = { - .type = DEFERRED_COMMAND_TYPE_DRAW, - .draw = command - }; - - arrpush(deferred_commands, final_command); -} - - -size_t get_quad_payload_size(struct QuadBatch batch) { - if (batch.constant_colored && batch.textured) - return sizeof (ElementIndexedQuadWithoutColor); - else if (!batch.constant_colored && batch.textured) - return sizeof (ElementIndexedQuad); - else if (batch.constant_colored && !batch.textured) - return sizeof (ElementIndexedQuadWithoutColorWithoutTexture); - else if (!batch.constant_colored && !batch.textured) - return sizeof (ElementIndexedQuadWithoutTexture); - - SDL_assert(false); - return 0; -} - - -bool push_quad_payload_to_vertex_buffer_builder(struct QuadBatch batch, - VertexBufferBuilder *builder, - Vec2 v0, Vec2 v1, Vec2 v2, Vec2 v3, - Vec2 uv0, Vec2 uv1, Vec2 uv2, Vec2 uv3, - Color color) -{ - if (!batch.constant_colored && batch.textured) { - ElementIndexedQuad const buffer_element = { - .v0 = v0, - .v1 = v1, - .v2 = v2, - .v3 = v3, - - .uv0 = uv0, - .uv1 = uv1, - .uv2 = uv2, - .uv3 = uv3, - - /* equal for all (flat shaded) */ - .c0 = color, - // .c1 = color, - .c2 = color, - // .c3 = color, - }; - - return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element); - - } else if (batch.constant_colored && batch.textured) { - ElementIndexedQuadWithoutColor const buffer_element = { - .v0 = v0, - .v1 = v1, - .v2 = v2, - .v3 = v3, - - .uv0 = uv0, - .uv1 = uv1, - .uv2 = uv2, - .uv3 = uv3, - }; - - return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element); - - } else if (!batch.constant_colored && !batch.textured) { - ElementIndexedQuadWithoutTexture const buffer_element = { - .v0 = v0, - .v1 = v1, - .v2 = v2, - .v3 = v3, - - /* equal for all (flat shaded) */ - .c0 = color, - // .c1 = color, - .c2 = color, - // .c3 = color, - }; - - return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element); - - } else if (batch.constant_colored && !batch.textured) { - ElementIndexedQuadWithoutColorWithoutTexture const buffer_element = { - .v0 = v0, - .v1 = v1, - .v2 = v2, - .v3 = v3, - }; - - return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element); - } - - SDL_assert(false); - return false; -} - - -void finally_draw_uncolored_space_traingle_batch(const MeshBatch *batch, - const TextureKey texture_key, - const VertexBuffer buffer) -{ - const size_t primitives_len = arrlenu(batch->primitives); - - /* nothing to do */ - if (primitives_len == 0) - return; - - const Rect srcrect = textures_get_srcrect(&ctx.texture_cache, texture_key); - const Rect dims = textures_get_dims(&ctx.texture_cache, texture_key); - - const float wr = srcrect.w / dims.w; - const float hr = srcrect.h / dims.h; - const float xr = srcrect.x / dims.w; - const float yr = srcrect.y / dims.h; - - /* update pixel-based uvs to correspond with texture atlases */ - for (size_t i = 0; i < primitives_len; ++i) { - UncoloredSpaceTriangle *payload = - &((UncoloredSpaceTriangle *)(void *)batch->primitives)[i]; - - payload->uv0.x = xr + ((float)payload->uv0.x / srcrect.w) * wr; - payload->uv0.y = yr + ((float)payload->uv0.y / srcrect.h) * hr; - payload->uv1.x = xr + ((float)payload->uv1.x / srcrect.w) * wr; - payload->uv1.y = yr + ((float)payload->uv1.y / srcrect.h) * hr; - payload->uv2.x = xr + ((float)payload->uv2.x / srcrect.w) * wr; - payload->uv2.y = yr + ((float)payload->uv2.y / srcrect.h) * hr; - } - - specify_vertex_buffer(buffer, batch->primitives, primitives_len * sizeof (UncoloredSpaceTriangle)); - - DeferredCommandDraw command = {0}; - - command.vertices = (AttributeArrayPointer) { - .arity = 3, - .type = GL_FLOAT, - .stride = offsetof(UncoloredSpaceTriangle, v1), - .offset = offsetof(UncoloredSpaceTriangle, v0), - .buffer = buffer - }; - - command.texcoords = (AttributeArrayPointer) { - .arity = 2, - .type = GL_FLOAT, - .stride = offsetof(UncoloredSpaceTriangle, v1), - .offset = offsetof(UncoloredSpaceTriangle, uv0), - .buffer = buffer - }; - - command.textured = true; - command.texture_key = texture_key; - - command.primitive_count = (GLsizei)(3 * primitives_len); - - DeferredCommand final_command = { - .type = DEFERRED_COMMAND_TYPE_DRAW, - .draw = command - }; - - arrpush(deferred_commands, final_command); -} - - -bool push_text_payload_to_vertex_buffer_builder(FontData const *font_data, - VertexBufferBuilder *builder, - stbtt_aligned_quad quad) -{ - (void)font_data; - - ElementIndexedQuadWithoutColor buffer_element = { - .v0 = (Vec2){ quad.x0, quad.y0 }, - .v1 = (Vec2){ quad.x1, quad.y0 }, - .v2 = (Vec2){ quad.x1, quad.y1 }, - .v3 = (Vec2){ quad.x0, quad.y1 }, - - .uv0 = (Vec2){ quad.s0, quad.t0 }, - .uv1 = (Vec2){ quad.s1, quad.t0 }, - .uv2 = (Vec2){ quad.s1, quad.t1 }, - .uv3 = (Vec2){ quad.s0, quad.t1 }, - }; - - return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element); -} - - -void finally_draw_text(FontData const *font_data, - size_t len, - Color color, - VertexBuffer buffer) -{ - DeferredCommandDraw command = {0}; - - command.vertices = (AttributeArrayPointer) { - .arity = 2, - .type = GL_FLOAT, - .stride = offsetof(ElementIndexedQuadWithoutColor, v1), - .offset = offsetof(ElementIndexedQuadWithoutColor, v0), - .buffer = buffer - }; - - command.texcoords = (AttributeArrayPointer) { - .arity = 2, - .type = GL_FLOAT, - .stride = offsetof(ElementIndexedQuadWithoutColor, v1), - .offset = offsetof(ElementIndexedQuadWithoutColor, uv0), - .buffer = buffer - }; - - command.constant_colored = true; - command.color = color; - - command.gpu_texture = font_data->texture; - command.uses_gpu_key = true; - command.textured = true; - - command.element_buffer = get_quad_element_buffer(); - command.element_count = 6 * (GLsizei)len; - command.range_end = 6 * (GLsizei)len; - - use_texture_mode(TEXTURE_MODE_GHOSTLY); - - DeferredCommand final_command = { - .type = DEFERRED_COMMAND_TYPE_DRAW, - .draw = command - }; - - arrpush(deferred_commands, final_command); - - /* TODO: why doesn't it get restored if not placed here? */ - // glDepthMask(GL_TRUE); -} - - -size_t get_text_payload_size(void) { - return sizeof (ElementIndexedQuadWithoutColor); -} - - static void load_cubemap_side(const char *path, GLenum target) { SDL_Surface *surface = textures_load_surface(path); /* TODO: sanity check whether all of them have same dimensions? */