ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Add red triangle
    OpenGL/iOS_Metal 2018. 10. 13. 11:48

    안녕하세요 dely입니다:)

     

    저번 글에서 Metal로 노란색으로 배경 채우기에 이어 빨간색 삼각형을 추가해보겠습니다.

     

    (참고영상: Working with Triangles in Metal)

     

    오늘의 목표!!

     

     

    이번에는 빨간색 삼각형을 추가로 그려주기 위해 vertex개념과 shader를 이용해보려 합니다.

     

    1. 삼각형 vertex 추가 및 pipelineState와 vertexBuffer 프로퍼티 선언

     

    그려줄 삼각형 위치를 vertices 배열로 지정해줍니다.

     

    화면의 중점이 (0, 0)이고, 좌측하단이 (-1, -1), 우측상단이 (1, 1)입니다.

     

    여기서 눈에 보이는 것은 2d지만 사실상 3d 형태이기 때문에 x, y, z 축을 입력합니다.

     

    var vertices: [Float] = [

            0, 1, 0,

            -1, -1, 0,

            1, -1, 0

    ]

     

    파이프라인과 vertex를 담을 프로퍼티를 선언합니다.

     

    var pipelineState: MTLRenderPipelineState?

    var vertexBuffer: MTLBuffer?

     

     

    2. buildBuffer

     

    Renderer.swift에 buildModel() method를 만듭니다.

     

    여기서 vertices 배열을 담을 버퍼를 만들게 됩니다.

     

    bytes에 vertex 배열을, length에 배열 x Float크기를 지정하여 만들게 됩니다.

     

    private func buildModel() {

            vertexBuffer = device.makeBuffer(bytes: vertices, length: vertices.count * MemoryLayout<Float>.size, options: [])

    }

     

     

    3. Shader.metal

     

    Shader를 이용하여 색깔을 칠할 위치(vertex_shader)와 어떤 색을 칠할지(fragment_shader)를 정하게 됩니다.

     

    vertex float4 vertex_shader(const device packed_float3 *vertices [[buffer(0)]],

                                uint vertexId [[vertex_id]]) {

        return float4(vertices[vertixId], 1);

    }

     

    fragment half4 fragment_shader(){

        return half4(1, 0, 0, 1);

    }

     

     

    4. pipeline

     

    Renderer.swift에서 buildPipelineState() method를 만듭니다.

     

    여기서는 Shader.metal에서 만들어준 vertex_shader과 fragment_shader를 연결해줍니다.

     

        private func buildPipelineState(){

            let library = device.makeDefaultLibrary()

            let vertexFunction = library?.makeFunction(name: "vertex_shader")

            let fragmentFunction = library?.makeFunction(name: "fragment_shader")

            

            let pipelineDesciptor = MTLRenderPipelineDescriptor()

            pipelineDesciptor.vertexFunction = vertexFunction

            pipelineDesciptor.fragmentFunction = fragmentFunction

            pipelineDesciptor.colorAttachments[0].pixelFormat = .bgra8Unorm

            

            do {

                pipelineState = try device.makeRenderPipelineState(descriptor: pipelineDesciptor)

            } catch let error as NSError {

                print("error: \(error.localizedDescription)")

            }

        }

     

    5. draw()

     

    이제 위에서 만든 pipelineState를 가져와서 draw() method에서 인코딩합니다.

     

    (굵은 글씨로 지정한 코드 추가)

     

    func draw(in view: MTKView) {

    guard let drawable = view.currentDrawable,

     

    let pipelineState = pipelineState,

     

    let descriptor = view.currentRenderPassDescriptor else {

     

    return

     

       }

     

    let commandBuffer = commandQueue.makeCommandBuffer()

     

            

     

    let commandEncoder = commandBuffer?.makeRenderCommandEncoder(descriptor: descriptor)

     

            

     

    commandEncoder?.setRenderPipelineState(pipelineState)

     

    commandEncoder?.setVertexBuffer(vertexBuffer, offset: 0, index: 0)

     

    commandEncoder?.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: vertices.count)

     

    commandEncoder?.endEncoding()

     

    commandBuffer?.present(drawable)

     

    commandBuffer?.commit()

     

    }

     

    반응형

    'OpenGL > iOS_Metal' 카테고리의 다른 글

    Drawing Primitives  (0) 2019.07.03
    Hello Again, Metal  (0) 2019.07.01
    Refactoring Fill the Yellow texture  (0) 2018.10.12
    Fill the Yellow texture  (0) 2018.10.07
    Hello Metal  (0) 2018.10.06

    댓글

Designed by Tistory.