我用AVFoundation来获取相机流。我使用这段代码从以下位置获取MTLTextures:
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
id<MTLTexture> texture = nil;
{
size_t width = CVPixelBufferGetWidth(pixelBuffer);
size_t height = CVPixelBufferGetHeight(pixelBuffer);
MTLPixelFormat pixelFormat = MTLPixelFormatBGRA8Unorm;
CVMetalTextureRef metalTextureRef = NULL;
CVReturn status = CVMetalTextureCacheCreateTextureFromImage(NULL, _textureCache, pixelBuffer, NULL, pixelFormat, width, height, 0, &metalTextureRef);
if(status == kCVReturnSuccess)
{
texture = CVMetalTextureGetTexture(metalTextureRef);
if (self.delegate){
[self.delegate textureUpdated:texture];
}
CFRelease(metalTextureRef);
}
}
}
它工作得很好,除非生成的MTLTexture对象不是mipmaped (只有一个mip级别)。在这一呼吁中:
CVMetalTextureCacheCreateTextureFromImage(NULL, _textureCache, pixelBuffer, NULL, pixelFormat, width, height, 0, &metalTextureRef);
还有一个名为"textureAtributes",的参数--我认为可以指定我想要mipmaped纹理,但是在文档中没有找到确切的内容。我也没有找到在其中传递其他东西而不是NULL的源代码。
在OpenGLES for iOS中,有类似的方法,具有相同的参数,文档中也没有单词。
发布于 2014-11-13 02:27:18
刚收到金属工程师这里的答复。这里有句话:
不,不可能直接从CVPixelBuffer生成not映射的纹理。 CVPixelBuffer图像通常具有线性/跨步布局,因为非GPU硬件块可能与这些块交互,而且大多数GPU硬件只支持来自平铺纹理的mipmapping。您需要发出一个blit从线性MTLTexture复制到您自己创建的私有MTLTexture,然后生成mipmap。
至于textureAttributes,,只支持一个键:kCVMetalTextureCacheMaximumTextureAgeKey
发布于 2014-11-10 00:18:07
没有一种直接获得mipmapped纹理的方法,但是您可以自己轻松地生成一个纹理。
首先,使用您的金属设备创建一个空的金属纹理,其大小和格式与您现有的纹理相同,但具有完整的mipmap链。见newTexture文档
使用MTLCommandBuffer对象创建blitEncoder对象。见blitCommandEncoder文档
使用blitEncoder将相机纹理复制到空纹理。destinationLevel应该是零,因为您只是在复制顶级mipmap。见copyFromTexture文档
最后,使用blitEncoder通过调用generateMipmapsForTexture生成所有mip级别。见generateMipMapsForTexture文档
在这结束,你有一个金属纹理从相机与一个完整的mip链。
https://stackoverflow.com/questions/26733147
复制相似问题