Add tangents
This commit is contained in:
parent
e764879f17
commit
6e75910bef
@ -30,6 +30,7 @@ VERTEX_EXPORT VertexData {
|
|||||||
vec3 position;
|
vec3 position;
|
||||||
vec3 normal;
|
vec3 normal;
|
||||||
vec2 uv;
|
vec2 uv;
|
||||||
|
vec3 tangent;
|
||||||
} VertexOut;
|
} VertexOut;
|
||||||
|
|
||||||
#if VERTEX_SHADER
|
#if VERTEX_SHADER
|
||||||
@ -37,6 +38,7 @@ VERTEX_EXPORT VertexData {
|
|||||||
layout(location = 0) in vec3 aPos;
|
layout(location = 0) in vec3 aPos;
|
||||||
layout(location = 1) in vec3 aNorm;
|
layout(location = 1) in vec3 aNorm;
|
||||||
layout(location = 2) in vec2 aUV;
|
layout(location = 2) in vec2 aUV;
|
||||||
|
layout(location = 3) in vec3 aTangent;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = projection * view * model * vec4(aPos.xyz, 1.0);
|
gl_Position = projection * view * model * vec4(aPos.xyz, 1.0);
|
||||||
@ -44,6 +46,7 @@ void main() {
|
|||||||
VertexOut.position = posWorld.xyz / posWorld.w;
|
VertexOut.position = posWorld.xyz / posWorld.w;
|
||||||
VertexOut.normal = aNorm;
|
VertexOut.normal = aNorm;
|
||||||
VertexOut.uv = aUV;
|
VertexOut.uv = aUV;
|
||||||
|
VertexOut.tangent = aTangent;
|
||||||
}
|
}
|
||||||
#endif // VERTEX_SHADER
|
#endif // VERTEX_SHADER
|
||||||
|
|
||||||
|
@ -235,6 +235,11 @@ const NullMesh = LoadedMesh{
|
|||||||
.offset = 0,
|
.offset = 0,
|
||||||
.stride = 0,
|
.stride = 0,
|
||||||
},
|
},
|
||||||
|
.tangents = BufferSlice{
|
||||||
|
.buffer = 0,
|
||||||
|
.offset = 0,
|
||||||
|
.stride = 0,
|
||||||
|
},
|
||||||
.uvs = BufferSlice{
|
.uvs = BufferSlice{
|
||||||
.buffer = 0,
|
.buffer = 0,
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
@ -265,7 +270,7 @@ fn loadMeshErr(self: *AssetManager, id: AssetId) !*const LoadedMesh {
|
|||||||
const data = try self.loadFile(self.frame_arena, path, MESH_MAX_BYTES);
|
const data = try self.loadFile(self.frame_arena, path, MESH_MAX_BYTES);
|
||||||
const mesh = formats.Mesh.fromBuffer(data.bytes);
|
const mesh = formats.Mesh.fromBuffer(data.bytes);
|
||||||
|
|
||||||
var bufs = [_]gl.GLuint{ 0, 0, 0, 0 };
|
var bufs = [_]gl.GLuint{ 0, 0, 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);
|
||||||
|
|
||||||
@ -273,38 +278,44 @@ fn loadMeshErr(self: *AssetManager, id: AssetId) !*const LoadedMesh {
|
|||||||
std.debug.assert(vertices != 0);
|
std.debug.assert(vertices != 0);
|
||||||
const normals = bufs[1];
|
const normals = bufs[1];
|
||||||
std.debug.assert(normals != 0);
|
std.debug.assert(normals != 0);
|
||||||
const uvs = bufs[2];
|
const tangents = bufs[2];
|
||||||
|
std.debug.assert(tangents != 0);
|
||||||
|
const uvs = bufs[3];
|
||||||
std.debug.assert(uvs != 0);
|
std.debug.assert(uvs != 0);
|
||||||
const indices = bufs[3];
|
const indices = bufs[4];
|
||||||
std.debug.assert(indices != 0);
|
std.debug.assert(indices != 0);
|
||||||
|
|
||||||
gl.namedBufferStorage(
|
gl.namedBufferStorage(
|
||||||
vertices,
|
vertices,
|
||||||
@intCast(mesh.vertices.len * @sizeOf(formats.Vector3)),
|
@intCast(mesh.vertices.len * @sizeOf(formats.Vector3)),
|
||||||
@ptrCast(mesh.vertices),
|
@ptrCast(mesh.vertices.ptr),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
gl.namedBufferStorage(
|
gl.namedBufferStorage(
|
||||||
normals,
|
normals,
|
||||||
@intCast(mesh.normals.len * @sizeOf(formats.Vector3)),
|
@intCast(mesh.normals.len * @sizeOf(formats.Vector3)),
|
||||||
@ptrCast(mesh.normals),
|
@ptrCast(mesh.normals.ptr),
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
gl.namedBufferStorage(
|
||||||
|
tangents,
|
||||||
|
@intCast(mesh.tangents.len * @sizeOf(formats.Vector3)),
|
||||||
|
@ptrCast(mesh.tangents.ptr),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
gl.namedBufferStorage(
|
gl.namedBufferStorage(
|
||||||
uvs,
|
uvs,
|
||||||
@intCast(mesh.uvs.len * @sizeOf(formats.Vector2)),
|
@intCast(mesh.uvs.len * @sizeOf(formats.Vector2)),
|
||||||
@ptrCast(mesh.uvs),
|
@ptrCast(mesh.uvs.ptr),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
gl.namedBufferStorage(
|
gl.namedBufferStorage(
|
||||||
indices,
|
indices,
|
||||||
@intCast(mesh.indices.len * @sizeOf(formats.Index)),
|
@intCast(mesh.indices.len * @sizeOf(formats.Index)),
|
||||||
@ptrCast(mesh.indices),
|
@ptrCast(mesh.indices.ptr),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
|
||||||
// gl.bindVertexBuffer(_bindingindex: GLuint, _buffer: GLuint, _offset: GLintptr, _stride: GLsizei)
|
|
||||||
|
|
||||||
const loaded_mesh = LoadedMesh{
|
const loaded_mesh = LoadedMesh{
|
||||||
.aabb = .{
|
.aabb = .{
|
||||||
.min = Vec3.new(mesh.aabb.min.x, mesh.aabb.min.y, mesh.aabb.min.z),
|
.min = Vec3.new(mesh.aabb.min.x, mesh.aabb.min.y, mesh.aabb.min.z),
|
||||||
@ -320,6 +331,11 @@ fn loadMeshErr(self: *AssetManager, id: AssetId) !*const LoadedMesh {
|
|||||||
.offset = 0,
|
.offset = 0,
|
||||||
.stride = @sizeOf(formats.Vector3),
|
.stride = @sizeOf(formats.Vector3),
|
||||||
},
|
},
|
||||||
|
.tangents = .{
|
||||||
|
.buffer = tangents,
|
||||||
|
.offset = 0,
|
||||||
|
.stride = @sizeOf(formats.Vector3),
|
||||||
|
},
|
||||||
.uvs = .{
|
.uvs = .{
|
||||||
.buffer = uvs,
|
.buffer = uvs,
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
@ -422,6 +438,7 @@ const LoadedMesh = struct {
|
|||||||
aabb: AABB,
|
aabb: AABB,
|
||||||
positions: BufferSlice,
|
positions: BufferSlice,
|
||||||
normals: BufferSlice,
|
normals: BufferSlice,
|
||||||
|
tangents: BufferSlice,
|
||||||
uvs: BufferSlice,
|
uvs: BufferSlice,
|
||||||
indices: IndexSlice,
|
indices: IndexSlice,
|
||||||
};
|
};
|
||||||
@ -572,7 +589,7 @@ fn unloadAssetWithDependees(self: *AssetManager, id: AssetId) void {
|
|||||||
|
|
||||||
switch (asset.*) {
|
switch (asset.*) {
|
||||||
.mesh => |*mesh| {
|
.mesh => |*mesh| {
|
||||||
gl.deleteBuffers(4, &[_]gl.GLuint{ mesh.positions.buffer, mesh.normals.buffer, mesh.uvs.buffer, mesh.indices.buffer });
|
gl.deleteBuffers(5, &[_]gl.GLuint{ mesh.positions.buffer, mesh.normals.buffer, mesh.tangents.buffer, mesh.uvs.buffer, mesh.indices.buffer });
|
||||||
},
|
},
|
||||||
.shader => |*shader| {
|
.shader => |*shader| {
|
||||||
self.allocator.free(shader.source);
|
self.allocator.free(shader.source);
|
||||||
|
@ -51,13 +51,16 @@ pub fn init(allocator: std.mem.Allocator, frame_arena: std.mem.Allocator, assetm
|
|||||||
gl.vertexArrayAttribFormat(vao, Attrib.Position.value(), 3, gl.FLOAT, gl.FALSE, 0);
|
gl.vertexArrayAttribFormat(vao, Attrib.Position.value(), 3, gl.FLOAT, gl.FALSE, 0);
|
||||||
|
|
||||||
// normals
|
// normals
|
||||||
// gl.vertexArrayVertexBuffer(vao, 1, normals, 0, @sizeOf(formats.Vector3));
|
|
||||||
gl.enableVertexArrayAttrib(vao, Attrib.Normal.value());
|
gl.enableVertexArrayAttrib(vao, Attrib.Normal.value());
|
||||||
gl.vertexArrayAttribBinding(vao, Attrib.Normal.value(), 1);
|
gl.vertexArrayAttribBinding(vao, Attrib.Normal.value(), 1);
|
||||||
gl.vertexArrayAttribFormat(vao, Attrib.Normal.value(), 3, gl.FLOAT, gl.FALSE, 0);
|
gl.vertexArrayAttribFormat(vao, Attrib.Normal.value(), 3, gl.FLOAT, gl.FALSE, 0);
|
||||||
|
|
||||||
|
// tangents
|
||||||
|
gl.enableVertexArrayAttrib(vao, Attrib.Tangent.value());
|
||||||
|
gl.vertexArrayAttribBinding(vao, Attrib.Tangent.value(), 3);
|
||||||
|
gl.vertexArrayAttribFormat(vao, Attrib.Tangent.value(), 3, gl.FLOAT, gl.FALSE, 0);
|
||||||
|
|
||||||
// uvs
|
// uvs
|
||||||
// gl.vertexArrayVertexBuffer(vao, 1, normals, 0, @sizeOf(formats.Vector3));
|
|
||||||
gl.enableVertexArrayAttrib(vao, Attrib.UV.value());
|
gl.enableVertexArrayAttrib(vao, Attrib.UV.value());
|
||||||
gl.vertexArrayAttribBinding(vao, Attrib.UV.value(), 2);
|
gl.vertexArrayAttribBinding(vao, Attrib.UV.value(), 2);
|
||||||
gl.vertexArrayAttribFormat(vao, Attrib.UV.value(), 2, gl.FLOAT, gl.FALSE, 0);
|
gl.vertexArrayAttribFormat(vao, Attrib.UV.value(), 2, gl.FLOAT, gl.FALSE, 0);
|
||||||
@ -185,6 +188,7 @@ pub fn draw(self: *Render, cmd: DrawCommand) void {
|
|||||||
const mesh = self.assetman.resolveMesh(cmd.mesh);
|
const mesh = self.assetman.resolveMesh(cmd.mesh);
|
||||||
mesh.positions.bind(Render.Attrib.Position.value());
|
mesh.positions.bind(Render.Attrib.Position.value());
|
||||||
mesh.normals.bind(Render.Attrib.Normal.value());
|
mesh.normals.bind(Render.Attrib.Normal.value());
|
||||||
|
mesh.tangents.bind(Render.Attrib.Tangent.value());
|
||||||
mesh.uvs.bind(Render.Attrib.UV.value());
|
mesh.uvs.bind(Render.Attrib.UV.value());
|
||||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, mesh.indices.buffer);
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, mesh.indices.buffer);
|
||||||
gl.drawElements(
|
gl.drawElements(
|
||||||
@ -237,6 +241,7 @@ pub const Attrib = enum(gl.GLuint) {
|
|||||||
Position = 0,
|
Position = 0,
|
||||||
Normal = 1,
|
Normal = 1,
|
||||||
UV = 2,
|
UV = 2,
|
||||||
|
Tangent = 3,
|
||||||
|
|
||||||
pub inline fn value(self: Attrib) gl.GLuint {
|
pub inline fn value(self: Attrib) gl.GLuint {
|
||||||
return @intFromEnum(self);
|
return @intFromEnum(self);
|
||||||
|
@ -24,6 +24,7 @@ pub const Mesh = struct {
|
|||||||
|
|
||||||
vertices: []align(1) Vector3,
|
vertices: []align(1) Vector3,
|
||||||
normals: []align(1) Vector3,
|
normals: []align(1) Vector3,
|
||||||
|
tangents: []align(1) Vector3,
|
||||||
uvs: []align(1) Vector2,
|
uvs: []align(1) Vector2,
|
||||||
indices: []align(1) Index,
|
indices: []align(1) Index,
|
||||||
|
|
||||||
@ -54,6 +55,8 @@ pub const Mesh = struct {
|
|||||||
offset += size;
|
offset += size;
|
||||||
const normals = std.mem.bytesAsSlice(Vector3, buffer[offset .. offset + size]);
|
const normals = std.mem.bytesAsSlice(Vector3, buffer[offset .. offset + size]);
|
||||||
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(Vector2);
|
||||||
const uvs = std.mem.bytesAsSlice(Vector2, buffer[offset .. offset + size]);
|
const uvs = std.mem.bytesAsSlice(Vector2, buffer[offset .. offset + size]);
|
||||||
@ -67,6 +70,7 @@ pub const Mesh = struct {
|
|||||||
.aabb = aabb,
|
.aabb = aabb,
|
||||||
.vertices = vertices,
|
.vertices = vertices,
|
||||||
.normals = normals,
|
.normals = normals,
|
||||||
|
.tangents = tangents,
|
||||||
.uvs = uvs,
|
.uvs = uvs,
|
||||||
.indices = indices,
|
.indices = indices,
|
||||||
};
|
};
|
||||||
@ -92,6 +96,9 @@ pub fn writeMesh(writer: anytype, value: Mesh, endian: std.builtin.Endian) !void
|
|||||||
for (value.normals) |n| {
|
for (value.normals) |n| {
|
||||||
try writeVector3(writer, n, endian);
|
try writeVector3(writer, n, endian);
|
||||||
}
|
}
|
||||||
|
for (value.tangents) |t| {
|
||||||
|
try writeVector3(writer, t, endian);
|
||||||
|
}
|
||||||
for (value.uvs) |uv| {
|
for (value.uvs) |uv| {
|
||||||
try writeVector2(writer, uv, endian);
|
try writeVector2(writer, uv, endian);
|
||||||
}
|
}
|
||||||
|
@ -83,11 +83,13 @@ fn processMesh(allocator: std.mem.Allocator, input: [*:0]const u8, output: []con
|
|||||||
const mesh: *c.aiMesh = @ptrCast(scene.mMeshes[0]);
|
const mesh: *c.aiMesh = @ptrCast(scene.mMeshes[0]);
|
||||||
|
|
||||||
if (mesh.mNormals == null) return error.MissingNormals;
|
if (mesh.mNormals == null) return error.MissingNormals;
|
||||||
|
if (mesh.mTangents == null) return error.MissingTangents;
|
||||||
if (mesh.mTextureCoords[0] == null) return error.MissingUVs;
|
if (mesh.mTextureCoords[0] == null) return error.MissingUVs;
|
||||||
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 normals = try allocator.alloc(Vector3, @intCast(mesh.mNumVertices));
|
||||||
|
var tangents = try allocator.alloc(Vector3, @intCast(mesh.mNumVertices));
|
||||||
var uvs = try allocator.alloc(Vector2, @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
|
||||||
@ -103,6 +105,11 @@ fn processMesh(allocator: std.mem.Allocator, input: [*:0]const u8, output: []con
|
|||||||
.y = mesh.mNormals[i].y,
|
.y = mesh.mNormals[i].y,
|
||||||
.z = mesh.mNormals[i].z,
|
.z = mesh.mNormals[i].z,
|
||||||
};
|
};
|
||||||
|
tangents[i] = .{
|
||||||
|
.x = mesh.mTangents[i].x,
|
||||||
|
.y = mesh.mTangents[i].y,
|
||||||
|
.z = mesh.mTangents[i].z,
|
||||||
|
};
|
||||||
uvs[i] = .{
|
uvs[i] = .{
|
||||||
.x = mesh.mTextureCoords[0][i].x,
|
.x = mesh.mTextureCoords[0][i].x,
|
||||||
.y = mesh.mTextureCoords[0][i].y,
|
.y = mesh.mTextureCoords[0][i].y,
|
||||||
@ -136,6 +143,7 @@ fn processMesh(allocator: std.mem.Allocator, input: [*:0]const u8, output: []con
|
|||||||
},
|
},
|
||||||
.vertices = vertices,
|
.vertices = vertices,
|
||||||
.normals = normals,
|
.normals = normals,
|
||||||
|
.tangents = tangents,
|
||||||
.uvs = uvs,
|
.uvs = uvs,
|
||||||
.indices = indices,
|
.indices = indices,
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user