Metal(二)- 案例01:HelloWorld

2020-08-31  本文已影响0人  Henry________

使用metal做一个最简单的demo,目的是了解一下metal的渲染流程


效果图

整体绘制流程:


绘制流程.png

具体代码实现:

1, MTKView配置

    //1.获取拿到`MTKView`设备
    _view = (MTKView *)self.view;
    //2.为_view 设置MTLDevice(必须)
    //一个MTLDevice 对象代表获取GPU的使用权限
    //通常我们可以调用方法MTLCreateSystemDefaultDevice()来获取单个的GPU对象.
    _view.device = MTLCreateSystemDefaultDevice();
    
    //3.HNRender该类是听从apple的建议,单独创建一个类来完成metal的渲染和代理的管理
    _render = [[HNRender alloc] initWithMetalKitView:_view];
    _view.delegate = _render;
    //4.视图可以根据该属性设置帧速率(该代理drawInMTKView方法的调用频率)
    _view.preferredFramesPerSecond = 1;

2,HNRender的初始化

-(id)initWithMetalKitView:(MTKView *)mtkView{
    self = [super init];
    if(self){
        //1.从mtkview中获取device,用于MTLCommandQueue的创建
        _device = mtkView.device;
        //2.MTLCommandQueue是程序与GPU交互的第一个对象,也是一个串行队列,保证CommandBuffer的顺序执行
        _commandQueue = [_device newCommandQueue];
    }
    return self;
}

3,实现MTKViewDelegate

数据准备

//获取一个随机色
//color为自定义结构体
    Color color;
    color.red = (float)(random() % 255) / 255;
    color.green = (float)(random() % 255) / 255;
    color.blue = (float)(random() % 255) / 255;
    color.alpha = 1;

开始绘制

- (void)drawInMTKView:(MTKView *)view{
    //1. 设置view的clearColor,相当于背景色
    view.clearColor = MTLClearColorMake(color.red, color.green, color.blue, color.alpha);
    
    //2. 每次渲染创建一个新的commandBuffer命令渲染编辑器
    //使用MTLCommandQueue创建MTCommandBuffer新对象,并且将MTLCommandQueue加入到MTCommandBuffer对象中去.
    id<MTLCommandBuffer> commandBuffer = [_commandQueue commandBuffer];
    commandBuffer.label = @"HNBuffer";
    
    //3. 通过当前MTKView获得渲染描述符
    //在渲染过程中使用的渲染配置状态,包括光栅化(例如多重采样),可见性,混合,镶嵌和图形功能状态,主要是渲染管道描述符中指定顶点或片段函数。
    MTLRenderPassDescriptor *descriptor = view.currentRenderPassDescriptor;
    if (descriptor) {
        //4.MTLCommandEncoder(命令渲染编辑器)通过MTLRenderPassDescriptor来创建
        id<MTLCommandEncoder> encoder = [commandBuffer renderCommandEncoderWithDescriptor:descriptor];
        encoder.label = @"HNRenderEncoder";
        
        //5. 此处做绘制操作
        
        //6. 完成encoder操作
        [encoder endEncoding];
        
        
    }
    
    /*
     因为GPU是不会直接绘制到屏幕上,因此你不给出去指令.是不会有任何内容渲染到屏幕上.
    */
    //7. 添加一个命令将帧缓存区的内容绘制到屏幕上
    [commandBuffer presentDrawable:view.currentDrawable];
    
    //8.
    //提交绘制
    [commandBuffer commit];
}
demo的GitHub地址
上一篇 下一篇

猜你喜欢

热点阅读