twn_lines.c: 3d case

This commit is contained in:
veclavtalica 2025-03-01 03:46:11 +03:00
parent 5911cbd980
commit 307d5552f6
6 changed files with 62 additions and 6 deletions

View File

@ -32,7 +32,7 @@ static void process_fly_mode(State *state) {
scn->looking_direction = dir_and_up.direction; scn->looking_direction = dir_and_up.direction;
const Vec3 right = m_vec_norm(m_vec_cross(dir_and_up.direction, dir_and_up.up)); const Vec3 right = m_vec_norm(m_vec_cross(dir_and_up.direction, dir_and_up.up));
const float speed = 0.04f; /* TODO: put this in a better place */ const float speed = 0.1f; /* TODO: put this in a better place */
if (input_action_pressed("player_left")) if (input_action_pressed("player_left"))
scn->pos = vec3_sub(scn->pos, m_vec_scale(right, speed)); scn->pos = vec3_sub(scn->pos, m_vec_scale(right, speed));

View File

@ -47,6 +47,13 @@ TWN_API void draw_line(Vec2 start,
float thickness, /* optional, default: 1 */ float thickness, /* optional, default: 1 */
Color color); /* optional, default: all 255 */ Color color); /* optional, default: all 255 */
/* intended for debugging and spatial reference */
TWN_API void draw_line_3d(Vec3 start,
Vec3 finish,
float thickness, /* optional, default: 1 */
Color color); /* optional, default: all 255 */
/* TODO: combine with draw_rectangle()? */ /* TODO: combine with draw_rectangle()? */
TWN_API void draw_box(Rect rect, TWN_API void draw_box(Rect rect,
float thickness, /* optional, default: 1 */ float thickness, /* optional, default: 1 */

View File

@ -56,6 +56,9 @@ void render_clear(void) {
for (size_t i = 0; i < hmlenu(ctx.quad_batches); ++i) for (size_t i = 0; i < hmlenu(ctx.quad_batches); ++i)
arrsetlen(ctx.quad_batches[i].value.primitives, 0); arrsetlen(ctx.quad_batches[i].value.primitives, 0);
for (size_t i = 0; i < hmlenu(ctx.line_batches); ++i)
arrsetlen(ctx.line_batches[i].value.vertices, 0);
} }
@ -328,7 +331,7 @@ static void render_2d(void) {
render_circle(&invocation.primitive->circle); render_circle(&invocation.primitive->circle);
break; break;
case PRIMITIVE_2D_LINES: case PRIMITIVE_2D_LINES:
render_lines(&invocation.primitive->line); render_lines(&invocation.primitive->line, false);
stbds_arrfreef(invocation.primitive->line.vertices); stbds_arrfreef(invocation.primitive->line.vertices);
break; break;
case PRIMITIVE_2D_TEXT: case PRIMITIVE_2D_TEXT:
@ -361,7 +364,7 @@ static void render_2d(void) {
render_text(&invocation.primitive->text); render_text(&invocation.primitive->text);
break; break;
case PRIMITIVE_2D_LINES: case PRIMITIVE_2D_LINES:
render_lines(&invocation.primitive->line); render_lines(&invocation.primitive->line, false);
break; break;
default: default:
SDL_assert(false); SDL_assert(false);
@ -388,6 +391,9 @@ static void render_space(void) {
for (size_t i = 0; i < hmlenu(ctx.billboard_batches); ++i) for (size_t i = 0; i < hmlenu(ctx.billboard_batches); ++i)
finally_draw_billboard_batch(&ctx.billboard_batches[i].value, ctx.billboard_batches[i].key); finally_draw_billboard_batch(&ctx.billboard_batches[i].value, ctx.billboard_batches[i].key);
for (size_t i = 0; i < hmlenu(ctx.line_batches); ++i)
render_lines(&ctx.line_batches[i].value, true);
render_skybox(); /* after everything else, as to use depth buffer for early z rejection */ render_skybox(); /* after everything else, as to use depth buffer for early z rejection */
} }

View File

@ -322,7 +322,7 @@ IndexBuffer get_circle_element_buffer(void);
void render_circle(const CirclePrimitive *circle); void render_circle(const CirclePrimitive *circle);
void render_lines(const LinePrimitive *line); void render_lines(const LinePrimitive *line, bool is_3d);
void render_rectangle(const RectPrimitive *rectangle); void render_rectangle(const RectPrimitive *rectangle);

View File

@ -14,6 +14,11 @@ void draw_line(Vec2 start,
if (fabsf(1.0f - thickness) >= 0.00001f) if (fabsf(1.0f - thickness) >= 0.00001f)
log_warn("Thickness isn't yet implemented for line drawing (got %f)", (double)thickness); log_warn("Thickness isn't yet implemented for line drawing (got %f)", (double)thickness);
if (thickness < 1.0f) {
log_warn("Invalid thickness given.");
return;
}
struct LineVertex const v0 = { .position = (Vec3){start.x, start.y, 0}, .color = color }; struct LineVertex const v0 = { .position = (Vec3){start.x, start.y, 0}, .color = color };
struct LineVertex const v1 = { .position = (Vec3){finish.x, finish.y, 0}, .color = color }; struct LineVertex const v1 = { .position = (Vec3){finish.x, finish.y, 0}, .color = color };
@ -46,7 +51,36 @@ void draw_line(Vec2 start,
} }
void render_lines(LinePrimitive const *line) { void draw_line_3d(Vec3 start,
Vec3 finish,
float thickness,
Color color)
{
if (fabsf(1.0f - thickness) >= 0.00001f)
log_warn("Thickness isn't yet implemented for line drawing (got %f)", (double)thickness);
if (thickness < 1.0f) {
log_warn("Invalid thickness given.");
return;
}
struct LineVertex const v0 = { .position = start, .color = color };
struct LineVertex const v1 = { .position = finish, .color = color };
/* 3d case, unordered depth based draw */
struct LineBatchItemKey const key = { .color = color, .thickness = (uint8_t)(floorf(thickness)) };
struct LineBatchItem *batch_p = hmgetp_null(ctx.line_batches, key);
if (!batch_p) {
hmput(ctx.line_batches, key, ((struct LinePrimitive){.thickness = thickness, .color = color}));
batch_p = &ctx.line_batches[hmlenu(ctx.line_batches) - 1];
}
arrput(batch_p->value.vertices, v0);
arrput(batch_p->value.vertices, v1);
return;
}
void render_lines(LinePrimitive const *line, bool is_3d) {
DeferredCommandDraw command = {0}; DeferredCommandDraw command = {0};
VertexBuffer buffer = get_scratch_vertex_array(); VertexBuffer buffer = get_scratch_vertex_array();
@ -71,7 +105,9 @@ void render_lines(LinePrimitive const *line) {
command.primitive_count = (uint32_t)arrlenu(line->vertices); command.primitive_count = (uint32_t)arrlenu(line->vertices);
command.geometry_mode = DEFERRED_COMMAND_DRAW_GEOMETRY_MODE_LINES; command.geometry_mode = DEFERRED_COMMAND_DRAW_GEOMETRY_MODE_LINES;
command.pipeline = PIPELINE_2D; command.pipeline = is_3d ? PIPELINE_SPACE : PIPELINE_2D;
command.texture_mode = line->color.a == 255 ? TEXTURE_MODE_OPAQUE : TEXTURE_MODE_GHOSTLY;
command.depth_range_high = depth_range_high; command.depth_range_high = depth_range_high;
command.depth_range_low = depth_range_low; command.depth_range_low = depth_range_low;

View File

@ -50,6 +50,13 @@ typedef struct EngineContext {
MeshBatchItem *uncolored_mesh_batches; MeshBatchItem *uncolored_mesh_batches;
MeshBatchItem *billboard_batches; MeshBatchItem *billboard_batches;
MeshBatchItem *quad_batches; MeshBatchItem *quad_batches;
struct LineBatchItem {
struct LineBatchItemKey {
Color color;
uint8_t thickness;
} key;
struct LinePrimitive value;
} *line_batches;
TextCache text_cache; TextCache text_cache;
TextureCache texture_cache; TextureCache texture_cache;