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
fn vs_main(
@location(0) in_vertex_position: vec2f
) -> @builtin(position) vec4f {
return vec4f(in_vertex_position, 0.0, 1.0);
fn vs_main(in: VertexInput) -> VertexOutput {
// --- # ---
var out: VertexOutput;
// --- # ---
out.position = vec4f(in.position, 1.0);
out.uv = in.uv;
out.normal = in.normal;
// --- # ---
return out;
}
//
// FRAGMENT
//
@fragment
fn fs_main() -> @location(0) vec4f {
return vec4f(0.001, 0.001, 0.001, 1.0);
fn fs_main(out: VertexOutput) -> @location(0) vec4f {
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 {
vbuf: *wgpu.WGPUBufferImpl,
ibuf: ?*wgpu.WGPUBufferImpl = null,
vertex_count: u32,
index_count: u32,
};
//
@ -77,42 +80,120 @@ pub fn getOrCreate(
self: *Self,
mesh: MeshID,
) !*GPUMesh {
return try self.data.getOrPut(mesh, .{
.vbuf = blk: {
// --- DATA ---
const vertices: []const f32 = switch (mesh) {
.triangle => &.{
-0.5, -0.5,
0.5, -0.5,
0.0, 0.5,
return try self.data.getOrPut(mesh, blk: {
// --- # ---
const vertices: []const Vertex = switch (mesh) {
.triangle => &.{
.{
.position = .{ -0.5, -0.5, 0.0 },
.normal = .{ 0.0, 0.0, 1.0 },
.uv = .{ 0.0, 0.0 },
},
.square => &.{
-0.5, -0.5,
0.5, -0.5,
0.5, 0.5,
-0.5, -0.5,
0.5, 0.5,
-0.5, 0.5,
.{
.position = .{ 0.5, -0.5, 0.0 },
.normal = .{ 0.0, 0.0, 1.0 },
.uv = .{ 1.0, 0.0 },
},
else => &.{},
};
.{
.position = .{ 0.0, 0.5, 0.0 },
.normal = .{ 0.0, 0.0, 1.0 },
.uv = .{ 0.5, 1.0 },
},
},
// --- GET SIZE ---
const size = vertices.len * @sizeOf(f32);
.square, .quad => &.{
.{
.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 },
},
},
// --- CREATE ---
const buff = wgpu.wgpuDeviceCreateBuffer(self.device, &wgpu.WGPUBufferDescriptor{
.size = size,
.usage = wgpu.WGPUBufferUsage_CopyDst | wgpu.WGPUBufferUsage_Vertex,
}) orelse return error.FailedToCreateBuffer;
else => &.{},
};
// --- WRITE ---
wgpu.wgpuQueueWriteBuffer(self.queue, buff, 0, vertices.ptr, size);
// --- # ---
const indices: []const u32 = switch (mesh) {
.square, .quad => &.{
0, 1, 2,
0, 2, 3,
},
// --- RESULT ---
break :blk buff;
},
.ibuf = null,
.triangle => &.{
0, 1, 2,
},
else => &.{},
};
// --- 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 ---
break :blk .{
.vbuf = vbuf,
.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 ShaderCache = @import("shader_cache.zig");
const Vertex = @import("mesh_cache.zig").Vertex;
/// ----------------------------------------------------
/// ----------------------------------------------------
@ -15,6 +16,13 @@ pub const GPUPipeline = struct {
raw: *wgpu.WGPURenderPipelineImpl,
};
/// ----------------------------------------------------
/// ----------------------------------------------------
pub const GPUMaterial = struct { // TODO: Should prob create Material Cache instead
buffer: *wgpu.WGPUBufferImpl,
bind_group: *wgpu.WGPUBindGroupImpl,
};
//
// FIELDS
//
@ -84,13 +92,25 @@ fn createPipeline(
.entryPoint = .{ .data = "vs_main", .length = wgpu.WGPU_STRLEN },
.bufferCount = 1,
.buffers = &wgpu.WGPUVertexBufferLayout{
.attributeCount = 1,
.attributes = &wgpu.WGPUVertexAttribute{ // TODO: Use Vertex attributes instead | Mabe mabe allow for custom, mabe mabe later tho
.shaderLocation = 0,
.format = wgpu.WGPUVertexFormat_Float32x2,
.offset = 0,
.attributeCount = 3,
.attributes = &[_]wgpu.WGPUVertexAttribute{ // TODO: Mabe mabe allow for custom, mabe mabe later tho
.{
.format = wgpu.WGPUVertexFormat_Float32x3,
.offset = @offsetOf(Vertex, "position"),
.shaderLocation = 0,
},
.{
.format = wgpu.WGPUVertexFormat_Float32x3,
.offset = @offsetOf(Vertex, "normal"),
.shaderLocation = 1,
},
.{
.format = wgpu.WGPUVertexFormat_Float32x2,
.offset = @offsetOf(Vertex, "uv"),
.shaderLocation = 2,
},
},
.arrayStride = 2 * @sizeOf(f32),
.arrayStride = @sizeOf(Vertex),
.stepMode = wgpu.WGPUVertexStepMode_Vertex,
},
},

View file

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

View file

@ -20,7 +20,7 @@ pub fn begin(app: *App) !void {
try res.renderer.draw(.{
.begin_pass = .{
.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;
@ -32,6 +32,14 @@ pub fn begin(app: *App) !void {
.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 mesh = try res.mesh_cache.getOrCreate(v.mesh);
// --- DRAW ---
// --- BIND ---
wgpu.wgpuRenderPassEncoderSetPipeline(render_pass, pipeline.raw);
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 => {},
}