Resize depth texture when window resizes

main
copygirl 9 months ago
parent 6b69fee401
commit 7f5c5ce16c
  1. 5
      src/main.zig
  2. 51
      src/renderer.zig

@ -52,9 +52,14 @@ pub fn update(app: *App) !bool {
var iter = core.pollEvents(); var iter = core.pollEvents();
while (iter.next()) |event| { while (iter.next()) |event| {
switch (event) { switch (event) {
// Allow the renderer to act on the window being resized.
// This is required so we can resize necessary buffers.
.framebuffer_resize => |_| app.renderer.resize(),
// Close the window when requested, such as when // Close the window when requested, such as when
// pressing the X button in the window title bar. // pressing the X button in the window title bar.
.close => return true, .close => return true,
else => {}, else => {},
} }
} }

@ -38,26 +38,17 @@ const Renderer = @This();
app: *App, app: *App,
depth_texture: *gpu.Texture,
depth_texture_view: *gpu.TextureView,
pipeline: *gpu.RenderPipeline, pipeline: *gpu.RenderPipeline,
scene_uniform_buffer: *gpu.Buffer, scene_uniform_buffer: *gpu.Buffer,
scene_uniform_bind_group: *gpu.BindGroup, scene_uniform_bind_group: *gpu.BindGroup,
depth_texture: ?*gpu.Texture = null,
depth_texture_view: ?*gpu.TextureView = null,
primitive_data: []PrimitiveData, primitive_data: []PrimitiveData,
object_data: []ObjectData, object_data: []ObjectData,
pub fn init(app: *App) !*Renderer { pub fn init(app: *App) !*Renderer {
// 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.
const depth_texture = core.device.createTexture(&.{
.usage = .{ .render_attachment = true },
.size = .{ .width = core.descriptor.width, .height = core.descriptor.height },
.format = .depth24_plus,
});
const depth_texture_view = depth_texture.createView(null);
const shader_module = core.device.createShaderModuleWGSL("shader.wgsl", @embedFile("shader.wgsl")); const shader_module = core.device.createShaderModuleWGSL("shader.wgsl", @embedFile("shader.wgsl"));
defer shader_module.release(); defer shader_module.release();
@ -167,14 +158,17 @@ pub fn init(app: *App) !*Renderer {
const result = try app.allocator.create(Renderer); const result = try app.allocator.create(Renderer);
result.* = .{ result.* = .{
.app = app, .app = app,
.depth_texture = depth_texture,
.depth_texture_view = depth_texture_view,
.pipeline = pipeline, .pipeline = pipeline,
.scene_uniform_buffer = scene_uniform.buffer, .scene_uniform_buffer = scene_uniform.buffer,
.scene_uniform_bind_group = scene_uniform.bind_group, .scene_uniform_bind_group = scene_uniform.bind_group,
.primitive_data = primitive_data, .primitive_data = primitive_data,
.object_data = object_data, .object_data = object_data,
}; };
// Initialize the depth texture.
// This is called also whenever the window is resized.
result.recreateDepthTexture();
return result; return result;
} }
@ -183,8 +177,6 @@ pub fn deinit(self: *Renderer) void {
// in the order they were created in `init`. // in the order they were created in `init`.
defer self.app.allocator.destroy(self); defer self.app.allocator.destroy(self);
defer self.depth_texture.release();
defer self.depth_texture_view.release();
defer self.pipeline.release(); defer self.pipeline.release();
defer self.scene_uniform_buffer.release(); defer self.scene_uniform_buffer.release();
defer self.scene_uniform_bind_group.release(); defer self.scene_uniform_bind_group.release();
@ -199,6 +191,15 @@ pub fn deinit(self: *Renderer) void {
o.uniform_buffer.release(); o.uniform_buffer.release();
o.uniform_bind_group.release(); o.uniform_bind_group.release();
}; };
defer if (self.depth_texture) |t| t.release();
defer if (self.depth_texture_view) |v| v.release();
}
pub fn resize(self: *Renderer) void {
// Recreate depth texture with the proper size, otherwise
// the application may crash when the window is resized.
self.recreateDepthTexture();
} }
pub fn update(self: *Renderer) void { pub fn update(self: *Renderer) void {
@ -236,7 +237,7 @@ pub fn update(self: *Renderer) void {
.store_op = .store, .store_op = .store,
}}, }},
.depth_stencil_attachment = &.{ .depth_stencil_attachment = &.{
.view = self.depth_texture_view, .view = self.depth_texture_view.?,
.depth_load_op = .clear, .depth_load_op = .clear,
.depth_store_op = .store, .depth_store_op = .store,
.depth_clear_value = 1.0, .depth_clear_value = 1.0,
@ -285,6 +286,22 @@ pub fn update(self: *Renderer) void {
core.queue.submit(&.{command}); core.queue.submit(&.{command});
} }
/// Creates 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.
pub fn recreateDepthTexture(self: *Renderer) void {
// Release previous depth butter and view, if any.
if (self.depth_texture) |t| t.release();
if (self.depth_texture_view) |v| v.release();
self.depth_texture = core.device.createTexture(&.{
.usage = .{ .render_attachment = true },
.size = .{ .width = core.descriptor.width, .height = core.descriptor.height },
.format = .depth24_plus,
});
self.depth_texture_view = self.depth_texture.?.createView(null);
}
/// Creates a buffer on the GPU to store uniform parameter information as /// Creates a buffer on the GPU to store uniform parameter information as
/// well as a bind group with the specified layout pointing to that buffer. /// well as a bind group with the specified layout pointing to that buffer.
/// Additionally, immediately fills the buffer with the provided data. /// Additionally, immediately fills the buffer with the provided data.

Loading…
Cancel
Save