openGL 在像素传输期间反转纹理方向?

标签 opengl textures

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

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

  • 来自各种图像源(包括静止图像、视频文件和实时视频)的图像数据
  • 通过将帧缓冲区复制到主内存(glReadPixels)获取的图像数据
  • 通过抓取帧缓冲区到纹理获取的图像数据( glCopyTexImage )

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

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

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

    基本上我看到了三种解决问题的方法。
  • 确保所有图像数据都在“正确”中(在 openGL 术语中,这
    是颠倒的)方向,转换所有“不正确”的数据,然后将其传递给 openGL
  • 根据图像方向提供不同的纹理坐标(0..1 表示自下而上的图像,1..0 表示自上而下的图像)
  • 翻转 gfx 卡上的图像

  • 在过去,我一直在做#1,但结果证明它太慢了。我们想不惜一切代价避免像素缓冲区的副本。

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

    剩下#3,我从来没有为我工作过(但我相信它 一定很简单 )。
    直觉上我虽然使用类似 glPixelZoom() 的东西。
    这适用于 glDrawPixels() (但谁在现实生活中使用它?),并且它应该适用于 glReadPixels()
    后者很棒,因为它允许我至少为主内存中的所有图像强制一个相当快的同质像素方向(自上而下)。

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

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

    啊,理想情况下,它适用于二的幂和非二的幂(或矩形)纹理。 (在可能的情况下...)

    最佳答案

    is there a solution for this simple problem? something that is fast, easy to maintain and runs on openGL-1.1 through 4.x?



    不。

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

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

    但是,如果您真的,真的不想翻转数据,您可以简单地让所有着色器采用统一的方式,告诉它​​们是否反转其纹理坐标数据的 Y。反转不应该只是乘法/加法运算。这可以在顶点着色器中完成以最小化处理时间。

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

    关于openGL 在像素传输期间反转纹理方向?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16875490/

    相关文章:

    opengl - 现代 OpenGL 中的正交投影

    linux - 无法在 Ubuntu 上运行我自己的 OpenGL 3 程序

    xcode - Xcode 4.3.1 中的纹理工具位于哪里?

    javascript - 在 Three.js 中更改 MouseOver 上的纹理颜色

    opengl - glActiveTexture 和 glBindTexture 的区别和关系

    c++ - 当不是最后加载的纹理时,纹理会显得模糊

    c++ - 你如何检查鼠标是否在 freeglut 的三角形区域内单击?

    c++ - malloc() 和 glDrawPixels() 的访问冲突?

    c++ - opengl不画任何东西

    c++ - OpenGL 纹理渲染颠倒且模糊