Commit: 5ecd2554b77675bad84f81a6c9fb7e60907764bb
Parent: 5d94a74e8838d1ad6445ef4a6c9362c99a875010
Author: Randy Palamar
Date: Sat, 5 Jul 2025 17:38:15 -0600
ui: remove render_2d.frag
render_3d.frag can do the same thing but also 3D
Diffstat:
7 files changed, 84 insertions(+), 131 deletions(-)
diff --git a/beamformer.c b/beamformer.c
@@ -486,7 +486,7 @@ DEBUG_EXPORT BEAMFORMER_RELOAD_SHADER_FN(beamformer_reload_shader)
if (new_program) {
glDeleteProgram(*src->shader);
*src->shader = new_program;
- if (src->kind == BeamformerShaderKind_Render2D) ctx->frame_view_render_context.updated = 1;
+ if (src->kind == BeamformerShaderKind_Render3D) ctx->frame_view_render_context.updated = 1;
}
return new_program != 0;
}
diff --git a/beamformer.h b/beamformer.h
@@ -75,11 +75,9 @@ typedef struct {
#define FRAME_VIEW_RENDER_TARGET_SIZE 1024, 1024
typedef struct {
- u32 shaders[2]; /* [0] -> 2D render, [1] -> 3D render */
+ u32 shader;
u32 framebuffers[2]; /* [0] -> multisample target, [1] -> normal target for resolving */
u32 renderbuffers[2]; /* only used for 3D views, size is fixed */
- u32 vao;
- u32 vbo;
b32 updated;
} FrameViewRenderContext;
diff --git a/beamformer_parameters.h b/beamformer_parameters.h
@@ -23,11 +23,10 @@ typedef enum {
#define X(e, n, s, h, pn) BeamformerShaderKind_##e = n,
COMPUTE_SHADERS
#undef X
- BeamformerShaderKind_Render2D,
BeamformerShaderKind_Render3D,
BeamformerShaderKind_Count,
- BeamformerShaderKind_ComputeCount = BeamformerShaderKind_Render2D,
+ BeamformerShaderKind_ComputeCount = BeamformerShaderKind_Render3D,
} BeamformerShaderKind;
typedef struct {
diff --git a/math.c b/math.c
@@ -336,6 +336,17 @@ v4_lerp(v4 a, v4 b, f32 t)
return result;
}
+function m4
+m4_identity(void)
+{
+ m4 result;
+ result.c[0] = (v4){{1, 0, 0, 0}};
+ result.c[1] = (v4){{0, 1, 0, 0}};
+ result.c[2] = (v4){{0, 0, 1, 0}};
+ result.c[3] = (v4){{0, 0, 0, 1}};
+ return result;
+}
+
function v4
m4_row(m4 a, u32 row)
{
@@ -412,6 +423,17 @@ m4_translation(v3 delta)
}
function m4
+m4_scale(v3 scale)
+{
+ m4 result;
+ result.c[0] = (v4){{scale.x, 0, 0, 0}};
+ result.c[1] = (v4){{0, scale.y, 0, 0}};
+ result.c[2] = (v4){{0, 0, scale.z, 0}};
+ result.c[3] = (v4){{0, 0, 0, 1}};
+ return result;
+}
+
+function m4
m4_rotation_about_y(f32 turns)
{
f32 sa = sin_f32(turns * 2 * PI);
@@ -427,12 +449,7 @@ m4_rotation_about_y(f32 turns)
function m4
y_aligned_volume_transform(v3 extent, v3 translation, f32 rotation_turns)
{
- m4 S;
- S.c[0] = (v4){{extent.x, 0, 0, 0}};
- S.c[1] = (v4){{0, extent.y, 0, 0}};
- S.c[2] = (v4){{0, 0, extent.z, 0}};
- S.c[3] = (v4){{0, 0, 0, 1}};
-
+ m4 S = m4_scale(extent);
m4 R = m4_rotation_about_y(rotation_turns);
m4 T = m4_translation(translation);
m4 result = m4_mul(m4_mul(R, S), T);
@@ -451,6 +468,19 @@ m4_mul_v4(m4 a, v4 v)
}
function m4
+orthographic_projection(f32 n, f32 f, f32 t, f32 r)
+{
+ m4 result;
+ f32 a = -2 / (f - n);
+ f32 b = - (f + n) / (f - n);
+ result.c[0] = (v4){{1 / r, 0, 0, 0}};
+ result.c[1] = (v4){{0, 1 / t, 0, 0}};
+ result.c[2] = (v4){{0, 0, a, 0}};
+ result.c[3] = (v4){{0, 0, b, 1}};
+ return result;
+}
+
+function m4
perspective_projection(f32 n, f32 f, f32 fov, f32 aspect)
{
m4 result;
diff --git a/shaders/render_2d.frag.glsl b/shaders/render_2d.frag.glsl
@@ -1,34 +0,0 @@
-/* See LICENSE for license details. */
-
-/* input: h [0,360] | s,v [0, 1] *
- * output: rgb [0,1] */
-vec3 hsv2rgb(vec3 hsv)
-{
- vec3 k = mod(vec3(5, 3, 1) + hsv.x / 60, 6);
- k = max(min(min(k, 4 - k), 1), 0);
- return hsv.z - hsv.z * hsv.y * k;
-}
-
-void main()
-{
- ivec3 out_data_dim = textureSize(u_texture, 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 */
- vec3 tex_coord = vec3(texture_coordinate.x, 0.5, texture_coordinate.y);
- float smp = length(texture(u_texture, tex_coord).xy);
- float threshold_val = pow(10.0f, u_threshold / 20.0f);
- smp = clamp(smp, 0.0f, threshold_val);
- smp = smp / threshold_val;
- smp = pow(smp, u_gamma);
-
- if (u_log_scale) {
- smp = 20 * log(smp) / log(10);
- smp = clamp(smp, -u_db_cutoff, 0) / -u_db_cutoff;
- smp = 1 - smp;
- }
-
- //v_out_colour = vec4(hsv2rgb(vec3(360 * smp, 0.8, 0.95)), 1);
- v_out_colour = vec4(smp, smp, smp, 1);
-}
diff --git a/static.c b/static.c
@@ -392,68 +392,13 @@ setup_beamformer(BeamformerCtx *ctx, BeamformerInput *input, Arena *memory)
glNamedRenderbufferStorageMultisample(fvr->renderbuffers[1], msaa_samples, GL_DEPTH_COMPONENT24,
FRAME_VIEW_RENDER_TARGET_SIZE);
- f32 vertices[] = {
- -1, 1, 0, 0,
- -1, -1, 0, 1,
- 1, -1, 1, 1,
- -1, 1, 0, 0,
- 1, -1, 1, 1,
- 1, 1, 1, 0,
- };
- glCreateVertexArrays(1, &fvr->vao);
- glCreateBuffers(1, &fvr->vbo);
-
- glNamedBufferData(fvr->vbo, sizeof(vertices), vertices, GL_STATIC_DRAW);
-
- glEnableVertexArrayAttrib(fvr->vao, 0);
- glEnableVertexArrayAttrib(fvr->vao, 1);
- glVertexArrayVertexBuffer(fvr->vao, 0, fvr->vbo, 0, 4 * sizeof(f32));
- glVertexArrayVertexBuffer(fvr->vao, 1, fvr->vbo, 2 * sizeof(f32), 4 * sizeof(f32));
- glVertexArrayAttribFormat(fvr->vao, 0, 2, GL_FLOAT, 0, 0);
- glVertexArrayAttribFormat(fvr->vao, 1, 2, GL_FLOAT, 0, 2 * sizeof(f32));
- glVertexArrayAttribBinding(fvr->vao, 0, 0);
- glVertexArrayAttribBinding(fvr->vao, 1, 0);
-
- ShaderReloadContext *render_2d = push_struct(memory, typeof(*render_2d));
- render_2d->beamformer_context = ctx;
- render_2d->path = s8(static_path_join("shaders", "render_2d.frag.glsl"));
- render_2d->name = s8("shaders/render_2d.glsl");
- render_2d->gl_type = GL_FRAGMENT_SHADER;
- render_2d->kind = BeamformerShaderKind_Render2D;
- render_2d->shader = fvr->shaders + 0;
- render_2d->header = s8(""
- "layout(location = 0) in vec2 texture_coordinate;\n"
- "layout(location = 0) out vec4 v_out_colour;\n\n"
- "layout(location = " str(FRAME_VIEW_DYNAMIC_RANGE_LOC) ") uniform float u_db_cutoff = 60;\n"
- "layout(location = " str(FRAME_VIEW_THRESHOLD_LOC) ") uniform float u_threshold = 40;\n"
- "layout(location = " str(FRAME_VIEW_GAMMA_LOC) ") uniform float u_gamma = 1;\n"
- "layout(location = " str(FRAME_VIEW_LOG_SCALE_LOC) ") uniform bool u_log_scale;\n"
- "\n"
- "layout(binding = 0) uniform sampler3D u_texture;\n");
- render_2d->link = push_struct(memory, typeof(*render_2d));
- render_2d->link->gl_type = GL_VERTEX_SHADER;
- render_2d->link->link = render_2d;
- render_2d->link->header = s8(""
- "layout(location = 0) in vec2 v_position;\n"
- "layout(location = 1) in vec2 v_texture_coordinate;\n"
- "\n"
- "layout(location = 0) out vec2 f_texture_coordinate;\n"
- "\n"
- "void main()\n"
- "{\n"
- "\tf_texture_coordinate = v_texture_coordinate;\n"
- "\tgl_Position = vec4(v_position, 0, 1);\n"
- "}\n");
- reload_shader(&ctx->os, render_2d->path, (iptr)render_2d, *memory);
- os_add_file_watch(&ctx->os, memory, render_2d->path, reload_shader, (iptr)render_2d);
-
ShaderReloadContext *render_3d = push_struct(memory, typeof(*render_3d));
render_3d->beamformer_context = ctx;
render_3d->path = s8(static_path_join("shaders", "render_3d.frag.glsl"));
render_3d->name = s8("shaders/render_3d.glsl");
render_3d->gl_type = GL_FRAGMENT_SHADER;
render_3d->kind = BeamformerShaderKind_Render3D;
- render_3d->shader = fvr->shaders + 1;
+ render_3d->shader = &fvr->shader;
render_3d->header = s8(""
"layout(location = 0) in vec3 normal;\n"
"layout(location = 1) in vec3 texture_coordinate;\n\n"
diff --git a/ui.c b/ui.c
@@ -1,7 +1,6 @@
/* See LICENSE for license details. */
/* TODO(rnp):
* [ ]: live parameters control panel
- * [ ]: refactor: render_2d.frag should be merged into render_3d.frag
* [ ]: refactor: ui should be in its own thread and that thread should only be concerned with the ui
* [ ]: refactor: remove all the excessive measure_texts (cell drawing, hover_interaction in params table)
* [ ]: refactor: move remaining fragment shader stuff into ui
@@ -1384,15 +1383,21 @@ ui_copy_frame(BeamformerUI *ui, Variable *view, RegionSplitDirection direction)
}
function v3
-x_plane_size(BeamformerUI *ui)
-{
- v3 min = v4_from_f32_array(ui->params.output_min_coordinate).xyz;
- v3 max = v4_from_f32_array(ui->params.output_max_coordinate).xyz;
- v3 result = v3_sub(max, min);
- swap(result.y, result.z);
- result.x = MAX(1e-3, result.x);
- result.y = MAX(1e-3, result.y);
- result.z = MAX(1e-3, result.z);
+beamformer_frame_view_plane_size(BeamformerUI *ui, BeamformerFrameView *view)
+{
+ v3 result;
+ if (view->kind == BeamformerFrameViewKind_3DXPlane) {
+ v3 min = v4_from_f32_array(ui->params.output_min_coordinate).xyz;
+ v3 max = v4_from_f32_array(ui->params.output_max_coordinate).xyz;
+ result = v3_sub(max, min);
+ swap(result.y, result.z);
+ result.x = MAX(1e-3, result.x);
+ result.y = MAX(1e-3, result.y);
+ result.z = MAX(1e-3, result.z);
+ } else {
+ v2 size = v2_sub(XZ(view->max_coordinate), XZ(view->min_coordinate));
+ result = (v3){.x = size.x, .y = size.y};
+ }
return result;
}
@@ -1438,7 +1443,7 @@ offset_x_plane_position(BeamformerUI *ui, BeamformerFrameView *view, BeamformerV
function v3
camera_for_x_plane_view(BeamformerUI *ui, BeamformerFrameView *view)
{
- v3 size = x_plane_size(ui);
+ v3 size = beamformer_frame_view_plane_size(ui, view);
v3 target = x_plane_position(ui);
f32 dist = v2_magnitude(XY(size));
v3 result = v3_add(target, (v3){{dist, -0.5f * size.y * tan_f32(50.0f * PI / 180.0f), dist}});
@@ -1501,7 +1506,7 @@ render_single_xplane(BeamformerUI *ui, BeamformerFrameView *view, Variable *x_pl
if (ui->latest_plane[tag])
texture = ui->latest_plane[tag]->texture;
- v3 scale = x_plane_size(ui);
+ v3 scale = beamformer_frame_view_plane_size(ui, view);
m4 model_transform = y_aligned_volume_transform(scale, translate, rotation_turns);
v4 colour = v4_lerp(FG_COLOUR, HOVERED_COLOUR, x_plane_shift->hover_t);
@@ -1533,8 +1538,6 @@ render_single_xplane(BeamformerUI *ui, BeamformerFrameView *view, Variable *x_pl
function void
render_3D_xplane(BeamformerUI *ui, BeamformerFrameView *view, u32 program)
{
- glBindVertexArray(ui->unit_cube_model.vao);
-
if (view->demo->bool32) {
view->rotation += dt_for_frame * 0.125f;
if (view->rotation > 1.0f) view->rotation -= 1.0f;
@@ -1546,6 +1549,7 @@ render_3D_xplane(BeamformerUI *ui, BeamformerFrameView *view, u32 program)
glProgramUniformMatrix4fv(program, FRAME_VIEW_VIEW_MATRIX_LOC, 1, 0, view_m.E);
glProgramUniformMatrix4fv(program, FRAME_VIEW_PROJ_MATRIX_LOC, 1, 0, projection.E);
+ glProgramUniform1f(program, FRAME_VIEW_BB_FRACTION_LOC, FRAME_VIEW_BB_FRACTION);
v3 model_translate = offset_x_plane_position(ui, view, BeamformerViewPlaneTag_XZ);
render_single_xplane(ui, view, view->x_plane_shifts + 0, program,
@@ -1558,6 +1562,24 @@ render_3D_xplane(BeamformerUI *ui, BeamformerFrameView *view, u32 program)
model_translate, BeamformerViewPlaneTag_YZ);
}
+function void
+render_2D_plane(BeamformerUI *ui, BeamformerFrameView *view, u32 program)
+{
+ m4 view_m = m4_identity();
+ v3 size = beamformer_frame_view_plane_size(ui, view);
+ m4 model = m4_scale(size);
+ m4 projection = orthographic_projection(0, 1, size.y / 2, size.x / 2);
+
+ glProgramUniformMatrix4fv(program, FRAME_VIEW_MODEL_MATRIX_LOC, 1, 0, model.E);
+ glProgramUniformMatrix4fv(program, FRAME_VIEW_VIEW_MATRIX_LOC, 1, 0, view_m.E);
+ glProgramUniformMatrix4fv(program, FRAME_VIEW_PROJ_MATRIX_LOC, 1, 0, projection.E);
+
+ glProgramUniform1f(program, FRAME_VIEW_BB_FRACTION_LOC, 0);
+ glBindTextureUnit(0, view->frame->texture);
+ glDrawElements(GL_TRIANGLES, ui->unit_cube_model.elements, GL_UNSIGNED_SHORT,
+ (void *)ui->unit_cube_model.elements_offset);
+}
+
function b32
frame_view_ready_to_present(BeamformerUI *ui, BeamformerFrameView *view)
{
@@ -1602,24 +1624,19 @@ function void
update_frame_views(BeamformerUI *ui, Rect window)
{
FrameViewRenderContext *ctx = ui->frame_view_render_context;
- b32 fbo_bound = 0, shader_3d = 0;
+ b32 fbo_bound = 0;
for (BeamformerFrameView *view = ui->views; view; view = view->next) {
if (view_update(ui, view)) {
if (!fbo_bound) {
fbo_bound = 1;
glBindFramebuffer(GL_FRAMEBUFFER, ctx->framebuffers[0]);
- glUseProgram(ctx->shaders[0]);
+ glUseProgram(ctx->shader);
+ glBindVertexArray(ui->unit_cube_model.vao);
glEnable(GL_DEPTH_TEST);
}
- if (view->kind == BeamformerFrameViewKind_3DXPlane) {
- if (!shader_3d) { glUseProgram(ctx->shaders[1]); shader_3d = 1; }
- } else {
- if ( shader_3d) { glUseProgram(ctx->shaders[0]); shader_3d = 0; }
- }
-
u32 fb = ctx->framebuffers[0];
- u32 program = ctx->shaders[shader_3d];
+ u32 program = ctx->shader;
glViewport(0, 0, view->texture_dim.w, view->texture_dim.h);
glProgramUniform1f(program, FRAME_VIEW_THRESHOLD_LOC, view->threshold.real32);
glProgramUniform1f(program, FRAME_VIEW_DYNAMIC_RANGE_LOC, view->dynamic_range.real32);
@@ -1631,7 +1648,7 @@ update_frame_views(BeamformerUI *ui, Rect window)
glNamedFramebufferRenderbuffer(fb, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, ctx->renderbuffers[1]);
glClearNamedFramebufferfv(fb, GL_COLOR, 0, (f32 []){0, 0, 0, 0});
glClearNamedFramebufferfv(fb, GL_DEPTH, 0, (f32 []){1});
- render_3D_xplane(ui, view, ctx->shaders[1]);
+ render_3D_xplane(ui, view, program);
/* NOTE(rnp): resolve multisampled scene */
glNamedFramebufferTexture(ctx->framebuffers[1], GL_COLOR_ATTACHMENT0, view->textures[0], 0);
glBlitNamedFramebuffer(fb, ctx->framebuffers[1], 0, 0, FRAME_VIEW_RENDER_TARGET_SIZE,
@@ -1641,9 +1658,7 @@ update_frame_views(BeamformerUI *ui, Rect window)
glNamedFramebufferTexture(fb, GL_DEPTH_ATTACHMENT, view->textures[1], 0);
glClearNamedFramebufferfv(fb, GL_COLOR, 0, (f32 []){0, 0, 0, 0});
glClearNamedFramebufferfv(fb, GL_DEPTH, 0, (f32 []){1});
- glBindVertexArray(ctx->vao);
- glBindTextureUnit(0, view->frame->texture);
- glDrawArrays(GL_TRIANGLES, 0, 6);
+ render_2D_plane(ui, view, program);
}
glGenerateTextureMipmap(view->textures[0]);
view->dirty = 0;
@@ -2227,7 +2242,7 @@ draw_3D_xplane_frame_view(BeamformerUI *ui, Arena arena, Variable *var, Rect dis
i32 id = -1;
if (hover_interaction(ui, mouse, auto_interaction(vr, var))) {
ray mouse_ray = ray_for_x_plane_view(ui, view, normalized_p_in_rect(vr, mouse, 0));
- v3 x_size = v3_scale(x_plane_size(ui), 0.5f);
+ v3 x_size = v3_scale(beamformer_frame_view_plane_size(ui, view), 0.5f);
f32 rotation = x_plane_rotation_for_view_plane(view, BeamformerViewPlaneTag_XZ);
m4 x_rotation = m4_rotation_about_y(rotation);
@@ -2326,7 +2341,7 @@ draw_beamformer_frame_view(BeamformerUI *ui, Arena a, Variable *var, Rect displa
.y = pixels_per_meter.y * (frame->max_coordinate.z - max.z),
};
- Rectangle tex_r = {texture_start.x, texture_start.y, texture_points.x, -texture_points.y};
+ Rectangle tex_r = {texture_start.x, texture_start.y, texture_points.x, texture_points.y};
NPatchInfo tex_np = { tex_r, 0, 0, 0, 0, NPATCH_NINE_PATCH };
DrawTextureNPatch(make_raylib_texture(view), tex_np, vr.rl, (Vector2){0}, 0, WHITE);