diff --git a/README.md b/README.md index 87a2acb..11e8408 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ paru -S --needed sdl3 wgpu-native - [x] Device - [x] Cache - [ ] Renderer +- [ ] Hot Reloading ### Engine - [ ] ClassDB diff --git a/src/plugins/cache/resource/embeded/shaders/pbr.wgsl b/src/plugins/cache/resource/embeded/shaders/pbr.wgsl index 574617b..438d60b 100644 --- a/src/plugins/cache/resource/embeded/shaders/pbr.wgsl +++ b/src/plugins/cache/resource/embeded/shaders/pbr.wgsl @@ -1,19 +1,11 @@ @vertex fn vs_main( - @builtin(vertex_index) in_vertex_index: u32 + @location(0) in_vertex_position: vec2f ) -> @builtin(position) vec4f { - var p = vec2f(0.0, 0.0); - if in_vertex_index == 0u { - p = vec2f(-0.5, -0.5); - } else if in_vertex_index == 1u { - p = vec2f(0.5, -0.5); - } else { - p = vec2f(0.0, 0.5); - } - return vec4f(p, 0.0, 1.0); + return vec4f(in_vertex_position, 0.0, 1.0); } @fragment fn fs_main() -> @location(0) vec4f { - return vec4f(0.0, 0.4, 1.0, 1.0); + return vec4f(0.001, 0.001, 0.001, 1.0); } diff --git a/src/plugins/cache/resource/mesh_cache.zig b/src/plugins/cache/resource/mesh_cache.zig new file mode 100644 index 0000000..526dc4d --- /dev/null +++ b/src/plugins/cache/resource/mesh_cache.zig @@ -0,0 +1,118 @@ +//! ---------------------------------------------------- +//! ---------------------------------------------------- + +const std = @import("std"); +const gtl = @import("gtl"); +const wgpu = @import("wgpu"); +const Self = @This(); + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub const Vertex = struct { + position: @Vector(3, f32), + normal: @Vector(3, f32), + uv: @Vector(2, f32), +}; + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub const MeshID = union(enum) { + cube, + quad, + square, + triangle, + custom: u32, // TODO: idk, someday +}; + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub const GPUMesh = struct { + vbuf: *wgpu.WGPUBufferImpl, + ibuf: ?*wgpu.WGPUBufferImpl = null, +}; + +// +// FIELDS +// + +data: gtl.KeyedSlotMap(MeshID, GPUMesh), +device: *wgpu.WGPUDeviceImpl, +queue: *wgpu.WGPUQueueImpl, +alloc: std.mem.Allocator, + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub fn init( + device: *wgpu.WGPUDeviceImpl, + queue: *wgpu.WGPUQueueImpl, + alloc: std.mem.Allocator, +) Self { + return .{ + .data = .init(alloc), + .device = device, + .queue = queue, + .alloc = alloc, + }; +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub fn deinit(self: *Self) void { + // --- FREE BUFFERS --- + for (self.data.items()) |entry| { + wgpu.wgpuBufferRelease(entry.value.vbuf); + + if (entry.value.ibuf) |ibuf| { + wgpu.wgpuBufferRelease(ibuf); + } + } + + // --- # --- + self.data.deinit(); +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub fn getOrCreate( + self: *Self, + mesh: MeshID, +) !*GPUMesh { + return try self.data.getOrPut(mesh, .{ + .vbuf = blk: { + // --- DATA --- + const vertices: []const f32 = switch (mesh) { + .triangle => &.{ + -0.5, -0.5, + 0.5, -0.5, + 0.0, 0.5, + }, + .square => &.{ + -0.5, -0.5, + 0.5, -0.5, + 0.5, 0.5, + + -0.5, -0.5, + 0.5, 0.5, + -0.5, 0.5, + }, + else => &.{}, + }; + + // --- GET SIZE --- + const size = vertices.len * @sizeOf(f32); + + // --- CREATE --- + const buff = wgpu.wgpuDeviceCreateBuffer(self.device, &wgpu.WGPUBufferDescriptor{ + .size = size, + .usage = wgpu.WGPUBufferUsage_CopyDst | wgpu.WGPUBufferUsage_Vertex, + }) orelse return error.FailedToCreateBuffer; + + // --- WRITE --- + wgpu.wgpuQueueWriteBuffer(self.queue, buff, 0, vertices.ptr, size); + + // --- RESULT --- + break :blk buff; + }, + .ibuf = null, + }); +} diff --git a/src/plugins/cache/resource/pipeline_cache.zig b/src/plugins/cache/resource/pipeline_cache.zig index 0f6cee2..4833679 100644 --- a/src/plugins/cache/resource/pipeline_cache.zig +++ b/src/plugins/cache/resource/pipeline_cache.zig @@ -82,13 +82,24 @@ fn createPipeline( .vertex = .{ .module = shader_module.raw, .entryPoint = .{ .data = "vs_main", .length = wgpu.WGPU_STRLEN }, + .bufferCount = 1, + .buffers = &wgpu.WGPUVertexBufferLayout{ + .attributeCount = 1, + .attributes = &wgpu.WGPUVertexAttribute{ // TODO: Use Vertex attributes instead | Mabe mabe allow for custom, mabe mabe later tho + .shaderLocation = 0, + .format = wgpu.WGPUVertexFormat_Float32x2, + .offset = 0, + }, + .arrayStride = 2 * @sizeOf(f32), + .stepMode = wgpu.WGPUVertexStepMode_Vertex, + }, }, .fragment = &wgpu.WGPUFragmentState{ .module = shader_module.raw, .entryPoint = .{ .data = "fs_main", .length = wgpu.WGPU_STRLEN }, .targetCount = 1, .targets = &wgpu.WGPUColorTargetState{ - .format = 28, + .format = 28, // FIX: Use proper format .blend = &wgpu.WGPUBlendState{ .color = .{ .srcFactor = wgpu.WGPUBlendFactor_SrcAlpha, diff --git a/src/plugins/cache/root.zig b/src/plugins/cache/root.zig index 8b17205..90761a2 100644 --- a/src/plugins/cache/root.zig +++ b/src/plugins/cache/root.zig @@ -14,6 +14,7 @@ const lifetime = @import("system/lifetime.zig"); pub const ShaderCache = @import("resource/shader_cache.zig"); pub const PipelineCache = @import("resource/pipeline_cache.zig"); +pub const MeshCache = @import("resource/mesh_cache.zig"); /// ---------------------------------------------------- /// ---------------------------------------------------- diff --git a/src/plugins/cache/system/lifetime.zig b/src/plugins/cache/system/lifetime.zig index 8ec9066..681099f 100644 --- a/src/plugins/cache/system/lifetime.zig +++ b/src/plugins/cache/system/lifetime.zig @@ -5,8 +5,10 @@ const std = @import("std"); const gtl = @import("gtl"); const App = @import("app"); const WGPUDevice = @import("../../device/resource/wgpu_device.zig"); + const ShaderCache = @import("../resource/shader_cache.zig"); const PipelineCache = @import("../resource/pipeline_cache.zig"); +const MeshCache = @import("../resource/mesh_cache.zig"); /// ---------------------------------------------------- /// ---------------------------------------------------- @@ -30,6 +32,16 @@ pub fn init(app: *App) !void { app.alloc, )); + // --- MESH CACHE --- + const meshes = try app.resources.getOrSet(MeshCache.init( + res.device.raw, + res.device.queue, + app.alloc, + )); + // _ = meshes; + + _ = try meshes.getOrCreate(.cube); + // TODO: Remove or place it somewhere else, idk // --- TEST --- @@ -84,9 +96,11 @@ pub fn deinit(app: *App) !void { const res = try app.resources.getMany(struct { shaders: *ShaderCache, pipelines: *PipelineCache, + meshes: *MeshCache, }); // --- # --- res.shaders.deinit(); res.pipelines.deinit(); + res.meshes.deinit(); } diff --git a/src/plugins/common/component/mesh.zig b/src/plugins/common/component/mesh.zig new file mode 100644 index 0000000..00a25f9 --- /dev/null +++ b/src/plugins/common/component/mesh.zig @@ -0,0 +1,3 @@ +const MeshID = @import("../../cache/resource/mesh_cache.zig").MeshID; + +value: MeshID, diff --git a/src/plugins/common/component/transform2D.zig b/src/plugins/common/component/transform2D.zig new file mode 100644 index 0000000..0708cb6 --- /dev/null +++ b/src/plugins/common/component/transform2D.zig @@ -0,0 +1,3 @@ +position: @Vector(2, f32) = .{ 0, 0 }, +scale: @Vector(2, f32) = .{ 32, 32 }, +angle: f32 = 0, diff --git a/src/plugins/common/component/transform3D.zig b/src/plugins/common/component/transform3D.zig new file mode 100644 index 0000000..e3423f6 --- /dev/null +++ b/src/plugins/common/component/transform3D.zig @@ -0,0 +1,3 @@ +position: @Vector(3, f32) = .{ 0, 0, 0 }, +rotation: @Vector(3, f32) = .{ 0, 0, 0 }, +scale: @Vector(3, f32) = .{ 1, 1, 1 }, diff --git a/src/plugins/common/root.zig b/src/plugins/common/root.zig index 04a5598..e52a1ae 100644 --- a/src/plugins/common/root.zig +++ b/src/plugins/common/root.zig @@ -5,4 +5,10 @@ // COMPONENTS // +// --- POSITION --- +pub const Transform3D = @import("component/transform3D.zig"); +pub const Transform2D = @import("component/transform2D.zig"); + +// --- STYLE --- pub const Material = @import("component/material.zig"); +pub const Mesh = @import("component/mesh.zig"); diff --git a/src/plugins/renderer/resource/renderer.zig b/src/plugins/renderer/resource/renderer.zig index 4c3d3c3..3b3dec8 100644 --- a/src/plugins/renderer/resource/renderer.zig +++ b/src/plugins/renderer/resource/renderer.zig @@ -4,23 +4,23 @@ const std = @import("std"); const gtl = @import("gtl"); const Material = @import("../../common/component/material.zig"); +const Mesh = @import("../../cache/resource/mesh_cache.zig").MeshID; const Handle = gtl.Handle; const Self = @This(); // TODO: -const Mesh = struct {}; const Camera = struct {}; /// ---------------------------------------------------- /// ---------------------------------------------------- pub const DrawCMD = union(enum) { draw: struct { - mesh: Handle(Mesh), + mesh: Mesh, material: Material.Unique, }, draw_indexed: struct { - mesh: Handle(Mesh), + mesh: Mesh, material: Material.Unique, }, diff --git a/src/plugins/renderer/system/frame.zig b/src/plugins/renderer/system/frame.zig index 0d0d1cf..2e343db 100644 --- a/src/plugins/renderer/system/frame.zig +++ b/src/plugins/renderer/system/frame.zig @@ -16,19 +16,22 @@ pub fn begin(app: *App) !void { res.renderer.clear(); { // TEST + // --- DRAW --- try res.renderer.draw(.{ .begin_pass = .{ .camera = undefined, - .color = .{ 0.2, 0.8, 0.2, 1.0 }, + .color = .{ 0.08, 0.08, 0.8, 1.0 }, }, }); + defer res.renderer.draw(.end_pass) catch unreachable; + + // --- # --- try res.renderer.draw(.{ .draw = .{ - .mesh = undefined, + .mesh = .square, .material = .{}, }, }); - try res.renderer.draw(.end_pass); } } diff --git a/src/plugins/renderer/system/present.zig b/src/plugins/renderer/system/present.zig index b70536f..d20972e 100644 --- a/src/plugins/renderer/system/present.zig +++ b/src/plugins/renderer/system/present.zig @@ -9,6 +9,7 @@ const Window = @import("../../window/resource/window.zig"); const Device = @import("../../device/resource/wgpu_device.zig"); const Renderer = @import("../resource/renderer.zig"); const PipelineCache = @import("../../cache/resource/pipeline_cache.zig"); +const MeshCache = @import("../../cache/resource/mesh_cache.zig"); /// ---------------------------------------------------- /// ---------------------------------------------------- @@ -19,6 +20,7 @@ pub fn draw(app: *App) !void { device: *Device, renderer: *Renderer, pipeline_cache: *PipelineCache, + mesh_cache: *MeshCache, }); // --- SURFACE TEXTURE --- @@ -91,14 +93,14 @@ pub fn draw(app: *App) !void { } }, .draw => |v| { - // --- ENSURE PIPELINE --- - const pipeline = try res.pipeline_cache.getOrCreate( - v.material, - ); + // --- ENSURE --- + const pipeline = try res.pipeline_cache.getOrCreate(v.material); + const mesh = try res.mesh_cache.getOrCreate(v.mesh); // --- DRAW --- wgpu.wgpuRenderPassEncoderSetPipeline(render_pass, pipeline.raw); - wgpu.wgpuRenderPassEncoderDraw(render_pass, 3, 1, 0, 0); + wgpu.wgpuRenderPassEncoderSetVertexBuffer(render_pass, 0, mesh.vbuf, 0, wgpu.wgpuBufferGetSize(mesh.vbuf)); + wgpu.wgpuRenderPassEncoderDraw(render_pass, @intCast(wgpu.wgpuBufferGetSize(mesh.vbuf) / (2 * @sizeOf(f32))), 1, 0, 0); }, else => {}, }