Got uvs
This commit is contained in:
parent
9277c010c8
commit
d21d128633
173587
assets/bunny.obj
173587
assets/bunny.obj
File diff suppressed because it is too large
Load Diff
7474
assets/bunny_orig.obj1
Normal file
7474
assets/bunny_orig.obj1
Normal file
File diff suppressed because it is too large
Load Diff
@ -27,18 +27,21 @@ layout(location = 2) uniform vec3 color;
|
||||
VERTEX_EXPORT VertexData {
|
||||
vec3 position;
|
||||
vec3 normal;
|
||||
vec2 uv;
|
||||
} VertexOut;
|
||||
|
||||
#if VERTEX_SHADER
|
||||
|
||||
layout(location = 0) in vec3 aPos;
|
||||
layout(location = 1) in vec3 aNorm;
|
||||
layout(location = 2) in vec2 aUV;
|
||||
|
||||
void main() {
|
||||
gl_Position = projection * view * model * vec4(aPos.xyz, 1.0);
|
||||
vec4 posWorld = model * vec4(aPos, 1.0);
|
||||
VertexOut.position = posWorld.xyz / posWorld.w;
|
||||
VertexOut.normal = aNorm;
|
||||
VertexOut.uv = aUV;
|
||||
}
|
||||
#endif // VERTEX_SHADER
|
||||
|
||||
@ -71,6 +74,8 @@ void main() {
|
||||
|
||||
float gamma = 2.2;
|
||||
FragColor.rgb = pow(FragColor.rgb, vec3(1.0/gamma));
|
||||
|
||||
FragColor.rgb = vec3(VertexOut.uv, 0);
|
||||
}
|
||||
|
||||
#endif // FRAGMNET_SHADER
|
||||
|
@ -214,6 +214,11 @@ const NullMesh = LoadedMesh{
|
||||
.offset = 0,
|
||||
.stride = 0,
|
||||
},
|
||||
.uvs = BufferSlice{
|
||||
.buffer = 0,
|
||||
.offset = 0,
|
||||
.stride = 0,
|
||||
},
|
||||
.indices = IndexSlice{
|
||||
.buffer = 0,
|
||||
.offset = 0,
|
||||
@ -234,7 +239,7 @@ fn loadMeshErr(self: *AssetManager, id: AssetId) !*const LoadedMesh {
|
||||
const data = try self.loadFile(self.frame_arena, path, MESH_MAX_BYTES);
|
||||
const mesh = formats.Mesh.fromBuffer(data.bytes);
|
||||
|
||||
var bufs = [_]gl.GLuint{ 0, 0, 0 };
|
||||
var bufs = [_]gl.GLuint{ 0, 0, 0, 0 };
|
||||
gl.createBuffers(bufs.len, &bufs);
|
||||
errdefer gl.deleteBuffers(bufs.len, &bufs);
|
||||
|
||||
@ -242,7 +247,9 @@ fn loadMeshErr(self: *AssetManager, id: AssetId) !*const LoadedMesh {
|
||||
std.debug.assert(vertices != 0);
|
||||
const normals = bufs[1];
|
||||
std.debug.assert(normals != 0);
|
||||
const indices = bufs[2];
|
||||
const uvs = bufs[2];
|
||||
std.debug.assert(uvs != 0);
|
||||
const indices = bufs[3];
|
||||
std.debug.assert(indices != 0);
|
||||
|
||||
gl.namedBufferStorage(
|
||||
@ -257,6 +264,12 @@ fn loadMeshErr(self: *AssetManager, id: AssetId) !*const LoadedMesh {
|
||||
@ptrCast(mesh.normals),
|
||||
0,
|
||||
);
|
||||
gl.namedBufferStorage(
|
||||
uvs,
|
||||
@intCast(mesh.uvs.len * @sizeOf(formats.Vector2)),
|
||||
@ptrCast(mesh.uvs),
|
||||
0,
|
||||
);
|
||||
gl.namedBufferStorage(
|
||||
indices,
|
||||
@intCast(mesh.indices.len * @sizeOf(formats.Index)),
|
||||
@ -277,11 +290,16 @@ fn loadMeshErr(self: *AssetManager, id: AssetId) !*const LoadedMesh {
|
||||
.offset = 0,
|
||||
.stride = @sizeOf(formats.Vector3),
|
||||
},
|
||||
.uvs = .{
|
||||
.buffer = uvs,
|
||||
.offset = 0,
|
||||
.stride = @sizeOf(formats.Vector2),
|
||||
},
|
||||
.indices = .{
|
||||
.buffer = indices,
|
||||
.offset = 0,
|
||||
.count = @intCast(mesh.indices.len),
|
||||
.type = gl.UNSIGNED_SHORT,
|
||||
.type = gl.UNSIGNED_INT,
|
||||
},
|
||||
};
|
||||
|
||||
@ -307,6 +325,7 @@ const LoadedShaderProgram = struct {
|
||||
const LoadedMesh = struct {
|
||||
positions: BufferSlice,
|
||||
normals: BufferSlice,
|
||||
uvs: BufferSlice,
|
||||
indices: IndexSlice,
|
||||
};
|
||||
|
||||
@ -446,7 +465,7 @@ fn unloadAssetWithDependees(self: *AssetManager, id: AssetId) void {
|
||||
|
||||
switch (asset.*) {
|
||||
.mesh => |*mesh| {
|
||||
gl.deleteBuffers(3, &[_]gl.GLuint{ mesh.positions.buffer, mesh.normals.buffer, mesh.indices.buffer });
|
||||
gl.deleteBuffers(4, &[_]gl.GLuint{ mesh.positions.buffer, mesh.normals.buffer, mesh.uvs.buffer, mesh.indices.buffer });
|
||||
},
|
||||
.shader => |*shader| {
|
||||
self.allocator.free(shader.source);
|
||||
|
@ -4,16 +4,21 @@ const Handle = @import("assets").Handle;
|
||||
|
||||
pub const native_endian = builtin.cpu.arch.endian();
|
||||
|
||||
pub const Vector2 = extern struct {
|
||||
x: f32,
|
||||
y: f32,
|
||||
};
|
||||
pub const Vector3 = extern struct {
|
||||
x: f32,
|
||||
y: f32,
|
||||
z: f32,
|
||||
};
|
||||
pub const Index = u16;
|
||||
pub const Index = u32;
|
||||
|
||||
pub const Mesh = struct {
|
||||
vertices: []align(1) Vector3,
|
||||
normals: []align(1) Vector3,
|
||||
uvs: []align(1) Vector2,
|
||||
indices: []align(1) Index,
|
||||
|
||||
// This will panic if data is incorrect
|
||||
@ -40,6 +45,10 @@ pub const Mesh = struct {
|
||||
const normals = std.mem.bytesAsSlice(Vector3, buffer[offset .. offset + size]);
|
||||
offset += size;
|
||||
|
||||
size = vert_len * @sizeOf(Vector2);
|
||||
const uvs = std.mem.bytesAsSlice(Vector2, buffer[offset .. offset + size]);
|
||||
offset += size;
|
||||
|
||||
size = ind_len * @sizeOf(Index);
|
||||
const indices = std.mem.bytesAsSlice(Index, buffer[offset .. offset + size]);
|
||||
offset += size;
|
||||
@ -47,6 +56,7 @@ pub const Mesh = struct {
|
||||
return .{
|
||||
.vertices = vertices,
|
||||
.normals = normals,
|
||||
.uvs = uvs,
|
||||
.indices = indices,
|
||||
};
|
||||
}
|
||||
@ -64,6 +74,9 @@ pub fn writeMesh(writer: anytype, value: Mesh, endian: std.builtin.Endian) !void
|
||||
for (value.normals) |n| {
|
||||
try writeVector3(writer, n, endian);
|
||||
}
|
||||
for (value.uvs) |uv| {
|
||||
try writeVector2(writer, uv, endian);
|
||||
}
|
||||
for (value.indices) |i| {
|
||||
try writer.writeInt(Index, i, endian);
|
||||
}
|
||||
@ -113,6 +126,10 @@ pub fn writeShaderProgram(writer: anytype, shader: u32, vertex: bool, fragment:
|
||||
);
|
||||
}
|
||||
|
||||
fn writeVector2(writer: anytype, value: Vector2, endian: std.builtin.Endian) !void {
|
||||
try writeFloat(writer, value.x, endian);
|
||||
try writeFloat(writer, value.y, endian);
|
||||
}
|
||||
fn writeVector3(writer: anytype, value: Vector3, endian: std.builtin.Endian) !void {
|
||||
try writeFloat(writer, value.x, endian);
|
||||
try writeFloat(writer, value.y, endian);
|
||||
|
@ -40,6 +40,7 @@ const MAX_POINT_LIGHTS = 8;
|
||||
const Attrib = enum(gl.GLuint) {
|
||||
Position = 0,
|
||||
Normal = 1,
|
||||
UV = 2,
|
||||
|
||||
pub inline fn value(self: Attrib) gl.GLuint {
|
||||
return @intFromEnum(self);
|
||||
@ -369,6 +370,12 @@ export fn game_init(global_allocator: *std.mem.Allocator) void {
|
||||
gl.vertexArrayAttribFormat(vao, Attrib.Normal.value(), 3, gl.FLOAT, gl.FALSE, 0);
|
||||
gl.enableVertexArrayAttrib(vao, Attrib.Normal.value());
|
||||
|
||||
// uvs
|
||||
// gl.vertexArrayVertexBuffer(vao, 1, normals, 0, @sizeOf(formats.Vector3));
|
||||
gl.vertexArrayAttribBinding(vao, Attrib.UV.value(), 1);
|
||||
gl.vertexArrayAttribFormat(vao, Attrib.UV.value(), 2, gl.FLOAT, gl.FALSE, 0);
|
||||
gl.enableVertexArrayAttrib(vao, Attrib.UV.value());
|
||||
|
||||
const PERSISTENT_BUFFER_FLAGS: gl.GLbitfield = gl.MAP_PERSISTENT_BIT | gl.MAP_WRITE_BIT | gl.MAP_COHERENT_BIT;
|
||||
|
||||
// Camera matrices ubo
|
||||
@ -704,6 +711,7 @@ export fn game_update() bool {
|
||||
const mesh = g_assetman.resolveMesh(mesh_handle);
|
||||
mesh.positions.bind(Attrib.Position.value());
|
||||
mesh.normals.bind(Attrib.Normal.value());
|
||||
mesh.uvs.bind(Attrib.UV.value());
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, mesh.indices.buffer);
|
||||
gl.drawElements(
|
||||
gl.TRIANGLES,
|
||||
|
@ -1,6 +1,7 @@
|
||||
const std = @import("std");
|
||||
const formats = @import("formats");
|
||||
const asset_manifest = @import("asset_manifest");
|
||||
const Vector2 = formats.Vector2;
|
||||
const Vector3 = formats.Vector3;
|
||||
const c = @cImport({
|
||||
@cInclude("assimp/cimport.h");
|
||||
@ -68,10 +69,14 @@ fn processMesh(allocator: std.mem.Allocator, input: [*:0]const u8, output: []con
|
||||
const mesh: *c.aiMesh = @ptrCast(scene.mMeshes[0]);
|
||||
|
||||
if (mesh.mNormals == null) return error.MissingNormals;
|
||||
if (mesh.mTextureCoords[0] == null) return error.MissingUVs;
|
||||
if (mesh.mNumUVComponents[0] != 2) return error.WrongUVComponents;
|
||||
|
||||
var vertices = try allocator.alloc(Vector3, @intCast(mesh.mNumVertices));
|
||||
var normals = try allocator.alloc(Vector3, @intCast(mesh.mNumVertices));
|
||||
var indices = try allocator.alloc(u16, @intCast(mesh.mNumFaces * 3)); // triangles
|
||||
var uvs = try allocator.alloc(Vector2, @intCast(mesh.mNumVertices));
|
||||
|
||||
var indices = try allocator.alloc(formats.Index, @intCast(mesh.mNumFaces * 3)); // triangles
|
||||
|
||||
for (0..mesh.mNumVertices) |i| {
|
||||
vertices[i] = .{
|
||||
@ -84,18 +89,28 @@ fn processMesh(allocator: std.mem.Allocator, input: [*:0]const u8, output: []con
|
||||
.y = mesh.mNormals[i].y,
|
||||
.z = mesh.mNormals[i].z,
|
||||
};
|
||||
uvs[i] = .{
|
||||
.x = mesh.mTextureCoords[0][i].x,
|
||||
.y = mesh.mTextureCoords[0][i].y,
|
||||
};
|
||||
}
|
||||
|
||||
for (0..mesh.mNumFaces) |i| {
|
||||
std.debug.assert(mesh.mFaces[i].mNumIndices == 3);
|
||||
for (0..3) |j| {
|
||||
indices[i * 3 + j] = @intCast(mesh.mFaces[i].mIndices[j]);
|
||||
const index = mesh.mFaces[i].mIndices[j];
|
||||
if (index > std.math.maxInt(formats.Index)) {
|
||||
std.log.err("indices out of range for index format: {}\n", .{index});
|
||||
return error.TimeToIncreaseIndexSize;
|
||||
}
|
||||
indices[i * 3 + j] = @intCast(index);
|
||||
}
|
||||
}
|
||||
|
||||
const out_mesh = formats.Mesh{
|
||||
.vertices = vertices,
|
||||
.normals = normals,
|
||||
.uvs = uvs,
|
||||
.indices = indices,
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user