我一直在使用Xcode项目,但现在我开始在其他平台上运行我想要的项目,所以我使用Swift Package Manager来生成项目,但是我面临一个问题,我的库需要包含一个金属着色器文件(也是一个openGL着色器文件),但我对如何实现这一点毫无头绪。
我的项目有2个部分,包含图形内容的库和可执行文件是我的实际应用程序,所以我想将我的图形库导入到我的应用程序中,但问题是金属着色器文件不包含在Xcode项目似乎也没有编译/包含在库的捆绑文件中,因此我可以在运行时加载并在需要时使用它。
另外,如果你认为我做错了事,请指点我。
此致
答案 0 :(得分:3)
将您的 Shaders.metal
文件放入 Metal
目录。然后在 Package.swift
.target(
name: "TargetName",
dependencies: [
.product(name: "AnotherModule", package: "AnotherPackage")
],
resources: [
.copy("Metal/")
]
)
现在您可以访问您的图书馆了:
let url = Bundle.module.url(forResource: "Shaders", withExtension: "metal", subdirectory: "Metal")!
let source = try String(contentsOf: url)
let library = try device.makeLibrary(source: source, options: nil)
甚至更好(但仅适用于单个着色器文件):
.target(
name: "TargetName",
dependencies: [
.product(name: "AnotherModule", package: "AnotherPackage")
],
resources: [
.process("Metal/Shaders.metal")
]
)
现在您可以访问您的图书馆了:
let library = try device.makeDefaultLibrary(bundle: Bundle.module)
答案 1 :(得分:2)
在Xcode 12 (swift-tools-version:5.3)中,可以使用h["monday"]["morning"].append("Ben")
方法在Swift软件包中使用.metal文件。
Swift软件包的结构应类似于:
h["monday"]["morning"] = []
h["monday"]["morning"].append("Ben")
文件MTLDevice.makeDefaultLibrary(bundle:)
应该包含Metal源代码,文件-Sources
-MetalShaders
-MetalShaders.metal
-MetalShaders.swift
-Tests
-MetalShadersTests
-MetalShadersTests.swift
应该包含必要的设置代码。 MetalShaders.metal
初始内容的一个示例如下:
MetalShaders.swift
使用这种方法,可以通过从swift包中导入目标,就像导入其他框架或包一样,从依赖于Swift包的Xcode项目中访问MetalShaders.swift
变量。 / p>
// A metal device for access to the GPU.
public var metalDevice: MTLDevice!
// A metal library.
public var packageMetalLibrary: MTLLibrary!
// Function to perform the initial setup for Metal processing on the GPU
public func setupMetal() {
// Create metal device for the default GPU:
metalDevice = MTLCreateSystemDefaultDevice()
// Create the library of metal functions
// Note: Need to use makeDefaultLibrary(bundle:) as the "normal"
// call makeDefaultLibrary() returns nil.
packageMetalLibrary = try? metalDevice.makeDefaultLibrary(bundle: Bundle.module)
// List the available Metal shader functions
print(packageMetalLibrary.functionNames)
//
// ... add additional setup code here ...
//
}
由于从iOS 10 / macOS 10.12开始可以使用方法packageMetalLibrary
,因此可以在早期版本的Xcode上使用此方法,但是需要实现import MetalShaders
扩展名,但并非必须如此。清除是否可行。
答案 2 :(得分:1)
let source = """
#include <metal_stdlib>
using namespace metal;
struct Vertex {...
"""
let library = try device.makeLibrary(source: source options: nil)
print(library.functionNames)
Metal的类允许在运行时从String构建着色器库。 https://developer.apple.com/documentation/metal/libraries 希望能有所帮助。
答案 3 :(得分:0)
似乎现在无法做到这一点。当找到解决方法或Apple修复此问题时,我会更新此信息。
https://bugs.swift.org/browse/SR-2866
编辑:我找到的临时解决方案是创建bash script,编辑工作区设置以更改构建路径,然后将metallib文件编译/复制到可执行路径(didn还没试过看看如何通过SPM或类似的方式分发库,现在只能使用同一文件夹中的代码(即Sources / MyEngine&lt; - (此文件夹有金属着色器),Sources / MyGame )。