Commit: b2a678ea2cb8f0ded3db53cf9c34a8843a1506d9
Parent: af4c8ec39796779c9fd0b93b87f8b31d216a0037
Author: Randy Palamar
Date: Sat, 24 May 2025 22:39:20 -0600
textured cube with drawn bounding box
Diffstat:
5 files changed, 113 insertions(+), 43 deletions(-)
diff --git a/common.c b/common.c
@@ -3,6 +3,9 @@
#include "glad/gl.h"
#include "GLFW/glfw3.h"
+#include <stdio.h>
+#include <stdarg.h>
+
#define BG_CLEAR_COLOUR (v4){{0.12, 0.1, 0.1, 1}}
#define RENDER_TARGET_SIZE 1024, 1024
@@ -12,7 +15,10 @@
* the specified frame rate */
#define OUTPUT_TIME_SECONDS 8.0f
#define OUTPUT_FRAME_RATE 30.0f
-#define OUTPUT_BG_CLEAR_COLOUR (v4){{0.0, 0.2, 0.0, 1}}
+#define OUTPUT_BG_CLEAR_COLOUR (v4){{0.0, 0.0, 0.0, 1}}
+
+#define BOUNDING_BOX_COLOUR 0.78, 0.07, 0.20, 1
+#define BOUNDING_BOX_FRACTION 0.005f
#define MODEL_RENDER_MODEL_MATRIX_LOC (0)
#define MODEL_RENDER_VIEW_MATRIX_LOC (1)
@@ -21,14 +27,8 @@
#define MODEL_RENDER_DYNAMIC_RANGE_LOC (4)
#define MODEL_RENDER_THRESHOLD_LOC (5)
#define MODEL_RENDER_GAMMA_LOC (6)
-
-typedef struct {
- v3 normal;
- v3 position;
- v3 colour;
- v3 texture_coordinate;
- u32 flags;
-} Vertex;
+#define MODEL_RENDER_BB_COLOUR_LOC (7)
+#define MODEL_RENDER_BB_FRACTION_LOC (8)
struct gl_debug_ctx {
Stream stream;
@@ -56,6 +56,21 @@ gl_debug_logger(u32 src, u32 type, u32 id, u32 lvl, s32 len, const char *msg, co
stream_reset(e, 0);
}
+function void
+stream_printf(Stream *s, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ s32 length = vsnprintf(0, 0, format, ap);
+ s->errors |= (s->cap - s->widx) < (length + 1);
+ if (!s->errors) {
+ vsnprintf((char *)(s->data + s->widx), s->cap - s->widx, format, ap);
+ s->widx += length;
+ }
+ va_end(ap);
+}
+
function u32
compile_shader(OS *os, Arena a, u32 type, str8 shader, str8 name)
{
@@ -148,6 +163,33 @@ function FILE_WATCH_CALLBACK_FN(reload_shader)
return 1;
}
+function Texture
+load_complex_texture(Arena arena, c8 *file_path, b32 multi_file, u32 width, u32 height, u32 depth)
+{
+ Texture result = {0};
+ glCreateTextures(GL_TEXTURE_3D, 1, &result.texture);
+ glTextureStorage3D(result.texture, 1, GL_RG32F, width, height, depth);
+ glTextureParameteri(result.texture, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
+ glTextureParameteri(result.texture, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
+
+ if (multi_file) {
+ /* NOTE(rnp): assumes single plane */
+ for (u32 i = 0; i < depth; i++) {
+ Stream spath = arena_stream(arena);
+ stream_printf(&spath, file_path, i);
+ str8 path = arena_stream_commit_zero(&arena, &spath);
+ str8 raw = os_read_whole_file(&arena, (char *)path.data);
+ glTextureSubImage3D(result.texture, 0, 0, 0, i, width, height, 1, GL_RG,
+ GL_FLOAT, raw.data);
+ }
+ } else {
+ str8 raw = os_read_whole_file(&arena, file_path);
+ glTextureSubImage3D(result.texture, 0, 0, 0, 0, width, height, depth, GL_RG,
+ GL_FLOAT, raw.data);
+ }
+ return result;
+}
+
function RenderModel
load_render_model(Arena arena, c8 *positions_file_name, c8 *indices_file_name, c8 *normals_file_name)
{
@@ -217,7 +259,7 @@ init_viewer(ViewerContext *ctx)
{
ctx->window_size = (sv2){.w = 640, .h = 640};
ctx->camera_radius = 5;
- ctx->camera_angle = CAMERA_ELEVATION_ANGLE * PI / 180.0f;
+ ctx->camera_angle = -CAMERA_ELEVATION_ANGLE * PI / 180.0f;
if (!glfwInit()) os_fatal(str8("failed to start glfw\n"));
@@ -246,6 +288,8 @@ init_viewer(ViewerContext *ctx)
#endif
glEnable(GL_DEPTH_TEST);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
RenderContext *rc = &ctx->model_render_context;
@@ -268,6 +312,7 @@ init_viewer(ViewerContext *ctx)
"layout(location = 1) in vec3 v_normal;\n"
"\n"
"layout(location = 0) out vec3 f_normal;\n"
+ "layout(location = 1) out vec3 f_texture_coordinate;\n"
"\n"
"layout(location = " str(MODEL_RENDER_MODEL_MATRIX_LOC) ") uniform mat4 u_model;\n"
"layout(location = " str(MODEL_RENDER_VIEW_MATRIX_LOC) ") uniform mat4 u_view;\n"
@@ -276,6 +321,7 @@ init_viewer(ViewerContext *ctx)
"\n"
"void main()\n"
"{\n"
+ "\tf_texture_coordinate = (v_position + 1) / 2;\n"
//"\tf_normal = normalize(mat3(u_model) * v_normal);\n"
"\tf_normal = v_normal;\n"
"\tgl_Position = u_projection * u_view * u_model * vec4(v_position, 1);\n"
@@ -283,30 +329,22 @@ init_viewer(ViewerContext *ctx)
model_rc->fragment_header = str8(""
"#version 460 core\n\n"
- "layout(location = 0) in vec3 normal;\n\n"
+ "layout(location = 0) in vec3 normal;\n"
+ "layout(location = 1) in vec3 texture_coordinate;\n\n"
"layout(location = 0) out vec4 out_colour;\n\n"
"layout(location = " str(MODEL_RENDER_DYNAMIC_RANGE_LOC) ") uniform float u_db_cutoff = 60;\n"
"layout(location = " str(MODEL_RENDER_THRESHOLD_LOC) ") uniform float u_threshold = 40;\n"
"layout(location = " str(MODEL_RENDER_GAMMA_LOC) ") uniform float u_gamma = 1;\n"
"layout(location = " str(MODEL_RENDER_LOG_SCALE_LOC) ") uniform bool u_log_scale;\n"
+ "layout(location = " str(MODEL_RENDER_BB_COLOUR_LOC) ") uniform vec4 u_bb_colour = vec4(" str(BOUNDING_BOX_COLOUR) ");\n"
+ "layout(location = " str(MODEL_RENDER_BB_FRACTION_LOC) ") uniform float u_bb_fraction = " str(BOUNDING_BOX_FRACTION) ";\n\n"
+ "layout(binding = 0) uniform sampler3D u_texture;\n"
"\n#line 1\n");
str8 render_model = str8("render_model.frag.glsl");
reload_shader(&ctx->os, render_model, (sptr)model_rc, ctx->arena);
os_add_file_watch(&ctx->os, &ctx->arena, render_model, reload_shader, (sptr)model_rc);
- /* TODO(rnp): think about a reasonable region (probably min_coord -> max_coord + 10%) */
- f32 n = 1;
- f32 f = 20;
- f32 a = -f / (f - n);
- f32 b = -f * n / (f - n);
- m4 projection;
- projection.c[0] = (v4){{1, 0, 0, 0}};
- projection.c[1] = (v4){{0, 1, 0, 0}};
- projection.c[2] = (v4){{0, 0, a, -1}};
- projection.c[3] = (v4){{0, 0, b, 0}};
- glProgramUniformMatrix4fv(rc->shader, MODEL_RENDER_PROJ_MATRIX_LOC, 1, 0, projection.E);
-
rc = &ctx->overlay_render_context;
ShaderReloadContext *overlay_rc = push_struct(&ctx->arena, ShaderReloadContext);
overlay_rc->render_context = rc;
@@ -326,7 +364,7 @@ init_viewer(ViewerContext *ctx)
"\n"
"void main()\n"
"{\n"
- "\tf_texture_coordinate = 1 - v_texture_coordinate;\n"
+ "\tf_texture_coordinate = v_texture_coordinate;\n"
"\tf_colour = v_colour;\n"
"\tf_flags = v_flags;\n"
"\tgl_Position = vec4(v_position, 0, 1);\n"
@@ -365,6 +403,9 @@ init_viewer(ViewerContext *ctx)
ctx->unit_cube = load_render_model(ctx->arena, "unit_cube_positions.bin",
"unit_cube_indices.bin", "unit_cube_normals.bin");
+
+ c8 *walking_cysts = "./data/test/frame_%02u.bin";
+ ctx->view_texture = load_complex_texture(ctx->arena, walking_cysts, 1, 512, 1024, 64);
}
function void
@@ -408,6 +449,20 @@ viewer_frame_step(ViewerContext *ctx, f32 dt)
glUseProgram(ctx->model_render_context.shader);
+ /* TODO(rnp): this needs to be set on hot reload */
+ /* TODO(rnp): think about a reasonable region (probably min_coord -> max_coord + 10%) */
+ f32 n = 1;
+ f32 f = 20;
+ f32 a = -f / (f - n);
+ f32 b = -f * n / (f - n);
+ m4 projection;
+ projection.c[0] = (v4){{1, 0, 0, 0}};
+ projection.c[1] = (v4){{0, 1, 0, 0}};
+ projection.c[2] = (v4){{0, 0, a, -1}};
+ projection.c[3] = (v4){{0, 0, b, 0}};
+ glProgramUniformMatrix4fv(ctx->model_render_context.shader, MODEL_RENDER_PROJ_MATRIX_LOC,
+ 1, 0, projection.E);
+
v3 camera = ctx->camera_position;
set_camera(ctx->model_render_context.shader, MODEL_RENDER_VIEW_MATRIX_LOC,
camera, v3_normalize(v3_sub(camera, (v3){0})), (v3){{0, 1, 0}});
@@ -421,6 +476,7 @@ viewer_frame_step(ViewerContext *ctx, f32 dt)
glProgramUniformMatrix4fv(ctx->model_render_context.shader, MODEL_RENDER_MODEL_MATRIX_LOC,
1, 0, model_transform.E);
+ glBindTextureUnit(0, ctx->view_texture.texture);
glBindVertexArray(ctx->unit_cube.vao);
glDrawElements(GL_TRIANGLES, ctx->unit_cube.elements, GL_UNSIGNED_SHORT,
(void *)ctx->unit_cube.elements_offset);
diff --git a/main_linux.c b/main_linux.c
@@ -47,7 +47,7 @@ dispatch_file_watch_events(OS *os, Arena arena)
extern s32
main(void)
{
- Arena memory = os_alloc_arena(MB(16));
+ Arena memory = os_alloc_arena(GB(1));
ViewerContext *ctx = push_struct(&memory, ViewerContext);
ctx->arena = memory;
diff --git a/main_w32.c b/main_w32.c
@@ -77,7 +77,7 @@ clear_io_queue(OS *os, Arena arena)
extern i32
main(void)
{
- Arena memory = os_alloc_arena(MB(16));
+ Arena memory = os_alloc_arena(GB(1));
ViewerContext *ctx = push_struct(&memory, ViewerContext);
ctx->arena = memory;
diff --git a/render_model.frag.glsl b/render_model.frag.glsl
@@ -1,5 +1,4 @@
/* See LICENSE for license details. */
-//layout(binding = 0) uniform sampler3D u_out_data_tex;
/* input: h [0,360] | s,v [0, 1] *
* output: rgb [0,1] */
@@ -10,19 +9,19 @@ vec3 hsv2rgb(vec3 hsv)
return hsv.z - hsv.z * hsv.y * k;
}
-void main()
+bool bounding_box_test(vec3 coord, float p)
{
- #if 0
- ivec3 out_data_dim = textureSize(u_out_data_tex, 0);
-
- //vec2 min_max = texelFetch(u_out_data_tex, ivec3(0), textureQueryLevels(u_out_data_tex) - 1).xy;
-
- /* TODO(rnp): select between x and y and specify slice */
- ivec2 coord = ivec2(fragment_texture_coordinate * vec2(out_data_dim.xz));
- ivec3 smp_coord = ivec3(coord.x, out_data_dim.y / 2, coord.y);
- float smp = length(texelFetch(u_out_data_tex, smp_coord, 0).xy);
+ bool result = false;
+ bvec3 tests = bvec3(1 - step(vec3(p), coord) * step(coord, vec3(1 - p)));
+ if ((tests.x && tests.y) || (tests.x && tests.z) || (tests.y && tests.z))
+ result = true;
+ return result;
+}
- float threshold_val = pow(10.0f, u_threshold / 20.0f);
+void main()
+{
+ float smp = length(texture(u_texture, texture_coordinate).xy);
+ float threshold_val = pow(10.0f, (u_threshold + 13) / 20.0f);
smp = clamp(smp, 0.0f, threshold_val);
smp = smp / threshold_val;
smp = pow(smp, u_gamma);
@@ -33,8 +32,13 @@ void main()
smp = 1 - smp;
}
- //v_out_colour = vec4(hsv2rgb(vec3(360 * smp, 0.8, 0.95)), 1);
- #endif
+ //out_colour = vec4(abs(normal), 1);
+ //out_colour = vec4(1, 1, 1, smp);
+ //out_colour = vec4(smp * abs(normal), 1);
- out_colour = vec4(abs(normal), 1);
+ if (bounding_box_test(texture_coordinate, u_bb_fraction)) {
+ out_colour = u_bb_colour;
+ } else {
+ out_colour = vec4(smp, smp, smp, 1);
+ }
}
diff --git a/util.h b/util.h
@@ -72,8 +72,8 @@
#define static_assert _Static_assert
/* NOTE: garbage to get the prepocessor to properly stringize the value of a macro */
-#define str_(x) #x
-#define str(x) str_(x)
+#define str_(...) #__VA_ARGS__
+#define str(...) str_(__VA_ARGS__)
#define countof(a) (sizeof(a) / sizeof(*a))
#define ARRAY_COUNT(a) (sizeof(a) / sizeof(*a))
@@ -269,6 +269,13 @@ struct OS {
};
typedef struct {
+ u32 texture;
+ u32 width;
+ u32 height;
+ u32 depth;
+} Texture;
+
+typedef struct {
u32 shader;
u32 vao;
u32 vbo;
@@ -303,6 +310,9 @@ typedef struct {
f32 camera_angle;
f32 camera_radius;
v3 camera_position;
+
+ Texture view_texture;
+
b32 should_exit;
void *window;