Added proper draw with Vertex | Triangle x Square Collab!

This commit is contained in:
abux 2026-07-29 02:06:24 +01:00
parent 14dc99d212
commit f404232edb
6 changed files with 211 additions and 49 deletions

View file

@ -1,11 +1,59 @@
// ----------------------------------------------------
// ----------------------------------------------------
struct VertexInput {
@location(0) position: vec3f,
@location(1) normal: vec3f,
@location(2) uv: vec2f,
};
// ----------------------------------------------------
// ----------------------------------------------------
struct VertexOutput {
@builtin(position) position: vec4f,
@location(0) uv: vec2f,
@location(1) normal: vec3f,
};
// ----------------------------------------------------
// ----------------------------------------------------
struct Material {
albedo: vec4f,
metallic: f32,
roughness: f32,
_pad0: vec2f,
};
//
// UNIFORMS
//
@group(1) @binding(0)
var<uniform> material: Material;
//
// VERTEX
//
@vertex @vertex
fn vs_main( fn vs_main(in: VertexInput) -> VertexOutput {
@location(0) in_vertex_position: vec2f // --- # ---
) -> @builtin(position) vec4f { var out: VertexOutput;
return vec4f(in_vertex_position, 0.0, 1.0);
// --- # ---
out.position = vec4f(in.position, 1.0);
out.uv = in.uv;
out.normal = in.normal;
// --- # ---
return out;
} }
//
// FRAGMENT
//
@fragment @fragment
fn fs_main() -> @location(0) vec4f { fn fs_main(out: VertexOutput) -> @location(0) vec4f {
return vec4f(0.001, 0.001, 0.001, 1.0); return vec4f(out.uv, 0.3, 1.0);
// return vec4f(material.albedo);
} }

View file

