swift - 我应该如何在 Metal 中渲染文本?

标签 swift text rendering metal

我只需要渲染二维文本,但我发现的示例(Text Rendering by MetalByExample.com)是用 Objective-C 编写的,非常困惑,并且可能有很多垃圾(不必要的代码或步骤)以获得完整功能)。我应该如何在 Metal 中渲染简单文本?这在 SwiftUI 中是微不足道的,但在 Metal 中如何做到呢?我知道这个问题有点模糊,但是关于如何在 Metal 中渲染简单文本的有用资源很少。给定这个起始代码,我如何渲染一个简单的 hello world 文本?

import Cocoa
import MetalKit
class ViewController: NSViewController {
    private let Device = MTLCreateSystemDefaultDevice()!
    private var CommandQue: MTLCommandQueue!, Pipeline: MTLRenderPipelineState!
    private var View: MTKView {
        return view as! MTKView
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        View.delegate = self
        View.device = Device
        CommandQue = Device.makeCommandQueue()
        let PipelineDescriptor = MTLRenderPipelineDescriptor()
        let Library = Device.makeDefaultLibrary()!
        PipelineDescriptor.vertexFunction = Library.makeFunction(name: "V")
        PipelineDescriptor.fragmentFunction = Library.makeFunction(name: "T")
        Pipeline = try? Device.makeRenderPipelineState(descriptor: PipelineDescriptor)
    }
}
extension ViewController: MTKViewDelegate {
    func mtkView(_ _: MTKView, drawableSizeWillChange Size: CGSize) {
        View.draw()
    }
    func draw(in _: MTKView) {
        let CommandBuffer = CommandQue.makeCommandBuffer()!, CommandEncoder = CommandBuffer.makeRenderCommandEncoder(descriptor: View.currentRenderPassDescriptor!)!
        CommandEncoder.setRenderPipelineState(Pipeline!)
        
        // Render
        
        CommandEncoder.endEncoding()
        CommandBuffer.present(View.currentDrawable!)
        CommandBuffer.commit()
    }
}

基本上,我如何在 Metal 中复制这个简单的 SwiftUI?我并不是要求“为我编写此代码”,但我想要一些关于从哪里开始的指示?

struct ContentView: View {
    var body: some View {
        Text("Hello, World!")
    }
}

最佳答案

您可以使用Core Image的CITextImageGenerator为了那个原因。 (还有用于属性文本的 CIAttributedTextImageGenerator。)

只需创建一个包含文本的 CIImage 并使用 CIContext 将文本渲染到 MTLTexture (或直接渲染到 View 中):

// Render
let textImage = CIFilter(name: "CITextImageGenerator", parameters: [
    "inputText": "Hello World!",
    "inputFontName": "HelveticaNeue",
    "inputFontSize": 40,
    "inputScaleFactor": 2.0
]).outputImage!

// Note: create the CIContext once and re-use it
self.ciContext.render(textImage, to: View.currentDrawable!, commandBuffer: CommandBuffer, bounds: textImage.extent colorSpace: CGColorSpaceCreateDeviceRGB())

从 macOS 10.15 开始,您还可以导入 CoreImage.CIFilterBuiltins 并使用新的基于协议(protocol)的 Core Image 接口(interface):

let textImageGenerator = CIFilter.textImageGenerator()
textImageGenerator.text = "Hello World!"
// ...
let textImage = textImageGenerator.outputImage!

如果你想改变文本的颜色,你可以使用带有属性字符串的CIAttributedTextImageGenerator,或者使用更多的核心图像过滤器和混合技术来为文本图像着色,然后再将其渲染到文本图像中。查看。

关于swift - 我应该如何在 Metal 中渲染文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65100459/

相关文章:

python - 从文本构建日期数组

javascript - 渲染速度: more objects or more scenes?

node.js - Pencilblue - 用于获取所有呈现文章的列表的 Web 服务

c++ - 在 OpenGL 中渲染 .ply 文件

ios - 具有多个标签的自调整单元格不显示多行标签

python - 如何计算句子中的单词数,忽略数字、标点符号和空格?

javascript - 从txt文件中获取值

ios - 避免弹出窗口在水平紧凑的环境中适应全屏

json - Swiftyjson - JSON 到带有字母部分的 TableView

ios - 如何真正阻止音频快速播放