From ff101925ffe2d4b6fbb929f64875b3043c22bfb5 Mon Sep 17 00:00:00 2001 From: Peter Li Date: Fri, 18 Apr 2025 19:54:59 -0700 Subject: [PATCH] saving before stash --- engine/core/src/inputs/inputStack.zig | 6 + engine/platform/src/windowing.zig | 2 + engine/rend/build.zig | 1 + engine/rend/shaders/lit_mesh.frag.hlsl | 5 + engine/rend/shaders/lit_mesh.frag.json | 22 +++ engine/rend/shaders/meshes.vert.hlsl | 5 +- engine/rend/shaders/meshes.vert.json | 4 +- engine/rend/src/camera/CameraComponent.zig | 96 ++++++++++++ engine/rend/src/camera/camera.zig | 5 + engine/rend/src/meshes/MeshComponent.zig | 34 +++- engine/rend/src/rend.zig | 12 ++ engine/rend/src/sgpu/mesh-pool.zig | 1 + engine/rend/src/sgpu/renderer.zig | 148 +++++++++++++++--- lib/sdl3/build.zig | 6 + lib/sdl3/shaderTypes/shaderTypes.zig | 16 +- lib/sdl3/spvreflect/spvreflect.py | 32 ++-- lib/sdl3/src/sdl3.zig | 1 + lib/tracy/build.zig | 2 +- .../content/_shaders/dxil/lit_mesh.frag.dxil | Bin 0 -> 2808 bytes .../content/_shaders/dxil/meshes.vert.dxil | Bin 5216 -> 5216 bytes .../content/_shaders/msl/lit_mesh.frag.msl | 22 +++ projects/content/_shaders/msl/meshes.vert.msl | 1 + .../content/_shaders/spv/lit_mesh.frag.spv | Bin 0 -> 488 bytes projects/content/_shaders/spv/meshes.vert.spv | Bin 1492 -> 1492 bytes projects/reflected.zig | 32 ++++ projects/sampleGame/main.zig | 38 ++++- 26 files changed, 434 insertions(+), 57 deletions(-) create mode 100644 engine/rend/shaders/lit_mesh.frag.hlsl create mode 100644 engine/rend/shaders/lit_mesh.frag.json create mode 100644 engine/rend/src/camera/CameraComponent.zig create mode 100644 engine/rend/src/camera/camera.zig create mode 100644 projects/content/_shaders/dxil/lit_mesh.frag.dxil create mode 100644 projects/content/_shaders/msl/lit_mesh.frag.msl create mode 100644 projects/content/_shaders/spv/lit_mesh.frag.spv create mode 100644 projects/reflected.zig diff --git a/engine/core/src/inputs/inputStack.zig b/engine/core/src/inputs/inputStack.zig index 64cce87..9e5fd7e 100644 --- a/engine/core/src/inputs/inputStack.zig +++ b/engine/core/src/inputs/inputStack.zig @@ -391,6 +391,8 @@ pub const Binding = union(BindingType) { p.magnitude.x = std.math.clamp(p.magnitude.x, -1.0, 1.0); p.magnitude.y = std.math.clamp(p.magnitude.y, -1.0, 1.0); + // core.engine_log(" >> {any} > routeBindingEvent magnitude {d} {d}", .{ key, p.magnitude.x, p.magnitude.y }); + // for (p.data.listeners.items) |listener| { // listener.func(listener.ctx, p.magnitude); // } @@ -562,11 +564,14 @@ pub const InputStack = struct { fn routeKeyEvent(self: *@This(), key: Key, event: ActionEvent) void { // for all bindings in reverse order from this layer, route the input, stop the // route if the input was consumed + // core.engine_log(" >> {any} > routeKeyEvent 1", .{key}); if (self.active.bindingStack.items.len == 0) { return; } + // core.engine_log(" >> {any} > routeKeyEvent 2", .{key}); var i: i32 = @intCast(self.active.bindingStack.items.len - 1); + // core.engine_log(" >> {any} > routeKeyEvent 2 binding count : {d}", .{ key, i }); while (i >= 0) : (i -= 1) { const binding = self.active.bindingStack.items[@intCast(i)]; var consumed: bool = false; @@ -597,6 +602,7 @@ pub const InputStack = struct { .key => |key| { const keyEvent: ActionEvent = key.action; // @enumFromInt(@as(u8, @intCast(key.action))); if (keyEvent != .keyHeld) { + // core.engine_log("converted: {any}", .{keyEvent}); self.routeKeyEvent(key.key, keyEvent); } }, diff --git a/engine/platform/src/windowing.zig b/engine/platform/src/windowing.zig index 3aedecf..89b5d5a 100644 --- a/engine/platform/src/windowing.zig +++ b/engine/platform/src/windowing.zig @@ -151,6 +151,8 @@ pub const PlatformInstance = struct { else => {}, } } + + inputStack.sendAxisUpdates(); } pub fn getCursorPosition(self: *@This()) core.Vector2f { diff --git a/engine/rend/build.zig b/engine/rend/build.zig index d64c705..3e3f47e 100644 --- a/engine/rend/build.zig +++ b/engine/rend/build.zig @@ -34,6 +34,7 @@ pub fn build(b: *std.Build) void { sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "sample.vert", b.path("shaders/sample.vert.json")); sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "meshes.vert", b.path("shaders/meshes.vert.json")); + sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "lit_mesh.frag", b.path("shaders/lit_mesh.frag.json")); // ========== tests ========== const tests = b.addTest(.{ diff --git a/engine/rend/shaders/lit_mesh.frag.hlsl b/engine/rend/shaders/lit_mesh.frag.hlsl new file mode 100644 index 0000000..797ad2b --- /dev/null +++ b/engine/rend/shaders/lit_mesh.frag.hlsl @@ -0,0 +1,5 @@ +float4 main(float2 UV : TEXCOORD0) : SV_Target0 +{ + return float4(UV, 0.0, 1.0); +} + diff --git a/engine/rend/shaders/lit_mesh.frag.json b/engine/rend/shaders/lit_mesh.frag.json new file mode 100644 index 0000000..4cbde78 --- /dev/null +++ b/engine/rend/shaders/lit_mesh.frag.json @@ -0,0 +1,22 @@ +{ + "entryPoints" : [ + { + "name" : "main", + "mode" : "frag" + } + ], + "inputs" : [ + { + "type" : "vec2", + "name" : "in.var.TEXCOORD0", + "location" : 0 + } + ], + "outputs" : [ + { + "type" : "vec4", + "name" : "out.var.SV_Target0", + "location" : 0 + } + ] +} \ No newline at end of file diff --git a/engine/rend/shaders/meshes.vert.hlsl b/engine/rend/shaders/meshes.vert.hlsl index 160ca56..35108d3 100644 --- a/engine/rend/shaders/meshes.vert.hlsl +++ b/engine/rend/shaders/meshes.vert.hlsl @@ -13,6 +13,7 @@ struct Input struct Output { float2 TexCoord : TEXCOORD0; + float4 Position : SV_Position; }; @@ -25,8 +26,8 @@ StructuredBuffer scene: register(t0, space0); cbuffer Uniforms : register(b0, space1) { - float4x4 ViewProjection; - float time; + float4x4 ViewProjection : packoffset(c0); + float time: packoffset(c16); }; Output main(Input input) diff --git a/engine/rend/shaders/meshes.vert.json b/engine/rend/shaders/meshes.vert.json index 279e031..77e68b2 100644 --- a/engine/rend/shaders/meshes.vert.json +++ b/engine/rend/shaders/meshes.vert.json @@ -48,7 +48,7 @@ { "name" : "time", "type" : "float", - "offset" : 64 + "offset" : 256 } ] } @@ -86,7 +86,7 @@ { "type" : "_10", "name" : "type.Uniforms", - "block_size" : 68, + "block_size" : 260, "set" : 1, "binding" : 0 } diff --git a/engine/rend/src/camera/CameraComponent.zig b/engine/rend/src/camera/CameraComponent.zig new file mode 100644 index 0000000..67273aa --- /dev/null +++ b/engine/rend/src/camera/CameraComponent.zig @@ -0,0 +1,96 @@ +fov: f32 = 70.0, +altFov: f32 = 70.0, +aspect: f32 = 16.0 / 9.0, +near_clipping: f32 = 0.1, +far_clipping: f32 = 10000.0, +transform: core.Transform = zm.identity(), + +worldTransform: Mat = zm.identity(), +projection: Mat = makePerspective( + core.radians(70.0), // angle + 16.0 / 9.0, + 0.1, + 200000, +), +projectionAlt: Mat = makePerspective( + core.radians(70.0), // angle + 16.0 / 9.0, + 0.0001, + 1000, +), + +yaw: f32 = 0, +pitch: f32 = 0, +roll: f32 = 0, + +final: Mat = zm.identity(), +finalAlt: Mat = zm.identity(), + +entity: core.Entity = undefined, + +pub fn initECS(self: *@This(), handle: core.SetHandle) void { + self.entity = core.Entity.fromHandle(handle); +} + +pub fn updateProjections(self: *@This()) core.Transform { + self.projection = zm.perspectiveFovRh(core.radians(self.fov), 16.0 / 9.0, 0.1, 200000); + self.projection[1][1] *= -1; + + self.projectionAlt = zm.perspectiveFovRh(core.radians(self.altFov), 16.0 / 9.0, 0.01, 200000); + self.projectionAlt[1][1] *= -1; +} + +pub fn resolve(self: *@This()) void { + const scene = self.entity.get(core.Scene).?; + + const position = scene.getPosition(); + { + var base = core.zm.identity(); + base = mul(core.zm.rotationY(-self.yaw), base); + base = mul(core.zm.rotationX(self.pitch), base); + base = mul(core.zm.rotationZ(self.roll), base); + + const pr2 = core.scene.SceneObjectPosRot{ + .position = position, + }; + + self.worldTransform = mul(base, pr2.toTransform()); + } + + // calculate viewProjections + { + var base = core.zm.rotationY(self.yaw + core.radians(180.0)); + base = mul(base, core.zm.rotationX(self.pitch)); + base = mul(base, core.zm.rotationZ(self.roll)); + self.transform = base; + + self.transform = mul(zm.translationV(position.fmul(-1).toZm()), self.transform); + self.final = mul(self.transform, self.projection); + self.finalAlt = mul(self.transform, self.projectionAlt); + } +} + +fn makePerspective(fov: f32, aspect: f32, near: f32, far: f32) Mat { + const proj = core.zm.perspectiveFovRh( + core.radians(fov), + aspect, + near, + far, + ); + // proj[1][1] *= -1; + return proj; +} + +pub var BaseContainer: *core.SparseMap(@This()) = undefined; +pub const ComponentName = "Camera"; + +pub const ScriptExports: []const []const u8 = &.{}; + +pub const EcsComponentDefinition = ecs.DefineComponent(@This(), .set); + +const core = @import("core"); +const ecs = core.ecs; +const zm = core.zm; +const mul = zm.mul; +const Mat = core.Mat; +const std = @import("std"); diff --git a/engine/rend/src/camera/camera.zig b/engine/rend/src/camera/camera.zig new file mode 100644 index 0000000..8a15cf2 --- /dev/null +++ b/engine/rend/src/camera/camera.zig @@ -0,0 +1,5 @@ +fov: f32 = 70.0, +altFov: f32 = 70.0, +aspect: f32 = 16.0 / 9.0, +near_clipping: f32 = 0.1, +far_clipping: f32 = 10000.0, diff --git a/engine/rend/src/meshes/MeshComponent.zig b/engine/rend/src/meshes/MeshComponent.zig index 6778d31..d22ab1d 100644 --- a/engine/rend/src/meshes/MeshComponent.zig +++ b/engine/rend/src/meshes/MeshComponent.zig @@ -5,25 +5,47 @@ visibility: bool = true, textureName: core.Name = core.NameInvalid, meshName: core.Name = core.NameInvalid, +entity: core.Entity = undefined, + pub var BaseContainer: *MeshSet = undefined; pub const ComponentName = "Mesh"; pub const ScriptExports: []const []const u8 = &.{ "setMesh", - "setTextureByName", + // "setTexture", }; -pub fn setMeshByName(self: *@This(), meshName: core.Name) void { - self.meshName = meshName; +pub fn initECS(self: *@This(), handle: core.SetHandle) void { + // get the mesh component + self.entity = core.Entity{ .handle = handle }; + + if (self.entity.get(core.Scene) == null) { + @panic("mesh added to something that doesn't have a scene component, not supported"); + } +} + +pub fn setMeshByName(self: *@This(), meshName: *core.Name) void { + self.mesh = rend.getMeshByName(meshName); + self.meshName = meshName.*; } // script function pub fn setMesh(self: *@This(), meshName: []const u8) void { - const name = core.MakeName(meshName); - self.mesh = rend.getMeshByName(core.MakeName(meshName)); - self.meshName = name; + var name = core.MakeName(meshName); + self.setMeshByName(&name); } +// pub fn setTextureByName(self: *@This(), n: []const u8) void { +// var name = core.MakeName(n); +// self.mesh = rend.getTextureByName(&name); +// self.textureName = name; +// } + +// pub fn setTexture(self: *@This(), n: []const u8) void { +// var name = core.MakeName(n); +// self.textureName = rend.getTextureByName(&name); +// } + // animator: ?*Animator = null, todo.. implement animator pub const MeshSet = core.SparseSet(@This()); diff --git a/engine/rend/src/rend.zig b/engine/rend/src/rend.zig index 3277069..7082be8 100644 --- a/engine/rend/src/rend.zig +++ b/engine/rend/src/rend.zig @@ -8,6 +8,10 @@ pub const MeshUpdate = meshes.MeshUpdate; pub const MeshVertex = meshes.MeshVertex; pub const IndexedMesh = meshes.IndexedMesh; +// components exports +pub const MeshComponent = @import("meshes/MeshComponent.zig"); +pub const CameraComponent = @import("camera/CameraComponent.zig"); + // asset loaders pub const gltfLoader = @import("meshes/gltfLoader.zig"); @@ -20,6 +24,9 @@ pub const MeshPool = renderer.MeshPool; pub const getMesh = renderer.getMesh; pub const getMeshByName = renderer.getMeshByName; +// camera API +pub const setActiveCamera = renderer.setActiveCamera; + var rendAllocator: std.mem.Allocator = undefined; pub fn getAllocator() std.mem.Allocator { return rendAllocator; @@ -38,9 +45,14 @@ pub fn start_module(comptime programSpec: anytype, args: anytype, allocator: std core.engine_log("starting up renderer interface", .{}); rendAllocator = allocator; try renderer.start(); + + try core.defineComponent(MeshComponent, allocator); + try core.defineComponent(CameraComponent, allocator); } pub fn shutdown_module(allocator: std.mem.Allocator) void { + core.undefineComponent(MeshComponent); + core.undefineComponent(CameraComponent); _ = allocator; renderer.shutdown(); } diff --git a/engine/rend/src/sgpu/mesh-pool.zig b/engine/rend/src/sgpu/mesh-pool.zig index f8c8ed5..92776c7 100644 --- a/engine/rend/src/sgpu/mesh-pool.zig +++ b/engine/rend/src/sgpu/mesh-pool.zig @@ -72,6 +72,7 @@ pub const MeshPool = struct { const vertexSpan = try self.addTransfer(copyPass, self.vertexBuffer, meshes.MeshVertex, &self.vertexSpans, new.vertices); var name = new.name; + core.graphics_log("uploading {d} vertices and {d} indices", .{ vertexSpan.size, indexSpan.size }); try self.installedMeshes.put(self.allocator, name.handle(), .{ .vertex = vertexSpan, .index = indexSpan, diff --git a/engine/rend/src/sgpu/renderer.zig b/engine/rend/src/sgpu/renderer.zig index bda8944..426df47 100644 --- a/engine/rend/src/sgpu/renderer.zig +++ b/engine/rend/src/sgpu/renderer.zig @@ -14,13 +14,18 @@ pub const Renderer = struct { shaderSuffix: []const u8 = undefined, shaderformat: gpu.GPUShaderFormat = undefined, entrypoint: []const u8 = "main", - pipeline: *gpu.GPUGraphicsPipeline = undefined, + testPipeline: *gpu.GPUGraphicsPipeline = undefined, + meshPipe: *gpu.GPUGraphicsPipeline = undefined, scissor: gpu.Rect = .{ .x = 0, .y = 0, .w = 1600, .h = 900 }, colorBuffer: *gpu.GPUBuffer = undefined, colorBufferTransfer: *gpu.GPUTransferBuffer = undefined, window: *sdl3.Window = undefined, + activeCamera: ?*rend.CameraComponent = null, + ssboScene: *gpu.GPUBuffer = undefined, + ssboSceneUpload: *gpu.GPUTransferBuffer = undefined, + meshPool: *MeshPool = undefined, uploads: std.ArrayListUnmanaged(struct { ptr: *anyopaque, func: *const fn (*anyopaque, *gpu.GPUCopyPass) void }) = .{}, @@ -29,6 +34,8 @@ pub const Renderer = struct { pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This()); + pub const MaxObjectCount = 50000; + pub fn init(allocator: std.mem.Allocator) !*@This() { const self = try allocator.create(@This()); @@ -57,7 +64,7 @@ pub const Renderer = struct { .shaderformatSpirv = true, .shaderformatDxil = true, .shaderformatMsl = true, - }, false, null); + }, true, null); self.window = platform.getInstance().window; @@ -69,6 +76,7 @@ pub const Renderer = struct { core.engine_log("sgpu device created, using shader format: {s}", .{self.shaderSuffix}); try self.createPipeline(); + try self.createMeshPipeline(); try self.registerRendererObject(MeshPool); } @@ -92,9 +100,94 @@ pub const Renderer = struct { } } + fn addAttribute(list: *std.ArrayList(gpu.GPUVertexAttribute), offset: *u32, size: u32, format: gpu.GPUVertexElementFormat) !void { + try list.append(.{ .location = @intCast(list.items.len), .offset = offset.* + size, .format = format, .buffer_slot = 0 }); + offset.* = offset.* + size; + } + + pub fn createMeshPipeline(self: *@This()) !void { + const vertex = try self.loadShader("meshes.vert", sample_vert.LoadArgs); + const fragment = try self.loadShader("lit_mesh.frag", lit_mesh_frag.LoadArgs); + + var pci = std.mem.zeroes(gpu.GPUGraphicsPipelineCreateInfo); + pci.vertex_shader = vertex; + pci.fragment_shader = fragment; + + var attributes = std.ArrayList(gpu.GPUVertexAttribute).init(self.allocator); + defer attributes.deinit(); + + var offset: u32 = 0; + { + try addAttribute(&attributes, &offset, @sizeOf(f32) * 3, .vertexelementformatFloat3); + try addAttribute(&attributes, &offset, @sizeOf(f32) * 3, .vertexelementformatFloat3); + try addAttribute(&attributes, &offset, @sizeOf(f32) * 4, .vertexelementformatFloat4); + try addAttribute(&attributes, &offset, @sizeOf(f32) * 2, .vertexelementformatFloat2); + try addAttribute(&attributes, &offset, @sizeOf(u32), .vertexelementformatUint); + } + + pci.vertex_input_state = .{ + .num_vertex_buffers = 1, + .vertex_buffer_descriptions = &[_]gpu.GPUVertexBufferDescription{ + .{ .slot = 0, .pitch = @sizeOf(rend.MeshVertex), .input_rate = .vertexinputrateVertex, .instance_step_rate = 0 }, + }, + .num_vertex_attributes = @intCast(attributes.items.len), + .vertex_attributes = @ptrCast(attributes.items.ptr), + }; + + pci.target_info.num_color_targets = 1; + pci.target_info.color_target_descriptions = &[_]gpu.GPUColorTargetDescription{ + .{ + .format = self.device.getGPUSwapchainTextureFormat(self.window), + .blend_state = std.mem.zeroes(gpu.GPUColorTargetBlendState), + }, + }; + + pci.rasterizer_state.fill_mode = .fillmodeFill; + self.meshPipe = self.device.createGPUGraphicsPipeline(&pci); + + // ssbo buffer + + // todo.. sparse uploads + self.ssboScene = self.device.createGPUBuffer(&.{ + .usage = .{ .bufferusageGraphicsStorageRead = true }, + .size = MaxObjectCount * @sizeOf(meshes_vert.Scene), + .props = 0, + }); + + self.ssboSceneUpload = self.device.createGPUTransferBuffer(&.{ + .usage = .transferbufferusageUpload, + .size = MaxObjectCount * @sizeOf(meshes_vert.Scene), + .props = 0, + }); + } + + pub fn uploadSSBOs(self: *@This(), copyPass: *gpu.GPUCopyPass) void { + const uploadMapped: [*]meshes_vert.Scene = self.device.mapGPUTransferBuffer(self.ssboSceneUpload, true); + self.device.unmapGPUTransferBuffer(self.ssboSceneUpload); + + const container = &rend.MeshComponent.BaseContainer; + const uploadCount: usize = @min(container.dense.items.len, MaxObjectCount); + for (0..uploadCount) |i| { + // const object = &container.dense.items[i].value; + const objectId = container.dense.items[i].sparseIndex; + var transform = core.Transform.identity(); + + if (core.Scene.SceneObjectContainer.get(objectId, ._repr)) |repr| { + transform = repr.transform; + } + uploadMapped[i].Model = @bitCast(transform); + } + + copyPass.uploadToGPUBuffer(&.{ .transfer_buffer = self.ssboSceneUpload, .offset = 0 }, &.{ + .buffer = self.ssboScene, + .offset = 0, + .size = uploadCount * @sizeOf(meshes_vert.Scene), + }, true); + } + pub fn createPipeline(self: *@This()) !void { - const vertex = try self.loadShader("sample.vert", 0, 0, 1, 0); - const fragment = try self.loadShader("sample.frag", 0, 0, 0, 0); + const vertex = try self.loadShader("sample.vert", sample_vert.LoadArgs); + const fragment = try self.loadShader("sample.frag", .{}); var pci = std.mem.zeroes(gpu.GPUGraphicsPipelineCreateInfo); pci.fragment_shader = fragment; @@ -109,7 +202,7 @@ pub const Renderer = struct { }; pci.rasterizer_state.fill_mode = .fillmodeFill; - self.pipeline = self.device.createGPUGraphicsPipeline(&pci); + self.testPipeline = self.device.createGPUGraphicsPipeline(&pci); self.colorBuffer = self.device.createGPUBuffer(&.{ .usage = .{ .bufferusageVertex = true }, @@ -127,18 +220,12 @@ pub const Renderer = struct { pub fn loadShader( self: *@This(), shaderName: []const u8, - num_samplers: u32, // The number of samplers defined in the shader. - num_storage_textures: u32, // The number of storage textures defined in the shader. - num_storage_buffers: u32, // The number of storage buffers defined in the shader. - num_uniform_buffers: u32, // The number of uniform buffers defined in the shader. + loadArgs: ShaderLoadArgs, ) !*gpu.GPUShader { const contentPath = try std.fmt.allocPrint(self.allocator, "_shaders/{s}/{s}{s}", .{ self.shaderType, shaderName, self.shaderSuffix }); defer self.allocator.free(contentPath); - const mapping = try core.fs().loadFile(contentPath); - defer core.fs().unmap(mapping); - var stage: gpu.GPUShaderStage = undefined; if (std.mem.endsWith(u8, shaderName, ".vert")) { @@ -149,21 +236,26 @@ pub const Renderer = struct { return error.NotImplemented; } + core.engine_log("creating shader {s} => {s} {any} args: {any}", .{ shaderName, contentPath, stage, loadArgs }); + + const mapping = try core.fs().loadFile(contentPath); + defer core.fs().unmap(mapping); + const sci = gpu.GPUShaderCreateInfo{ .code = @ptrCast(mapping.bytes.ptr), .entrypoint = @ptrCast(self.entrypoint.ptr), .format = self.shaderformat, .code_size = mapping.bytes.len - 1, .stage = stage, - .num_samplers = num_samplers, - .num_storage_textures = num_storage_textures, // The number of storage textures defined in the shader. - .num_storage_buffers = num_storage_buffers, // The number of storage buffers defined in the shader. - .num_uniform_buffers = num_uniform_buffers, // The number of uniform buffers defined in the shader. + .num_samplers = loadArgs.num_samplers, + .num_storage_textures = loadArgs.num_storage_textures, // The number of storage textures defined in the shader. + .num_storage_buffers = loadArgs.num_storage_buffers, // The number of storage buffers defined in the shader. + .num_uniform_buffers = loadArgs.num_uniform_buffers, // The number of uniform buffers defined in the shader. .props = 0, }; const rv = self.device.createGPUShader(&sci); - core.engine_log("creating shader {s} => {s} {any}", .{ shaderName, contentPath, stage }); + return rv; } @@ -179,6 +271,11 @@ pub const Renderer = struct { self.device.unmapGPUTransferBuffer(self.colorBufferTransfer); + if (self.activeCamera) |camera| { + camera.resolve(); + } + // map and upload Uniforms here + const copyPass = cmd.beginGPUCopyPass(); defer copyPass.endGPUCopyPass(); copyPass.uploadToGPUBuffer(&.{ .transfer_buffer = self.colorBufferTransfer, .offset = 0 }, &.{ @@ -190,6 +287,7 @@ pub const Renderer = struct { for (self.uploads.items) |upload| { upload.func(upload.ptr, copyPass); } + if (!cmd.submitGPUCommandBuffer()) { core.graphics_log("submit gpu command buffer SDL ERROR: {s}", .{sdl3.getError()}); } @@ -214,7 +312,7 @@ pub const Renderer = struct { targetInfo.store_op = .storeopStore; const renderpass = cmd.beginGPURenderPass(&targetInfo, 1, null); - renderpass.bindGPUGraphicsPipeline(self.pipeline); + renderpass.bindGPUGraphicsPipeline(self.testPipeline); renderpass.bindGPUVertexStorageBuffers(0, &self.colorBuffer, 1); renderpass.setGPUScissor(&self.scissor); renderpass.drawGPUPrimitives(3, 1, 0, 0); @@ -225,6 +323,8 @@ pub const Renderer = struct { } pub fn deinit(self: *@This()) void { + self.device.releaseGPUGraphicsPipeline(self.testPipeline); + for (self.destroys.items) |d| { d.func(d.ptr); } @@ -245,11 +345,16 @@ const core = @import("core"); const platform = @import("platform"); const sdl3 = @import("sdl3"); const gpu = sdl3.gpu; -const SSBO_Scene = @import("sample.vert").Scene; + const meshes_vert = @import("meshes.vert"); +const lit_mesh_frag = @import("lit_mesh.frag"); +const sample_vert = @import("sample.vert"); + const MeshVertices = meshes_vert.Scene; const MeshUniforms = meshes_vert.Uniforms; +const ShaderLoadArgs = sdl3.shaderTypes.ShaderLoadArgs; + pub const mesh_pool = @import("mesh-pool.zig"); pub const MeshPool = mesh_pool.MeshPool; @@ -264,6 +369,11 @@ pub fn shutdown() void {} pub fn context() *Renderer { return gRenderer; } + +pub fn setActiveCamera(camera: ?*rend.CameraComponent) void { + gRenderer.activeCamera = camera; +} + pub const getMesh = mesh_pool.getMesh; pub const getMeshByName = mesh_pool.getMeshByName; diff --git a/lib/sdl3/build.zig b/lib/sdl3/build.zig index e8233da..3f218de 100644 --- a/lib/sdl3/build.zig +++ b/lib/sdl3/build.zig @@ -53,6 +53,12 @@ pub fn build(b: *std.Build) void { .root_source_file = b.path("src/sdl3.zig"), }); + const shaderTypes = b.dependency("shaderTypes", .{ + .target = target, + .optimize = optimize, + }); + mod.addImport("shaderTypes", shaderTypes.module("shaderTypes")); + mod.addIncludePath(b.path("SDL/include")); mod.linkLibrary(sdl3_lib); diff --git a/lib/sdl3/shaderTypes/shaderTypes.zig b/lib/sdl3/shaderTypes/shaderTypes.zig index cc132ff..83929c6 100644 --- a/lib/sdl3/shaderTypes/shaderTypes.zig +++ b/lib/sdl3/shaderTypes/shaderTypes.zig @@ -94,15 +94,15 @@ pub const FieldDetail = struct { }; pub const ShaderLoadArgs = struct { - num_samplers: u32, // The number of samplers defined in the shader. - num_storage_textures: u32, // The number of storage textures defined in the shader. - num_storage_buffers: u32, // The number of storage buffers defined in the shader. - num_uniform_buffers: u32, // The number of uniform buffers defined in the shader. + num_samplers: u32 = 0, // The number of samplers defined in the shader. + num_storage_textures: u32 = 0, // The number of storage textures defined in the shader. + num_storage_buffers: u32 = 0, // The number of storage buffers defined in the shader. + num_uniform_buffers: u32 = 0, // The number of uniform buffers defined in the shader. }; pub const BufferInfo = union(enum(usize)) { - sampler: usize, // sampler - texture: usize, // storage texture - storage: usize, // storate buffer object - uniform: usize, // uniform/push constant + sampler: u32, // sampler + texture: u32, // storage texture + storage: u32, // storate buffer object + uniform: u32, // uniform/push constant }; diff --git a/lib/sdl3/spvreflect/spvreflect.py b/lib/sdl3/spvreflect/spvreflect.py index 3676b54..6b9c7e5 100644 --- a/lib/sdl3/spvreflect/spvreflect.py +++ b/lib/sdl3/spvreflect/spvreflect.py @@ -45,25 +45,27 @@ pub const float = shaderTypes.float; pub const BufferInfo = shaderTypes.BufferInfo; """ - types = reflect['types'] - storageIndex = 0 - if 'ssbos' in reflect: - for ssbo in reflect['ssbos']: - zs = parseTypeToZig(types, ssbo['type'], "storage", storageIndex) - storageIndex += 1 - ostring += zs + "\n" - uniformIndex = 0 - if 'ubos' in reflect: - for uniform in reflect['ubos']: - zs = parseTypeToZig(types, uniform['type'], "uniform", uniformIndex) - ostring += zs + "\n" - - zs = "pub const LoadArgs = shaderTypes.ShaderLoadArgs{" - samplerIndex = 0 textureIndex = 0 + if 'types' in reflect: + + types = reflect['types'] + + if 'ssbos' in reflect: + for ssbo in reflect['ssbos']: + zs = parseTypeToZig(types, ssbo['type'], "storage", ssbo['binding']) + storageIndex += 1 + ostring += zs + "\n" + + if 'ubos' in reflect: + for uniform in reflect['ubos']: + uniformIndex += 1 + zs = parseTypeToZig(types, uniform['type'], "uniform", uniform['binding']) + ostring += zs + "\n" + + zs = "pub const LoadArgs = shaderTypes.ShaderLoadArgs{" zs += f""" .num_samplers = {samplerIndex}, // The number of samplers defined in the shader. diff --git a/lib/sdl3/src/sdl3.zig b/lib/sdl3/src/sdl3.zig index 3af95af..1870875 100644 --- a/lib/sdl3/src/sdl3.zig +++ b/lib/sdl3/src/sdl3.zig @@ -50,3 +50,4 @@ pub fn getError() [*c]const u8 { pub const gpu = @import("gpu.zig"); pub const Scancode = @import("scancode.zig").Scancode; +pub const shaderTypes = @import("shaderTypes"); diff --git a/lib/tracy/build.zig b/lib/tracy/build.zig index 70e9fd2..5b34ac1 100644 --- a/lib/tracy/build.zig +++ b/lib/tracy/build.zig @@ -9,7 +9,7 @@ pub fn build(b: *std.Build) void { //const tracy_enabled = b.option(bool, "tracy", "Enables tracy integration") orelse false; - const tracy_enabled: bool = true; //if (b.graph.env_map.hash_map.get("WITH_TRACY") != null) true else false; + const tracy_enabled: bool = false; //if (b.graph.env_map.hash_map.get("WITH_TRACY") != null) true else false; // if (b.graph.env_map.hash_map.get("WITH_TRACY")) |with_tracy| { // tracy_enabled = with_tracy; // } diff --git a/projects/content/_shaders/dxil/lit_mesh.frag.dxil b/projects/content/_shaders/dxil/lit_mesh.frag.dxil new file mode 100644 index 0000000000000000000000000000000000000000..dba1c0acdaa246394ae8eb7117edbaf6de8a0b97 GIT binary patch literal 2808 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 delta 1114 zcmaE$@jyewCBn&B_?@co!zmJf;wwVUe#c$(+$h4q%FW!hK;YB@8LveQ%$wC&H?j!S zy|T}`KX<3Iq1DrU5$=0GZhpbJk%`f8^DLfq%=MfM3=A%37(~Jqr#Ri58q+8e&?xGq zC>nK8B;=r|+e4AChZjwlfNGT4I2oD}9M&FuypU0f1s6EsKHe zT8AT3gMx%aalpodQY{BflO`}IaImq-M&uq~lQVy0uQ4Esg=~Ad7EHy@5JrT?1E& zzyq)Yud_iN9j>$HkR(gB0nj6&Z23U#^ug_yDXwMSvZu_PXv7Cux?2Aho4z z#W1U0GU*<0bl?J6l@$O}8m@omkPORmkkYGc`qqYa-s)=`+st2us z8BK!BEDVkY9d8zjyE$^|SS(1stO-|9!_Xew08{ZrQO0i}r%u3vjp)+7A z{w$OUW8~7wSde^E`$T#I)S3wn?cp0>N?ep=;}W@a8WtEQ6@a4J-*drX-G(E;sP0kY zIGAxrp+`;NaK}MLV3gZvUF6%7AO!TI!7K%q#hlFsvmAJo+1P<;=EI&Ao0h|q-wTP= zI}3kL;L|b$2G3$nCxclA9E&-RBm_&q9XN-f^EkH~j{pP9L4`}56C$?3oHbXVlbQRB z7W2;@2?by}b-W_1qS)zZ07-!p{in2iW`(3Ffxj)D8ZilxQgAajICP%kf%vH2pyP;= z>LNo9s1;J&Q!@@I7_8%cVhk}UFmeOSGPZ+|gyWKSQRs>!FpGhbhQQobZ-*3t9!NG> zB&O>qma +#include + +using namespace metal; + +struct main0_out +{ + float4 out_var_SV_Target0 [[color(0)]]; +}; + +struct main0_in +{ + float2 in_var_TEXCOORD0 [[user(locn0)]]; +}; + +fragment main0_out main0(main0_in in [[stage_in]]) +{ + main0_out out = {}; + out.out_var_SV_Target0 = float4(in.in_var_TEXCOORD0, 0.0, 1.0); + return out; +} + diff --git a/projects/content/_shaders/msl/meshes.vert.msl b/projects/content/_shaders/msl/meshes.vert.msl index 51d6266..bc0d27e 100644 --- a/projects/content/_shaders/msl/meshes.vert.msl +++ b/projects/content/_shaders/msl/meshes.vert.msl @@ -16,6 +16,7 @@ struct type_StructuredBuffer_Scene struct type_Uniforms { float4x4 ViewProjection; + char _m1_pad[192]; float time; }; diff --git a/projects/content/_shaders/spv/lit_mesh.frag.spv b/projects/content/_shaders/spv/lit_mesh.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..f634fcaca104d8833de91169aedb57cc6c8656ad GIT binary patch literal 488 zcmYk2OG^V$429!N$NKC;L3dJdStzbV5bHw4WqlOsPG%v}g)Nlo+Mn%4@cV9O#6TuF zIXOx0lm1)KiwxdS`rNFgRxTjK+exApKonYlM; zHC|8X>*^5JJMD31k8Fcj-!H#e@vE7Q*aExH`aY^{;xUySqWMKN!+FjT*BW(aTw|Y{ yrtX_LyTnU+y{Cn%e@L(Qf3IqUzgnlNIp-dg_jGZ4<$Sa69CDj`<$l>>>>>> game prepare", .{}); var z = core.tracy.ZoneN(@src(), "PREPARING GAME"); defer z.End(); @@ -38,6 +44,27 @@ pub fn prepare(self: *@This()) !void { exitInput.addKey(.escape, .keyDown); _ = exitInput.data.addListener(null, onExit); exitInput.activate(); + + self.camera = try core.createEntity(); + const scene = self.camera.addComponent(core.Scene).?; + _ = scene; + const camera = self.camera.addComponent(rend.CameraComponent).?; + rend.setActiveCamera(camera); + + self.moveInput = try core.Axis2dBinding.create(core.MakeName("movement")); + + self.moveInput.addKey(.w, 1.0, .y); + self.moveInput.addKey(.s, -1.0, .y); + self.moveInput.addKey(.d, 1.0, .x); + self.moveInput.addKey(.a, -1.0, .x); + + _ = self.moveInput.data.addListener(self, onMove); + self.moveInput.activate(); +} + +fn onMove(ctx: ?*anyopaque, axis: core.Vector2f) void { + const self: *@This() = @ptrCast(@alignCast(ctx)); + self.moveVector = .{ .x = -axis.x, .z = axis.y, .y = 0.0 }; } pub fn onExit(ctx: ?*anyopaque, action: core.ActionEvent) void { @@ -47,9 +74,12 @@ pub fn onExit(ctx: ?*anyopaque, action: core.ActionEvent) void { core.exitNow(); } -pub fn tick(self: *@This(), _: f64) void { - _ = self; - std.time.sleep(6000 * 1000); // just gonna put this here... +pub fn tick(self: *@This(), dt: f64) void { + const fdt: f32 = @floatCast(dt); + if (self.camera.get(core.Scene)) |scene| { + scene.getPosRot().position = scene.getPosRot().position.add(self.moveVector.fmul(self.cameraSpeed * fdt)); + core.engine_log(" camera position >> {any}", .{scene.getPosRot().position}); + } } pub fn deinit(self: *@This()) void {