From 0eb9a4482886bb2a8a04469d1f266bd3dfcff9c1 Mon Sep 17 00:00:00 2001 From: abux Date: Wed, 29 Jul 2026 21:36:00 +0100 Subject: [PATCH] Added some retarded stuff | Clean it up and fix it | Yes --- src/main.zig | 4 + .../cache/resource/embeded/shaders/pbr.wgsl | 22 +++++ src/plugins/cache/resource/pipeline_cache.zig | 71 ++++++++++++-- src/plugins/cache/system/lifetime.zig | 4 +- src/plugins/common/component/material.zig | 2 + src/plugins/lua/root.zig | 97 +++++++++++++++++++ src/plugins/playground/root.zig | 53 ++++++++++ src/plugins/renderer/resource/renderer.zig | 34 ++++++- src/plugins/renderer/system/frame.zig | 78 ++++++++------- src/plugins/renderer/system/lifetime.zig | 17 +++- src/plugins/renderer/system/present.zig | 7 ++ src/scripts/main.lua | 38 ++++++++ 12 files changed, 377 insertions(+), 50 deletions(-) create mode 100644 src/plugins/lua/root.zig create mode 100644 src/plugins/playground/root.zig create mode 100644 src/scripts/main.lua diff --git a/src/main.zig b/src/main.zig index 624543d..69d2de5 100644 --- a/src/main.zig +++ b/src/main.zig @@ -13,6 +13,8 @@ const App = @import("app"); // const template = @import("plugins/template/root.zig"); +const playground = @import("plugins/playground/root.zig"); +const lua = @import("plugins/lua/root.zig"); const common = @import("plugins/common/root.zig"); const platform = @import("plugins/platform/root.zig"); const device = @import("plugins/device/root.zig"); @@ -30,12 +32,14 @@ pub fn main(init: std.process.Init) !void { // --- ADD PLUGINS --- try app.plugins.addMany(&.{ + lua.plugin, platform.plugin, device.plugin, window.plugin, cache.plugin, input.plugin, renderer.plugin, + playground.plugin, }); try app.plugins.build(&app); diff --git a/src/plugins/cache/resource/embeded/shaders/pbr.wgsl b/src/plugins/cache/resource/embeded/shaders/pbr.wgsl index 6930462..ea3d26c 100644 --- a/src/plugins/cache/resource/embeded/shaders/pbr.wgsl +++ b/src/plugins/cache/resource/embeded/shaders/pbr.wgsl @@ -23,11 +23,33 @@ struct Material { _pad0: vec2f, }; +// ---------------------------------------------------- +// ---------------------------------------------------- +struct CameraUniform { + view: mat4x4, + projection: mat4x4, + view_projection: mat4x4, + camera_position: vec3, + _pad: f32, +}; + +// ---------------------------------------------------- +// ---------------------------------------------------- +struct ModelUniform { + model: mat4x4, +}; + // // UNIFORMS // +@group(0) @binding(0) +var camera: CameraUniform; + @group(1) @binding(0) +var model: ModelUniform; + +@group(2) @binding(0) var material: Material; // diff --git a/src/plugins/cache/resource/pipeline_cache.zig b/src/plugins/cache/resource/pipeline_cache.zig index 5e274a6..bc2714f 100644 --- a/src/plugins/cache/resource/pipeline_cache.zig +++ b/src/plugins/cache/resource/pipeline_cache.zig @@ -8,17 +8,19 @@ const Self = @This(); const Material = @import("../../common/component/material.zig"); const ShaderCache = @import("shader_cache.zig"); +const ShaderID = ShaderCache.ShaderID; const Vertex = @import("mesh_cache.zig").Vertex; /// ---------------------------------------------------- /// ---------------------------------------------------- pub const GPUPipeline = struct { raw: *wgpu.WGPURenderPipelineImpl, + layout: *wgpu.WGPUPipelineLayoutImpl, }; /// ---------------------------------------------------- /// ---------------------------------------------------- -pub const GPUMaterial = struct { // TODO: Should prob create Material Cache instead +pub const GPUMaterial = struct { buffer: *wgpu.WGPUBufferImpl, bind_group: *wgpu.WGPUBindGroupImpl, }; @@ -28,7 +30,8 @@ pub const GPUMaterial = struct { // TODO: Should prob create Material Cache inst // pipelines: gtl.KeyedSlotMap(Material.Unique, GPUPipeline), -materials: gtl.SlotMap(GPUMaterial), +materials: gtl.SlotMap(Material), +materials_gpu: gtl.KeyedSlotMap(gtl.Handle(Material), GPUMaterial), shader_cache: *ShaderCache, queue: *wgpu.WGPUQueueImpl, device: *wgpu.WGPUDeviceImpl, @@ -45,6 +48,7 @@ pub fn init( return .{ .pipelines = .init(alloc), .materials = .init(alloc), + .materials_gpu = .init(alloc), .shader_cache = shader_cache, .queue = queue, .device = device, @@ -57,28 +61,76 @@ pub fn init( pub fn deinit(self: *Self) void { // --- FREE PIPELINES --- for (self.pipelines.items()) |entry| { + // wgpu.wgpuPipelineLayoutRelease(entry.value.layout); wgpu.wgpuRenderPipelineRelease(entry.value.raw); } // --- FREE MATERIALS --- - for (self.materials.items()) |gpu| { - wgpu.wgpuBufferRelease(gpu.buffer); - wgpu.wgpuBindGroupRelease(gpu.bind_group); + for (self.materials_gpu.items()) |entry| { + wgpu.wgpuBufferRelease(entry.value.buffer); + wgpu.wgpuBindGroupRelease(entry.value.bind_group); } // --- # --- self.pipelines.deinit(); self.materials.deinit(); + self.materials_gpu.deinit(); +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub fn getOrCreateMaterial( + self: *Self, + material: Material, +) !*GPUMaterial { + return try self.materials.getOrPut( + material.unique.shader, + blk: { + // --- UNIFORM --- + const uniform = wgpu.wgpuDeviceCreateBuffer(self.device, &wgpu.WGPUBufferDescriptor{ + .usage = wgpu.WGPUBufferUsage_CopyDst | wgpu.WGPUBufferUsage_Uniform, + .size = @sizeOf(Material.Style), + }) orelse return error.Buffer; + + wgpu.wgpuQueueWriteBuffer( + self.queue, + uniform, + 0, + &material.style, + @sizeOf(Material.Style), + ); + + // --- RESULT --- + break :blk .{ + .bind_group = undefined, + .buffer = uniform, + }; + }, + ); } /// ---------------------------------------------------- /// ---------------------------------------------------- pub fn getOrCreate( self: *Self, - key: Material.Unique, + key: Material, ) !*GPUPipeline { - return try self.pipelines.getOrPut(key, .{ - .raw = try self.createPipeline(key), + return try self.pipelines.getOrPut(key.unique, blk: { + // const layout = wgpu.wgpuDeviceCreatePipelineLayout( + // self.device, + // &wgpu.WGPUPipelineLayoutDescriptor{ + // .bindGroupLayoutCount = 1, + // .bindGroupLayouts = &wgpu.WGPUBindGroupLayoutDescriptor{ + // .entryCount = 1, + // }, + // }, + // ) orelse return error.Layout; + + // --- RESULT --- + break :blk .{ + .raw = try self.createPipeline(key.unique, undefined), + .layout = undefined, + }; }); } @@ -87,7 +139,10 @@ pub fn getOrCreate( fn createPipeline( self: *Self, key: Material.Unique, + layout: *wgpu.WGPUPipelineLayoutImpl, ) !*wgpu.WGPURenderPipelineImpl { + _ = layout; + // --- ENSURE SHADER MODULE --- const shader_module = try self.shader_cache.getOrCreate( key.shader, diff --git a/src/plugins/cache/system/lifetime.zig b/src/plugins/cache/system/lifetime.zig index 213009c..904b0e8 100644 --- a/src/plugins/cache/system/lifetime.zig +++ b/src/plugins/cache/system/lifetime.zig @@ -46,8 +46,8 @@ pub fn init(app: *App) !void { _ = try pipelines.getOrCreate(.{}); _ = try pipelines.getOrCreate(.{}); - _ = try pipelines.getOrCreate(.{ .shader = .unlit }); - _ = try pipelines.getOrCreate(.{ .shader = .unlit }); + _ = try pipelines.getOrCreate(.{ .unique = .{ .shader = .unlit } }); + _ = try pipelines.getOrCreate(.{ .unique = .{ .shader = .unlit } }); { // DEBUG std.debug.print("{s}┏━{s} PIPELINES\n", .{ gtl.ansi.blue, gtl.ansi.reset }); diff --git a/src/plugins/common/component/material.zig b/src/plugins/common/component/material.zig index 20521e7..d64534b 100644 --- a/src/plugins/common/component/material.zig +++ b/src/plugins/common/component/material.zig @@ -4,6 +4,7 @@ const gtl = @import("gtl"); const ShaderID = @import("../../cache/resource/shader_cache.zig").ShaderID; const Handle = gtl.Handle; +const Self = @This(); /// ---------------------------------------------------- /// ---------------------------------------------------- @@ -50,3 +51,4 @@ pub const Unique = struct { style: Style = .{}, unique: Unique = .{}, +value: ?Handle(Self) = null, diff --git a/src/plugins/lua/root.zig b/src/plugins/lua/root.zig new file mode 100644 index 0000000..d6a0acb --- /dev/null +++ b/src/plugins/lua/root.zig @@ -0,0 +1,97 @@ +//! ---------------------------------------------------- +//! ---------------------------------------------------- + +// +// PRIVATE +// + +const App = @import("app"); +const Zla = @import("zla"); + +// +// PUBLIC +// + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub const plugin: App.plugin.Plugin = .{ + .name = "LUA", + .build = build, +}; + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub fn build( + _: *App.plugin.Plugin, + app: *App, +) !void { + // --- LIFETIME --- + try app.schedules.addMany(App.stage.init, &.{init}); + try app.schedules.addMany(App.stage.deinit, &.{ deinit, lua_deinit }); + + // --- EXEC --- + try app.schedules.addManyAfter(App.stage.init, App.stage.init, &.{lua_init}); + + // --- FRAME --- + try app.schedules.add(App.stage.inputs, lua_inputs); + try app.schedules.add(App.stage.update, lua_update); + try app.schedules.add(App.stage.draw, lua_draw); +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +fn init(app: *App) !void { + // --- ZLA --- + _ = try app.resources.getOrSet( + try Zla.init(app.alloc), + ); +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +fn deinit(app: *App) !void { + // --- # --- + const res = try app.resources.getMany(struct { + zla: *Zla, + }); + + // --- # --- + res.zla.deinit(); +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +fn lua_init(app: *App) !void { + const res = try app.resources.getMany(struct { zla: *Zla }); + + try res.zla.execFromFile(void, "src/scripts/main.lua"); + try res.zla.call(void, "init", .{}); +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +fn lua_deinit(app: *App) !void { + const res = try app.resources.getMany(struct { zla: *Zla }); + try res.zla.call(void, "deinit", .{}); +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +fn lua_inputs(app: *App) !void { + const res = try app.resources.getMany(struct { zla: *Zla }); + try res.zla.call(void, "inputs", .{}); +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +fn lua_update(app: *App) !void { + const res = try app.resources.getMany(struct { zla: *Zla }); + try res.zla.call(void, "update", .{}); +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +fn lua_draw(app: *App) !void { + const res = try app.resources.getMany(struct { zla: *Zla }); + try res.zla.call(void, "draw", .{}); +} diff --git a/src/plugins/playground/root.zig b/src/plugins/playground/root.zig new file mode 100644 index 0000000..e3c629a --- /dev/null +++ b/src/plugins/playground/root.zig @@ -0,0 +1,53 @@ +//! ---------------------------------------------------- +//! ---------------------------------------------------- + +// +// PRIVATE +// + +const App = @import("app"); +const Mesh = @import("../common/component/mesh.zig"); +const Material = @import("../common/component/material.zig"); +const Transform3D = @import("../common/component/transform3D.zig"); + +const PipelineCache = @import("../cache/resource/pipeline_cache.zig"); + +// +// PUBLIC +// + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub const plugin: App.plugin.Plugin = .{ + .name = "Playground", + .build = build, +}; + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +fn build( + _: *App.plugin.Plugin, + app: *App, +) !void { + try app.schedules.add(App.stage.init, start); +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +fn start(app: *App) !void { + // --- # --- + const pipeline_cache = app.resources.getPtr( + PipelineCache, + ) orelse return error.PipelineCacheNotSet; + + // --- # --- + try app.world.spawn(.{ + Mesh{ .value = .square }, + Material{ + .style = .{}, + .unique = .{}, + .value = try pipeline_cache.materials.put(.{}), + }, + Transform3D{}, + }); +} diff --git a/src/plugins/renderer/resource/renderer.zig b/src/plugins/renderer/resource/renderer.zig index efc4141..f30cea3 100644 --- a/src/plugins/renderer/resource/renderer.zig +++ b/src/plugins/renderer/resource/renderer.zig @@ -16,12 +16,12 @@ const Camera = struct {}; pub const DrawCMD = union(enum) { draw: struct { mesh: Mesh, - material: Material.Unique, + material: Material, }, draw_indexed: struct { mesh: Mesh, - material: Material.Unique, + material: Material, }, begin_pass: struct { @@ -79,3 +79,33 @@ pub fn draw( cmd, ); } + +// +// TESTING +// + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub fn beginPass(self: *Self) void { + self.draw(.{ .begin_pass = .{ + .camera = undefined, + } }) catch unreachable; +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub fn endPass(self: *Self) void { + self.draw(.end_pass) catch unreachable; +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub fn drawTriangle(self: *Self) void { + self.draw(.{ .draw = .{ .material = .{}, .mesh = .triangle } }) catch unreachable; +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub fn drawSquare(self: *Self) void { + self.draw(.{ .draw = .{ .material = .{}, .mesh = .square } }) catch unreachable; +} diff --git a/src/plugins/renderer/system/frame.zig b/src/plugins/renderer/system/frame.zig index c83e7c3..265c82f 100644 --- a/src/plugins/renderer/system/frame.zig +++ b/src/plugins/renderer/system/frame.zig @@ -15,43 +15,47 @@ pub fn begin(app: *App) !void { // --- # --- res.renderer.clear(); - { // TEST - // --- DRAW --- - try res.renderer.draw(.{ - .begin_pass = .{ - .camera = undefined, - .color = .{ 0.001, 0.001, 0.001, 1.0 }, - }, - }); - defer res.renderer.draw(.end_pass) catch unreachable; - - // --- # --- - try res.renderer.draw(.{ - .draw = .{ - .mesh = .square, - .material = .{}, - }, - }); - } - - { // TEST - // --- DRAW --- - try res.renderer.draw(.{ - .begin_pass = .{ - .camera = undefined, - .load_op = .load, - }, - }); - defer res.renderer.draw(.end_pass) catch unreachable; - - // --- # --- - try res.renderer.draw(.{ - .draw = .{ - .mesh = .triangle, - .material = .{}, - }, - }); - } + // { // TEST + // // --- DRAW --- + // try res.renderer.draw(.{ + // .begin_pass = .{ + // .camera = undefined, + // .color = .{ 0.001, 0.001, 0.001, 1.0 }, + // }, + // }); + // defer res.renderer.draw(.end_pass) catch unreachable; + // + // // --- # --- + // try res.renderer.draw(.{ + // .draw = .{ + // .mesh = .square, + // .material = .{ + // .style = .{ + // .albedo = .{ 0.2, 0.8, 0.2, 1.0 }, + // }, + // }, + // }, + // }); + // } + // + // { // TEST + // // --- DRAW --- + // try res.renderer.draw(.{ + // .begin_pass = .{ + // .camera = undefined, + // .load_op = .load, + // }, + // }); + // defer res.renderer.draw(.end_pass) catch unreachable; + // + // // --- # --- + // try res.renderer.draw(.{ + // .draw = .{ + // .mesh = .triangle, + // .material = .{}, + // }, + // }); + // } } /// ---------------------------------------------------- diff --git a/src/plugins/renderer/system/lifetime.zig b/src/plugins/renderer/system/lifetime.zig index 5081136..2b07b18 100644 --- a/src/plugins/renderer/system/lifetime.zig +++ b/src/plugins/renderer/system/lifetime.zig @@ -2,14 +2,29 @@ //! ---------------------------------------------------- const App = @import("app"); +const Zla = @import("zla"); const Renderer = @import("../resource/renderer.zig"); /// ---------------------------------------------------- /// ---------------------------------------------------- pub fn init(app: *App) !void { - try app.resources.set(Renderer.init( + // --- # --- + const zla = app.resources.getPtr(Zla) orelse return error.ZlaNotSet; + + // --- # --- + const renderer = try app.resources.getOrSet(Renderer.init( app.alloc, )); + + // --- REGISTER --- + zla.registerMethods(Renderer, &.{ + .{ .name = "beginPass", .func = Renderer.beginPass }, + .{ .name = "endPass", .func = Renderer.endPass }, + .{ .name = "drawTriangle", .func = Renderer.drawTriangle }, + .{ .name = "drawSquare", .func = Renderer.drawSquare }, + }); + zla.pushUserdata(renderer); + zla.setGlobal("ren"); } /// ---------------------------------------------------- diff --git a/src/plugins/renderer/system/present.zig b/src/plugins/renderer/system/present.zig index 8cd8e53..150199e 100644 --- a/src/plugins/renderer/system/present.zig +++ b/src/plugins/renderer/system/present.zig @@ -24,6 +24,10 @@ pub fn draw(app: *App) !void { mesh_cache: *MeshCache, }); + { // TODO: Move this | Gather Materials + + } + // --- DO NONE ON WINDOW RESIZE --- if (app.events.consume(Resized)) |_| { return; @@ -118,8 +122,11 @@ pub fn draw(app: *App) !void { .draw => |v| { // --- ENSURE --- const pipeline = try res.pipeline_cache.getOrCreate(v.material); + // const material = try res.pipeline_cache.getOrCreateMaterial(v.material); const mesh = try res.mesh_cache.getOrCreate(v.mesh); + // _ = material; + // --- BIND --- wgpu.wgpuRenderPassEncoderSetPipeline(render_pass, pipeline.raw); wgpu.wgpuRenderPassEncoderSetVertexBuffer(render_pass, 0, mesh.vbuf, 0, wgpu.wgpuBufferGetSize(mesh.vbuf)); diff --git a/src/scripts/main.lua b/src/scripts/main.lua new file mode 100644 index 0000000..6fdbef9 --- /dev/null +++ b/src/scripts/main.lua @@ -0,0 +1,38 @@ +---@diagnostic disable: lowercase-global + +------------------------------------------------------- +------------------------------------------------------- +function init() + print("\x1b[32m[LUA]\x1b[0m init") + + -- world:spawn { + -- Player {} + -- Transform {} + -- } +end + +------------------------------------------------------- +------------------------------------------------------- +function deinit() + print("\x1b[32m[LUA]\x1b[0m deinit") +end + +------------------------------------------------------- +------------------------------------------------------- +function inputs() + -- print("\x1b[32m[LUA]\x1b[0m inputs") +end + +------------------------------------------------------- +------------------------------------------------------- +function update() +end + +------------------------------------------------------- +------------------------------------------------------- +function draw() + ren:beginPass() + ren:drawSquare() + ren:drawTriangle() + ren:endPass() +end