summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assets/shaders/shader.vert6
-rw-r--r--build.zig1
-rw-r--r--src/ecs/ecs.zig7
-rw-r--r--src/ecs/entities.zig24
-rw-r--r--src/main.zig16
-rw-r--r--src/renderer/Camera.zig10
-rw-r--r--src/renderer/Renderer.zig43
-rw-r--r--src/renderer/Window.zig2
-rw-r--r--src/renderer/vulkan.zig34
9 files changed, 82 insertions, 61 deletions
diff --git a/assets/shaders/shader.vert b/assets/shaders/shader.vert
index f5353e3..c759755 100644
--- a/assets/shaders/shader.vert
+++ b/assets/shaders/shader.vert
@@ -2,12 +2,10 @@
layout(location = 0) in vec3 vertPos;
-layout(binding = 0) uniform UniformObject {
+layout (binding = 0) uniform Uniform {
mat4 proj;
- mat4 view;
- mat4 model;
} ubo;
void main() {
- gl_Position = ubo.view * ubo.proj * vec4(vertPos, 1.0);
+ gl_Position = ubo.proj * vec4(vertPos, 1.0);
}
diff --git a/build.zig b/build.zig
index 399286f..c398bd4 100644
--- a/build.zig
+++ b/build.zig
@@ -118,6 +118,7 @@ pub fn build(b: *std.Build) void {
.root_module = mods,
.name = "mods",
});
+
const mods_docs = b.addInstallDirectory(.{
.source_dir = mods_lib.getEmittedDocs(),
.install_dir = .prefix,
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| {