iOS 8: Komme i gang med Metal

iOS 8: Komme i gang med Metal
22
Del
15
Del
Dette Cyber ​​mandag Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av.

Denne veiledningen vil vise deg hvordan du kommer i gang med Metal, et rammeverk introdusert i iOS 8 som støtter GPU akselerert 3D-grafikk rendering og data parallelle beregningsarbeidsbelastninger. I denne opplæringen, vil vi ta en titt på de teoretiske begreper som underly Metal. Du vil også lære hvordan du lager en Metal program som setter den nødvendige maskinvaren staten for grafikk, begår kommandoer for henrettelse i GPU, og forvalter buffer, tekstur objekter, og pre-kompilert shadere.

1. First things first

Denne opplæringen forutsetter at du er kjent med Objective-C-språk og har litt erfaring med OpenGL, OpenCL, eller en tilsvarende grafikk API.

Det krever også en fysisk enhet med en Apple A7 eller A8-prosessor. Dette betyr at du trenger en iPhone 5S, 6, eller 6 Plus, eller en iPad Air eller mini (andre generasjon). IOS Simulator vil gi deg kompilering feil.

Denne opplæringen er kun fokusert på Metal, og det vil ikke dekke Shading Metal Language. Vi vil skape en shader, men vi vil bare dekke de grunnleggende operasjoner for å samhandle med det.

Hvis du bruker Xcode for første gang, så sørg for at du legger til din Apple-ID i Kontoer
delen av Xcode er Preferences
. Dette vil sikre at du ikke får problemer når deployere en applikasjon på enheten.

Xcode 6 inneholder et prosjekt mal for Metal, men for å hjelpe deg å bedre forstå Metal, har vi tenkt å lage et prosjekt fra scratch.

På et endelig notat, vil vi bruke Objective-C i denne opplæringen, og det er viktig at du har en grunnleggende forståelse av dette programmeringsspråk.

2. Innledning

For de av dere som er kjent med OpenGL eller OpenGL ES, er Metal et lavnivå 3D-grafikk rammeverk, men med lavere overhead. I motsetning til Apples Sprite Kit eller Scene Kit rammeverk som du, som standard, kan ikke kommunisere med gjengivelsen rørledningen, med Metal du ha absolutt makt til å skape, kontrollere og endre denne rørledningen.

har Metal følgende funksjoner:.

Rammeverket gir ekstremt lav overhead tilgang til A7 og A8 GPU, slik utrolig høy ytelse for avanserte grafikkgjengivelse og beregningsoppgaver

Metal eliminerer mange flaskehalser, slik som kost tilstand validering som er funnet i tradisjonelle grafikk-APIer.

Det er eksplisitt utformet for å flytte alle dyre statlige oversettings og kompilering operasjoner ut av runtime og gjengivelse miljø.

Det gir ferdigbygd shaders , statlige objekter, og eksplisitt kommando planlegging for å sikre din søknad oppnår høyest mulig ytelse og effektivitet for grafikkgjengivelse og beregningsoppgaver.

Rammen er designet for å utnytte moderne arkitektoniske hensyn, for eksempel multiprosessering og delt minne.

Det er dypt integrert med iOS 8, A7 og A8-brikkesett, og Apple-maskinvare, og skaper en enhetlig og uavhengig rammeverk.

Nok med teorien, er det på tide å forstå hvordan en Metal program er bygget.

3. Opprette et Metal Application

En Metal program er preget av et sett av nødvendige skritt til riktig presentere data på skjermen. Disse trinnene er som regel laget i rekkefølge og noen referanser er gått fra en til en annen. Disse trinnene er:

får enheten

opprette et kommandokøen

skape ressurser som buffere, teksturer og shaders

opprette en gjengivelse rørledning

opprette en visning

Trinn 1: Få Device

