Let there be proper shader layouts n stuff \o/
This commit is contained in:
parent
ccde4427be
commit
b03bb1a70a
21 changed files with 418 additions and 709 deletions
|
|
@ -21,8 +21,8 @@
|
||||||
.hash = "gtl-0.0.0-e3QoJMRYAADChgXn2sogTxsbUpEBSHjOGZeoEx4ccMMD",
|
.hash = "gtl-0.0.0-e3QoJMRYAADChgXn2sogTxsbUpEBSHjOGZeoEx4ccMMD",
|
||||||
},
|
},
|
||||||
.NYXMath = .{
|
.NYXMath = .{
|
||||||
.url = "git+http://192.168.0.11:25569/abux/NYXMath.git#58d57b61f3fa25e234af1af3e1e56bb656f4d77d",
|
.url = "git+http://192.168.0.11:25569/abux/NYXMath.git#cb7b54995bdb46321f112bba2a704d58cf53aeb1",
|
||||||
.hash = "NYXMath-0.0.0-BD6ST8zOAAB1dgmaGKShXtKmGTuYqgiDpAY2faHM_HnV",
|
.hash = "NYXMath-0.0.0-BD6ST9rOAAA0uSpPK_woZrta3nTh0f5w7hFewJ-e2Kv1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
// ----------------------------------------------------
|
|
||||||
// ----------------------------------------------------
|
|
||||||
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,
|
|
||||||
};
|
|
||||||
|
|
||||||
// ----------------------------------------------------
|
|
||||||
// ----------------------------------------------------
|
|
||||||
struct CameraUniform {
|
|
||||||
view: mat4x4<f32>,
|
|
||||||
projection: mat4x4<f32>,
|
|
||||||
view_projection: mat4x4<f32>,
|
|
||||||
camera_position: vec3<f32>,
|
|
||||||
_pad: f32,
|
|
||||||
};
|
|
||||||
|
|
||||||
// ----------------------------------------------------
|
|
||||||
// ----------------------------------------------------
|
|
||||||
struct ModelUniform {
|
|
||||||
model: mat4x4<f32>,
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// UNIFORMS
|
|
||||||
//
|
|
||||||
|
|
||||||
@group(0) @binding(0)
|
|
||||||
var<uniform> camera: CameraUniform;
|
|
||||||
|
|
||||||
@group(1) @binding(0)
|
|
||||||
var<uniform> model: ModelUniform;
|
|
||||||
|
|
||||||
@group(2) @binding(0)
|
|
||||||
var<uniform> material: Material;
|
|
||||||
|
|
||||||
//
|
|
||||||
// VERTEX
|
|
||||||
//
|
|
||||||
|
|
||||||
@vertex
|
|
||||||
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(out: VertexOutput) -> @location(0) vec4f {
|
|
||||||
var final_color: vec4f = material.albedo;
|
|
||||||
final_color.x += out.uv.x * 0.2;
|
|
||||||
final_color.y += out.uv.y * 0.2;
|
|
||||||
return vec4f(final_color);
|
|
||||||
}
|
|
||||||
41
src/plugins/cache/resource/mesh_cache.zig
vendored
41
src/plugins/cache/resource/mesh_cache.zig
vendored
|
|
@ -127,6 +127,38 @@ pub fn getOrCreate(
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
.cube => &.{
|
||||||
|
.{ .position = .{ -0.5, -0.5, 0.5 }, .normal = .{ 0, 0, 1 }, .uv = .{ 0, 1 } },
|
||||||
|
.{ .position = .{ 0.5, -0.5, 0.5 }, .normal = .{ 0, 0, 1 }, .uv = .{ 1, 1 } },
|
||||||
|
.{ .position = .{ 0.5, 0.5, 0.5 }, .normal = .{ 0, 0, 1 }, .uv = .{ 1, 0 } },
|
||||||
|
.{ .position = .{ -0.5, 0.5, 0.5 }, .normal = .{ 0, 0, 1 }, .uv = .{ 0, 0 } },
|
||||||
|
|
||||||
|
.{ .position = .{ 0.5, -0.5, -0.5 }, .normal = .{ 0, 0, -1 }, .uv = .{ 0, 1 } },
|
||||||
|
.{ .position = .{ -0.5, -0.5, -0.5 }, .normal = .{ 0, 0, -1 }, .uv = .{ 1, 1 } },
|
||||||
|
.{ .position = .{ -0.5, 0.5, -0.5 }, .normal = .{ 0, 0, -1 }, .uv = .{ 1, 0 } },
|
||||||
|
.{ .position = .{ 0.5, 0.5, -0.5 }, .normal = .{ 0, 0, -1 }, .uv = .{ 0, 0 } },
|
||||||
|
|
||||||
|
.{ .position = .{ -0.5, -0.5, -0.5 }, .normal = .{ -1, 0, 0 }, .uv = .{ 0, 1 } },
|
||||||
|
.{ .position = .{ -0.5, -0.5, 0.5 }, .normal = .{ -1, 0, 0 }, .uv = .{ 1, 1 } },
|
||||||
|
.{ .position = .{ -0.5, 0.5, 0.5 }, .normal = .{ -1, 0, 0 }, .uv = .{ 1, 0 } },
|
||||||
|
.{ .position = .{ -0.5, 0.5, -0.5 }, .normal = .{ -1, 0, 0 }, .uv = .{ 0, 0 } },
|
||||||
|
|
||||||
|
.{ .position = .{ 0.5, -0.5, 0.5 }, .normal = .{ 1, 0, 0 }, .uv = .{ 0, 1 } },
|
||||||
|
.{ .position = .{ 0.5, -0.5, -0.5 }, .normal = .{ 1, 0, 0 }, .uv = .{ 1, 1 } },
|
||||||
|
.{ .position = .{ 0.5, 0.5, -0.5 }, .normal = .{ 1, 0, 0 }, .uv = .{ 1, 0 } },
|
||||||
|
.{ .position = .{ 0.5, 0.5, 0.5 }, .normal = .{ 1, 0, 0 }, .uv = .{ 0, 0 } },
|
||||||
|
|
||||||
|
.{ .position = .{ -0.5, 0.5, 0.5 }, .normal = .{ 0, 1, 0 }, .uv = .{ 0, 1 } },
|
||||||
|
.{ .position = .{ 0.5, 0.5, 0.5 }, .normal = .{ 0, 1, 0 }, .uv = .{ 1, 1 } },
|
||||||
|
.{ .position = .{ 0.5, 0.5, -0.5 }, .normal = .{ 0, 1, 0 }, .uv = .{ 1, 0 } },
|
||||||
|
.{ .position = .{ -0.5, 0.5, -0.5 }, .normal = .{ 0, 1, 0 }, .uv = .{ 0, 0 } },
|
||||||
|
|
||||||
|
.{ .position = .{ -0.5, -0.5, -0.5 }, .normal = .{ 0, -1, 0 }, .uv = .{ 0, 1 } },
|
||||||
|
.{ .position = .{ 0.5, -0.5, -0.5 }, .normal = .{ 0, -1, 0 }, .uv = .{ 1, 1 } },
|
||||||
|
.{ .position = .{ 0.5, -0.5, 0.5 }, .normal = .{ 0, -1, 0 }, .uv = .{ 1, 0 } },
|
||||||
|
.{ .position = .{ -0.5, -0.5, 0.5 }, .normal = .{ 0, -1, 0 }, .uv = .{ 0, 0 } },
|
||||||
|
},
|
||||||
|
|
||||||
else => &.{},
|
else => &.{},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -141,6 +173,15 @@ pub fn getOrCreate(
|
||||||
0, 1, 2,
|
0, 1, 2,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
.cube => &.{
|
||||||
|
0, 1, 2, 0, 2, 3,
|
||||||
|
4, 5, 6, 4, 6, 7,
|
||||||
|
8, 9, 10, 8, 10, 11,
|
||||||
|
12, 13, 14, 12, 14, 15,
|
||||||
|
16, 17, 18, 16, 18, 19,
|
||||||
|
20, 21, 22, 20, 22, 23,
|
||||||
|
},
|
||||||
|
|
||||||
else => &.{},
|
else => &.{},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
332
src/plugins/cache/resource/pipeline_cache.zig.old
vendored
332
src/plugins/cache/resource/pipeline_cache.zig.old
vendored
|
|
@ -1,332 +0,0 @@
|
||||||
//! ----------------------------------------------------
|
|
||||||
//! TODO: Move [materials, materials_gpu and GPUMaterial somewhere else]
|
|
||||||
//! Depricated
|
|
||||||
//! ----------------------------------------------------
|
|
||||||
|
|
||||||
const std = @import("std");
|
|
||||||
const gtl = @import("gtl");
|
|
||||||
const wgpu = @import("wgpu");
|
|
||||||
const Self = @This();
|
|
||||||
|
|
||||||
const Material = @import("../../renderer/template/material.zig");
|
|
||||||
const ShaderCache = @import("shader_cache.zig");
|
|
||||||
const ShaderID = ShaderCache.ShaderID;
|
|
||||||
const Vertex = @import("mesh_cache.zig").Vertex;
|
|
||||||
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
pub const GPUPipeline = struct {
|
|
||||||
raw: *wgpu.WGPURenderPipelineImpl,
|
|
||||||
layout: *wgpu.WGPUPipelineLayoutImpl,
|
|
||||||
bind_group_layouts: [3]*wgpu.WGPUBindGroupLayoutImpl,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
pub const GPUMaterial = struct {
|
|
||||||
buffer: *wgpu.WGPUBufferImpl,
|
|
||||||
bind_group: *wgpu.WGPUBindGroupImpl,
|
|
||||||
dirty: bool = true,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
/// TODO: Mabe mabe switch to it, someday
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
pub const GPUUniform = struct {
|
|
||||||
buffer: wgpu.WGPUBuffer,
|
|
||||||
bind_group: wgpu.WGPUBindGroup,
|
|
||||||
dirty: bool = true,
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// FIELDS
|
|
||||||
//
|
|
||||||
|
|
||||||
pipelines: gtl.KeyedSlotMap(Material.Unique, GPUPipeline),
|
|
||||||
materials: gtl.SlotMap(Material),
|
|
||||||
materials_gpu: gtl.KeyedSlotMap(gtl.Handle(Material), GPUMaterial),
|
|
||||||
shader_cache: *ShaderCache,
|
|
||||||
queue: *wgpu.WGPUQueueImpl,
|
|
||||||
device: *wgpu.WGPUDeviceImpl,
|
|
||||||
alloc: std.mem.Allocator,
|
|
||||||
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
pub fn init(
|
|
||||||
shader_cache: *ShaderCache,
|
|
||||||
queue: *wgpu.WGPUQueueImpl,
|
|
||||||
device: *wgpu.WGPUDeviceImpl,
|
|
||||||
alloc: std.mem.Allocator,
|
|
||||||
) Self {
|
|
||||||
return .{
|
|
||||||
.pipelines = .init(alloc),
|
|
||||||
.materials = .init(alloc),
|
|
||||||
.materials_gpu = .init(alloc),
|
|
||||||
.shader_cache = shader_cache,
|
|
||||||
.queue = queue,
|
|
||||||
.device = device,
|
|
||||||
.alloc = alloc,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
pub fn deinit(self: *Self) void {
|
|
||||||
// --- FREE PIPELINES ---
|
|
||||||
for (self.pipelines.items()) |entry| {
|
|
||||||
wgpu.wgpuPipelineLayoutRelease(entry.value.layout);
|
|
||||||
wgpu.wgpuRenderPipelineRelease(entry.value.raw);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- FREE MATERIALS ---
|
|
||||||
for (self.materials_gpu.items()) |entry| {
|
|
||||||
wgpu.wgpuBufferRelease(entry.value.buffer);
|
|
||||||
wgpu.wgpuBindGroupRelease(entry.value.bind_group);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- # ---
|
|
||||||
self.pipelines.deinit();
|
|
||||||
self.materials.deinit();
|
|
||||||
self.materials_gpu.deinit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
pub fn getOrCreateMaterial(
|
|
||||||
self: *Self,
|
|
||||||
material_handle: gtl.Handle(Material),
|
|
||||||
) !*GPUMaterial {
|
|
||||||
return try self.materials_gpu.getOrPut(
|
|
||||||
material_handle,
|
|
||||||
blk: {
|
|
||||||
// --- # ---
|
|
||||||
if (self.materials_gpu.getByKey(material_handle)) |v| return v;
|
|
||||||
const material = self.materials.get(material_handle) orelse return error.MaterialNotFound;
|
|
||||||
|
|
||||||
// --- ENSURE PIPELINE ---
|
|
||||||
const pipeline = try self.getOrCreatePipeline(material);
|
|
||||||
|
|
||||||
// --- UNIFORM ---
|
|
||||||
const uniform = wgpu.wgpuDeviceCreateBuffer(self.device, &wgpu.WGPUBufferDescriptor{
|
|
||||||
.usage = wgpu.WGPUBufferUsage_CopyDst | wgpu.WGPUBufferUsage_Uniform,
|
|
||||||
.size = @sizeOf(Material.Style),
|
|
||||||
}) orelse return error.Buffer;
|
|
||||||
|
|
||||||
// --- WRITE TO UNIFORM ---
|
|
||||||
wgpu.wgpuQueueWriteBuffer(
|
|
||||||
self.queue,
|
|
||||||
uniform,
|
|
||||||
0,
|
|
||||||
&material.style,
|
|
||||||
@sizeOf(Material.Style),
|
|
||||||
);
|
|
||||||
|
|
||||||
// --- BIND GROUP ---
|
|
||||||
const bind_group = wgpu.wgpuDeviceCreateBindGroup(self.device, &wgpu.WGPUBindGroupDescriptor{
|
|
||||||
.layout = pipeline.bind_group_layouts[0],
|
|
||||||
.entryCount = 1,
|
|
||||||
.entries = &[_]wgpu.WGPUBindGroupEntry{
|
|
||||||
.{
|
|
||||||
.binding = 0,
|
|
||||||
.buffer = uniform,
|
|
||||||
.offset = 0,
|
|
||||||
.size = @sizeOf(Material.Style),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}) orelse return error.BindGroup;
|
|
||||||
|
|
||||||
// --- RESULT ---
|
|
||||||
break :blk .{
|
|
||||||
.buffer = uniform,
|
|
||||||
.bind_group = bind_group,
|
|
||||||
.dirty = false,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
pub fn getOrCreatePipeline(
|
|
||||||
self: *Self,
|
|
||||||
material: *const Material,
|
|
||||||
) !*GPUPipeline {
|
|
||||||
return try self.pipelines.getOrPut(material.unique, blk: {
|
|
||||||
// --- # ---
|
|
||||||
if (self.pipelines.getByKey(material.unique)) |v| return v;
|
|
||||||
|
|
||||||
//
|
|
||||||
// LAYOUTS
|
|
||||||
//
|
|
||||||
|
|
||||||
// --- CAMERA ---
|
|
||||||
const camera_layout = wgpu.wgpuDeviceCreateBindGroupLayout(self.device, &wgpu.WGPUBindGroupLayoutDescriptor{
|
|
||||||
.entryCount = 1,
|
|
||||||
.entries = &[_]wgpu.WGPUBindGroupLayoutEntry{
|
|
||||||
.{
|
|
||||||
.binding = 0,
|
|
||||||
.visibility = wgpu.WGPUShaderStage_Vertex | wgpu.WGPUShaderStage_Fragment,
|
|
||||||
.buffer = .{
|
|
||||||
.type = wgpu.WGPUBufferBindingType_Uniform,
|
|
||||||
.minBindingSize = @sizeOf(Material.Style),
|
|
||||||
.hasDynamicOffset = 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}) orelse return error.BindGroupLayout;
|
|
||||||
|
|
||||||
// --- MODEL ---
|
|
||||||
const model_layout = wgpu.wgpuDeviceCreateBindGroupLayout(self.device, &wgpu.WGPUBindGroupLayoutDescriptor{
|
|
||||||
.entryCount = 1,
|
|
||||||
.entries = &[_]wgpu.WGPUBindGroupLayoutEntry{
|
|
||||||
.{
|
|
||||||
.binding = 0,
|
|
||||||
.visibility = wgpu.WGPUShaderStage_Vertex | wgpu.WGPUShaderStage_Fragment,
|
|
||||||
.buffer = .{
|
|
||||||
.type = wgpu.WGPUBufferBindingType_Uniform,
|
|
||||||
.minBindingSize = @sizeOf(Material.Style),
|
|
||||||
.hasDynamicOffset = 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}) orelse return error.BindGroupLayout;
|
|
||||||
|
|
||||||
// --- MATERIAL ---
|
|
||||||
const material_layout = wgpu.wgpuDeviceCreateBindGroupLayout(self.device, &wgpu.WGPUBindGroupLayoutDescriptor{
|
|
||||||
.entryCount = 1,
|
|
||||||
.entries = &[_]wgpu.WGPUBindGroupLayoutEntry{
|
|
||||||
.{
|
|
||||||
.binding = 0,
|
|
||||||
.visibility = wgpu.WGPUShaderStage_Vertex | wgpu.WGPUShaderStage_Fragment,
|
|
||||||
.buffer = .{
|
|
||||||
.type = wgpu.WGPUBufferBindingType_Uniform,
|
|
||||||
.minBindingSize = @sizeOf(Material.Style),
|
|
||||||
.hasDynamicOffset = 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}) orelse return error.BindGroupLayout;
|
|
||||||
|
|
||||||
var bind_group_layouts = [_]wgpu.WGPUBindGroupLayout{
|
|
||||||
camera_layout,
|
|
||||||
model_layout,
|
|
||||||
material_layout,
|
|
||||||
};
|
|
||||||
|
|
||||||
// --- PIPELINE LAYOUT ---
|
|
||||||
const pipeline_layout = wgpu.wgpuDeviceCreatePipelineLayout(
|
|
||||||
self.device,
|
|
||||||
&wgpu.WGPUPipelineLayoutDescriptor{
|
|
||||||
.bindGroupLayoutCount = 3,
|
|
||||||
.bindGroupLayouts = &bind_group_layouts,
|
|
||||||
},
|
|
||||||
) orelse return error.Layout;
|
|
||||||
|
|
||||||
// --- CREATE PIPELINE ---
|
|
||||||
const pipeline = try self.createPipeline(
|
|
||||||
material.unique,
|
|
||||||
pipeline_layout,
|
|
||||||
);
|
|
||||||
|
|
||||||
// --- RESULT ---
|
|
||||||
break :blk .{
|
|
||||||
.raw = pipeline,
|
|
||||||
.layout = pipeline_layout,
|
|
||||||
.bind_group_layouts = .{
|
|
||||||
camera_layout,
|
|
||||||
model_layout,
|
|
||||||
material_layout,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
fn createPipeline(
|
|
||||||
self: *Self,
|
|
||||||
key: Material.Unique,
|
|
||||||
layout: *wgpu.WGPUPipelineLayoutImpl,
|
|
||||||
) !*wgpu.WGPURenderPipelineImpl {
|
|
||||||
// --- ENSURE SHADER MODULE ---
|
|
||||||
const shader_module = try self.shader_cache.getOrCreate(
|
|
||||||
key.shader,
|
|
||||||
);
|
|
||||||
|
|
||||||
// --- RESULT ---
|
|
||||||
return wgpu.wgpuDeviceCreateRenderPipeline(self.device, &wgpu.WGPURenderPipelineDescriptor{
|
|
||||||
.label = .{ .data = @tagName(key.shader), .length = wgpu.WGPU_STRLEN },
|
|
||||||
.layout = layout,
|
|
||||||
.vertex = .{
|
|
||||||
.module = shader_module.raw,
|
|
||||||
.entryPoint = .{ .data = "vs_main", .length = wgpu.WGPU_STRLEN },
|
|
||||||
.bufferCount = 1,
|
|
||||||
.buffers = &wgpu.WGPUVertexBufferLayout{
|
|
||||||
.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 = @sizeOf(Vertex),
|
|
||||||
.stepMode = wgpu.WGPUVertexStepMode_Vertex,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.fragment = &wgpu.WGPUFragmentState{
|
|
||||||
.module = shader_module.raw,
|
|
||||||
.entryPoint = .{ .data = "fs_main", .length = wgpu.WGPU_STRLEN },
|
|
||||||
.targetCount = 1,
|
|
||||||
.targets = &wgpu.WGPUColorTargetState{
|
|
||||||
.format = 28, // FIX: Use proper format
|
|
||||||
.blend = &wgpu.WGPUBlendState{
|
|
||||||
.color = .{
|
|
||||||
.srcFactor = wgpu.WGPUBlendFactor_SrcAlpha,
|
|
||||||
.dstFactor = wgpu.WGPUBlendFactor_OneMinusSrcAlpha,
|
|
||||||
.operation = wgpu.WGPUBlendOperation_Add,
|
|
||||||
},
|
|
||||||
.alpha = .{
|
|
||||||
.srcFactor = wgpu.WGPUBlendFactor_Zero,
|
|
||||||
.dstFactor = wgpu.WGPUBlendFactor_One,
|
|
||||||
.operation = wgpu.WGPUBlendOperation_Add,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.writeMask = wgpu.WGPUColorWriteMask_All,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.primitive = .{
|
|
||||||
.topology = switch (key.topology) {
|
|
||||||
.triangle_list => wgpu.WGPUPrimitiveTopology_TriangleList,
|
|
||||||
.point_list => wgpu.WGPUPrimitiveTopology_PointList,
|
|
||||||
.line_list => wgpu.WGPUPrimitiveTopology_LineList,
|
|
||||||
},
|
|
||||||
.frontFace = switch (key.front_face) {
|
|
||||||
.ccw => wgpu.WGPUFrontFace_CCW,
|
|
||||||
.cw => wgpu.WGPUFrontFace_CW,
|
|
||||||
},
|
|
||||||
.cullMode = switch (key.cull_mode) {
|
|
||||||
.back => wgpu.WGPUCullMode_Back,
|
|
||||||
.front => wgpu.WGPUCullMode_Front,
|
|
||||||
.none => wgpu.WGPUCullMode_None,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.multisample = .{
|
|
||||||
.count = 1,
|
|
||||||
.mask = ~@as(u32, 0),
|
|
||||||
.alphaToCoverageEnabled = 0,
|
|
||||||
},
|
|
||||||
}) orelse {
|
|
||||||
return error.PipelineCreationFailed;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
103
src/plugins/cache/resource/shader_cache.zig.old
vendored
103
src/plugins/cache/resource/shader_cache.zig.old
vendored
|
|
@ -1,103 +0,0 @@
|
||||||
//! ----------------------------------------------------
|
|
||||||
//! ----------------------------------------------------
|
|
||||||
|
|
||||||
const std = @import("std");
|
|
||||||
const gtl = @import("gtl");
|
|
||||||
const wgpu = @import("wgpu");
|
|
||||||
const Self = @This();
|
|
||||||
|
|
||||||
//
|
|
||||||
// EMBEDED
|
|
||||||
//
|
|
||||||
|
|
||||||
const PBRCode = @embedFile("embeded/shaders/pbr.wgsl");
|
|
||||||
const UnlitCode = @embedFile("embeded/shaders/pbr.wgsl");
|
|
||||||
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
pub const ShaderID = union(enum) {
|
|
||||||
pbr,
|
|
||||||
unlit,
|
|
||||||
custom: u32,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
pub const GPUShader = struct {
|
|
||||||
raw: *wgpu.WGPUShaderModuleImpl,
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// FIELDS
|
|
||||||
//
|
|
||||||
|
|
||||||
modules: gtl.KeyedSlotMap(ShaderID, GPUShader),
|
|
||||||
custom_paths: std.ArrayList([]const u8),
|
|
||||||
device: *wgpu.WGPUDeviceImpl,
|
|
||||||
alloc: std.mem.Allocator,
|
|
||||||
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
pub fn init(
|
|
||||||
device: *wgpu.WGPUDeviceImpl,
|
|
||||||
alloc: std.mem.Allocator,
|
|
||||||
) Self {
|
|
||||||
return .{
|
|
||||||
.modules = .init(alloc),
|
|
||||||
.custom_paths = .empty,
|
|
||||||
.device = device,
|
|
||||||
.alloc = alloc,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
pub fn deinit(self: *Self) void {
|
|
||||||
// --- FREE SHADERS ---
|
|
||||||
for (self.modules.items()) |entry| {
|
|
||||||
wgpu.wgpuShaderModuleRelease(entry.value.raw);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- # ---
|
|
||||||
self.modules.deinit();
|
|
||||||
self.custom_paths.deinit(self.alloc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
pub fn getOrCreate(
|
|
||||||
self: *Self,
|
|
||||||
key: ShaderID,
|
|
||||||
) !*GPUShader {
|
|
||||||
return try self.modules.getOrPut(key, .{
|
|
||||||
.raw = try self.createShader(key),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
/// ----------------------------------------------------
|
|
||||||
fn createShader(
|
|
||||||
self: *Self,
|
|
||||||
key: ShaderID,
|
|
||||||
) !*wgpu.WGPUShaderModuleImpl {
|
|
||||||
// --- CODE ---
|
|
||||||
const code: []const u8 = switch (key) {
|
|
||||||
.pbr => PBRCode,
|
|
||||||
.unlit => UnlitCode,
|
|
||||||
.custom => |v| self.custom_paths.items[@intCast(v)], // TODO: Handle out of bounds
|
|
||||||
};
|
|
||||||
|
|
||||||
// --- SOURCE ---
|
|
||||||
var source: wgpu.WGPUShaderSourceWGSL = .{
|
|
||||||
.chain = .{ .sType = wgpu.WGPUSType_ShaderSourceWGSL },
|
|
||||||
.code = .{ .data = code.ptr, .length = wgpu.WGPU_STRLEN },
|
|
||||||
};
|
|
||||||
|
|
||||||
// --- RESULT ---
|
|
||||||
return wgpu.wgpuDeviceCreateShaderModule(self.device, &wgpu.WGPUShaderModuleDescriptor{
|
|
||||||
.label = .{ .data = @tagName(key), .length = wgpu.WGPU_STRLEN },
|
|
||||||
.nextInChain = &source.chain,
|
|
||||||
}) orelse {
|
|
||||||
return error.ShaderModuleCreationFailed;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -11,7 +11,7 @@ projection: union(enum) {
|
||||||
far: f32 = 4000.0,
|
far: f32 = 4000.0,
|
||||||
near: f32 = 0.05,
|
near: f32 = 0.05,
|
||||||
},
|
},
|
||||||
} = .{ .ortho = .{} },
|
},
|
||||||
|
|
||||||
target: union(enum) {
|
target: union(enum) {
|
||||||
window,
|
window,
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,4 @@ const math = @import("math");
|
||||||
|
|
||||||
position: math.Vec3f = .as(0),
|
position: math.Vec3f = .as(0),
|
||||||
rotation: math.Quat = .identity(),
|
rotation: math.Quat = .identity(),
|
||||||
scale: math.Vec3f = .as(0),
|
scale: math.Vec3f = .as(1),
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
// PRIVATE
|
// PRIVATE
|
||||||
//
|
//
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
const App = @import("app");
|
const App = @import("app");
|
||||||
|
|
||||||
const Camera = @import("../common/component/camera.zig");
|
const Camera = @import("../common/component/camera.zig");
|
||||||
|
|
@ -34,6 +35,8 @@ fn build(
|
||||||
try app.schedules.addAfter(App.stage.init, App.stage.init, start);
|
try app.schedules.addAfter(App.stage.init, App.stage.init, start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const FlyCamera = struct {};
|
||||||
|
|
||||||
/// ----------------------------------------------------
|
/// ----------------------------------------------------
|
||||||
/// ----------------------------------------------------
|
/// ----------------------------------------------------
|
||||||
fn start(app: *App) !void {
|
fn start(app: *App) !void {
|
||||||
|
|
@ -44,36 +47,68 @@ fn start(app: *App) !void {
|
||||||
|
|
||||||
// --- CAMERA ---
|
// --- CAMERA ---
|
||||||
try app.world.spawn(.{
|
try app.world.spawn(.{
|
||||||
Camera{},
|
FlyCamera{},
|
||||||
Transform3D{},
|
Camera{
|
||||||
|
.projection = .{
|
||||||
|
.perspective = .{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Transform3D{
|
||||||
|
.position = .new(.{ 0, -2.5, -6.5 }),
|
||||||
|
.rotation = .fromEuler(.init(
|
||||||
|
-std.math.degreesToRadians(30),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
)),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// --- # ---
|
// --- # ---
|
||||||
try app.world.spawn(.{
|
try app.world.spawn(.{
|
||||||
Mesh{ .value = .square },
|
Mesh{ .value = .cube },
|
||||||
Material{
|
Material{
|
||||||
.value = try render_world.materials.put(.{
|
.value = try render_world.materials.put(.{
|
||||||
.style = .{
|
.style = .{
|
||||||
.albedo = .{ 0.8, 0.2, 0.2, 1.0 },
|
.albedo = .{ 0.8, 0.2, 0.2, 1.0 },
|
||||||
},
|
},
|
||||||
.unique = .{
|
.unique = .{
|
||||||
.topology = .line_list,
|
.cull_mode = .none,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
Transform3D{},
|
Transform3D{},
|
||||||
});
|
});
|
||||||
|
|
||||||
// --- # ---
|
const count: usize = 100;
|
||||||
|
const radius: f32 = 5.0;
|
||||||
|
|
||||||
|
for (0..count) |i| {
|
||||||
|
const angle = (@as(f32, @floatFromInt(i)) / @as(f32, @floatFromInt(count))) * std.math.tau;
|
||||||
|
|
||||||
try app.world.spawn(.{
|
try app.world.spawn(.{
|
||||||
Mesh{ .value = .triangle },
|
Mesh{ .value = .cube },
|
||||||
Material{
|
Material{
|
||||||
.value = try render_world.materials.put(.{
|
.value = try render_world.materials.put(.{
|
||||||
.style = .{
|
.style = .{
|
||||||
.albedo = .{ 0.2, 0.2, 0.8, 1 },
|
.albedo = .{ 0.2, 0.2, 0.8, 1 },
|
||||||
},
|
},
|
||||||
|
.unique = .{
|
||||||
|
.cull_mode = .none,
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
Transform3D{},
|
Transform3D{
|
||||||
|
.position = .new(.{
|
||||||
|
@cos(angle) * radius,
|
||||||
|
0,
|
||||||
|
@sin(angle) * radius,
|
||||||
|
}),
|
||||||
|
.rotation = .fromEuler(.init(
|
||||||
|
std.math.degreesToRadians(180),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
)),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,29 +14,26 @@ struct VertexOutput {
|
||||||
@location(1) normal: vec3f,
|
@location(1) normal: vec3f,
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------
|
|
||||||
// ----------------------------------------------------
|
|
||||||
struct Material {
|
|
||||||
albedo: vec4f,
|
|
||||||
metallic: f32,
|
|
||||||
roughness: f32,
|
|
||||||
_pad0: vec2f,
|
|
||||||
};
|
|
||||||
|
|
||||||
// ----------------------------------------------------
|
// ----------------------------------------------------
|
||||||
// ----------------------------------------------------
|
// ----------------------------------------------------
|
||||||
struct CameraUniform {
|
struct CameraUniform {
|
||||||
view: mat4x4<f32>,
|
view: mat4x4<f32>,
|
||||||
projection: mat4x4<f32>,
|
projection: mat4x4<f32>,
|
||||||
view_projection: mat4x4<f32>,
|
|
||||||
camera_position: vec3<f32>,
|
|
||||||
_pad: f32,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------
|
// ----------------------------------------------------
|
||||||
// ----------------------------------------------------
|
// ----------------------------------------------------
|
||||||
struct ModelUniform {
|
struct ModelUniform {
|
||||||
model: mat4x4<f32>,
|
data: mat4x4<f32>,
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------
|
||||||
|
// ----------------------------------------------------
|
||||||
|
struct Material {
|
||||||
|
albedo: vec4f,
|
||||||
|
metallic: f32,
|
||||||
|
roughness: f32,
|
||||||
|
_pad0: vec2f,
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -62,7 +59,7 @@ fn vs_main(in: VertexInput) -> VertexOutput {
|
||||||
var out: VertexOutput;
|
var out: VertexOutput;
|
||||||
|
|
||||||
// --- # ---
|
// --- # ---
|
||||||
out.position = vec4f(in.position, 1.0);
|
out.position = camera.projection * camera.view * model.data * vec4f(in.position, 1.0);
|
||||||
out.uv = in.uv;
|
out.uv = in.uv;
|
||||||
out.normal = in.normal;
|
out.normal = in.normal;
|
||||||
|
|
||||||
|
|
|
||||||
5
src/plugins/renderer/resource/render_layout.zig
Normal file
5
src/plugins/renderer/resource/render_layout.zig
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
const wgpu = @import("wgpu");
|
||||||
|
|
||||||
|
camera: *wgpu.WGPUBindGroupLayoutImpl,
|
||||||
|
model: *wgpu.WGPUBindGroupLayoutImpl,
|
||||||
|
material: *wgpu.WGPUBindGroupLayoutImpl,
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const gtl = @import("gtl");
|
const gtl = @import("gtl");
|
||||||
const wgpu = @import("wgpu");
|
const wgpu = @import("wgpu");
|
||||||
|
pub const Entity = u64; // TODO: You lazy retard
|
||||||
|
|
||||||
// --- CAMERA ---
|
// --- CAMERA ---
|
||||||
pub const GPUCamera = @import("../template/gpu_camera.zig");
|
pub const GPUCamera = @import("../template/gpu_camera.zig");
|
||||||
|
|
@ -23,7 +24,8 @@ pub const Pipeline = Material.Unique;
|
||||||
pub const GPUPipeline = @import("../template/gpu_pipeline.zig");
|
pub const GPUPipeline = @import("../template/gpu_pipeline.zig");
|
||||||
|
|
||||||
// --- OBJECT ---
|
// --- OBJECT ---
|
||||||
pub const Entity = u64; // TODO: You lazy retard
|
pub const MeshID = @import("../../cache/resource/mesh_cache.zig").MeshID;
|
||||||
|
pub const GPUObject = @import("../template/gpu_object.zig");
|
||||||
pub const FrameObject = @import("../template/frame_object.zig");
|
pub const FrameObject = @import("../template/frame_object.zig");
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -38,6 +40,7 @@ pub const UnlitCode = @embedFile("embeded/shaders/pbr.wgsl");
|
||||||
//
|
//
|
||||||
|
|
||||||
gpu_cameras: gtl.KeyedSlotMap(Entity, GPUCamera),
|
gpu_cameras: gtl.KeyedSlotMap(Entity, GPUCamera),
|
||||||
|
gpu_objects: gtl.KeyedSlotMap(Entity, GPUObject),
|
||||||
gpu_shaders: gtl.KeyedSlotMap(ShaderID, GPUShader),
|
gpu_shaders: gtl.KeyedSlotMap(ShaderID, GPUShader),
|
||||||
gpu_pipelines: gtl.KeyedSlotMap(Pipeline, GPUPipeline),
|
gpu_pipelines: gtl.KeyedSlotMap(Pipeline, GPUPipeline),
|
||||||
gpu_materials: gtl.KeyedSlotMap(gtl.Handle(Material), GPUMaterial),
|
gpu_materials: gtl.KeyedSlotMap(gtl.Handle(Material), GPUMaterial),
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ const Camera = struct {};
|
||||||
pub const DrawCMD = union(enum) {
|
pub const DrawCMD = union(enum) {
|
||||||
draw: struct {
|
draw: struct {
|
||||||
mesh: Mesh,
|
mesh: Mesh,
|
||||||
|
entity: u64,
|
||||||
material: Handle(Material),
|
material: Handle(Material),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@ const present = @import("system/present.zig");
|
||||||
//
|
//
|
||||||
|
|
||||||
const Renderer = @import("resource/renderer.zig");
|
const Renderer = @import("resource/renderer.zig");
|
||||||
|
const RenderWorld = @import("resource/render_world.zig");
|
||||||
|
const RenderLayout = @import("resource/render_layout.zig");
|
||||||
|
|
||||||
/// ----------------------------------------------------
|
/// ----------------------------------------------------
|
||||||
/// ----------------------------------------------------
|
/// ----------------------------------------------------
|
||||||
|
|
@ -41,9 +43,11 @@ fn build(
|
||||||
|
|
||||||
// --- PRE DRAW ---
|
// --- PRE DRAW ---
|
||||||
try app.schedules.addManyBefore(App.stage.draw, App.stage.draw, &.{
|
try app.schedules.addManyBefore(App.stage.draw, App.stage.draw, &.{
|
||||||
prepare.cameras,
|
|
||||||
prepare.shaders,
|
prepare.shaders,
|
||||||
prepare.pipelines,
|
prepare.pipelines,
|
||||||
|
|
||||||
|
prepare.cameras,
|
||||||
|
prepare.objects,
|
||||||
prepare.materials,
|
prepare.materials,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ pub fn begin(app: *App) !void {
|
||||||
// --- # ---
|
// --- # ---
|
||||||
res.renderer.clear();
|
res.renderer.clear();
|
||||||
|
|
||||||
// --- DRAW ---
|
// --- # ---
|
||||||
for (res.render_world.frame_views.items) |view| {
|
for (res.render_world.frame_views.items) |view| {
|
||||||
// --- NEW PASS ---
|
// --- NEW PASS ---
|
||||||
try res.renderer.draw(.{
|
try res.renderer.draw(.{
|
||||||
|
|
@ -33,11 +33,12 @@ pub fn begin(app: *App) !void {
|
||||||
});
|
});
|
||||||
defer res.renderer.draw(.end_pass) catch unreachable;
|
defer res.renderer.draw(.end_pass) catch unreachable;
|
||||||
|
|
||||||
// --- # ---
|
// --- DRAW ---
|
||||||
for (res.render_world.frame_objects.items) |obj| {
|
for (res.render_world.frame_objects.items) |obj| {
|
||||||
try res.renderer.draw(.{
|
try res.renderer.draw(.{
|
||||||
.draw = .{
|
.draw = .{
|
||||||
.material = obj.material,
|
.material = obj.material,
|
||||||
|
.entity = obj.entity,
|
||||||
.mesh = obj.mesh,
|
.mesh = obj.mesh,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -47,48 +48,6 @@ pub fn begin(app: *App) !void {
|
||||||
// --- YES ---
|
// --- YES ---
|
||||||
res.render_world.frame_views.clearRetainingCapacity();
|
res.render_world.frame_views.clearRetainingCapacity();
|
||||||
res.render_world.frame_objects.clearRetainingCapacity();
|
res.render_world.frame_objects.clearRetainingCapacity();
|
||||||
|
|
||||||
// { // TEST
|
|
||||||
// // --- DRAW ---
|
|
||||||
// try res.renderer.draw(.{
|
|
||||||
// .begin_pass = .{
|
|
||||||
// .camera = undefined,
|
|
||||||
// .color = .{ 0.001, 0.001, 0.001, 1.0 },
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
// defer res.renderer.draw(.end_pass) catch unreachable;
|
|
||||||
//
|
|
||||||
// // --- # ---
|
|
||||||
// try res.renderer.draw(.{
|
|
||||||
// .draw = .{
|
|
||||||
// .mesh = .square,
|
|
||||||
// .material = .{
|
|
||||||
// .style = .{
|
|
||||||
// .albedo = .{ 0.2, 0.8, 0.2, 1.0 },
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// { // TEST
|
|
||||||
// // --- DRAW ---
|
|
||||||
// try res.renderer.draw(.{
|
|
||||||
// .begin_pass = .{
|
|
||||||
// .camera = undefined,
|
|
||||||
// .load_op = .load,
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
// defer res.renderer.draw(.end_pass) catch unreachable;
|
|
||||||
//
|
|
||||||
// // --- # ---
|
|
||||||
// try res.renderer.draw(.{
|
|
||||||
// .draw = .{
|
|
||||||
// .mesh = .triangle,
|
|
||||||
// .material = .{},
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ----------------------------------------------------
|
/// ----------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,24 @@ const wgpu = @import("wgpu");
|
||||||
const App = @import("app");
|
const App = @import("app");
|
||||||
const Zla = @import("zla");
|
const Zla = @import("zla");
|
||||||
|
|
||||||
|
const WGPUDevice = @import("../../device/resource/wgpu_device.zig");
|
||||||
const Renderer = @import("../resource/renderer.zig");
|
const Renderer = @import("../resource/renderer.zig");
|
||||||
const RenderWorld = @import("../resource/render_world.zig");
|
const RenderWorld = @import("../resource/render_world.zig");
|
||||||
|
const RenderLayout = @import("../resource/render_layout.zig");
|
||||||
|
|
||||||
|
// --- TEMPLATES ---
|
||||||
|
const TMaterial = @import("../template/material.zig");
|
||||||
|
const TCamera = @import("../template/gpu_camera.zig");
|
||||||
|
const TMesh = @import("../template/gpu_object.zig");
|
||||||
|
|
||||||
/// ----------------------------------------------------
|
/// ----------------------------------------------------
|
||||||
/// ----------------------------------------------------
|
/// ----------------------------------------------------
|
||||||
pub fn init(app: *App) !void {
|
pub fn init(app: *App) !void {
|
||||||
|
// --- # ---
|
||||||
|
const res = try app.resources.getMany(struct {
|
||||||
|
device: *WGPUDevice,
|
||||||
|
});
|
||||||
|
|
||||||
// --- # ---
|
// --- # ---
|
||||||
try app.resources.set(Renderer.init(
|
try app.resources.set(Renderer.init(
|
||||||
app.alloc,
|
app.alloc,
|
||||||
|
|
@ -19,6 +31,7 @@ pub fn init(app: *App) !void {
|
||||||
// --- # ---
|
// --- # ---
|
||||||
try app.resources.set(RenderWorld{
|
try app.resources.set(RenderWorld{
|
||||||
.gpu_cameras = .init(app.alloc),
|
.gpu_cameras = .init(app.alloc),
|
||||||
|
.gpu_objects = .init(app.alloc),
|
||||||
.gpu_shaders = .init(app.alloc),
|
.gpu_shaders = .init(app.alloc),
|
||||||
.gpu_materials = .init(app.alloc),
|
.gpu_materials = .init(app.alloc),
|
||||||
.gpu_pipelines = .init(app.alloc),
|
.gpu_pipelines = .init(app.alloc),
|
||||||
|
|
@ -28,6 +41,54 @@ pub fn init(app: *App) !void {
|
||||||
|
|
||||||
.materials = .init(app.alloc),
|
.materials = .init(app.alloc),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// --- # ---
|
||||||
|
try app.resources.set(RenderLayout{
|
||||||
|
.camera = wgpu.wgpuDeviceCreateBindGroupLayout(res.device.raw, &wgpu.WGPUBindGroupLayoutDescriptor{
|
||||||
|
.entryCount = 1,
|
||||||
|
.entries = &[_]wgpu.WGPUBindGroupLayoutEntry{
|
||||||
|
.{
|
||||||
|
.binding = 0,
|
||||||
|
.visibility = wgpu.WGPUShaderStage_Vertex | wgpu.WGPUShaderStage_Fragment,
|
||||||
|
.buffer = .{
|
||||||
|
.type = wgpu.WGPUBufferBindingType_Uniform,
|
||||||
|
.minBindingSize = @sizeOf(TCamera.Uniform),
|
||||||
|
.hasDynamicOffset = 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}) orelse return error.CameraBindGroupLayout,
|
||||||
|
|
||||||
|
.model = wgpu.wgpuDeviceCreateBindGroupLayout(res.device.raw, &wgpu.WGPUBindGroupLayoutDescriptor{
|
||||||
|
.entryCount = 1,
|
||||||
|
.entries = &[_]wgpu.WGPUBindGroupLayoutEntry{
|
||||||
|
.{
|
||||||
|
.binding = 0,
|
||||||
|
.visibility = wgpu.WGPUShaderStage_Vertex | wgpu.WGPUShaderStage_Fragment,
|
||||||
|
.buffer = .{
|
||||||
|
.type = wgpu.WGPUBufferBindingType_Uniform,
|
||||||
|
.minBindingSize = @sizeOf(TMesh.Uniform),
|
||||||
|
.hasDynamicOffset = 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}) orelse return error.ModelBindGroupLayout,
|
||||||
|
|
||||||
|
.material = wgpu.wgpuDeviceCreateBindGroupLayout(res.device.raw, &wgpu.WGPUBindGroupLayoutDescriptor{
|
||||||
|
.entryCount = 1,
|
||||||
|
.entries = &[_]wgpu.WGPUBindGroupLayoutEntry{
|
||||||
|
.{
|
||||||
|
.binding = 0,
|
||||||
|
.visibility = wgpu.WGPUShaderStage_Vertex | wgpu.WGPUShaderStage_Fragment,
|
||||||
|
.buffer = .{
|
||||||
|
.type = wgpu.WGPUBufferBindingType_Uniform,
|
||||||
|
.minBindingSize = @sizeOf(TMaterial.Style),
|
||||||
|
.hasDynamicOffset = 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}) orelse return error.MaterialBindGroupLayout,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ----------------------------------------------------
|
/// ----------------------------------------------------
|
||||||
|
|
@ -37,6 +98,7 @@ pub fn deinit(app: *App) !void {
|
||||||
const res = try app.resources.getMany(struct {
|
const res = try app.resources.getMany(struct {
|
||||||
ren: *Renderer,
|
ren: *Renderer,
|
||||||
ren_world: *RenderWorld,
|
ren_world: *RenderWorld,
|
||||||
|
ren_layout: *RenderLayout,
|
||||||
});
|
});
|
||||||
|
|
||||||
// --- FREE SHADERS ---
|
// --- FREE SHADERS ---
|
||||||
|
|
@ -56,11 +118,29 @@ pub fn deinit(app: *App) !void {
|
||||||
wgpu.wgpuBindGroupRelease(entry.value.bind_group);
|
wgpu.wgpuBindGroupRelease(entry.value.bind_group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- FREE CAMERAS ---
|
||||||
|
for (res.ren_world.gpu_cameras.items()) |entry| {
|
||||||
|
wgpu.wgpuBufferRelease(entry.value.buffer);
|
||||||
|
wgpu.wgpuBindGroupRelease(entry.value.bind_group);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- FREE OBJECTS ---
|
||||||
|
for (res.ren_world.gpu_objects.items()) |entry| {
|
||||||
|
wgpu.wgpuBufferRelease(entry.value.buffer);
|
||||||
|
wgpu.wgpuBindGroupRelease(entry.value.bind_group);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- FREE LAYOUTS ---
|
||||||
|
wgpu.wgpuBindGroupLayoutRelease(res.ren_layout.camera);
|
||||||
|
wgpu.wgpuBindGroupLayoutRelease(res.ren_layout.model);
|
||||||
|
wgpu.wgpuBindGroupLayoutRelease(res.ren_layout.material);
|
||||||
|
|
||||||
// --- # ---
|
// --- # ---
|
||||||
res.ren_world.materials.deinit();
|
res.ren_world.materials.deinit();
|
||||||
res.ren_world.frame_views.deinit(app.alloc);
|
res.ren_world.frame_views.deinit(app.alloc);
|
||||||
res.ren_world.frame_objects.deinit(app.alloc);
|
res.ren_world.frame_objects.deinit(app.alloc);
|
||||||
res.ren_world.gpu_cameras.deinit();
|
res.ren_world.gpu_cameras.deinit();
|
||||||
|
res.ren_world.gpu_objects.deinit();
|
||||||
res.ren_world.gpu_shaders.deinit();
|
res.ren_world.gpu_shaders.deinit();
|
||||||
res.ren_world.gpu_materials.deinit();
|
res.ren_world.gpu_materials.deinit();
|
||||||
res.ren_world.gpu_pipelines.deinit();
|
res.ren_world.gpu_pipelines.deinit();
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
// --- # ---
|
// --- # ---
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const math = @import("math");
|
||||||
const wgpu = @import("wgpu");
|
const wgpu = @import("wgpu");
|
||||||
const App = @import("app");
|
const App = @import("app");
|
||||||
const Zla = @import("zla");
|
const Zla = @import("zla");
|
||||||
|
|
@ -11,6 +12,7 @@ const Zla = @import("zla");
|
||||||
const Vertex = @import("../../cache/resource/mesh_cache.zig").Vertex;
|
const Vertex = @import("../../cache/resource/mesh_cache.zig").Vertex;
|
||||||
const WGPUDevice = @import("../../device/resource/wgpu_device.zig");
|
const WGPUDevice = @import("../../device/resource/wgpu_device.zig");
|
||||||
const RenderWorld = @import("../resource/render_world.zig");
|
const RenderWorld = @import("../resource/render_world.zig");
|
||||||
|
const RenderLayout = @import("../resource/render_layout.zig");
|
||||||
|
|
||||||
// --- # ---
|
// --- # ---
|
||||||
const Transform2D = @import("../../common/component/transform2D.zig");
|
const Transform2D = @import("../../common/component/transform2D.zig");
|
||||||
|
|
@ -18,6 +20,7 @@ const Transform3D = @import("../../common/component/transform3D.zig");
|
||||||
|
|
||||||
// --- MESH ---
|
// --- MESH ---
|
||||||
const CMesh = @import("../../common/component/mesh.zig");
|
const CMesh = @import("../../common/component/mesh.zig");
|
||||||
|
const TMesh = @import("../template/gpu_object.zig");
|
||||||
|
|
||||||
// --- MATERIAL ---
|
// --- MATERIAL ---
|
||||||
const CMaterial = @import("../../common/component/material.zig");
|
const CMaterial = @import("../../common/component/material.zig");
|
||||||
|
|
@ -33,23 +36,78 @@ pub fn cameras(app: *App) !void {
|
||||||
// --- # ---
|
// --- # ---
|
||||||
const res = try app.resources.getMany(struct {
|
const res = try app.resources.getMany(struct {
|
||||||
render_world: *RenderWorld,
|
render_world: *RenderWorld,
|
||||||
|
render_layout: *RenderLayout,
|
||||||
|
device: *WGPUDevice,
|
||||||
});
|
});
|
||||||
|
|
||||||
{
|
|
||||||
// --- # ---
|
// --- # ---
|
||||||
var query = app.world.query(struct {
|
var query = app.world.query(struct {
|
||||||
camera: *const CCamera,
|
camera: *const CCamera,
|
||||||
|
transform2D: ?*const Transform2D,
|
||||||
|
transform3D: ?*const Transform3D,
|
||||||
}, .{});
|
}, .{});
|
||||||
while (query.next()) |e| {
|
while (query.next()) |e| {
|
||||||
// --- GPU ---
|
// --- GPU ---
|
||||||
const raw = try res.render_world.gpu_cameras.getOrPut(query.entity(), blk: {
|
const raw = try res.render_world.gpu_cameras.getOrPut(query.entity(), blk: {
|
||||||
if (res.render_world.gpu_cameras.getByKey(query.entity())) |v| break :blk v.*;
|
// --- # ---
|
||||||
|
if (res.render_world.gpu_cameras.getByKey(
|
||||||
|
query.entity(),
|
||||||
|
)) |v| break :blk v.*;
|
||||||
|
|
||||||
|
// --- UNIFORM ---
|
||||||
|
const uniform = wgpu.wgpuDeviceCreateBuffer(res.device.raw, &wgpu.WGPUBufferDescriptor{
|
||||||
|
.usage = wgpu.WGPUBufferUsage_CopyDst | wgpu.WGPUBufferUsage_Uniform,
|
||||||
|
.size = @sizeOf(TCamera.Uniform),
|
||||||
|
}) orelse return error.Buffer;
|
||||||
|
|
||||||
|
// --- VIEW ---
|
||||||
|
const view: math.Mat4x4 = if (e.transform3D) |t3| cmp: { // 3D
|
||||||
|
const eye = t3.position;
|
||||||
|
const forward = t3.rotation.rotate(math.Vec3f.new(.{ 0, 0, 1 }));
|
||||||
|
const up = t3.rotation.rotate(math.Vec3f.new(.{ 0, 1, 0 }));
|
||||||
|
break :cmp math.Mat4x4.lookAt(eye, eye.add(forward), up);
|
||||||
|
} else if (e.transform2D) |t2| cmp: { // 2D
|
||||||
|
const eye: math.Vec3f = .new(.{ t2.position.value[0], t2.position.value[1], 0 });
|
||||||
|
break :cmp math.Mat4x4.rotateZ(-t2.angle)
|
||||||
|
.mul(math.Mat4x4.translate(-eye.value[0], -eye.value[1], 0));
|
||||||
|
} else math.Mat4x4.identity();
|
||||||
|
|
||||||
|
// --- PROJECTION ---
|
||||||
|
const projection: math.Mat4x4 = switch (e.camera.projection) {
|
||||||
|
.perspective => |v| .perspective(std.math.degreesToRadians(v.fov), 800.0 / 600.0, v.near, v.far),
|
||||||
|
.ortho => |v| .orthographic(800.0, 0, 600.0, 0, v.near, v.far),
|
||||||
|
};
|
||||||
|
|
||||||
|
// --- WRITE TO UNIFORM ---
|
||||||
|
wgpu.wgpuQueueWriteBuffer(
|
||||||
|
res.device.queue,
|
||||||
|
uniform,
|
||||||
|
0,
|
||||||
|
&TCamera.Uniform{
|
||||||
|
.view = view.transpose(),
|
||||||
|
.projection = projection.transpose(),
|
||||||
|
},
|
||||||
|
@sizeOf(TCamera.Uniform),
|
||||||
|
);
|
||||||
|
|
||||||
|
// --- BIND GROUP ---
|
||||||
|
const bind_group = wgpu.wgpuDeviceCreateBindGroup(res.device.raw, &wgpu.WGPUBindGroupDescriptor{
|
||||||
|
.layout = res.render_layout.camera,
|
||||||
|
.entryCount = 1,
|
||||||
|
.entries = &[_]wgpu.WGPUBindGroupEntry{
|
||||||
|
.{
|
||||||
|
.binding = 0,
|
||||||
|
.buffer = uniform,
|
||||||
|
.offset = 0,
|
||||||
|
.size = @sizeOf(TCamera.Uniform),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}) orelse return error.BindGroup;
|
||||||
|
|
||||||
break :blk .{
|
break :blk .{
|
||||||
.projection = switch (e.camera.projection) {
|
.buffer = uniform,
|
||||||
.perspective => |v| .perspective(v.fov, 800.0 / 600.0, v.near, v.far),
|
.bind_group = bind_group,
|
||||||
.ortho => |v| .orthographic(800, 0, 600, 0, v.near, v.far),
|
.dirty = false,
|
||||||
},
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -61,9 +119,18 @@ pub fn cameras(app: *App) !void {
|
||||||
.raw = raw,
|
.raw = raw,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
pub fn objects(app: *App) !void {
|
||||||
|
// --- # ---
|
||||||
|
const res = try app.resources.getMany(struct {
|
||||||
|
render_world: *RenderWorld,
|
||||||
|
render_layout: *RenderLayout,
|
||||||
|
device: *WGPUDevice,
|
||||||
|
});
|
||||||
|
|
||||||
{
|
|
||||||
// --- # ---
|
// --- # ---
|
||||||
var query = app.world.query(struct {
|
var query = app.world.query(struct {
|
||||||
mesh: *const CMesh,
|
mesh: *const CMesh,
|
||||||
|
|
@ -72,8 +139,70 @@ pub fn cameras(app: *App) !void {
|
||||||
transform3D: ?*const Transform3D,
|
transform3D: ?*const Transform3D,
|
||||||
}, .{});
|
}, .{});
|
||||||
while (query.next()) |e| {
|
while (query.next()) |e| {
|
||||||
|
// --- ENSURE TRANSFORM ---
|
||||||
|
if (e.transform2D == null and
|
||||||
|
e.transform3D == null) continue;
|
||||||
|
|
||||||
|
// --- GPU ---
|
||||||
|
_ = try res.render_world.gpu_objects.getOrPut(query.entity(), blk: {
|
||||||
|
// --- # ---
|
||||||
|
if (res.render_world.gpu_objects.getByKey(
|
||||||
|
query.entity(),
|
||||||
|
)) |v| break :blk v.*;
|
||||||
|
|
||||||
|
// --- UNIFORM ---
|
||||||
|
const uniform = wgpu.wgpuDeviceCreateBuffer(res.device.raw, &wgpu.WGPUBufferDescriptor{
|
||||||
|
.usage = wgpu.WGPUBufferUsage_CopyDst | wgpu.WGPUBufferUsage_Uniform,
|
||||||
|
.size = @sizeOf(TMesh.Uniform),
|
||||||
|
}) orelse return error.Buffer;
|
||||||
|
|
||||||
|
// --- MODEL ---
|
||||||
|
const pos: math.Vec3f = e.transform3D.?.position;
|
||||||
|
const scl: math.Vec3f = e.transform3D.?.scale;
|
||||||
|
const rot: math.Quat = e.transform3D.?.rotation;
|
||||||
|
|
||||||
|
// --- FINAL MODEL ---
|
||||||
|
const model =
|
||||||
|
math.Mat4x4.translate(pos.value[0], pos.value[1], pos.value[2])
|
||||||
|
.mul(rot.toMat4())
|
||||||
|
.mul(math.Mat4x4.scale(scl.value[0], scl.value[1], scl.value[2]));
|
||||||
|
|
||||||
|
// --- WRITE TO UNIFORM ---
|
||||||
|
wgpu.wgpuQueueWriteBuffer(
|
||||||
|
res.device.queue,
|
||||||
|
uniform,
|
||||||
|
0,
|
||||||
|
&TMesh.Uniform{
|
||||||
|
.data = model.transpose(),
|
||||||
|
},
|
||||||
|
@sizeOf(TMesh.Uniform),
|
||||||
|
);
|
||||||
|
|
||||||
|
// --- BIND GROUP ---
|
||||||
|
const bind_group = wgpu.wgpuDeviceCreateBindGroup(res.device.raw, &wgpu.WGPUBindGroupDescriptor{
|
||||||
|
.layout = res.render_layout.model,
|
||||||
|
.entryCount = 1,
|
||||||
|
.entries = &[_]wgpu.WGPUBindGroupEntry{
|
||||||
|
.{
|
||||||
|
.binding = 0,
|
||||||
|
.buffer = uniform,
|
||||||
|
.offset = 0,
|
||||||
|
.size = @sizeOf(TMesh.Uniform),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}) orelse return error.BindGroup;
|
||||||
|
|
||||||
|
break :blk .{
|
||||||
|
.buffer = uniform,
|
||||||
|
.bind_group = bind_group,
|
||||||
|
.dirty = false,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// --- FRAME ---
|
||||||
try res.render_world.frame_objects.append(app.alloc, .{
|
try res.render_world.frame_objects.append(app.alloc, .{
|
||||||
.mesh = e.mesh.value,
|
.mesh = e.mesh.value,
|
||||||
|
.entity = query.entity(),
|
||||||
.material = e.material.value,
|
.material = e.material.value,
|
||||||
.transform = blk: {
|
.transform = blk: {
|
||||||
if (e.transform2D) |v| break :blk .{ .@"2D" = v.* };
|
if (e.transform2D) |v| break :blk .{ .@"2D" = v.* };
|
||||||
|
|
@ -82,7 +211,6 @@ pub fn cameras(app: *App) !void {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ----------------------------------------------------
|
/// ----------------------------------------------------
|
||||||
|
|
@ -143,6 +271,7 @@ pub fn pipelines(app: *App) !void {
|
||||||
// --- # ---
|
// --- # ---
|
||||||
const res = try app.resources.getMany(struct {
|
const res = try app.resources.getMany(struct {
|
||||||
render_world: *RenderWorld,
|
render_world: *RenderWorld,
|
||||||
|
render_layout: *RenderLayout,
|
||||||
device: *WGPUDevice,
|
device: *WGPUDevice,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -163,62 +292,11 @@ pub fn pipelines(app: *App) !void {
|
||||||
material.unique,
|
material.unique,
|
||||||
)) return;
|
)) return;
|
||||||
|
|
||||||
//
|
// --- LAYOUT ---
|
||||||
// LAYOUTS
|
|
||||||
//
|
|
||||||
|
|
||||||
// --- CAMERA ---
|
|
||||||
const camera_layout = wgpu.wgpuDeviceCreateBindGroupLayout(res.device.raw, &wgpu.WGPUBindGroupLayoutDescriptor{
|
|
||||||
.entryCount = 1,
|
|
||||||
.entries = &[_]wgpu.WGPUBindGroupLayoutEntry{
|
|
||||||
.{
|
|
||||||
.binding = 0,
|
|
||||||
.visibility = wgpu.WGPUShaderStage_Vertex | wgpu.WGPUShaderStage_Fragment,
|
|
||||||
.buffer = .{
|
|
||||||
.type = wgpu.WGPUBufferBindingType_Uniform,
|
|
||||||
.minBindingSize = @sizeOf(TMaterial.Style),
|
|
||||||
.hasDynamicOffset = 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}) orelse return error.BindGroupLayout;
|
|
||||||
|
|
||||||
// --- MODEL ---
|
|
||||||
const model_layout = wgpu.wgpuDeviceCreateBindGroupLayout(res.device.raw, &wgpu.WGPUBindGroupLayoutDescriptor{
|
|
||||||
.entryCount = 1,
|
|
||||||
.entries = &[_]wgpu.WGPUBindGroupLayoutEntry{
|
|
||||||
.{
|
|
||||||
.binding = 0,
|
|
||||||
.visibility = wgpu.WGPUShaderStage_Vertex | wgpu.WGPUShaderStage_Fragment,
|
|
||||||
.buffer = .{
|
|
||||||
.type = wgpu.WGPUBufferBindingType_Uniform,
|
|
||||||
.minBindingSize = @sizeOf(TMaterial.Style),
|
|
||||||
.hasDynamicOffset = 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}) orelse return error.BindGroupLayout;
|
|
||||||
|
|
||||||
// --- MATERIAL ---
|
|
||||||
const material_layout = wgpu.wgpuDeviceCreateBindGroupLayout(res.device.raw, &wgpu.WGPUBindGroupLayoutDescriptor{
|
|
||||||
.entryCount = 1,
|
|
||||||
.entries = &[_]wgpu.WGPUBindGroupLayoutEntry{
|
|
||||||
.{
|
|
||||||
.binding = 0,
|
|
||||||
.visibility = wgpu.WGPUShaderStage_Vertex | wgpu.WGPUShaderStage_Fragment,
|
|
||||||
.buffer = .{
|
|
||||||
.type = wgpu.WGPUBufferBindingType_Uniform,
|
|
||||||
.minBindingSize = @sizeOf(TMaterial.Style),
|
|
||||||
.hasDynamicOffset = 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}) orelse return error.BindGroupLayout;
|
|
||||||
|
|
||||||
var bind_group_layouts = [_]wgpu.WGPUBindGroupLayout{
|
var bind_group_layouts = [_]wgpu.WGPUBindGroupLayout{
|
||||||
camera_layout,
|
res.render_layout.camera,
|
||||||
model_layout,
|
res.render_layout.model,
|
||||||
material_layout,
|
res.render_layout.material,
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- PIPELINE LAYOUT ---
|
// --- PIPELINE LAYOUT ---
|
||||||
|
|
@ -234,7 +312,9 @@ pub fn pipelines(app: *App) !void {
|
||||||
const pipeline = try createPipeline(
|
const pipeline = try createPipeline(
|
||||||
material.unique,
|
material.unique,
|
||||||
pipeline_layout,
|
pipeline_layout,
|
||||||
if (res.render_world.gpu_shaders.getByKey(material.unique.shader)) |v| v.raw else return error.ShaderNotFound,
|
if (res.render_world.gpu_shaders.getByKey(
|
||||||
|
material.unique.shader,
|
||||||
|
)) |v| v.raw else return error.ShaderNotFound,
|
||||||
res.device.raw,
|
res.device.raw,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -242,11 +322,6 @@ pub fn pipelines(app: *App) !void {
|
||||||
break :blk .{
|
break :blk .{
|
||||||
.raw = pipeline,
|
.raw = pipeline,
|
||||||
.layout = pipeline_layout,
|
.layout = pipeline_layout,
|
||||||
.bind_group_layouts = .{
|
|
||||||
camera_layout,
|
|
||||||
model_layout,
|
|
||||||
material_layout,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -258,6 +333,7 @@ pub fn materials(app: *App) !void {
|
||||||
// --- # ---
|
// --- # ---
|
||||||
const res = try app.resources.getMany(struct {
|
const res = try app.resources.getMany(struct {
|
||||||
render_world: *RenderWorld,
|
render_world: *RenderWorld,
|
||||||
|
render_layout: *RenderLayout,
|
||||||
device: *WGPUDevice,
|
device: *WGPUDevice,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -276,8 +352,9 @@ pub fn materials(app: *App) !void {
|
||||||
)) return;
|
)) return;
|
||||||
|
|
||||||
// --- # ---
|
// --- # ---
|
||||||
const material = res.render_world.materials.get(e.material.value) orelse return error.MaterialNotFound;
|
const material = res.render_world.materials.get(
|
||||||
const pipeline = res.render_world.gpu_pipelines.getByKey(material.unique) orelse return error.PipelineNotFound;
|
e.material.value,
|
||||||
|
) orelse return error.MaterialNotFound;
|
||||||
|
|
||||||
// --- UNIFORM ---
|
// --- UNIFORM ---
|
||||||
const uniform = wgpu.wgpuDeviceCreateBuffer(res.device.raw, &wgpu.WGPUBufferDescriptor{
|
const uniform = wgpu.wgpuDeviceCreateBuffer(res.device.raw, &wgpu.WGPUBufferDescriptor{
|
||||||
|
|
@ -296,7 +373,7 @@ pub fn materials(app: *App) !void {
|
||||||
|
|
||||||
// --- BIND GROUP ---
|
// --- BIND GROUP ---
|
||||||
const bind_group = wgpu.wgpuDeviceCreateBindGroup(res.device.raw, &wgpu.WGPUBindGroupDescriptor{
|
const bind_group = wgpu.wgpuDeviceCreateBindGroup(res.device.raw, &wgpu.WGPUBindGroupDescriptor{
|
||||||
.layout = pipeline.bind_group_layouts[0],
|
.layout = res.render_layout.material,
|
||||||
.entryCount = 1,
|
.entryCount = 1,
|
||||||
.entries = &[_]wgpu.WGPUBindGroupEntry{
|
.entries = &[_]wgpu.WGPUBindGroupEntry{
|
||||||
.{
|
.{
|
||||||
|
|
@ -399,6 +476,7 @@ fn createPipeline(
|
||||||
.mask = ~@as(u32, 0),
|
.mask = ~@as(u32, 0),
|
||||||
.alphaToCoverageEnabled = 0,
|
.alphaToCoverageEnabled = 0,
|
||||||
},
|
},
|
||||||
|
.depthStencil = null,
|
||||||
}) orelse {
|
}) orelse {
|
||||||
return error.PipelineCreationFailed;
|
return error.PipelineCreationFailed;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@ pub fn draw(app: *App) !void {
|
||||||
|
|
||||||
// --- FRAME ---
|
// --- FRAME ---
|
||||||
var render_pass: ?*wgpu.WGPURenderPassEncoderImpl = null;
|
var render_pass: ?*wgpu.WGPURenderPassEncoderImpl = null;
|
||||||
|
var camera: ?u64 = null;
|
||||||
|
|
||||||
for (res.renderer.commands.items) |cmd| {
|
for (res.renderer.commands.items) |cmd| {
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
|
|
@ -107,6 +108,9 @@ pub fn draw(app: *App) !void {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// --- SET CAMERA ---
|
||||||
|
camera = v.camera;
|
||||||
},
|
},
|
||||||
.end_pass => {
|
.end_pass => {
|
||||||
if (render_pass) |rp| {
|
if (render_pass) |rp| {
|
||||||
|
|
@ -119,7 +123,9 @@ pub fn draw(app: *App) !void {
|
||||||
// --- ENSURE ---
|
// --- ENSURE ---
|
||||||
const material = res.render_world.materials.get(v.material) orelse return error.MaterialNotFound;
|
const material = res.render_world.materials.get(v.material) orelse return error.MaterialNotFound;
|
||||||
const gpu_material = res.render_world.gpu_materials.getByKey(v.material) orelse return error.GPUMaterialNotFound;
|
const gpu_material = res.render_world.gpu_materials.getByKey(v.material) orelse return error.GPUMaterialNotFound;
|
||||||
|
const gpu_camera = res.render_world.gpu_cameras.getByKey(camera orelse return error.CameraNotSet) orelse return error.GPUCameraNotFound;
|
||||||
const pipeline = res.render_world.gpu_pipelines.getByKey(material.unique) orelse return error.GPUPipelineNotFound;
|
const pipeline = res.render_world.gpu_pipelines.getByKey(material.unique) orelse return error.GPUPipelineNotFound;
|
||||||
|
const gpu_mesh = res.render_world.gpu_objects.getByKey(v.entity) orelse return error.GPUMeshNotFound;
|
||||||
const mesh = try res.mesh_cache.getOrCreate(v.mesh);
|
const mesh = try res.mesh_cache.getOrCreate(v.mesh);
|
||||||
|
|
||||||
// --- BIND ---
|
// --- BIND ---
|
||||||
|
|
@ -127,8 +133,8 @@ pub fn draw(app: *App) !void {
|
||||||
wgpu.wgpuRenderPassEncoderSetVertexBuffer(render_pass, 0, mesh.vbuf, 0, wgpu.wgpuBufferGetSize(mesh.vbuf));
|
wgpu.wgpuRenderPassEncoderSetVertexBuffer(render_pass, 0, mesh.vbuf, 0, wgpu.wgpuBufferGetSize(mesh.vbuf));
|
||||||
|
|
||||||
// --- BIND SHADER GROUPS ---
|
// --- BIND SHADER GROUPS ---
|
||||||
wgpu.wgpuRenderPassEncoderSetBindGroup(render_pass, 0, gpu_material.bind_group, 0, null);
|
wgpu.wgpuRenderPassEncoderSetBindGroup(render_pass, 0, gpu_camera.bind_group, 0, null);
|
||||||
wgpu.wgpuRenderPassEncoderSetBindGroup(render_pass, 1, gpu_material.bind_group, 0, null);
|
wgpu.wgpuRenderPassEncoderSetBindGroup(render_pass, 1, gpu_mesh.bind_group, 0, null);
|
||||||
wgpu.wgpuRenderPassEncoderSetBindGroup(render_pass, 2, gpu_material.bind_group, 0, null);
|
wgpu.wgpuRenderPassEncoderSetBindGroup(render_pass, 2, gpu_material.bind_group, 0, null);
|
||||||
|
|
||||||
// --- DRAW ---
|
// --- DRAW ---
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ const Handle = gtl.Handle;
|
||||||
//
|
//
|
||||||
|
|
||||||
mesh: MeshID,
|
mesh: MeshID,
|
||||||
|
entity: u64, // TODO: Change to Entity type
|
||||||
material: Handle(Material),
|
material: Handle(Material),
|
||||||
transform: union(enum) {
|
transform: union(enum) {
|
||||||
@"2D": Transform2D,
|
@"2D": Transform2D,
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,11 @@
|
||||||
|
const wgpu = @import("wgpu");
|
||||||
const math = @import("math");
|
const math = @import("math");
|
||||||
|
|
||||||
projection: math.Mat4x4,
|
pub const Uniform = struct {
|
||||||
|
view: math.Mat4x4,
|
||||||
|
projection: math.Mat4x4,
|
||||||
|
};
|
||||||
|
|
||||||
|
buffer: *wgpu.WGPUBufferImpl,
|
||||||
|
bind_group: *wgpu.WGPUBindGroupImpl,
|
||||||
|
dirty: bool = true,
|
||||||
|
|
|
||||||
10
src/plugins/renderer/template/gpu_object.zig
Normal file
10
src/plugins/renderer/template/gpu_object.zig
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
const wgpu = @import("wgpu");
|
||||||
|
const math = @import("math");
|
||||||
|
|
||||||
|
pub const Uniform = struct {
|
||||||
|
data: math.Mat4x4,
|
||||||
|
};
|
||||||
|
|
||||||
|
buffer: *wgpu.WGPUBufferImpl,
|
||||||
|
bind_group: *wgpu.WGPUBindGroupImpl,
|
||||||
|
dirty: bool = true,
|
||||||
|
|
@ -2,4 +2,3 @@ const wgpu = @import("wgpu");
|
||||||
|
|
||||||
raw: *wgpu.WGPURenderPipelineImpl,
|
raw: *wgpu.WGPURenderPipelineImpl,
|
||||||
layout: *wgpu.WGPUPipelineLayoutImpl,
|
layout: *wgpu.WGPUPipelineLayoutImpl,
|
||||||
bind_group_layouts: [3]*wgpu.WGPUBindGroupLayoutImpl,
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue