parent
f735d49fc2
commit
3761035aea
2 changed files with 125 additions and 91 deletions
@ -0,0 +1,102 @@ |
|||||||
|
const std = @import("std"); |
||||||
|
|
||||||
|
const core = @import("mach-core"); |
||||||
|
const gpu = core.gpu; |
||||||
|
|
||||||
|
const main = @import("./main.zig"); |
||||||
|
const createAndWriteBuffer = main.createAndWriteBuffer; |
||||||
|
|
||||||
|
/// Describes the layout of each vertex that a primitive is made of. |
||||||
|
pub const VertexData = struct { |
||||||
|
position: [3]f32, |
||||||
|
}; |
||||||
|
|
||||||
|
/// Contains the data to render a primitive (3D shape or model). |
||||||
|
pub const PrimitiveData = struct { |
||||||
|
/// Vertices describe the "points" that a primitive is made out of. |
||||||
|
/// This buffer is of type `[]VertexData`. |
||||||
|
vertex_buffer: *gpu.Buffer, |
||||||
|
vertex_count: u32, |
||||||
|
|
||||||
|
/// Indices describe what vertices make up the triangles in a primitive. |
||||||
|
/// This buffer is of type `[]u32`. |
||||||
|
index_buffer: *gpu.Buffer, |
||||||
|
index_count: u32, |
||||||
|
|
||||||
|
// For example, `vertex_buffer` may have 4 points defining a square, but |
||||||
|
// since it needs to be rendered using 2 triangles, `index_buffer` will |
||||||
|
// contain 6 entries, `0, 1, 2` and `3, 2, 1` making up one triangle each. |
||||||
|
}; |
||||||
|
|
||||||
|
/// Creates a primitive from the provided vertices and indices, |
||||||
|
/// and uploads the buffers necessary to render it to the GPU. |
||||||
|
pub fn createPrimitive( |
||||||
|
vertices: []const VertexData, |
||||||
|
indices: []const u32, |
||||||
|
) PrimitiveData { |
||||||
|
return .{ |
||||||
|
.vertex_buffer = createAndWriteBuffer(VertexData, vertices, .{ .vertex = true, .copy_dst = true }), |
||||||
|
.vertex_count = @intCast(vertices.len), |
||||||
|
.index_buffer = createAndWriteBuffer(u32, indices, .{ .index = true, .copy_dst = true }), |
||||||
|
.index_count = @intCast(indices.len), |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
fn vert(x: f32, y: f32, z: f32) VertexData { |
||||||
|
return .{ .position = .{ x, y, z } }; |
||||||
|
} |
||||||
|
|
||||||
|
pub fn createTrianglePrimitive(length: f32) PrimitiveData { |
||||||
|
const radius = length / @sqrt(3.0); |
||||||
|
const a0 = 0.0; |
||||||
|
const a1 = std.math.tau / 3.0; |
||||||
|
const a2 = std.math.tau / 3.0 * 2.0; |
||||||
|
return createPrimitive( |
||||||
|
// A triangle is made up of 3 vertices. |
||||||
|
// |
||||||
|
// 0 |
||||||
|
// / \ |
||||||
|
// / \ |
||||||
|
// 1-----2 |
||||||
|
&.{ |
||||||
|
vert(@sin(a0) * radius, @cos(a0) * radius, 0.0), |
||||||
|
vert(@sin(a1) * radius, @cos(a1) * radius, 0.0), |
||||||
|
vert(@sin(a2) * radius, @cos(a2) * radius, 0.0), |
||||||
|
}, |
||||||
|
// Vertices have to be specified in counter-clockwise, |
||||||
|
// so the "front" of the triangle is facing the right way. |
||||||
|
&.{ |
||||||
|
0, 1, 2, |
||||||
|
}, |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
pub fn createSquarePrimitive(width: f32) PrimitiveData { |
||||||
|
const half_width = width / 2.0; |
||||||
|
return createPrimitive( |
||||||
|
// A square is made up of 4 vertices, ... |
||||||
|
// |
||||||
|
// 0---2 |
||||||
|
// | | |
||||||
|
// | | |
||||||
|
// 1---3 |
||||||
|
&.{ |
||||||
|
// zig fmt: off |
||||||
|
vert(-half_width, -half_width, 0.0), |
||||||
|
vert(-half_width, half_width, 0.0), |
||||||
|
vert( half_width, -half_width, 0.0), |
||||||
|
vert( half_width, half_width, 0.0), |
||||||
|
// zig fmt: on |
||||||
|
}, |
||||||
|
// ... but it has to be split up into 2 triangles. |
||||||
|
// |
||||||
|
// 0--2 4 |
||||||
|
// | / /| |
||||||
|
// |/ / | |
||||||
|
// 1 5--3 |
||||||
|
&.{ |
||||||
|
0, 1, 2, |
||||||
|
3, 2, 1, |
||||||
|
}, |
||||||
|
); |
||||||
|
} |
Loading…
Reference in new issue