involverer Dette trinnet etableringen av en MTLDevice objekt, hjertet av et metall søknad. Den MTLDevice klassen gir en direkte måte å kommunisere med GPU driver og maskinvare. For å få en henvisning til en MTLDevice eksempel, må du ringe System Standard Device
som vist nedenfor. Med denne referansen, har du direkte tilgang til enhetens maskinvare
id. ≪ MTLDevice > mtlDevice = MTLCreateSystemDefaultDevice ();
Trinn 2: Lag en Command Queue

MTLCommandQueue klassen gir en måte å sende kommandoer eller instruksjoner til GPU. Å initial en forekomst av MTLCommandQueue klassen, må du bruke MTLDevice objektet vi opprettet tidligere, og kaller newCommandQueue metoden på det
id. ≪ MTLCommandQueue > mtlCommandQueue = [mtlDevice newCommandQueue];
Trinn 3: Lag Resources

involverer Dette trinnet etablering av buffer gjenstander, teksturer og andre ressurser. I denne opplæringen, vil du opprette ekser. Disse objektene er lagret på server /GPU side og for å kunne kommunisere med dem du trenger for å lage en bestemt datastruktur som skal inneholde tilsvarende data til de som er tilgjengelige i toppunktet objektet.

For eksempel, hvis du trenger for å overføre data til en 2D toppunkt stilling, bør du deklarerer en datastruktur som inneholder et objekt for at 2D posisjon. Deretter må du deklarere det i både klient, iOS program, og server side, Metal shader. Ta en titt på følgende eksempel for avklaring
typedef struct {GLKVector2 posisjon;}. YourDataStruct;

Vær oppmerksom på at du må importere GLKMath
biblioteket fra GLKit
rammeverk som vist nedenfor
#import. < GLKit /GLKMath.h >.

Du kan deretter erklære et objekt med riktige koordinater
YourDataStruct trekant [3] = {{-.5f, 0.0f } {0.5f, 0.0f} {0.0f, 0.5f}};
Trinn 4: Lag en gjengivelse Pipeline

Opprette gjengivelsen rørledningen er trolig det vanskeligste trinnet , siden du må ta vare på flere initializations og konfigurasjoner, som hver er illustrert i følgende diagram

Gjengivelsen rørledningen er konfigurert med to klasser:.

MTLRenderPipelineDescriptor: gir alle av renderørlednings stater, som toppunktet stillinger, farge, dybde og sjablong buffere, blant andre

MTLRenderPipelineState: den kompilerte versjonen av MTLRenderPipelineDescriptor og som vil bli distribuert til enheten

Legg merke til at du ikke trenger å opprette alle renderørlednings stedene. Du bør bare lage de som dekker dine behov

Følgende kodebiten viser deg hvordan du oppretter MTLRenderPipelineDescriptor objektet
MTLRenderPipelineDescriptor * mtlRenderPipelineDescriptor = [MTLRenderPipelineDescriptor ny];..

På dette punktet, du har opprettet deskriptoren, men du fortsatt trenger å konfigurere den med minst pixel format. Dette er hva vi gjør i følgende kode blokken
mtlRenderPipelineDescriptor.colorAttachments [0] .pixelFormat = MTLPixelFormatBGRA8Unorm;.

For mer avanserte applikasjoner, må du også angi standard vertex og fragment shaders som vist nedenfor id < MTLLibrary > lib = [mtlDevice newDefaultLibrary]; mtlRenderPipelineDescriptor.vertexFunction = [lib newFunctionWithName: @ "SomeVertexMethodName"]; mtlRenderPipelineDescriptor.fragmentFunction = [lib newFunctionWithName: @ "SomeFragmentMethodName"];

newFunctionWithName metoden søker din Metal kildefilen, på jakt etter den SomeVertexMethodName metoden. Navnet på shader seg selv er ikke viktig siden oppslaget gjøres direkte gjennom metodenavn. Dette betyr at du bør definere unike metoder for unike shader operasjoner. Vi skal se dypere inn i metall shaders senere.

