cubemap.zig (2766B)
1 const std = @import("std"); 2 const gpu = @import("mach_gpu"); 3 const Image = @import("zigimg").Image; 4 const App = @import("main.zig").App; 5 6 view: *gpu.TextureView, 7 sampler: *gpu.Sampler, 8 9 const CubeMap = @This(); 10 11 const CubeMapPaths = struct { 12 pos_x: []const u8, 13 neg_x: []const u8, 14 pos_y: []const u8, 15 neg_y: []const u8, 16 pos_z: []const u8, 17 neg_z: []const u8, 18 }; 19 20 pub fn init(paths: CubeMapPaths, allocator: std.mem.Allocator, app: *App) !CubeMap { 21 var images: [6]Image = undefined; 22 images[0] = try Image.fromFilePath(allocator, paths.pos_x); 23 defer images[0].deinit(); 24 images[1] = try Image.fromFilePath(allocator, paths.neg_x); 25 defer images[1].deinit(); 26 images[2] = try Image.fromFilePath(allocator, paths.pos_y); 27 defer images[2].deinit(); 28 images[3] = try Image.fromFilePath(allocator, paths.neg_y); 29 defer images[3].deinit(); 30 images[4] = try Image.fromFilePath(allocator, paths.pos_z); 31 defer images[4].deinit(); 32 images[5] = try Image.fromFilePath(allocator, paths.neg_z); 33 defer images[5].deinit(); 34 35 const img_size = gpu.Extent3D{ 36 .width = @as(u32, @intCast(images[0].width)), 37 .height = @as(u32, @intCast(images[1].height)), 38 }; 39 40 const tex_size = gpu.Extent3D{ 41 .width = @as(u32, @intCast(images[0].width)), 42 .height = @as(u32, @intCast(images[1].height)), 43 .depth_or_array_layers = 6, 44 }; 45 46 const texture = app.device.createTexture(&.{ 47 .size = tex_size, 48 .format = .rgba8_unorm, 49 .dimension = .dimension_2d, 50 .usage = .{ 51 .texture_binding = true, 52 .copy_dst = true, 53 .render_attachment = false, 54 }, 55 }); 56 57 const data_layout = gpu.Texture.DataLayout{ 58 .bytes_per_row = @as(u32, @intCast(images[0].width * 4)), 59 .rows_per_image = @as(u32, @intCast(images[0].height)), 60 }; 61 62 for (0..6) |i| { 63 const destination = gpu.ImageCopyTexture{ 64 .texture = texture, 65 .origin = gpu.Origin3D{ .x = 0, .y = 0, .z = @as(u32, @intCast(i)) }, 66 }; 67 switch (images[i].pixels) { 68 .rgba32 => |pixels| { 69 app.queue.writeTexture( 70 &destination, 71 &data_layout, 72 &img_size, 73 pixels, 74 ); 75 }, 76 else => @panic("unsupported image color format"), 77 } 78 } 79 80 const view = texture.createView( 81 &gpu.TextureView.Descriptor{ .dimension = .dimension_cube }, 82 ); 83 texture.release(); 84 85 const sampler = app.device.createSampler(&.{ 86 .mag_filter = .linear, 87 .min_filter = .linear, 88 }); 89 90 return .{ 91 .view = view, 92 .sampler = sampler, 93 }; 94 }