commit a51c3d95e2075ca372cc57e66951f0445156eb13
parent 90673dac563c9dd955aa7c15b186d7fb028c8735
Author: Christian Ermann <christianermann@gmail.com>
Date: Sat, 27 Apr 2024 21:56:23 -0400
Render triangle using buffers
Diffstat:
M | src/main.zig | | | 113 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- |
1 file changed, 112 insertions(+), 1 deletion(-)
diff --git a/src/main.zig b/src/main.zig
@@ -327,6 +327,117 @@ const DefaultRenderPipeline = struct {
}
};
+const f32x3 = @Vector(3, f32);
+
+const UnlitRenderPipeline = struct {
+ gpu_pipeline: *gpu.RenderPipeline,
+ vtx_buffer: *gpu.Buffer,
+ idx_buffer: *gpu.Buffer,
+
+ pub fn init(app: *App) UnlitRenderPipeline {
+ const triangle_vtx = [3]f32x3{ .{ 0.0, 0.5, 0.0 }, .{ -0.5, -0.5, 0.0 }, .{ 0.5, -0.5, 0.0 } };
+ const vtx_buffer_descriptor = gpu.Buffer.Descriptor{
+ .size = 3 * @sizeOf(f32x3),
+ .usage = .{ .vertex = true, .copy_dst = true },
+ .mapped_at_creation = .false,
+ };
+ const vtx_buffer = app.device.createBuffer(&vtx_buffer_descriptor);
+ app.queue.writeBuffer(vtx_buffer, 0, &triangle_vtx);
+
+ const vtx_attributes = [_]gpu.VertexAttribute{
+ .{ .format = .float32x3, .shader_location = 0, .offset = 0 },
+ };
+ const vtx_buffer_layout = gpu.VertexBufferLayout.init(.{
+ .array_stride = @sizeOf(f32x3),
+ .step_mode = .vertex,
+ .attributes = &vtx_attributes,
+ });
+
+ const triangle_idx = [3]u32{ 0, 1, 2 };
+ const idx_buffer_descriptor = gpu.Buffer.Descriptor{
+ .size = 3 * @sizeOf(u32),
+ .usage = .{ .index = true, .copy_dst = true },
+ .mapped_at_creation = .false,
+ };
+ const idx_buffer = app.device.createBuffer(&idx_buffer_descriptor);
+ app.queue.writeBuffer(idx_buffer, 0, &triangle_idx);
+
+ const vs =
+ \\ struct VertexInput {
+ \\ @location(0) position: vec3<f32>,
+ \\ };
+ \\
+ \\ @vertex fn main(in: VertexInput) -> @builtin(position) vec4<f32> {
+ \\ return vec4<f32>(in.position, 1.0);
+ \\ }
+ ;
+ const vs_module = app.device.createShaderModuleWGSL("default vertex shader", vs);
+ defer vs_module.release();
+
+ const vertex = gpu.VertexState.init(.{
+ .module = vs_module,
+ .entry_point = "main",
+ .buffers = &.{vtx_buffer_layout},
+ });
+
+ const fs =
+ \\ @fragment fn main() -> @location(0) vec4<f32> {
+ \\ return vec4<f32>(1.0, 0.0, 0.0, 1.0);
+ \\ }
+ ;
+ const fs_module = app.device.createShaderModuleWGSL("default fragment shader", fs);
+ defer fs_module.release();
+
+ const blend: gpu.BlendState = .{};
+ const color_target = gpu.ColorTargetState{
+ .format = app.swap_chain.format,
+ .blend = &blend,
+ .write_mask = gpu.ColorWriteMaskFlags.all,
+ };
+ const fragment = gpu.FragmentState.init(.{
+ .module = fs_module,
+ .entry_point = "main",
+ .targets = &.{color_target},
+ });
+
+ const pipeline_descriptor = gpu.RenderPipeline.Descriptor{
+ .label = "default render pipeline",
+ .fragment = &fragment,
+ .layout = null,
+ .depth_stencil = null,
+ .vertex = vertex,
+ .multisample = .{},
+ .primitive = .{
+ .topology = .triangle_list,
+ .front_face = .ccw,
+ .cull_mode = .back,
+ },
+ };
+
+ return .{
+ .gpu_pipeline = app.device.createRenderPipeline(&pipeline_descriptor),
+ .vtx_buffer = vtx_buffer,
+ .idx_buffer = idx_buffer,
+ };
+ }
+
+ pub fn frame(ptr: *anyopaque, pass: *gpu.RenderPassEncoder) void {
+ const self: *UnlitRenderPipeline = @ptrCast(@alignCast(ptr));
+ pass.setPipeline(self.gpu_pipeline);
+
+ pass.setVertexBuffer(0, self.vtx_buffer, 0, @sizeOf(f32x3) * 3);
+ pass.setIndexBuffer(self.idx_buffer, .uint32, 0, @sizeOf(u32) * 3);
+ pass.drawIndexed(3, 1, 0, 0, 0);
+ }
+
+ pub fn pipeline(self: *UnlitRenderPipeline) RenderPipeline {
+ return .{
+ .ptr = self,
+ .frameFn = frame,
+ };
+ }
+};
+
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
@@ -335,7 +446,7 @@ pub fn main() !void {
try app.init(allocator);
defer app.deinit();
- var drp = DefaultRenderPipeline.init(&app);
+ var drp = UnlitRenderPipeline.init(&app);
const pipelines = [_]RenderPipeline{drp.pipeline()};