Med MTLRenderPipelineDescriptor objektet opprettet og konfigurert, er neste skritt å opprette og definere MTLRenderPipelineState ved å passere i den nyopprettede MTLRenderPipelineDescriptor objekt
NSError * error = [[NSError Alloc] init];. id < MTLRenderPipelineState > mtlRenderPipelineState = [mtlDevice newRenderPipelineStateWithDescriptor: mtlRenderPipelineDescriptor error: & error];
Trinn 5: Opprett en Vis

For å opprette en Metal-visning, må du underklasse UIView og overstyre layerClass metode som vist nedenfor
+ (id) layerClass {return [CAMetalLayer klasse];}.

I denne opplæringen, vil vi se på en annen måte å skape en CAMetalLayer klasse som gir utbygger mer kontroll over lags egenskaper og konfigurasjon.

4. Tegne en Metal App

Nå som vi har initialisert de nødvendige gjenstander, må vi begynne å tegne noe på skjermen. Akkurat som initialisering, må du følge en rekke tiltak:

få kommandobufferet

sette en render pass

uavgjort
forplikte seg til kommandobufferet

Trinn 1: Få Command Buffer

Det første trinnet er å opprette et objekt som lagrer en serie liste over kommandoer for enheten til å utføre. Du oppretter en MTLCommandBuffer objekt og legge kommandoer som skal kjøres sekvensielt av GPU. Følgende kodebit viser hvordan du oppretter en kommando buffer. Vi bruker MTLCommandQueue objektet vi opprettet tidligere
id. ≪ MTLCommandBuffer > mtlCommandBuffer = [mtlCommandQueue commandBuffer];
Trinn 2: Start en Render Pass

I Metal, er gjengivelsen konfigurasjon kompleks og du må eksplisitt når gjengi pass begynner og når det ender. Du må angi framebuffer- konfigurasjoner opp foran for at iOS å konfigurere maskinvaren skikkelig for den spesifikke konfigurasjonen.

For de som er kjent med OpenGL og OpenGL ES, er dette trinnet lignende siden den rammebuffer har de samme egenskapene, Color Vedlegg
(0 til 3), Dybde
, og Stencil
konfigurasjoner. Du kan se en visuell representasjon av dette trinnet i diagrammet nedenfor.

Du må først opprette en tekstur for å gjengjelde. Teksturen er opprettet fra CAMetalDrawable klasse og bruker nextDrawable metode for å hente neste tekstur til å trekke i listen
id. ≪ CAMetalDrawable > frameDrawable; frameDrawable = [renderLayer nextDrawable];

Dette nextDrawable samtale kan og vil være din søknad flaskehals siden det lett kan blokkere søknaden din. CPU og GPU kan desynchronized og man må vente på den andre, noe som kan føre til en blokk uttalelse. Det er synkrone mekanismer som kan, og bør alltid settes inn for å løse disse problemene, men jeg vil ikke dekke disse i denne innledende opplæringen.

Nå som du har en tekstur for å gjengjelde, må du opprette et MTLRenderPassDescriptor objekt å lagre rammebuffer og tekstur informasjon. Ta en titt på følgende kodebiten for å se hvordan dette fungerer
MTLRenderPassDescriptor * mtlRenderPassDescriptor;. MtlRenderPassDescriptor = [MTLRenderPassDescriptor nye]; mtlRenderPassDescriptor.colorAttachments [0] .texture = frameDrawable.texture; mtlRenderPassDescriptor.colorAttachments [0] .loadAction = MTLLoadActionClear; mtlRenderPassDescriptor.colorAttachments [0] .clearColor = MTLClearColorMake (0,75, 0,25, 1,0, 1,0);

Det første trinnet setter opp teksturen å tegne. Den andre definerer en bestemt handling for å ta, i dette tilfellet å avskjære tekstur og hindre innholdet i teksturen som blir lastet inn i GPU hurtigbufferen. Det siste trinnet endrer bakgrunnsfargen til en bestemt farge

Trinn 3:. Tegn

