NYXEngine/src/plugins/renderer/system/present.zig

115 lines
4.1 KiB
Zig
Raw Normal View History

2026-07-28 23:30:07 +01:00
//! ----------------------------------------------------
//! ----------------------------------------------------
const std = @import("std");
const wgpu = @import("wgpu");
const App = @import("app");
const Window = @import("../../window/resource/window.zig");
const Device = @import("../../device/resource/wgpu_device.zig");
const Renderer = @import("../resource/renderer.zig");
const PipelineCache = @import("../../cache/resource/pipeline_cache.zig");
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn draw(app: *App) !void {
// --- # ---
const res = try app.resources.getMany(struct {
window: *Window,
device: *Device,
renderer: *Renderer,
pipeline_cache: *PipelineCache,
});
// --- SURFACE TEXTURE ---
var surface_texture: wgpu.WGPUSurfaceTexture = .{};
defer wgpu.wgpuTextureRelease(surface_texture.texture);
// --- GET SURFACE TEXTURE ---
wgpu.wgpuSurfaceGetCurrentTexture(
@ptrCast(res.window.surface),
&surface_texture,
);
// --- GET SURFACE COLOR VIEW ---
const target_view = wgpu.wgpuTextureCreateView(surface_texture.texture, &wgpu.WGPUTextureViewDescriptor{
.format = wgpu.wgpuTextureGetFormat(surface_texture.texture),
.dimension = wgpu.WGPUTextureViewDimension_2D,
.baseMipLevel = 0,
.mipLevelCount = 1,
.baseArrayLayer = 0,
.arrayLayerCount = 1,
.aspect = wgpu.WGPUTextureAspect_All,
});
defer wgpu.wgpuTextureViewRelease(target_view);
// --- ENCODER ---
const encoder = wgpu.wgpuDeviceCreateCommandEncoder(
res.device.raw,
&wgpu.WGPUCommandEncoderDescriptor{},
);
defer wgpu.wgpuCommandEncoderRelease(encoder);
// --- FRAME ---
var render_pass: ?*wgpu.WGPURenderPassEncoderImpl = null;
for (res.renderer.commands.items) |cmd| {
switch (cmd) {
.begin_pass => |v| {
// --- END PREV PASS ---
if (render_pass) |rp| {
wgpu.wgpuRenderPassEncoderEnd(rp);
wgpu.wgpuRenderPassEncoderRelease(rp);
}
// --- NEW RENDER PASS ---
render_pass = wgpu.wgpuCommandEncoderBeginRenderPass(
encoder,
&wgpu.WGPURenderPassDescriptor{
.colorAttachmentCount = 1,
.colorAttachments = &wgpu.WGPURenderPassColorAttachment{
.view = target_view,
.resolveTarget = null,
.loadOp = wgpu.WGPULoadOp_Clear,
.storeOp = wgpu.WGPUStoreOp_Store,
.clearValue = .{
.r = v.color[0],
.g = v.color[1],
.b = v.color[2],
.a = v.color[3],
},
.depthSlice = wgpu.WGPU_DEPTH_SLICE_UNDEFINED,
},
},
);
},
.end_pass => {
if (render_pass) |rp| {
wgpu.wgpuRenderPassEncoderEnd(rp);
wgpu.wgpuRenderPassEncoderRelease(rp);
render_pass = null;
}
},
.draw => |v| {
// --- ENSURE PIPELINE ---
const pipeline = try res.pipeline_cache.getOrCreate(
v.material,
);
// --- DRAW ---
wgpu.wgpuRenderPassEncoderSetPipeline(render_pass, pipeline.raw);
wgpu.wgpuRenderPassEncoderDraw(render_pass, 3, 1, 0, 0);
},
else => {},
}
}
// --- FINISH ENCODER | CMD BUFFER ---
const cmd_buff = wgpu.wgpuCommandEncoderFinish(encoder, &.{});
defer wgpu.wgpuCommandBufferRelease(cmd_buff);
// --- SUBMIT AND PRESENT ---
wgpu.wgpuQueueSubmit(res.device.queue, 1, &cmd_buff);
_ = wgpu.wgpuSurfacePresent(@ptrCast(res.window.surface));
}