diff --git a/src/main.zig b/src/main.zig index dd145f2..1c4e197 100644 --- a/src/main.zig +++ b/src/main.zig @@ -60,6 +60,8 @@ random: std.rand.Random, app_timer: core.Timer, title_timer: core.Timer, +depth_texture: *gpu.Texture, +depth_texture_view: *gpu.TextureView, pipeline: *gpu.RenderPipeline, scene_uniform_buffer: *gpu.Buffer, scene_uniform_bind_group: *gpu.BindGroup, @@ -87,6 +89,16 @@ pub fn init(app: *App) !void { app.app_timer = try core.Timer.start(); app.title_timer = try core.Timer.start(); + // Create a depth texture. This is used to ensure that when things are + // rendered, an object behind another won't draw over one in front, simply + // because it was rendered at a later point in time. + app.depth_texture = core.device.createTexture(&.{ + .usage = .{ .render_attachment = true }, + .size = .{ .width = core.descriptor.width, .height = core.descriptor.height }, + .format = .depth24_plus, + }); + app.depth_texture_view = app.depth_texture.createView(null); + const shader_module = core.device.createShaderModuleWGSL("shader.wgsl", @embedFile("shader.wgsl")); defer shader_module.release(); @@ -105,16 +117,21 @@ pub fn init(app: *App) !void { }), }, }), - .fragment = &gpu.FragmentState.init(.{ - .module = shader_module, - .entry_point = "frag_main", - .targets = &.{.{ .format = core.descriptor.format }}, - }), .primitive = .{ .topology = .triangle_list, .front_face = .ccw, .cull_mode = .back, }, + .depth_stencil = &.{ + .format = .depth24_plus, + .depth_write_enabled = .true, + .depth_compare = .less, + }, + .fragment = &gpu.FragmentState.init(.{ + .module = shader_module, + .entry_point = "frag_main", + .targets = &.{.{ .format = core.descriptor.format }}, + }), }); // Set up scene related uniform buffers and bind groups. @@ -283,6 +300,8 @@ pub fn deinit(app: *App) void { // in the order they were created in `init`. defer core.deinit(); defer _ = app.gpa.deinit(); // TODO: Check for memory leaks? + defer app.depth_texture.release(); + defer app.depth_texture_view.release(); defer app.pipeline.release(); defer app.scene_uniform_buffer.release(); defer app.scene_uniform_bind_group.release(); @@ -340,6 +359,12 @@ pub fn update(app: *App) !bool { .load_op = .clear, .store_op = .store, }}, + .depth_stencil_attachment = &.{ + .view = app.depth_texture_view, + .depth_load_op = .clear, + .depth_store_op = .store, + .depth_clear_value = 1.0, + }, }); // Create a `WGPUCommandEncoder` which provides an interface for recording GPU commands.