remove indirection in vertex builder

This commit is contained in:
veclavtalica 2025-01-17 22:48:35 +03:00
parent 40aef0a1f9
commit 8a5d639f95
8 changed files with 53 additions and 85 deletions

View File

@ -125,9 +125,11 @@ void finally_draw_billboard_batch(struct MeshBatch const *batch,
.v3 = vec3_add(billboard.position, a), .v3 = vec3_add(billboard.position, a),
}; };
push_to_vertex_buffer_builder(&builder, &payload, sizeof (payload)); ((struct ElementIndexedBillboard *)builder.base)[i] = payload;
} }
finish_vertex_builder(&builder);
/* commit to drawing */ /* commit to drawing */
DeferredCommandDraw command = {0}; DeferredCommandDraw command = {0};

View File

@ -37,9 +37,7 @@ enum {
typedef uint32_t VertexBuffer; typedef uint32_t VertexBuffer;
typedef struct VertexBufferBuilder { typedef struct VertexBufferBuilder {
size_t bytes_left;
size_t size; size_t size;
void *mapping;
void *base; void *base;
} VertexBufferBuilder; } VertexBufferBuilder;
@ -271,10 +269,7 @@ void specify_vertex_buffer(VertexBuffer buffer, void const *data, size_t bytes);
/* uses present in 1.5 buffer mapping feature */ /* uses present in 1.5 buffer mapping feature */
VertexBufferBuilder build_vertex_buffer(VertexBuffer buffer, size_t bytes); VertexBufferBuilder build_vertex_buffer(VertexBuffer buffer, size_t bytes);
/* collects bytes for sending to the gpu until all is pushed, which is when false is returned */ void finish_vertex_builder(VertexBufferBuilder *builder);
bool push_to_vertex_buffer_builder(VertexBufferBuilder *builder,
void const *bytes,
size_t size);
/* state */ /* state */
@ -301,7 +296,8 @@ void finally_render_quads(Primitive2D const primitives[],
size_t get_quad_payload_size(struct QuadBatch batch); size_t get_quad_payload_size(struct QuadBatch batch);
bool push_quad_payload_to_vertex_buffer_builder(struct QuadBatch batch, void push_quad_payload_to_vertex_buffer_builder(struct QuadBatch batch,
size_t index,
VertexBufferBuilder *builder, VertexBufferBuilder *builder,
Vec2 v0, Vec2 v1, Vec2 v2, Vec2 v3, Vec2 v0, Vec2 v1, Vec2 v2, Vec2 v3,
Vec2 uv0, Vec2 uv1, Vec2 uv2, Vec2 uv3, Vec2 uv0, Vec2 uv1, Vec2 uv2, Vec2 uv3,
@ -313,12 +309,6 @@ void finally_draw_uncolored_space_traingle_batch(MeshBatch const *batch,
void finally_draw_billboard_batch(MeshBatch const *batch, void finally_draw_billboard_batch(MeshBatch const *batch,
TextureKey texture_key); TextureKey texture_key);
size_t get_text_payload_size(void);
bool push_text_payload_to_vertex_buffer_builder(FontData const *font_data,
VertexBufferBuilder *builder,
stbtt_aligned_quad quad);
void finally_draw_text(FontData const *font_data, void finally_draw_text(FontData const *font_data,
size_t len, size_t len,
Color color, Color color,

View File

@ -218,29 +218,18 @@ VertexBufferBuilder build_vertex_buffer(VertexBuffer buffer, size_t bytes) {
CRY("build_vertex_buffer", "Error mapping a vertex array buffer"); CRY("build_vertex_buffer", "Error mapping a vertex array buffer");
return (VertexBufferBuilder) { return (VertexBufferBuilder) {
.mapping = mapping, .base = mapping,
.bytes_left = bytes, .size = bytes,
}; };
} }
bool push_to_vertex_buffer_builder(VertexBufferBuilder *builder, void finish_vertex_builder(VertexBufferBuilder *builder) {
void const *bytes, size_t size) { glUnmapBuffer(GL_ARRAY_BUFFER);
if (builder->bytes_left == 0) glBindBuffer(GL_ARRAY_BUFFER, 0);
return false;
memcpy(builder->mapping, bytes, size); builder->base = 0;
builder->bytes_left -= size; builder->size = 0;
/* trigger data send */
if (builder->bytes_left == 0) {
glUnmapBuffer(GL_ARRAY_BUFFER);
return false;
}
builder->mapping = (void *)((uintptr_t)builder->mapping + size);
return true;
} }

View File

@ -44,16 +44,15 @@ VertexBuffer get_quad_element_buffer(void) {
VertexBufferBuilder builder = build_vertex_buffer(buffer, sizeof (GLshort) * QUAD_ELEMENT_BUFFER_LENGTH * 6 ); VertexBufferBuilder builder = build_vertex_buffer(buffer, sizeof (GLshort) * QUAD_ELEMENT_BUFFER_LENGTH * 6 );
for (size_t i = 0; i < QUAD_ELEMENT_BUFFER_LENGTH; ++i) { for (size_t i = 0; i < QUAD_ELEMENT_BUFFER_LENGTH; ++i) {
GLshort indices[6]; ((GLshort *)builder.base)[i * 6 + 0] = (GLshort)(i * 4 + 0);
indices[0] = (GLshort)(i * 4 + 0); ((GLshort *)builder.base)[i * 6 + 1] = (GLshort)(i * 4 + 1);
indices[1] = (GLshort)(i * 4 + 1); ((GLshort *)builder.base)[i * 6 + 2] = (GLshort)(i * 4 + 2);
indices[2] = (GLshort)(i * 4 + 2); ((GLshort *)builder.base)[i * 6 + 3] = (GLshort)(i * 4 + 2);
indices[3] = (GLshort)(i * 4 + 2); ((GLshort *)builder.base)[i * 6 + 4] = (GLshort)(i * 4 + 3);
indices[4] = (GLshort)(i * 4 + 3); ((GLshort *)builder.base)[i * 6 + 5] = (GLshort)(i * 4 + 0);
indices[5] = (GLshort)(i * 4 + 0);
push_to_vertex_buffer_builder(&builder, indices, sizeof indices);
} }
finish_vertex_builder(&builder);
} }
SDL_assert_always(buffer); SDL_assert_always(buffer);
@ -71,17 +70,14 @@ VertexBuffer get_circle_element_buffer(void) {
for (size_t i = 1; i < CIRCLE_VERTICES_MAX - 1; ++i) { for (size_t i = 1; i < CIRCLE_VERTICES_MAX - 1; ++i) {
/* first one is center point index, always zero */ /* first one is center point index, always zero */
GLshort indices[3]; ((GLshort *)builder.base)[(i - 1) * 3 + 0] = 0;
indices[0] = 0;
/* generated point index */ /* generated point index */
indices[1] = (GLshort)i; ((GLshort *)builder.base)[(i - 1) * 3 + 1] = (GLshort)i;
((GLshort *)builder.base)[(i - 1) * 3 + 2] = (GLshort)i + 1;
indices[2] = (GLshort)i + 1;
push_to_vertex_buffer_builder(&builder, indices, sizeof indices);
} }
finish_vertex_builder(&builder);
} }
SDL_assert_always(buffer); SDL_assert_always(buffer);

View File

@ -101,14 +101,15 @@ size_t get_quad_payload_size(struct QuadBatch batch) {
} }
bool push_quad_payload_to_vertex_buffer_builder(struct QuadBatch batch, void push_quad_payload_to_vertex_buffer_builder(struct QuadBatch batch,
size_t index,
VertexBufferBuilder *builder, VertexBufferBuilder *builder,
Vec2 v0, Vec2 v1, Vec2 v2, Vec2 v3, Vec2 v0, Vec2 v1, Vec2 v2, Vec2 v3,
Vec2 uv0, Vec2 uv1, Vec2 uv2, Vec2 uv3, Vec2 uv0, Vec2 uv1, Vec2 uv2, Vec2 uv3,
Color color) Color color)
{ {
if (!batch.constant_colored && batch.textured) { if (!batch.constant_colored && batch.textured) {
ElementIndexedQuad const buffer_element = { ElementIndexedQuad const payload = {
.v0 = v0, .v0 = v0,
.v1 = v1, .v1 = v1,
.v2 = v2, .v2 = v2,
@ -126,10 +127,10 @@ bool push_quad_payload_to_vertex_buffer_builder(struct QuadBatch batch,
// .c3 = color, // .c3 = color,
}; };
return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element); ((ElementIndexedQuad *)builder->base)[index] = payload;
} else if (batch.constant_colored && batch.textured) { } else if (batch.constant_colored && batch.textured) {
ElementIndexedQuadWithoutColor const buffer_element = { ElementIndexedQuadWithoutColor const payload = {
.v0 = v0, .v0 = v0,
.v1 = v1, .v1 = v1,
.v2 = v2, .v2 = v2,
@ -141,10 +142,10 @@ bool push_quad_payload_to_vertex_buffer_builder(struct QuadBatch batch,
.uv3 = uv3, .uv3 = uv3,
}; };
return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element); ((ElementIndexedQuadWithoutColor *)builder->base)[index] = payload;
} else if (!batch.constant_colored && !batch.textured) { } else if (!batch.constant_colored && !batch.textured) {
ElementIndexedQuadWithoutTexture const buffer_element = { ElementIndexedQuadWithoutTexture const payload = {
.v0 = v0, .v0 = v0,
.v1 = v1, .v1 = v1,
.v2 = v2, .v2 = v2,
@ -157,19 +158,18 @@ bool push_quad_payload_to_vertex_buffer_builder(struct QuadBatch batch,
// .c3 = color, // .c3 = color,
}; };
return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element); ((ElementIndexedQuadWithoutTexture *)builder->base)[index] = payload;
} else if (batch.constant_colored && !batch.textured) { } else if (batch.constant_colored && !batch.textured) {
ElementIndexedQuadWithoutColorWithoutTexture const buffer_element = { ElementIndexedQuadWithoutColorWithoutTexture const payload = {
.v0 = v0, .v0 = v0,
.v1 = v1, .v1 = v1,
.v2 = v2, .v2 = v2,
.v3 = v3, .v3 = v3,
}; };
return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element); ((ElementIndexedQuadWithoutColorWithoutTexture *)builder->base)[index] = payload;
} }
SDL_assert(false); SDL_assert(false);
return false;
} }

View File

@ -85,7 +85,7 @@ void render_rect_batch(const Primitive2D primitives[],
Vec2 v3 = { rect.rect.x + rect.rect.w, rect.rect.y }; Vec2 v3 = { rect.rect.x + rect.rect.w, rect.rect.y };
push_quad_payload_to_vertex_buffer_builder( push_quad_payload_to_vertex_buffer_builder(
batch, &payload, batch, i, &payload,
v0, v1, v2, v3, v0, v1, v2, v3,
(Vec2){0}, (Vec2){0}, (Vec2){0}, (Vec2){0}, (Vec2){0}, (Vec2){0}, (Vec2){0}, (Vec2){0},
rect.color); rect.color);

View File

@ -242,7 +242,7 @@ void render_sprite_batch(const Primitive2D primitives[],
v3 = (Vec2){ c.x + t.x * +h.x - t.y * -h.y, c.y + t.y * +h.x + t.x * -h.y }; v3 = (Vec2){ c.x + t.x * +h.x - t.y * -h.y, c.y + t.y * +h.x + t.x * -h.y };
} }
push_quad_payload_to_vertex_buffer_builder(batch, &payload, v0, v1, v2, v3, uv0, uv1, uv2, uv3, sprite.color); push_quad_payload_to_vertex_buffer_builder(batch, i, &payload, v0, v1, v2, v3, uv0, uv1, uv2, uv3, sprite.color);
} }
} }

View File

@ -175,7 +175,7 @@ static void text_draw_with(FontData* font_data, char* text, Vec2 position, Color
const size_t len = SDL_strlen(text); const size_t len = SDL_strlen(text);
VertexBufferBuilder payload = build_vertex_buffer(vertex_array, sizeof (ElementIndexedQuadWithoutColor) * len); VertexBufferBuilder builder = build_vertex_buffer(vertex_array, sizeof (ElementIndexedQuadWithoutColor) * len);
for (size_t i = 0; i < len; ++i) { for (size_t i = 0; i < len; ++i) {
const char c = text[i]; const char c = text[i];
@ -204,9 +204,22 @@ static void text_draw_with(FontData* font_data, char* text, Vec2 position, Color
quad.y0 += (float)font_data->ascent; quad.y0 += (float)font_data->ascent;
quad.y1 += (float)font_data->ascent; quad.y1 += (float)font_data->ascent;
push_text_payload_to_vertex_buffer_builder(font_data, &payload, quad); ElementIndexedQuadWithoutColor const payload = {
.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 },
};
((ElementIndexedQuadWithoutColor *)builder.base)[i] = payload;
} }
finish_vertex_builder(&builder);
finally_draw_text(font_data, len, color, vertex_array); finally_draw_text(font_data, len, color, vertex_array);
} }
@ -320,28 +333,6 @@ float draw_text_width(const char *string, float height, const char *font) {
} }
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, void finally_draw_text(FontData const *font_data,
size_t len, size_t len,
Color color, Color color,