Skip to content

Instantly share code, notes, and snippets.

@hugonijhuis
Created February 8, 2021 15:17
Show Gist options
  • Select an option

  • Save hugonijhuis/d5b983784cf4519c5b352f41a790c237 to your computer and use it in GitHub Desktop.

Select an option

Save hugonijhuis/d5b983784cf4519c5b352f41a790c237 to your computer and use it in GitHub Desktop.
Simple interaction between Metal and SwiftUI
//
// MetalView.swift
// uncharted-realms
//
// Created by Hugo Nijhuis-Mekkelholt on 27/01/2021.
//
import SwiftUI
import MetalKit
struct MetalView {
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeMTKView(_ context: MetalView.Context) -> MTKView {
let mtkView = MTKView()
mtkView.delegate = context.coordinator
mtkView.preferredFramesPerSecond = 60
if let metalDevice = MTLCreateSystemDefaultDevice() {
mtkView.device = metalDevice
}
mtkView.framebufferOnly = false
mtkView.clearColor = MTLClearColor(red: 0, green: 0, blue: 0, alpha: 0)
mtkView.drawableSize = mtkView.frame.size
mtkView.enableSetNeedsDisplay = true
mtkView.isPaused = false
return mtkView
}
class Coordinator : NSObject, MTKViewDelegate {
var parent: MetalView
var metalDevice: MTLDevice!
var metalCommandQueue: MTLCommandQueue!
init(_ parent: MetalView) {
self.parent = parent
if let metalDevice = MTLCreateSystemDefaultDevice() {
self.metalDevice = metalDevice
}
self.metalCommandQueue = metalDevice.makeCommandQueue()!
super.init()
}
func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {
}
func draw(in view: MTKView) {
guard let drawable = view.currentDrawable else {
return
}
let commandBuffer = metalCommandQueue.makeCommandBuffer()
let rpd = view.currentRenderPassDescriptor
rpd?.colorAttachments[0].clearColor = MTLClearColorMake(0.43, 0.73, 0.35, 1.0)
rpd?.colorAttachments[0].loadAction = .clear
rpd?.colorAttachments[0].storeAction = .store
let re = commandBuffer?.makeRenderCommandEncoder(descriptor: rpd!)
re?.endEncoding()
commandBuffer?.present(drawable)
commandBuffer?.commit()
}
}
}
#if os(macOS)
extension MetalView : NSViewRepresentable {
func makeNSView(context: Context) -> MTKView {
return makeMTKView(context)
}
func updateNSView(_ nsView: MTKView, context: Context) {
}
}
#endif
#if os(iOS)
extension MetalView : UIViewRepresentable {
func makeUIView(context: Context) -> MTKView {
return makeMTKView(context)
}
func updateUIView(_ nsView: MTKView, context: Context) {
}
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment