Metal 开发教程(一)

原文链接: https://developer.apple.com/documentation/metalkit/mtkview?language=objc

MTKView 用于创建,配置,显示metal对象。MTKView提供了一个MTLRenderPassDescriptor对象,该对象指向一个纹理来渲染内容。MTKView 使用CAMetalLayer来管理drawable对象。MTKView 需要一个MTLDevice对象来管理Metal对象。在绘制之前必须设置device相关属性。

MTKView 提供了3种绘制模式:

  • Timed updates: view内容的重绘依赖内部的计时器。此时paused 和 enableSetNeedsDisplay 为NO。该模式用于定期更新的游戏和其他动画内容。
  •  Draw notifications: 当内容无效时view会进行重绘操作。一般由于调用了setNeedsDisplay方法或其他相关的view行为。paused 和 enableSetNeedsDisplay为YES。该模式用于传统的工作流程序,当数据更改时会进行更新。
  • Explicit drawing: 当显式调用draw方法时view会进行重绘操作。paused=YES, enableSetNeedsDisplay=NO。该模式用于创建自定义的工作流程。

无论哪种绘图模式,当view需要更新内容时会调用子类的drawRect:方法或者delegate的drawInMTKView:方法。你需要实现MTKView的子类或提供delegate,无需2种都提供。在你的绘制方法中你可以根据view的descriptor获取rander进行绘制。

每个MTKView都有一个CAMetalLayer;通过实现MTKViewDelegate 来和MTKView的交互。调用MTKView的属性currentRenderPassDescriptor配置render.

MTLRenderPassDescriptor* onscreenDescriptor = view.currentRenderPassDescriptor;

读取此属性时,Core Animation隐式获取当前帧的drawable并将其存储在currentDrawable属性中,配置要绘制的render包括必要的 depth, stencil 和 antialiasing textures。你可以在创建MTLRenderCommandEncoder之前调整descriptor功能。建议尽可能晚的获取drawable,最好在渲染之前立即获取。

 当内容渲染完成后,您必须呈现drawable以更新view的内容。呈现内容最方便的方法是在命令缓冲区上调用presentDrawable:方法,然后调用commit方法将命令提交给GPU。

// If there's a valid render pass descriptor, use it to render to the current drawable.
if(onscreenDescriptor != nil) {
    id<MTLRenderCommandEncoder> onscreenCommandEncoder = [onscreenCommandBuffer renderCommandEncoderWithDescriptor:onscreenDescriptor];
    /* Set render state and resources.
       ...
     */
    /* Issue draw calls.
       ...
     */
    [onscreenCommandEncoder endEncoding];
    // END encoding your onscreen render pass.

    // Register the drawable's presentation.
    [onscreenCommandBuffer presentDrawable:view.currentDrawable];
}

// Finalize your onscreen CPU work and commit the command buffer to a GPU.
[onscreenCommandBuffer commit];

当命令队列计划执行命令缓冲区时,drawable将跟踪该命令缓冲区中自身的所有呈现或写入请求。在命令完成执行之前,操作系统不会在屏幕上显示drawable。通过请求命令缓冲区显示drawable,可以确保在命令队列调度了此命令缓冲区之后显示。在注册drawable的之前,无需等待命令缓冲区完成执行。

为了追求更好的性能,当你准备好要渲染内容的时候来获取render的descriptor,并且尽可能减少控制drawable对象。命令一旦完成应立即释放drawable。

 

posted @ 2020-03-10 22:58  爱学习的绿叶  阅读(969)  评论(0编辑  收藏  举报