Try interleaved vertex attributes

This commit is contained in:
sergeypdev 2024-07-26 11:53:29 +04:00
parent 3daad6b31b
commit f21bc2245a
4 changed files with 41 additions and 97 deletions

View File

@ -282,17 +282,7 @@ const NullMesh = LoadedMesh{
.offset = 0, .offset = 0,
.stride = 0, .stride = 0,
}, },
.normals = BufferSlice{ .ps_data = BufferSlice{
.buffer = 0,
.offset = 0,
.stride = 0,
},
.tangents = BufferSlice{
.buffer = 0,
.offset = 0,
.stride = 0,
},
.uvs = BufferSlice{
.buffer = 0, .buffer = 0,
.offset = 0, .offset = 0,
.stride = 0, .stride = 0,
@ -339,13 +329,8 @@ fn loadMeshErr(self: *AssetManager, id: AssetId) !LoadedMesh {
gl.namedBufferSubData(self.vertex_heap.vertices.buffer, @intCast(vertex_offset * @sizeOf(formats.Vector3)), @intCast(vertices_len * @sizeOf(formats.Vector3)), @ptrCast(mesh.vertices.ptr)); gl.namedBufferSubData(self.vertex_heap.vertices.buffer, @intCast(vertex_offset * @sizeOf(formats.Vector3)), @intCast(vertices_len * @sizeOf(formats.Vector3)), @ptrCast(mesh.vertices.ptr));
checkGLError(); checkGLError();
gl.namedBufferSubData(self.vertex_heap.normals.buffer, @intCast(vertex_offset * @sizeOf(formats.Vector3)), @intCast(vertices_len * @sizeOf(formats.Vector3)), @ptrCast(mesh.normals.ptr)); gl.namedBufferSubData(self.vertex_heap.ps_data.buffer, @intCast(vertex_offset * @sizeOf(formats.VertexPSData)), @intCast(vertices_len * @sizeOf(formats.VertexPSData)), @ptrCast(mesh.ps_data.ptr));
checkGLError(); checkGLError();
gl.namedBufferSubData(self.vertex_heap.tangents.buffer, @intCast(vertex_offset * @sizeOf(formats.Vector3)), @intCast(vertices_len * @sizeOf(formats.Vector3)), @ptrCast(mesh.tangents.ptr));
checkGLError();
gl.namedBufferSubData(self.vertex_heap.uvs.buffer, @intCast(vertex_offset * @sizeOf(formats.Vector2)), @intCast(vertices_len * @sizeOf(formats.Vector2)), @ptrCast(mesh.uvs.ptr));
checkGLError();
const index_offset = allocation.index.offset; const index_offset = allocation.index.offset;
gl.namedBufferSubData(self.vertex_heap.indices.buffer, @intCast(index_offset * @sizeOf(formats.Index)), @intCast(mesh.indices.len * @sizeOf(formats.Index)), @ptrCast(mesh.indices.ptr)); gl.namedBufferSubData(self.vertex_heap.indices.buffer, @intCast(index_offset * @sizeOf(formats.Index)), @intCast(mesh.indices.len * @sizeOf(formats.Index)), @ptrCast(mesh.indices.ptr));
@ -361,20 +346,10 @@ fn loadMeshErr(self: *AssetManager, id: AssetId) !LoadedMesh {
.offset = @intCast(vertex_offset * @sizeOf(formats.Vector3)), .offset = @intCast(vertex_offset * @sizeOf(formats.Vector3)),
.stride = @sizeOf(formats.Vector3), .stride = @sizeOf(formats.Vector3),
}, },
.normals = .{ .ps_data = .{
.buffer = self.vertex_heap.normals.buffer, .buffer = self.vertex_heap.ps_data.buffer,
.offset = @intCast(vertex_offset * @sizeOf(formats.Vector3)), .offset = @intCast(vertex_offset * @sizeOf(formats.VertexPSData)),
.stride = @sizeOf(formats.Vector3), .stride = @sizeOf(formats.VertexPSData),
},
.tangents = .{
.buffer = self.vertex_heap.tangents.buffer,
.offset = @intCast(vertex_offset * @sizeOf(formats.Vector3)),
.stride = @sizeOf(formats.Vector3),
},
.uvs = .{
.buffer = self.vertex_heap.uvs.buffer,
.offset = @intCast(vertex_offset * @sizeOf(formats.Vector2)),
.stride = @sizeOf(formats.Vector2),
}, },
.indices = .{ .indices = .{
.buffer = self.vertex_heap.indices.buffer, .buffer = self.vertex_heap.indices.buffer,
@ -544,9 +519,7 @@ const LoadedMesh = struct {
aabb: AABB, aabb: AABB,
heap_handle: VertexBufferHeap.Alloc, heap_handle: VertexBufferHeap.Alloc,
positions: BufferSlice, positions: BufferSlice,
normals: BufferSlice, ps_data: BufferSlice,
tangents: BufferSlice,
uvs: BufferSlice,
indices: IndexSlice, indices: IndexSlice,
material: formats.Material, material: formats.Material,
}; };
@ -754,17 +727,15 @@ const VertexBufferHeap = struct {
}; };
} }
pub fn bind(self: *const Buffer, index: gl.GLuint) void { pub fn bind(self: *const Buffer, index: gl.GLuint, offset: gl.GLintptr) void {
gl.bindVertexBuffer(index, self.buffer, 0, self.stride); gl.bindVertexBuffer(index, self.buffer, offset, self.stride);
} }
}; };
vertex_buddy: BuddyAllocator, vertex_buddy: BuddyAllocator,
index_buddy: BuddyAllocator, index_buddy: BuddyAllocator,
vertices: Buffer, vertices: Buffer,
normals: Buffer, ps_data: Buffer,
tangents: Buffer,
uvs: Buffer,
indices: Buffer, indices: Buffer,
pub fn init(allocator: std.mem.Allocator) !Self { pub fn init(allocator: std.mem.Allocator) !Self {
@ -780,7 +751,7 @@ const VertexBufferHeap = struct {
const vertex_buf_size = vertex_buddy.getSize(); const vertex_buf_size = vertex_buddy.getSize();
const index_buf_size = index_buddy.getSize(); const index_buf_size = index_buddy.getSize();
var bufs = [_]gl.GLuint{ 0, 0, 0, 0, 0 }; var bufs = [_]gl.GLuint{ 0, 0, 0 };
gl.createBuffers(bufs.len, &bufs); gl.createBuffers(bufs.len, &bufs);
errdefer gl.deleteBuffers(bufs.len, &bufs); errdefer gl.deleteBuffers(bufs.len, &bufs);
@ -791,10 +762,8 @@ const VertexBufferHeap = struct {
} }
const vertices = Buffer.init(bufs[0], @sizeOf(formats.Vector3)); const vertices = Buffer.init(bufs[0], @sizeOf(formats.Vector3));
const normals = Buffer.init(bufs[1], @sizeOf(formats.Vector3)); const ps_data = Buffer.init(bufs[1], @sizeOf(formats.VertexPSData));
const tangents = Buffer.init(bufs[2], @sizeOf(formats.Vector3)); const indices = Buffer.init(bufs[2], @sizeOf(formats.Index));
const uvs = Buffer.init(bufs[3], @sizeOf(formats.Vector2));
const indices = Buffer.init(bufs[4], @sizeOf(formats.Index));
gl.namedBufferStorage( gl.namedBufferStorage(
vertices.buffer, vertices.buffer,
@ -803,20 +772,8 @@ const VertexBufferHeap = struct {
gl.DYNAMIC_STORAGE_BIT, gl.DYNAMIC_STORAGE_BIT,
); );
gl.namedBufferStorage( gl.namedBufferStorage(
normals.buffer, ps_data.buffer,
@intCast(vertex_buf_size * @sizeOf(formats.Vector3)), @intCast(vertex_buf_size * @sizeOf(formats.VertexPSData)),
null,
gl.DYNAMIC_STORAGE_BIT,
);
gl.namedBufferStorage(
tangents.buffer,
@intCast(vertex_buf_size * @sizeOf(formats.Vector3)),
null,
gl.DYNAMIC_STORAGE_BIT,
);
gl.namedBufferStorage(
uvs.buffer,
@intCast(vertex_buf_size * @sizeOf(formats.Vector2)),
null, null,
gl.DYNAMIC_STORAGE_BIT, gl.DYNAMIC_STORAGE_BIT,
); );
@ -831,9 +788,7 @@ const VertexBufferHeap = struct {
.vertex_buddy = vertex_buddy, .vertex_buddy = vertex_buddy,
.index_buddy = index_buddy, .index_buddy = index_buddy,
.vertices = vertices, .vertices = vertices,
.normals = normals, .ps_data = ps_data,
.tangents = tangents,
.uvs = uvs,
.indices = indices, .indices = indices,
}; };
} }
@ -842,7 +797,7 @@ const VertexBufferHeap = struct {
self.index_buddy.deinit(); self.index_buddy.deinit();
self.vertex_buddy.deinit(); self.vertex_buddy.deinit();
const bufs = [_]gl.GLuint{ self.vertices, self.normals, self.tangents, self.uvs, self.indices }; const bufs = [_]gl.GLuint{ self.vertices, self.ps_data, self.indices };
gl.deleteBuffers(bufs.len, &bufs); gl.deleteBuffers(bufs.len, &bufs);
} }

