//! ---------------------------------------------------- //! ---------------------------------------------------- const vk = @import("vulkan"); const std = @import("std"); const sdl = @import("sdl"); const math = @import("math"); const cmn = @import("common"); const Gfx = @import("gfx"); /// ---------------------------------------------------- /// ---------------------------------------------------- const Camera = struct { projection: math.Mat4x4, view: math.Mat4x4, }; /// ---------------------------------------------------- /// ---------------------------------------------------- const Model = struct { matrix: math.Mat4x4, }; /// ---------------------------------------------------- /// ---------------------------------------------------- pub fn main(init: std.process.Init) !void { // // DATA // var material: cmn.UnlitMaterial = .{ .albedo = .{ 1.0, 0.2, 0.2, 1.0 } }; const camera: Camera = .{ .projection = .perspective(std.math.degreesToRadians(90), 800.0 / 600.0, 0.01, 1000), .view = .lookAt(.new(.{ 1, 1, -2 }), .new(.{ 0, 0, 1 }), .new(.{ 0, 1, 0 })), }; var model: Model = .{ .matrix = math.Mat4x4.translate( 0, 0, 0, ) .mul(math.Quat.fromEuler(.init(0, 0, 0)).toMat4()) .mul(math.Mat4x4.scale( 1, 1, 1, )), }; // // SDL // if (!sdl.SDL_Init(sdl.SDL_INIT_VIDEO)) return error.FailedToInitSDL; defer sdl.SDL_Quit(); const window = sdl.SDL_CreateWindow("NYXGFX", 800, 600, 0) orelse return error.FailedTomakeWindow; defer sdl.SDL_DestroyWindow(window); const props = sdl.SDL_GetWindowProperties(window); const display = sdl.SDL_GetPointerProperty(props, sdl.SDL_PROP_WINDOW_X11_DISPLAY_POINTER, null); const xwindow = sdl.SDL_GetNumberProperty(props, sdl.SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0); // // GFX // var gfx: Gfx = try .init( init.gpa, init.io, ); defer gfx.deinit(); // // CORE // const instance = try gfx.makeInstance(.{ .vulkan = .{ .api_version = .v1_3, .vk_13_features = .{}, }, }); const surface = try gfx.makeSurface(.{ .window = .{ .xlib = .{ .window = @intCast(xwindow), .display = display.?, }, }, .instance = instance, }); const adapter = try gfx.makeAdapter(.{ .instance = instance, }); const device = try gfx.makeDevice(.{ .instance = instance, .adapter = adapter, .surface = surface, }); const swapchain = try gfx.makeSwapchain(.{ .surface = surface, .adapter = adapter, .device = device, }); // // DEBUG // if (gfx.getAdapterInfo(adapter)) |info| { std.debug.print("Name: {s} | Type: {s}\n", .{ info.name, @tagName(info.gpu_type) }); } // // TEXTURES // const texture = try gfx.makeTexture(.{ .image = .{ .path = "examples/assets/textures/texture.jpg" }, .sampler = .{ .min_filter = .linear, .address_u = .repeat }, .adapter = adapter, .device = device, }); // // BUFFERS // const vbuf = try gfx.makeBuffer(cmn.Cube.vertices, .vertex, adapter, device); const ibuf = try gfx.makeBuffer(cmn.Cube.indices, .index, adapter, device); // // SHADERS // const simple_vert = try gfx.makeShader("examples/assets/shaders/compiled/3D.vert.spv", device); const simple_frag = try gfx.makeShader("examples/assets/shaders/compiled/3D.frag.spv", device); // // PIPELINES // const pipeline = try gfx.makePipeline(.{ .vertex_attributes = &.{ .{ .location = 0, .format = .vec3, .offset = @offsetOf(cmn.Vertex, "pos") }, .{ .location = 1, .format = .vec3, .offset = @offsetOf(cmn.Vertex, "normal") }, .{ .location = 2, .format = .vec2, .offset = @offsetOf(cmn.Vertex, "uv") }, }, .vertex_binding = .{ .stride = @sizeOf(cmn.Vertex) }, .uniforms = &.{ .{ .name = "camera", .size = @sizeOf(Camera) }, .{ .name = "model", .size = @sizeOf(Model) }, }, .textures = &.{ texture, }, .depth_format = .d32_sfloat, .vert_shader = simple_vert, .frag_shader = simple_frag, .device = device, .swapchain = swapchain, }); // // MISC // var event: sdl.SDL_Event = undefined; var running: bool = true; var i: f32 = 0; while (running) { // // INPUTS // while (sdl.SDL_PollEvent(&event)) { switch (event.type) { sdl.SDL_EVENT_QUIT => running = false, else => {}, } } i += 0.001; i = @mod(i, 1); material.albedo[1] = i; try pipeline.setUniform("camera", Camera{ .projection = camera.projection.transpose(), .view = camera.view.transpose(), }); // // FRAME // try gfx.beginFrame(swapchain, device); defer gfx.endFrame(swapchain, device) catch unreachable; // // PASS // if (gfx.beginPass(swapchain, .{ .clear_color = .{ 0.01, 0.01, 0.01, 1.0 }, .depth_enabled = true, })) |pass| { defer pass.end(); for (0..4) |x| { model = .{ .matrix = math.Mat4x4.translate( 0, 0, @floatFromInt(x), ) .mul(math.Quat.fromEuler(.init( @as(f32, @floatFromInt(x)) * 0.1, @as(f32, @floatFromInt(x)) * 0.15, @as(f32, @floatFromInt(x)) * 0.13, )).toMat4()) .mul(math.Mat4x4.scale( 1, 1, 1, )), }; try pipeline.bind(); try vbuf.bind(); try ibuf.bind(); try pipeline.setUniform("model", Model{ .matrix = model.matrix.transpose(), }); pass.drawIndexed(cmn.Cube.indices.len, 1, 0, 0, 0); } } if (gfx.beginPass(swapchain, .{ .load_op = .load, })) |pass| { defer pass.end(); } } }