Proper resource based render | Somewhat proper rendering | Changed stuff n stuff | Now go amimir
This commit is contained in:
parent
d213a23ca7
commit
ccde4427be
31 changed files with 811 additions and 133 deletions
|
|
@ -60,6 +60,12 @@ pub fn build(b: *std.Build) void {
|
|||
});
|
||||
exe.root_module.addImport("zla", zla.module("zla"));
|
||||
|
||||
const math = b.dependency("NYXMath", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
exe.root_module.addImport("math", math.module("NYXMath"));
|
||||
|
||||
//
|
||||
// SYSTEM DEPENDENCIES
|
||||
//
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@
|
|||
.url = "git+http://2.120.146.66:25569/abux/gtl.git#3c7fcfcb1276b76ec4695ce5ce9dba4d8255a176",
|
||||
.hash = "gtl-0.0.0-e3QoJMRYAADChgXn2sogTxsbUpEBSHjOGZeoEx4ccMMD",
|
||||
},
|
||||
.NYXMath = .{
|
||||
.url = "git+http://192.168.0.11:25569/abux/NYXMath.git#58d57b61f3fa25e234af1af3e1e56bb656f4d77d",
|
||||
.hash = "NYXMath-0.0.0-BD6ST8zOAAB1dgmaGKShXtKmGTuYqgiDpAY2faHM_HnV",
|
||||
},
|
||||
},
|
||||
|
||||
.paths = .{
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
|
||||
const std = @import("std");
|
||||
const math = @import("math");
|
||||
const App = @import("app");
|
||||
|
||||
//
|
||||
|
|
@ -61,13 +62,17 @@ pub fn main(init: std.process.Init) !void {
|
|||
if (app.events.consume(App.event.AppExit)) |_| break;
|
||||
|
||||
// --- # ---
|
||||
try app.schedules.runMany(&.{
|
||||
app.schedules.runMany(&.{
|
||||
App.stage.begin_frame,
|
||||
App.stage.inputs,
|
||||
App.stage.fixed_update,
|
||||
App.stage.update,
|
||||
App.stage.draw,
|
||||
App.stage.end_frame,
|
||||
}, &app);
|
||||
}, &app) catch |err| {
|
||||
std.debug.print("\x1b[31m[ERROR]\x1b[0m {s}\n", .{
|
||||
@errorName(err),
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,13 +43,13 @@ struct ModelUniform {
|
|||
// UNIFORMS
|
||||
//
|
||||
|
||||
// @group(0) @binding(0)
|
||||
// var<uniform> camera: CameraUniform;
|
||||
|
||||
// @group(1) @binding(0)
|
||||
// var<uniform> model: ModelUniform;
|
||||
|
||||
@group(0) @binding(0)
|
||||
var<uniform> camera: CameraUniform;
|
||||
|
||||
@group(1) @binding(0)
|
||||
var<uniform> model: ModelUniform;
|
||||
|
||||
@group(2) @binding(0)
|
||||
var<uniform> material: Material;
|
||||
|
||||
//
|
||||
|
|
|
|||
3
src/plugins/cache/resource/mesh_cache.zig
vendored
3
src/plugins/cache/resource/mesh_cache.zig
vendored
|
|
@ -81,6 +81,9 @@ pub fn getOrCreate(
|
|||
mesh: MeshID,
|
||||
) !*GPUMesh {
|
||||
return try self.data.getOrPut(mesh, blk: {
|
||||
// --- # ---
|
||||
if (self.data.getByKey(mesh)) |v| return v;
|
||||
|
||||
// --- # ---
|
||||
const vertices: []const Vertex = switch (mesh) {
|
||||
.triangle => &.{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
//! ----------------------------------------------------
|
||||
//! TODO: Move [materials, materials_gpu and GPUMaterial somewhere else]
|
||||
//! Depricated
|
||||
//! ----------------------------------------------------
|
||||
|
||||
const std = @import("std");
|
||||
|
|
@ -16,8 +18,7 @@ const Vertex = @import("mesh_cache.zig").Vertex;
|
|||
pub const GPUPipeline = struct {
|
||||
raw: *wgpu.WGPURenderPipelineImpl,
|
||||
layout: *wgpu.WGPUPipelineLayoutImpl,
|
||||
bind_group_layouts: [1]*wgpu.WGPUBindGroupLayoutImpl,
|
||||
// bind_group_layouts: []const *wgpu.WGPUBindGroupLayoutImpl,
|
||||
bind_group_layouts: [3]*wgpu.WGPUBindGroupLayoutImpl,
|
||||
};
|
||||
|
||||
/// ----------------------------------------------------
|
||||
|
|
@ -28,6 +29,15 @@ pub const GPUMaterial = struct {
|
|||
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
|
||||
//
|
||||
|
|
@ -145,7 +155,43 @@ pub fn getOrCreatePipeline(
|
|||
// --- # ---
|
||||
if (self.pipelines.getByKey(material.unique)) |v| return v;
|
||||
|
||||
// --- MATERIAL LAYOUT ---
|
||||
//
|
||||
// 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{
|
||||
|
|
@ -161,12 +207,18 @@ pub fn getOrCreatePipeline(
|
|||
},
|
||||
}) 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 = 1,
|
||||
.bindGroupLayouts = &material_layout,
|
||||
.bindGroupLayoutCount = 3,
|
||||
.bindGroupLayouts = &bind_group_layouts,
|
||||
},
|
||||
) orelse return error.Layout;
|
||||
|
||||
|
|
@ -181,6 +233,8 @@ pub fn getOrCreatePipeline(
|
|||
.raw = pipeline,
|
||||
.layout = pipeline_layout,
|
||||
.bind_group_layouts = .{
|
||||
camera_layout,
|
||||
model_layout,
|
||||
material_layout,
|
||||
},
|
||||
};
|
||||
3
src/plugins/cache/root.zig
vendored
3
src/plugins/cache/root.zig
vendored
|
|
@ -1,4 +1,5 @@
|
|||
//! ----------------------------------------------------
|
||||
//! DEPRICATED
|
||||
//! ----------------------------------------------------
|
||||
|
||||
//
|
||||
|
|
@ -12,8 +13,6 @@ const lifetime = @import("system/lifetime.zig");
|
|||
// PUBLIC
|
||||
//
|
||||
|
||||
pub const ShaderCache = @import("resource/shader_cache.zig");
|
||||
pub const PipelineCache = @import("resource/pipeline_cache.zig");
|
||||
pub const MeshCache = @import("resource/mesh_cache.zig");
|
||||
|
||||
/// ----------------------------------------------------
|
||||
|
|
|
|||
21
src/plugins/cache/system/lifetime.zig
vendored
21
src/plugins/cache/system/lifetime.zig
vendored
|
|
@ -6,8 +6,6 @@ const gtl = @import("gtl");
|
|||
const App = @import("app");
|
||||
const WGPUDevice = @import("../../device/resource/wgpu_device.zig");
|
||||
|
||||
const ShaderCache = @import("../resource/shader_cache.zig");
|
||||
const PipelineCache = @import("../resource/pipeline_cache.zig");
|
||||
const MeshCache = @import("../resource/mesh_cache.zig");
|
||||
|
||||
/// ----------------------------------------------------
|
||||
|
|
@ -18,19 +16,7 @@ pub fn init(app: *App) !void {
|
|||
device: *const WGPUDevice,
|
||||
});
|
||||
|
||||
// --- SHADER CACHE ---
|
||||
const shaders = try app.resources.getOrSet(ShaderCache.init(
|
||||
res.device.raw,
|
||||
app.alloc,
|
||||
));
|
||||
|
||||
// --- PIPELINE CACHE ---
|
||||
const pipelines = try app.resources.getOrSet(PipelineCache.init(
|
||||
shaders,
|
||||
res.device.queue,
|
||||
res.device.raw,
|
||||
app.alloc,
|
||||
));
|
||||
// TODO: Depricated stuff here | Use RenderWorld
|
||||
|
||||
// --- MESH CACHE ---
|
||||
const meshes = try app.resources.getOrSet(MeshCache.init(
|
||||
|
|
@ -40,7 +26,6 @@ pub fn init(app: *App) !void {
|
|||
));
|
||||
|
||||
_ = meshes;
|
||||
_ = pipelines;
|
||||
|
||||
// TODO: Remove or place it somewhere else, idk
|
||||
|
||||
|
|
@ -94,13 +79,9 @@ pub fn init(app: *App) !void {
|
|||
pub fn deinit(app: *App) !void {
|
||||
// --- # ---
|
||||
const res = try app.resources.getMany(struct {
|
||||
shaders: *ShaderCache,
|
||||
pipelines: *PipelineCache,
|
||||
meshes: *MeshCache,
|
||||
});
|
||||
|
||||
// --- # ---
|
||||
res.shaders.deinit();
|
||||
res.pipelines.deinit();
|
||||
res.meshes.deinit();
|
||||
}
|
||||
|
|
|
|||
22
src/plugins/common/component/camera.zig
Normal file
22
src/plugins/common/component/camera.zig
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
const math = @import("math");
|
||||
|
||||
projection: union(enum) {
|
||||
perspective: struct {
|
||||
fov: f32 = 80.0,
|
||||
far: f32 = 4000.0,
|
||||
near: f32 = 0.05,
|
||||
},
|
||||
ortho: struct {
|
||||
size: f32 = 1.0,
|
||||
far: f32 = 4000.0,
|
||||
near: f32 = 0.05,
|
||||
},
|
||||
} = .{ .ortho = .{} },
|
||||
|
||||
target: union(enum) {
|
||||
window,
|
||||
texture, // TODO: Handle to a texture, someday
|
||||
} = .window,
|
||||
|
||||
order: u32 = 0,
|
||||
priority: u32 = 0,
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
//! ----------------------------------------------------
|
||||
//! ----------------------------------------------------
|
||||
|
||||
const gtl = @import("gtl");
|
||||
const ShaderID = @import("../../cache/resource/shader_cache.zig").ShaderID;
|
||||
const Handle = gtl.Handle;
|
||||
const Self = @This();
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub const Style = struct {
|
||||
albedo: @Vector(4, f32) = .{ 1, 1, 1, 1 },
|
||||
metallic: f32 = 0.0,
|
||||
roughness: f32 = 0.5,
|
||||
_pad0: [2]f32 = .{ 0, 0 },
|
||||
};
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub const Unique = struct {
|
||||
shader: ShaderID = .pbr,
|
||||
|
||||
front_face: enum {
|
||||
cw,
|
||||
ccw,
|
||||
} = .ccw,
|
||||
|
||||
cull_mode: enum {
|
||||
back,
|
||||
front,
|
||||
none,
|
||||
} = .back,
|
||||
|
||||
topology: enum {
|
||||
triangle_list,
|
||||
point_list,
|
||||
line_list,
|
||||
} = .triangle_list,
|
||||
|
||||
blend_mode: enum {
|
||||
none,
|
||||
alpha,
|
||||
additive,
|
||||
multiply,
|
||||
} = .none,
|
||||
};
|
||||
|
||||
//
|
||||
// FIELDS
|
||||
//
|
||||
|
||||
style: Style = .{},
|
||||
unique: Unique = .{},
|
||||
value: ?Handle(Self) = null,
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
position: @Vector(2, f32) = .{ 0, 0 },
|
||||
scale: @Vector(2, f32) = .{ 32, 32 },
|
||||
const math = @import("math");
|
||||
|
||||
position: math.Vec2f = .as(0),
|
||||
scale: math.Vec2f = .as(32),
|
||||
angle: f32 = 0,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
position: @Vector(3, f32) = .{ 0, 0, 0 },
|
||||
rotation: @Vector(3, f32) = .{ 0, 0, 0 },
|
||||
scale: @Vector(3, f32) = .{ 1, 1, 1 },
|
||||
const math = @import("math");
|
||||
|
||||
position: math.Vec3f = .as(0),
|
||||
rotation: math.Quat = .identity(),
|
||||
scale: math.Vec3f = .as(0),
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@
|
|||
// COMPONENTS
|
||||
//
|
||||
|
||||
// --- VIEW ---
|
||||
const Camera = @import("component/camera.zig");
|
||||
|
||||
// --- POSITION ---
|
||||
pub const Transform3D = @import("component/transform3D.zig");
|
||||
pub const Transform2D = @import("component/transform2D.zig");
|
||||
|
|
|
|||
|
|
@ -6,11 +6,13 @@
|
|||
//
|
||||
|
||||
const App = @import("app");
|
||||
|
||||
const Camera = @import("../common/component/camera.zig");
|
||||
const Mesh = @import("../common/component/mesh.zig");
|
||||
const Material = @import("../common/component/material.zig");
|
||||
const Transform3D = @import("../common/component/transform3D.zig");
|
||||
|
||||
const PipelineCache = @import("../cache/resource/pipeline_cache.zig");
|
||||
const RenderWorld = @import("../renderer/resource/render_world.zig");
|
||||
|
||||
//
|
||||
// PUBLIC
|
||||
|
|
@ -36,19 +38,27 @@ fn build(
|
|||
/// ----------------------------------------------------
|
||||
fn start(app: *App) !void {
|
||||
// --- # ---
|
||||
const pipeline_cache = app.resources.getPtr(
|
||||
PipelineCache,
|
||||
) orelse return error.PipelineCacheNotSet;
|
||||
const render_world = app.resources.getPtr(
|
||||
RenderWorld,
|
||||
).?;
|
||||
|
||||
// --- CAMERA ---
|
||||
try app.world.spawn(.{
|
||||
Camera{},
|
||||
Transform3D{},
|
||||
});
|
||||
|
||||
// --- # ---
|
||||
try app.world.spawn(.{
|
||||
Mesh{ .value = .square },
|
||||
Material{
|
||||
.value = try pipeline_cache.materials.put(.{
|
||||
.value = try render_world.materials.put(.{
|
||||
.style = .{
|
||||
.albedo = .{ 0.8, 0.2, 0.2, 1 },
|
||||
.albedo = .{ 0.8, 0.2, 0.2, 1.0 },
|
||||
},
|
||||
.unique = .{
|
||||
.topology = .line_list,
|
||||
},
|
||||
.unique = .{},
|
||||
}),
|
||||
},
|
||||
Transform3D{},
|
||||
|
|
@ -58,11 +68,10 @@ fn start(app: *App) !void {
|
|||
try app.world.spawn(.{
|
||||
Mesh{ .value = .triangle },
|
||||
Material{
|
||||
.value = try pipeline_cache.materials.put(.{
|
||||
.value = try render_world.materials.put(.{
|
||||
.style = .{
|
||||
.albedo = .{ 0.2, 0.2, 0.8, 1 },
|
||||
},
|
||||
.unique = .{},
|
||||
}),
|
||||
},
|
||||
Transform3D{},
|
||||
|
|
|
|||
83
src/plugins/renderer/resource/embeded/shaders/pbr.wgsl
Normal file
83
src/plugins/renderer/resource/embeded/shaders/pbr.wgsl
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
// ----------------------------------------------------
|
||||
// ----------------------------------------------------
|
||||
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);
|
||||
}
|
||||
47
src/plugins/renderer/resource/render_world.zig
Normal file
47
src/plugins/renderer/resource/render_world.zig
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
//! ----------------------------------------------------
|
||||
//! ----------------------------------------------------
|
||||
|
||||
// --- # ---
|
||||
const std = @import("std");
|
||||
const gtl = @import("gtl");
|
||||
const wgpu = @import("wgpu");
|
||||
|
||||
// --- CAMERA ---
|
||||
pub const GPUCamera = @import("../template/gpu_camera.zig");
|
||||
pub const FrameView = @import("../template/frame_view.zig");
|
||||
|
||||
// --- SHADER ---
|
||||
pub const ShaderID = @import("../template/shader_id.zig").ShaderID;
|
||||
pub const GPUShader = @import("../template/gpu_shader.zig");
|
||||
|
||||
// --- MATERIAL ---
|
||||
pub const Material = @import("../template/material.zig");
|
||||
pub const GPUMaterial = @import("../template/gpu_material.zig");
|
||||
|
||||
// --- PIPELINE ---
|
||||
pub const Pipeline = Material.Unique;
|
||||
pub const GPUPipeline = @import("../template/gpu_pipeline.zig");
|
||||
|
||||
// --- OBJECT ---
|
||||
pub const Entity = u64; // TODO: You lazy retard
|
||||
pub const FrameObject = @import("../template/frame_object.zig");
|
||||
|
||||
//
|
||||
// EMBEDED
|
||||
//
|
||||
|
||||
pub const PBRCode = @embedFile("embeded/shaders/pbr.wgsl");
|
||||
pub const UnlitCode = @embedFile("embeded/shaders/pbr.wgsl");
|
||||
|
||||
//
|
||||
// FIELDS
|
||||
//
|
||||
|
||||
gpu_cameras: gtl.KeyedSlotMap(Entity, GPUCamera),
|
||||
gpu_shaders: gtl.KeyedSlotMap(ShaderID, GPUShader),
|
||||
gpu_pipelines: gtl.KeyedSlotMap(Pipeline, GPUPipeline),
|
||||
gpu_materials: gtl.KeyedSlotMap(gtl.Handle(Material), GPUMaterial),
|
||||
|
||||
frame_views: std.ArrayList(FrameView),
|
||||
frame_objects: std.ArrayList(FrameObject),
|
||||
materials: gtl.SlotMap(Material), // TODO: Move this to assets resource or sum
|
||||
|
|
@ -25,7 +25,7 @@ pub const DrawCMD = union(enum) {
|
|||
},
|
||||
|
||||
begin_pass: struct {
|
||||
camera: Handle(Camera),
|
||||
camera: u64, // TODO: Change it to Entity type instead
|
||||
color: [4]f32 = .{ 0, 0, 0, 255 },
|
||||
load_op: enum {
|
||||
load,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ const App = @import("app");
|
|||
|
||||
const lifetime = @import("system/lifetime.zig");
|
||||
const frame = @import("system/frame.zig");
|
||||
const prepare = @import("system/prepare.zig");
|
||||
const present = @import("system/present.zig");
|
||||
|
||||
//
|
||||
|
|
@ -38,6 +39,14 @@ fn build(
|
|||
try app.schedules.add(App.stage.begin_frame, frame.begin);
|
||||
try app.schedules.add(App.stage.end_frame, frame.end);
|
||||
|
||||
// --- PRE DRAW ---
|
||||
try app.schedules.addManyBefore(App.stage.draw, App.stage.draw, &.{
|
||||
prepare.cameras,
|
||||
prepare.shaders,
|
||||
prepare.pipelines,
|
||||
prepare.materials,
|
||||
});
|
||||
|
||||
// --- DRAW ---
|
||||
try app.schedules.add(App.stage.draw, present.draw);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
const std = @import("std");
|
||||
const App = @import("app");
|
||||
const Renderer = @import("../resource/renderer.zig");
|
||||
const RenderWorld = @import("../resource/render_world.zig");
|
||||
|
||||
const Mesh = @import("../../common/component/mesh.zig");
|
||||
const Material = @import("../../common/component/material.zig");
|
||||
|
|
@ -15,35 +16,38 @@ pub fn begin(app: *App) !void {
|
|||
// --- # ---
|
||||
const res = try app.resources.getMany(struct {
|
||||
renderer: *Renderer,
|
||||
render_world: *RenderWorld,
|
||||
});
|
||||
|
||||
// --- # ---
|
||||
res.renderer.clear();
|
||||
|
||||
// --- 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;
|
||||
|
||||
// --- QUERY ---
|
||||
var query = app.world.query(struct {
|
||||
mesh: *Mesh,
|
||||
material: *Material,
|
||||
transform3D: ?*Transform3D,
|
||||
}, .{});
|
||||
while (query.next()) |e| {
|
||||
for (res.render_world.frame_views.items) |view| {
|
||||
// --- NEW PASS ---
|
||||
try res.renderer.draw(.{
|
||||
.draw = .{
|
||||
.material = e.material.value,
|
||||
.mesh = e.mesh.value,
|
||||
.begin_pass = .{
|
||||
.camera = view.camera,
|
||||
.color = .{ 0.001, 0.001, 0.001, 1.0 },
|
||||
},
|
||||
});
|
||||
defer res.renderer.draw(.end_pass) catch unreachable;
|
||||
|
||||
// --- # ---
|
||||
for (res.render_world.frame_objects.items) |obj| {
|
||||
try res.renderer.draw(.{
|
||||
.draw = .{
|
||||
.material = obj.material,
|
||||
.mesh = obj.mesh,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// --- YES ---
|
||||
res.render_world.frame_views.clearRetainingCapacity();
|
||||
res.render_world.frame_objects.clearRetainingCapacity();
|
||||
|
||||
// { // TEST
|
||||
// // --- DRAW ---
|
||||
// try res.renderer.draw(.{
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
//! ----------------------------------------------------
|
||||
//! ----------------------------------------------------
|
||||
|
||||
const wgpu = @import("wgpu");
|
||||
const App = @import("app");
|
||||
const Zla = @import("zla");
|
||||
|
||||
const Renderer = @import("../resource/renderer.zig");
|
||||
const RenderWorld = @import("../resource/render_world.zig");
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
|
|
@ -12,11 +15,54 @@ pub fn init(app: *App) !void {
|
|||
try app.resources.set(Renderer.init(
|
||||
app.alloc,
|
||||
));
|
||||
|
||||
// --- # ---
|
||||
try app.resources.set(RenderWorld{
|
||||
.gpu_cameras = .init(app.alloc),
|
||||
.gpu_shaders = .init(app.alloc),
|
||||
.gpu_materials = .init(app.alloc),
|
||||
.gpu_pipelines = .init(app.alloc),
|
||||
|
||||
.frame_views = .empty,
|
||||
.frame_objects = .empty,
|
||||
|
||||
.materials = .init(app.alloc),
|
||||
});
|
||||
}
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub fn deinit(app: *App) !void {
|
||||
const renderer = app.resources.getPtr(Renderer) orelse return error.RendererNotSet;
|
||||
renderer.deinit();
|
||||
// --- # ---
|
||||
const res = try app.resources.getMany(struct {
|
||||
ren: *Renderer,
|
||||
ren_world: *RenderWorld,
|
||||
});
|
||||
|
||||
// --- FREE SHADERS ---
|
||||
for (res.ren_world.gpu_shaders.items()) |entry| {
|
||||
wgpu.wgpuShaderModuleRelease(entry.value.raw);
|
||||
}
|
||||
|
||||
// --- FREE PIPELINES ---
|
||||
for (res.ren_world.gpu_pipelines.items()) |entry| {
|
||||
wgpu.wgpuPipelineLayoutRelease(entry.value.layout);
|
||||
wgpu.wgpuRenderPipelineRelease(entry.value.raw);
|
||||
}
|
||||
|
||||
// --- FREE MATERIALS ---
|
||||
for (res.ren_world.gpu_materials.items()) |entry| {
|
||||
wgpu.wgpuBufferRelease(entry.value.buffer);
|
||||
wgpu.wgpuBindGroupRelease(entry.value.bind_group);
|
||||
}
|
||||
|
||||
// --- # ---
|
||||
res.ren_world.materials.deinit();
|
||||
res.ren_world.frame_views.deinit(app.alloc);
|
||||
res.ren_world.frame_objects.deinit(app.alloc);
|
||||
res.ren_world.gpu_cameras.deinit();
|
||||
res.ren_world.gpu_shaders.deinit();
|
||||
res.ren_world.gpu_materials.deinit();
|
||||
res.ren_world.gpu_pipelines.deinit();
|
||||
res.ren.deinit();
|
||||
}
|
||||
|
|
|
|||
405
src/plugins/renderer/system/prepare.zig
Normal file
405
src/plugins/renderer/system/prepare.zig
Normal file
|
|
@ -0,0 +1,405 @@
|
|||
//! ----------------------------------------------------
|
||||
//! ----------------------------------------------------
|
||||
|
||||
// --- # ---
|
||||
const std = @import("std");
|
||||
const wgpu = @import("wgpu");
|
||||
const App = @import("app");
|
||||
const Zla = @import("zla");
|
||||
|
||||
// --- # ---
|
||||
const Vertex = @import("../../cache/resource/mesh_cache.zig").Vertex;
|
||||
const WGPUDevice = @import("../../device/resource/wgpu_device.zig");
|
||||
const RenderWorld = @import("../resource/render_world.zig");
|
||||
|
||||
// --- # ---
|
||||
const Transform2D = @import("../../common/component/transform2D.zig");
|
||||
const Transform3D = @import("../../common/component/transform3D.zig");
|
||||
|
||||
// --- MESH ---
|
||||
const CMesh = @import("../../common/component/mesh.zig");
|
||||
|
||||
// --- MATERIAL ---
|
||||
const CMaterial = @import("../../common/component/material.zig");
|
||||
const TMaterial = @import("../template/material.zig");
|
||||
|
||||
// --- CAMERA ---
|
||||
const CCamera = @import("../../common/component/camera.zig");
|
||||
const TCamera = @import("../template/gpu_camera.zig");
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub fn cameras(app: *App) !void {
|
||||
// --- # ---
|
||||
const res = try app.resources.getMany(struct {
|
||||
render_world: *RenderWorld,
|
||||
});
|
||||
|
||||
{
|
||||
// --- # ---
|
||||
var query = app.world.query(struct {
|
||||
camera: *const CCamera,
|
||||
}, .{});
|
||||
while (query.next()) |e| {
|
||||
// --- GPU ---
|
||||
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.*;
|
||||
|
||||
break :blk .{
|
||||
.projection = switch (e.camera.projection) {
|
||||
.perspective => |v| .perspective(v.fov, 800.0 / 600.0, v.near, v.far),
|
||||
.ortho => |v| .orthographic(800, 0, 600, 0, v.near, v.far),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
// --- FRAME ---
|
||||
try res.render_world.frame_views.append(app.alloc, .{
|
||||
.order = e.camera.order,
|
||||
.priority = e.camera.priority,
|
||||
.camera = query.entity(),
|
||||
.raw = raw,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// --- # ---
|
||||
var query = app.world.query(struct {
|
||||
mesh: *const CMesh,
|
||||
material: *const CMaterial,
|
||||
transform2D: ?*const Transform2D,
|
||||
transform3D: ?*const Transform3D,
|
||||
}, .{});
|
||||
while (query.next()) |e| {
|
||||
try res.render_world.frame_objects.append(app.alloc, .{
|
||||
.mesh = e.mesh.value,
|
||||
.material = e.material.value,
|
||||
.transform = blk: {
|
||||
if (e.transform2D) |v| break :blk .{ .@"2D" = v.* };
|
||||
if (e.transform3D) |v| break :blk .{ .@"3D" = v.* };
|
||||
break :blk .{ .@"2D" = .{} };
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub fn shaders(app: *App) !void {
|
||||
// --- # ---
|
||||
const res = try app.resources.getMany(struct {
|
||||
render_world: *RenderWorld,
|
||||
device: *WGPUDevice,
|
||||
});
|
||||
|
||||
// --- # ---
|
||||
var query = app.world.query(struct {
|
||||
material: *const CMaterial,
|
||||
}, .{});
|
||||
while (query.next()) |e| {
|
||||
// --- GET MATERIAL ---
|
||||
const material = res.render_world.materials.get(
|
||||
e.material.value,
|
||||
) orelse return error.MaterialNotFound;
|
||||
|
||||
// --- ENSURE SHADER ---
|
||||
_ = try res.render_world.gpu_shaders.getOrPut(material.unique.shader, blk: {
|
||||
// --- # ---
|
||||
if (res.render_world.gpu_shaders.contains(
|
||||
material.unique.shader,
|
||||
)) return;
|
||||
|
||||
// --- CODE ---
|
||||
const code: []const u8 = switch (material.unique.shader) {
|
||||
.pbr => RenderWorld.PBRCode,
|
||||
.unlit => RenderWorld.UnlitCode,
|
||||
.custom => return error.TooLazyToImplement, // TODO: Yes
|
||||
};
|
||||
|
||||
// --- SOURCE ---
|
||||
var source: wgpu.WGPUShaderSourceWGSL = .{
|
||||
.chain = .{ .sType = wgpu.WGPUSType_ShaderSourceWGSL },
|
||||
.code = .{ .data = code.ptr, .length = wgpu.WGPU_STRLEN },
|
||||
};
|
||||
|
||||
// --- RESULT ---
|
||||
break :blk .{
|
||||
.raw = wgpu.wgpuDeviceCreateShaderModule(res.device.raw, &wgpu.WGPUShaderModuleDescriptor{
|
||||
.label = .{ .data = @tagName(material.unique.shader), .length = wgpu.WGPU_STRLEN },
|
||||
.nextInChain = &source.chain,
|
||||
}) orelse {
|
||||
return error.ShaderModuleCreationFailed;
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub fn pipelines(app: *App) !void {
|
||||
// --- # ---
|
||||
const res = try app.resources.getMany(struct {
|
||||
render_world: *RenderWorld,
|
||||
device: *WGPUDevice,
|
||||
});
|
||||
|
||||
// --- # ---
|
||||
var query = app.world.query(struct {
|
||||
material: *const CMaterial,
|
||||
}, .{});
|
||||
while (query.next()) |e| {
|
||||
// --- GET MATERIAL ---
|
||||
const material = res.render_world.materials.get(
|
||||
e.material.value,
|
||||
) orelse return error.MaterialNotFound;
|
||||
|
||||
// --- ENSURE PIPELINE ---
|
||||
_ = try res.render_world.gpu_pipelines.getOrPut(material.unique, blk: {
|
||||
// --- # ---
|
||||
if (res.render_world.gpu_pipelines.contains(
|
||||
material.unique,
|
||||
)) return;
|
||||
|
||||
//
|
||||
// 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{
|
||||
camera_layout,
|
||||
model_layout,
|
||||
material_layout,
|
||||
};
|
||||
|
||||
// --- PIPELINE LAYOUT ---
|
||||
const pipeline_layout = wgpu.wgpuDeviceCreatePipelineLayout(
|
||||
res.device.raw,
|
||||
&wgpu.WGPUPipelineLayoutDescriptor{
|
||||
.bindGroupLayoutCount = 3,
|
||||
.bindGroupLayouts = &bind_group_layouts,
|
||||
},
|
||||
) orelse return error.Layout;
|
||||
|
||||
// --- CREATE PIPELINE ---
|
||||
const pipeline = try createPipeline(
|
||||
material.unique,
|
||||
pipeline_layout,
|
||||
if (res.render_world.gpu_shaders.getByKey(material.unique.shader)) |v| v.raw else return error.ShaderNotFound,
|
||||
res.device.raw,
|
||||
);
|
||||
|
||||
// --- RESULT ---
|
||||
break :blk .{
|
||||
.raw = pipeline,
|
||||
.layout = pipeline_layout,
|
||||
.bind_group_layouts = .{
|
||||
camera_layout,
|
||||
model_layout,
|
||||
material_layout,
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub fn materials(app: *App) !void {
|
||||
// --- # ---
|
||||
const res = try app.resources.getMany(struct {
|
||||
render_world: *RenderWorld,
|
||||
device: *WGPUDevice,
|
||||
});
|
||||
|
||||
// --- # ---
|
||||
var query = app.world.query(struct {
|
||||
material: *const CMaterial,
|
||||
}, .{});
|
||||
while (query.next()) |e| {
|
||||
// --- ENSURE MATERIAL ---
|
||||
_ = try res.render_world.gpu_materials.getOrPut(
|
||||
e.material.value,
|
||||
blk: {
|
||||
// --- # ---
|
||||
if (res.render_world.gpu_materials.contains(
|
||||
e.material.value,
|
||||
)) return;
|
||||
|
||||
// --- # ---
|
||||
const material = res.render_world.materials.get(e.material.value) orelse return error.MaterialNotFound;
|
||||
const pipeline = res.render_world.gpu_pipelines.getByKey(material.unique) orelse return error.PipelineNotFound;
|
||||
|
||||
// --- UNIFORM ---
|
||||
const uniform = wgpu.wgpuDeviceCreateBuffer(res.device.raw, &wgpu.WGPUBufferDescriptor{
|
||||
.usage = wgpu.WGPUBufferUsage_CopyDst | wgpu.WGPUBufferUsage_Uniform,
|
||||
.size = @sizeOf(TMaterial.Style),
|
||||
}) orelse return error.Buffer;
|
||||
|
||||
// --- WRITE TO UNIFORM ---
|
||||
wgpu.wgpuQueueWriteBuffer(
|
||||
res.device.queue,
|
||||
uniform,
|
||||
0,
|
||||
&material.style,
|
||||
@sizeOf(TMaterial.Style),
|
||||
);
|
||||
|
||||
// --- BIND GROUP ---
|
||||
const bind_group = wgpu.wgpuDeviceCreateBindGroup(res.device.raw, &wgpu.WGPUBindGroupDescriptor{
|
||||
.layout = pipeline.bind_group_layouts[0],
|
||||
.entryCount = 1,
|
||||
.entries = &[_]wgpu.WGPUBindGroupEntry{
|
||||
.{
|
||||
.binding = 0,
|
||||
.buffer = uniform,
|
||||
.offset = 0,
|
||||
.size = @sizeOf(TMaterial.Style),
|
||||
},
|
||||
},
|
||||
}) orelse return error.BindGroup;
|
||||
|
||||
// --- RESULT ---
|
||||
break :blk .{
|
||||
.buffer = uniform,
|
||||
.bind_group = bind_group,
|
||||
.dirty = false,
|
||||
};
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
fn createPipeline(
|
||||
key: TMaterial.Unique,
|
||||
layout: *wgpu.WGPUPipelineLayoutImpl,
|
||||
shader: *wgpu.WGPUShaderModuleImpl,
|
||||
device: *wgpu.WGPUDeviceImpl,
|
||||
) !*wgpu.WGPURenderPipelineImpl {
|
||||
return wgpu.wgpuDeviceCreateRenderPipeline(device, &wgpu.WGPURenderPipelineDescriptor{
|
||||
.label = .{ .data = @tagName(key.shader), .length = wgpu.WGPU_STRLEN },
|
||||
.layout = layout,
|
||||
.vertex = .{
|
||||
.module = shader,
|
||||
.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,
|
||||
.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;
|
||||
};
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ const Window = @import("../../window/resource/window.zig");
|
|||
const Resized = @import("../../window/event/resized.zig");
|
||||
const Device = @import("../../device/resource/wgpu_device.zig");
|
||||
const Renderer = @import("../resource/renderer.zig");
|
||||
const PipelineCache = @import("../../cache/resource/pipeline_cache.zig");
|
||||
const RenderWorld = @import("../resource/render_world.zig");
|
||||
const MeshCache = @import("../../cache/resource/mesh_cache.zig");
|
||||
|
||||
/// ----------------------------------------------------
|
||||
|
|
@ -20,13 +20,10 @@ pub fn draw(app: *App) !void {
|
|||
window: *Window,
|
||||
device: *Device,
|
||||
renderer: *Renderer,
|
||||
pipeline_cache: *PipelineCache,
|
||||
render_world: *RenderWorld,
|
||||
mesh_cache: *MeshCache,
|
||||
});
|
||||
|
||||
{ // TODO: Move this | Gather Materials
|
||||
}
|
||||
|
||||
// --- DO NONE ON WINDOW RESIZE ---
|
||||
if (app.events.consume(Resized)) |_| {
|
||||
return;
|
||||
|
|
@ -120,15 +117,19 @@ pub fn draw(app: *App) !void {
|
|||
},
|
||||
.draw => |v| {
|
||||
// --- ENSURE ---
|
||||
const material = res.pipeline_cache.materials.get(v.material) orelse return error.MaterialNotFound;
|
||||
const gpu_material = try res.pipeline_cache.getOrCreateMaterial(v.material);
|
||||
const pipeline = try res.pipeline_cache.getOrCreatePipeline(material);
|
||||
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 pipeline = res.render_world.gpu_pipelines.getByKey(material.unique) orelse return error.GPUPipelineNotFound;
|
||||
const mesh = try res.mesh_cache.getOrCreate(v.mesh);
|
||||
|
||||
// --- BIND ---
|
||||
wgpu.wgpuRenderPassEncoderSetPipeline(render_pass, pipeline.raw);
|
||||
wgpu.wgpuRenderPassEncoderSetVertexBuffer(render_pass, 0, mesh.vbuf, 0, wgpu.wgpuBufferGetSize(mesh.vbuf));
|
||||
|
||||
// --- BIND SHADER GROUPS ---
|
||||
wgpu.wgpuRenderPassEncoderSetBindGroup(render_pass, 0, gpu_material.bind_group, 0, null);
|
||||
wgpu.wgpuRenderPassEncoderSetBindGroup(render_pass, 1, gpu_material.bind_group, 0, null);
|
||||
wgpu.wgpuRenderPassEncoderSetBindGroup(render_pass, 2, gpu_material.bind_group, 0, null);
|
||||
|
||||
// --- DRAW ---
|
||||
if (mesh.ibuf) |ibuf| {
|
||||
|
|
|
|||
20
src/plugins/renderer/template/frame_object.zig
Normal file
20
src/plugins/renderer/template/frame_object.zig
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
//! ----------------------------------------------------
|
||||
//! ----------------------------------------------------
|
||||
|
||||
const gtl = @import("gtl");
|
||||
const Material = @import("material.zig");
|
||||
const Transform2D = @import("../../common/component/transform2D.zig");
|
||||
const Transform3D = @import("../../common/component/transform3D.zig");
|
||||
const MeshID = @import("../../cache/resource/mesh_cache.zig").MeshID;
|
||||
const Handle = gtl.Handle;
|
||||
|
||||
//
|
||||
// FIELDS
|
||||
//
|
||||
|
||||
mesh: MeshID,
|
||||
material: Handle(Material),
|
||||
transform: union(enum) {
|
||||
@"2D": Transform2D,
|
||||
@"3D": Transform3D,
|
||||
},
|
||||
6
src/plugins/renderer/template/frame_view.zig
Normal file
6
src/plugins/renderer/template/frame_view.zig
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
const GPUCamera = @import("gpu_camera.zig");
|
||||
|
||||
raw: *GPUCamera,
|
||||
order: u32 = 0,
|
||||
priority: u32 = 0,
|
||||
camera: u64, // TODO: Change to ENTITY Type
|
||||
3
src/plugins/renderer/template/gpu_camera.zig
Normal file
3
src/plugins/renderer/template/gpu_camera.zig
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
const math = @import("math");
|
||||
|
||||
projection: math.Mat4x4,
|
||||
5
src/plugins/renderer/template/gpu_material.zig
Normal file
5
src/plugins/renderer/template/gpu_material.zig
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
const wgpu = @import("wgpu");
|
||||
|
||||
buffer: *wgpu.WGPUBufferImpl,
|
||||
bind_group: *wgpu.WGPUBindGroupImpl,
|
||||
dirty: bool = true,
|
||||
5
src/plugins/renderer/template/gpu_pipeline.zig
Normal file
5
src/plugins/renderer/template/gpu_pipeline.zig
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
const wgpu = @import("wgpu");
|
||||
|
||||
raw: *wgpu.WGPURenderPipelineImpl,
|
||||
layout: *wgpu.WGPUPipelineLayoutImpl,
|
||||
bind_group_layouts: [3]*wgpu.WGPUBindGroupLayoutImpl,
|
||||
3
src/plugins/renderer/template/gpu_shader.zig
Normal file
3
src/plugins/renderer/template/gpu_shader.zig
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
const wgpu = @import("wgpu");
|
||||
|
||||
raw: *wgpu.WGPUShaderModuleImpl,
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
//! ----------------------------------------------------
|
||||
|
||||
const gtl = @import("gtl");
|
||||
const ShaderID = @import("../../cache/resource/shader_cache.zig").ShaderID;
|
||||
const ShaderID = @import("../template/shader_id.zig").ShaderID;
|
||||
const Handle = gtl.Handle;
|
||||
const Self = @This();
|
||||
|
||||
|
|
|
|||
5
src/plugins/renderer/template/shader_id.zig
Normal file
5
src/plugins/renderer/template/shader_id.zig
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
pub const ShaderID = union(enum) {
|
||||
pbr,
|
||||
unlit,
|
||||
custom: u32,
|
||||
};
|
||||
Loading…
Add table
Reference in a new issue