opengl - 如何从 ARGB NSImage 加载 OpenGL 纹理而不需要调整?

标签 opengl jpeg loading nsimage argb

我正在为 Mac OS >= 10.6 编写一个应用程序,该应用程序可以根据从磁盘加载的图像创建 OpenGL 纹理。

首先,我将图像加载到 NSImage 中。然后我从图像中获取 NSBitmapImageRep 并使用 glTexImage2D 将像素数据加载到纹理中。

对于 RGB 或 RGBA 图像,它工作得很好。我可以传入 3 字节/像素的 RGB 或 4 字节的 RGBA,并创建 4 字节/像素的 RGBA 纹理。

但是,我刚刚让测试人员向我发送了一张似乎具有 ARGB 字节顺序的 JPEG 图像(在 Canon EOS 50D 上拍摄,不确定它是如何导入的)。

我在这个线程上找到了一篇文章:(http://www.cocoabuilder.com/archive/cocoa/12782-coregraphics-over-opengl.html)这表明我指定 GL_BGRA 的格式参数来 glTexImage2D,以及 GL_UNSIGNED_INT_8_8_8_8_REV 类型。

这似乎合乎逻辑,而且似乎应该有效,但事实并非如此。我得到了不同的颜色值,但仍然是错误的。

我编写了“swizzling”(手动字节交换)代码,将 ARGB 图像数据混洗到新的 RGBA 缓冲区中,但这种逐字节混洗对于大图像来说会很慢。

我还想了解如何让这项工作“以正确的方式”进行。

将 ARGB 数据加载到 RGBA OpenGL 纹理中的技巧是什么?

我当前对 xxx 的调用如下所示:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, newWidth, newHeight, 0, format, GL_UNSIGNED_BYTE, pixelBuffer);

其中 RGB 或 RGBA。

我尝试使用:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, newWidth, newHeight, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixelBuffer);

当我的图像代表报告它处于“alpha 优先”顺序时。

作为第二个问题,我还了解到大多数显卡的“ native ”格式是 GL_BGRA,因此以该格式创建纹理会导致更快的纹理绘制。纹理绘制的速度比加载纹理的速度更重要,因此预先将数据“混合”为 BGRA 格式是值得的。我尝试要求 OpenGL 通过指定 GL_RGBA 的“内部格式”来创建 BGRA 纹理,但这会导致完全黑色的图像。我对文档的解释使我期望,如果源格式和内部格式不同,glTexImage2D 会在读取数据时对数据进行字节交换,但当我尝试指定以下格式的“内部格式”时,我会收到 OpenGL 错误 0x500 (GL_INVALID_ENUM) GL_RGBA。我错过了什么?

最佳答案

我不知道如何将 ARGB 数据直接加载到纹理中,但有一个比仅在 CPU 上进行混合更好的解决方法。您可以在 GPU 上非常有效地完成此操作:

  1. 将 ARGB 数据加载到临时 RGBA 纹理中。
  2. 使用此纹理绘制全屏四边形,同时使用简单的像素着色器渲染到目标纹理。
  3. 继续加载其他资源,无需停止 GPU 管道。

像素着色器示例:

#version 130
uniform sampler2DRect unit_in;
void main() {
    gl_FragColor = texture( unit_in, gl_FragCoord.xy ).gbar;
}

关于opengl - 如何从 ARGB NSImage 加载 OpenGL 纹理而不需要调整?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4958644/

相关文章:

c++ - 使用 CUDA 计算二维像素阵列,声明适当的网格和 block 大小

ios - 给定图像数据和 UTI 转换为 JPEG

html - 渐进式 jpeg 与基线 jpeg

javascript - 有些 JS 加载,有些则不加载

opengl - 无法让 Freeglut 在 Windows 上与 Haskell 一起使用

opengl - 如何在桌面上创建 OpenGL ES 2 上下文?

opengl - 如何在旋转对象时在OpenGL中固定光源?

ios - 在服务器上将 HEIF (.heic) 转换为 JPEG?

linux - 为什么ELF程序头有两个LOAD入口,而程序布局三段

Java动态加载和卸载.java文件,垃圾收集?