核心视频像素缓冲区为GL_TEXTURE_2D

时间:2012-12-18 12:54:06

标签: macos opengl core-video

所以我设置了CVPixelBuffer并在iOS上成功将它们绑定到OpenGL FBO。但现在尝试在OSX上做同样的事情让我陷入困境。

CVOpenGLTextureCacheCreateTextureFromImage中的纹理返回GL_TEXTURE_RECTANGLE而不是GL_TEXTURE_2D目标。

我找到了kCVOpenGLBufferTarget键,但似乎它应该与CVOpenGLBufferCreate一起使用而不是CVPixelBufferCreate。

甚至可以使用CVPixelBufferCreate在OSX上获得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来提取像素数据?

2 个答案:

答案 0 :(得分:0)

因为这似乎是悬而未决的,我最近处理的是:不,GL_TEXTURE_RECTANGLE似乎是唯一的用例。要获得GL_TEXTURE_2D,你必须渲染到纹理。

答案 1 :(得分:0)

刚刚遇到这个问题,即使它已经过时,我也会回答它,以防其他人遇到它。

iOS使用OpenGL ES(最初是2.0,然后是3.0)。 OS X使用常规的旧(非ES)OpenGL,可选择Core配置文件(仅限3.0+)或兼容性配置文件(最多3.2)。

这里的不同之处在于OpenGL(非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。