【问题标题】:Core Video pixel buffers as GL_TEXTURE_2D核心视频像素缓冲区为 GL_TEXTURE_2D
【发布时间】:2012-12-05 16:34:33
【问题描述】:

所以我已经设置了 CVPixelBuffer,并在 iOS 上成功地将它们绑定到 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 来提取像素数据?

【问题讨论】:

  • 您使用的是核心配置文件吗?
  • 考虑到我不知道那是什么,直到你提到它......可能不会。
  • 好的,我没有使用 3.2 核心配置文件。即使是现在,Core Video 仍然使用 GL_TEXTURE_RECTANGLE 作为目标。
  • 我应该注意到 #import 会导致编译器警告“gl.h 和 gl3.h 都包含在内”。这表明 CoreVideo 没有对我使用 3.2 核心配置文件。
  • 我认为如果您使用核心配置文件而不是使用 GL_TEXTURE_2D,至少在 iOS 上是这样。 3.2 应该与 es 2.0 兼容,后者支持 TEXTURE_2D 中的矩形纹理

标签: macos opengl core-video


【解决方案1】:

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

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。

【讨论】:

    【解决方案2】:

    因为这似乎一直悬而未决并且是我最近处理的问题:不,GL_TEXTURE_RECTANGLE 似乎是唯一的用例。要获得GL_TEXTURE_2D,您将不得不渲染到纹理。

    【讨论】:

    • 元评论:我从一开始就将其标记为社区 wiki,因为所有这些都在三年前的 cmets 中陈述或暗示,但最好将其正式化为答案。
    猜你喜欢
    • 1970-01-01
    • 2017-09-28
    • 1970-01-01
    • 2014-07-04
    • 1970-01-01
    • 2012-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多