是否可以仅使用编辑器和终端来编写Metal图形程序?如果是这样,那么最小应用程序的例子将是什么?
我想尝试一些生成式编码,但是没有Xcode。我能够使用OpenGL制作小型C或Python程序,但Apple弃用了它,使我考虑使用Metal。
我可以使用Swift和一些标头包含的内容吗?还是我需要更多吗?
答案 0 :(得分:2)
您可以从命令行编译和运行使用Metal的应用程序,而根本没有Xcode项目,但是您仍然需要Xcode提供的基础结构(SDK和工具链),因此需要安装它。 / p>
在Swift中编写一个简单的应用程序非常简单,该应用程序创建必要的Metal对象,对一些工作进行编码,然后将结果写入文件。出于这个问题的目的,我将提供一个简单的Cocoa应用程序的源代码,该应用程序将通过创建一个承载MetalKit视图并绘制到该窗口的窗口来进一步介绍。有了这个脚手架,您就可以编写一个非常复杂的应用程序,而无需启动Xcode。
import Foundation
import Cocoa
import Metal
import MetalKit
class AppDelegate : NSObject, NSApplicationDelegate {
let window = NSWindow()
let windowDelegate = WindowDelegate()
var rootViewController: NSViewController?
func applicationDidFinishLaunching(_ notification: Notification) {
window.setContentSize(NSSize(width: 800, height: 600))
window.styleMask = [ .titled, .closable, .miniaturizable, .resizable ]
window.title = "Window"
window.level = .normal
window.delegate = windowDelegate
window.center()
let view = window.contentView!
rootViewController = ViewController(nibName: nil, bundle: nil)
rootViewController!.view.frame = view.bounds
view.addSubview(rootViewController!.view)
window.makeKeyAndOrderFront(window)
NSApp.activate(ignoringOtherApps: true)
}
}
class WindowDelegate : NSObject, NSWindowDelegate {
func windowWillClose(_ notification: Notification) {
NSApp.terminate(self)
}
}
class ViewController : NSViewController, MTKViewDelegate {
var device: MTLDevice!
var commandQueue: MTLCommandQueue!
override init(nibName nibNameOrNil: NSNib.Name?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override func loadView() {
device = MTLCreateSystemDefaultDevice()!
commandQueue = device.makeCommandQueue()!
let metalView = MTKView(frame: .zero, device: device)
metalView.clearColor = MTLClearColorMake(0, 0, 1, 1)
metalView.delegate = self
self.view = metalView
}
func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {
}
func draw(in view: MTKView) {
guard let commandBuffer = commandQueue.makeCommandBuffer(),
let passDescriptor = view.currentRenderPassDescriptor else { return }
if let commandEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: passDescriptor) {
// set state, issue draw calls, etc.
commandEncoder.endEncoding()
}
commandBuffer.present(view.currentDrawable!)
commandBuffer.commit()
}
}
func makeMainMenu() -> NSMenu {
let mainMenu = NSMenu()
let mainAppMenuItem = NSMenuItem(title: "Application", action: nil, keyEquivalent: "")
let mainFileMenuItem = NSMenuItem(title: "File", action: nil, keyEquivalent: "")
mainMenu.addItem(mainAppMenuItem)
mainMenu.addItem(mainFileMenuItem)
let appMenu = NSMenu()
mainAppMenuItem.submenu = appMenu
let appServicesMenu = NSMenu()
NSApp.servicesMenu = appServicesMenu
appMenu.addItem(withTitle: "Hide", action: #selector(NSApplication.hide(_:)), keyEquivalent: "h")
appMenu.addItem({ () -> NSMenuItem in
let m = NSMenuItem(title: "Hide Others", action: #selector(NSApplication.hideOtherApplications(_:)), keyEquivalent: "h")
m.keyEquivalentModifierMask = [.command, .option]
return m
}())
appMenu.addItem(withTitle: "Show All", action: #selector(NSApplication.unhideAllApplications(_:)), keyEquivalent: "")
appMenu.addItem(NSMenuItem.separator())
appMenu.addItem(withTitle: "Services", action: nil, keyEquivalent: "").submenu = appServicesMenu
appMenu.addItem(NSMenuItem.separator())
appMenu.addItem(withTitle: "Quit", action: #selector(NSApplication.terminate(_:)), keyEquivalent: "q")
let fileMenu = NSMenu(title: "Window")
mainFileMenuItem.submenu = fileMenu
fileMenu.addItem(withTitle: "Close", action: #selector(NSWindowController.close), keyEquivalent: "w")
return mainMenu
}
let app = NSApplication.shared
NSApp.setActivationPolicy(.regular)
NSApp.mainMenu = makeMainMenu()
let appDelegate = AppDelegate()
NSApp.delegate = appDelegate
NSApp.run()
尽管这看起来像很多代码,但其中大部分是可可模板,用于创建窗口及其主菜单并与之交互。金属代码仅在中间隐藏了几行(请参见func draw
)。
要构建和运行此应用,请将代码保存到Swift文件(我称为MinalMetal.swift),然后使用xcrun
找到构建所需的工具和SDK:
xcrun -sdk macosx swiftc MinimalMetal.swift -o MinimalMetal
这将在同一目录中创建一个名为“ MinimalMetal”的可执行文件,您可以使用该可执行文件运行
./MinimalMetal
这是一款功能完善的应用程序,具有窗口,菜单,运行循环和60 FPS绘图。从这里,您可以使用您可能想要的Metal的所有功能。
答案 1 :(得分:0)
您可以使用python,请尝试以下操作: https://github.com/wtnb75/runmetal您可以将金属内核编译为字符串并将其与numpy数组链接