support arbitrary count of billboards per batch (in regards to preallocated short index buffer)
This commit is contained in:
parent
d7a119a592
commit
4dd028aeae
@ -3,6 +3,7 @@
|
|||||||
#include "twn_engine_context_c.h"
|
#include "twn_engine_context_c.h"
|
||||||
#include "twn_textures_c.h"
|
#include "twn_textures_c.h"
|
||||||
#include "twn_types.h"
|
#include "twn_types.h"
|
||||||
|
#include "twn_util_c.h"
|
||||||
#include "twn_vec.h"
|
#include "twn_vec.h"
|
||||||
|
|
||||||
#include <stb_ds.h>
|
#include <stb_ds.h>
|
||||||
@ -85,88 +86,93 @@ void finally_draw_billboard_batch(struct MeshBatch const *batch,
|
|||||||
const Vec2 uv2 = { xr, yr + hr };
|
const Vec2 uv2 = { xr, yr + hr };
|
||||||
const Vec2 uv3 = { xr, yr };
|
const Vec2 uv3 = { xr, yr };
|
||||||
|
|
||||||
/* emit vertex data */
|
for (size_t batch_n = 0; batch_n <= (primitives_len - 1) / QUAD_ELEMENT_BUFFER_LENGTH; batch_n++) {
|
||||||
VertexBuffer const buffer = get_scratch_vertex_array();
|
|
||||||
VertexBufferBuilder builder = build_vertex_buffer(buffer, sizeof (ElementIndexedBillboard) * primitives_len);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < primitives_len; ++i) {
|
/* emit vertex data */
|
||||||
struct SpaceBillboard const billboard = ((SpaceBillboard *)(void *)batch->primitives)[i];
|
VertexBuffer const buffer = get_scratch_vertex_array();
|
||||||
|
VertexBufferBuilder builder = build_vertex_buffer(
|
||||||
|
buffer,
|
||||||
|
sizeof (ElementIndexedBillboard) * MIN(primitives_len - batch_n * QUAD_ELEMENT_BUFFER_LENGTH, QUAD_ELEMENT_BUFFER_LENGTH));
|
||||||
|
|
||||||
/* a = (right + up) * size, b = (right - up) * size*/
|
for (size_t i = 0; i < primitives_len; ++i) {
|
||||||
Vec3 a, b;
|
struct SpaceBillboard const billboard = ((SpaceBillboard *)(void *)batch->primitives)[batch_n * QUAD_ELEMENT_BUFFER_LENGTH + i];
|
||||||
if (billboard.cylindrical) {
|
|
||||||
a = vec3_mul(right_plus_up_cylindrical, ((Vec3){billboard.size.x, billboard.size.y, billboard.size.x }));
|
/* a = (right + up) * size, b = (right - up) * size*/
|
||||||
b = vec3_mul(right_minus_up_cylindrical, ((Vec3){billboard.size.x, billboard.size.y, billboard.size.x }));
|
Vec3 a, b;
|
||||||
} else {
|
if (billboard.cylindrical) {
|
||||||
a = vec3_mul(right_plus_up, ((Vec3){billboard.size.x, billboard.size.y, billboard.size.x }));
|
a = vec3_mul(right_plus_up_cylindrical, ((Vec3){billboard.size.x, billboard.size.y, billboard.size.x }));
|
||||||
b = vec3_mul(right_minus_up, ((Vec3){billboard.size.x, billboard.size.y, billboard.size.x }));
|
b = vec3_mul(right_minus_up_cylindrical, ((Vec3){billboard.size.x, billboard.size.y, billboard.size.x }));
|
||||||
|
} else {
|
||||||
|
a = vec3_mul(right_plus_up, ((Vec3){billboard.size.x, billboard.size.y, billboard.size.x }));
|
||||||
|
b = vec3_mul(right_minus_up, ((Vec3){billboard.size.x, billboard.size.y, billboard.size.x }));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ElementIndexedBillboard const payload = {
|
||||||
|
/* TODO: use the flat shading to not set two of the colors */
|
||||||
|
.c0 = billboard.color,
|
||||||
|
.c1 = billboard.color,
|
||||||
|
.c2 = billboard.color,
|
||||||
|
.c3 = billboard.color,
|
||||||
|
|
||||||
|
.uv0 = uv0,
|
||||||
|
.uv1 = uv1,
|
||||||
|
.uv2 = uv2,
|
||||||
|
.uv3 = uv3,
|
||||||
|
|
||||||
|
.v0 = vec3_sub(billboard.position, b),
|
||||||
|
.v1 = vec3_sub(billboard.position, a),
|
||||||
|
.v2 = vec3_add(billboard.position, b),
|
||||||
|
.v3 = vec3_add(billboard.position, a),
|
||||||
|
};
|
||||||
|
|
||||||
|
push_to_vertex_buffer_builder(&builder, &payload, sizeof (payload));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ElementIndexedBillboard const payload = {
|
/* commit to drawing */
|
||||||
/* TODO: use the flat shading to not set two of the colors */
|
DeferredCommandDraw command = {0};
|
||||||
.c0 = billboard.color,
|
|
||||||
.c1 = billboard.color,
|
|
||||||
.c2 = billboard.color,
|
|
||||||
.c3 = billboard.color,
|
|
||||||
|
|
||||||
.uv0 = uv0,
|
command.vertices = (AttributeArrayPointer) {
|
||||||
.uv1 = uv1,
|
.arity = 3,
|
||||||
.uv2 = uv2,
|
.type = GL_FLOAT,
|
||||||
.uv3 = uv3,
|
.stride = offsetof(ElementIndexedBillboard, v1),
|
||||||
|
.offset = offsetof(ElementIndexedBillboard, v0),
|
||||||
.v0 = vec3_sub(billboard.position, b),
|
.buffer = buffer
|
||||||
.v1 = vec3_sub(billboard.position, a),
|
|
||||||
.v2 = vec3_add(billboard.position, b),
|
|
||||||
.v3 = vec3_add(billboard.position, a),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
push_to_vertex_buffer_builder(&builder, &payload, sizeof (payload));
|
command.texcoords = (AttributeArrayPointer) {
|
||||||
|
.arity = 2,
|
||||||
|
.type = GL_FLOAT,
|
||||||
|
.stride = offsetof(ElementIndexedBillboard, v1),
|
||||||
|
.offset = offsetof(ElementIndexedBillboard, uv0),
|
||||||
|
.buffer = buffer
|
||||||
|
};
|
||||||
|
|
||||||
|
command.colors = (AttributeArrayPointer) {
|
||||||
|
.arity = 4,
|
||||||
|
.type = GL_UNSIGNED_BYTE,
|
||||||
|
.stride = offsetof(ElementIndexedBillboard, v1),
|
||||||
|
.offset = offsetof(ElementIndexedBillboard, c0),
|
||||||
|
.buffer = buffer
|
||||||
|
};
|
||||||
|
|
||||||
|
command.textured = true;
|
||||||
|
command.texture_key = texture_key;
|
||||||
|
|
||||||
|
command.element_buffer = get_quad_element_buffer();
|
||||||
|
command.element_count = 6 * (GLsizei)primitives_len;
|
||||||
|
command.range_end = 6 * (GLsizei)primitives_len;
|
||||||
|
|
||||||
|
/* TODO: support alpha blended case, with distance sort */
|
||||||
|
TextureMode mode = textures_get_mode(&ctx.texture_cache, texture_key);
|
||||||
|
if (mode == TEXTURE_MODE_GHOSTLY)
|
||||||
|
mode = TEXTURE_MODE_SEETHROUGH;
|
||||||
|
use_texture_mode(mode);
|
||||||
|
|
||||||
|
DeferredCommand final_command = {
|
||||||
|
.type = DEFERRED_COMMAND_TYPE_DRAW,
|
||||||
|
.draw = command
|
||||||
|
};
|
||||||
|
|
||||||
|
arrpush(deferred_commands, final_command);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* commit to drawing */
|
|
||||||
DeferredCommandDraw command = {0};
|
|
||||||
|
|
||||||
command.vertices = (AttributeArrayPointer) {
|
|
||||||
.arity = 3,
|
|
||||||
.type = GL_FLOAT,
|
|
||||||
.stride = offsetof(ElementIndexedBillboard, v1),
|
|
||||||
.offset = offsetof(ElementIndexedBillboard, v0),
|
|
||||||
.buffer = buffer
|
|
||||||
};
|
|
||||||
|
|
||||||
command.texcoords = (AttributeArrayPointer) {
|
|
||||||
.arity = 2,
|
|
||||||
.type = GL_FLOAT,
|
|
||||||
.stride = offsetof(ElementIndexedBillboard, v1),
|
|
||||||
.offset = offsetof(ElementIndexedBillboard, uv0),
|
|
||||||
.buffer = buffer
|
|
||||||
};
|
|
||||||
|
|
||||||
command.colors = (AttributeArrayPointer) {
|
|
||||||
.arity = 4,
|
|
||||||
.type = GL_UNSIGNED_BYTE,
|
|
||||||
.stride = offsetof(ElementIndexedBillboard, v1),
|
|
||||||
.offset = offsetof(ElementIndexedBillboard, c0),
|
|
||||||
.buffer = buffer
|
|
||||||
};
|
|
||||||
|
|
||||||
command.textured = true;
|
|
||||||
command.texture_key = texture_key;
|
|
||||||
|
|
||||||
command.element_buffer = get_quad_element_buffer();
|
|
||||||
command.element_count = 6 * (GLsizei)primitives_len;
|
|
||||||
command.range_end = 6 * (GLsizei)primitives_len;
|
|
||||||
|
|
||||||
/* TODO: support alpha blended case, with distance sort */
|
|
||||||
TextureMode mode = textures_get_mode(&ctx.texture_cache, texture_key);
|
|
||||||
if (mode == TEXTURE_MODE_GHOSTLY)
|
|
||||||
mode = TEXTURE_MODE_SEETHROUGH;
|
|
||||||
use_texture_mode(mode);
|
|
||||||
|
|
||||||
DeferredCommand final_command = {
|
|
||||||
.type = DEFERRED_COMMAND_TYPE_DRAW,
|
|
||||||
.draw = command
|
|
||||||
};
|
|
||||||
|
|
||||||
arrpush(deferred_commands, final_command);
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user