glteximage2d的Android位图像素格式

 2023-01-20    326  

问题描述

我正在尝试加载纹理,以与java一起使用bitmap类与NDK OpenGL一起使用.它有效,但是我的像素格式有问题.

首先,在Java中,我从这样的资产文件夹中加载了一个位图:

glteximage2d的Android位图像素格式

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

位图配置没有RGBA频道顺序的选项.

[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位图类没有在RGBA中创建缓冲区的选项.因此,我最终弄乱了颜色通道.顺便说一句,我确实需要alpha频道.

问题是:如何最有效地从Java Bitmap类中以RGBA88888格式产生像素缓冲区,或者如何以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,您可以使用纹理swizzle参数来交换颜色通道.请参阅 >

GL_TEXTURE_SWIZZLE_R

设置将在将其返回到着色器之前将其应用于Texel的R组件.参数的有效值为GL_RED,GL_GREEN,GL_BLUE,GL_ALPHA,GL_ZERO和GL_TEXTURE_SWIZZLE_R.如果GL_TEXTURE_SWIZZLE_R是GL_RED,则R的值将从被提取的Texel的第一个通道中获取.如果GL_TEXTURE_SWIZZLE_R是GL_GREEN,则R的值将取自获取的Texel的第二个通道. …

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

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);

可以在 openggl es es openggl es es es openggl es es eS openggl es es es openggl es es eS openg, 3.0.5规格; 3.8.14纹理状态;第162页

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


一个完全不同的解决方案是使用 Canvas 转换.绘制android.com/reference/android/graphics/bitmap#copy(画布,然后使用目标位图,该目标位图由画布保留.
我在github上找到了这种解决方案: fix android 2.3无法在RGBA888888888的格式中解码 p>

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;
}

其他推荐答案

我认为没有方法可以这样做,但是您可以使用此

优化算法

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

    for(int i = 0; i < len; i++) {
        unsigned int aux = (int)pixels[i];
        pixels[i] = (aux << 8) | (aux >> 24);
    }

}

以上所述是小编给大家介绍的glteximage2d的Android位图像素格式,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!

原文链接:https://77isp.com/post/26118.html

=========================================

https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。