diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ecs/ecs.zig | 7 | ||||
-rw-r--r-- | src/ecs/entities.zig | 24 | ||||
-rw-r--r-- | src/main.zig | 16 | ||||
-rw-r--r-- | src/renderer/Camera.zig | 10 | ||||
-rw-r--r-- | src/renderer/Renderer.zig | 43 | ||||
-rw-r--r-- | src/renderer/Window.zig | 2 | ||||
-rw-r--r-- | src/renderer/vulkan.zig | 34 |
7 files changed, 79 insertions, 57 deletions
diff --git a/src/ecs/ecs.zig b/src/ecs/ecs.zig index e389223..4ec765f 100644 --- a/src/ecs/ecs.zig +++ b/src/ecs/ecs.zig @@ -1,7 +1,12 @@ pub const components = @import("components.zig"); pub const entities = @import("entities.zig"); +pub const SystemError = error{ + fail, + die, +}; + pub const Pool = entities.Pool; pub const Resources = entities.Resources; -pub const System = *const fn (*Pool) void; +pub const System = *const fn (*Pool) anyerror!void; pub const SystemGroup = []const System; diff --git a/src/ecs/entities.zig b/src/ecs/entities.zig index b50055e..fc573ce 100644 --- a/src/ecs/entities.zig +++ b/src/ecs/entities.zig @@ -4,14 +4,17 @@ const components = @import("components.zig"); const sparse = @import("sparse.zig"); const Renderer = @import("renderer"); const Input = @import("sideros").Input; +const ecs = @import("ecs.zig"); -pub const System = *const fn (*Pool) void; +pub const System = ecs.System; pub const SystemGroup = []const System; +pub const SyncGroup = []const System; pub const Resources = struct { window: Renderer.Window, renderer: Renderer, input: Input, + delta_time: f64 = 0.0, }; pub const Human = struct { @@ -24,6 +27,7 @@ pub const Pool = struct { resources: Resources, allocator: Allocator, system_groups: std.ArrayList(SystemGroup), + sync_groups: std.ArrayList(SyncGroup), thread_pool: *std.Thread.Pool, wait_group: std.Thread.WaitGroup, mutex: std.Thread.Mutex, @@ -33,6 +37,7 @@ pub const Pool = struct { .humans = .{}, .resources = resources, .system_groups = std.ArrayList(SystemGroup).init(allocator), + .sync_groups = std.ArrayList(SystemGroup).init(allocator), .thread_pool = try allocator.create(std.Thread.Pool), .wait_group = .{}, .mutex = .{}, @@ -47,8 +52,12 @@ pub const Pool = struct { return pool; } - pub fn addSystemGroup(self: *@This(), group: SystemGroup) !void { - try self.system_groups.append(group); + pub fn addSystemGroup(self: *@This(), group: SystemGroup, sync: bool) !void { + if (sync) { + try self.sync_groups.append(group); + } else { + try self.system_groups.append(group); + } } pub fn deinit(self: *@This()) void { @@ -65,11 +74,18 @@ pub const Pool = struct { fn run(pool: *Pool, index: usize) void { const group = pool.system_groups.items[index]; for (group) |system| { - system(pool); + // TODO: system errors should be correctly handled + system(pool) catch unreachable; } } }.run, .{ self, i }); } + for (0..self.sync_groups.items.len) |i| { + const group = self.sync_groups.items[i]; + for (group) |system| { + system(self) catch unreachable; + } + } } fn getEntities(self: *@This(), T: type) *std.MultiArrayList(T) { diff --git a/src/main.zig b/src/main.zig index 289806d..dffaa4d 100644 --- a/src/main.zig +++ b/src/main.zig @@ -40,8 +40,8 @@ pub fn main() !void { var w = try Renderer.Window.create(800, 600, "sideros"); defer w.destroy(); - var r = try Renderer.create(allocator, w); - defer r.destroy(); + var r = try Renderer.init(allocator, w); + defer r.deinit(); const resources = ecs.Resources{ .window = w, @@ -52,9 +52,9 @@ pub fn main() !void { var pool = try ecs.Pool.init(allocator, resources); defer pool.deinit(); w.setResources(&pool.resources); - //try pool.addSystemGroup(&[_]entities.System{ - // testSystem, - //}); + try pool.addSystemGroup(&[_]ecs.System{ + Renderer.render, + }, true); // try pool.addSystemGroup(&[_]ecs.System{ // testSystem2, // }); @@ -64,10 +64,12 @@ pub fn main() !void { // try pool.addComponent(entity, ecs.components.Position{ .x = 1.0, .y = 0.5, .z = 3.0 }); // try pool.addComponent(entity, ecs.components.Speed{ .speed = 5.0 }); // } - + var last_time: f64 = 0.0; while (!w.shouldClose()) { + const current_time = Renderer.Window.getTime(); + pool.resources.delta_time = current_time - last_time; + last_time = current_time; Renderer.Window.pollEvents(); - try r.tick(); pool.tick(); } } diff --git a/src/renderer/Camera.zig b/src/renderer/Camera.zig index 9ab305c..31620e8 100644 --- a/src/renderer/Camera.zig +++ b/src/renderer/Camera.zig @@ -1,6 +1,8 @@ const std = @import("std"); const ecs = @import("ecs"); -const math = @import("../math.zig"); +const sideros = @import("sideros"); +const math = sideros.math; + const Camera = @This(); const UP = @Vector(3, f32){ 0.0, 1.0, 0.0 }; @@ -19,15 +21,15 @@ front: @Vector(3, f32), up: @Vector(3, f32), speed: f32 = 2.5, -fn getProjection(width: usize, height: usize) math.Matrix { +pub fn getProjection(width: usize, height: usize) math.Matrix { return math.Matrix.perspective(math.rad(45.0), (@as(f32, @floatFromInt(width)) / @as(f32, @floatFromInt(height))), 0.1, 10.0); } -fn getView(self: Camera) math.Matrix { +pub fn getView(self: Camera) math.Matrix { math.lookAt(self.position, self.position + self.front, self.up); } -fn moveCamera(pool: *ecs.Pool) void { +pub fn moveCamera(pool: *ecs.Pool) void { const input = pool.resources.input; const camera = pool.resources.camera; if (input.isKeyDown(.w)) { diff --git a/src/renderer/Renderer.zig b/src/renderer/Renderer.zig index a195751..774b13e 100644 --- a/src/renderer/Renderer.zig +++ b/src/renderer/Renderer.zig @@ -1,4 +1,5 @@ const c = @import("c.zig"); +const ecs = @import("ecs"); const std = @import("std"); const vk = @import("vulkan.zig"); pub const Window = @import("Window.zig"); @@ -18,7 +19,7 @@ current_frame: u32, vertex_buffer: vk.Buffer, index_buffer: vk.Buffer, -pub fn create(allocator: Allocator, w: Window) !Renderer { +pub fn init(allocator: Allocator, w: Window) !Renderer { const instance = try vk.Instance.create(allocator); const surface = try vk.Surface.create(instance, w); @@ -61,7 +62,7 @@ pub fn create(allocator: Allocator, w: Window) !Renderer { }; } -pub fn destroy(self: Renderer) void { +pub fn deinit(self: Renderer) void { self.device.waitIdle(); self.index_buffer.destroy(self.device.handle); self.vertex_buffer.destroy(self.device.handle); @@ -73,22 +74,24 @@ pub fn destroy(self: Renderer) void { self.instance.destroy(); } -// TODO: tick is maybe a bad name? something like present() or submit() is better? -pub fn tick(self: *Renderer) !void { - try self.device.waitFence(self.current_frame); - const image = try self.swapchain.nextImage(self.device, self.current_frame); - try self.device.resetCommand(self.current_frame); - try self.device.beginCommand(self.current_frame); - self.render_pass.begin(self.swapchain, self.device, image, self.current_frame); - self.graphics_pipeline.bind(self.device, self.current_frame); - self.device.bindVertexBuffer(self.vertex_buffer, self.current_frame); - self.device.bindIndexBuffer(self.index_buffer, self.current_frame); - self.device.bindDescriptorSets(self.graphics_pipeline, self.current_frame); - self.device.draw(@intCast(self.index_buffer.size / @sizeOf(u16)), self.current_frame); - self.render_pass.end(self.device, self.current_frame); - try self.device.endCommand(self.current_frame); - - try self.device.submit(self.swapchain, image, self.current_frame); - - self.current_frame = (self.current_frame + 1) % 2; +// TODO: render is maybe a bad name? something like present() or submit() is better? +pub fn render(pool: *ecs.Pool) anyerror!void { + var renderer = pool.resources.renderer; + + try renderer.device.waitFence(renderer.current_frame); + const image = try renderer.swapchain.nextImage(renderer.device, renderer.current_frame); + try renderer.device.resetCommand(renderer.current_frame); + try renderer.device.beginCommand(renderer.current_frame); + renderer.render_pass.begin(renderer.swapchain, renderer.device, image, renderer.current_frame); + renderer.graphics_pipeline.bind(renderer.device, renderer.current_frame); + renderer.device.bindVertexBuffer(renderer.vertex_buffer, renderer.current_frame); + renderer.device.bindIndexBuffer(renderer.index_buffer, renderer.current_frame); + renderer.device.bindDescriptorSets(renderer.graphics_pipeline, renderer.current_frame); + renderer.device.draw(@intCast(renderer.index_buffer.size / @sizeOf(u16)), renderer.current_frame); + renderer.render_pass.end(renderer.device, renderer.current_frame); + try renderer.device.endCommand(renderer.current_frame); + + try renderer.device.submit(renderer.swapchain, image, renderer.current_frame); + + renderer.current_frame = (renderer.current_frame + 1) % 2; } diff --git a/src/renderer/Window.zig b/src/renderer/Window.zig index bc8f83b..528ac44 100644 --- a/src/renderer/Window.zig +++ b/src/renderer/Window.zig @@ -74,7 +74,7 @@ pub fn destroy(self: Window) void { c.glfwTerminate(); } -pub fn getTime() f32 { +pub fn getTime() f64 { return c.glfwGetTime(); } diff --git a/src/renderer/vulkan.zig b/src/renderer/vulkan.zig index 1f878f9..6a7b73b 100644 --- a/src/renderer/vulkan.zig +++ b/src/renderer/vulkan.zig @@ -3,6 +3,7 @@ const c = @import("c.zig"); const Window = @import("Window.zig"); const Mesh = @import("Mesh.zig"); const sideros = @import("sideros"); +const Camera = @import("Camera.zig"); const math = sideros.math; const Allocator = std.mem.Allocator; @@ -302,7 +303,7 @@ pub fn GraphicsPipeline(comptime n: usize) type { descriptor_pool: c.VkDescriptorPool, descriptor_set: c.VkDescriptorSet, descriptor_set_layout: c.VkDescriptorSetLayout, - uniform_buffer: Buffer, + projection_buffer: Buffer, const Self = @This(); @@ -486,36 +487,25 @@ pub fn GraphicsPipeline(comptime n: usize) type { try mapError(c.vkAllocateDescriptorSets(device.handle, &descriptor_allocate_info, &descriptor_set)); - const proj = math.Matrix.perspective(math.rad(45.0), (@as(f32, @floatFromInt(swapchain.extent.width)) / @as(f32, @floatFromInt(swapchain.extent.height))), 0.1, 10.0); - - const view = math.Matrix.lookAt(@Vector(3, f32){ 0.0, 0.0, 10.0 }, @Vector(3, f32){ 0.0, 0.0, 0.0 }, @Vector(3, f32){ 0.0, 1.0, 0.0 }); - const model = math.Matrix.identity(); - - const uniform = Uniform{ - .proj = proj, - .view = view, - .model = model, - }; - - const uniform_buffer = try device.createBuffer(BufferUsage{ .uniform_buffer = true, .transfer_dst = true }, BufferFlags{ .device_local = true }, @sizeOf(Uniform)); + const projection_buffer = try device.createBuffer(BufferUsage{ .uniform_buffer = true, .transfer_dst = true }, BufferFlags{ .device_local = true }, @sizeOf(math.Matrix)); var data: [*c]u8 = undefined; try mapError(c.vkMapMemory( device.handle, - uniform_buffer.memory, + projection_buffer.memory, 0, - uniform_buffer.size, + projection_buffer.size, 0, @ptrCast(&data), )); - @memcpy(data[0..(@sizeOf(math.Matrix) * 3)], std.mem.asBytes(&uniform)); + @memcpy(data[0..@sizeOf(math.Matrix)], std.mem.asBytes(&Camera.getProjection(swapchain.extent.width, swapchain.extent.height))); const descriptor_buffer_info = c.VkDescriptorBufferInfo{ - .buffer = uniform_buffer.handle, + .buffer = projection_buffer.handle, .offset = 0, - .range = uniform_buffer.size, + .range = projection_buffer.size, }; const write_descriptor_set = c.VkWriteDescriptorSet{ @@ -536,7 +526,7 @@ pub fn GraphicsPipeline(comptime n: usize) type { .descriptor_pool = descriptor_pool, .descriptor_set = descriptor_set, .descriptor_set_layout = descriptor_set_layout, - .uniform_buffer = uniform_buffer, + .projection_buffer = projection_buffer, }; } @@ -546,7 +536,7 @@ pub fn GraphicsPipeline(comptime n: usize) type { } pub fn destroy(self: Self, device: Device(n)) void { - self.uniform_buffer.destroy(device.handle); + self.projection_buffer.destroy(device.handle); c.vkDestroyDescriptorSetLayout(device.handle, self.descriptor_set_layout, null); c.vkDestroyDescriptorPool(device.handle, self.descriptor_pool, null); c.vkDestroyPipeline(device.handle, self.handle, null); @@ -871,6 +861,10 @@ pub fn Device(comptime n: usize) type { c.vkCmdBindDescriptorSets(self.command_buffers[frame], c.VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.layout, 0, 1, &pipeline.descriptor_set, 0, null); } + pub fn updateBuffer(self: Self, comptime T: type, buffer: Buffer, data: [*]T, frame: usize) void { + c.vkCmdUpdateBuffer(self.command_buffers[frame], buffer.handle, 0, @sizeOf(T), @ptrCast(@alignCast(data))); + } + pub fn pick_memory_type(self: Self, type_bits: u32, flags: u32) u32 { var memory_type_index: u32 = 0; for (0..self.memory_properties.memoryTypeCount) |index| { |