-
Add red triangleOpenGL/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