Я предполагаю, что вы хотите сохранить изображение из MTKView . Но эта функция должна работать для любых текстур. Также не забудьте установить: framebufferOnly = false;
Свойство .
bool takeScreenshot = true;
/// Called whenever the view needs to render a frame
- (void)drawInMTKView:(nonnull MTKView *)view
{
// Create a new command buffer for each render pass to the current drawable
id<MTLCommandBuffer> commandBuffer = [_commandQueue commandBuffer];
commandBuffer.label = @"MyCommand";
// Obtain a renderPassDescriptor generated from the view's drawable textures
MTLRenderPassDescriptor *renderPassDescriptor = view.currentRenderPassDescriptor;
id<MTLTexture> currentSwapChainTexture = view.currentDrawable.texture;
// Your render code...
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> cb)
{
if(takeScreenshot)
{
SaveTexture(currentSwapChainTexture);
takeScreenshot = false;
}
}];
// Finalize rendering here & push the command buffer to the GPU
[commandBuffer commit];
// CPU <-> GPU Synchronization
if(takeScreenshot)[commandBuffer waitUntilCompleted];
Сохранить текстуру Функция:
void SaveTexture(id<MTLTexture> texture)
{
int width = (int) texture.width;
int height = (int) texture.height;
int bytePerPixel = 4;
int bytesPerRow = width * bytePerPixel;
int bytesCount = width * height * bytePerPixel;
int bitsPerComponent = 8;
int bitsPerPixel = 32;
void *imageBytes = malloc(bytesCount);
void *destBytes = malloc(bytesCount);
MTLRegion mtlregion = MTLRegionMake2D(0, 0, width, height);
[texture getBytes:imageBytes bytesPerRow:bytesPerRow fromRegion:mtlregion mipmapLevel:0];
vImage_Buffer src;
src.data = imageBytes;
src.width = width;
src.height = height;
src.rowBytes = bytesPerRow;
vImage_Buffer dest;
dest.data = destBytes;
dest.width = width;
dest.height = height;
dest.rowBytes = bytesPerRow;
// BGRA -> RGBA (Swap)
const uint8_t map[4] = {2, 1, 0, 3};
vImagePermuteChannels_ARGB8888(&src, &dest, map, kvImageNoFlags);
CGColorSpaceRef cgColorSpaceRef = CGColorSpaceCreateWithName(kCGColorSpaceDisplayP3); //kCGColorSpaceSRGB - For sRGB
CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big;
CGContextRef context = CGBitmapContextCreate(destBytes, width, height, bitsPerComponent, bytesPerRow, cgColorSpaceRef, bitmapInfo);
CGImageRef cgImage = CGBitmapContextCreateImage(context);
// Your NSImage
NSImage * image = [[NSImage alloc] initWithCGImage:cgImage size:NSZeroSize];
// Save to Photos
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^
{
[PHAssetCreationRequest creationRequestForAssetFromImage: image];
}
completionHandler:^(BOOL success, NSError * error)
{
if(success) printf("Success \n");
}];
free(imageBytes);
free(destBytes);
CGColorSpaceRelease(cgColorSpaceRef);
CGContextRelease(context);
CGImageRelease(cgImage);
texture = nil;
}