diff --git a/src/component/pbr_material.zig b/src/component/pbr_material.zig new file mode 100644 index 0000000..e69de29 diff --git a/src/component/root.zig b/src/component/root.zig index fa6fe00..acb23f4 100644 --- a/src/component/root.zig +++ b/src/component/root.zig @@ -1 +1,5 @@ +// --- CAMERA --- pub const Camera = @import("camera.zig"); + +// --- MATERIALS --- +pub const PBRMaterial = @import("pbr_material.zig"); diff --git a/src/plugin.zig b/src/plugin.zig index 000d691..530721d 100644 --- a/src/plugin.zig +++ b/src/plugin.zig @@ -1,3 +1,6 @@ +//! ---------------------------------------------------- +//! ---------------------------------------------------- + const App = @import("app"); const system = @import("system/root.zig"); const resource = @import("resource/root.zig"); @@ -16,10 +19,13 @@ fn build( _: *App.plugin.Plugin, ctx: App.plugin.Context, ) !void { - // --- RESOURCES --- + // --- CORE --- try ctx.app.resources.set(resource.Instance{}); try ctx.app.resources.set(resource.Device{}); try ctx.app.resources.set(resource.window{}); + + // --- RENDER --- + try ctx.app.resources.set(resource.RenderFrame{}); try ctx.app.resources.set(resource.RenderQueue.init(ctx.app.alloc)); // --- INIT --- @@ -27,10 +33,14 @@ fn build( system.instance.init, system.window.init, system.device.init, + + system.frame.begin, }); // --- DEINIT --- try ctx.app.schedules.addMany(App.stage.Deinit, &.{ + system.frame.end, + system.device.deinit, system.window.deinit, system.instance.deinit, diff --git a/src/resource/render_frame.zig b/src/resource/render_frame.zig new file mode 100644 index 0000000..b2dd0aa --- /dev/null +++ b/src/resource/render_frame.zig @@ -0,0 +1,20 @@ +//! ---------------------------------------------------- +//! ---------------------------------------------------- + +const std = @import("std"); +const wgpu = @import("wgpu"); +const Self = @This(); + +// +// FIELDS +// + +surface_tex: wgpu.WGPUSurfaceTexture = .{}, +color_view: ?*wgpu.WGPUTextureViewImpl = null, +encoder: ?*wgpu.WGPUCommandEncoderImpl = null, + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub fn reset(self: *Self) void { + self.* = .{}; +} diff --git a/src/resource/root.zig b/src/resource/root.zig index f7072dc..6ae1375 100644 --- a/src/resource/root.zig +++ b/src/resource/root.zig @@ -4,4 +4,5 @@ pub const Device = @import("device.zig"); pub const window = @import("window.zig"); // --- DRAW --- +pub const RenderFrame = @import("render_frame.zig"); pub const RenderQueue = @import("render_queue.zig"); diff --git a/src/system/draw.zig b/src/system/draw.zig new file mode 100644 index 0000000..e69de29 diff --git a/src/system/frame.zig b/src/system/frame.zig new file mode 100644 index 0000000..1912318 --- /dev/null +++ b/src/system/frame.zig @@ -0,0 +1,104 @@ +//! ---------------------------------------------------- +//! ---------------------------------------------------- + +const std = @import("std"); +const sdl = @import("sdl"); +const wgpu = @import("wgpu"); +const App = @import("app"); + +const Window = @import("../resource/window.zig"); +const Device = @import("../resource/device.zig"); +const RenderFrame = @import("../resource/render_frame.zig"); + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub fn begin(ctx: App.scheduler.Context) !void { + // --- GET RESOURCES --- + const res = try ctx.app.resources.getMany(struct { + window: *Window, + device: *Device, + render_frame: *RenderFrame, + }); + + // --- GET SURFACE TEXTURE --- + wgpu.wgpuSurfaceGetCurrentTexture( + @ptrCast(res.window.surface), + &res.render_frame.surface_tex, + ); + + // --- CHECK SURFACE TEXTURE STATUS --- + switch (res.render_frame.surface_tex.status) { + wgpu.WGPUStatus_Error => return error.SurfaceTexture, + else => {}, + } + + // --- GET SURFACE COLOR VIEW --- + res.render_frame.color_view = wgpu.wgpuTextureCreateView( + res.render_frame.surface_tex.texture, + &wgpu.WGPUTextureViewDescriptor{ + .format = wgpu.wgpuTextureGetFormat(res.render_frame.surface_tex.texture), + .dimension = wgpu.WGPUTextureDimension_2D, + .baseMipLevel = 0, + .mipLevelCount = 1, + .baseArrayLayer = 0, + .arrayLayerCount = 1, + .aspect = wgpu.WGPUTextureAspect_All, + }, + ) orelse return error.TextureView; + + // --- NEW CMD ENCODER --- + res.render_frame.encoder = wgpu.wgpuDeviceCreateCommandEncoder( + res.device.raw, + &wgpu.WGPUCommandEncoderDescriptor{}, + ) orelse return error.CMDEncoder; +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub fn end(ctx: App.scheduler.Context) !void { + // --- GET RESOURCES --- + const res = try ctx.app.resources.getMany(struct { + window: *Window, + device: *Device, + render_frame: *RenderFrame, + }); + + if (res.render_frame.encoder) |encoder| { + // --- NEW CMD BUFF --- + const cmd = wgpu.wgpuCommandEncoderFinish( + encoder, + &wgpu.WGPUCommandBufferDescriptor{}, + ) orelse return error.CMD; + defer wgpu.wgpuCommandBufferRelease(cmd); + + // --- GATHER --- + const cmds: []const wgpu.WGPUCommandBuffer = &.{ + cmd, + }; + + // --- SUBMIT --- + wgpu.wgpuQueueSubmit( + res.device.queue, + cmds.len, + cmds.ptr, + ); + } + + // --- PRESENT --- + switch (wgpu.wgpuSurfacePresent(@ptrCast(res.window.surface))) { + wgpu.WGPUWaitStatus_Error => return error.Present, + else => {}, + } + + // --- FREE COLOR VIEW --- + if (res.render_frame.color_view) |view| { + wgpu.wgpuTextureViewRelease(view); + wgpu.wgpuTextureRelease(res.render_frame.surface_tex.texture); + } + + // --- RESET FRAME --- + res.render_frame.reset(); + + // --- DEBUG --- + sdl.SDL_Delay(2000); // TODO: Remove +} diff --git a/src/system/root.zig b/src/system/root.zig index 23209be..08b4047 100644 --- a/src/system/root.zig +++ b/src/system/root.zig @@ -2,3 +2,7 @@ pub const instance = @import("instance.zig"); pub const device = @import("device.zig"); pub const window = @import("window.zig"); + +// --- FRAME --- +pub const frame = @import("frame.zig"); +pub const draw = @import("draw.zig");