概述

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 绘制流程有个基本了解。


​​​​​​​

Metal 框架之 MTKView相关推荐

  1. Metal 框架之自定义设置渲染通道

    概述 渲染通道是一系列渲染命令,用于绘制一组纹理.本示例执行一对渲染通道来渲染视图的内容.对于第一个通道,示例创建了一个自定义渲染,将图像渲染成纹理.这个通道是一个离屏渲染通道,因为样本渲染为普通纹理 ...

  2. Metal 框架之渲染管线渲染图元

    概述 在 < Metal 框架之使用 Metal 来绘制视图内容 >中,介绍了如何设置 MTKView 对象并使用渲染通道更改视图的内容,实现了将背景色渲染为视图的内容.本示例将介绍如何配 ...

  3. Metal 框架之使用 Metal Debugger 查看 GPU 工作负载

    概述 为了了解计算机是如何运行 App 或调试问题,通常要使用调试器.传统的调试器通过暂停一个线程来工作,但对基于 Metal 的 App 效果不佳. Xcode 通过帧捕获工作流专门为 Metal ...

  4. Metal 框架之创建纹理及纹理采样

    概述 Metal 中使用纹理来绘制和处理图像,它是由像素组成的.使用2维数组的纹理来保存图像,每个元素都包含颜色数据.通过纹理映射技术将纹理绘制到几何图元上. 在片段着色器中,使用片段函数对纹理采样来 ...

  5. 基于 Metal 框架的 GPU 计算

    概述 GPU 的优势在于并发计算能力,在本示例中,你将学习如何使用 Apple 的新框架 Metal 来实现并发计算. 你将学会如何将用C编写的简单函数转换为 Metal Shading Langua ...

  6. Metal 框架之从可绘制纹理中读取像素数据

    概述 Metal 优化了纹理以供 GPU 快速访问,但不允许直接从 CPU 访问纹理的内容.当 App 需要更改或读取纹理的内容时,需要 Metal 在纹理和可访问的 CPU 内存(系统内存或使用共享 ...

  7. Metal 框架之资源存储模式

    概述 Metal 中使用 MTLStorageMode 来指定资源的内存位置和访问权限. MTLStorageMode 是个枚举类型,定义如下: public enum MTLStorageMode ...

  8. Metal 框架之渲染到多个视口

    概述 视口定义了渲染目标的一部分,绘图命令会渲染到该区域内.使用视口选择,可以为绘图命令提供多个视口,并且可以为绘图命令渲染的每个图元动态选择其中的一个视口.通过视口选择,使用更少的绘图命令,可以更轻 ...

  9. Metal 框架之渲染到多个纹理切片

    概述 使用图层选择为顶点着色器中的每个图元选择目标切片,可以将图元渲染到纹理数组.立方体纹理或 3D 纹理的多个层(切片)中.层是单个 1D.2D 或 3D 像素块,由目标纹理中的切片和 mipmap ...

最新文章

  1. vba 字体颜色_多掌握一些VBA语句,让自己书写代码更加顺畅
  2. 无人驾驶系列】光学雷达(LiDAR)在无人驾驶技术中的应用
  3. 16-python基础5-文件读写操作
  4. 网和aoe网的区别_运动内衣与普通内衣有什么区别?运动内衣里面还需要穿文胸吗? 小家生活网20201002 11:03:04...
  5. 存储过程/函数权限的问题解决(The user specified as a definer ('root'@'%') does not exist)...
  6. (转)KeyDown、KeyUp、KeyPress区别
  7. 产品小姐姐收到这个黑科技后,开心了一整天...
  8. mysql数据库的笔试题_MySQL数据库常见面试题
  9. java正则表达式爬图片_Java正则表达式爬取网页,贴出完整代码
  10. MVC5+EF6简单实例---以原有SQLServer数据库两表联合查询为例
  11. WPF中如何选择合适的元数据标记?(英文)
  12. Java下载base64图片
  13. Java内存模型—JMM详解
  14. 【LSTM时间序列预测】基于matlab贝叶斯网络优化LSTM时间序列预测【含Matlab源码 1329期】
  15. ESP32笔记(2) flash使用
  16. win10下出现.net framework 3.5错误代码0x800F081F的问题
  17. 大数据为我们的生活带来了什么?
  18. linux who 时间,linux命令之who、w、whoami
  19. 协同过滤推荐算法及应用
  20. Libgdx之国际化 中英文菜单切换

热门文章

  1. 蚂蚁金服、滴滴们掀起A/H上市潮,它们能打破折溢价的烦恼吗?
  2. 25-方向传感器实现指南针
  3. Halcon 第三章『Morphology形态学』◆第3节:顶帽运算与底帽运算
  4. 体验ANT DESIGN PRO V5--项目创建并安装umi气泡工作台
  5. a king读后感 love of the_小王子英语读后感推荐
  6. android 后台运行 保活
  7. Git 修改已提交的 commit 信息
  8. 单片机经典外围电路(一)--LCD1602显示
  9. MacBook替换登录界面壁纸
  10. html5百度地图选中标注点,js 调用百度地图api并在地图上进行打点添加标注