渲染代码书写指北之Metal
2019-07-15 本文已影响0人
silasjs
渲染代码书写指北之Metal
Metal.png- 使用
MTKView
- 设置
MTKView
的device
MTLCreateSystemDefaultDevice();
- 设置MTKView的代理为渲染对象
- 设置
- 自定义渲染对象
- 创建渲染对象,并接收
MTKView
- (instancetype)initWithMTKView:(SSMTView *)view;
- 遵守
<MTKViewDelegate>
协议,并实现协议方法:
- (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size { //设置视口 } - (void)drawInMTKView:(nonnull MTKView *)view { //渲染代码 }
- 着色器
- 加载着色器
id<MTLLibrary> defaultLibrary = [_device newDefaultLibrary];
- 加载顶点函数
id<MTLFunction> vertexFunction = [defaultLibrary newFunctionWithName:@"vertexShader"];
- 加载片元函数
id<MTLFunction> 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<MTLCommandBuffer> commandBuffer = [_commandQueue commandBuffer]; commandBuffer.label = @"MyCommand";
- 渲染命令编码器
// MTLRenderPassDescriptor:一组渲染目标,用作渲染通道生成的像素的输出目标。 MTLRenderPassDescriptor *renderPassDescriptor = view.currentRenderPassDescriptor; //创建渲染命令编码器,这样我们才可以渲染到something id<MTLRenderCommandEncoder> 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];
- 创建渲染对象,并接收