const gfx = @import("gfx"); const ona = @import("ona"); const std = @import("std"); const CRT = extern struct { width: f32, height: f32, time: f32, padding: [4]u8 = undefined, }; const Effects = struct { render_texture: gfx.Texture = .default, image_textures: [2]gfx.Texture = [_]gfx.Texture{.default} ** 2, last_time: f64 = 0, image_index: usize = 0, crt_effect: gfx.Effect = .default, }; fn load(display: ona.Write(gfx.Display), effects: ona.Write(Effects), assets: ona.Write(gfx.Assets)) !void { display.state.width, display.state.height = .{1280, 720}; effects.state.render_texture = try assets.state.load_texture(.{ .format = .rgba8, .access = .{ .render = .{ .width = display.state.width, .height = display.state.height, }, }, }); effects.state.crt_effect = try assets.state.load_effect_file(ona.files.bundle, "./crt.frag.spv"); var descs = gfx.Descs.init(ona.heap.allocator); defer { descs.deinit(); } effects.state.image_textures = .{ try assets.state.load_texture(try descs.checker_texture(.{ .colors = .{gfx.colors.black, gfx.colors.purple}, .width = 8, .height = 8, })), try assets.state.load_texture(try descs.checker_texture(.{ .colors = .{gfx.colors.black, gfx.colors.grey}, .width = 8, .height = 8, })) }; } pub const main = ona.App.game .with_module(gfx) .with_state(Effects{}) .with_system(.load, ona.system_fn(load), .{.label = "load effects"}) .with_system(.update, ona.system_fn(update), .{.label = "update effects"}) .with_system(.render, ona.system_fn(render), .{.label = "render effects"}).build(); fn update(effects: ona.Write(Effects), loop: ona.Read(ona.Loop)) void { const update_seconds = 5; if ((loop.state.elapsed_time - effects.state.last_time) > update_seconds) { effects.state.image_index = (effects.state.image_index + 1) % effects.state.image_textures.len; effects.state.last_time = loop.state.elapsed_time; } } fn render(commands: gfx.Commands(.background), effects: ona.Write(Effects), loop: ona.Read(ona.Loop), display: ona.Write(gfx.Display)) !void { try commands.set_target(.{ .texture = effects.state.render_texture, .clear_color = gfx.colors.black, .clear_depth = 0, .clear_stencil = 0, }); const width: f32 = @floatFromInt(display.state.width); const height: f32 = @floatFromInt(display.state.height); try commands.draw_texture(.{ .texture = effects.state.image_textures[effects.state.image_index], .size = .{width, height}, }); try commands.set_effect(.{ .effect = effects.state.crt_effect, .properties = std.mem.asBytes(&CRT{ .width = width, .height = height, .time = @floatCast(loop.state.elapsed_time), }), }); try commands.set_target(.{ .clear_color = null, .clear_depth = null, .clear_stencil = null, }); try commands.draw_texture(.{ .texture = effects.state.render_texture, .size = .{width, height}, }); }