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工程目前的编译和调试都需要真机进行调试。
文章图片
文章图片
如果
没有连接真机并把目标设为真机的话,会出现
Metal Compiler Error问题。
文章图片
设为真机后,最后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 调试
文章图片
GPU Trace查看界面
本文版权DsoTsin所有,转载文章请注明出处!
下一讲【iOS8 Metal API 教程:第二讲】编写Metal Shader并渲染3D模型(上)
由于缺米,Metal教程等后续Mac到手之后再更新(虚拟机太慢了)
推荐阅读
- 宽容谁
- 我要做大厨
- 增长黑客的海盗法则
- 画画吗()
- 2019-02-13——今天谈梦想()
- 远去的风筝
- 三十年后的广场舞大爷
- 叙述作文
- 20190302|20190302 复盘翻盘
- 学无止境,人生还很长