gpt4 book ai didi

glTexImage2D 的 android 位图像素格式

转载 作者:太空宇宙 更新时间:2023-11-03 13:16:52 24 4
gpt4 key购买 nike

我正在尝试使用 Bitmap 类从 Java 加载纹理以与 NDK OpenGL 一起使用。它可以工作,但我在像素格式方面遇到了问题。

首先,在 Java 中,我像这样从 assets 文件夹加载位图:

Bitmap bitmap = BitmapFactory.decodeStream(amgr.open(path));
return bitmap.copy(Bitmap.Config.ARGB_8888, false);

位图配置没有 RGBA channel 顺序选项。

[JNI 事情发生在这里]

使用 GLES 1,然后我像这样缓冲纹理:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
// `pixels` is the pixel buffer I produced earlier.

如您所见,像素格式存在问题。 glTexImage2D 没有 ARGB 选项,但 Java Bitmap 类没有创建 RGBA 缓冲区的选项。所以我最终搞砸了颜色 channel 。顺便说一下,我确实需要 alpha channel 。

问题是:如何最有效地从 Java 位图类生成 RGBA8888 格式的像素缓冲区,或者如何加载 ARGB8888 格式的 GL 纹理?

除了手动逐个像素交换字节之外,肯定还有其他方法吗?

我目前正在这样做:

void pxl::swap_channels_ARGB_to_RGBA(void *pixBuf, const int len)
{
jint *pixels = (jint *)pixBuf;

for(int i = 0; i < len; i++)
{
jint pixel = pixels[i];

jint a = (pixel >> 24) & 0xFF;
jint r = (pixel >> 16) & 0xFF;
jint g = (pixel >> 8) & 0xFF;
jint b = (pixel >> 0) & 0xFF;

pixels[i] = (jint)(a | (r << 24 ) | (g << 16) | (b << 8));
}
}

或者可能还有其他错误?老实说,不太确定 glTexImage2D 选项。

谢谢!

最佳答案

此问题无法在 OpenGL ES 1.1 中解决,但在 OpenGL ES 3.0 中或通过 OpenGL 扩展可以解决 EXT_texture_swizzle :

从 OpenGL ES 3.0 开始,您可以使用纹理混合参数来交换颜色 channel 。参见 glTexParameter :

GL_TEXTURE_SWIZZLE_R

Sets the swizzle that will be applied to the r component of a texel before it is returned to the shader. Valid values for param are GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_ZERO and GL_ONE. If GL_TEXTURE_SWIZZLE_R is GL_RED, the value for r will be taken from the first channel of the fetched texel. If GL_TEXTURE_SWIZZLE_R is GL_GREEN, the value for r will be taken from the second channel of the fetched texel. ...

这意味着当您为纹理对象设置以下纹理参数时,查找纹理时将交换颜色 channel :

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_GREEN);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_BLUE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_ALPHA);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);


规范中的相关部分可以在 OpenGL ES 3.0.5 Specification; 3.8.14 Texture State; page 162 找到。

要检查 OpenGL 扩展是否有效,glGetString(GL_EXTENSIONS)可以使用,它返回以空格分隔的支持扩展列表。



一个完全不同的解决方案是使用 Canvas为转换。绘制 Bitmap在 Canvas 上,然后使用 Canvas 持有的目标位图。
我在 GitHub 上找到了这个解决方案:fix android 2.3 can't decode bitmap in rgba8888 format

public static Bitmap convert(Bitmap bitmap, Bitmap.Config config) {
Bitmap convertedBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), config);
Canvas canvas = new Canvas(convertedBitmap);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
canvas.drawBitmap(bitmap, 0, 0, paint);
return convertedBitmap;
}

关于glTexImage2D 的 android 位图像素格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34705921/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com