使用Metal繪制第一個(gè)三角形

在之前OpenGL系列基礎(chǔ)之上,我們又對(duì)iOS原生Metal做了一些探索嫁审,這里主要是記錄一下學(xué)習(xí)的過程。

1.MTKView

在學(xué)習(xí)metal之前我們需要了解一下什么是MTKView失驶,它是蘋果基于自家的Metal渲染架構(gòu)上構(gòu)建的一個(gè)渲染視圖載體土居,類似于前面提到過的GLKView。它能夠?yàn)槲覀兲峁┰?code>OpenGL ES的類似效果嬉探。下面介紹下MTKView的初始化代碼:

- (void)createMTKView {
    // 創(chuàng)建GPU設(shè)備
    id<MTLDevice> device = MTLCreateSystemDefaultDevice();
    _device = device;
    // 創(chuàng)建MTKView
    self.mtkView = [[MTKView alloc] initWithFrame:self.view.bounds device:device];
    self.mtkView.delegate = self;
    self.mtkView.backgroundColor = UIColor.clearColor;
    [self.view addSubview:self.mtkView];

    // 記錄mtkView視口的大小
    self.viewportSize = (vector_uint2){self.mtkView.drawableSize.width, self.mtkView.drawableSize.height};

    // 創(chuàng)建命令隊(duì)列
    id<MTLCommandQueue> commandQueue = [self.device newCommandQueue];
    _commandQueue = commandQueue;
}

2.創(chuàng)建渲染管道

這里解釋下MTLRenderPipelineDescriptor對(duì)象擦耀,為了我們能操控渲染管道,蘋果提供了這個(gè)對(duì)象涩堤。它可以關(guān)聯(lián)自定義著色器等操作眷蜓。

- (void)createRenderPipelineState {
    NSError *error;
    id<MTLLibrary> library = [self.device newDefaultLibrary];
    if (error) {
        NSLog(@"error:%@",error);
    }
    // 創(chuàng)建頂點(diǎn)著色器
    id<MTLFunction> vertextFunction = [library newFunctionWithName:@"vertextShader"];
    // 創(chuàng)建片段著色器
    id<MTLFunction> fragmentFunction = [library newFunctionWithName:@"fragmentShader"];

    MTLRenderPipelineDescriptor *renderPipelineDescritior = [[MTLRenderPipelineDescriptor alloc] init];
    renderPipelineDescritior.colorAttachments[0].pixelFormat = self.mtkView.colorPixelFormat;
    renderPipelineDescritior.vertexFunction = vertextFunction;
    renderPipelineDescritior.fragmentFunction = fragmentFunction;

    // 創(chuàng)建渲染管道 id<MTLRenderPipelineState>
    id<MTLRenderPipelineState> renderPipelineState = [self.device newRenderPipelineStateWithDescriptor:renderPipelineDescritior error:nil];
    _renderPipelineState = renderPipelineState;
}

3.初始化頂點(diǎn)緩存

在前面的準(zhǔn)備工作都做好之前,我們需要設(shè)置一些頂點(diǎn)數(shù)據(jù)來告訴MTKView胎围,我們需要繪制的內(nèi)容的頂點(diǎn)數(shù)據(jù)吁系。

- (void)createVertextBuffer {
    // 頂點(diǎn)數(shù)據(jù) (頂點(diǎn)坐標(biāo) + 頂點(diǎn)顏色)
    BBVertex vertext[] = {
        { {-1, -0.5, 0, 1}, {1, 0, 0, 1} },
        { {0, 0.5, 0, 1}, {0, 1, 0, 1} },
        { {1, -0.5, 0, 1}, {0, 0, 1, 1} },
    };

    // 頂點(diǎn)數(shù)目
    _vertextCount = sizeof(vertext) / sizeof(BBVertex);

    // 構(gòu)建頂點(diǎn)緩存,這里options需要設(shè)置MTLResourceStorageModeShared,方便頂點(diǎn)數(shù)據(jù)在CPU與GPU之間快速存取
    id<MTLBuffer> vertextBuffer = [self.device newBufferWithBytes:vertext length:sizeof(vertext) options:MTLResourceStorageModeShared];

    _vertextBuffer = vertextBuffer;
}