@ -29,6 +29,9 @@ pub const MeshID = union(enum) {
pub const GPUMesh = struct { pub const GPUMesh = struct {
vbuf: *wgpu.WGPUBufferImpl, vbuf: *wgpu.WGPUBufferImpl,
ibuf: ?*wgpu.WGPUBufferImpl = null, ibuf: ?*wgpu.WGPUBufferImpl = null,
vertex_count: u32,
index_count: u32,
}; };
// //
@ -77,42 +80,120 @@ pub fn getOrCreate(
self: *Self, self: *Self,
mesh: MeshID, mesh: MeshID,
) !*GPUMesh { ) !*GPUMesh {
return try self.data.getOrPut(mesh, .{ return try self.data.getOrPut(mesh, blk: {
.vbuf = blk: { // --- # ---
// --- DATA --- const vertices: []const Vertex = switch (mesh) {
const vertices: []const f32 = switch (mesh) {
.triangle => &.{ .triangle => &.{
-0.5, -0.5, .{
0.5, -0.5, .position = .{ -0.5, -0.5, 0.0 },
0.0, 0.5, .normal = .{ 0.0, 0.0, 1.0 },
.uv = .{ 0.0, 0.0 },
},
.{
.position = .{ 0.5, -0.5, 0.0 },
.normal = .{ 0.0, 0.0, 1.0 },
.uv = .{ 1.0, 0.0 },
},
.{
.position = .{ 0.0, 0.5, 0.0 },
.normal = .{ 0.0, 0.0, 1.0 },
.uv = .{ 0.5, 1.0 },
},
}, },
.square => &.{
-0.5, -0.5,
0.5, -0.5,
0.5, 0.5,
-0.5, -0.5, .square, .quad => &.{
0.5, 0.5, .{
-0.5, 0.5, .position = .{ -0.5, -0.5, 0.0 },
.normal = .{ 0.0, 0.0, 1.0 },
.uv = .{ 0.0, 1.0 },
}, },
.{
.position = .{ 0.5, -0.5, 0.0 },
.normal = .{ 0.0, 0.0, 1.0 },
.uv = .{ 1.0, 1.0 },
},
.{
.position = .{ 0.5, 0.5, 0.0 },
.normal = .{ 0.0, 0.0, 1.0 },
.uv = .{ 1.0, 0.0 },
},
.{
.position = .{ -0.5, 0.5, 0.0 },
.normal = .{ 0.0, 0.0, 1.0 },
.uv = .{ 0.0, 0.0 },
},
},
else => &.{}, else => &.{},
}; };
// --- GET SIZE --- // --- # ---
const size = vertices.len * @sizeOf(f32); const indices: []const u32 = switch (mesh) {
.square, .quad => &.{
0, 1, 2,
0, 2, 3,
},
// --- CREATE --- .triangle => &.{
const buff = wgpu.wgpuDeviceCreateBuffer(self.device, &wgpu.WGPUBufferDescriptor{ 0, 1, 2,
.size = size, },
.usage = wgpu.WGPUBufferUsage_CopyDst | wgpu.WGPUBufferUsage_Vertex,
}) orelse return error.FailedToCreateBuffer;
// --- WRITE --- else => &.{},
wgpu.wgpuQueueWriteBuffer(self.queue, buff, 0, vertices.ptr, size); };
// --- GET SIZES ---
const vbuf_size = vertices.len * @sizeOf(Vertex);
const ibuf_size = indices.len * @sizeOf(u32);
// --- CREATE VBUF ---
const vbuf = wgpu.wgpuDeviceCreateBuffer(
self.device,
&wgpu.WGPUBufferDescriptor{
.size = vbuf_size,
.usage = wgpu.WGPUBufferUsage_CopyDst |
wgpu.WGPUBufferUsage_Vertex,
},
) orelse return error.FailedToCreateBuffer;
// --- WRITE TO VBUF ---
wgpu.wgpuQueueWriteBuffer(
self.queue,
vbuf,
0,
vertices.ptr,
vbuf_size,
);
// --- CREATE IBUF ---
const ibuf = if (indices.len > 0)
wgpu.wgpuDeviceCreateBuffer(
self.device,
&wgpu.WGPUBufferDescriptor{
.size = ibuf_size,
.usage = wgpu.WGPUBufferUsage_CopyDst |
wgpu.WGPUBufferUsage_Index,
},
)
else
null;
// --- WRITE TO IBUF ---
if (ibuf) |buffer| {
wgpu.wgpuQueueWriteBuffer(
self.queue,
buffer,
0,
indices.ptr,
ibuf_size,
);
}
// --- RESULT --- // --- RESULT ---
break :blk buff; break :blk .{
}, .vbuf = vbuf,
.ibuf = null, .ibuf = ibuf,
.vertex_count = @intCast(vertices.len),
.index_count = @intCast(indices.len),
};
}); });
} }

View file

@ -8,6 +8,7 @@ const Self = @This();
const Material = @import("../../common/component/material.zig"); const Material = @import("../../common/component/material.zig");
const ShaderCache = @import("shader_cache.zig"); const ShaderCache = @import("shader_cache.zig");
const Vertex = @import("mesh_cache.zig").Vertex;
/// ---------------------------------------------------- /// ----------------------------------------------------
/// ---------------------------------------------------- /// ----------------------------------------------------
@ -15,6 +16,13 @@ pub const GPUPipeline = struct {
raw: *wgpu.WGPURenderPipelineImpl, raw: *wgpu.WGPURenderPipelineImpl,
}; };
/// ----------------------------------------------------
/// ----------------------------------------------------
pub const GPUMaterial = struct { // TODO: Should prob create Material Cache instead
buffer: *wgpu.WGPUBufferImpl,
bind_group: *wgpu.WGPUBindGroupImpl,
};
// //
// FIELDS // FIELDS
// //
@ -84,13 +92,25 @@ fn createPipeline(
.entryPoint = .{ .data = "vs_main", .length = wgpu.WGPU_STRLEN }, .entryPoint = .{ .data = "vs_main", .length = wgpu.WGPU_STRLEN },
.bufferCount = 1, .bufferCount = 1,
.buffers = &wgpu.WGPUVertexBufferLayout{ .buffers = &wgpu.WGPUVertexBufferLayout{
.attributeCount = 1, .attributeCount = 3,
.attributes = &wgpu.WGPUVertexAttribute{ // TODO: Use Vertex attributes instead | Mabe mabe allow for custom, mabe mabe later tho .attributes = &[_]wgpu.WGPUVertexAttribute{ // TODO: Mabe mabe allow for custom, mabe mabe later tho
.{
.format = wgpu.WGPUVertexFormat_Float32x3,
.offset = @offsetOf(Vertex, "position"),
.shaderLocation = 0, .shaderLocation = 0,
.format = wgpu.WGPUVertexFormat_Float32x2,
.offset = 0,
}, },
.arrayStride = 2 * @sizeOf(f32), .{
.format = wgpu.WGPUVertexFormat_Float32x3,
.offset = @offsetOf(Vertex, "normal"),
.shaderLocation = 1,
},
.{
.format = wgpu.WGPUVertexFormat_Float32x2,
.offset = @offsetOf(Vertex, "uv"),
.shaderLocation = 2,
},
},
.arrayStride = @sizeOf(Vertex),
.stepMode = wgpu.WGPUVertexStepMode_Vertex, .stepMode = wgpu.WGPUVertexStepMode_Vertex,
}, },
}, },

