Integrate Metal/ObjC Tutorial into SwiftUI

I have modified Apple's Tutorial "CPU-GPU-Synchronization.xcodeproj" to suit my needs but cannot see how to launch it, e.g., as a sheet, from a Button inside a SwiftUI App.
I found this:
"developer.apple.com/forums/thread/119112"
which establishes the Coordinater wrapper, device and CommandQueue, etc., but how do I "replace?" those already established in ObjC code? For example, ObjC does not recognize SwiftUI struct's and I can't @objc preface a SwiftUI struct as I can a SwiftUI class(ref. the above thread).

Alternatively, is this the best venue to ask Apple to update/integrate their tutorials?

Thanks.

Accepted Reply

This what I have done:
Code Block
import SwiftUI
import MetalKit
struct MyMtkView: UIViewRepresentable {
typealias UIViewType = MTKView
var mtkView: MTKView
init() {
self.mtkView = MTKView()
}
func makeCoordinator() -> Coordinator {
Coordinator(self, mtkView: mtkView)
}
func makeUIView(context: UIViewRepresentableContext<MyMtkView>) -> MTKView {
mtkView.delegate = context.coordinator
mtkView.isPaused = false
mtkView.preferredFramesPerSecond = 60
mtkView.enableSetNeedsDisplay = false
mtkView.framebufferOnly = true
return mtkView
}
func updateUIView(_ uiView: MTKView, context: UIViewRepresentableContext<MyMtkView>) {
//
}
class Coordinator : AAPLRenderer {
var parent: MyMtkView
init(_ parent: MyMtkView, mtkView: MTKView) {
self.parent = parent
guard let metalDevice = MTLCreateSystemDefaultDevice() else {
fatalError("Metal is not supported on this device")
}
mtkView.device = metalDevice
super.init(metalKitView: mtkView)
mtkView.framebufferOnly = false
mtkView.clearColor = MTLClearColor(red: 0, green: 0, blue: 0, alpha: 0)
mtkView.drawableSize = mtkView.frame.size
mtkView.enableSetNeedsDisplay = true
self.mtkView(mtkView, drawableSizeWillChange: mtkView.drawableSize)
}
}
}

  • You need to create a device using MTLCreateSystemDefaultDevice as in the thread you have shown

  • You need to initialize AAPLRenderer (Rendere?) with passing mtkView

Replies

is this the best venue to ask Apple to update/integrate their tutorials?

No. Apple's engineer would answer to the questions on certain technical topics allowed.
But other than that, Apple has never responded to the posts in the dev forums.
Better use the feedback assistant to tell some request on development issue.
(Unfortunately, you should better not expect Apple would respond to the feedback immediately and clearly.)


As for now, what you are asking is sort of vague and hard to answer.
If you could show some details including what you have done till now and focus on more specific topic, you would get better responses.
Apple's Tutorial "CPU-GPU-Synchronization.xcodeproj" is readily available so I won't post any part of it. It is a stand-alone app that I want to launch from my SwiftUI app in some-or-any view. In "developer.apple.com/forums/thread/119112" a "Graphics and Games Engineer " kindly posted the code for creating the Coordinator, device, CommandQueue, etc. within SwiftUI code. What code/syntax is needed in either the objc tutorial code or the SwiftUI code to get the tutorial app to draw into the SwiftUI-created space?

Or am I making this more complicated than it should be?

I have tried creating a class in Swift with the Swift UIRepresentable as a var, then preface that class with "@objc" which should have made it available to the tutorial code, but it doesn't recognize it.

Or am I making this more complicated than it should be? 

I think so. I tried to make the SwiftUI version of the project, it took a few hours. The link you have shown really helped and I just spent most of the time searching for the right settings for MTKView.
I modified the "Graphics and Games Engineer " code thus;
  1. struct MetalView: UIViewRepresentable {

  2.     func makeCoordinator() -> Coordinator {

  3.         Coordinator(self)

  4.     }

  5.     func makeUIView(context: UIViewRepresentableContext<MetalView>) -> MTKView {

  6.         let renderer = Renderer() //. Renderer() is from Apple's Tutorial "CPU-GPU-Synchronization.xcodeproj"

  7.         let mtkView = MTKView()

  8. //        mtkView.delegate = context.coordinator

  9.         mtkView.delegate = renderer     //  if this is the last edit, compiles but gives white screen

  10.         mtkView.preferredFramesPerSecond = 60

  11.         mtkView.enableSetNeedsDisplay = true

  12. // if let metalDevice = MTLCreateSystemDefaultDevice() {

  13. // mtkView.device = metalDevice

  14. // }

  15. if let metalDevice = renderer._device {

  16. mtkView.device = metalDevice

  17. }

...

line 18 gives: "Value of type 'Renderer' has no member '_device' " and so I am stuck. I had programmed the first 128K Mac using C, when its native language was Pascal. However, I had never used ObjectiveC until now and the syntax foils me. If an ObjC @implementation is as a Swift class, then why isn't _device a member?
This what I have done:
Code Block
import SwiftUI
import MetalKit
struct MyMtkView: UIViewRepresentable {
typealias UIViewType = MTKView
var mtkView: MTKView
init() {
self.mtkView = MTKView()
}
func makeCoordinator() -> Coordinator {
Coordinator(self, mtkView: mtkView)
}
func makeUIView(context: UIViewRepresentableContext<MyMtkView>) -> MTKView {
mtkView.delegate = context.coordinator
mtkView.isPaused = false
mtkView.preferredFramesPerSecond = 60
mtkView.enableSetNeedsDisplay = false
mtkView.framebufferOnly = true
return mtkView
}
func updateUIView(_ uiView: MTKView, context: UIViewRepresentableContext<MyMtkView>) {
//
}
class Coordinator : AAPLRenderer {
var parent: MyMtkView
init(_ parent: MyMtkView, mtkView: MTKView) {
self.parent = parent
guard let metalDevice = MTLCreateSystemDefaultDevice() else {
fatalError("Metal is not supported on this device")
}
mtkView.device = metalDevice
super.init(metalKitView: mtkView)
mtkView.framebufferOnly = false
mtkView.clearColor = MTLClearColor(red: 0, green: 0, blue: 0, alpha: 0)
mtkView.drawableSize = mtkView.frame.size
mtkView.enableSetNeedsDisplay = true
self.mtkView(mtkView, drawableSizeWillChange: mtkView.drawableSize)
}
}
}

  • You need to create a device using MTLCreateSystemDefaultDevice as in the thread you have shown

  • You need to initialize AAPLRenderer (Rendere?) with passing mtkView

Wow! Thanks so much. I'll have to study this to see why it works! Starting with "typealias". Took you a few hours you say. I'd been blocked for over a month. Bless you!