4.渲染方法

在開始渲染之前白魂,我們必須實(shí)現(xiàn)MTKView的兩個(gè)代理方法:

/**
MTKView視口大小發(fā)生變化時(shí)候回調(diào)
*/
- (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size {
    self.viewportSize = (vector_uint2){size.width, size.height};
}

/*!
這個(gè)方法執(zhí)行的頻率和MTKView默認(rèn)刷新頻率一致汽纤,默認(rèn)60幀。
可以通過設(shè)置MTKView的屬性preferredFramesPerSecond來調(diào)整回調(diào)頻率
*/
- (void)drawInMTKView:(nonnull MTKView *)view {
    id<MTLCommandBuffer> commandBuffer = [_commandQueue commandBuffer];
    commandBuffer.label = @"commandBuffer";
    // 獲取渲染描述對(duì)象福荸,可以理解為拿到真正的渲染對(duì)象
    MTLRenderPassDescriptor *renderPassPipeline = view.currentRenderPassDescriptor;
    if (commandBuffer && renderPassPipeline) {
        // 設(shè)置背景色
        renderPassPipeline.colorAttachments[0].clearColor = MTLClearColorMake(1, 1, 1, 1);
        // 1.創(chuàng)建渲染編碼器
        id<MTLRenderCommandEncoder> renderCommandEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassPipeline];
        // 2.設(shè)置視口大小
        [renderCommandEncoder setViewport:(MTLViewport){0,0, self.viewportSize.x, self.viewportSize.y,-1,1}];
        // 3.設(shè)置渲染管道狀態(tài)
        [renderCommandEncoder setRenderPipelineState:self.renderPipelineState];
        // 4.設(shè)置頂點(diǎn)緩存區(qū)
        [renderCommandEncoder setVertexBuffer:self.vertextBuffer offset:0 atIndex:BBVertexInputIndexVertexes];
        // 5.設(shè)置圖元連接方式
        [renderCommandEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:self.vertextCount];
        // 6.結(jié)束命令編碼
        [renderCommandEncoder endEncoding];
        // 7.開始繪制
        [commandBuffer presentDrawable:view.currentDrawable];
    }
    // 提交命令緩存
    [commandBuffer commit];
}

5.渲染結(jié)果

三角形.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蕴坪,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子敬锐,更是在濱河造成了極大的恐慌背传,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件台夺,死亡現(xiàn)場(chǎng)離奇詭異径玖,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)颤介,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門梳星,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人买窟,你說我怎么就攤上這事丰泊。” “怎么了始绍?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵瞳购,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我亏推,道長(zhǎng)学赛,這世上最難降的妖魔是什么年堆? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮盏浇,結(jié)果婚禮上变丧,老公的妹妹穿的比我還像新娘。我一直安慰自己绢掰,他們只是感情好痒蓬,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著滴劲,像睡著了一般攻晒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上班挖,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天鲁捏,我揣著相機(jī)與錄音,去河邊找鬼萧芙。 笑死给梅,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的双揪。 我是一名探鬼主播动羽,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼渔期!你這毒婦竟也來了曹质?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤擎场,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后几莽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體迅办,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年章蚣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了站欺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡纤垂,死狀恐怖矾策,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情峭沦,我是刑警寧澤贾虽,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站吼鱼,受9級(jí)特大地震影響蓬豁,放射性物質(zhì)發(fā)生泄漏绰咽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一地粪、第九天 我趴在偏房一處隱蔽的房頂上張望取募。 院中可真熱鬧,春花似錦蟆技、人聲如沸玩敏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)旺聚。三九已至,卻和暖如春几苍,著一層夾襖步出監(jiān)牢的瞬間翻屈,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工妻坝, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留伸眶,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓刽宪,卻偏偏與公主長(zhǎng)得像厘贼,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子圣拄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354