目标:
// HIGH LEVEL
// create a texture
// render the current view to it
// write the texture to png at file path
// release texture / buffers?
我尝试解决方案(尚未编译):
void OutputFrameBuffer(const char *filepath) {
mvGraphics &graphics = GContext->graphics;
mvGraphics_Metal *graphicsData =
(mvGraphics_Metal *)graphics.backendSpecifics;
mvViewportData *_view =
(mvViewportData *)GContext->viewport->platformSpecifics;
id<CAMetalDrawable> drawable = _view->layer.nextDrawable;
id<MTLCommandBuffer> commandBuffer =
[graphicsData->commandQueue commandBuffer];
// Encode a render pass to render the image to the drawable texture.
[self drawScene:view withCommandBuffer:commandBuffer];
id<MTLTexture> readTexture = drawable.texture;
MTLOrigin readOrigin = MTLOriginMake(region.origin.x, region.origin.y, 0);
MTLSize readSize = MTLSizeMake(region.size.width, region.size.height, 1);
const id<MTLBuffer> pixelBuffer =
[self readPixelsWithCommandBuffer:commandBuffer
fromTexture:readTexture
atOrigin:readOrigin
withSize:readSize];
NSUInteger bytesPerPixel = sizeofPixelFormat(readTexture.pixelFormat);
NSUInteger bytesPerRow = size.width * bytesPerPixel;
NSUInteger bytesPerImage = size.height * bytesPerRow;
id<MTLBuffer> _readBuffer =
[readTexture.device newBufferWithLength:bytesPerImage
options:MTLResourceStorageModeShared];
id<MTLBlitCommandEncoder> blitEncoder = [commandBuffer blitCommandEncoder];
[blitEncoder copyFromTexture:readTexture
sourceSlice:0
sourceLevel:0
sourceOrigin:origin
sourceSize:size
toBuffer:_readBuffer
destinationOffset:0
destinationBytesPerRow:bytesPerRow
destinationBytesPerImage:bytesPerImage];
[blitEncoder endEncoding];
[commandBuffer commit];
// The app must wait for the GPU to complete the blit pass before it can
// read data from _readBuffer.
[commandBuffer waitUntilCompleted];
// Read texture data from the GPU
NSUInteger _bytesPerRow = readTexture.width * 4; // Assuming RGBA8 format
NSUInteger bufferSize = bytesPerRow * readTexture.height;
// void *buffer = malloc(bufferSize);
// [renderTexture getBytes:buffer
// bytesPerRow:bytesPerRow
// fromRegion:MTLRegionMake2D(0, 0, renderTexture.width,
// renderTexture.height)
// mipmapLevel:0];
// Convert char* fname to NSString
std::string fnameString(filepath);
NSString *filePath = [NSString stringWithUTF8String:fnameString.c_str()];
// Save texture data to a file
NSData *imageData = [NSData dataWithBytesNoCopy:_readBuffer
length:bufferSize
freeWhenDone:YES];
[imageData writeToFile:filePath atomically:YES];
// Cleanup
free(_readBuffer);
}
C 文件中暴露的数据:$GContext: mvContext$ 其中包含 2 个结构体:
mvViewportData
{
GLFWwindow* handle = nullptr;
CAMetalLayer* layer = nullptr;
};
struct mvGraphics_Metal
{
MTLRenderPassDescriptor* renderPassDescriptor;
id <MTLCommandQueue> commandQueue;
id <MTLDevice> device;
};
我正在尝试为开源 Dearpygui 做出贡献,因为我希望它能够在我的 Mac 上运行!
我尝试改编以下示例 https://developer.apple.com/documentation/metal/textures/creating_and_sampling_textures https://developer.apple.com/documentation/metal/onscreen_presentation/reading_pixel_data_from_a_drawable_texture
但我觉得我错过了一些东西,即我从 ChatGPT 获得了 png 的纹理,但我不相信它。还有上下文区域和图像大小。我已经超出了我的深度。我还没有编译:D
与其尝试让 ChatGPT 为您编写一个函数,我建议您查看 Stack Overflow 上的工作示例,例如这个已回答的问题,该问题从可绘制对象
CGImage
创建 UIImage
或 MTLTexture
: