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 0000000..dba1c0a Binary files /dev/null and b/projects/content/_shaders/dxil/lit_mesh.frag.dxil differ diff --git a/projects/content/_shaders/dxil/meshes.vert.dxil b/projects/content/_shaders/dxil/meshes.vert.dxil index 3eeb0b1..97fc28f 100644 Binary files a/projects/content/_shaders/dxil/meshes.vert.dxil and b/projects/content/_shaders/dxil/meshes.vert.dxil differ diff --git a/projects/content/_shaders/msl/lit_mesh.frag.msl b/projects/content/_shaders/msl/lit_mesh.frag.msl new file mode 100644 index 0000000..a07b1a6 --- /dev/null +++ b/projects/content/_shaders/msl/lit_mesh.frag.msl @@ -0,0 +1,22 @@ +#include +#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 0000000..f634fca Binary files /dev/null and b/projects/content/_shaders/spv/lit_mesh.frag.spv differ diff --git a/projects/content/_shaders/spv/meshes.vert.spv b/projects/content/_shaders/spv/meshes.vert.spv index e7ccb60..e31a92e 100644 Binary files a/projects/content/_shaders/spv/meshes.vert.spv and b/projects/content/_shaders/spv/meshes.vert.spv differ diff --git a/projects/reflected.zig b/projects/reflected.zig new file mode 100644 index 0000000..bd4cc27 --- /dev/null +++ b/projects/reflected.zig @@ -0,0 +1,32 @@ +pub const shaderTypes = @import("shaderTypes"); + +pub const int = shaderTypes.int; +pub const uint = shaderTypes.uint; + +pub const vec2 = shaderTypes.vec2; +pub const u8vec4 = shaderTypes.u8vec4; +pub const vec3 = shaderTypes.vec3; +pub const vec4 = shaderTypes.vec4; +pub const mat4 = shaderTypes.mat4; +pub const float = shaderTypes.float; + +pub const BufferInfo = shaderTypes.BufferInfo; +pub const Scene = struct { + Model: mat4, + + pub const Buffer: BufferInfo = .{ .storage = 0 }; +}; + +pub const Uniforms = struct { + ViewProjection: mat4, + time: float, + + pub const Buffer: BufferInfo = .{ .uniform = 0 }; +}; + +pub const LoadArgs = shaderTypes.ShaderLoadArgs{ + .num_samplers = 0, // The number of samplers defined in the shader. + .num_storage_textures = 0, // The number of storage textures defined in the shader. + .num_storage_buffers = 1, // The number of storage buffers defined in the shader. + .num_uniform_buffers = 1, // The number of uniform buffers defined in the shader. +}; diff --git a/projects/sampleGame/main.zig b/projects/sampleGame/main.zig index 1955297..7934bc4 100644 --- a/projects/sampleGame/main.zig +++ b/projects/sampleGame/main.zig @@ -1,5 +1,12 @@ allocator: std.mem.Allocator, +camera: core.Entity = undefined, +cameraSpeed: f32 = 10.0, + +moveInput: *core.Axis2dBinding = undefined, + +moveVector: core.Vectorf = .{}, + pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This()); pub fn init(allocator: std.mem.Allocator) !*@This() { @@ -24,7 +31,6 @@ const assetReferences = [_]assets.AssetImportReference{ }; pub fn prepare(self: *@This()) !void { - _ = self; core.engine_log(">>>>>>> 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 {