Могу ли я программировать графику Apple Metal без Xcode? - PullRequest
0 голосов
/ 25 октября 2018

Можно ли кодировать программу для работы с графикой Metal только с помощью редактора на терминале?Если это так, что будет примером минимального приложения?

Я бы хотел попробовать генеративное кодирование, но без Xcode.Я смог сделать небольшие программы на C или Python с OpenGL, но его отказ от Apple заставляет меня задуматься о Metal.

Могу ли я использовать Swift и некоторые включения в заголовки или что-то в этом роде?или мне нужно намного больше?

Ответы [ 2 ]

0 голосов
/ 21 июня 2019

вы можете с python, попробуйте это: https://github.com/wtnb75/runmetal вы можете скомпилировать металлическое ядро ​​в строку и связать его с массивами numpy

0 голосов
/ 26 октября 2018

Вы можете скомпилировать и запустить приложение, которое использует Metal, из командной строки вообще без проекта XCode, но вам все еще нужна инфраструктура (SDK и набор инструментов), предоставляемая XCode, поэтому вам необходимо установить ее.

Довольно просто написать простое приложение в Swift, которое создает необходимые металлические объекты, кодирует некоторые работы и записывает результат в файл.Для целей этого вопроса я предоставлю исходный текст для простого приложения 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()

Хотя это выглядит как большой код, большая часть его - шаблон Cocoa для создания и взаимодействия с окном и егоглавное меню.Код Metal - это всего лишь несколько строк, спрятанных посередине (см. func draw).

Чтобы создать и запустить это приложение, сохраните код в файле Swift (я назвал мой MinimalMetal.swift) и используйтеxcrun для поиска инструментов и SDK, необходимых для сборки:

xcrun -sdk macosx swiftc MinimalMetal.swift -o MinimalMetal

Это создает исполняемый файл с именем "MinimalMetal" в том же каталоге, который вы можете запустить с помощью

./MinimalMetal 

Thisявляется полноценным приложением с окном, меню, циклом выполнения и рисованием 60 FPS.Отсюда вы можете использовать все функции Metal, которые вам могут понадобиться.

...