Made Renderer a separate module
This commit is contained in:
parent
09691ec4d9
commit
1730f1e298
14 changed files with 292 additions and 260 deletions
30
build.zig
30
build.zig
|
|
@ -55,17 +55,28 @@ pub fn build(b: *std.Build) void {
|
|||
}, .flags = &[_][]const u8{ "-D_GLFW_X11", "-Wall", "-Wextra" } });
|
||||
glfw.linkLibC();
|
||||
|
||||
const sideros = b.addModule("sideros", .{
|
||||
.root_source_file = b.path("src/sideros.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
const mods = b.addModule("mods", .{
|
||||
.root_source_file = b.path("src/mods/mods.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
mods.addImport("sideros", sideros);
|
||||
|
||||
const ecs = b.addModule("ecs", .{
|
||||
.root_source_file = b.path("src/ecs/ecs.zig"),
|
||||
const renderer = b.addModule("renderer", .{
|
||||
.root_source_file = b.path("src/renderer/Renderer.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
renderer.addImport("sideros", sideros);
|
||||
|
||||
renderer.addIncludePath(b.path("ext/glfw/include"));
|
||||
compileAllShaders(b, renderer);
|
||||
|
||||
const exe = b.addExecutable(.{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
|
|
@ -74,11 +85,10 @@ pub fn build(b: *std.Build) void {
|
|||
.name = "sideros",
|
||||
});
|
||||
exe.root_module.addImport("mods", mods);
|
||||
exe.root_module.addImport("ecs", ecs);
|
||||
exe.addIncludePath(b.path("ext/glfw/include"));
|
||||
exe.root_module.addImport("sideros", sideros);
|
||||
exe.root_module.addImport("renderer", renderer);
|
||||
|
||||
exe.linkSystemLibrary("vulkan");
|
||||
compileAllShaders(b, exe);
|
||||
exe.linkLibrary(glfw);
|
||||
exe.linkLibC();
|
||||
|
||||
|
|
@ -127,7 +137,7 @@ pub fn build(b: *std.Build) void {
|
|||
test_step.dependOn(&run_exe_unit_tests.step);
|
||||
}
|
||||
|
||||
fn compileAllShaders(b: *std.Build, exe: *std.Build.Step.Compile) void {
|
||||
fn compileAllShaders(b: *std.Build, module: *std.Build.Module) void {
|
||||
const shaders_dir = if (@hasDecl(@TypeOf(b.build_root.handle), "openIterableDir"))
|
||||
b.build_root.handle.openIterableDir("assets/shaders", .{}) catch @panic("Failed to open shaders directory")
|
||||
else
|
||||
|
|
@ -140,15 +150,15 @@ fn compileAllShaders(b: *std.Build, exe: *std.Build.Step.Compile) void {
|
|||
const basename = std.fs.path.basename(entry.name);
|
||||
const name = basename[0 .. basename.len - ext.len];
|
||||
if (std.mem.eql(u8, ext, ".vert")) {
|
||||
addShader(b, exe, name, .vertex);
|
||||
addShader(b, module, name, .vertex);
|
||||
} else if (std.mem.eql(u8, ext, ".frag")) {
|
||||
addShader(b, exe, name, .fragment);
|
||||
addShader(b, module, name, .fragment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn addShader(b: *std.Build, exe: *std.Build.Step.Compile, name: []const u8, stage: ShaderStage) void {
|
||||
fn addShader(b: *std.Build, module: *std.Build.Module, name: []const u8, stage: ShaderStage) void {
|
||||
const mod_name = std.fmt.allocPrint(b.allocator, "{s}_{s}", .{ name, if (stage == .vertex) "vert" else "frag" }) catch @panic("");
|
||||
const source = std.fmt.allocPrint(b.allocator, "assets/shaders/{s}.{s}", .{ name, if (stage == .vertex) "vert" else "frag" }) catch @panic("");
|
||||
const outpath = std.fmt.allocPrint(b.allocator, "assets/shaders/{s}_{s}.spv", .{ name, if (stage == .vertex) "vert" else "frag" }) catch @panic("");
|
||||
|
|
@ -158,5 +168,5 @@ fn addShader(b: *std.Build, exe: *std.Build.Step.Compile, name: []const u8, stag
|
|||
const output = shader_compilation.addOutputFileArg(outpath);
|
||||
shader_compilation.addFileArg(b.path(source));
|
||||
|
||||
exe.root_module.addAnonymousImport(mod_name, .{ .root_source_file = output });
|
||||
module.addAnonymousImport(mod_name, .{ .root_source_file = output });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,5 +2,6 @@ pub const components = @import("components.zig");
|
|||
const entities = @import("entities.zig");
|
||||
|
||||
pub const Pool = entities.Pool;
|
||||
pub const Resources = entities.Resources;
|
||||
pub const System = *const fn (*Pool) void;
|
||||
pub const SystemGroup = []const System;
|
||||
|
|
|
|||
|
|
@ -2,15 +2,21 @@ const std = @import("std");
|
|||
const Allocator = std.mem.Allocator;
|
||||
const components = @import("components.zig");
|
||||
const sparse = @import("sparse.zig");
|
||||
const Renderer = @import("renderer");
|
||||
|
||||
pub const System = *const fn (*Pool) void;
|
||||
pub const SystemGroup = []const System;
|
||||
|
||||
pub const Resources = struct {
|
||||
window: Renderer.Window,
|
||||
renderer: Renderer,
|
||||
};
|
||||
|
||||
pub const Pool = struct {
|
||||
// Components
|
||||
position: sparse.SparseSet(components.Position),
|
||||
speed: sparse.SparseSet(components.Speed),
|
||||
|
||||
resources: Resources,
|
||||
system_groups: std.ArrayList(SystemGroup),
|
||||
thread_pool: *std.Thread.Pool,
|
||||
wait_group: std.Thread.WaitGroup,
|
||||
|
|
@ -20,11 +26,11 @@ pub const Pool = struct {
|
|||
|
||||
component_flags: std.AutoHashMap(usize, usize),
|
||||
|
||||
pub fn init(allocator: Allocator) !@This() {
|
||||
pub fn init(allocator: Allocator, resources: Resources) !@This() {
|
||||
var pool = @This(){
|
||||
.position = sparse.SparseSet(components.Position).init(allocator),
|
||||
.speed = sparse.SparseSet(components.Speed).init(allocator),
|
||||
|
||||
.resources = resources,
|
||||
.system_groups = std.ArrayList(SystemGroup).init(allocator),
|
||||
.thread_pool = try allocator.create(std.Thread.Pool),
|
||||
.wait_group = .{},
|
||||
|
|
|
|||
88
src/main.zig
88
src/main.zig
|
|
@ -1,13 +1,10 @@
|
|||
const std = @import("std");
|
||||
const c = @import("c.zig");
|
||||
const window = @import("rendering/window.zig");
|
||||
|
||||
const config = @import("config");
|
||||
const Renderer = @import("rendering/renderer_vulkan.zig");
|
||||
const math = @import("math.zig");
|
||||
const math = @import("sideros").math;
|
||||
const mods = @import("mods");
|
||||
const ecs = @import("ecs");
|
||||
const gltf = @import("rendering/gltf.zig");
|
||||
const ecs = @import("ecs/ecs.zig");
|
||||
pub const Renderer = @import("renderer");
|
||||
|
||||
fn testSystem2(pool: *ecs.Pool) void {
|
||||
for (pool.getQuery(ecs.components.Position), 0..) |position, i| {
|
||||
|
|
@ -23,52 +20,47 @@ pub fn main() !void {
|
|||
const allocator = gpa.allocator();
|
||||
defer if (gpa.deinit() != .ok) @panic("Leaked memory");
|
||||
|
||||
var global_runtime = mods.GlobalRuntime.init(allocator);
|
||||
defer global_runtime.deinit();
|
||||
try global_runtime.addFunction("debug", mods.Wasm.debug);
|
||||
//var global_runtime = mods.GlobalRuntime.init(allocator);
|
||||
//defer global_runtime.deinit();
|
||||
//try global_runtime.addFunction("debug", mods.Wasm.debug);
|
||||
|
||||
const file = try std.fs.cwd().openFile("assets/core.wasm", .{});
|
||||
const all = try file.readToEndAlloc(allocator, 1_000_000); // 1 MB
|
||||
var parser = mods.Parser{
|
||||
.bytes = all,
|
||||
.byte_idx = 0,
|
||||
.allocator = allocator,
|
||||
};
|
||||
const module = parser.parseModule() catch |err| {
|
||||
std.debug.print("[ERROR]: error at byte {x}(0x{x})\n", .{ parser.byte_idx, parser.bytes[parser.byte_idx] });
|
||||
return err;
|
||||
};
|
||||
var runtime = try mods.Runtime.init(allocator, module, &global_runtime);
|
||||
defer runtime.deinit(allocator);
|
||||
//const file = try std.fs.cwd().openFile("assets/core.wasm", .{});
|
||||
//const all = try file.readToEndAlloc(allocator, 1_000_000); // 1 MB
|
||||
//var parser = mods.Parser{
|
||||
// .bytes = all,
|
||||
// .byte_idx = 0,
|
||||
// .allocator = allocator,
|
||||
//};
|
||||
//const module = parser.parseModule() catch |err| {
|
||||
// std.debug.print("[ERROR]: error at byte {x}(0x{x})\n", .{ parser.byte_idx, parser.bytes[parser.byte_idx] });
|
||||
// return err;
|
||||
//};
|
||||
//var runtime = try mods.Runtime.init(allocator, module, &global_runtime);
|
||||
//defer runtime.deinit(allocator);
|
||||
|
||||
var parameters = [_]usize{};
|
||||
try runtime.callExternal(allocator, "preinit", ¶meters);
|
||||
const w = try window.Window.create(800, 600, "sideros");
|
||||
//var parameters = [_]usize{};
|
||||
//try runtime.callExternal(allocator, "preinit", ¶meters);
|
||||
const w = try Renderer.Window.create(800, 600, "sideros");
|
||||
defer w.destroy();
|
||||
|
||||
// var pool = try ecs.Pool.init(allocator);
|
||||
// defer pool.deinit(allocator);
|
||||
|
||||
//try pool.addSystemGroup(&[_]entities.System{
|
||||
// testSystem,
|
||||
//});
|
||||
// try pool.addSystemGroup(&[_]ecs.System{
|
||||
// testSystem2,
|
||||
// });
|
||||
|
||||
// for (0..1000) |_| {
|
||||
// const entity = try pool.createEntity();
|
||||
// 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 });
|
||||
// }
|
||||
|
||||
// TODO(luccie-cmd): Renderer.create shouldn't return an error
|
||||
// var r = try Renderer.create(allocator, w);
|
||||
// defer r.destroy();
|
||||
var r = try Renderer.create(allocator, w);
|
||||
defer r.destroy();
|
||||
|
||||
// while (!w.shouldClose()) {
|
||||
// c.glfwPollEvents();
|
||||
// try r.tick();
|
||||
// pool.tick();
|
||||
// }
|
||||
const resources = ecs.Resources{
|
||||
.window = w,
|
||||
.renderer = r,
|
||||
};
|
||||
|
||||
var pool = try ecs.Pool.init(allocator, resources);
|
||||
defer pool.deinit(allocator);
|
||||
|
||||
try pool.addSystemGroup(&[_]ecs.System{
|
||||
testSystem2,
|
||||
});
|
||||
|
||||
while (!w.shouldClose()) {
|
||||
try r.tick();
|
||||
pool.tick();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
21
src/renderer/Camera.zig
Normal file
21
src/renderer/Camera.zig
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
const std = @import("std");
|
||||
const ecs = @import("ecs");
|
||||
const math = @import("../math.zig");
|
||||
const Camera = @This();
|
||||
const UP = @Vector(3, f32){ 0.0, 1.0, 0.0 };
|
||||
|
||||
pub const Uniform = struct {
|
||||
proj: math.Matrix,
|
||||
view: math.Matrix,
|
||||
model: math.Matrix,
|
||||
};
|
||||
|
||||
uniform: Uniform,
|
||||
position: @Vector(3, f32),
|
||||
target: @Vector(3, f32),
|
||||
direction: @Vector(3, f32),
|
||||
right: @Vector(3, f32),
|
||||
up: @Vector(3, f32),
|
||||
|
||||
fn input(pool: *ecs.Pool) void {
|
||||
}
|
||||
119
src/renderer/Mesh.zig
Normal file
119
src/renderer/Mesh.zig
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
const c = @import("c.zig");
|
||||
const std = @import("std");
|
||||
const vk = @import("vulkan.zig");
|
||||
const gltf = @import("gltf.zig");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const Mesh = @This();
|
||||
|
||||
pub const Vertex = struct {
|
||||
position: [3]f32,
|
||||
|
||||
pub fn create(x: f32, y: f32, z: f32) Vertex {
|
||||
return Vertex{
|
||||
.position = .{ x, y, z },
|
||||
};
|
||||
}
|
||||
|
||||
pub fn bindingDescription() c.VkVertexInputBindingDescription {
|
||||
const binding_description: c.VkVertexInputBindingDescription = .{
|
||||
.binding = 0,
|
||||
.stride = @sizeOf(Vertex),
|
||||
.inputRate = c.VK_VERTEX_INPUT_RATE_VERTEX,
|
||||
};
|
||||
|
||||
return binding_description;
|
||||
}
|
||||
|
||||
pub fn attributeDescription() c.VkVertexInputAttributeDescription {
|
||||
const attribute_description: c.VkVertexInputAttributeDescription = .{
|
||||
.location = 0,
|
||||
.binding = 0,
|
||||
.format = c.VK_FORMAT_R32G32B32_SFLOAT,
|
||||
.offset = 0,
|
||||
};
|
||||
|
||||
return attribute_description;
|
||||
}
|
||||
};
|
||||
|
||||
vertex_buffer: vk.Buffer,
|
||||
index_buffer: vk.Buffer,
|
||||
|
||||
pub fn createVertexBuffer(allocator: Allocator, device: anytype) !vk.Buffer {
|
||||
const gltf_data = try gltf.parseFile(allocator, "assets/models/block.glb");
|
||||
|
||||
const vertices = gltf_data.vertices;
|
||||
|
||||
var data: [*c]?*anyopaque = null;
|
||||
|
||||
const buffer = try device.createBuffer(vk.BufferUsage{ .transfer_src = true }, vk.BufferFlags{ .host_visible = true, .host_coherent = true }, @sizeOf(Vertex) * vertices.len);
|
||||
|
||||
try vk.mapError(c.vkMapMemory(
|
||||
device.handle,
|
||||
buffer.memory,
|
||||
0,
|
||||
buffer.size,
|
||||
0,
|
||||
@ptrCast(&data),
|
||||
));
|
||||
|
||||
if (data) |ptr| {
|
||||
const gpu_vertices: [*]Vertex = @ptrCast(@alignCast(ptr));
|
||||
|
||||
@memcpy(gpu_vertices, @as([]Vertex, @ptrCast(vertices[0..])));
|
||||
}
|
||||
|
||||
c.vkUnmapMemory(device.handle, buffer.memory);
|
||||
|
||||
const vertex_buffer = try device.createBuffer(vk.BufferUsage{ .vertex_buffer = true, .transfer_dst = true }, vk.BufferFlags{ .device_local = true }, @sizeOf(Vertex) * vertices.len);
|
||||
|
||||
try buffer.copyTo(device, vertex_buffer);
|
||||
buffer.destroy(device.handle);
|
||||
|
||||
return vertex_buffer;
|
||||
}
|
||||
|
||||
pub fn createIndexBuffer(allocator: Allocator, device: anytype) !vk.Buffer {
|
||||
const gltf_data = try gltf.parseFile(allocator, "assets/models/block.glb");
|
||||
const indices = gltf_data.indices;
|
||||
//const indices = [_]u16{ 0, 1, 2, 3, 0, 2 };
|
||||
|
||||
var data: [*c]?*anyopaque = null;
|
||||
|
||||
const buffer = try device.createBuffer(vk.BufferUsage{ .transfer_src = true }, vk.BufferFlags{ .host_visible = true, .host_coherent = true }, @sizeOf(u16) * indices.len);
|
||||
|
||||
try vk.mapError(c.vkMapMemory(
|
||||
device.handle,
|
||||
buffer.memory,
|
||||
0,
|
||||
buffer.size,
|
||||
0,
|
||||
@ptrCast(&data),
|
||||
));
|
||||
|
||||
if (data) |ptr| {
|
||||
const gpu_indices: [*]u16 = @ptrCast(@alignCast(ptr));
|
||||
|
||||
@memcpy(gpu_indices, indices[0..]);
|
||||
}
|
||||
|
||||
c.vkUnmapMemory(device.handle, buffer.memory);
|
||||
|
||||
const index_buffer = try device.createBuffer(vk.BufferUsage{ .index_buffer = true, .transfer_dst = true }, vk.BufferFlags{ .device_local = true }, @sizeOf(u16) * indices.len);
|
||||
|
||||
try buffer.copyTo(device, index_buffer);
|
||||
buffer.destroy(device.handle);
|
||||
|
||||
return index_buffer;
|
||||
}
|
||||
|
||||
pub fn create(allocator: Allocator, device: anytype) !Mesh {
|
||||
const vertex_buffer = try Mesh.createVertexBuffer(allocator, device);
|
||||
const index_buffer = try Mesh.createIndexBuffer(allocator, device);
|
||||
|
||||
return Mesh{
|
||||
.vertex_buffer = vertex_buffer,
|
||||
.index_buffer = index_buffer,
|
||||
};
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
const c = @import("../c.zig");
|
||||
const c = @import("c.zig");
|
||||
const std = @import("std");
|
||||
const vk = @import("vulkan.zig");
|
||||
const window = @import("window.zig");
|
||||
const mesh = @import("mesh.zig");
|
||||
pub const Window = @import("Window.zig");
|
||||
pub const Mesh = @import("Mesh.zig");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const Renderer = @This();
|
||||
|
|
@ -18,7 +18,7 @@ current_frame: u32,
|
|||
vertex_buffer: vk.Buffer,
|
||||
index_buffer: vk.Buffer,
|
||||
|
||||
pub fn create(allocator: Allocator, w: window.Window) !Renderer {
|
||||
pub fn create(allocator: Allocator, w: Window) !Renderer {
|
||||
const instance = try vk.Instance.create(allocator);
|
||||
|
||||
const surface = try vk.Surface.create(instance, w);
|
||||
|
|
@ -44,7 +44,7 @@ pub fn create(allocator: Allocator, w: window.Window) !Renderer {
|
|||
// renderer.render(some_other_thing);
|
||||
// ...
|
||||
// renderer.submit()
|
||||
const triangle = try mesh.Mesh.create(allocator, device);
|
||||
const triangle = try Mesh.create(allocator, device);
|
||||
|
||||
return Renderer{
|
||||
.instance = instance,
|
||||
64
src/renderer/Window.zig
Normal file
64
src/renderer/Window.zig
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
const c = @import("c.zig");
|
||||
const std = @import("std");
|
||||
|
||||
const Window = @This();
|
||||
|
||||
pub const Error = error{
|
||||
platform_unavailable,
|
||||
platform_error,
|
||||
};
|
||||
|
||||
pub fn getExtensions() [][*c]const u8 {
|
||||
var extension_count: u32 = undefined;
|
||||
const raw: [*c][*c]const u8 = c.glfwGetRequiredInstanceExtensions(&extension_count);
|
||||
const extensions = raw[0..extension_count];
|
||||
|
||||
return extensions;
|
||||
}
|
||||
|
||||
title: []const u8,
|
||||
width: usize,
|
||||
height: usize,
|
||||
raw: *c.GLFWwindow,
|
||||
|
||||
pub fn create(width: usize, height: usize, title: []const u8) !Window {
|
||||
if (c.glfwInit() != c.GLFW_TRUE) {
|
||||
const status = c.glfwGetError(null);
|
||||
|
||||
return switch (status) {
|
||||
c.GLFW_PLATFORM_UNAVAILABLE => Error.platform_unavailable,
|
||||
c.GLFW_PLATFORM_ERROR => Error.platform_error,
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
c.glfwWindowHint(c.GLFW_RESIZABLE, c.GLFW_FALSE);
|
||||
c.glfwWindowHint(c.GLFW_CLIENT_API, c.GLFW_NO_API);
|
||||
const raw = c.glfwCreateWindow(@intCast(width), @intCast(height), title.ptr, null, null);
|
||||
c.glfwShowWindow(raw);
|
||||
|
||||
return Window{
|
||||
.title = title,
|
||||
.width = width,
|
||||
.height = height,
|
||||
.raw = raw.?,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn shouldClose(self: Window) bool {
|
||||
return c.glfwWindowShouldClose(self.raw) == c.GLFW_TRUE;
|
||||
}
|
||||
|
||||
pub fn size(self: Window) struct { usize, usize } {
|
||||
var width: u32 = undefined;
|
||||
var height: u32 = undefined;
|
||||
|
||||
c.glfwGetFramebufferSize(self.raw, @ptrCast(&width), @ptrCast(&height));
|
||||
|
||||
return .{ @intCast(width), @intCast(height) };
|
||||
}
|
||||
|
||||
pub fn destroy(self: Window) void {
|
||||
c.glfwDestroyWindow(self.raw);
|
||||
c.glfwTerminate();
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
const std = @import("std");
|
||||
const mesh = @import("mesh.zig");
|
||||
const Mesh = @import("Mesh.zig");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
pub const Model = struct {
|
||||
|
|
@ -106,7 +106,7 @@ pub const Model = struct {
|
|||
scenes: ?[]Scene = null,
|
||||
nodes: ?[]Node = null,
|
||||
materials: ?[]Material = null,
|
||||
meshes: ?[]Mesh = null,
|
||||
meshes: ?[]Model.Mesh = null,
|
||||
accessors: ?[]Accessor = null,
|
||||
bufferViews: ?[]BufferView = null,
|
||||
buffers: ?[]Buffer = null,
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
const std = @import("std");
|
||||
const c = @import("../c.zig");
|
||||
const window = @import("./window.zig");
|
||||
const mesh = @import("./mesh.zig");
|
||||
const math = @import("../math.zig");
|
||||
const c = @import("c.zig");
|
||||
const Window = @import("Window.zig");
|
||||
const Mesh = @import("Mesh.zig");
|
||||
const sideros = @import("sideros");
|
||||
const math = sideros.math;
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const builtin = @import("builtin");
|
||||
|
|
@ -71,7 +72,7 @@ pub const Instance = struct {
|
|||
handle: c.VkInstance,
|
||||
|
||||
pub fn create(allocator: Allocator) !Instance {
|
||||
const extensions = window.getExtensions();
|
||||
const extensions = Window.getExtensions();
|
||||
|
||||
// Querry avaliable extensions size
|
||||
var avaliableExtensionsCount: u32 = 0;
|
||||
|
|
@ -323,8 +324,8 @@ pub fn GraphicsPipeline(comptime n: usize) type {
|
|||
// TODO: shouldn't this be closer to usage?
|
||||
const shader_stage_infos: []const c.VkPipelineShaderStageCreateInfo = &.{ vertex_shader_stage_info, fragment_shader_stage_info };
|
||||
|
||||
const vertex_attributes: []const c.VkVertexInputAttributeDescription = &.{mesh.Vertex.attributeDescription()};
|
||||
const vertex_bindings: []const c.VkVertexInputBindingDescription = &.{mesh.Vertex.bindingDescription()};
|
||||
const vertex_attributes: []const c.VkVertexInputAttributeDescription = &.{Mesh.Vertex.attributeDescription()};
|
||||
const vertex_bindings: []const c.VkVertexInputBindingDescription = &.{Mesh.Vertex.bindingDescription()};
|
||||
|
||||
const vertex_input_info: c.VkPipelineVertexInputStateCreateInfo = .{
|
||||
.sType = c.VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
||||
|
|
@ -613,7 +614,7 @@ pub fn Swapchain(comptime n: usize) type {
|
|||
}
|
||||
|
||||
// TODO: Allow to recreate so Window can be resized
|
||||
pub fn create(allocator: Allocator, surface: Surface, device: Device(n), physical_device: PhysicalDevice, w: window.Window, render_pass: RenderPass(n)) !Self {
|
||||
pub fn create(allocator: Allocator, surface: Surface, device: Device(n), physical_device: PhysicalDevice, w: Window, render_pass: RenderPass(n)) !Self {
|
||||
const present_modes = try surface.presentModes(allocator, physical_device);
|
||||
defer allocator.free(present_modes);
|
||||
const capabilities = try surface.capabilities(physical_device);
|
||||
|
|
@ -765,7 +766,7 @@ pub fn Swapchain(comptime n: usize) type {
|
|||
pub const Surface = struct {
|
||||
handle: c.VkSurfaceKHR,
|
||||
|
||||
pub fn create(instance: Instance, w: window.Window) !Surface {
|
||||
pub fn create(instance: Instance, w: Window) !Surface {
|
||||
var handle: c.VkSurfaceKHR = undefined;
|
||||
try mapError(c.glfwCreateWindowSurface(instance.handle, w.raw, null, &handle));
|
||||
return Surface{
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
const c = @import("../c.zig");
|
||||
const std = @import("std");
|
||||
const vk = @import("vulkan.zig");
|
||||
const gltf = @import("gltf.zig");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
pub const Vertex = struct {
|
||||
position: [3]f32,
|
||||
|
||||
pub fn create(x: f32, y: f32, z: f32) Vertex {
|
||||
return Vertex{
|
||||
.position = .{ x, y, z },
|
||||
};
|
||||
}
|
||||
|
||||
pub fn bindingDescription() c.VkVertexInputBindingDescription {
|
||||
const binding_description: c.VkVertexInputBindingDescription = .{
|
||||
.binding = 0,
|
||||
.stride = @sizeOf(Vertex),
|
||||
.inputRate = c.VK_VERTEX_INPUT_RATE_VERTEX,
|
||||
};
|
||||
|
||||
return binding_description;
|
||||
}
|
||||
|
||||
pub fn attributeDescription() c.VkVertexInputAttributeDescription {
|
||||
const attribute_description: c.VkVertexInputAttributeDescription = .{
|
||||
.location = 0,
|
||||
.binding = 0,
|
||||
.format = c.VK_FORMAT_R32G32B32_SFLOAT,
|
||||
.offset = 0,
|
||||
};
|
||||
|
||||
return attribute_description;
|
||||
}
|
||||
};
|
||||
|
||||
pub const Mesh = struct {
|
||||
vertex_buffer: vk.Buffer,
|
||||
index_buffer: vk.Buffer,
|
||||
|
||||
pub fn createVertexBuffer(allocator: Allocator, device: anytype) !vk.Buffer {
|
||||
const gltf_data = try gltf.parseFile(allocator, "assets/models/block.glb");
|
||||
|
||||
const vertices = gltf_data.vertices;
|
||||
|
||||
var data: [*c]?*anyopaque = null;
|
||||
|
||||
const buffer = try device.createBuffer(vk.BufferUsage{ .transfer_src = true }, vk.BufferFlags{ .host_visible = true, .host_coherent = true }, @sizeOf(Vertex) * vertices.len);
|
||||
|
||||
try vk.mapError(c.vkMapMemory(
|
||||
device.handle,
|
||||
buffer.memory,
|
||||
0,
|
||||
buffer.size,
|
||||
0,
|
||||
@ptrCast(&data),
|
||||
));
|
||||
|
||||
if (data) |ptr| {
|
||||
const gpu_vertices: [*]Vertex = @ptrCast(@alignCast(ptr));
|
||||
|
||||
@memcpy(gpu_vertices, @as([]Vertex, @ptrCast(vertices[0..])));
|
||||
}
|
||||
|
||||
c.vkUnmapMemory(device.handle, buffer.memory);
|
||||
|
||||
const vertex_buffer = try device.createBuffer(vk.BufferUsage{ .vertex_buffer = true, .transfer_dst = true }, vk.BufferFlags{ .device_local = true }, @sizeOf(Vertex) * vertices.len);
|
||||
|
||||
try buffer.copyTo(device, vertex_buffer);
|
||||
buffer.destroy(device.handle);
|
||||
|
||||
return vertex_buffer;
|
||||
}
|
||||
|
||||
pub fn createIndexBuffer(allocator: Allocator, device: anytype) !vk.Buffer {
|
||||
const gltf_data = try gltf.parseFile(allocator, "assets/models/block.glb");
|
||||
const indices = gltf_data.indices;
|
||||
//const indices = [_]u16{ 0, 1, 2, 3, 0, 2 };
|
||||
|
||||
var data: [*c]?*anyopaque = null;
|
||||
|
||||
const buffer = try device.createBuffer(vk.BufferUsage{ .transfer_src = true }, vk.BufferFlags{ .host_visible = true, .host_coherent = true }, @sizeOf(u16) * indices.len);
|
||||
|
||||
try vk.mapError(c.vkMapMemory(
|
||||
device.handle,
|
||||
buffer.memory,
|
||||
0,
|
||||
buffer.size,
|
||||
0,
|
||||
@ptrCast(&data),
|
||||
));
|
||||
|
||||
if (data) |ptr| {
|
||||
const gpu_indices: [*]u16 = @ptrCast(@alignCast(ptr));
|
||||
|
||||
@memcpy(gpu_indices, indices[0..]);
|
||||
}
|
||||
|
||||
c.vkUnmapMemory(device.handle, buffer.memory);
|
||||
|
||||
const index_buffer = try device.createBuffer(vk.BufferUsage{ .index_buffer = true, .transfer_dst = true }, vk.BufferFlags{ .device_local = true }, @sizeOf(u16) * indices.len);
|
||||
|
||||
try buffer.copyTo(device, index_buffer);
|
||||
buffer.destroy(device.handle);
|
||||
|
||||
return index_buffer;
|
||||
}
|
||||
|
||||
pub fn create(allocator: Allocator, device: anytype) !Mesh {
|
||||
const vertex_buffer = try Mesh.createVertexBuffer(allocator, device);
|
||||
const index_buffer = try Mesh.createIndexBuffer(allocator, device);
|
||||
|
||||
return Mesh{
|
||||
.vertex_buffer = vertex_buffer,
|
||||
.index_buffer = index_buffer,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
const c = @import("../c.zig");
|
||||
const std = @import("std");
|
||||
|
||||
pub const Error = error{
|
||||
platform_unavailable,
|
||||
platform_error,
|
||||
};
|
||||
|
||||
pub fn getExtensions() [][*c]const u8 {
|
||||
var extension_count: u32 = undefined;
|
||||
const raw: [*c][*c]const u8 = c.glfwGetRequiredInstanceExtensions(&extension_count);
|
||||
const extensions = raw[0..extension_count];
|
||||
|
||||
return extensions;
|
||||
}
|
||||
|
||||
pub const Window = struct {
|
||||
title: []const u8,
|
||||
width: usize,
|
||||
height: usize,
|
||||
raw: *c.GLFWwindow,
|
||||
|
||||
pub fn create(width: usize, height: usize, title: []const u8) !Window {
|
||||
if (c.glfwInit() != c.GLFW_TRUE) {
|
||||
const status = c.glfwGetError(null);
|
||||
|
||||
return switch (status) {
|
||||
c.GLFW_PLATFORM_UNAVAILABLE => Error.platform_unavailable,
|
||||
c.GLFW_PLATFORM_ERROR => Error.platform_error,
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
c.glfwWindowHint(c.GLFW_RESIZABLE, c.GLFW_FALSE);
|
||||
c.glfwWindowHint(c.GLFW_CLIENT_API, c.GLFW_NO_API);
|
||||
const raw = c.glfwCreateWindow(@intCast(width), @intCast(height), title.ptr, null, null);
|
||||
c.glfwShowWindow(raw);
|
||||
|
||||
return Window{
|
||||
.title = title,
|
||||
.width = width,
|
||||
.height = height,
|
||||
.raw = raw.?,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn shouldClose(self: Window) bool {
|
||||
return c.glfwWindowShouldClose(self.raw) == c.GLFW_TRUE;
|
||||
}
|
||||
|
||||
pub fn size(self: Window) struct { usize, usize } {
|
||||
var width: u32 = undefined;
|
||||
var height: u32 = undefined;
|
||||
|
||||
c.glfwGetFramebufferSize(self.raw, @ptrCast(&width), @ptrCast(&height));
|
||||
|
||||
return .{ @intCast(width), @intCast(height) };
|
||||
}
|
||||
|
||||
pub fn destroy(self: Window) void {
|
||||
c.glfwDestroyWindow(self.raw);
|
||||
c.glfwTerminate();
|
||||
}
|
||||
};
|
||||
1
src/sideros.zig
Normal file
1
src/sideros.zig
Normal file
|
|
@ -0,0 +1 @@
|
|||
pub const math = @import("math.zig");
|
||||
Loading…
Add table
Add a link
Reference in a new issue