View file

@ -38,9 +38,7 @@ pub fn init(app: *App) !void {
res.device.queue, res.device.queue,
app.alloc, app.alloc,
)); ));
// _ = meshes; _ = meshes;
_ = try meshes.getOrCreate(.cube);
// TODO: Remove or place it somewhere else, idk // TODO: Remove or place it somewhere else, idk

View file

@ -20,7 +20,7 @@ pub fn begin(app: *App) !void {
try res.renderer.draw(.{ try res.renderer.draw(.{
.begin_pass = .{ .begin_pass = .{
.camera = undefined, .camera = undefined,
.color = .{ 0.08, 0.08, 0.8, 1.0 }, .color = .{ 0.001, 0.001, 0.001, 1.0 },
}, },
}); });
defer res.renderer.draw(.end_pass) catch unreachable; defer res.renderer.draw(.end_pass) catch unreachable;
@ -32,6 +32,14 @@ pub fn begin(app: *App) !void {
.material = .{}, .material = .{},
}, },
}); });
// --- # ---
try res.renderer.draw(.{
.draw = .{
.mesh = .triangle,
.material = .{},
},
});
} }
} }

View file

@ -97,10 +97,17 @@ pub fn draw(app: *App) !void {
const pipeline = try res.pipeline_cache.getOrCreate(v.material); const pipeline = try res.pipeline_cache.getOrCreate(v.material);
const mesh = try res.mesh_cache.getOrCreate(v.mesh); const mesh = try res.mesh_cache.getOrCreate(v.mesh);
// --- DRAW --- // --- BIND ---
wgpu.wgpuRenderPassEncoderSetPipeline(render_pass, pipeline.raw); wgpu.wgpuRenderPassEncoderSetPipeline(render_pass, pipeline.raw);
wgpu.wgpuRenderPassEncoderSetVertexBuffer(render_pass, 0, mesh.vbuf, 0, wgpu.wgpuBufferGetSize(mesh.vbuf)); wgpu.wgpuRenderPassEncoderSetVertexBuffer(render_pass, 0, mesh.vbuf, 0, wgpu.wgpuBufferGetSize(mesh.vbuf));
wgpu.wgpuRenderPassEncoderDraw(render_pass, @intCast(wgpu.wgpuBufferGetSize(mesh.vbuf) / (2 * @sizeOf(f32))), 1, 0, 0);
// --- DRAW ---
if (mesh.ibuf) |ibuf| {
wgpu.wgpuRenderPassEncoderSetIndexBuffer(render_pass, ibuf, wgpu.WGPUIndexFormat_Uint32, 0, wgpu.wgpuBufferGetSize(ibuf));
wgpu.wgpuRenderPassEncoderDrawIndexed(render_pass, mesh.index_count, 1, 0, 0, 0);
} else {
wgpu.wgpuRenderPassEncoderDraw(render_pass, mesh.vertex_count, 1, 0, 0);
}
}, },
else => {}, else => {},
} }