diff --git a/engine/rend/build.zig b/engine/rend/build.zig index 3e3f47e..d00ab36 100644 --- a/engine/rend/build.zig +++ b/engine/rend/build.zig @@ -36,6 +36,9 @@ pub fn build(b: *std.Build) void { 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")); + sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "debug.frag", b.path("shaders/debug.frag.json")); + sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "debug.vert", b.path("shaders/debug.vert.json")); + // ========== tests ========== const tests = b.addTest(.{ .target = target, diff --git a/engine/rend/shaders/debug.frag.hlsl b/engine/rend/shaders/debug.frag.hlsl new file mode 100644 index 0000000..0fb7dea --- /dev/null +++ b/engine/rend/shaders/debug.frag.hlsl @@ -0,0 +1,4 @@ +float4 main(float3 Color : TEXCOORD0) : SV_Target0 +{ + return float4(Color, 1.0); +} diff --git a/engine/rend/shaders/debug.frag.json b/engine/rend/shaders/debug.frag.json new file mode 100644 index 0000000..3691330 --- /dev/null +++ b/engine/rend/shaders/debug.frag.json @@ -0,0 +1,22 @@ +{ + "entryPoints" : [ + { + "name" : "main", + "mode" : "frag" + } + ], + "inputs" : [ + { + "type" : "vec3", + "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/debug.vert.hlsl b/engine/rend/shaders/debug.vert.hlsl new file mode 100644 index 0000000..032bcf0 --- /dev/null +++ b/engine/rend/shaders/debug.vert.hlsl @@ -0,0 +1,38 @@ +struct Input +{ + float3 Position : TEXCOORD0; + + uint Instance : SV_InstanceID; +}; + +struct Output +{ + float3 Color : TEXCOORD0; + float4 Position : SV_Position; +}; + +struct Scene +{ + float4x4 Model; + float3 Color; +}; + +StructuredBuffer scene: register(t0, space0); + +cbuffer Uniforms : register(b0, space1) +{ + float4x4 ViewProjection; +}; + +Output main(Input input) +{ + Output output; + + float4 pos = float4(input.Position, 1.0); + + output.Position = mul(ViewProjection, mul(scene[input.Instance].Model, pos)); + output.Color = scene[input.Instance].Color; + + return output; +} + diff --git a/engine/rend/shaders/debug.vert.json b/engine/rend/shaders/debug.vert.json new file mode 100644 index 0000000..f3b65c7 --- /dev/null +++ b/engine/rend/shaders/debug.vert.json @@ -0,0 +1,89 @@ +{ + "entryPoints" : [ + { + "name" : "main", + "mode" : "vert" + } + ], + "types" : { + "_7" : { + "name" : "Scene", + "members" : [ + { + "name" : "Model", + "type" : "mat4", + "offset" : 0, + "matrix_stride" : 16, + "row_major" : true + }, + { + "name" : "Color", + "type" : "vec3", + "offset" : 64 + } + ] + }, + "_6" : { + "name" : "type.StructuredBuffer.Scene", + "members" : [ + { + "name" : "_m0", + "type" : "_7", + "array" : [ + 0 + ], + "array_size_is_literal" : [ + true + ], + "offset" : 0, + "array_stride" : 80 + } + ] + }, + "_9" : { + "name" : "type.Uniforms", + "members" : [ + { + "name" : "ViewProjection", + "type" : "mat4", + "offset" : 0, + "matrix_stride" : 16, + "row_major" : true + } + ] + } + }, + "inputs" : [ + { + "type" : "vec3", + "name" : "in.var.TEXCOORD0", + "location" : 0 + } + ], + "outputs" : [ + { + "type" : "vec3", + "name" : "out.var.TEXCOORD0", + "location" : 0 + } + ], + "ssbos" : [ + { + "type" : "_6", + "name" : "scene", + "readonly" : true, + "block_size" : 0, + "set" : 0, + "binding" : 0 + } + ], + "ubos" : [ + { + "type" : "_9", + "name" : "type.Uniforms", + "block_size" : 64, + "set" : 1, + "binding" : 0 + } + ] +} \ No newline at end of file diff --git a/engine/rend/shaders/lit_mesh.frag.hlsl b/engine/rend/shaders/lit_mesh.frag.hlsl index ec0888f..eeffff9 100644 --- a/engine/rend/shaders/lit_mesh.frag.hlsl +++ b/engine/rend/shaders/lit_mesh.frag.hlsl @@ -30,18 +30,18 @@ float3 BlinnPhong(float3 normal, float3 fragPos, float3 lightPos, float3 lightCo float cutoffFactor = 0.5; float dist = length(lightPos - fragPos); float attenuation = 1.0 / (dist * 2); - if (dist > cutoff1) - { - attenuation *= cutoffFactor; - } - if (dist > cutoff2) - { - attenuation *= cutoffFactor; - } - if (dist > maxDist) - { - attenuation = 0; - } + //if (dist > cutoff1) + //{ + // attenuation *= cutoffFactor; + //} + //if (dist > cutoff2) + //{ + // attenuation *= cutoffFactor; + //} + //if (dist > maxDist) + //{ + // attenuation = 0; + //} diffuse *= attenuation; diff --git a/engine/rend/src/sgpu/DebugDrawSystem.zig b/engine/rend/src/sgpu/DebugDrawSystem.zig index 371baad..807bc43 100644 --- a/engine/rend/src/sgpu/DebugDrawSystem.zig +++ b/engine/rend/src/sgpu/DebugDrawSystem.zig @@ -1,7 +1,21 @@ pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This()); allocator: std.mem.Allocator, +debugDraws: core.RingQueueU(DebugPrimitive), + device: *gpu.GPUDevice = undefined, +renderer: *Renderer = undefined, +pipeline: *gpu.GPUGraphicsPipeline = undefined, + +ssbo: *gpu.GPUBuffer = undefined, +ssobUpload: *gpu.GPUTransferBuffer = undefined, + +meshes: [@as(usize, @intCast(@intFromEnum(DebugPrimitiveType.box) + 1))]?rend.IndexedMesh = .{ null, null, null }, +deltaTime: f64 = 0, + +drawsThisFrame: std.ArrayListUnmanaged(DebugPrimitive) = .{}, + +pub const MaxObjectCount = 4096; const assetReferences = [_]assets.AssetImportReference{ assets.MakeImportRefOptions( @@ -24,6 +38,7 @@ const assetReferences = [_]assets.AssetImportReference{ pub fn create(allocator: std.mem.Allocator) !*@This() { const self = try allocator.create(@This()); self.* = .{ + .debugDraws = try core.RingQueueU(DebugPrimitive).init(allocator, MaxObjectCount), .allocator = allocator, }; core.engine_logs("[DebugDrawSystem] starting up..."); @@ -34,53 +49,327 @@ pub fn create(allocator: std.mem.Allocator) !*@This() { try assets.loadList(assetReferences); + gDebugDrawSys = self; + return self; } +pub fn updateMeshes(self: *@This()) void { + + // line = 0, + // sphere = 1, + // box = 2, + const list: [3][]const u8 = .{ + "m_debug_line", // 0 + "m_debug_sphere", // 1 + "m_debug_box", // 2 + }; + + for (list, 0..) |path, i| { + self.meshes[i] = rend.getMesh(path); + } +} + +pub fn tick(self: *@This(), dt: f64) void { + self.deltaTime = dt; + + if (self.meshes[0] == null) { + self.updateMeshes(); + } +} + +// ========= Rendering section ========= +pub fn onUpload(p: *anyopaque, copyPass: *gpu.GPUCopyPass) void { + const self: *@This() = @ptrCast(@alignCast(p)); + + const count = self.debugDraws.count(); + { + const uploadMapped: [*]debug_vert.Scene = @ptrCast(@alignCast(self.device.mapGPUTransferBuffer(self.ssobUpload, true))); + defer self.device.unmapGPUTransferBuffer(self.ssobUpload); + + var offset: usize = 0; + + self.drawsThisFrame.clearRetainingCapacity(); + + while (offset < count) { + var primitive: DebugPrimitive = self.debugDraws.pop().?; + uploadMapped[offset] = .{ + .Model = primitive.resolve(), + .Color = @bitCast(primitive.color), + }; + + self.drawsThisFrame.append(self.allocator, primitive) catch unreachable; + + primitive.duration -= @as(f32, @floatCast(self.deltaTime)); + offset += 1; + if (primitive.duration >= 0) { + // push this primitive so that it goes to the next frame + self.debugDraws.push(primitive) catch continue; + } + } + } + + if (count > 0) { + copyPass.uploadToGPUBuffer(&.{ .transfer_buffer = self.ssobUpload, .offset = 0 }, &.{ + .buffer = self.ssbo, + .offset = 0, + .size = @intCast(count * @sizeOf(debug_vert.Scene)), + }, true); + } +} + +pub fn postMesh(p: *anyopaque, cmd: *gpu.GPUCommandBuffer, renderpass: *gpu.GPURenderPass) void { + const self: *@This() = @ptrCast(@alignCast(p)); + + if (self.meshes[0] == null) { + return; + } + + renderpass.bindGPUGraphicsPipeline(self.pipeline); + renderpass.bindGPUVertexStorageBuffers(0, &self.ssbo, 1); + + for (self.drawsThisFrame.items, 0..) |draw, i| { + var mesh: rend.IndexedMesh = undefined; + switch (draw.primitive) { + .box => { + mesh = self.meshes[2].?; + }, + .sphere => { + mesh = self.meshes[1].?; + }, + .line => { + mesh = self.meshes[0].?; + }, + } + + renderpass.drawGPUIndexedPrimitives(mesh.index.size, 1, mesh.index.start, @intCast(mesh.vertex.start), @intCast(i)); + } + _ = cmd; +} +// ========= End of Rendering section ========= + +pub fn createBuffers(self: *@This()) !void { + self.ssbo = self.device.createGPUBuffer(&.{ + .usage = .{ .bufferusageGraphicsStorageRead = true, .bufferusageVertex = true }, + .size = MaxObjectCount * @sizeOf(debug_vert.Scene), + .props = 0, + }); + + self.ssobUpload = self.device.createGPUTransferBuffer(&.{ + .usage = .transferbufferusageUpload, + .size = MaxObjectCount * @sizeOf(debug_vert.Scene), + .props = 0, + }); +} + +pub fn createPipeline(self: *@This()) !*gpu.GPUGraphicsPipeline { + const vertex = try rend.context().loadShader("debug.vert", debug_vert.LoadArgs); + const fragment = try rend.context().loadShader("debug.frag", debug_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); + } + + 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.depth_stencil_state.compare_op = .compareopLess; + pci.depth_stencil_state.enable_depth_test = true; + pci.depth_stencil_state.enable_depth_write = true; + pci.depth_stencil_state.write_mask = 0xff; + + pci.target_info.has_depth_stencil_target = true; + pci.target_info.depth_stencil_format = .textureformatD32Float; + pci.target_info.num_color_targets = 1; + pci.target_info.color_target_descriptions = &[_]gpu.GPUColorTargetDescription{ + .{ + .format = self.device.getGPUSwapchainTextureFormat(rend.context().window), + .blend_state = std.mem.zeroes(gpu.GPUColorTargetBlendState), + }, + }; + + pci.rasterizer_state.fill_mode = .fillmodeLine; + const pipe = self.device.createGPUGraphicsPipeline(&pci); + + return pipe; +} + +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.*, .format = format, .buffer_slot = 0 }); + offset.* = offset.* + size; +} + pub fn setup(self: *@This(), device: *gpu.GPUDevice) !void { + core.engine_logs("[DebugDrawSystem] registering to renderer..."); self.device = device; + self.renderer = rend.context(); + self.pipeline = try self.createPipeline(); + try self.createBuffers(); + + //core.installDebugDrawInterface(self.allocator, newInterface: DebugDrawInterface); + try core.installDebugDrawInterface(self.allocator, .{ + .debugSphereFn = debugSphere, // : *const fn (pos: core.Vectorf, radius: f32, DebugDrawParams) void, + .debugBoxFn = debugBox, // : *const fn (pos: core.Vectorf, extents: core.Vectorf, DebugDrawParams) void, + .debugLineFn = debugLine, // : *const fn (start: core.Vectorf, end: core.Vectorf, DebugDrawParams) void, + }); } pub fn destroy(self: *@This()) void { + self.debugDraws.deinit(self.allocator); + self.drawsThisFrame.deinit(self.allocator); self.allocator.destroy(self); } +// ==================== Primitives =================== + +pub const DebugLine = struct { + start: core.Vectorf, + end: core.Vectorf, + + pub fn resolve(self: @This(), _: anytype) core.Transform { + var delta = self.start.sub(self.end); + const d = delta.normalize(); + const axz = std.math.atan2(-d.z, d.x) + core.radians(180.0); + const ay = -std.math.asin(d.y); + const mat1 = core.zm.matFromRollPitchYaw(0, 0, ay); + const mat2 = core.zm.rotationY(axz); + const len = delta.length(); + return core.zm.mul(core.zm.mul( + core.zm.mul(mat1, mat2), + core.zm.scaling(len, len, len), + ), core.zm.translationV(self.start.toZm())); + } +}; + +pub const DebugSphere = struct { + position: core.Vectorf, + radius: f32, + rotation: core.Quat, + + pub fn resolve(self: @This(), _: anytype) core.Transform { + return core.zm.mul(core.zm.mul( + core.zm.matFromQuat(self.rotation), + core.zm.scaling(self.radius, self.radius, self.radius), + ), core.zm.translationV(self.position.toZm())); + } +}; + +pub const DebugBox = struct { + position: core.Vectorf, + extents: core.Vectorf, + rotation: core.Quat, + + pub fn resolve(self: @This(), _: anytype) core.Transform { + return core.zm.mul(core.zm.mul( + core.zm.matFromQuat(self.rotation), + core.zm.scalingV(self.extents.toZm()), + ), core.zm.translationV(self.position.toZm())); + } +}; + +const DebugPrimitiveType = enum(u8) { + line = 0, + sphere = 1, + box = 2, +}; + +pub const DebugPrimitive = struct { + primitive: union(DebugPrimitiveType) { + line: DebugLine, + sphere: DebugSphere, + box: DebugBox, + }, + color: core.Vectorf = .{ .x = 0.0, .y = 1.0, .z = 0.0 }, + duration: f32 = 0.0, + + pub fn resolve(self: @This()) core.Transform { + // comptime core.asserts(@sizeOf(DebugPrimitiveGpu) == DebugPrimitiveGpu.TargetSize, ""); + + switch (self.primitive) { + .line => |inner| { + return inner.resolve(.{}); + }, + .sphere => |inner| { + return inner.resolve(.{}); + }, + .box => |inner| { + return inner.resolve(.{}); + }, + } + unreachable; + + // return core.implement_func_for_tagged_union_nonull(self.primitive, "resolve", core.Transform, .{}); + } +}; + +const DebugPrimitiveGpu = struct { + const UnpaddedSize = @sizeOf(core.Transform) + @sizeOf(core.Vectorf); + const TargetSize = 80; + + model: core.Transform, + color: core.Vectorf, + + pad: [TargetSize - UnpaddedSize]u8 = std.mem.zeroes([TargetSize - UnpaddedSize]u8), +}; + +const DebugDrawSharedInstance = struct {}; + +const DebugSharedData = struct { + drawsThisFrame: std.ArrayListUnmanaged(DebugPrimitive) = .{}, + lock: std.Thread.Mutex = .{}, + + pub fn deinit(self: *@This(), allocator: std.mem.Allocator) void { + self.drawsThisFrame.deinit(allocator); + } +}; + +const objectCount = 2048; + +// ==================== End of primitives ============ + +var gDebugDrawSys: *@This() = undefined; + pub fn debugSphere(position: core.Vectorf, radius: f32, params: DebugDrawParams) void { - _ = position; - _ = radius; - _ = params; - // gDebugDrawSys.debugDraws.push(.{ - // .primitive = .{ .sphere = .{ .position = position, .radius = radius, .rotation = params.rotation } }, - // .color = params.color, - // .duration = params.duration, - // }) catch return; + gDebugDrawSys.debugDraws.push(.{ + .primitive = .{ .sphere = .{ .position = position, .radius = radius, .rotation = params.rotation } }, + .color = params.color, + .duration = params.duration, + }) catch return; } pub fn debugLine(start: core.Vectorf, end: core.Vectorf, params: DebugDrawParams) void { - _ = start; - _ = end; - _ = params; - // gDebugDrawSys.debugDraws.push(.{ - // .primitive = .{ .line = .{ - // .start = start, - // .end = end, - // } }, - // .color = params.color, - // .duration = params.duration, - // }) catch return; + gDebugDrawSys.debugDraws.push(.{ + .primitive = .{ .line = .{ + .start = start, + .end = end, + } }, + .color = params.color, + .duration = params.duration, + }) catch return; } pub fn debugBox(position: core.Vectorf, extents: core.Vectorf, params: DebugDrawParams) void { - _ = position; - _ = extents; - _ = params; - // gDebugDrawSys.debugDraws.push(.{ - // .primitive = .{ - // .box = .{ .position = position, .extents = extents, .rotation = params.rotation }, - // }, - // .color = params.color, - // .duration = params.duration, - // }) catch return; + gDebugDrawSys.debugDraws.push(.{ + .primitive = .{ + .box = .{ .position = position, .extents = extents, .rotation = params.rotation }, + }, + .color = params.color, + .duration = params.duration, + }) catch return; } const DebugDrawParams = core.DebugDrawParams; @@ -93,6 +382,9 @@ const sdl3 = @import("sdl3"); const gpu = sdl3.gpu; const std = @import("std"); +const debug_frag = @import("debug.frag"); +const debug_vert = @import("debug.vert"); +const Renderer = @import("renderer.zig").Renderer; const primitive_box align(8) = @embedFile("embedded/primitive_box.obj").*; const primitive_line align(8) = @embedFile("embedded/primitive_line.obj").*; const primitive_sphere align(8) = @embedFile("embedded/primitive_sphere.obj").*; diff --git a/engine/rend/src/sgpu/mesh-pool.zig b/engine/rend/src/sgpu/mesh-pool.zig index 26c219b..cd69af1 100644 --- a/engine/rend/src/sgpu/mesh-pool.zig +++ b/engine/rend/src/sgpu/mesh-pool.zig @@ -170,7 +170,6 @@ pub fn getMesh(name: []const u8) ?rend.IndexedMesh { } pub fn getMeshByName(name: *core.Name) ?rend.IndexedMesh { - core.engine_log("getMeshByName {d}", .{name.handle()}); return gMeshPool.installedMeshes.get(name.handle()); } diff --git a/engine/rend/src/sgpu/renderer.zig b/engine/rend/src/sgpu/renderer.zig index 2ed8dbc..a38f5cc 100644 --- a/engine/rend/src/sgpu/renderer.zig +++ b/engine/rend/src/sgpu/renderer.zig @@ -31,6 +31,7 @@ pub const Renderer = struct { uploads: std.ArrayListUnmanaged(struct { ptr: *anyopaque, func: *const fn (*anyopaque, *gpu.GPUCopyPass) void }) = .{}, uploadCleanup: std.ArrayListUnmanaged(struct { ptr: *anyopaque, func: *const fn (*anyopaque) void }) = .{}, + postMesh: std.ArrayListUnmanaged(struct { ptr: *anyopaque, func: *const fn (*anyopaque, *gpu.GPUCommandBuffer, *gpu.GPURenderPass) void }) = .{}, postRenders: std.ArrayListUnmanaged(struct { ptr: *anyopaque, func: *const fn (*anyopaque, *gpu.GPUCommandBuffer) void }) = .{}, destroys: std.ArrayListUnmanaged(struct { ptr: *anyopaque, func: *const fn (*anyopaque) void }) = .{}, preDraws: std.ArrayListUnmanaged(struct { ptr: *anyopaque, func: *const fn (*anyopaque, *gpu.GPUCommandBuffer) void }) = .{}, @@ -80,8 +81,8 @@ pub const Renderer = struct { core.engine_log("sgpu device created, using shader format: {s}", .{self.shaderSuffix}); - // try self.createPipeline(); try self.createMeshPipeline(); + try self.createBuffers(); try self.createDepthTexture(); self.meshPool = try self.createRendererObject(MeshPool); @@ -108,7 +109,7 @@ pub const Renderer = struct { var defaultTextureName = core.MakeName("t_default"); self.defaultTexture = getTexture(&defaultTextureName).?; - self.debugDrawSys = try core.createObject(DebugDrawSystem, .{}); + self.debugDrawSys = try self.createRendererEngineObject(DebugDrawSystem); } pub fn createSamplers(self: *@This()) !void { @@ -137,6 +138,10 @@ pub const Renderer = struct { try self.postRenders.append(self.allocator, .{ .ptr = object, .func = T.postRender }); } + if (@hasDecl(T, "postMesh")) { + try self.postMesh.append(self.allocator, .{ .ptr = object, .func = T.postMesh }); + } + if (@hasDecl(T, "onPreDraw")) { try self.preDraws.append(self.allocator, .{ .ptr = object, .func = T.onPreDraw }); } @@ -146,6 +151,8 @@ pub const Renderer = struct { const object = try core.createObject(T, .{}); try object.setup(self.device); + try self.registerRendererObject(T, object); + return object; } @@ -243,6 +250,9 @@ pub const Renderer = struct { pci.rasterizer_state.fill_mode = .fillmodeFill; self.meshPipe = self.device.createGPUGraphicsPipeline(&pci); + } + + pub fn createBuffers(self: *@This()) !void { // ssbo buffer @@ -261,20 +271,23 @@ pub const Renderer = struct { } pub fn uploadSSBOs(self: *@This(), copyPass: *gpu.GPUCopyPass) !void { - const uploadMapped: [*]meshes_vert.Scene = @ptrCast(@alignCast(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.zm.identity(); + { + const uploadMapped: [*]meshes_vert.Scene = @ptrCast(@alignCast(self.device.mapGPUTransferBuffer(self.ssboSceneUpload, true))); + defer self.device.unmapGPUTransferBuffer(self.ssboSceneUpload); - if (core.Scene.SceneObjectContainer.get(objectId, ._repr)) |repr| { - transform = repr.transform; + // iterate over MeshComponents + for (0..uploadCount) |i| { + // const object = &container.dense.items[i].value; + const objectId = container.dense.items[i].sparseIndex; + var transform = core.zm.identity(); + + if (core.Scene.SceneObjectContainer.get(objectId, ._repr)) |repr| { + transform = repr.transform; + } + uploadMapped[i].Model = @bitCast(transform); } - uploadMapped[i].Model = @bitCast(transform); } if (uploadCount == 0) @@ -287,40 +300,6 @@ pub const Renderer = struct { }, true); } - pub fn createPipeline(self: *@This()) !void { - 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; - pci.vertex_shader = vertex; - - pci.target_info.num_color_targets = 1; - pci.target_info.has_depth_stencil_target = true; - pci.target_info.depth_stencil_format = .textureformatD32Float; - 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.testPipeline = self.device.createGPUGraphicsPipeline(&pci); - - self.colorBuffer = self.device.createGPUBuffer(&.{ - .usage = .{ .bufferusageVertex = true, .bufferusageGraphicsStorageRead = true }, - .size = 8192 * 2, - .props = 0, - }); - - self.colorBufferTransfer = self.device.createGPUTransferBuffer(&.{ - .usage = .transferbufferusageUpload, - .size = 8192 * 2, - .props = 0, - }); - } - pub fn loadShader( self: *@This(), shaderName: []const u8, @@ -458,6 +437,7 @@ pub const Renderer = struct { const renderpass = cmd.beginGPURenderPass(&targetInfo, 1, &depthTarget); //renderpass.bindGPUGraphicsPipeline(self.testPipeline); + renderpass.bindGPUGraphicsPipeline(self.meshPipe); renderpass.bindGPUVertexStorageBuffers(0, &self.ssboScene, 1); @@ -498,6 +478,10 @@ pub const Renderer = struct { } } + for (self.postMesh.items) |interface| { + interface.func(interface.ptr, cmd, renderpass); + } + renderpass.endGPURenderPass(); for (self.postRenders.items) |interface| { @@ -517,6 +501,8 @@ pub const Renderer = struct { for (self.destroys.items) |d| { d.func(d.ptr); } + + self.postMesh.deinit(self.allocator); self.uploadCleanup.deinit(self.allocator); self.preDraws.deinit(self.allocator); self.postRenders.deinit(self.allocator); diff --git a/projects/content/_shaders/dxil/debug.frag.dxil b/projects/content/_shaders/dxil/debug.frag.dxil new file mode 100644 index 0000000..75770c4 Binary files /dev/null and b/projects/content/_shaders/dxil/debug.frag.dxil differ diff --git a/projects/content/_shaders/dxil/debug.vert.dxil b/projects/content/_shaders/dxil/debug.vert.dxil new file mode 100644 index 0000000..89a9c46 Binary files /dev/null and b/projects/content/_shaders/dxil/debug.vert.dxil differ diff --git a/projects/content/_shaders/dxil/lit_mesh.frag.dxil b/projects/content/_shaders/dxil/lit_mesh.frag.dxil index f2b005b..779aff1 100644 Binary files a/projects/content/_shaders/dxil/lit_mesh.frag.dxil and b/projects/content/_shaders/dxil/lit_mesh.frag.dxil differ diff --git a/projects/content/_shaders/msl/debug.frag.msl b/projects/content/_shaders/msl/debug.frag.msl new file mode 100644 index 0000000..ecf7cb2 --- /dev/null +++ b/projects/content/_shaders/msl/debug.frag.msl @@ -0,0 +1,22 @@ +#include +#include + +using namespace metal; + +struct main0_out +{ + float4 out_var_SV_Target0 [[color(0)]]; +}; + +struct main0_in +{ + float3 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, 1.0); + return out; +} + diff --git a/projects/content/_shaders/msl/debug.vert.msl b/projects/content/_shaders/msl/debug.vert.msl new file mode 100644 index 0000000..482ac8a --- /dev/null +++ b/projects/content/_shaders/msl/debug.vert.msl @@ -0,0 +1,40 @@ +#include +#include + +using namespace metal; + +struct Scene +{ + float4x4 Model; + float3 Color; +}; + +struct type_StructuredBuffer_Scene +{ + Scene _m0[1]; +}; + +struct type_Uniforms +{ + float4x4 ViewProjection; +}; + +struct main0_out +{ + float3 out_var_TEXCOORD0 [[user(locn0)]]; + float4 gl_Position [[position]]; +}; + +struct main0_in +{ + float3 in_var_TEXCOORD0 [[attribute(0)]]; +}; + +vertex main0_out main0(main0_in in [[stage_in]], constant type_Uniforms& Uniforms [[buffer(0)]], const device type_StructuredBuffer_Scene& scene [[buffer(1)]], uint gl_InstanceIndex [[instance_id]]) +{ + main0_out out = {}; + out.out_var_TEXCOORD0 = scene._m0[gl_InstanceIndex].Color; + out.gl_Position = Uniforms.ViewProjection * (scene._m0[gl_InstanceIndex].Model * float4(in.in_var_TEXCOORD0, 1.0)); + return out; +} + diff --git a/projects/content/_shaders/msl/lit_mesh.frag.msl b/projects/content/_shaders/msl/lit_mesh.frag.msl index e8c494d..766471f 100644 --- a/projects/content/_shaders/msl/lit_mesh.frag.msl +++ b/projects/content/_shaders/msl/lit_mesh.frag.msl @@ -24,30 +24,11 @@ struct main0_in fragment main0_out main0(main0_in in [[stage_in]], constant type_Uniforms& Uniforms [[buffer(0)]], texture2d Texture [[texture(0)]], sampler Sampler [[sampler(0)]]) { main0_out out = {}; - float4 _54 = Texture.sample(Sampler, in.in_var_TEXCOORD0); - float3 _57 = float3(0.0, 16.0, -5.0) - in.in_var_TEXCOORD1; - float3 _58 = fast::normalize(_57); - float _73 = length(_57); - float _79; - if (_73 > 2.0) - { - _79 = 0.25 / _73; - } - else - { - _79 = 0.5 / _73; - } - float _84; - if (_73 > 4.0) - { - _84 = _79 * 0.5; - } - else - { - _84 = _79; - } - float _86 = (_73 > 5.0) ? 0.0 : _84; - out.out_var_SV_Target0 = float4(powr(_54.xyz * (float3(0.00200000009499490261077880859375, 0.00200000009499490261077880859375, 0.000600000028498470783233642578125) + (((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * precise::max(dot(_58, in.in_var_TEXCOORD2), 0.0)) * _86) + (((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * powr(precise::max(dot(in.in_var_TEXCOORD2, fast::normalize(_58 + fast::normalize(in.in_var_TEXCOORD1 - float3(Uniforms.viewPos)))), 0.0), 30.0)) * 2.0) * _86))), float3(0.4545454680919647216796875)), _54.w); + float4 _56 = Texture.sample(Sampler, in.in_var_TEXCOORD0); + float3 _59 = float3(0.0, 16.0, -5.0) - in.in_var_TEXCOORD1; + float3 _60 = fast::normalize(_59); + float _76 = 0.5 / length(_59); + out.out_var_SV_Target0 = float4(powr(_56.xyz * (mix(float3(0.00999999977648258209228515625, 0.00999999977648258209228515625, 0.0030000000260770320892333984375), float3(0.0040000001899898052215576171875, 0.0040000001899898052215576171875, 0.0599999986588954925537109375), float3(in.in_var_TEXCOORD2.y)) + (((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * precise::max(dot(_60, in.in_var_TEXCOORD2), 0.0)) * _76) + (((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * powr(precise::max(dot(in.in_var_TEXCOORD2, fast::normalize(_60 + fast::normalize(in.in_var_TEXCOORD1 - float3(Uniforms.viewPos)))), 0.0), 30.0)) * 2.0) * _76))), float3(0.4545454680919647216796875)), _56.w); return out; } diff --git a/projects/content/_shaders/spv/debug.frag.spv b/projects/content/_shaders/spv/debug.frag.spv new file mode 100644 index 0000000..4de2ab7 Binary files /dev/null and b/projects/content/_shaders/spv/debug.frag.spv differ diff --git a/projects/content/_shaders/spv/debug.vert.spv b/projects/content/_shaders/spv/debug.vert.spv new file mode 100644 index 0000000..ea987d8 Binary files /dev/null and b/projects/content/_shaders/spv/debug.vert.spv differ diff --git a/projects/content/_shaders/spv/lit_mesh.frag.spv b/projects/content/_shaders/spv/lit_mesh.frag.spv index 57d6a4f..a77c143 100644 Binary files a/projects/content/_shaders/spv/lit_mesh.frag.spv and b/projects/content/_shaders/spv/lit_mesh.frag.spv differ diff --git a/projects/sampleGame/main.zig b/projects/sampleGame/main.zig index 703dd30..4ca14c4 100644 --- a/projects/sampleGame/main.zig +++ b/projects/sampleGame/main.zig @@ -63,7 +63,8 @@ pub fn prepare(self: *@This()) !void { exitInput.activate(); self.camera = try core.createEntity(); - _ = self.camera.addComponent(core.Scene).?; + const cameraScene = self.camera.addComponent(core.Scene).?; + cameraScene.setPosition(.{ .z = -15 }); const camera = self.camera.addComponent(rend.CameraComponent).?; { @@ -155,6 +156,8 @@ pub fn tick(self: *@This(), dt: f64) void { // core.engine_log(" camera position >> {any}", .{scene.getPosRot().position}); } + core.debugSphere(.{ .y = 0 }, 4, .{}); + var show: bool = true; ig.showDemoWindow(&show);