How to render 2 images independently in metal
up vote
0
down vote
favorite
my target is to render 2 image spontaneously.First image or texture is my camera image which comes from live video and for second one I want to load image from gif where some position of the gif has alpha = 0
so that I can see my back image also.my draw method
looks like below.
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 ------------------------------
}
}
and for presenting images my render
method looks like this.
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)
// }
}
I have renderGif
method also which looks same as render
method but with different parameter name self.gifInternalTexture!
and commandGifBuffer
.So the question is when I render my video without gif it works fine but when I apply gif which I expect to render in top are not showing and also video is frizzing maybe because of this command commandBuffer.waitUntilCompleted()
the warning message which it give is
should not be called after already presenting this drawable. Get a nextDrawable instead.
maybe because it already present currentdrawable
in render
function. so how can I render tow image independently and show one under the another?? What should be my architecture?
ios swift metal metalkit
add a comment |
up vote
0
down vote
favorite
my target is to render 2 image spontaneously.First image or texture is my camera image which comes from live video and for second one I want to load image from gif where some position of the gif has alpha = 0
so that I can see my back image also.my draw method
looks like below.
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 ------------------------------
}
}
and for presenting images my render
method looks like this.
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)
// }
}
I have renderGif
method also which looks same as render
method but with different parameter name self.gifInternalTexture!
and commandGifBuffer
.So the question is when I render my video without gif it works fine but when I apply gif which I expect to render in top are not showing and also video is frizzing maybe because of this command commandBuffer.waitUntilCompleted()
the warning message which it give is
should not be called after already presenting this drawable. Get a nextDrawable instead.
maybe because it already present currentdrawable
in render
function. so how can I render tow image independently and show one under the another?? What should be my architecture?
ios swift metal metalkit
you may try remove ` commandBuffer.waitUntilCompleted()` to see the result
– E.Coms
Nov 7 at 18:24
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
my target is to render 2 image spontaneously.First image or texture is my camera image which comes from live video and for second one I want to load image from gif where some position of the gif has alpha = 0
so that I can see my back image also.my draw method
looks like below.
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 ------------------------------
}
}
and for presenting images my render
method looks like this.
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)
// }
}
I have renderGif
method also which looks same as render
method but with different parameter name self.gifInternalTexture!
and commandGifBuffer
.So the question is when I render my video without gif it works fine but when I apply gif which I expect to render in top are not showing and also video is frizzing maybe because of this command commandBuffer.waitUntilCompleted()
the warning message which it give is
should not be called after already presenting this drawable. Get a nextDrawable instead.
maybe because it already present currentdrawable
in render
function. so how can I render tow image independently and show one under the another?? What should be my architecture?
ios swift metal metalkit
my target is to render 2 image spontaneously.First image or texture is my camera image which comes from live video and for second one I want to load image from gif where some position of the gif has alpha = 0
so that I can see my back image also.my draw method
looks like below.
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 ------------------------------
}
}
and for presenting images my render
method looks like this.
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)
// }
}
I have renderGif
method also which looks same as render
method but with different parameter name self.gifInternalTexture!
and commandGifBuffer
.So the question is when I render my video without gif it works fine but when I apply gif which I expect to render in top are not showing and also video is frizzing maybe because of this command commandBuffer.waitUntilCompleted()
the warning message which it give is
should not be called after already presenting this drawable. Get a nextDrawable instead.
maybe because it already present currentdrawable
in render
function. so how can I render tow image independently and show one under the another?? What should be my architecture?
ios swift metal metalkit
ios swift metal metalkit
edited Nov 7 at 9:30
Cœur
16.9k9102139
16.9k9102139
asked Nov 7 at 9:25
Rumy
124112
124112
you may try remove ` commandBuffer.waitUntilCompleted()` to see the result
– E.Coms
Nov 7 at 18:24
add a comment |
you may try remove ` commandBuffer.waitUntilCompleted()` to see the result
– E.Coms
Nov 7 at 18:24
you may try remove ` commandBuffer.waitUntilCompleted()` to see the result
– E.Coms
Nov 7 at 18:24
you may try remove ` commandBuffer.waitUntilCompleted()` to see the result
– E.Coms
Nov 7 at 18:24
add a comment |
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53186592%2fhow-to-render-2-images-independently-in-metal%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
you may try remove ` commandBuffer.waitUntilCompleted()` to see the result
– E.Coms
Nov 7 at 18:24