Skip to content

Instantly share code, notes, and snippets.

@buahaha
Last active November 10, 2023 13:28
Show Gist options
  • Save buahaha/19b27170e629276606ab2e057823de70 to your computer and use it in GitHub Desktop.
Save buahaha/19b27170e629276606ab2e057823de70 to your computer and use it in GitHub Desktop.
Metal API SwiftUI view
//
// Created by Szymon Błaszczyński on 26/08/2021.
//
import Foundation
import MetalKit
import SwiftUI
struct MetalView: NSViewRepresentable {
func makeCoordinator() -> Coordinator {
Coordinator(self, mtkView: mtkView)
}
typealias NSViewType = MTKView
var mtkView: MTKView
func makeNSView(context: NSViewRepresentableContext<MetalView>) -> MTKView {
mtkView.delegate = context.coordinator
mtkView.preferredFramesPerSecond = 60
mtkView.enableSetNeedsDisplay = true
mtkView.isPaused = false
mtkView.colorPixelFormat = MTLPixelFormat.bgra8Unorm
return mtkView
}
func updateNSView(_ nsView: MTKView, context: NSViewRepresentableContext<MetalView>) {
}
class Coordinator: NSObject, MTKViewDelegate {
var parent: MetalView
var ciContext: CIContext!
var metalDevice: MTLDevice!
var metalCommandQueue: MTLCommandQueue!
var mtlTexture: MTLTexture!
var startTime: Date!
init(_ parent: MetalView, mtkView: MTKView) {
self.parent = parent
if let metalDevice = MTLCreateSystemDefaultDevice() {
mtkView.device = metalDevice
self.metalDevice = metalDevice
}
self.ciContext = CIContext(mtlDevice: metalDevice)
self.metalCommandQueue = metalDevice.makeCommandQueue()!
super.init()
mtkView.framebufferOnly = false
mtkView.clearColor = MTLClearColor(red: 0, green: 0, blue: 0, alpha: 0)
mtkView.drawableSize = mtkView.frame.size
mtkView.enableSetNeedsDisplay = true
}
func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {
}
func draw(in view: MTKView) {
guard let drawable = view.currentDrawable else {
return
}
let texture: MTLTexture = drawable.texture
let passDescriptor = view.currentRenderPassDescriptor
passDescriptor?.colorAttachments[0].texture = texture
passDescriptor?.colorAttachments[0].loadAction = .clear
passDescriptor?.colorAttachments[0].storeAction = .store
passDescriptor?.colorAttachments[0].clearColor = MTLClearColorMake(1, 0, 0, 1)
let commandQueue = metalDevice.makeCommandQueue()!
let commandBuffer = commandQueue.makeCommandBuffer()!
let commandEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: passDescriptor!)
commandEncoder?.endEncoding()
commandBuffer.present(drawable)
commandBuffer.commit()
}
}
}
@buahaha
Copy link
Author

buahaha commented Aug 26, 2021

Usage: MetalView(mtkView: MTKView() in your SwiftUI body

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment