Как сделать 2 изображения независимо друг от друга в металле
Моя цель - спонтанно визуализировать 2 изображения. Первое изображение или текстура - это изображение с моей камеры, полученное из видео в реальном времени, а во-вторых, я хочу загрузить изображение из gif, где какая-то позиция gif имеет alpha = 0
так что я могу видеть мое заднее изображение также. 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
функция. так как я могу визуализировать буксирное изображение независимо и показывать одно под другим?? Какой должна быть моя архитектура?