Swift2.0 Metal 시작

17646 단어 SwiftMetal
새 그래픽 API "Metal"의 시작 내용입니다.
X코드로 메탈을 테스트할 때는 게임 항목에서 시작할 수 있었지만, 갑자기 많은 양의 코드가 보이자 슬그머니 파일을 닫으려고 했다.
이번에는 Single View Application을 시작으로 순서대로 메탈이 설정되어 사용됩니다.
이 지침은 참고Learning iOS 8 Game Development Using Swift로 해설을 진행한다.
이 책은 게임 개발뿐만 아니라 iOS의 그래픽 처리 방법을 소개한 좋은 책도 추천합니다!

사이트 축소판 그림


시작하기 전에도 다음 페이지를 추천합니다.

  • DSAS 개발자의 방
    상세한 해설이 있다.모르는 용어는 이 안에서 검색하면서 진행하는 것이 좋다.

  • iOS의 새 그래픽 API-Mamtal을 시작하십시오.
    이것도 추천합니다.
  • 대략적인 해설인 만큼 관심이 있다면 세부사항을 조사해보면 이해가 더 잘 된다.

    설치 시 고려 사항


    각 장치에 메탈을 설치해야 합니다.Mac의 종이 파쇄기가 움직이지 않는다.
    (최신 OS 10.11에서는 확인되지 않음)

    새 프로젝트 작성


    우선 새로운 프로젝트를 만든다.Single View Application 을 선택하십시오.

    라이브러리 설정


    Builde Phases를 통해 Metal의 일련의 라이브러리를 설정합니다.

    QuartzCore는 CAMetalLayer를 사용하기 위해 설정됩니다.
    (CoreAnimation 시스템에는 QuartzCore 프레임이 필요합니다.)

    미리 준비하다


    그래픽 라이브러리 시스템은 OpenGL로 다양한 사전 준비가 필요합니다.
    나는 가능한 한 필요한 최소한의 설정으로 진행하고 싶다.
    먼저 프로그램 라이브러리의 읽기 설정을 진행합니다.
    import UIKit
    import Metal
    import QuartzCore
    
    다음은 메탈 코드입니다.
    이번 인코딩은 모두 ViewController의viewDidLoad () 방법에 기술되어 있습니다.
    먼저 ViewController를 엽니다.
    메탈을 사용할 때는 필요한 코드를 준비해야 합니다.
    MTLDevice
    MT L CreateSystem DefaultDevice()를 통해 장치를 가져옵니다.디바이스에 직접 액세스할 수 있습니다.
    let device: MTLDevice? = MTLCreateSystemDefaultDevice()
    
    MTLCommandQueue
    GPU에 렌더링 명령을 전달하는 대기열입니다.대기열이 유지되는 명령을 순서대로 처리하고 렌더링을 계속합니다.
    let commandQueue: MTLCommandQueue!  = device.newCommandQueue()
    

    리소스 준비


    다음은 자원을 준비합니다.드로잉 계통의 리소스라면 교점 좌표 목록이나 텍스쳐입니다.
    교점 좌표를 준비합니다.이번에는 2D의 삼각형을 그렸다.
    let vertexArray: [Float] = [
        0.0, 0.1,
        -0.1, -0.1,
        0.1, -0.1
    ]
    
    VertexArray는 ViewController 클래스의 외부에 정의됩니다.
    화면에서 정점 좌표를 기반으로 도면을 그립니다.

    정점 버퍼 만들기


    정점 좌표가 준비되었으므로 그래픽 라이브러리에서 작업하려면 Vertex Buffer에 저장합니다.
    Metal은 MTLBUffer입니다.상단 포인트와 상단 유형 (이번에는 Flat) 부터 저장할 메모리를 준비합니다.
    이 점은 일단 이런 규칙이라는 것을 깨닫게 되면 문제없다.
    var vertexBuffer: MTLBuffer! = device.newBufferWithBytes( vertexArray,
        length: vertexArray.count * sizeofValue(vertexArray[0]),
        options: MTLResourceOptions.OptionCPUCacheModeDefault
    )
    

    Shader 만들기


    Shader는 정점의 변환과 픽셀의 착색 등 도형과 관련된 계산 처리를 한데 모아 만든 것이다.
    물론 Shader 없이도 그래픽 처리가 가능합니다.사용하지 않을 경우 CPU로 계산하게 하지만 픽셀 처리 등으로 엄청난 계산량이 발생하기 때문에 곧 성능 문제가 발생할 수 있다.
    (화면 크기가 100x100인 경우 픽셀 처리는 10000)
    그래서 Shader는 GPU를 이용하여 계산을 한다.이것은 매우 빠르다.쉐더를 쓰는 이유는 여기야.
    면도기는 두 종류가 있다.Vertex shader 및 Fragment shader
    여기서 아래의 이해에 따라 진행한다.아무튼 이런 건 괜찮아.
  • Vertex shader: 정점의 이동, 회전의 변환 처리
  • Fragment shader: 픽셀별 처리(1px로 처리)
  • 나는 곧 Shader를 만들 것이다.
    일반적으로 Shader의 파일은 두 가지(Vertex와 Fragment)가 있는데 메탈은 하나의 파일로 통합할 수 있다.물론 두 개의 서류로 나눌 수 있다.이번에는 하나의 문건으로 총결하였다.Shader.메탈 만들기.
    
    // スタンダードライブラリを読み込む
    #include <metal_stdlib>
    
    // 識別子metalを省略できる設定
    using namespace metal;  
    
    // VertexShader
    // 頂点の計算処理 入力の座標に対して特に何もしません。
    vertex float4 myVertexShader(const device float2 * vertex_array [[ buffer(0) ]], uint vid [[ vertex_id ]]) {
        return float4(vertex_array[vid],0,1);
    }
    
    // Fragment Shader
    // 各ピクセルの処理 黒でぬりつぶします。別名Pixel Shaderとも呼ばれます。
    fragment float4 myFragmentShader() {
        return float4(0.0, 0.0, 0.0, 1.0); // 図形ないの各ピクセルの色を指定します。
    }
    
    Shader.metal은 C++11의 기술인 것 같습니다.
    두 개의 함수가 있는데, 그것들은 Shader 처리이다.
    두 함수의 첫머리에는 어떤 Shader를 표시하는 식별자'vertex'와'fragment'가 있다.
    함수의 설명 방법은
    (Shader 식별자)(반환값) 함수 이름(매개변수)
    //처리 내용
    }
    의 형식.
    이번 Shader의 처리 내용은 자세히 설명하지 않습니다.
    Shader에는 몇 가지 특별한 유형이 있습니다.
  • float, float2, flaot3, float4
  • int, int2, int3, int4
  • vert1, vert2...
  • vert는 변수입니다.
    나는 flat4가 4개의 flat값 요소를 가진 구조값이라면 문제없다고 생각한다.
    예를 들어 x, y,z,w(4원수), r,g,b,a(색깔) 등이다.
    나는 이 근처에서 처음 보는 것이 어려울 것 같아서 먼저 다음 곳으로 이동했다.
    이 Shader 파일은 컴파일할 때 Shader Library에 추가됩니다.이로써 Shader의 재컴파일을 방지하고 효율화를 실현한다.device를 통해 Shader Library에 액세스할 수 있습니다.
    let defaultLibrary = device.newDefaultLibrary()
    let newVertexFunction = defaultLibrary!.newFunctionWithName("myVertexShader")
    let newFragmentFunction = defaultLibrary?.newFunctionWithName("myFragmentShader")
    
    Shader 함수 이름을 가져왔습니다. 나중에 사용하십시오.
    그런 다음 도면 파이프라인을 생성합니다.piperline descriptor를 만듭니다.이것은 File 설명자와 동일합니다.
    이것을 통해 그리기 처리를 합니다.
    let pipelineStateDescriptor = MTLRenderPipelineDescriptor()
    
    // 頂点処理を設定
    pipelineStateDescriptor.vertexFunction      = newVertexFunction
    
    // ピクセル処理を設定
    pipelineStateDescriptor.fragmentFunction    = newFragmentFunction
    
    // 色成分の順序を設定
    pipelineStateDescriptor.colorAttachments[0].pixelFormat = .BGRA8Unorm 
    
    // RenderPipelineの状態を取得
    var pipelineState: MTLRenderPipelineState!
    do {
       pipelineState = try device.newRenderPipelineStateWithDescriptor(pipelineStateDescriptor)
    } catch {
       print("error with device.newRenderPipelineStateWithDescriptor")
    }
    
    메탈의 Pixel Format에 대해 자세히 알고 싶으신 분들은 확인하세요여기..

    CAMetalLayer 만들기


    드로잉 결과를 내보내기 위해 View에 CAMetal Layer를 추가합니다.
    오류가 발생하면 디바이스에서 Metal을 사용할 수 없습니다.
    (애플 A7칩은 이후 사용할 수 있다.)
    let metalLayer = CAMetalLayer()
    metalLayer.device = device
    metalLayer.pixelFormat = .BGRA8Unorm   // pipeline descriptorに設定したものと同じものを設定する。
    metalLayer.frame = view.layer.frame     // フレームサイズを設定
    view.layer.addSublayer(metalLayer)
    
    이제 그릴 준비가 됐습니다.

    드로잉 처리


    여기서부터 그림 그리기 시작합니다.
    먼저 CAMetalLayer에서 도면 영역에 대한 참조를 가져옵니다.
    let drawable = metalLayer.nextDrawable()
    
    그런 다음 Render Descriptor를 만듭니다.
    let renderPassDescriptor = MTLRenderPassDescriptor()
    
    그릴 텍스쳐를 설정합니다.
    renderPassDescriptor.colorAttachments[0].texture = drawable?.texture
    
    프레임이 로드될 때의 처리를 설정합니다.
    renderPassDescriptor.colorAttachments[0].loadAction = .Clear // 毎フレームクリアされる
    
    투명 색상을 설정하고 layer를 채운 다음 그 위에 그립니다.
    renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColor(
                red: 1.0,
                green: 1.0,
                blue: 1.0,
                alpha: 1.0
    )
    
    그리고 레이어에 삼각형을 그립니다.
    commandQue에서 commandBuffer를 가져옵니다.
    let commandBuffer = commandQueue.commandBuffer()
    
    모든command는 기계 언어로 변환되어야 합니다.
    이것은 MTLRenderCommandEnceoder를 사용합니다.
    let renderEncoder: MTLRenderCommandEncoder = commandBuffer.renderCommandEncoderWithDescriptor(renderPassDescriptor
    
    렌더기를 설정하고 정점 Buffer를 설정합니다.
    renderEncoder.setRenderPipelineState(pipelineState)
    renderEncoder.setVertexBuffer(vertexBuffer, offset: 0, atIndex: 0)     
    
    이렇게 하면 삼각형을 그릴 수 있다.너무 길어...
    renderEncoder.drawPrimitives(.Triangle, vertexStart: 0, vertexCount: 3, instanceCount: 1); // 描画
    
    렌더링을 종료합니다.
    renderEncoder.endEncoding()
    
    화면에 아직 표시되지 않았기 때문에 표시 방법을 실행합니다.
    commiit()에 텍스쳐를 반영합니다.
    commandBuffer.presentDrawable(drawable!)
    commandBuffer.commit()
    
    이렇게 하면 완성된다.이번에 만든 코드는 이쪽에서도 확인할 수 있어요.
    마지막으로 조금 더 속도를 내며 OpenGL보다 메탈이 입문하기 쉽다.
    정보 자체는 네트워크에 충분한 정보가 거의 없고 코드 자체는 대부분 Objective-c이다.
    앞으로 생각해보면 스위프트에서 공부하는 걸 추천합니다.
    OpenGL을 시험해 보면 도형 라이브러리가 어떤 것인지 더 잘 이해할 수 있다.
    도형 라이브러리는 결코 게임에만 있는 것이 아니기 때문에 많은 개발자들이 시도할 것을 기대하고 있다.
    이 글의 후속추가 캘린더도 계속된다.

    좋은 웹페이지 즐겨찾기