Med rammebuffer og tekstur konfigurert, er det på tide å lage en MTLRenderCommandEncoder eksempel. Den MTLRenderCommandEncoder klasse er ansvarlig for de tradisjonelle interaksjoner med skjermen, og kan sees som en beholder for en grafikkgjengivelse tilstand. Det betyr også koden din inn i en hardware-spesifikk kommando format som vil bli utført av enheten
id. ≪ MTLRenderCommandEncoder > renderCommand = [mtlCommandBuffer renderCommandEncoderWithDescriptor: mtlRenderPassDescriptor]; //Set MTLRenderPipelineState //Tegn objektene her [renderCommand endEncoding];
Trinn 4: forplikte seg til kommandobufferet

Vi har nå en buffer og instruksjoner som venter i minnet. Det neste trinnet er å begå kommandoene til kommandobufferet og se grafikken trukket inn på skjermen. Merk at GPU vil bare kjøre kode som du spesifikt begå for effekten. Følgende linjer med kode la deg planlegge din rammebuffer og forplikte kommandobufferet til GPU
[mtlCommandBuffer presentDrawable: frameDrawable];. [MtlCommandBuffer begå];

På dette punktet, bør du ha en viss innsikt i hvordan en Metal søknad er strukturert. Men du skal forstå alt dette, må du gjøre det selv. Det er nå på tide å kode første Metal søknaden.

5. Opprette et Metal Application

Start-Xcode 6 og velg Nytt > Prosjekt ...
fra Fil
menyen. Velg Enkel visning Application
fra listen over maler og velge et produktnavn. Sette Objective-C
som språk og velg iPhone
fra Enheter
menyen.

Åpne ViewController.m Hotell og legge disse import uttalelser på toppen
#import. < Metal /Metal.h > #import < QuartzCore /CAMetalLayer.h >

Du må også legge til Metal Hotell og < b> QuartzCore
rammer i de Koblede Rammer og biblioteker
delen av målets Bygg Phases
. Fra nå av bør oppmerksomheten være rettet mot gjennomføringen fil av ViewController klassen.

6. Opprette Metal Structure

Som jeg nevnte tidligere, er din første oppgave å sette og initialkjerne objekter som brukes på tvers av hele programmet. I det følgende kodebiten, vi erklære en rekke instansvariabler. Disse bør se kjent ut hvis du har lest den første delen av denne opplæringen
implementation ViewController {id. ≪ MTLDevice > mtlDevice; id < MTLCommandQueue > mtlCommandQueue; MTLRenderPassDescriptor * mtlRenderPassDescriptor; CAMetalLayer * metalLayer; id < CAMetalDrawable > frameDrawable; CADisplayLink * Display;}

I visningen kontrolleren viewDidLoad metode, initial vi MTLDevice og CommandQueue tilfeller
mtlDevice = MTLCreateSystemDefaultDevice ();. MtlCommandQueue = [mtlDevice newCommandQueue];

Du kan nå kommunisere med enheten og opprette kommando køer. Det er nå på tide å konfigurere CAMetalLayer objektet. Din CAMetalLayer lag bør ha en bestemt konfigurasjon avhengig av enheten, pixel format, og rammestørrelse. Du bør også angi at det skal bruke bare rammebuffer og at det bør legges til det aktive laget.

Hvis du har et problem konfigurere CAMetalLayer objekt, deretter inn følgende kode vil hjelpe deg med dette
metalLayer = [CAMetalLayer lag] [metalLayer setDevice: mtlDevice];. [metalLayer setPixelFormat: MTLPixelFormatBGRA8Unorm]; metalLayer.framebufferOnly = YES [metalLayer setFrame: self.view.layer.frame] [selvtillit. view.layer addSublayer: metalLayer];

Du bør også sette visningen tetthet, bakgrunnsfarge, og innholdet skaleringsfaktor. Dette er illustrert i neste kodebiten product: [self.view setOpaque: YES] [self.view setBackgroundColor: null];. [Self.view setContentScaleFactor: [UIScreen mainScreen] .scale];

