在像素传输过程中openGL反转纹理方向?

时间:2013-06-01 17:47:11

标签: opengl textures

众所周知,openGL使用的像素数据方向在左/下有0/0,而世界其他地方(包括几乎所有图像格式)都使用左/上。 多年来,这一直是无休止的担忧(至少对我而言),我仍然无法找到一个好的解决方案。

在我的应用程序中,我想支持以下图像数据作为纹理:

  1. 来自各种图像源(包括静止图像,视频文件和实时视频)的图像数据
  2. 通过将帧缓冲区复制到主存储器(glReadPixels
  3. 获取的图像数据
  4. 通过抓取帧缓冲区到纹理(glCopyTexImage
  5. 获取的图像数据

    (案例#1提供自上而下的图像(大约98%的情况;为了简单起见,我们假设所有“外部图像”都有自上而下的方向);#2和#3有底部 - 方向)

    我希望能够将所有这些纹理应用到各种任意复杂的对象上(例如,从磁盘读取的3D模型,其中存储了纹理坐标信息)。

    因此我想要一个对象的texture_coords的单一表示。渲染对象时,我不想被图像源的方向所困扰。 (直到现在,我总是携带一个topdown - 标志和纹理ID一起使用,当实际设置纹理坐标时使用它。我想摆脱这个笨拙的黑客!

    基本上我看到了解决问题的三种方法。

    1. 确保所有图像数据都是“正确的”(用openGL术语表示) 是颠倒的方向,转换所有“不正确”的数据,然后传递给openGL
    2. 根据图像方向提供不同的纹理坐标(自下而上图像为0..1,自上而下图像为1..0)
    3. 翻转gfx-card上的图片
    4. 在旧时代,我一直在做#1,但事实证明它太慢了。我们想不惜一切代价避免像素缓冲区的复制。

      几年前我已经转向#2了,但这是维持复杂的方法。我真的不明白为什么我应该携带原始图像的元数据,一旦我将图像转移到gfx卡并有一个漂亮的小抽象“纹理” - 对象。 我正在最终将我的代码转换为VBO,并且希望避免更新我的texcoord数组,因为我使用的是相同大小但方向不同的图像!

      留下#3,我从未设法为我工作(但我相信必须非常简单)。 直觉上我虽然使用像glPixelZoom()这样的东西。 这适用于glDrawPixels()(但是谁在现实生活中使用它?),并且afaik它应该与glReadPixels()一起使用。 后者很棒,因为它允许我至少为内存中的所有图像强制一个合理快速的同质像素方向(自上而下)。

      然而,似乎glPixelZoom()对通过glTexImage2D转移的数据没有影响,更不用说glCopyTex2D(),因此从主内存像素生成的纹理都将颠倒(我可以忍受,因为这只意味着我必须在加载时将所有传入的texcoords转换为自上而下)。 现在剩下的问题是,我还没有找到一种方法将帧缓冲区复制到纹理(使用glCopyTex(Sub)Image),可以与那些自上而下的texcoords一起使用(即:如何翻转图像时使用glCopyTexImage()

      这个简单问题有解决方案吗?什么,易于维护并在openGL-1.1到4.x上运行?

      啊,理想情况下它可以同时使用2次幂和非幂次(或矩形)纹理。 (只要这是可能的......)

2 个答案:

答案 0 :(得分:7)

  

这个简单问题有解决方案吗?一些快速,易于维护并在openGL-1.1到4.x上运行的东西?

没有

没有方法可以在像素上传时更改像素数据的方向。没有方法可以原位改变纹理的方向。用于更改纹理方向的 only 方法(除了下载,翻转和重新上传之外)是使用从包含源纹理的帧缓冲区到包含目标纹理的帧缓冲区的倒置帧缓冲区blit 。并且glFramebufferBlit不适用于任何旧版本的硬件,它不支持GL 2.x.

所以你必须做其他人做的事情:在上传之前翻转你的纹理。或者更好的是,翻转磁盘上的纹理,然后加载它们而不会翻转它们。

然而,如果你真的,真的想要不翻转数据,你可以简单地让你的所有着色器都采用一种制服来告诉他们是否要反转他们的纹理坐标数据的Y.反转不应该只是一个乘法/加法运算。这可以在顶点着色器中完成,以最大限度地缩短处理时间。

或者,如果您在固定功能的黑暗时代进行编码,则可以应用反转Y的纹理矩阵。

答案 1 :(得分:2)

为什么你不改变将纹理映射到多边形的方式? 我使用这个映射坐标{0,1,1,1,0,0,1,0}作为原点左上角 并且此映射坐标为原点左下角的{0,0,1,0,0,1,1,1}。 然后你不需要手动切换你的照片。

有关将纹理映射到多边形的更多详细信息,请参见: http://iphonedevelopment.blogspot.de/2009/05/opengl-es-from-ground-up-part-6_25.html