我被SwiftUI和Metal卡住了,几乎要给予了。
我从https://developer.apple.com/forums/thread/119112?answerId=654964022#654964022得到这个例子:
import MetalKit
struct MetalView: NSViewRepresentable {
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeNSView(context: NSViewRepresentableContext<MetalView>) -> MTKView {
let mtkView = MTKView()
mtkView.delegate = context.coordinator
mtkView.preferredFramesPerSecond = 60
mtkView.enableSetNeedsDisplay = true
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
return mtkView
}
func updateNSView(_ nsView: MTKView, context: NSViewRepresentableContext<MetalView>) {
}
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, 1, 0, 1)
rpd?.colorAttachments[0].loadAction = .clear
rpd?.colorAttachments[0].storeAction = .store
let re = commandBuffer?.makeRenderCommandEncoder(descriptor: rpd!)
re?.endEncoding()
commandBuffer?.present(drawable)
commandBuffer?.commit()
}
}
}
字符串
.但是我不知道如何使用MetalView()来显示数据,当我从SwiftUI视图调用它时,它似乎确实可以工作。我想用它来显示一个CIImage,它将被CIFilters过滤和操作.
有人可以请指出我在正确的方向上如何告诉这个视图如何显示的东西?我想我需要它来显示纹理的内容,但尝试了无数个小时,最终从零开始更无数次...
这就是我现在运行我的图像过滤器的方式,但它导致滑块非常慢,这就是为什么我决定尝试学习Metal..
func ciExposure (inputImage: CIImage, inputEV: Double) -> CIImage {
let filter = CIFilter(name: "CIExposureAdjust")!
filter.setValue(inputImage, forKey: kCIInputImageKey)
filter.setValue(inputEV, forKey: kCIInputEVKey)
return filter.outputImage!
}
型
我想我需要把那个filter.outputImage以某种方式传递给MetalView?
任何帮助都是非常,非常感谢的...
4条答案
按热度按时间tyu7yeag1#
Apple的WWDC 2022包含了一个名为“使用Core Image、Metal和SwiftUI显示EDR内容”的教程/视频,其中描述了如何将Core Image与Metal和SwiftUI混合。它指向了一些名为“使用Core Image渲染目标生成动画”(here)的新示例代码。
这个示例项目非常以CoreImage为中心(这应该很适合你的目的),但我希望Apple能发布更多的示例代码示例,展示Metal与SwiftUI的集成。
gr8qqesn2#
我有一个小的Core Image + SwiftUI示例项目on Github,它可能是一个很好的起点。它还没有涵盖很多内容,但它已经演示了如何显示过滤的相机帧。
特别是查看视图的
draw
函数。它用于将CIImage
渲染为MTKView
(您可以在委托的draw
函数中执行相同的操作)。m1m5dgzv3#
好吧,这对我来说是个小把戏:
字符串
rawImage是我的CIImage纹理,我从我的过滤功能。
上下文是在其他地方创建的,但应该是:
型
接下来是添加Frank Schlegel提供的代码的居中部分。
fslejnso4#
从macOS 14.0 / Xcode 15开始,您可以使用Metal代码作为视图修改器。
因此,您可以创建Rectangle()并应用金属视觉效果(或扭曲效果)。
这里有一个很长的例子,有很多参数。
第一个月
字符串
你需要一个这样的金属锉
型