渲染代码书写指北之Metal

渲染代码书写指北之Metal

渲染代码书写指北之Metal_第1张图片
Metal.png
  • 使用MTKView
    • 设置MTKViewdevice
    MTLCreateSystemDefaultDevice();
    
    • 设置MTKView的代理为渲染对象
  • 自定义渲染对象
    • 创建渲染对象,并接收MTKView
    - (instancetype)initWithMTKView:(SSMTView *)view;
    
    • 遵守协议,并实现协议方法:
    - (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size {
        //设置视口
    }
    - (void)drawInMTKView:(nonnull MTKView *)view {
        //渲染代码
    }
    
    • 着色器
      • 加载着色器
      id defaultLibrary = [_device newDefaultLibrary];
      
      • 加载顶点函数
      id vertexFunction = [defaultLibrary newFunctionWithName:@"vertexShader"];
      
      • 加载片元函数
      id fragmentFunction = [defaultLibrary newFunctionWithName:@"fragmentShader"];
      
    • 管道
    //3.配置用于创建管道状态的管道
    MTLRenderPipelineDescriptor *pipelineStateDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
    //管道名称
    pipelineStateDescriptor.label = @"Simple Pipeline";
    //可编程函数,用于处理渲染过程中的各个顶点
    pipelineStateDescriptor.vertexFunction = vertexFunction;
    //可编程函数,用于处理渲染过程中各个片段/片元
    pipelineStateDescriptor.fragmentFunction = fragmentFunction;
    //一组存储颜色数据的组件
    pipelineStateDescriptor.colorAttachments[0].pixelFormat = mtkView.colorPixelFormat;
    //4.同步创建并返回渲染管线状态对象
    _pipelineState = [_device newRenderPipelineStateWithDescriptor:pipelineStateDescriptor error:&error];
    
    • 命令队列
    _commandQueue = [_device newCommandQueue];
    
    • 顶点数据
    • 纹理数据
    • 投影矩阵和模型视图矩阵
    • 视口更新
    • 渲染
      • 命令缓冲区
      id commandBuffer = [_commandQueue commandBuffer];
      commandBuffer.label = @"MyCommand";
      
      • 渲染命令编码器
      // MTLRenderPassDescriptor:一组渲染目标,用作渲染通道生成的像素的输出目标。
      MTLRenderPassDescriptor *renderPassDescriptor = view.currentRenderPassDescriptor;
      //创建渲染命令编码器,这样我们才可以渲染到something
      id renderEncoder =[commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
      renderEncoder.label = @"MyRenderEncoder";
      
      • 设置视口
      MTLViewport viewPort = {
          0.0,0.0,_viewportSize.x,_viewportSize.y,-1.0,1.0
      };
      [renderEncoder setViewport:viewPort];
      //[renderEncoder setViewport:(MTLViewport){0.0, 0.0, _viewportSize.x, _viewportSize.y, -1.0, 1.0 }];
      
      • 设置管道
      [renderEncoder setRenderPipelineState:_pipelineState];
      
      • 传送视口数据
      //1) 发送到顶点着色函数中,视图大小
      //2) 视图大小内存空间大小
      //3) 对应的索引
      [renderEncoder setVertexBytes:&_viewportSize
                             length:sizeof(_viewportSize)
                            atIndex:CCVertexInputIndexViewportSize];
      
      • 传送顶点数据
      //顶点数据+颜色数据
      //   1) 指向要传递给着色器的内存的指针
      //   2) 我们想要传递的数据的内存大小
      //   3)一个整数索引,它对应于我们的“vertexShader”函数中的缓冲区属性限定符的索引。
      
      [renderEncoder setVertexBytes:triangleVertices
                             length:sizeof(triangleVertices)
                            atIndex:CCVertexInputIndexVertices];
      
      • 传送纹理数据
      • 传送投影矩阵和模型视图矩阵
      • 设置正背面剔除
      • 绘制
      // @method drawPrimitives:vertexStart:vertexCount:
      //@brief 在不使用索引列表的情况下,绘制图元
      //@param 绘制图形组装的基元类型
      //@param 从哪个位置数据开始绘制,一般为0
      //@param 每个图元的顶点个数,绘制的图型顶点数量
      /*
       MTLPrimitiveTypePoint = 0, 点
       MTLPrimitiveTypeLine = 1, 线段
       MTLPrimitiveTypeLineStrip = 2, 线环
       MTLPrimitiveTypeTriangle = 3,  三角形
       MTLPrimitiveTypeTriangleStrip = 4, 三角型扇
       */
      [renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle
                        vertexStart:0
                        vertexCount:3];
      
      • 结束渲染命令编码
      [renderEncoder endEncoding];
      
      • 使用当前可绘制的进度表
      [commandBuffer presentDrawable:view.currentDrawable];
      
      • 完成渲染并将命令缓冲区推送到GPU
      [commandBuffer commit];
      

你可能感兴趣的:(渲染代码书写指北之Metal)