Trying to create CVPixelBufferRef from MTLTexture on each call render of SCNRender object:
CVPixelBufferLockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0))
let bytesPerRow = 4 * Int(textureSizeX)
let region = MTLRegionMake2D(0, 0, Int(textureSizeX), Int(textureSizeY))
var tmpBuffer = CVPixelBufferGetBaseAddress(pixelBuffer!);
offscreenTexture.getBytes(tmpBuffer!, bytesPerRow: bytesPerRow, from: region, mipmapLevel: 0)
CVPixelBufferUnlockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0))
And then convert to UIImage to display on screen
let ciImage = CIImage.init(cvPixelBuffer: pixelBuffer!)
let temporaryContext = CIContext(options: nil)
let tempImage = temporaryContext.createCGImage(ciImage, from: CGRect(x: 0, y: 0, width: textureSizeX, height: textureSizeY))
let uiImage = UIImage.init(cgImage: tempImage!)
But image is not displayed
You should think of it the other way around, create a metal texture object that uses a CoreVideo buffer as the backing buffer and then render into the texture in the normal way.
- (id<MTLTexture>) makeBGRACoreVideoTexture:(CGSize)size
cvPixelBufferRefPtr:(CVPixelBufferRef*)cvPixelBufferRefPtr
{
int width = (int) size.width;
int height = (int) size.height;
// CoreVideo pixel buffer backing the indexes texture
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], kCVPixelBufferMetalCompatibilityKey,
[NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
[NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
nil];
CVPixelBufferRef pxbuffer = NULL;
CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault,
width,
height,
kCVPixelFormatType_32BGRA,
(__bridge CFDictionaryRef) options,
&pxbuffer);
NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);
*cvPixelBufferRefPtr = pxbuffer;
CVMetalTextureRef cvTexture = NULL;
CVReturn ret = CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault,
_textureCache,
pxbuffer,
nil,
MTLPixelFormatBGRA8Unorm,
CVPixelBufferGetWidth(pxbuffer),
CVPixelBufferGetHeight(pxbuffer),
0,
&cvTexture);
NSParameterAssert(ret == kCVReturnSuccess && cvTexture != NULL);
id<MTLTexture> metalTexture = CVMetalTextureGetTexture(cvTexture);
CFRelease(cvTexture);
return metalTexture;
}