Metal 框架之 MTKView

20 篇文章 0 订阅
19 篇文章 0 订阅

概述

MTKView 封装了 Metal 的基本功能,隐藏了配置 Metal 的一些操作,省去了开发者配置的麻烦,开发者只需要将精力花费在图形渲染即数据准备上就可以。

在 iOS, iPadOS, Mac Catalyst, tvOS中,代码定义如下:

```

class MTKView : UIView 

```

在 macOS 中定义如下:

```

class MTKView : NSView

```

MTKView 使用 CAMetalLayer 来管理 Metal 可绘制对象,通过 MTLRenderPassDescriptor 对象可以将内容渲染到一个纹理中。

此外,通过 MTKView 可以创建深度和模板纹理以及抗锯齿所需的任何中间纹理。该视图使用 CAMetalLayer 来管理 Metal 可绘制对象。

指定绘制模式

MTKView 支持三种绘制模式:

  • 定时更新:视图根据内部计时器重绘其内容。默认情况下使用这个绘制方式,初始化时需要将 isPaused 和 enableSetNeedsDisplay 都设置为 false。游戏和更新的动画内容常用这种模式。

  • 绘制通知:当调用 setNeedsDisplay() 或者 当某些内容使其内容无效时,视图会重绘自身。在这种情况下,将 isPaused 和 enableSetNeedsDisplay 设置为 true。这种模式适用于具有更传统工作流程的应用程序,更新只会在数据更改时发生,而不会定期更新。

  • 显式绘制:当显式调用 draw() 方法时,视图才会重绘其内容。这种模式下,需要将 isPaused 设置为 true 并将 enableSetNeedsDisplay 设置为 false。一般使用此模式来创建自定义工作流程。

绘制

无论使用哪一种绘图模式,当视图需要更新其内容时,在子类重写 draw(:) 方法时,它会调用 draw(:) 方法,否则在视图的委托上调用 draw(in:) 方法。

在绘图方法中,从视图中获取渲染通道描述符,此后的渲染结果都会存在渲染通道描述符中,最后渲染结果呈现在其关联的可绘制对象上。

从 MetalKit 视图中获取可绘制对象

CAMetalLayer 提供 MTKView 视图的绘图能力。在渲染器过程中,需要实现 MTKViewDelegate 协议来实现与 MetalKit 视图交互。调用 MetalKit 视图的 currentRenderPassDescriptor 属性可以获取当前帧的渲染通道描述符:

``` 

// BEGIN encoding your onscreen render pass.

// Obtain a render pass descriptor generated from the drawable's texture.

// (currentRenderPassDescriptor implicitly obtains the current drawable.)

// If there's a valid render pass descriptor, use it to render to the current drawable.

if let onscreenDescriptor = view.currentRenderPassDescriptor

```

当读取currentRenderPassDescriptor属性时,Core Animation 会隐式获取当前帧的可绘制对象并将其存储在 currentDrawable 属性中。后续深度、模板和抗锯齿纹理会被绘制到 currentDrawable 对象中。视图使用默认的存储和加载操作配置此渲染通道,在创建 MTLRenderCommandEncoder 之前,可以调整描述符。为了提升渲染性能,应该尽可能晚地获取可绘制对象,最好是在编码屏幕渲染通道之前。

关联可绘制对象

在渲染内容后,需要将可绘制对象的结果更新到视图中来显示。展示内容最方便的方法是调用命令缓冲区上的 present(:) 方法将视图与命令缓冲区关联起来,然后调用 commit() 方法将命令缓冲区提交给 GPU:

```  if let onscreenDescriptor = view.currentRenderPassDescriptor,

let onscreenCommandEncoder = onscreenCommandBuffer.makeRenderCommandEncoder(descriptor: onscreenDescriptor) {

    /* Set render state and resources.

       ...

     */

    /* Issue draw calls.

       ...

     */

    onscreenCommandEncoder.endEncoding()

    // END encoding your onscreen render pass.

    // Register the drawable's presentation.

    if let currentDrawable = view.currentDrawable {

        onscreenCommandBuffer.present(currentDrawable)

    }

}

// Finalize your onscreen CPU work and commit the command buffer to a GPU.

onscreenCommandBuffer.commit()

```

当命令队列调度可执行的命令缓冲区时,可绘制对象会在该命令缓冲区中遍历其自身的所有渲染或写入请求。在命令完成执行之前,操作系统不会在屏幕上显示可绘制对象。通过这种调度方式,保证了命令队列调度此命令缓冲区之后才显示渲染结果。

总结

本文介绍了如何使用 MTKView 来创建、配置和展示 Metal 对象。讲解了 MTKView 使用的每个步骤,阅读完本文可以对 MTKView 绘制流程有个基本了解。


​​​​​​​

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值