Det eneste trinnet venstre er å gjøre noe til skjermen. Initialisere CADisplayLink, passerer selv som målet ogselector (renderScene) som velgeren. Til slutt legger CADisplayLink objektet til dagens løp sløyfe
Display = [CADisplayLink displayLinkWithTarget bolig: Velger:selector (renderScene)] [Display addToRunLoop: [NSRunLoop currentRunLoop] forMode: NSDefaultRunLoopMode];.

Dette er hva det ferdige viewDidLoad metoden skal se ut Anmeldelser - (void) viewDidLoad {[super viewDidLoad].; mtlDevice = MTLCreateSystemDefaultDevice (); mtlCommandQueue = [mtlDevice newCommandQueue]; metalLayer = [CAMetalLayer lag]; [metalLayer setDevice: mtlDevice]; [metalLayer setPixelFormat: MTLPixelFormatBGRA8Unorm]; metalLayer.framebufferOnly = JA; [metalLayer setFrame: self.view.layer.frame]; [self.view.layer addSublayer: metalLayer]; [self.view setOpaque: YES]; [self.view setBackgroundColor: null]; [self.view setContentScaleFactor: [UIScreen mainScreen] .scale]; Display = [CADisplayLink displayLinkWithTarget bolig: Velger:selector (renderScene)]; [Display addToRunLoop: [NSRunLoop currentRunLoop] forMode: NSDefaultRunLoopMode];}

Hvis du bygger prosjektet, vil du legge merke til at Xcode gir oss en advarsel. Vi trenger fortsatt å implementere renderScene metoden.

renderScene metoden utføres hver ramme. Det er flere gjenstander som må klargjøres for hver ny ramme, slik som MTLCommandBuffer og MTLRenderCommandEncoder gjenstander

De tiltak vi må ta for å gjengi en ramme er:.
< li> opprette en MTLCommandBuffer objekt

initial en CAMetalDrawable objekt

initial en MTLRenderPassDescriptor objekt

konfigurere tekstur, loadAction, clearColor, og storeAction egenskaper av MTLRenderPassDescriptor objektet

opprette et nytt MTLRenderCommandEncoder objekt

presentere teikne og forplikte kommandobufferet

