volviewer

Volumetric Data Toy Viewer
git clone anongit@rnpnr.xyz:volviewer.git
Log | Files | Refs | Feed | LICENSE

Commit: 6f70fb0962e6c9cd37882b12821159b434f61c2e
Parent: 1a87fc8b28e9232f27f13573cfe07b5fd6168f58
Author: Randy Palamar
Date:   Sun, 25 May 2025 13:14:27 -0600

multi volume rendering

in this case we actually want the volumes themselves to rotate,
not the camera.

Diffstat:
Mcommon.c | 41+++++++++++++++++++++++++++++------------
Mutil.c | 43+++++++++++++++++++++++++++++++++++++++++++
2 files changed, 72 insertions(+), 12 deletions(-)

diff --git a/common.c b/common.c @@ -35,11 +35,12 @@ typedef struct { u32 texture; } VolumeDisplayItem; -#define DRAW_ALL_VOLUMES 0 +#define DRAW_ALL_VOLUMES 1 global u32 single_volume_index = 0; global VolumeDisplayItem volumes[] = { /* WALKING FORCES */ - {"./data/test/frame_%02u.bin", 512, 1024, 64, {{-18.5, -9.6, 5}}, {{18.5, 9.6, 42}}, 0.58, 62, 0, 0, 1}, + {"./data/test/frame_%02u.bin", 512, 1024, 64, {{-18.5, -9.6, 5}}, {{18.5, 9.6, 42}}, 0.58, 62, 3 * -18.5, 0, 1}, + {"./data/test/frame_%02u.bin", 512, 1024, 64, {{-18.5, -9.6, 5}}, {{18.5, 9.6, 42}}, 0.58, 62, 3 * 18.5, 0, 1}, }; #define MODEL_RENDER_MODEL_MATRIX_LOC (0) @@ -481,7 +482,7 @@ set_camera(u32 program, u32 location, v3 position, v3 normal, v3 orthogonal) } function void -draw_volume_item(ViewerContext *ctx, VolumeDisplayItem *v) +draw_volume_item(ViewerContext *ctx, VolumeDisplayItem *v, f32 rotation) { if (!v->texture) { v->texture = load_complex_texture(ctx->arena, v->file_path, v->multi_file, @@ -490,11 +491,27 @@ draw_volume_item(ViewerContext *ctx, VolumeDisplayItem *v) u32 program = ctx->model_render_context.shader; v3 scale = v3_sub(v->max_coord_mm, v->min_coord_mm); - m4 model_transform; - model_transform.c[0] = (v4){{scale.x, 0, 0, 0}}; - model_transform.c[1] = (v4){{0, scale.z, 0, 0}}; - model_transform.c[2] = (v4){{0, 0, scale.y, 0}}; - model_transform.c[3] = (v4){{v->translate_x, 0, 0, 1}}; + m4 S; + S.c[0] = (v4){{scale.x, 0, 0, 0}}; + S.c[1] = (v4){{0, scale.z, 0, 0}}; + S.c[2] = (v4){{0, 0, scale.y, 0}}; + S.c[3] = (v4){{0, 0, 0, 1}}; + + m4 T; + T.c[0] = (v4){{1, 0, 0, v->translate_x}}; + T.c[1] = (v4){{0, 1, 0, 0}}; + T.c[2] = (v4){{0, 0, 1, 0}}; + T.c[3] = (v4){{0, 0, 0, 1}}; + + f32 sa = sin_f32(rotation); + f32 ca = cos_f32(rotation); + m4 R; + R.c[0] = (v4){{ ca, 0, sa, 0}}; + R.c[1] = (v4){{ 0, 1, 0, 0}}; + R.c[2] = (v4){{-sa, 0, ca, 0}}; + R.c[3] = (v4){{ 0, 0, 0, 1}}; + + m4 model_transform = m4_mul(m4_mul(R, S), T); glProgramUniformMatrix4fv(program, MODEL_RENDER_MODEL_MATRIX_LOC, 1, 0, model_transform.E); glProgramUniform1f(program, MODEL_RENDER_CLIP_FRACTION_LOC, 1 - v->clip_fraction); @@ -513,8 +530,8 @@ update_scene(ViewerContext *ctx, f32 dt) if (ctx->cycle_t > 1) ctx->cycle_t -= 1; f32 angle = ctx->cycle_t * 2 * PI; - ctx->camera_position.x = ctx->camera_radius * cos_f32(angle); - ctx->camera_position.z = -ctx->camera_radius * sin_f32(angle); + ctx->camera_position.x = 0; + ctx->camera_position.z = -ctx->camera_radius; ctx->camera_position.y = ctx->camera_radius * tan_f32(ctx->camera_angle); RenderTarget *rt = &ctx->multisample_target; @@ -549,9 +566,9 @@ update_scene(ViewerContext *ctx, f32 dt) #if DRAW_ALL_VOLUMES for (u32 i = 0; i < countof(volumes); i++) - draw_volume_item(ctx, volumes + i); + draw_volume_item(ctx, volumes + i, angle); #else - draw_volume_item(ctx, volumes + single_volume_index); + draw_volume_item(ctx, volumes + single_volume_index, angle); #endif /* NOTE(rnp): resolve multisampled scene */ diff --git a/util.c b/util.c @@ -127,6 +127,49 @@ cross(v3 a, v3 b) return result; } +function f32 +v4_dot(v4 a, v4 b) +{ + f32 result = 0; + result += a.x * b.x; + result += a.y * b.y; + result += a.z * b.z; + result += a.w * b.w; + return result; +} + +function v4 +m4_row(m4 a, u32 row) +{ + v4 result; + result.E[0] = a.c[0].E[row]; + result.E[1] = a.c[1].E[row]; + result.E[2] = a.c[2].E[row]; + result.E[3] = a.c[3].E[row]; + return result; +} + +function v4 +m4_column(m4 a, u32 column) +{ + v4 result = a.c[column]; + return result; +} + +function m4 +m4_mul(m4 a, m4 b) +{ + m4 result; + for (u32 i = 0; i < countof(result.E); i++) { + u32 base = i / 4; + u32 sub = i % 4; + v4 v1 = m4_row(a, base); + v4 v2 = m4_column(b, sub); + result.E[i] = v4_dot(v1, v2); + } + return result; +} + function u32 utf8_encode(u8 *out, u32 cp) {