1

我已经设法从 AVPlayer 获取 CVPixelBufferRef 来提供像素数据,我可以使用这些数据来纹理 2D 对象。当我的像素缓冲区中有数据时,我会:

CVReturn err = CVOpenGLESTextureCacheCreateTextureFromImage('
kCFAllocatorDefault,
  videoTextureCache_,
  pixelBuffer, //this is a CVPixelBufferRef
  NULL,
  GL_TEXTURE_2D, 
  GL_RGBA,
  frameWidth,
  frameHeight,
  GL_BGRA,
  GL_UNSIGNED_BYTE,
  0,
  &texture);

我想用这个缓冲区来创建一个 GL_TEXTURE_CUBE_MAP。我的视频帧数据实际上是一个图像中的 6 个部分(例如立方体条),它们总共构成了立方体的侧面。关于如何做到这一点的任何想法?

我曾想过只是假装我的 GL_TEXTURE_2D 是 GL_TEXTURE_CUBE_MAP 并将我的天空盒上的纹理替换为上面代码生成的纹理,但这会造成扭曲的混乱(正如我想在尝试强制天空盒纹理时应该预期的那样)一个 GL_TEXTURE_2D。

另一个想法是使用 glPixelStorei 设置解包,然后从像素缓冲区中读取:

glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, X);
glPixelStorei(GL_UNPACK_SKIP_ROWS, Y);
glTexImage2D(...,&pixelbuffer);

但令人难以置信的是 GL_UNPACK_ROW_LENGTH 在 iOS 的 OpenGl ES2.0 中不受支持。

那么,有没有:

- 在使用缓冲区制作纹理之前,有什么方法可以通过将缓冲区索引到某个像素子集来拆分我们 CVPixelBufferRef 中的像素数据?

- 将 6 个新的 GL_TEXTURE_2D 作为上面代码创建的我的 GL_TEXTURE_2D 的索引子集的任何方法

- 将 GL_TEXTURE_2D 转换为有效 GL_TEXTURE_CUBE_MAP 的任何方法(例如,GLKit 具有从单个立方体文件加载 GL_TEXTURE_CUBE_MAP 的天空盒效果。它没有从内存加载纹理的方法,否则我会被排序)

-还有其他想法吗?

4

1 回答 1

1

如果不可能以任何其他方式(这不太可能,可能有另一种方式 - 所以这可能不是最好的答案并且涉及比必要更多的工作)这里是一个我会尝试的黑客:

立方体贴图的工作原理是将每个面的纹理从几何中心的一个点投射到每个立方体面。所以你可以自己重现这种行为;您可以使用投影纹理进行六个绘制调用,一个用于立方体的每个面。每次,您首先将您感兴趣的面部绘制到模板缓冲区,然后计算纹理的投影矩阵(这种技术在游戏中被大量用于“聚光灯”效果),然后计算出变换矩阵需要增加片段着色器的纹理读取,以便对于每个面,只有对应于该面的纹理部分在 (0..1) 纹理查找范围内结束。如果一切顺利,模板缓冲区应丢弃 0..1 范围之外的任何内容,然后您

上述方法实际上与我现在为应用程序所做的非常相似,只是我只使用投影纹理来屏蔽和替换立方体贴图的一小部分。我需要对我正在投影的小方块的边缘进行像素匹配,以便它无缝地应用于天空盒,这就是为什么我确信这种方法实际上会重现立方体贴图的行为——否则,像素匹配不会不可能。

无论如何,我希望你能找到一种简单地将 2D 转换为 CUBEMAP 的方法,因为这可能会更容易和更清晰。

于 2012-10-26T00:45:45.210 回答