volviewer

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

Commit: caa974ffa3c99cf4525c631eb2285098abefd1ea
Parent: b7d5d9608e1a0e91b8e037c5253ed1350d7b63d0
Author: Randy Palamar
Date:   Tue, 27 May 2025 15:22:57 -0600

move options to options.h, output video as single raw file

Diffstat:
Mcommon.c | 126+++++++++++++++++++++++++++----------------------------------------------------
Aoptions.h | 41+++++++++++++++++++++++++++++++++++++++++
Mos_linux.c | 6------
Mos_win32.c | 7-------
Mutil.c | 16++++++----------
Mutil.h | 3+++
6 files changed, 93 insertions(+), 106 deletions(-)

diff --git a/common.c b/common.c @@ -5,58 +5,23 @@ #include <stdio.h> #include <stdarg.h> -/* NOTE(rnp): for video output we will render a full rotation in this much time at the - * the specified frame rate */ -#define OUTPUT_TIME_SECONDS 8.0f -#define OUTPUT_FRAME_RATE 60.0f -#define OUTPUT_BG_CLEAR_COLOUR (v4){{0.05, 0.05, 0.05, 1}} - -#define OUTPUT_PATH "/tmp/out" - -#define RENDER_MSAA_SAMPLES 8 -#define RENDER_TARGET_SIZE 1920, 1080 -#define CAMERA_ELEVATION_ANGLE 25.0f -#define CAMERA_RADIUS 200.0f - -#define BOUNDING_BOX_COLOUR 0.78, 0.07, 0.20, 1 -#define BOUNDING_BOX_FRACTION 0.007f - -typedef struct { - c8 *file_path; - u32 width; /* number of points in data */ - u32 height; - u32 depth; - v3 min_coord_mm; - v3 max_coord_mm; - f32 clip_fraction; /* fraction of half volume used to create pyramidal shape (0 for cube) */ - f32 threshold; - f32 translate_x; /* mm to translate by when multi display is active */ - b32 swizzle; /* 1 -> swap y-z coordinates when sampling texture */ - b32 multi_file; /* 1 -> depth == N-frames, file_path == fmt string */ - u32 texture; -} VolumeDisplayItem; - -#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}, - /* RCA */ - {"./data/tpw.bin", 512, 64, 1024, {{-9.6, -9.6, 5}}, {{9.6, 9.6, 42}}, 0, 85, -5 * 18.5, 1, 0}, - {"./data/vls.bin", 512, 64, 1024, {{-9.6, -9.6, 5}}, {{9.6, 9.6, 42}}, 0, 82, 5 * 18.5, 1, 0}, -}; - -#define MODEL_RENDER_MODEL_MATRIX_LOC (0) -#define MODEL_RENDER_VIEW_MATRIX_LOC (1) -#define MODEL_RENDER_PROJ_MATRIX_LOC (2) -#define MODEL_RENDER_CLIP_FRACTION_LOC (3) -#define MODEL_RENDER_LOG_SCALE_LOC (4) -#define MODEL_RENDER_DYNAMIC_RANGE_LOC (5) -#define MODEL_RENDER_THRESHOLD_LOC (6) -#define MODEL_RENDER_GAMMA_LOC (7) -#define MODEL_RENDER_BB_COLOUR_LOC (8) -#define MODEL_RENDER_BB_FRACTION_LOC (9) -#define MODEL_RENDER_SWIZZLE_LOC (10) +#include "options.h" + +#define RENDER_TARGET_SIZE RENDER_TARGET_WIDTH, RENDER_TARGET_HEIGHT +#define TOTAL_OUTPUT_FRAMES (OUTPUT_FRAME_RATE * OUTPUT_TIME_SECONDS - 1) + +#define MODEL_RENDER_MODEL_MATRIX_LOC 0 +#define MODEL_RENDER_VIEW_MATRIX_LOC 1 +#define MODEL_RENDER_PROJ_MATRIX_LOC 2 +#define MODEL_RENDER_CLIP_FRACTION_LOC 3 +#define MODEL_RENDER_SWIZZLE_LOC 4 +#define MODEL_RENDER_LOG_SCALE_LOC 5 +#define MODEL_RENDER_DYNAMIC_RANGE_LOC 6 +#define MODEL_RENDER_THRESHOLD_LOC 7 +#define MODEL_RENDER_GAMMA_LOC 8 +#define MODEL_RENDER_BB_COLOUR_LOC 9 +#define MODEL_RENDER_BB_FRACTION_LOC 10 +#define MODEL_RENDER_GAIN_LOC 11 #define CYCLE_T_UPDATE_SPEED 0.25f #define BG_CLEAR_COLOUR (v4){{0.12, 0.1, 0.1, 1}} @@ -299,8 +264,19 @@ key_callback(GLFWwindow *window, s32 key, s32 scancode, s32 action, s32 modifier ctx->demo_mode = !ctx->demo_mode; if (key == GLFW_KEY_F12 && action == GLFW_PRESS && ctx->output_frames_count == 0) { - ctx->output_frames_count = OUTPUT_TIME_SECONDS * OUTPUT_FRAME_RATE; - ctx->cycle_t = 0; + sz frames = TOTAL_OUTPUT_FRAMES; + sz needed_bytes = sizeof(u32) * RENDER_TARGET_HEIGHT * RENDER_TARGET_WIDTH * frames; + if (!ctx->video_arena.beg) { + ctx->video_arena = os_alloc_arena(needed_bytes); + if (!ctx->video_arena.beg) { + fputs("failed to allocate space for output video, video " + "won't be saved\n", stderr); + } + } + if (ctx->video_arena.beg) { + ctx->output_frames_count = TOTAL_OUTPUT_FRAMES; + ctx->cycle_t = 0; + } } if (key == GLFW_KEY_A && action != GLFW_RELEASE) @@ -331,8 +307,6 @@ init_viewer(ViewerContext *ctx) ctx->camera_angle = -CAMERA_ELEVATION_ANGLE * PI / 180.0f; ctx->camera_fov = 60.0f; - os_make_directory(OUTPUT_PATH); - if (!glfwInit()) os_fatal(str8("failed to start glfw\n")); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); @@ -692,38 +666,24 @@ update_scene(ViewerContext *ctx, f32 dt) } function void -export_frame(Arena arena, u32 texture, str8 out_directory, u32 frame_index, u32 width, u32 height) -{ - Stream spath = arena_stream(arena); - stream_append_str8(&spath, out_directory); - if (spath.widx > 0 && spath.data[spath.widx - 1] != OS_PATH_SEPARATOR_CHAR) - stream_append_byte(&spath, OS_PATH_SEPARATOR_CHAR); - stream_append_str8(&spath, str8("frame_")); - stream_append_u64_width(&spath, frame_index, 4); - stream_append_str8(&spath, str8(".bin")); - str8 path = arena_stream_commit_zero(&arena, &spath); - - sz padding = -(uintptr_t)arena.beg & (64 - 1); - sz available = arena.end - arena.beg - padding; - sz needed = width * height * sizeof(u32); - if (available > needed) { - glGetTextureImage(texture, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, needed, arena.beg); - str8 raw = {.len = needed, .data = arena.beg}; - os_write_new_file((c8 *)path.data, raw); - } -} - -function void viewer_frame_step(ViewerContext *ctx, f32 dt) { if (ctx->do_update) { update_scene(ctx, dt); if (ctx->output_frames_count) { - u32 total_frames = OUTPUT_FRAME_RATE * OUTPUT_TIME_SECONDS; - u32 frame_index = total_frames - ctx->output_frames_count--; - printf("Saving Frame: [%u/%u]\n", frame_index, total_frames); - export_frame(ctx->arena, ctx->output_target.textures[0], str8(OUTPUT_PATH), - frame_index, RENDER_TARGET_SIZE); + u32 frame_index = TOTAL_OUTPUT_FRAMES - ctx->output_frames_count--; + printf("Reading Frame: [%u/%u]\n", frame_index, (u32)TOTAL_OUTPUT_FRAMES - 1); + sz needed = ctx->output_target.size.w * ctx->output_target.size.h * sizeof(u32); + glGetTextureImage(ctx->output_target.textures[0], 0, GL_RGBA, + GL_UNSIGNED_INT_8_8_8_8, needed, + ctx->video_arena.beg + ctx->video_arena_offset); + ctx->video_arena_offset += needed; + if (!ctx->output_frames_count) { + str8 raw = {.len = TOTAL_OUTPUT_FRAMES * needed, + .data = ctx->video_arena.beg}; + ctx->video_arena_offset = 0; + os_write_new_file(RAW_OUTPUT_PATH, raw); + } } ctx->do_update = 0; } diff --git a/options.h b/options.h @@ -0,0 +1,41 @@ +/* NOTE(rnp): for video output we will render a full rotation in this much time at the + * the specified frame rate */ +#define OUTPUT_TIME_SECONDS 8.0f +#define OUTPUT_FRAME_RATE 60 +#define OUTPUT_BG_CLEAR_COLOUR (v4){{0.05, 0.05, 0.05, 1}} + +#define RAW_OUTPUT_PATH "/tmp/out.raw" + +#define RENDER_MSAA_SAMPLES 8 +#define RENDER_TARGET_WIDTH 1920 +#define RENDER_TARGET_HEIGHT 1080 +#define CAMERA_ELEVATION_ANGLE 25.0f +#define CAMERA_RADIUS 200.0f + +#define BOUNDING_BOX_COLOUR 0.78, 0.07, 0.20, 1 +#define BOUNDING_BOX_FRACTION 0.007f + +typedef struct { + c8 *file_path; + u32 width; /* number of points in data */ + u32 height; + u32 depth; + v3 min_coord_mm; + v3 max_coord_mm; + f32 clip_fraction; /* fraction of half volume used to create pyramidal shape (0 for cube) */ + f32 threshold; + f32 translate_x; /* mm to translate by when multi display is active */ + b32 swizzle; /* 1 -> swap y-z coordinates when sampling texture */ + b32 multi_file; /* 1 -> depth == N-frames, file_path == fmt string */ + u32 texture; +} VolumeDisplayItem; + +#define DRAW_ALL_VOLUMES 1 +global u32 single_volume_index = 0; +global VolumeDisplayItem volumes[] = { + /* WALKING FORCES */ + {"./data/test/frame_%02u.bin", 512, 1024, 64, {{-20.5, -9.6, 5}}, {{20.5, 9.6, 50}}, 0.62, 72, 0, 0, 1}, + /* RCA */ + {"./data/tpw.bin", 512, 64, 1024, {{-9.6, -9.6, 5}}, {{9.6, 9.6, 50}}, 0, 92, -5 * 18.5, 1, 0}, + {"./data/vls.bin", 512, 64, 1024, {{-9.6, -9.6, 5}}, {{9.6, 9.6, 50}}, 0, 89, 5 * 18.5, 1, 0}, +}; diff --git a/os_linux.c b/os_linux.c @@ -105,9 +105,3 @@ function OS_ADD_FILE_WATCH_FN(os_add_file_watch) fw->callback = callback; fw->hash = str8_hash(path); } - -function void -os_make_directory(char *name) -{ - mkdir(name, 0770); -} diff --git a/os_win32.c b/os_win32.c @@ -81,7 +81,6 @@ typedef struct { #define W32(r) __declspec(dllimport) r __stdcall W32(b32) CloseHandle(sptr); -W32(b32) CreateDirectoryA(c8 *, void *); W32(sptr) CreateFileA(c8 *, u32, u32, void *, u32, u32, void *); W32(sptr) CreateFileMappingA(sptr, void *, u32, u32, u32, c8 *); W32(sptr) CreateIoCompletionPort(sptr, sptr, uptr, u32); @@ -238,9 +237,3 @@ function OS_ADD_FILE_WATCH_FN(os_add_file_watch) fw->callback = callback; fw->hash = str8_hash(path); } - -function void -os_make_directory(char *name) -{ - CreateDirectoryA(name, 0); -} diff --git a/util.c b/util.c @@ -295,16 +295,6 @@ stream_append_str8s_(Stream *s, str8 *strs, sz count) } function void -stream_append_u64(Stream *s, u64 n) -{ - u8 tmp[64]; - u8 *end = tmp + sizeof(tmp); - u8 *beg = end; - do { *--beg = '0' + (n % 10); } while (n /= 10); - stream_append(s, beg, end - beg); -} - -function void stream_append_u64_width(Stream *s, u64 n, u64 min_width) { u8 tmp[64]; @@ -320,6 +310,12 @@ stream_append_u64_width(Stream *s, u64 n, u64 min_width) } function void +stream_append_u64(Stream *s, u64 n) +{ + stream_append_u64_width(s, n, 0); +} + +function void stream_append_s64(Stream *s, s64 n) { if (n < 0) { diff --git a/util.h b/util.h @@ -314,6 +314,9 @@ typedef struct { b32 should_exit; + Arena video_arena; + sz video_arena_offset; + void *window; } ViewerContext;