render-zig

A 3D rendering engine written in Zig
git clone git://git.christianermann.dev/render-zig
Log | Files | Refs

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 }