|
|
|
@ -6,16 +6,19 @@ const zm = @import("zmath"); |
|
|
|
|
const vec = zm.f32x4; |
|
|
|
|
const Mat = zm.Mat; |
|
|
|
|
|
|
|
|
|
/// Describes the layout of each vertex that a primitive is made of. |
|
|
|
|
const VertexData = struct { |
|
|
|
|
position: [3]f32, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/// Holds information about how a perticular scene should be rendered. |
|
|
|
|
const SceneUniformBuffer = struct { |
|
|
|
|
view_proj_matrix: zm.Mat, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const ModelUniformBuffer = struct { |
|
|
|
|
matrix: zm.Mat, |
|
|
|
|
/// Holds information about where and how an object should be rendered. |
|
|
|
|
const ObjectUniformBuffer = struct { |
|
|
|
|
model_matrix: zm.Mat, |
|
|
|
|
color: [3]f32, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
@ -27,8 +30,8 @@ title_timer: core.Timer, |
|
|
|
|
pipeline: *gpu.RenderPipeline, |
|
|
|
|
scene_uniform_buffer: *gpu.Buffer, |
|
|
|
|
scene_bind_group: *gpu.BindGroup, |
|
|
|
|
model_uniform_buffers: [3]*gpu.Buffer, |
|
|
|
|
model_bind_groups: [3]*gpu.BindGroup, |
|
|
|
|
object_uniform_buffers: [3]*gpu.Buffer, |
|
|
|
|
object_bind_groups: [3]*gpu.BindGroup, |
|
|
|
|
vertex_count: u32, |
|
|
|
|
vertex_buffer: *gpu.Buffer, |
|
|
|
|
|
|
|
|
@ -80,33 +83,33 @@ pub fn init(app: *App) !void { |
|
|
|
|
}), |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
// The "model" uniforms contain information about how to render each model. |
|
|
|
|
// The "object" uniforms contain information about how to render each object in a scene. |
|
|
|
|
for (0..3) |i| { |
|
|
|
|
app.model_uniform_buffers[i] = core.device.createBuffer(&.{ |
|
|
|
|
app.object_uniform_buffers[i] = core.device.createBuffer(&.{ |
|
|
|
|
.usage = .{ .copy_dst = true, .uniform = true }, |
|
|
|
|
.size = @sizeOf(ModelUniformBuffer), |
|
|
|
|
.size = @sizeOf(ObjectUniformBuffer), |
|
|
|
|
.mapped_at_creation = .false, |
|
|
|
|
}); |
|
|
|
|
app.model_bind_groups[i] = core.device.createBindGroup( |
|
|
|
|
app.object_bind_groups[i] = core.device.createBindGroup( |
|
|
|
|
&gpu.BindGroup.Descriptor.init(.{ |
|
|
|
|
.layout = app.pipeline.getBindGroupLayout(1), |
|
|
|
|
.entries = &.{ |
|
|
|
|
gpu.BindGroup.Entry.buffer(0, app.model_uniform_buffers[i], 0, @sizeOf(ModelUniformBuffer)), |
|
|
|
|
gpu.BindGroup.Entry.buffer(0, app.object_uniform_buffers[i], 0, @sizeOf(ObjectUniformBuffer)), |
|
|
|
|
}, |
|
|
|
|
}), |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
// Upload model render information (matrix + color) to the GPU. |
|
|
|
|
core.queue.writeBuffer(app.model_uniform_buffers[0], 0, &[_]ModelUniformBuffer{.{ |
|
|
|
|
.matrix = zm.transpose(zm.translation(-1.0, 0.25, 0.0)), |
|
|
|
|
// Upload object information (model matrix + color) to the GPU. |
|
|
|
|
core.queue.writeBuffer(app.object_uniform_buffers[0], 0, &[_]ObjectUniformBuffer{.{ |
|
|
|
|
.model_matrix = zm.transpose(zm.translation(-1.0, 0.25, 0.0)), |
|
|
|
|
.color = .{ 1.0, 0.0, 0.0 }, |
|
|
|
|
}}); |
|
|
|
|
core.queue.writeBuffer(app.model_uniform_buffers[1], 0, &[_]ModelUniformBuffer{.{ |
|
|
|
|
.matrix = zm.transpose(zm.translation(0.0, -0.25, 0.0)), |
|
|
|
|
core.queue.writeBuffer(app.object_uniform_buffers[1], 0, &[_]ObjectUniformBuffer{.{ |
|
|
|
|
.model_matrix = zm.transpose(zm.translation(0.0, -0.25, 0.0)), |
|
|
|
|
.color = .{ 0.0, 1.0, 0.0 }, |
|
|
|
|
}}); |
|
|
|
|
core.queue.writeBuffer(app.model_uniform_buffers[2], 0, &[_]ModelUniformBuffer{.{ |
|
|
|
|
.matrix = zm.transpose(zm.translation(1.0, 0.0, 0.0)), |
|
|
|
|
core.queue.writeBuffer(app.object_uniform_buffers[2], 0, &[_]ObjectUniformBuffer{.{ |
|
|
|
|
.model_matrix = zm.transpose(zm.translation(1.0, 0.0, 0.0)), |
|
|
|
|
.color = .{ 0.0, 0.0, 1.0 }, |
|
|
|
|
}}); |
|
|
|
|
|
|
|
|
@ -133,8 +136,8 @@ pub fn deinit(app: *App) void { |
|
|
|
|
defer app.pipeline.release(); |
|
|
|
|
defer app.scene_uniform_buffer.release(); |
|
|
|
|
defer app.scene_bind_group.release(); |
|
|
|
|
defer for (app.model_uniform_buffers) |b| b.release(); |
|
|
|
|
defer for (app.model_bind_groups) |g| g.release(); |
|
|
|
|
defer for (app.object_uniform_buffers) |b| b.release(); |
|
|
|
|
defer for (app.object_bind_groups) |g| g.release(); |
|
|
|
|
defer app.vertex_buffer.release(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -200,9 +203,9 @@ pub fn update(app: *App) !bool { |
|
|
|
|
pass.setBindGroup(0, app.scene_bind_group, &.{}); |
|
|
|
|
pass.setVertexBuffer(0, app.vertex_buffer, 0, app.vertex_count * @sizeOf(VertexData)); |
|
|
|
|
|
|
|
|
|
for (app.model_bind_groups) |model_bind_group| { |
|
|
|
|
// Set the model bind group for a specific model we want to render. |
|
|
|
|
pass.setBindGroup(1, model_bind_group, &.{}); |
|
|
|
|
for (app.object_bind_groups) |object_bind_group| { |
|
|
|
|
// Set the bind group for an object we want to render. |
|
|
|
|
pass.setBindGroup(1, object_bind_group, &.{}); |
|
|
|
|
// Draw the vertices in `vertex_buffer`. |
|
|
|
|
pass.draw(app.vertex_count, 1, 0, 0); |
|
|
|
|
} |
|
|
|
|