티스토리 뷰

728x90
반응형

 

Using Metal to Draw a View’s Contents  정리

메탈로 graphics content를 렌더링 하는 법을 배울 것-!! 

<목차>


1. MTKView 준비 & 세팅

2. MTKViewDelegate 설정

3. MTLCommandQueue 준비

4. Render Pass Descriptor & Render Pass 만들기 

5. Drawable을 screen에 present하기 

6. Command Buffer를 commit 하기

 

[1] MTKView 준비 & 세팅

 

MetalKit 은 메탈 앱을 적은 코드로 더 빠르고 쉽게 만들 수 있게 해주는 프레임 워크이다.

우선 MetalKit을 import 해준다.

import MetalKit

 

draw를 위해 MTKView를 준비한다. 

MTKView는 NSView (in macOS) or UIView(in iOS and tvOS)의 서브클래스이다.

 

MTKView는 Metal device에 대한 reference를 필요로 한다. 

resource를 내부적으로 create하기 위해서...!! 

 

그래서 가장 먼저 해야할 것은

view의 device property 를 세팅해주는 것--! (device는  MTLDevice 타입이다)

 

그 다음, view의 enableSetNeedsDisplay를 true로 설정해줍니다. 

샘플에서 animated content를 그리지 않을 것이기 때문에,
이 설정을 통해 뷰가 contents의 업데이트가 필요할때만 (ex. shape가 변했을때)

draw를 하게 해줍니다. 

 

 

[2]  MTKViewDelegate 설정

 


두개의 메소드가 required 메소드 (필수) 입니다

 

1) mtkView(_:drawableSizeWillChange:) 

- cotents의 사이즈가 바뀌려고 할 때 불림.

ex) device orientation changes 

- size 파라미터는 뷰의 new drawable size. (drawable에 대한 설명은 아래에-!)



2) draw(in:) 
- view에 render를 요청할때 불림.
(This method is called on the delegate when it is asked to render into the view.)

- 이 메소드 안에서 command buffer를 만들고, command를 encode 하고, command buffer에 command 넣는 것 등을 할 것이다.

 

[3] MTLCommandQueue 준비

 

 

[4] Render Pass Descriptor & Render Pass 만들기 

 

< 개념 >

 

draw할때, GPU는 결과를 textures에 저장합니다.

textures는 image data를 가지고 있는 memory blocks 입니다.

GPU는 textures에 access 가능합니다. 

 

샘플에서 MTKView는 뷰에 그리는 데 필요한 모든 textures를 생성합니다. 

여러 텍스처를 만들어 렌더링하는 동안 한 텍스처의 내용을 표시할 수 있도록 합니다.

 

draw하기 위해서 render pass를 만들어야합니다.

render pass란 textures에 draw하기 위한 렌더링 명령들 (rendering commands)의 sequence입니다.

즉 textures들이 처음부터 끝까지 어떻게 process되어야하는지 나타내는 것입니다.

(참고로 render pass를 사용할때, textures는 render targets이라고 불리기도 합니다.)

 

기본적으로 render pass가 시작될때, texture가 view의 clearColor property에 해당하는 soild color로 지워지고

render pass가 끝날때, 모든 변경 사항이 texture에 다시 저장됩니다.

 

clearColor 설정해주겠습니다--!! 

mtkView.clearColor = MTLClearColorMake(0.0, 0.5, 0.5, 1.0)

 

< Render Pass Descriptor 만들기 >

 

render pass를 만들기 위해, 

render pass descriptor가 필요합니다. (MTLRenderPassDescriptor)

 

이 샘플에서는 직접 이것을 만들지 않고

mtkView한테 만들어달라고 합니다. 

let renderPassDescriptor = mtkView.currentRenderPassDescriptor

 

 

Render Pass 만들기 >

 

MTLRenderCommandEncoder 객체를 사용하여 command buffer에 인코딩하여 render pass를 만듭니다. 

위에서 만든 renderPassDescriptor를 makeRenderCommandEncoder의 파라미터로 넘겨줍니다. 

Render pass가 끝났다는 것을 알려주기 위해 endEncoding도 해주세요~

 

 

 

근데 샘플에서는 어떤 drawing command도 encode하지 않을 것이라고 하네요..!! 

그래서 render pass가 하는 일은 mtkView에 세팅해둔 clearColor로 texture를 칠하며 시작하고 바로 끝-! 입니다.

 

 

[5] Drawable을 screen에 present하기 

 

texture에 drawing하면 새로운 contents가 화면에 자동으로 표시되지 않습니다.

메탈에서 screen에 display할 수 있는 textures는 drawable objects에 의해 관리됩니다.

contens를 display하고 싶다면, drawable을 present해야합니다.

 

MTKView는 자동으로 textures를 관리하는 drawable objects를 만들어줍니다. (currentDrawable)

그리고 commandBuffer를 이용하여 drawable을 present해주세요

 

guard let currentDrawable = mtkView.currentDrawable else { return }
commandBuffer.present(currentDrawable)

 

위의 present 메소드는 command buffer가 실행하려고 할때, 메탈에게 "Core Animation과 조율해서 rendering이 끝나면 texture를 display해!!!" 라고 말하는 역할이라고 합니다. 

 

Core Animation이 texture를 present하면 그것은 view의 새로운 contents가 됩니다. 

(작업이 적용된 texture가 view의 새로운 background가 된다..?!?!? 라는 뜻입니다)

 

[6] Command Buffer를 commit 하기

commandBuffer.commit()

 

 

[최종코드]

 

 

돌리면 clear color 화면이 뜨게 됩니다-!!

 

 

반응형
댓글