Как сделать 2 изображения независимо друг от друга в металле - PullRequest
0 голосов
/ 07 ноября 2018

Моя цель - спонтанно визуализировать 2 изображения. Первое изображение или текстура - это изображение с моей камеры, полученное из видео в реальном времени, а во-вторых, я хочу загрузить изображение из gif, где какая-то позиция gif имеет alpha = 0, чтобы я мог см. мое заднее изображение также. my draw method выглядит как показано ниже.

    public func draw(in: MTKView) {

    autoreleasepool {
        guard let texture = texture else {
            print("Error : camera stream failed to create texture")
            return
        }
        guard let device = self.device else {
            print("Error : Metal Device is nil")
            return
        }
        guard let commandBuffer = commandQueue?.makeCommandBuffer() else {
            print("Error : Command encoder is nil")
            return
        }


        // resposible to create metal camera effect in camera raw image and output will be written to
        // internalTexture, if success, internal texture will be present to the screen using encoder

        self.createMetalEffect(texture, inputCommandBuffer: commandBuffer)

        guard let commandGifBuffer = commandQueue?.makeCommandBuffer() else{
            print("Error : Command encoder is nil")
            return
        }

        // rendering the effect output texture (writen to internalTexture via kernel) on screen
        // so the self.internalTexture must not be nil!
        render(texture: self.internalTexture!, withCommandBuffer: commandBuffer, device: device)

        // for loading gif here
        if isGifEnable{
            if count == self.imageArray.count - 1{
                count = 0
            }else{
                count += 1
            }
            if let giftexture = self.loadImageFrame(img: self.imageArray[count]){
                self.createGifMetalEffect(giftexture, inputCommandBuffer: commandGifBuffer)
                render(texture: self.gifInternalTexture!, withCommandBuffer: commandGifBuffer, device: device)
            }
        }

        /// ------------------------- end gif loading ------------------------------


    }
}

и для представления изображений мой метод render выглядит следующим образом.

        private func render(texture: MTLTexture,
                        withCommandBuffer commandBuffer: MTLCommandBuffer,
                        device: MTLDevice) {


        guard let renderPassDescriptor = metalView.currentRenderPassDescriptor else {
            print("Error : Render pass descriptor is nil")
            return
        }
        guard let drawable = metalView.currentDrawable else {
            print("Error : drawable from metal view is nil")
            return
        }
        guard let pipelineState = self.pipelineState else {
            print("Error : pipelineState is nil")
            return
        }
//        guard let animation = self.animationDescriptor else {
//            print("Error : animation is nil")
//            return
//        }
        guard let encoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor) else {
            print("Error : Fail to create screen render encoder from command buffer!")
                return
        }
        encoder.pushDebugGroup("RenderFrame")
        encoder.setRenderPipelineState(pipelineState)
        encoder.setFragmentTexture(texture, index: 0)
        encoder.drawPrimitives(type: .triangleStrip, vertexStart: 0,
                                vertexCount: 4, instanceCount: 1)

        encoder.popDebugGroup()
        encoder.endEncoding()

        commandBuffer.present(drawable)

        commandBuffer.commit()
        commandBuffer.waitUntilCompleted()
        self.metalTexture = texture

//        self.metalWriteQueue.async {
//            self.writeTexture(texture)
//        }

    }

У меня также есть метод renderGif, который выглядит так же, как метод render, но с другим именем параметра self.gifInternalTexture! и commandGifBuffer. Так что вопрос в том, когда я рендеринг моего видео без GIF, он работает нормально, но когда я применяю GIF я ожидаю, что рендеринг сверху не будет отображаться, а видео может быть слишком крутым из-за этой команды commandBuffer.waitUntilCompleted() предупреждающее сообщение, которое оно выдает:

should not be called after already presenting this drawable. Get a nextDrawable instead.

возможно, потому что он уже присутствует currentdrawable в функции render. так как я могу визуализировать буксирное изображение независимо и показывать одно под другим ?? Какой должна быть моя архитектура?

...