Ta gjerne se hva vi har sett så langt for å løse denne utfordringen på egen hånd. Hvis du ønsker å fortsette med denne opplæringen, så ta en titt på den løsningen som er vist nedenfor Anmeldelser - (void) renderScene {id. ≪ MTLCommandBuffer > mtlCommandBuffer = [mtlCommandQueue commandBuffer]; while (frameDrawable!) {frameDrawable = [metalLayer nextDrawable]; } If (! MtlRenderPassDescriptor) mtlRenderPassDescriptor = [MTLRenderPassDescriptor ny]; mtlRenderPassDescriptor.colorAttachments [0] .texture = frameDrawable.texture; mtlRenderPassDescriptor.colorAttachments [0] .loadAction = MTLLoadActionClear; mtlRenderPassDescriptor.colorAttachments [0] .clearColor = MTLClearColorMake (0,75, 0,25, 1,0, 1,0); mtlRenderPassDescriptor.colorAttachments [0] .storeAction = MTLStoreActionStore; id < MTLRenderCommandEncoder > renderCommand = [mtlCommandBuffer renderCommandEncoderWithDescriptor: mtlRenderPassDescriptor]; //Tegn objektene her //satt MTLRenderPipelineState .. [renderCommand endEncoding]; [mtlCommandBuffer presentDrawable: frameDrawable]; [mtlCommandBuffer begå]; mtlRenderPassDescriptor = null; frameDrawable = null;}

Vi trenger også å gjennomføre visningen kontrollerens dealloc metode der vi ugyldig Display objektet. Vi setter mtlDevice og mtlCommandQueue gjenstander til null Anmeldelser - (void) dealloc {[Displayugyldig].; mtlDevice = null; mtlCommandQueue = null;}
7. Tegne en trekant

Du har nå en helt grunnleggende Metal søknad. Det er på tide å legge til din første grafiske primitive, en trekant. Det første trinnet er å skape en struktur for trekanten
typedef struct {GLKVector2 posisjon;}. Triangle;

Ikke glem å legge en import regnskapet for GLKMath
bibliotek på toppen av ViewController.m
#import. < GLKit /GLKMath.h >

For å gjengi trekant, må du opprette en MTLRenderPipelineDescriptor objekt og en MTLRenderPipelineState objekt. I tillegg hvert objekt som er tegnet inn på skjermen tilhører MTLBuffer klassen
MTLRenderPipelineDescriptor * renderPipelineDescriptor;. Id < MTLRenderPipelineState > renderPipelineState; id < MTLBuffer > objekt;

Med disse instansvariabler erklært, bør du nå initial dem i viewDidLoad metode som jeg forklarte tidligere
renderPipelineDescriptor = [MTLRenderPipelineDescriptor nye];. renderPipelineDescriptor.colorAttachments [0] .pixelFormat = MTLPixelFormatBGRA8Unorm;

Å skygge trekanten, vil vi trenge Metal shaders. Metallet shaders skal tildeles den MTLRenderPipelineDescriptor objektet og innkapslet gjennom en MTLLibrary protokollen. Det høres kanskje komplisert, men trenger du bare å bruke følgende linjer med kode:
id < MTLLibrary > lib = [mtlDevice newDefaultLibrary]; renderPipelineDescriptor.vertexFunction = [lib newFunctionWithName: @ "VertexColor"]; renderPipelineDescriptor.fragmentFunction = [lib newFunctionWithName: @ "FragmentColor"]; renderPipelineState = [mtlDevice newRenderPipelineStateWithDescriptor: renderPipelineDescriptor error: null];

Den første linjen skaper et objekt som er i samsvar med den MTLLibrary protokollen. I den andre linjen, forteller vi biblioteket som metode må påberopes inne i shader å operere toppunktet pasning inne gjengivelsen rørledningen. I tredje linje, gjentar vi dette trinnet på pikselnivå fragmentene. Til slutt, i den siste linjen skaper vi en MTLRenderPipelineState objekt.

I Metal, kan du definere systemet koordinerer, men i denne opplæringen vil du bruke standard koordinatsystem, det vil si koordinatene til skjermens sentrum er (0,0).

I følgende kode blokken, skaper vi en trekant objekt med tre koordinater, (-.5f, 0.0f), (0.5f, 0.0f), (0.0f, 0.5f )
Triangle trekant [3] = {{-.5f, 0.0f} {0.5f, 0.0f} {0.0f, 0.5f}};.

Vi deretter legge på trekanten til < MTLBuffer > . objekt, noe som skaper en buffer for trekanten
objekt = [mtlDevice newBufferWithBytes: & trekant Lengde: sizeof (trekant [3]) alternativer: MTLResourceOptionCPUCacheModeDefault];

Dette er hva det ferdige viewDidLoad metoden skal se ut.
- (void) viewDidLoad {[super viewDidLoad]; mtlDevice = MTLCreateSystemDefaultDevice (); mtlCommandQueue = [mtlDevice newCommandQueue]; metalLayer = [CAMetalLayer lag]; [metalLayer setDevice: mtlDevice]; [metalLayer setPixelFormat: MTLPixelFormatBGRA8Unorm]; metalLayer.framebufferOnly = JA; [metalLayer setFrame: self.view.layer.frame]; [self.view.layer addSublayer: metalLayer]; [self.view setOpaque: YES]; [self.view setBackgroundColor: null]; [self.view setContentScaleFactor: [UIScreen mainScreen] .scale]; //Opprett en gjenbrukbar rørledning renderPipelineDescriptor = [MTLRenderPipelineDescriptor ny]; renderPipelineDescriptor.colorAttachments [0] .pixelFormat = MTLPixelFormatBGRA8Unorm; id < MTLLibrary > lib = [mtlDevice newDefaultLibrary]; renderPipelineDescriptor.vertexFunction = [lib newFunctionWithName: @ "VertexColor"]; renderPipelineDescriptor.fragmentFunction = [lib newFunctionWithName: @ "FragmentColor"]; renderPipelineState = [mtlDevice newRenderPipelineStateWithDescriptor: renderPipelineDescriptor error: null]; Trekant trekant [3] = {{-.5f, 0.0f} {0.5f, 0.0f} {0.0f, 0.5f}}; objekt = [mtlDevice newBufferWithBytes: & trekant Lengde: sizeof (Triangle [3]) alternativer: MTLResourceOptionCPUCacheModeDefault]; Display = [CADisplayLink displayLinkWithTarget bolig: Velger:selector (renderScene)]; [Display addToRunLoop: [NSRunLoop currentRunLoop] forMode: NSDefaultRunLoopMode];.}

viewDidLoad metoden er ferdig, men det er en siste trinnet mangler, skape shaders

8. Opprette Shaders

Hvis du vil lage en Metal shader, velg New > Fil ...
fra Fil
menyen velger du Source
>
Metal fil
fra iOS
delen, og gi den navnet MyShader
. Xcode vil deretter opprette en ny fil for deg, MyShader.metal
.

På toppen, bør du se følgende to linjer med kode. Den første omfatter den Metal Standard Bibliotek
mens den andre bruker metall navne
#include <. Metal_stdlib > bruker namespace metall;

Det første trinnet er å kopiere trekanten strukturen til shader. Shaders er vanligvis delt inn i to ulike operasjoner, toppunkt og pixel (fragmenter). Den første er knyttet til posisjonen til topp-punktet, mens den andre er relatert til den endelige fargen som toppunktet og alle posisjoner av bildeelementer innenfor polygonet. Du kan se på det på denne måten, det første vil rastrere polygon, pikslene i polygon, og den andre vil skyggen de samme piksler.

Siden de trenger for å kommunisere på en ensrettet måte, fra toppunktet til fragment , er det best å lage en struktur for dataene som vil bli vedtatt. I dette tilfellet har vi bare passerer posisjonen
typedef struct {float4 posisjon [[stilling]];}. TriangleOutput;

Nå, la oss lage toppunktet og fragment metoder. Husk at når du har programmert RenderPipelineDescriptor gjenstand for både toppunktet og fragment? Du brukte newFunctionWithName metoden, passerer i en NSString objekt. Strengen er navnet på den metoden som du kaller inne i shader. Dette betyr at du trenger å erklære to metoder med disse navnene, VertexColor og FragmentColor.

Hva betyr dette? Du kan lage dine shaders og navngi dem som du vil, men du må ringe metodene nøyaktig slik du erklære dem og de bør ha unike navn.

Inside dine shaders, legge til følgende kode blokken. Anmeldelser toppunktet TriangleOutput VertexColor (konst enhet Triangle * Hjørner [[buffer (0)]], konst uint indeksen [[vertex_id]]) {TriangleOutput ut; out.position = float4 (Toppunkter [index] .position, 0.0, 1.0); vende tilbake;} fragment half4 FragmentColor (void) {return half4 (1,0, 0,0, 0,0, 1,0);}

VertexColor metoden vil motta data som er lagret i posisjon 0 av buffer (minne som er tildelt) og vertex_id av toppunktet . Siden vi erklært en tre-toppunkt trekant, vil vertex_id være 0, 1 og 2. Det utganger en TriangleOutput objekt som automatisk mottatt av FragmentColor. Til slutt, det vil skygge hver piksel inne de tre hjørnene ved hjelp av en rød farge.

Det var det. Bygge og drive din søknad og nyte din første, helt nye 60fps Metal søknad.

9. Eksterne ressurser

Hvis du vil vite mer om Metal rammeverket og hvordan det fungerer, kan du sjekke ut flere andre ressurser:

WWDC 2014 (Arbeide med Metal seksjoner)

Metal Work Reference

Metal Programming Guide

Konklusjon

Dette avslutter vår innledende opplæringen på det nye Metal rammeverket. Hvis du har spørsmål eller kommentarer, må du gjerne slippe en linje i kommentarfeltet.