我可以在没有 Xcode 的情况下对 Apple Metal 图形进行编程吗? [英] Can I program Apple Metal graphics without Xcode?

查看:44
本文介绍了我可以在没有 Xcode 的情况下对 Apple Metal 图形进行编程吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以仅使用编辑器和终端来编写 Metal 图形程序?如果是,那么最小应用程序的示例是什么?

Is it possible to code a Metal graphics program with only an editor an the terminal? If it is, What would be an example of a minimal application?

我想尝试一些生成式编码,但没有 Xcode.我能够使用 OpenGL 编写小型 C 或 Python 程序,但它被 Apple 弃用让我考虑使用 Metal.

I'd like to try some generative coding but without Xcode. I was able to make small C or Python programs with OpenGL but its deprecation by Apple is making me consider Metal.

我可以使用 Swift 和一些头文件或类似的东西吗?还是我需要更多?

Can I use Swift and some header inclusions or something like that? or do I need a whole lot more?

推荐答案

您可以从命令行编译和运行使用 Metal 的应用程序,而根本不需要 Xcode 项目,但您仍然需要提供的基础设施(SDK 和工具链)通过 Xcode,所以你需要安装它.

You can compile and run an app that uses Metal from the command line with no Xcode project at all, but you still need the infrastructure (SDK and toolchain) provided by Xcode, so you'll need to have it installed.

用 Swift 编写一个简单的应用程序非常简单,它创建必需的 Metal 对象,编码一些工作,并将结果写入文件.出于这个问题的目的,我将提供一个简单的 Cocoa 应用程序的源代码,该应用程序通过创建一个承载 MetalKit 视图并绘制到它的窗口来更进一步.使用此脚手架,您无需启动 Xcode 即可编写非常复杂的应用.

It's quite straightforward to write a simple app in Swift that creates the requisite Metal objects, encodes some work, and writes the result to a file. For the purposes of this question, I'll provide the source for a simple Cocoa app that goes a bit further by creating a window that hosts a MetalKit view and draws to it. With this scaffolding, you could write a very sophisticated app without ever launching 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()

虽然这看起来像很多代码,但其中大部分是用于创建窗口及其主菜单并与之交互的 Cocoa 样板.Metal 代码只有几行隐藏在中间(参见 func draw).

Although this looks like a lot of code, the bulk of it is Cocoa boilerplate for creating and interacting with a window and its main menu. The Metal code is only a few lines tucked away in the middle (see func draw).

要构建和运行此应用程序,请将代码保存到 Swift 文件(我将其命名为 MinimalMetal.swift)并使用 xcrun 找到构建所需的工具和 SDK:

To build and run this app, save the code to a Swift file (I called mine MinimalMetal.swift) and use xcrun to locate the tools and SDKs necessary to build:

xcrun -sdk macosx swiftc MinimalMetal.swift -o MinimalMetal

这会在同一目录中创建一个名为MinimalMetal"的可执行文件,您可以使用该文件运行

This creates an executable named "MinimalMetal" in the same directory, which you can run with

./MinimalMetal 

这是一个成熟的应用程序,具有窗口、菜单、运行循环和 60 FPS 绘图.从这里,您可以使用 Metal 的所有功能.

This is a full-fledged app, with a window, menu, runloop, and 60 FPS drawing. From here, you can use all the features of Metal you might want to.

这篇关于我可以在没有 Xcode 的情况下对 Apple Metal 图形进行编程吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