3D图形API|【Metal API 教程(第一讲】用XCode6.1创建并调试Metal工程)

【3D图形API|【Metal API 教程(第一讲】用XCode6.1创建并调试Metal工程)】

Metal API

1.关于IOS 8 Metal
Metal API是apple 2014年在ios平台上推出的高效底层的3D图形API,它通过减少驱动层的API调用CPU的消耗提高渲染效率。
参考视频解说(百度云网盘链接) 1. Metal Framework Overview2. Metal Fundamentals 3. Metal Advanced
2.创建Metal工程

首先要准备好苹果开发者的账号和一只iPhone 6/6s/iPad Air 2,Metal工程目前的编译和调试都需要真机进行调试。
3D图形API|【Metal API 教程(第一讲】用XCode6.1创建并调试Metal工程)
文章图片


3D图形API|【Metal API 教程(第一讲】用XCode6.1创建并调试Metal工程)
文章图片


如果 没有连接真机并把目标设为真机的话,会出现 Metal Compiler Error问题。

3D图形API|【Metal API 教程(第一讲】用XCode6.1创建并调试Metal工程)
文章图片

设为真机后,最后link上MetalFramework点播放键就能在iphone6上运行了。
3. 代码概览 a. 创建设备和指令队列

_device = MTLCreateSystemDefaultDevice(); // create a new command queue _commandQueue = [_device newCommandQueue]; _defaultLibrary = [_device newDefaultLibrary];


b.加载资源(Metal Shader 和 ConstBuffer)
id fragmentProgram = [_defaultLibrary newFunctionWithName:@"lighting_fragment"]; id vertexProgram = [_defaultLibrary newFunctionWithName:@"lighting_vertex"];


_vertexBuffer = [_device newBufferWithBytes:kCubeVertexData length:sizeof(kCubeVertexData) options:MTLResourceOptionCPUCacheModeDefault]; _vertexBuffer.label = @"Vertices";


c.初始化渲染管线
MTLRenderPipelineDescriptor *pipelineStateDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; pipelineStateDescriptor.label= @"MyPipeline"; pipelineStateDescriptor.sampleCount= _sampleCount; pipelineStateDescriptor.vertexFunction= vertexProgram; pipelineStateDescriptor.fragmentFunction= fragmentProgram; pipelineStateDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm; pipelineStateDescriptor.depthAttachmentPixelFormat= _depthPixelFormat; // create a compiled pipeline state object. Shader functions (from the render pipeline descriptor) // are compiled when this is created unlessed they are obtained from the device's cache NSError *error = nil; _pipelineState = [_device newRenderPipelineStateWithDescriptor:pipelineStateDescriptor error:&error]; if(!_pipelineState) { NSLog(@">> ERROR: Couldnt create a pipeline: %@", error); // assert here if pipeline coudnt be created for any reason assert(0); }MTLDepthStencilDescriptor *depthStateDesc = [[MTLDepthStencilDescriptor alloc] init]; depthStateDesc.depthCompareFunction = MTLCompareFunctionLess; depthStateDesc.depthWriteEnabled = YES; _depthState = [_device newDepthStencilStateWithDescriptor:depthStateDesc]; //renderEncoder需要用到



d.执行渲染

// create a new command buffer for each renderpass to the current drawable id commandBuffer = [_commandQueue commandBuffer]; // create a render command encoder so we can render into something MTLRenderPassDescriptor *renderPassDescriptor = view.renderPassDescriptor; if (renderPassDescriptor) { id renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor]; [renderEncoder pushDebugGroup:@"Boxes"]; [renderEncoder setDepthStencilState:_depthState]; [renderEncoder setRenderPipelineState:_pipelineState]; [renderEncoder setVertexBuffer:_vertexBuffer offset:0 atIndex:0 ]; // NOTE: this could be alot faster if we render using instancing, but in this case we want to emit lots of draw calls for (int i = 0; i < kNumberOfBoxes; i++) { //set constant buffer for each box [renderEncoder setVertexBuffer:_dynamicConstantBuffer[_constantDataBufferIndex] offset:i*_sizeOfConstantT atIndex:1 ]; // tell the render context we want to draw our primitives [renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:36 instanceCount:1]; }[renderEncoder endEncoding]; [renderEncoder popDebugGroup]; // call the view's completion handler which is required by the view since it will signal its semaphore and set up the next buffer __block dispatch_semaphore_t block_sema = _inflight_semaphore; [commandBuffer addCompletedHandler:^(id buffer) { dispatch_semaphore_signal(block_sema); }]; // schedule a present once rendering to the framebuffer is complete [commandBuffer presentDrawable:view.currentDrawable]; // finalize rendering here. this will push the command buffer to the GPU [commandBuffer commit]; }




4.Metal 调试
3D图形API|【Metal API 教程(第一讲】用XCode6.1创建并调试Metal工程)
文章图片
GPU Trace查看界面
本文版权DsoTsin所有,转载文章请注明出处!

下一讲【iOS8 Metal API 教程:第二讲】编写Metal Shader并渲染3D模型(上)
由于缺米,Metal教程等后续Mac到手之后再更新(虚拟机太慢了)

    推荐阅读