//! ---------------------------------------------------- //! ---------------------------------------------------- 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)); }