使用MTKView显示JPEG图像 [英] Display JPEG image using MTKView

查看:388
本文介绍了使用MTKView显示JPEG图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一种方法可以通过MTKView和MTLBuffer(以及iPhone 6+)显示JPEG图像.我已经按照以下方式尝试过了(这只是测试):

Is there a way to display JPEG image via MTKView and MTLBuffer(and within iPhone 6+). I've tried this in a following way(this was just test):

- (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)drawInMTKView:(MTKView *)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];
}

此方法调用中出现错误:

I get an error in this method call:

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

/BuildRoot/Library/Caches/com.apple.xbs/Sources/Metal/Metal-54.31/ToolsLayers/Debug/MTLDebugRenderCommandEncoder.mm:2123: 断言失败-[MTLDebugRenderCommandEncoder 仅支持drawPrimitives:indirectBuffer:indirectBufferOffset:] 在MTLFeatureSet_iOS_GPUFamily3_v1及更高版本上

/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'

这是因为此API仅受

This is because this API supported only by iPhone 6s(+).

我认为我做的事情完全错了.也许我需要换个方向思考.有人可以帮助我还是指向正确的方向? 谢谢.

And I think I am doing something completely wrong. Maybe I need to think in other direction. Could somebody help me or point to right direction? Thanks.

推荐答案

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

There is no simple way to use MTLBuffer to present image data via MTKView. In this case you have to prepare right pixel presentation for right output texture that is used to display by MTKView in the drawble layer. The simplest way is to use MTKTextureLoader, or load data to MTLTexture object from UIImage/CGImage instance.

我做了类似的实验,使用MTL Layer MTLTexture(而不是MTLBuffer)在iOS设备上显示图像,并且我确定了显示图像的最佳方法(如果只需要:显示图像),它使用了直通无需渲染的内核功能.

I did a similar experiments with presenting images on iOS devices using MTL Layer an MTLTexture (instead of MTLBuffer), and i've decided the best way to display image (if this one needs only: to display image) it uses passthrough kernel-function without rendering.

在Swift2中,如下所示:

In Swift2 this looks like the follow:

...

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()
...

在金属底纹文件中:

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

这篇关于使用MTKView显示JPEG图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