iOS metal API(二) - 使用Metal绘制视图的内容

创建一个MetalKit视图和一个渲染过程以绘制视图的内容。

下载demo

纵览

在这个示例中,你将学习使用Metal 渲染图形内容的基础知识。你将使用MetalKit 框架创建一个视图并用Metal 来绘制视图的内容。然后,你将编码为视图设置背景颜色的渲染过程中的命令。

注意

MetalKit自动执行窗口系统任务,加载纹理并处理3D模型数据。阅读MetalKit来了解更多信息。

准备要绘制的MetalKit 视图

metalKit 提供一个叫MTKView的类, 它是NSView(在macOS中)或者UIView(在iOS 和 tvOS中)的子类,MTKView处理许多与将用Metal绘制的内容显示在屏幕上相关的细节。
为了在内部创建资源,MTKView需要对Metal设备对象的引用,因此,第一步是将视图的device属性设置为现有的MTLDevice

_view.device = MTLCreateSystemDefaultDevice();

MTKView上的其他属性允许你控制其行为,将视图内容擦除为纯背景色,设置它的clearColor属性。通过MTLClearColorMake()函数创建颜色,指定红色、绿色、蓝色和alpha值。

_view.clearColor = MTLClearColorMake(0.0, 0.5, 1.0, 1.0);

因为在这个示例中不会绘制动画内容,所以配置视图,使其仅在需要更新内容时绘制。

_view.enableSetNeedsDisplay = YES;

代理绘图任务

MTKView依赖于您的应用程序向Metal发出命令以生成可视内容。MTKView使用代理模式通知应用程序何时应该绘制。为了接受代理的回调,将视图的delegate属性设置为符合MTKViewDelegate协议的对象。

_view.delegate = _renderer;

代理实现了两个方法:
1.每当内容大小发生变化时,视图将调用mtkView:drawableSizeWillChange:方法,这种变化在包含视图的窗口调整大小时,或者当设备方向发生变化时(在iOS上)发生。这允许应用程序根据视图的大小调整渲染时的分辨率。
2.每当到刷新视图内容的时间时,视图会调用drawInMTKView:方法。在这个方法中创建一个命令缓冲区,编码命令告诉GPU画什么和什么时候现在在屏幕上,然后在将要由GPU执行的命令缓冲区中排队。这个有时候称为画框。你可以把一个框架看作是产生一个在屏幕上显示的单一图像的所有工作。在一个交互式App中,比如游戏, 你可能每秒钟画很多框架。
在这个示例中,一个叫AAPLRenderer的类实现了代理方法并承担绘图的责任。视图控制器创建这个类的一个实例并把它设置为视图的代理。

创建渲染过程描述符

当你绘图,GPU会把结果存储到纹理中,纹理是包含图像数据的内存块,可被GPU访问。在本示例中,MTKView将创建需要绘制到视图中的所有纹理。它创建多个纹理,以便在渲染到另一个纹理时显示一个纹理的内容。
要进行绘制,请创建一个渲染过程,该过程是一系列渲染命令,这些命令绘制成一组纹理。在渲染过程中使用时,纹理也被称为渲染目标。若要创建渲染过程,需要一个渲染过程描述符,即MTLRenderPassDescriptor的实例。在这个示例中,与其配置自己的渲染过程描述符,不如让MetalKit 给你创建一个。

MTLRenderPassDescriptor *renderPassDescriptor = view.currentRenderPassDescriptor;
if (renderPassDescriptor == nil)
{
    return;
}

一个渲染过程描述符描述一组渲染目标,以及在渲染过程开始和结束时应如何处理这些目标。渲染过程还定义了渲染的某些其他方面,这些方面不是此例的一部分。该视图返回一个渲染过程描述符,该描述符具有指向该视图的某个纹理的单色附件,并根据该视图的属性配置渲染过程。默认情况下,这意味着渲染过程开始时,渲染目标将被擦除为纯色来匹配视图的clearColor属性,并且在渲染过程结束时所有更改都存储回纹理。
一个一个视图的渲染过程描述符可能为nil, 在创建渲染过程之前, 应该确保渲染过程描述符对象不为nil。

创建一个渲染过程

通过使用 MTLRenderCommandEncoder对象将其编码到命令缓冲区来创建渲染过程。调用命令缓冲区的render>CommandEncoderWithDescriptor:方法并在渲染过程描述符中传递。

id<MTLRenderCommandEncoder> commandEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];

在本示例中,您不编码任何绘图命令,因此渲染过程只会删除纹理。调用编码器的endEncoding方法以指示该过程已完成。

[commandEncoder endEncoding];

在屏幕上呈现一幅图画

绘制到纹理不会自动在屏幕上显示新内容。实际上, 只有一些纹理可以显示在屏幕上。Metal中,可以在屏幕上显示的纹理由drawable对象管理,要显示内容,请显示可绘制对象。
MTKView自动创建可绘制对象来管理它的纹理,读取currentDrawable
属性以获取拥有作为渲染过程目标的纹理的drawable。视图返回一个CAMetalDrawable
对象,一个连接到核心动画的对象。

id<MTLDrawable> drawable = view.currentDrawable;

在命令缓冲区中调用presentDrawable:方法,传递drawable。

[commandBuffer presentDrawable:drawable];

此方法告诉Metal,当计划执行命令缓冲区时,Metal应与核心动画协调以在渲染完成后显示纹理。当核心动画呈现纹理时,它将成为视图的新内容。在本示例中,这意味着删除的纹理将成为视图的新背景。这种变化与核心动画为屏幕用户界面元素所做的任何其他视觉更新一起发生。

提交命令缓冲区

现在已经发出了帧的所有命令,提交命令缓冲区。

[commandBuffer commit];
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,743评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,296评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,285评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,485评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,581评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,821评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,960评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,719评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,186评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,516评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,650评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,329评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,936评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,757评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,991评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,370评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,527评论 2 349