Last active
April 2, 2025 06:50
-
-
Save nbhasin2/a988a2ec20763b018fd641136fe9505a to your computer and use it in GitHub Desktop.
Renderer_Step4.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import MetalKit | |
import SwiftUI | |
class Renderer: NSObject, MTKViewDelegate { | |
var device: MTLDevice! | |
var commandQueue: MTLCommandQueue! | |
var pipelineState: MTLRenderPipelineState! | |
var time: Float = 0.0 | |
init(device: MTLDevice) { | |
super.init() | |
self.device = device | |
self.commandQueue = device.makeCommandQueue() | |
self.setupPipeline() | |
} | |
func setupPipeline() { | |
let library = device.makeDefaultLibrary() | |
let vertexFunction = library?.makeFunction(name: "circle_vertex") | |
let fragmentFunction = library?.makeFunction(name: "circle_fragment") | |
let pipelineDescriptor = MTLRenderPipelineDescriptor() | |
pipelineDescriptor.vertexFunction = vertexFunction | |
pipelineDescriptor.fragmentFunction = fragmentFunction | |
pipelineDescriptor.colorAttachments[0].pixelFormat = .bgra8Unorm | |
do { | |
pipelineState = try device.makeRenderPipelineState(descriptor: pipelineDescriptor) | |
} catch { | |
fatalError("Failed to create pipeline state") | |
} | |
} | |
func draw(in view: MTKView) { | |
guard let drawable = view.currentDrawable else { return } | |
guard let descriptor = view.currentRenderPassDescriptor else { return } | |
let commandBuffer = commandQueue.makeCommandBuffer()! | |
let commandEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: descriptor)! | |
commandEncoder.setRenderPipelineState(pipelineState) | |
commandEncoder.setFragmentBytes(&time, length: MemoryLayout<Float>.size, index: 0) | |
commandEncoder.drawPrimitives(type: .triangleStrip, vertexStart: 0, vertexCount: 4) | |
commandEncoder.endEncoding() | |
commandBuffer.present(drawable) | |
commandBuffer.commit() | |
time += 0.01 | |
} | |
func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {} | |
} | |
struct MetalView: UIViewRepresentable { | |
var device: MTLDevice | |
func makeUIView(context: Context) -> MTKView { | |
let view = MTKView() | |
view.device = device | |
view.colorPixelFormat = .bgra8Unorm | |
view.framebufferOnly = false | |
let renderer = Renderer(device: device) | |
view.delegate = renderer | |
context.coordinator.renderer = renderer | |
return view | |
} | |
func updateUIView(_ uiView: MTKView, context: Context) {} | |
func makeCoordinator() -> Coordinator { | |
Coordinator() | |
} | |
class Coordinator { | |
var renderer: Renderer? | |
} | |
} | |
struct ContentView: View { | |
var body: some View { | |
MetalView(device: MTLCreateSystemDefaultDevice()!) | |
.edgesIgnoringSafeArea(.all) | |
} | |
} | |
#Preview { | |
ContentView() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment