如何从ARGB NSImage加载OpenGL纹理而不进行调整?

我正在为Mac OS> = 10.6编写一个应用程序,它可以从磁盘加载的图像创建OpenGL纹理。 首先,我将图像加载到NSImage中。然后我从图像中获取NSBitmapImageRep并使用glTexImage2D将像素数据加载到纹理中。 对于RGB或RGBA图像,它可以完美地工作。我可以传入3个字节/像素的RGB或4个字节的RGBA,并创建一个4字节/像素的RGBA纹理。 但是,我刚给测试人员发送了一张JPEG图像(在佳能EOS 50D上拍摄,不知道它是如何导入的)似乎有ARGB字节排序。 我在这个帖子上发了一篇文章:(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 first”顺序时。 作为第二个问题,我还读到大多数显卡的“原生”格式是GL_BGRA,因此以该格式创建纹理可以加快纹理绘制速度。纹理绘制的速度比加载纹理的速度更重要,因此将数据“调配”到BGRA格式是值得的。我试图通过指定GL_RGBA的“内部格式”来要求OpenGL创建BGRA纹理,但这会导致完全黑色的图像。我对文档的解释使我期望glTexImage2D在读取数据时将字节交换数据,如果源和内部格式不同,但是当我尝试指定“内部格式”时,我得到一个OpenGL错误0x500(GL_INVALID_ENUM) GL_RGBA。我错过了什么?     
已邀请:
我不知道将ARGB数据直接加载到纹理中的方法,但有一个更好的解决方法,而不仅仅是在CPU上进行调配。你可以在GPU上非常有效地做到: 将ARGB数据加载到临时RGBA纹理中。 使用此纹理绘制全屏四边形,同时使用简单的像素着色器渲染到目标纹理。 继续加载其他资源,无需停止GPU管道。 像素着色器示例:
#version 130
uniform sampler2DRect unit_in;
void main() {
    gl_FragColor = texture( unit_in, gl_FragCoord.xy ).gbar;
}
    
你用OpenGL渲染它,对吧? 如果你想以简单的方式做到这一点,你可以让你的像素着色器实时调配颜色。这对于显卡来说完全没问题,它们可以做更复杂的东西:)。 你可以使用这样的着色器:
uniform sampler2D image;
void main()
{
    gl_FragColor = texture2D(image, gl_FragCoord.xy).gbar;
}
如果您不了解着色器,请在此处阅读此内容:http://www.lighthouse3d.com/opengl/glsl/     
这个问题很老,但万一其他人正在寻找这个问题,我找到了一个不是严格安全但有效的解决方案。问题是每个32位RGBA值都有A作为第一个字节而不是最后一个字节。 NBitmapImageRep.bitmapData为您提供指向第一个字节的指针,您将该字符作为指向其像素的指针提供给OpenGL。只需将1添加到该指针,然后以正确的顺序指向RGB值,最后使用下一个像素的A. 这样做的问题是,最后一个像素将从图像末尾的一个字节取A值,A值全部为一个像素。但是就像提问者一样,我在加载JPG时得到了这个,所以alpha无论如何都是无关紧要的。这似乎不会导致问题,但我不会声称它“安全”。     

要回复问题请先登录注册