diff --git a/src/main.zig b/src/main.zig index 697e3ac..48c419b 100644 --- a/src/main.zig +++ b/src/main.zig @@ -47,7 +47,7 @@ depth_texture_view: *gpu.TextureView, pipeline: *gpu.RenderPipeline, scene_uniform_buffer: *gpu.Buffer, scene_uniform_bind_group: *gpu.BindGroup, -primitive_data: [2]PrimitiveData, +primitive_data: []PrimitiveData, object_data: []ObjectData, pub fn init(app: *App) !void { @@ -128,10 +128,15 @@ pub fn init(app: *App) !void { } // Set up the primitives we want to render. - app.primitive_data = .{ - primitives.createTrianglePrimitive(1.0), - primitives.createSquarePrimitive(1.0), - }; + // Using `dupe` to allocate a slice here allows easily adjusting the + // primitives to use, without changing the type of `primitive_data`. + app.primitive_data = try app.allocator.dupe(PrimitiveData, &.{ + // primitives.createTrianglePrimitive(1.0), + // primitives.createSquarePrimitive(0.8), + // primitives.createCirclePrimitive(0.5, 24), + primitives.createCubePrimitive(0.65), + primitives.createPyramidPrimitive(0.75), + }); // Set up object related uniform buffers and bind groups. // This uploads data to the GPU about all the object we @@ -239,6 +244,7 @@ pub fn deinit(app: *App) void { defer app.pipeline.release(); defer app.scene_uniform_buffer.release(); defer app.scene_uniform_bind_group.release(); + defer app.allocator.free(app.primitive_data); defer for (app.primitive_data) |p| { p.vertex_buffer.release(); p.index_buffer.release(); diff --git a/src/primitives.zig b/src/primitives.zig index dd909c3..d17e434 100644 --- a/src/primitives.zig +++ b/src/primitives.zig @@ -100,3 +100,110 @@ pub fn createSquarePrimitive(width: f32) PrimitiveData { }, ); } + +pub fn createCirclePrimitive(radius: f32, comptime sides: usize) PrimitiveData { + if (sides < 3) @compileError("sides must be at least 3"); + + var vertices: [sides]VertexData = undefined; + for (&vertices, 0..) |*vertex, i| { + const angle = std.math.tau / @as(f32, @floatFromInt(sides)) * @as(f32, @floatFromInt(i)); + vertex.* = vert(@sin(angle) * radius, @cos(angle) * radius, 0.0); + } + + var indices: [(sides - 2) * 3]u32 = undefined; + for (0..(sides - 2)) |i| { + indices[i * 3 + 0] = 0; + indices[i * 3 + 1] = @as(u32, @intCast(i)) + 1; + indices[i * 3 + 2] = @as(u32, @intCast(i)) + 2; + } + + return createPrimitive(&vertices, &indices); +} + +pub fn createCubePrimitive(width: f32) PrimitiveData { + const half_width = width / 2.0; + return createPrimitive( + // zig fmt: off + &.{ + // Right (+X) + vert( half_width, half_width, -half_width), + vert( half_width, -half_width, -half_width), + vert( half_width, half_width, half_width), + vert( half_width, -half_width, half_width), + // Left (-X) + vert(-half_width, half_width, half_width), + vert(-half_width, -half_width, half_width), + vert(-half_width, half_width, -half_width), + vert(-half_width, -half_width, -half_width), + // Top (+Y) + vert( half_width, half_width, -half_width), + vert( half_width, half_width, half_width), + vert(-half_width, half_width, -half_width), + vert(-half_width, half_width, half_width), + // Bottom (-Y) + vert(-half_width, -half_width, -half_width), + vert(-half_width, -half_width, half_width), + vert( half_width, -half_width, -half_width), + vert( half_width, -half_width, half_width), + // Front (+Z) + vert( half_width, half_width, half_width), + vert( half_width, -half_width, half_width), + vert(-half_width, half_width, half_width), + vert(-half_width, -half_width, half_width), + // Back (-Z) + vert(-half_width, half_width, -half_width), + vert(-half_width, -half_width, -half_width), + vert( half_width, half_width, -half_width), + vert( half_width, -half_width, -half_width), + }, + &.{ + 0, 1, 2, 3, 2, 1, // Right + 4, 5, 6, 7, 6, 5, // Left + 8, 9, 10, 11, 10, 9, // Top + 12, 13, 14, 15, 14, 13, // Bottom + 16, 17, 18, 19, 18, 17, // Front + 20, 21, 22, 23, 22, 21, // Back + }, + // zig fmt: on + ); +} + +pub fn createPyramidPrimitive(width: f32) PrimitiveData { + const half_width = width / 2.0; + return createPrimitive( + // zig fmt: off + &.{ + // Right + vert( 0.0, half_width, 0.0), + vert( half_width, -half_width, -half_width), + vert( half_width, -half_width, half_width), + // Left + vert( 0.0, half_width, 0.0), + vert(-half_width, -half_width, half_width), + vert(-half_width, -half_width, -half_width), + // Front + vert( 0.0, half_width, 0.0), + vert( half_width, -half_width, half_width), + vert(-half_width, -half_width, half_width), + // Back + vert( 0.0, half_width, 0.0), + vert(-half_width, -half_width, -half_width), + vert( half_width, -half_width, -half_width), + // Bottom + vert(-half_width, -half_width, -half_width), + vert(-half_width, -half_width, half_width), + vert( half_width, -half_width, -half_width), + vert( half_width, -half_width, half_width), + }, + &.{ + 0, 1, 2, // Right + 3, 4, 5, // Left + 6, 7, 8, // Front + 9, 10, 11, // Back + // Bottom + 12, 13, 14, + 15, 14, 13, + }, + // zig fmt: on + ); +}