View File

@ -814,13 +814,13 @@ pub fn finish(self: *Render) void {
gl.GL_ARB_bindless_texture.uniformHandleui64ARB(Uniform.ShadowMap2D.value(), self.shadow_texture_handle); gl.GL_ARB_bindless_texture.uniformHandleui64ARB(Uniform.ShadowMap2D.value(), self.shadow_texture_handle);
gl.GL_ARB_bindless_texture.uniformHandleui64ARB(Uniform.ShadowMapCube.value(), self.cube_shadow_texture_handle); gl.GL_ARB_bindless_texture.uniformHandleui64ARB(Uniform.ShadowMapCube.value(), self.cube_shadow_texture_handle);
self.assetman.vertex_heap.normals.bind(Render.Attrib.Normal.value()); self.assetman.vertex_heap.vertices.bind(Render.Attrib.Position.value(), 0);
checkGLError(); checkGLError();
self.assetman.vertex_heap.tangents.bind(Render.Attrib.Tangent.value()); self.assetman.vertex_heap.ps_data.bind(Render.Attrib.Normal.value(), @offsetOf(formats.VertexPSData, "normal"));
checkGLError(); checkGLError();
self.assetman.vertex_heap.uvs.bind(Render.Attrib.UV.value()); self.assetman.vertex_heap.ps_data.bind(Render.Attrib.Tangent.value(), @offsetOf(formats.VertexPSData, "tangent"));
checkGLError(); checkGLError();
self.assetman.vertex_heap.vertices.bind(Render.Attrib.Position.value()); self.assetman.vertex_heap.ps_data.bind(Render.Attrib.UV.value(), @offsetOf(formats.VertexPSData, "uv"));
checkGLError(); checkGLError();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.assetman.vertex_heap.indices.buffer); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.assetman.vertex_heap.indices.buffer);
checkGLError(); checkGLError();

