examples: migrate custom-renderer to mach.Core module API

Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
Stephen Gutekanst 2024-04-08 22:57:21 -07:00 committed by Stephen Gutekanst
parent 013546b189
commit 27fd19271c
4 changed files with 32 additions and 24 deletions

View file

@ -636,7 +636,7 @@ fn buildExamples(
.std_platform_only = true, .std_platform_only = true,
}, },
.{ .name = "core-custom-entrypoint", .deps = &.{}, .use_module_api = true }, .{ .name = "core-custom-entrypoint", .deps = &.{}, .use_module_api = true },
.{ .name = "custom-renderer", .deps = &.{} }, .{ .name = "custom-renderer", .deps = &.{}, .use_module_api = true },
.{ .{
.name = "sprite", .name = "sprite",
.deps = &.{ .zigimg, .assets }, .deps = &.{ .zigimg, .assets },

View file

@ -1,6 +1,5 @@
const std = @import("std"); const std = @import("std");
const mach = @import("mach"); const mach = @import("mach");
const core = mach.core;
const math = mach.math; const math = mach.math;
const Renderer = @import("Renderer.zig"); const Renderer = @import("Renderer.zig");
@ -44,16 +43,16 @@ fn init(
// These are injected dependencies - as long as these modules were registered in the top-level // These are injected dependencies - as long as these modules were registered in the top-level
// of the program we can have these types injected here, letting us work with other modules in // of the program we can have these types injected here, letting us work with other modules in
// our program seamlessly and with a type-safe API: // our program seamlessly and with a type-safe API:
engine: *mach.Engine.Mod, core: *mach.Core.Mod,
renderer: *Renderer.Mod, renderer: *Renderer.Mod,
game: *Mod, game: *Mod,
) !void { ) !void {
// The Mach .core is where we set window options, etc. // The Mach .core is where we set window options, etc.
// TODO(important): replace this API with something better // TODO(important): replace this API with something better
core.setTitle("Hello, ECS!"); mach.core.setTitle("Hello, ECS!");
// Create our player entity. // Create our player entity.
const player = try engine.newEntity(); const player = try core.newEntity();
// Give our player entity a .renderer.position and .renderer.scale component. Note that these // Give our player entity a .renderer.position and .renderer.scale component. Note that these
// are defined by the Renderer module, so we use `renderer: *Renderer.Mod` to interact with // are defined by the Renderer module, so we use `renderer: *Renderer.Mod` to interact with
@ -77,12 +76,12 @@ fn init(
// TODO(important): remove need for returning an error here // TODO(important): remove need for returning an error here
fn tick( fn tick(
engine: *mach.Engine.Mod, core: *mach.Core.Mod,
renderer: *Renderer.Mod, renderer: *Renderer.Mod,
game: *Mod, game: *Mod,
) !void { ) !void {
// TODO(important): event polling should occur in mach.Engine module and get fired as ECS event. // TODO(important): event polling should occur in mach.Core module and get fired as ECS event.
var iter = core.pollEvents(); var iter = mach.core.pollEvents();
var direction = game.state().direction; var direction = game.state().direction;
var spawning = game.state().spawning; var spawning = game.state().spawning;
while (iter.next()) |event| { while (iter.next()) |event| {
@ -107,7 +106,7 @@ fn tick(
else => {}, else => {},
} }
}, },
.close => engine.send(.exit, .{}), // Send an event telling the engine to exit the app .close => core.send(.exit, .{}), // Send an event telling mach to exit the app
else => {}, else => {},
} }
} }
@ -129,7 +128,7 @@ fn tick(
_ = game.state().spawn_timer.lap(); // Reset the timer _ = game.state().spawn_timer.lap(); // Reset the timer
for (0..5) |_| { for (0..5) |_| {
// Spawn a new entity at the same position as the player, but smaller in scale. // Spawn a new entity at the same position as the player, but smaller in scale.
const new_entity = try engine.newEntity(); const new_entity = try core.newEntity();
try renderer.set(new_entity, .position, player_pos); try renderer.set(new_entity, .position, player_pos);
try renderer.set(new_entity, .scale, 1.0 / 6.0); try renderer.set(new_entity, .scale, 1.0 / 6.0);
@ -150,7 +149,7 @@ fn tick(
// Query all the entities that have the .follower tag indicating they should follow the player. // Query all the entities that have the .follower tag indicating they should follow the player.
// TODO(important): better querying API // TODO(important): better querying API
var archetypes_iter = engine.entities.query(.{ .all = &.{ var archetypes_iter = core.entities.query(.{ .all = &.{
.{ .game = &.{.follower} }, .{ .game = &.{.follower} },
} }); } });
while (archetypes_iter.next()) |archetype| { while (archetypes_iter.next()) |archetype| {
@ -164,7 +163,7 @@ fn tick(
const close_dist = 1.0 / 15.0; const close_dist = 1.0 / 15.0;
var avoidance = Vec3.splat(0); var avoidance = Vec3.splat(0);
var avoidance_div: f32 = 1.0; var avoidance_div: f32 = 1.0;
var archetypes_iter_2 = engine.entities.query(.{ .all = &.{ var archetypes_iter_2 = core.entities.query(.{ .all = &.{
.{ .game = &.{.follower} }, .{ .game = &.{.follower} },
} }); } });
while (archetypes_iter_2.next()) |archetype_2| { while (archetypes_iter_2.next()) |archetype_2| {

View file

@ -3,7 +3,6 @@
const std = @import("std"); const std = @import("std");
const mach = @import("mach"); const mach = @import("mach");
const core = mach.core;
const gpu = mach.gpu; const gpu = mach.gpu;
const math = mach.math; const math = mach.math;
@ -40,16 +39,16 @@ const UniformBufferObject = extern struct {
}; };
fn init( fn init(
engine: *mach.Engine.Mod, core: *mach.Core.Mod,
renderer: *Mod, renderer: *Mod,
) !void { ) !void {
const device = engine.state().device; const device = core.state().device;
const shader_module = device.createShaderModuleWGSL("shader.wgsl", @embedFile("shader.wgsl")); const shader_module = device.createShaderModuleWGSL("shader.wgsl", @embedFile("shader.wgsl"));
// Fragment state // Fragment state
const blend = gpu.BlendState{}; const blend = gpu.BlendState{};
const color_target = gpu.ColorTargetState{ const color_target = gpu.ColorTargetState{
.format = core.descriptor.format, .format = mach.core.descriptor.format,
.blend = &blend, .blend = &blend,
.write_mask = gpu.ColorWriteMaskFlags.all, .write_mask = gpu.ColorWriteMaskFlags.all,
}; };
@ -114,13 +113,13 @@ fn deinit(
} }
fn tick( fn tick(
engine: *mach.Engine.Mod, core: *mach.Core.Mod,
renderer: *Mod, renderer: *Mod,
) !void { ) !void {
const device = engine.state().device; const device = core.state().device;
// Begin our render pass // Begin our render pass
const back_buffer_view = core.swap_chain.getCurrentTextureView().?; const back_buffer_view = mach.core.swap_chain.getCurrentTextureView().?;
const color_attachment = gpu.RenderPassColorAttachment{ const color_attachment = gpu.RenderPassColorAttachment{
.view = back_buffer_view, .view = back_buffer_view,
.clear_value = std.mem.zeroes(gpu.Color), .clear_value = std.mem.zeroes(gpu.Color),
@ -134,7 +133,7 @@ fn tick(
}); });
// Update uniform buffer // Update uniform buffer
var archetypes_iter = engine.entities.query(.{ .all = &.{ var archetypes_iter = core.entities.query(.{ .all = &.{
.{ .renderer = &.{ .position, .scale } }, .{ .renderer = &.{ .position, .scale } },
} }); } });
var num_entities: usize = 0; var num_entities: usize = 0;
@ -168,6 +167,6 @@ fn tick(
renderer.state().queue.submit(&[_]*gpu.CommandBuffer{command}); renderer.state().queue.submit(&[_]*gpu.CommandBuffer{command});
command.release(); command.release();
core.swap_chain.present(); mach.core.swap_chain.present();
back_buffer_view.release(); back_buffer_view.release();
} }

View file

@ -1,13 +1,23 @@
const mach = @import("mach"); const std = @import("std");
const mach = @import("mach");
const Renderer = @import("Renderer.zig"); const Renderer = @import("Renderer.zig");
const Game = @import("Game.zig"); const Game = @import("Game.zig");
// The global list of Mach modules registered for use in our application. // The global list of Mach modules registered for use in our application.
pub const modules = .{ pub const modules = .{
mach.Engine, mach.Core,
Renderer, Renderer,
Game, Game,
}; };
pub const App = mach.App; pub const GPUInterface = mach.core.wgpu.dawn.Interface;
// TODO: move this to a mach "entrypoint" zig module
pub fn main() !void {
// Initialize mach core
try mach.core.initModule();
// Main loop
while (try mach.core.tick()) {}
}