implemented glTF loading
This commit is contained in:
parent
7660bc09bc
commit
56559a9386
6 changed files with 186 additions and 35 deletions
BIN
assets/models/block.glb
Normal file
BIN
assets/models/block.glb
Normal file
Binary file not shown.
27
src/main.zig
27
src/main.zig
|
|
@ -7,6 +7,7 @@ const Renderer = @import("rendering/renderer_vulkan.zig");
|
||||||
const math = @import("math.zig");
|
const math = @import("math.zig");
|
||||||
const mods = @import("mods");
|
const mods = @import("mods");
|
||||||
const ecs = @import("ecs");
|
const ecs = @import("ecs");
|
||||||
|
const gltf = @import("rendering/gltf.zig");
|
||||||
|
|
||||||
fn testSystem2(pool: *ecs.Pool) void {
|
fn testSystem2(pool: *ecs.Pool) void {
|
||||||
for (pool.getQuery(ecs.components.Position), 0..) |position, i| {
|
for (pool.getQuery(ecs.components.Position), 0..) |position, i| {
|
||||||
|
|
@ -44,21 +45,21 @@ pub fn main() !void {
|
||||||
const w = try window.Window.create(800, 600, "sideros");
|
const w = try window.Window.create(800, 600, "sideros");
|
||||||
defer w.destroy();
|
defer w.destroy();
|
||||||
|
|
||||||
var pool = try ecs.Pool.init(allocator);
|
//var pool = try ecs.Pool.init(allocator);
|
||||||
defer pool.deinit(allocator);
|
//defer pool.deinit(allocator);
|
||||||
|
|
||||||
//try pool.addSystemGroup(&[_]entities.System{
|
////try pool.addSystemGroup(&[_]entities.System{
|
||||||
// testSystem,
|
//// testSystem,
|
||||||
|
////});
|
||||||
|
//try pool.addSystemGroup(&[_]ecs.System{
|
||||||
|
// testSystem2,
|
||||||
//});
|
//});
|
||||||
try pool.addSystemGroup(&[_]ecs.System{
|
|
||||||
testSystem2,
|
|
||||||
});
|
|
||||||
|
|
||||||
for (0..1000) |_| {
|
//for (0..1000) |_| {
|
||||||
const entity = try pool.createEntity();
|
// 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.Position{ .x = 1.0, .y = 0.5, .z = 3.0 });
|
||||||
try pool.addComponent(entity, ecs.components.Speed{ .speed = 5.0 });
|
// try pool.addComponent(entity, ecs.components.Speed{ .speed = 5.0 });
|
||||||
}
|
//}
|
||||||
|
|
||||||
// TODO(luccie-cmd): Renderer.create shouldn't return an error
|
// TODO(luccie-cmd): Renderer.create shouldn't return an error
|
||||||
var r = try Renderer.create(allocator, w);
|
var r = try Renderer.create(allocator, w);
|
||||||
|
|
@ -67,7 +68,7 @@ pub fn main() !void {
|
||||||
while (!w.shouldClose()) {
|
while (!w.shouldClose()) {
|
||||||
c.glfwPollEvents();
|
c.glfwPollEvents();
|
||||||
try r.tick();
|
try r.tick();
|
||||||
pool.tick();
|
//pool.tick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,165 @@ const std = @import("std");
|
||||||
const mesh = @import("mesh.zig");
|
const mesh = @import("mesh.zig");
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
pub const Model = packed struct {
|
pub const Model = struct {
|
||||||
const Chunk = packed struct {
|
const Asset = struct {
|
||||||
length: u32,
|
version: []u8,
|
||||||
ty: u32,
|
generator: ?[]u8 = null,
|
||||||
|
copyright: ?[]u8 = null,
|
||||||
|
};
|
||||||
|
const Buffer = struct {
|
||||||
|
byteLength: usize,
|
||||||
|
uri: ?[]u8 = null,
|
||||||
|
};
|
||||||
|
const BufferView = struct {
|
||||||
|
buffer: usize,
|
||||||
|
byteLength: usize,
|
||||||
|
byteOffset: usize,
|
||||||
|
byteStride: ?usize = null,
|
||||||
|
target: ?usize = null,
|
||||||
|
};
|
||||||
|
const Node = struct {
|
||||||
|
name: []u8,
|
||||||
|
mesh: ?usize = null,
|
||||||
|
weights: ?[]f64 = null,
|
||||||
|
children: ?[]usize = null,
|
||||||
|
rotation: ?[4]f64 = null,
|
||||||
|
scale: ?[3]f64 = null,
|
||||||
|
translation: ?[3]f64 = null,
|
||||||
|
camera: ?usize = null,
|
||||||
|
matrix: ?[16]usize = null,
|
||||||
|
};
|
||||||
|
const Accessor = struct {
|
||||||
|
bufferView: usize,
|
||||||
|
byteOffset: ?usize = null,
|
||||||
|
componentType: usize,
|
||||||
|
count: usize,
|
||||||
|
type: []u8,
|
||||||
|
max: ?[]f64 = null,
|
||||||
|
min: ?[]f64 = null,
|
||||||
|
};
|
||||||
|
const Primitive = struct {
|
||||||
|
const Attributes = struct {
|
||||||
|
NORMAL: ?usize = null,
|
||||||
|
POSITION: ?usize = null,
|
||||||
|
TANGENT: ?usize = null,
|
||||||
|
TEXCOORD_0: ?usize = null,
|
||||||
|
TEXCOORD_1: ?usize = null,
|
||||||
|
COLOR_0: ?usize = null,
|
||||||
|
JOINTS_0: ?usize = null,
|
||||||
|
WEIGHTS_0: ?usize = null,
|
||||||
|
};
|
||||||
|
|
||||||
},
|
attributes: ?Attributes = null,
|
||||||
header: packed struct {
|
indices: ?usize = null,
|
||||||
|
material: ?usize = null,
|
||||||
|
mode: ?usize = null,
|
||||||
|
};
|
||||||
|
const Mesh = struct {
|
||||||
|
name: ?[]u8 = null,
|
||||||
|
primitives: ?[]Primitive = null,
|
||||||
|
weights: ?[]f64 = null,
|
||||||
|
};
|
||||||
|
const Skin = struct {
|
||||||
|
inverseBindMatrices: usize,
|
||||||
|
joints: []usize,
|
||||||
|
skeleton: usize,
|
||||||
|
};
|
||||||
|
const Texture = struct {
|
||||||
|
sampler: usize,
|
||||||
|
source: usize,
|
||||||
|
};
|
||||||
|
const Image = struct {
|
||||||
|
uri: ?[]u8 = null,
|
||||||
|
bufferView: ?usize = null,
|
||||||
|
mimeType: ?[]u8 = null,
|
||||||
|
};
|
||||||
|
const Material = struct {
|
||||||
|
const Pbr = struct {
|
||||||
|
baseColorFactor: ?[4]f64 = null,
|
||||||
|
baseColorTexture: ?struct {
|
||||||
|
index: usize,
|
||||||
|
texCoord: usize,
|
||||||
|
} = null,
|
||||||
|
metallicFactor: ?f64 = null,
|
||||||
|
roughnessFactor: ?f64 = null,
|
||||||
|
};
|
||||||
|
name: ?[]u8 = null,
|
||||||
|
pbrMetallicRoughness: Pbr,
|
||||||
|
doubleSided: bool,
|
||||||
|
};
|
||||||
|
const Scene = struct {
|
||||||
|
nodes: ?[]usize = null,
|
||||||
|
name: ?[]u8 = null,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Chunk = packed struct {
|
||||||
|
const offset = Header.offset + 8;
|
||||||
|
length: u32,
|
||||||
|
type: u32,
|
||||||
|
};
|
||||||
|
|
||||||
|
const JsonChunk = struct {
|
||||||
|
asset: Asset,
|
||||||
|
scene: usize,
|
||||||
|
scenes: ?[]Scene = null,
|
||||||
|
nodes: ?[]Node = null,
|
||||||
|
materials: ?[]Material = null,
|
||||||
|
meshes: ?[]Mesh = null,
|
||||||
|
accessors: ?[]Accessor = null,
|
||||||
|
bufferViews: ?[]BufferView = null,
|
||||||
|
buffers: ?[]Buffer = null,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Header = packed struct {
|
||||||
|
const offset = 12;
|
||||||
magic: u32,
|
magic: u32,
|
||||||
version: u32,
|
version: u32,
|
||||||
length: u32,
|
length: u32,
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const Binary = struct {
|
||||||
|
data: []u8,
|
||||||
|
const Vec3 = [3]f32;
|
||||||
|
|
||||||
|
pub fn readU16(self: Binary, allocator: Allocator, view: BufferView, count: usize) ![]u16 {
|
||||||
|
const data = self.data[view.byteOffset .. view.byteOffset + view.byteLength];
|
||||||
|
const scalars = try allocator.alloc(u16, count);
|
||||||
|
|
||||||
|
var j: usize = 0;
|
||||||
|
for (0..data.len / 2) |i| {
|
||||||
|
scalars[i] = std.mem.bytesAsValue(u16, data[j .. j + 1]).*;
|
||||||
|
j += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return scalars;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn readVec3(self: Binary, allocator: Allocator, view: BufferView, count: usize) ![]Vec3 {
|
||||||
|
const data = self.data[view.byteOffset .. view.byteOffset + view.byteLength];
|
||||||
|
const vectors = try allocator.alloc(Vec3, count);
|
||||||
|
|
||||||
|
for (0..count) |i| {
|
||||||
|
vectors[i] = std.mem.bytesAsValue(Vec3, data[(@sizeOf(Vec3) * i) .. (@sizeOf(Vec3) * i) + @sizeOf(Vec3)]).*;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vectors;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn parseFile(allocator: Allocator, name: []const u8) !struct { vertices: [][3]f32, indices: []u16 } {
|
||||||
|
const file = try std.fs.cwd().openFile(name, .{});
|
||||||
|
const all = try file.readToEndAlloc(allocator, 1_000_000);
|
||||||
|
const json_chunk = std.mem.bytesAsValue(Model.Chunk, all[Model.Header.offset..]);
|
||||||
|
|
||||||
|
const data = (try std.json.parseFromSlice(Model.JsonChunk, allocator, @constCast(all[Model.Chunk.offset .. Model.Chunk.offset + json_chunk.length]), .{ .ignore_unknown_fields = true })).value;
|
||||||
|
const binary = Model.Binary{ .data = all[Model.Chunk.offset + json_chunk.length + 8 ..] };
|
||||||
|
|
||||||
|
const vertices = try binary.readVec3(allocator, data.bufferViews.?[data.meshes.?[0].primitives.?[0].attributes.?.POSITION.?], 24);
|
||||||
|
const indices = try binary.readU16(allocator, data.bufferViews.?[data.meshes.?[0].primitives.?[0].indices.?], 36);
|
||||||
|
std.debug.print("vertices: {any}\n", .{vertices});
|
||||||
|
std.debug.print("indices: {any}\n", .{indices});
|
||||||
|
|
||||||
|
return .{ .vertices = vertices, .indices = indices };
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
const c = @import("../c.zig");
|
const c = @import("../c.zig");
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const vk = @import("vulkan.zig");
|
const vk = @import("vulkan.zig");
|
||||||
|
const gltf = @import("gltf.zig");
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
pub const Vertex = struct {
|
pub const Vertex = struct {
|
||||||
|
|
@ -38,13 +39,10 @@ pub const Mesh = struct {
|
||||||
vertex_buffer: vk.Buffer,
|
vertex_buffer: vk.Buffer,
|
||||||
index_buffer: vk.Buffer,
|
index_buffer: vk.Buffer,
|
||||||
|
|
||||||
pub fn createVertexBuffer(device: anytype) !vk.Buffer {
|
pub fn createVertexBuffer(allocator: Allocator, device: anytype) !vk.Buffer {
|
||||||
const vertices = [_]Vertex{
|
const gltf_data = try gltf.parseFile(allocator, "assets/models/block.glb");
|
||||||
Vertex.create(0.5, -0.5, 0.0),
|
|
||||||
Vertex.create(0.5, 0.5, 0.0),
|
const vertices = gltf_data.vertices;
|
||||||
Vertex.create(-0.5, 0.5, 0.0),
|
|
||||||
Vertex.create(-0.5, -0.5, 0.0),
|
|
||||||
};
|
|
||||||
|
|
||||||
var data: [*c]?*anyopaque = null;
|
var data: [*c]?*anyopaque = null;
|
||||||
|
|
||||||
|
|
@ -62,7 +60,7 @@ pub const Mesh = struct {
|
||||||
if (data) |ptr| {
|
if (data) |ptr| {
|
||||||
const gpu_vertices: [*]Vertex = @ptrCast(@alignCast(ptr));
|
const gpu_vertices: [*]Vertex = @ptrCast(@alignCast(ptr));
|
||||||
|
|
||||||
@memcpy(gpu_vertices, vertices[0..]);
|
@memcpy(gpu_vertices, @as([]Vertex, @ptrCast(vertices[0..])));
|
||||||
}
|
}
|
||||||
|
|
||||||
c.vkUnmapMemory(device.handle, buffer.memory);
|
c.vkUnmapMemory(device.handle, buffer.memory);
|
||||||
|
|
@ -75,8 +73,10 @@ pub const Mesh = struct {
|
||||||
return vertex_buffer;
|
return vertex_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn createIndexBuffer(device: anytype) !vk.Buffer {
|
pub fn createIndexBuffer(allocator: Allocator, device: anytype) !vk.Buffer {
|
||||||
const indices = [_]u16{ 0, 1, 2, 3, 0, 2 };
|
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;
|
var data: [*c]?*anyopaque = null;
|
||||||
|
|
||||||
|
|
@ -107,9 +107,9 @@ pub const Mesh = struct {
|
||||||
return index_buffer;
|
return index_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create(device: anytype) !Mesh {
|
pub fn create(allocator: Allocator, device: anytype) !Mesh {
|
||||||
const vertex_buffer = try Mesh.createVertexBuffer(device);
|
const vertex_buffer = try Mesh.createVertexBuffer(allocator, device);
|
||||||
const index_buffer = try Mesh.createIndexBuffer(device);
|
const index_buffer = try Mesh.createIndexBuffer(allocator, device);
|
||||||
|
|
||||||
return Mesh{
|
return Mesh{
|
||||||
.vertex_buffer = vertex_buffer,
|
.vertex_buffer = vertex_buffer,
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ pub fn create(allocator: Allocator, w: window.Window) !Renderer {
|
||||||
// renderer.render(some_other_thing);
|
// renderer.render(some_other_thing);
|
||||||
// ...
|
// ...
|
||||||
// renderer.submit()
|
// renderer.submit()
|
||||||
const triangle = try mesh.Mesh.create(device);
|
const triangle = try mesh.Mesh.create(allocator, device);
|
||||||
|
|
||||||
return Renderer{
|
return Renderer{
|
||||||
.instance = instance,
|
.instance = instance,
|
||||||
|
|
|
||||||
|
|
@ -372,7 +372,7 @@ pub fn GraphicsPipeline(comptime n: usize) type {
|
||||||
.polygonMode = c.VK_POLYGON_MODE_FILL,
|
.polygonMode = c.VK_POLYGON_MODE_FILL,
|
||||||
.lineWidth = 1.0,
|
.lineWidth = 1.0,
|
||||||
.cullMode = c.VK_CULL_MODE_BACK_BIT,
|
.cullMode = c.VK_CULL_MODE_BACK_BIT,
|
||||||
.frontFace = c.VK_FRONT_FACE_CLOCKWISE,
|
.frontFace = c.VK_FRONT_FACE_COUNTER_CLOCKWISE,
|
||||||
.depthBiasEnable = c.VK_FALSE,
|
.depthBiasEnable = c.VK_FALSE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue