2017-12-20 28 views
0

기본 금속 자습서 설정에 따라 균일 한 색상의 빈 화면을 렌더링하려고합니다.금속은보기의 일부만 그리고 레이어에 대한 질문입니다.

금속이 화면의 일부분에만 그려지는 경우이 문제가 발생합니다.

단일보기 응용 프로그램을 설정하고 MainStoryboard의보기를 내가 만드는 클래스에 첨부했습니다. 배경색을 녹색으로 설정했습니다. 여기

클래스 녹색 화면 전체 그러나 이것은 단지 아이폰 6S에서이 사진으로 나타낸 플러스로 부분을 채운다 그렇지 않은 렌더링해야

class MBEMetalView: UIView { 

    var device:MTLDevice? 
    var MTLLayer:CAMetalLayer? 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 

     device = MTLCreateSystemDefaultDevice() 

     //The book said to cast the layer to a CAMetalLayer 
     //but that causes a crash in the redraw method because 
     //failed assertion `No rendertargets set in RenderPassDescriptor.' 
     //So we do this.. which might be wasteful? 
     MTLLayer = CAMetalLayer() 
     MTLLayer?.device = device 
     MTLLayer?.pixelFormat = MTLPixelFormat.bgra8Unorm 
     MTLLayer?.framebufferOnly = true 
     MTLLayer?.frame = frame 
     layer.addSublayer(MTLLayer!) 
    } 

    override func didMoveToWindow() { 
     redraw() 
    } 

    func redraw() { 
     var drawable = MTLLayer?.nextDrawable() 
     var texture = drawable?.texture 

     var passDescriptor = MTLRenderPassDescriptor() 
     passDescriptor.colorAttachments[0].texture = texture 
     passDescriptor.colorAttachments[0].loadAction = MTLLoadAction.clear 
     passDescriptor.colorAttachments[0].storeAction = MTLStoreAction.store 
     passDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0, 1, 0, 1) 


     var commandQueue = device?.makeCommandQueue() 
     var commandBuffer = commandQueue?.makeCommandBuffer() 
     var commandEncoder = commandBuffer?.makeRenderCommandEncoder(descriptor: passDescriptor) 
     commandEncoder?.endEncoding() 

     if let drawOn = drawable { 
      commandBuffer?.present(drawOn) 
      commandBuffer?.commit() 
     } 
    } 

} 

클래스를이다 (레드가 인 금속이 그리는 것이 아닌보기의 배경). 이 enter image description here

이 결과는 몇 가지 질문이 떠오른다 : 그들은 수 있었다

  1. 왜 금속은 화면
  2. 나는 다음 오전 튜토리얼의 일부에 렌더링되는 것이 목표 - C에서 그것을하고있다 새 레이어를 만드는 대신 상속 된 UIView의 레이어를 CAMetal 레이어 으로 캐스팅 할 수 있습니다. 이렇게하면 .addSublayer 라인을 제거 할 수 있습니다. 그러나 내가 이것을 시도하면 의견에 보여주는 충돌이 발생합니까? 왜 이런거야?
  3. 프레임이 iPhone X와 같은 안전한 영역이있는 장치에 의해 어떻게 전달 될 것입니까? 을 안전 영역 바깥에 그릴 때 추가로 사용해야합니까? 내가 프로그래밍 내보기의 프레임에서 안전 영역의 크기를 얻을 수있는 위치를 init(coder)CAMetalLayer의 프레임을 설정하고 절대 변하지 않을

답변

1

(넣다 새로운 디바이스가 출시 입니다). 그러나 init(coder)에서 최종 프레임 크기는 아직 알지 못합니다 (이 시점에서 Interface Builder에서 설정 한 크기를 사용하지만 아직 장치 크기는 설정하지 않았습니다). didMoveToWindow()에서도 금속 레이어의 프레임을 최종 크기로 설정합니다. (또는 아마도 layoutSubviews()에 있습니다.)

+0

이 답변을 주셔서 감사합니다. 질문의 두 번째와 세 번째 부분에 대해서도 대답 해 주시겠습니까? 귀하가 답변 한 질문의 가장 중요한 부분이지만 여전히 몇 가지 질문이 남아 있습니다. –

+0

3 부에 대한 답을 모르겠습니다 (아직 iPhone X에서 Metal로 그림을 그렸습니다). 2 부에서는 문제를 일으키는 실제 코드를 볼 필요가 있습니다. –