2022-01-12-Metal顯示圖片

創(chuàng)建MetalView

    self.mtkView.device = MTLCreateSystemDefaultDevice(); // 獲取默認(rèn)的device
    self.view = self.mtkView;
    self.mtkView.delegate = self;
    self.viewportSize = (vector_uint2){self.mtkView.drawableSize.width, self.mtkView.drawableSize.height}; 

創(chuàng)建pipeline

id<MTLLibrary> defaultLibrary = [self.mtkView.device newDefaultLibrary]; // .metal
    id<MTLFunction> vertexFunction = [defaultLibrary newFunctionWithName:@"vertexShader"]; // 頂點shader甘萧,vertexShader是函數(shù)名
    id<MTLFunction> fragmentFunction = [defaultLibrary newFunctionWithName:@"samplingShader"]; // 片元shader,samplingShader是函數(shù)名
    
    MTLRenderPipelineDescriptor *pipelineStateDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
    pipelineStateDescriptor.vertexFunction = vertexFunction;
    pipelineStateDescriptor.fragmentFunction = fragmentFunction;
    pipelineStateDescriptor.colorAttachments[0].pixelFormat = self.mtkView.colorPixelFormat;
    self.pipelineState = [self.mtkView.device newRenderPipelineStateWithDescriptor:pipelineStateDescriptor
                                                                         error:NULL]; // 創(chuàng)建圖形渲染管道,耗性能操作不宜頻繁調(diào)用
    self.commandQueue = [self.mtkView.device newCommandQueue]; // CommandQueue是渲染指令隊列躯护,保證渲染指令有序地提交到GPU

創(chuàng)建頂點矩陣

static const LYVertex quadVertices[] =
    {   // 頂點坐標(biāo),分別是x母市、y够坐、z、w檩帐;    紋理坐標(biāo)术幔,x、y湃密;
        { {  0.5, -0.5, 0.0, 1.0 },  { 1.f, 1.f } },
        { { -0.5, -0.5, 0.0, 1.0 },  { 0.f, 1.f } },
        { { -0.5,  0.5, 0.0, 1.0 },  { 0.f, 0.f } },
        
        { {  0.5, -0.5, 0.0, 1.0 },  { 1.f, 1.f } },
        { { -0.5,  0.5, 0.0, 1.0 },  { 0.f, 0.f } },
        { {  0.5,  0.5, 0.0, 1.0 },  { 1.f, 0.f } },
    };
    self.vertices = [self.mtkView.device newBufferWithBytes:quadVertices
                                                 length:sizeof(quadVertices)
                                                options:MTLResourceStorageModeShared]; // 創(chuàng)建頂點緩存
    self.numVertices = sizeof(quadVertices) / sizeof(LYVertex); // 頂點個數(shù)

創(chuàng)建紋理

- (void)setupTexture {
   UIImage *image = [UIImage imageNamed:@"abc"];
   // 紋理描述符
   MTLTextureDescriptor *textureDescriptor = [[MTLTextureDescriptor alloc] init];
   textureDescriptor.pixelFormat = MTLPixelFormatRGBA8Unorm;
   textureDescriptor.width = image.size.width;
   textureDescriptor.height = image.size.height;
   self.texture = [self.mtkView.device newTextureWithDescriptor:textureDescriptor]; // 創(chuàng)建紋理
   
   MTLRegion region = {{ 0, 0, 0 }, {image.size.width, image.size.height, 1}}; // 紋理上傳的范圍
   Byte *imageBytes = [self loadImage:image];
   if (imageBytes) { // UIImage的數(shù)據(jù)需要轉(zhuǎn)成二進制才能上傳诅挑,且不用jpg、png的NSData
       [self.texture replaceRegion:region
                   mipmapLevel:0
                     withBytes:imageBytes
                   bytesPerRow:4 * image.size.width];
       free(imageBytes); // 需要釋放資源
       imageBytes = NULL;
   }
}

- (Byte *)loadImage:(UIImage *)image {
   // 1獲取圖片的CGImageRef
   CGImageRef spriteImage = image.CGImage;
   
   // 2 讀取圖片的大小
   size_t width = CGImageGetWidth(spriteImage);
   size_t height = CGImageGetHeight(spriteImage);
   
   Byte * spriteData = (Byte *) calloc(width * height * 4, sizeof(Byte)); //rgba共4個byte
   
   CGContextRef spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width*4,
                                                      CGImageGetColorSpace(spriteImage), kCGImageAlphaPremultipliedLast);
   
   // 3在CGContextRef上繪圖
   CGContextDrawImage(spriteContext, CGRectMake(0, 0, width, height), spriteImage);
   
   CGContextRelease(spriteContext);
   
   return spriteData;
}

渲染

// 每次渲染都要單獨創(chuàng)建一個CommandBuffer
    id<MTLCommandBuffer> commandBuffer = [self.commandQueue commandBuffer];
    MTLRenderPassDescriptor *renderPassDescriptor = view.currentRenderPassDescriptor;
    // MTLRenderPassDescriptor描述一系列attachments的值泛源,類似GL的FrameBuffer拔妥;同時也用來創(chuàng)建MTLRenderCommandEncoder
    if(renderPassDescriptor != nil)
    {
        renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0.0, 0.5, 0.5, 1.0f); // 設(shè)置默認(rèn)顏色
        id<MTLRenderCommandEncoder> renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor]; //編碼繪制指令的Encoder
        [renderEncoder setViewport:(MTLViewport){0.0, 0.0, self.viewportSize.x, self.viewportSize.y, -1.0, 1.0 }]; // 設(shè)置顯示區(qū)域
        [renderEncoder setRenderPipelineState:self.pipelineState]; // 設(shè)置渲染管道,以保證頂點和片元兩個shader會被調(diào)用
        
        [renderEncoder setVertexBuffer:self.vertices
                                offset:0
                               atIndex:0]; // 設(shè)置頂點緩存

        [renderEncoder setFragmentTexture:self.texture
                                  atIndex:0]; // 設(shè)置紋理
        
        [renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle
                          vertexStart:0
                          vertexCount:self.numVertices]; // 繪制
        
        [renderEncoder endEncoding]; // 結(jié)束
        
        [commandBuffer presentDrawable:view.currentDrawable]; // 顯示
    }
    
    [commandBuffer commit]; // 提交俩由;

名詞解釋

  1. vertex:頂點函數(shù)
  2. fragment: 片元函數(shù)
  3. buffer: vertex參數(shù),小括號模具代表了encoder設(shè)置VertexBuffer的index毒嫡,
  4. texture: 輸入紋理,小括號枚舉代表了encoder設(shè)置的texture的index

疑問點

  1. sharder是怎么綁定的
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市兜畸,隨后出現(xiàn)的幾起案子努释,更是在濱河造成了極大的恐慌,老刑警劉巖咬摇,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伐蒂,死亡現(xiàn)場離奇詭異,居然都是意外死亡肛鹏,警方通過查閱死者的電腦和手機逸邦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來在扰,“玉大人缕减,你說我怎么就攤上這事∶⒅椋” “怎么了桥狡?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長皱卓。 經(jīng)常有香客問我裹芝,道長,這世上最難降的妖魔是什么娜汁? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任嫂易,我火速辦了婚禮,結(jié)果婚禮上掐禁,老公的妹妹穿的比我還像新娘怜械。我一直安慰自己,他們只是感情好穆桂,可當(dāng)我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布宫盔。 她就那樣靜靜地躺著,像睡著了一般享完。 火紅的嫁衣襯著肌膚如雪灼芭。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天般又,我揣著相機與錄音彼绷,去河邊找鬼。 笑死茴迁,一個胖子當(dāng)著我的面吹牛寄悯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播堕义,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼猜旬,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起洒擦,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤椿争,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后熟嫩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體秦踪,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年掸茅,在試婚紗的時候發(fā)現(xiàn)自己被綠了椅邓。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡昧狮,死狀恐怖景馁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情陵且,我是刑警寧澤裁僧,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站慕购,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏茬底。R本人自食惡果不足惜沪悲,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望阱表。 院中可真熱鬧殿如,春花似錦、人聲如沸最爬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽爱致。三九已至烤送,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間糠悯,已是汗流浹背帮坚。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留互艾,地道東北人试和。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像纫普,于是被迫代替她去往敵國和親阅悍。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容