众所周知,openGL使用的像素数据方向在左/下有0/0,而世界其他地方(包括几乎所有图像格式)都使用左/上.多年来,这一直是无休止的担忧(至少对我而言),我仍然无法找到一个好的解决方案.
在我的应用程序中,我想支持以下图像数据作为纹理:
glReadPixels)glCopyTexImage)获取的图像数据(案例#1提供自上而下的图像(大约98%的情况;为简单起见,我们假设所有"外部图像"都有自上而下的方向);#2和#3有自下而上的方向)
我希望能够将所有这些纹理应用到各种任意复杂的对象上(例如,从磁盘读取的3D模型,其中存储了纹理坐标信息).
因此,我想要一个对象的texture_coords的单一表示.渲染对象时,我不想被图像源的方向所困扰.(直到现在,我总是topdown在纹理id旁边带一个标志,当纹理坐标实际设置时使用它.我想摆脱这个笨拙的黑客!
基本上我看到了解决问题的三种方法.
在旧时代,我一直在做#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的幂和非幂(或矩形)纹理.(尽可能......)
有这个简单问题的解决方案吗?一些快速,易于维护并在openGL-1.1到4.x上运行的东西?
没有.
没有方法可以在像素上传时更改像素数据的方向.没有方法可以原位改变纹理的方向.更改纹理方向的唯一方法(除了下载,翻转和重新上传之外)是使用从包含源纹理的帧缓冲区到包含目标纹理的帧缓冲区的倒置帧缓冲区blit.并且glFramebufferBlit不适用于任何太旧的硬件,它不支持GL 2.x.
因此,您将不得不做其他人所做的事情:在上传之前翻转纹理.或者更好的是,翻转磁盘上的纹理,然后加载它们而不翻转它们.
但是,如果你真的真的想要不翻转数据,你可以简单地让你的所有着色器都采用制服来告诉他们是否要反转他们的纹理坐标数据的Y. 反转不应该只是一个乘法/加法运算.这可以在顶点着色器中完成,以最小化处理时间.
或者,如果您在固定功能的黑暗时代进行编码,则可以应用反转Y的纹理矩阵.