View File

@ -23,14 +23,18 @@ pub const AABB = extern struct {
}; };
pub const Index = u32; pub const Index = u32;
pub const VertexPSData = extern struct {
normal: Vector3,
tangent: Vector3,
uv: Vector2,
};
pub const Mesh = struct { pub const Mesh = struct {
aabb: AABB, aabb: AABB,
material: Material, material: Material,
vertices: []align(1) Vector3, vertices: []align(1) Vector3,
normals: []align(1) Vector3, ps_data: []align(1) VertexPSData,
tangents: []align(1) Vector3,
uvs: []align(1) Vector2,
indices: []align(1) Index, indices: []align(1) Index,
// This will panic if data is incorrect // This will panic if data is incorrect
@ -63,13 +67,9 @@ pub const Mesh = struct {
size = vert_len * @sizeOf(Vector3); size = vert_len * @sizeOf(Vector3);
const vertices = std.mem.bytesAsSlice(Vector3, buffer[offset .. offset + size]); const vertices = std.mem.bytesAsSlice(Vector3, buffer[offset .. offset + size]);
offset += size; offset += size;
const normals = std.mem.bytesAsSlice(Vector3, buffer[offset .. offset + size]);
offset += size;
const tangents = std.mem.bytesAsSlice(Vector3, buffer[offset .. offset + size]);
offset += size;
size = vert_len * @sizeOf(Vector2); size = vert_len * @sizeOf(VertexPSData);
const uvs = std.mem.bytesAsSlice(Vector2, buffer[offset .. offset + size]); const ps_data = std.mem.bytesAsSlice(VertexPSData, buffer[offset .. offset + size]);
offset += size; offset += size;
size = ind_len * @sizeOf(Index); size = ind_len * @sizeOf(Index);
@ -80,16 +80,14 @@ pub const Mesh = struct {
.aabb = aabb, .aabb = aabb,
.material = material.*, .material = material.*,
.vertices = vertices, .vertices = vertices,
.normals = normals, .ps_data = ps_data,
.tangents = tangents,
.uvs = uvs,
.indices = indices, .indices = indices,
}; };
} }
}; };
pub fn writeMesh(writer: anytype, value: Mesh, endian: std.builtin.Endian) !void { pub fn writeMesh(writer: anytype, value: Mesh, endian: std.builtin.Endian) !void {
std.debug.assert(value.vertices.len == value.normals.len); std.debug.assert(value.vertices.len == value.ps_data.len);
// AABB // AABB
{ {
@ -106,14 +104,10 @@ pub fn writeMesh(writer: anytype, value: Mesh, endian: std.builtin.Endian) !void
for (value.vertices) |v| { for (value.vertices) |v| {
try writeVector3(writer, v, endian); try writeVector3(writer, v, endian);
} }
for (value.normals) |n| { for (value.ps_data) |data| {
try writeVector3(writer, n, endian); try writeVector3(writer, data.normal, endian);
} try writeVector3(writer, data.tangent, endian);
for (value.tangents) |t| { try writeVector2(writer, data.uv, endian);
try writeVector3(writer, t, endian);
}
for (value.uvs) |uv| {
try writeVector2(writer, uv, endian);
} }
for (value.indices) |i| { for (value.indices) |i| {
try writer.writeInt(Index, i, endian); try writer.writeInt(Index, i, endian);

View File

@ -426,10 +426,7 @@ fn processMesh(allocator: std.mem.Allocator, scene: *const c.aiScene, material_o
if (mesh.mNumUVComponents[0] != 2) return error.WrongUVComponents; if (mesh.mNumUVComponents[0] != 2) return error.WrongUVComponents;
var vertices = try allocator.alloc(Vector3, @intCast(mesh.mNumVertices)); var vertices = try allocator.alloc(Vector3, @intCast(mesh.mNumVertices));
var normals = try allocator.alloc(Vector3, @intCast(mesh.mNumVertices)); var ps_data = try allocator.alloc(formats.VertexPSData, @intCast(mesh.mNumVertices));
var tangents = try allocator.alloc(Vector3, @intCast(mesh.mNumVertices));
var uvs = try allocator.alloc(Vector2, @intCast(mesh.mNumVertices));
var indices = try allocator.alloc(formats.Index, @intCast(mesh.mNumFaces * 3)); // triangles var indices = try allocator.alloc(formats.Index, @intCast(mesh.mNumFaces * 3)); // triangles
for (0..mesh.mNumVertices) |i| { for (0..mesh.mNumVertices) |i| {
@ -438,17 +435,17 @@ fn processMesh(allocator: std.mem.Allocator, scene: *const c.aiScene, material_o
.y = mesh.mVertices[i].y, .y = mesh.mVertices[i].y,
.z = mesh.mVertices[i].z, .z = mesh.mVertices[i].z,
}; };
normals[i] = .{ ps_data[i].normal = .{
.x = mesh.mNormals[i].x, .x = mesh.mNormals[i].x,
.y = mesh.mNormals[i].y, .y = mesh.mNormals[i].y,
.z = mesh.mNormals[i].z, .z = mesh.mNormals[i].z,
}; };
tangents[i] = .{ ps_data[i].tangent = .{
.x = mesh.mTangents[i].x, .x = mesh.mTangents[i].x,
.y = mesh.mTangents[i].y, .y = mesh.mTangents[i].y,
.z = mesh.mTangents[i].z, .z = mesh.mTangents[i].z,
}; };
uvs[i] = .{ ps_data[i].uv = .{
.x = mesh.mTextureCoords[0][i].x, .x = mesh.mTextureCoords[0][i].x,
.y = mesh.mTextureCoords[0][i].y, .y = mesh.mTextureCoords[0][i].y,
}; };
@ -482,9 +479,7 @@ fn processMesh(allocator: std.mem.Allocator, scene: *const c.aiScene, material_o
}, },
}, },
.vertices = vertices, .vertices = vertices,
.normals = normals, .ps_data = ps_data,
.tangents = tangents,
.uvs = uvs,
.indices = indices, .indices = indices,
.material = material, .material = material,
}; };