This commit is contained in:
sergeypdev 2024-02-12 19:39:14 +04:00
parent 9277c010c8
commit d21d128633
7 changed files with 173658 additions and 7481 deletions

File diff suppressed because it is too large Load Diff

7474
assets/bunny_orig.obj1 Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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,
};