所以我已经在iOS上成功地设置了CVPixelBuffer并将其绑定到OpenGL FBO上,但现在尝试在OSX上做同样的事情让我遇到了障碍。
CVOpenGL纹理缓存创建纹理自图像中的纹理将返回为GL_TEXTURE_RECTANGLE,而不是GL_TEXTURE_2D目标。
我已经找到了kCVOpenGLBufferTarget键,但它似乎应该与CVOpenGLBufferCreate一起使用,而不是与CVPixelBufferCreate一起使用。
是否有可能在OSX上使用CVPixelBufferCreate获得GL_TEXTURE_2D目标纹理,如果有,如何获得?
FWIW CV PBO设置列表:
NSDictionary *bufferAttributes = @{ (__bridge NSString *)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA), (__bridge NSString *)kCVPixelBufferWidthKey : @(size.width), (__bridge NSString *)kCVPixelBufferHeightKey : @(size.height), (__bridge NSString *)kCVPixelBufferIOSurfacePropertiesKey : @{ } };
if (pool)
{
error = CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault, pool, &renderTarget);
}
else
{
error = CVPixelBufferCreate(kCFAllocatorDefault, (NSUInteger)size.width, (NSUInteger)size.height, kCVPixelFormatType_32BGRA, (__bridge CFDictionaryRef)bufferAttributes, &renderTarget);
}
ZAssert(!error, @"Couldn't create pixel buffer");
error = CVOpenGLTextureCacheCreate(kCFAllocatorDefault, NULL, [[NSOpenGLContext context] CGLContextObj], [[NSOpenGLContext format] CGLPixelFormatObj], NULL, &textureCache);
ZAssert(!error, @"Could not create texture cache.");
error = CVOpenGLTextureCacheCreateTextureFromImage(kCFAllocatorDefault, textureCache, renderTarget, NULL, &renderTexture);
ZAssert(!error, @"Couldn't create a texture from cache.");
GLuint reference = CVOpenGLTextureGetName(renderTexture);
GLenum target = CVOpenGLTextureGetTarget(renderTexture);
更新:我已经成功地使用了GL_TEXTURE_RECTANGLE纹理。但是,这会导致很多问题,与iOS和OSX之间的兼容性着色器。无论如何,我宁愿继续使用规格化纹理坐标。
如果无法以这种方式直接从CVPixelBuffer获取GL_TEXTURE_2D纹理,是否可以创建一个CVOpenGLBuffer并将CVPixelBuffer附加到它以拉取像素数据?
3条答案
按热度按时间vawmfj5a1#
刚碰到这个,就算是陈年旧事,我也要回答一下,以防别人遇到。
iOS使用OpenGL ES(最初是2.0,然后是3.0)。OS X使用常规的旧版(非ES)OpenGL,可以选择核心配置文件(仅3.0+)或兼容性配置文件(最高3.2)。
不同之处在于OpenGL(non-ES)是很久以前设计的,当时对纹理大小有很多限制。随着显卡取消了这些限制,添加了扩展,包括GL_TEXTURE_RECTANGLE。现在,任何GPU支持任何大小的纹理都不是什么大事,但出于API兼容性的原因,他们无法真正修复OpenGL。由于OpenGL ES在技术上是一个并行但独立的API,这是最近设计的,他们能够从一开始就纠正这个问题(即他们从来不必担心打破旧的东西)。所以对于OpenGL ES,他们从来没有定义GL_TEXTURE_RECTANGLE,他们只是定义GL_TEXTURE_2D没有大小限制。
简短的回答- OS X使用Desktop OpenGL,由于传统的兼容性原因,它仍然单独处理矩形纹理,而iOS使用OpenGL ES,它对GL_TEXTURE_2D没有大小限制,因此根本没有提供GL_TEXTURE_RECTANGLE。因此,在OS X上,CoreVideo生成GL_TEXTURE_RECTANGLE对象,因为GL_TEXTURE_2D会浪费大量内存,而在iOS上,它将生成GL_TEXTURE_2D对象,因为GL_TEXTURE_RECTANGLE不存在,也不需要。
不幸的是OpenGL和OpenGL ES之间不兼容,但它就是这样,除了围绕它的代码之外没有什么可做的。或者,现在,你可以(也许应该考虑)转向Metal。
hgqdbh6s2#
因为这似乎一直悬而未决,是我最近处理的事情:不,
GL_TEXTURE_RECTANGLE
似乎是唯一的用例。要得到GL_TEXTURE_2D
,你必须渲染到纹理。jxct1oxe3#
FWIW,截至2023年,现代的
CGLTexImageIOSurface2D
比CVOpenGLESTextureCacheCreateTextureFromImage()
更快地将CVPixelData导入OpenGL纹理。只需确保您的CVPixelbuffers支持IOSurface,方法是在[[AVPlayerItemVideoOutput alloc] initWithPixelBufferAttributes]
的属性中包含(id)kCVPixelBufferIOSurfacePropertiesKey: @{},
你仍然会得到一个GL_TEXTURE_RECTANGLE,但是你会得到它的方式更快。我做了一个小着色器,以便我可以渲染GL_TEXTURE_RECTANGLE到一个GL_TEXTURE_2D绑定到一个帧缓冲区。