• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

ios - 使用 MTKView 显示 JPEG 图像

[复制链接]
菜鸟教程小白 发表于 2022-12-12 09:43:34 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

有没有办法通过 MTKView 和 MTLBuffer(以及在 iPhone 6+ 中)显示 JPEG 图像。我已经通过以下方式进行了尝试(这只是测试):

- (id<MTLBuffer>)testBuffer
{
    if (!_testBuffer)
    {
// 
        NSString *path = [[NSBundle mainBundle] pathForResource"testImage" ofType"jpg"];
        NSData *imageData = [NSData dataWithContentsOfFile:path];
        _testBuffer = [self.device newBufferWithBytes:imageData.bytes length:imageData.length options:MTLResourceCPUCacheModeWriteCombined];
    }

    return _testBuffer;
}

- (void)drawInMTKViewMTKView *)view
{
    MTLRenderPassDescriptor* renderPassDescriptor = view.currentRenderPassDescriptor;
    id <MTLCommandBuffer> commandBuffer = [_commandQueue commandBuffer];
    id <MTLRenderCommandEncoder> renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
    [renderEncoder drawPrimitives:MTLPrimitiveTypePoint indirectBuffer:self.testBuffer indirectBufferOffset:0];
    [renderEncoder endEncoding];
    [commandBuffer presentDrawable:view.currentDrawable];
    [commandBuffer commit];
}

我在此方法调用中遇到错误:

[renderEncoder drawPrimitives:MTLPrimitiveTypePoint indirectBuffer:self.testBuffer indirectBufferOffset:0];

/BuildRoot/Library/Caches/com.apple.xbs/Sources/Metal/Metal-54.31/ToolsLayers/Debug/MTLDebugRenderCommandEncoder.mm:2123: failed assertion `-[MTLDebugRenderCommandEncoder drawPrimitives:indirectBuffer:indirectBufferOffset:] is only supported on MTLFeatureSet_iOS_GPUFamily3_v1 and later'

这是因为只有 iPhone 6s(+) 支持此 API .

而且我认为我做错了什么。也许我需要换个方向思考。有人可以帮助我或指出正确的方向吗? 谢谢。



Best Answer-推荐答案


没有简单的方法可以使用 MTLBuffer 通过 MTKView 呈现图像数据。在这种情况下,您必须为正确的输出纹理准备正确的像素表示,该输出纹理用于由 MTKView 在可绘制层中显示。最简单的方法是使用 MTKTextureLoader,或者从 UIImage/CGImage 实例加载数据到 MTLTexture 对象。

我做了一个类似的实验,使用 MTL 层和 MTLTexture(而不是 MTLBuffer)在 iOS 设备上呈现图像,我已经决定了显示图像的最佳方式(如果只需要:显示图像)它使用直通无需渲染的内核函数。

在 Swift2 中,如下所示:

...

let textureLoader = MTKTextureLoader(device: self.device!)
if let image = UIImage(named: file){
   imageTexture = try! textureLoader.newTextureWithCGImage(image.CGImage!, options: nil)
   threadGroups = MTLSizeMake(
                (imageTexture.width+threadGroupCount.width)/threadGroupCount.width,
                (imageTexture.height+threadGroupCount.height)/threadGroupCount.height, 1)
    }
} 
...  

let function:MTLFunction! = library.newFunctionWithName("kernel_passthrough")
...
pipeline = try! self.device.newComputePipelineStateWithFunction(function)
...
let commandBuffer = commandQueue.commandBuffer()
let encoder = commandBuffer.computeCommandEncoder()
encoder.setComputePipelineState(pipeline)
encoder.setTexture(actualImageTexture, atIndex: 0)
encoder.setTexture(metalView.currentDrawable!.texture, atIndex: 1)
encoder.setBuffer(self.saturationUniform, offset: 0, atIndex: 0)
encoder.dispatchThreadgroups(threadGroups!, threadsPerThreadgroup: threadGroupCount)
encoder.endEncoding()
commandBuffer.presentDrawable(metalView.currentDrawable!)
commandBuffer.commit()
...

在 Metal 着色文件中:

kernel void kernel_passthrough(texture2d<float, access::read> inTexture [[texture(0)]],
                           texture2d<float, access::write> outTexture [[texture(1)]],
                           uint2 gid [[thread_position_in_grid]])
{
     float4 inColor   = inTexture.read(gid); 
     //
     // flip texture vertically if it needs to display with right orientation 
     //
     outTexture.write(inColor, gid);
}

完整示例来源:ImageMetalling-00

关于ios - 使用 MTKView 显示 JPEG 图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33605241/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap