macos - 核心视频像素缓冲区为 GL_TEXTURE_2D

标签 macos opengl core-video

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

来自 CVOpenGLTextureCacheCreateTextureFromImage 的纹理返回为 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 来提取像素数据?

最佳答案

刚遇到这个,虽然老了,我也要回答一下,以防其他人遇到。

iOS 使用 OpenGL ES(最初是 2.0,然后是 3.0)。 OS X 使用常规的旧(非 ES)OpenGL,可选择核心配置文件(仅限 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 使用桌面 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。

关于macos - 核心视频像素缓冲区为 GL_TEXTURE_2D,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13933503/

相关文章:

c - DDA画线算法有错误

opengl-es - 如何将 OpenGL ES 纹理转换为 CIImage

swift - 如何创建 CMVideoFormatDescription 对象

cocoa - 在 3d 中使用核心图像

cocoa - 从 NSMutableURLRequest 获取响应 header

objective-c - 在 Xcode 4.2 中找不到框架 header ,但应用程序运行正常

python - mac 无法安装spark

opengl - 在 SDL2 中使用 GLSL 着色器

c++ - 无法在 Mac OS X 上链接静态库

c++ - glClearBufferfv 不清除指定的颜色附件