diff options
author | quou <quou@disroot.org> | 2025-01-13 20:56:13 +1100 |
---|---|---|
committer | quou <quou@disroot.org> | 2025-01-13 20:56:13 +1100 |
commit | 014077c89bb3c50718d56430f387109ad43508b6 (patch) | |
tree | 02fa1ab03218fc22de4d875b7d8d593cbc19d67c /c2.cpp | |
parent | 4d5cdc97a044a39fabbfb980b2e48a817a6e485f (diff) |
basic picking and debug rendering
Diffstat (limited to 'c2.cpp')
-rw-r--r-- | c2.cpp | 161 |
1 files changed, 159 insertions, 2 deletions
@@ -13,6 +13,7 @@ extern "C" { #define video_arena_size (1024 * 1024 * 16) #define asset_arena_size (1024 * 1024 * 4) #define ui_arena_size (1024 * 16) +#define scene_arena_size (1024) #define per_frame_memory_size (1024 * 1024) static float verts[] = { @@ -533,6 +534,134 @@ struct Env_Probe { } }; +struct Line_Renderer { + static constexpr int max_lines = 1024; + Staged_Buffer vb, cb; + Shader* shader; + int vert_binding, cbuffer_binding; + int cur; + int w, h; + v3f cur_col; + + struct Vertex { + float x, y, z; + float r, g, b; + }* verts; + + struct CBuffer { + m4f vp; + }; + + void init(Device* dev, Asset_Arena* assets) { + vb.init( + dev, + "Line Renderer mesh", + max_lines * sizeof(Vertex) * 2, + Buffer_Flags::vertex_buffer + ); + cb.init( + dev, + "Line Renderer cbuffer", + sizeof(CBuffer), + Buffer_Flags::constant_buffer + ); + shader = (Shader*)assets->load("debug.csh"); + vert_binding = shader->binding_index("verts"); + cbuffer_binding = shader->descriptor_binding("cbuf"); + assert(vert_binding >= 0); + assert(cbuffer_binding >= 0); + verts = (Vertex*)vb.map(dev); + cur = 0; + } + + void destroy(Device* dev) { + vb.unmap(dev); + vb.destroy(dev); + cb.destroy(dev); + } + + void begin(int wi, int he) { + cur = 0; + w = wi; + h = he; + cur_col = v3f(1.0f, 1.0f, 1.0f); + } + + void colour(const v3f& c) { + cur_col = c; + } + + void add_line(const v3f& s, const v3f& e) { + if (cur >= max_lines) { + assert(0); + return; + } + Vertex& a = verts[cur * 2]; + Vertex& b = verts[cur * 2 + 1]; + a.x = s.x; + a.y = s.y; + a.z = s.z; + b.x = e.x; + b.y = e.y; + b.z = e.z; + a.r = cur_col.x; + a.g = cur_col.y; + a.b = cur_col.z; + b.r = cur_col.x; + b.g = cur_col.y; + b.b = cur_col.z; + cur++; + } + + void add_box(const AABB& b) { + add_line(v3f(b.max.x, b.max.y, b.max.z), v3f(b.max.x, b.max.y, b.min.z)); + add_line(v3f(b.max.x, b.max.y, b.max.z), v3f(b.max.x, b.min.y, b.max.z)); + add_line(v3f(b.max.x, b.max.y, b.max.z), v3f(b.min.x, b.max.y, b.max.z)); + add_line(v3f(b.max.x, b.min.y, b.min.z), v3f(b.max.x, b.max.y, b.min.z)); + add_line(v3f(b.max.x, b.min.y, b.min.z), v3f(b.max.x, b.min.y, b.max.z)); + add_line(v3f(b.min.x, b.max.y, b.max.z), v3f(b.min.x, b.min.y, b.max.z)); + add_line(v3f(b.min.x, b.max.y, b.min.z), v3f(b.max.x, b.max.y, b.min.z)); + add_line(v3f(b.min.x, b.max.y, b.min.z), v3f(b.min.x, b.max.y, b.max.z)); + add_line(v3f(b.min.x, b.min.y, b.max.z), v3f(b.max.x, b.min.y, b.max.z)); + add_line(v3f(b.min.x, b.min.y, b.min.z), v3f(b.max.x, b.min.y, b.min.z)); + add_line(v3f(b.min.x, b.min.y, b.min.z), v3f(b.min.x, b.max.y, b.min.z)); + add_line(v3f(b.min.x, b.min.y, b.min.z), v3f(b.min.x, b.min.y, b.max.z)); + } + + void flush( + const Camera& cam, + Device* dev, + Arena* a, + Render_Pass& rp + ) { + if (!cur) return; + CBuffer* c = (CBuffer*)cb.map(dev); + c->vp = cam.get_proj() * cam.get_view(); + cb.unmap(dev); + Pipeline_Builder pb(a, dev); + Context& ctx = dev->get_ctx(); + cb.update(ctx); + vb.update(ctx); + pb.begin(); + pb.shader(shader->id); + pb.cbuffer(cbuffer_binding, cb.gpuonly); + pb.vertex_format(shader->vf); + pb.geo(Geo_Type::lines); + Pipeline& pip = pb.build(); + Vertex_Buffer_Binding binding[] = {{ + .id = vb.gpuonly, + .offset = 0, + .target = vert_binding + }, {}}; + Draw d{}; + d.verts = binding; + d.vertex_count = cur * 2; + d.instance_count = 1; + ctx.submit(d, pip, rp); + cur = 0; + } +}; + struct Config_Buffer { float offset[2]; }; @@ -543,7 +672,7 @@ struct Config_Buffer2 { }; struct C2 : public App { - Arena video_arena, asset_arena, ui_arena; + Arena video_arena, asset_arena, ui_arena, scene_arena; Model_Loader model_loader; Material_Loader mat_loader; Asset_Arena assets; @@ -559,6 +688,7 @@ struct C2 : public App { Env_Probe eprobe; Buffer_Id vbo, cbuf; Sampler_Id clamped_linear; + Line_Renderer lr; UI* ui; UI::Label* fps_label; void* per_frame; @@ -566,6 +696,8 @@ struct C2 : public App { uint8_t r = 0; float rot = 0.0f; v3f raxis = v3f(0.0f, 1.0f, 0.0); + Model_Instance* selected_model; + int selected_mesh; void on_init() override { running = 1; @@ -584,6 +716,11 @@ struct C2 : public App { arena_alloc(arena, ui_arena_size), ui_arena_size ); + init_arena( + &scene_arena, + arena_alloc(arena, scene_arena_size), + scene_arena_size + ); assets.init(&asset_arena, "pack", 128); dev = Device::create(&video_arena, this); default_texture = make_default_texture(dev); @@ -607,11 +744,12 @@ struct C2 : public App { ); clamped_linear = create_clamped_linear(dev); ui = UI::create(dev, this, &ui_arena, ui_shader->id); + lr.init(dev, &assets); assert(per_frame != 0); vbo = upload_verts(dev); ui->layout(w, h); fps_label = ui->create_element<UI::Label>(ui->root, ""); - scene.init(arena, 32, clamped_linear); + scene.init(&scene_arena, 32, clamped_linear); monkey = scene.instantiate( dev, (Model*)assets.load("monkey.mdl") @@ -630,6 +768,7 @@ struct C2 : public App { init_arena(&frame_arena, per_frame, per_frame_memory_size); dev->begin_frame(); + lr.begin(w, h); if (frame % 10 == 0) { char buf[32]; @@ -748,6 +887,23 @@ struct C2 : public App { ui->render(&frame_arena, dev->get_backbuffer()); ctx.debug_pop(); + if (mjp(mbtn_left)) { + std::tie(selected_model, selected_mesh) = + scene.pick(camera, w, h, mx, my); + } + + lr.colour(v3f(1.0f, 0.0f, 0.0f)); + + if (selected_model) { + lr.add_box(selected_model->bounds[selected_mesh]); + } + + ctx.debug_push("debug"); + pb.begin_rp(); + pb.rp_target(dev->get_backbuffer(), Clear_Mode::restore); + lr.flush(camera, dev, &frame_arena, pb.build_rp()); + ctx.debug_pop(); + r += 10; rot += 1.0f * dt; frame++; @@ -757,6 +913,7 @@ struct C2 : public App { void on_destroy() override { scene.destroy(dev); sky.destroy(dev); + lr.destroy(dev); eprobe.destroy(dev); ui->destroy(); assets.destroy(); |