2016-01-10 2 views
0

J'essaie de charger des textures à utiliser avec NDK OpenGL à partir de Java avec la classe Bitmap. Cela fonctionne, mais j'ai des problèmes avec le format de pixel.Format de pixel bitmap android pour glTexImage2D

D'abord, en Java, je charge un bitmap de l'actif dossier comme celui-ci:

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

la configuration bitmap ne dispose pas d'option pour l'ordre de canal RGBA.

[les choses se passent ici JNI]

En utilisant GLES 1, je tampon puis la texture comme ceci:

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

Comme vous pouvez le voir, il y a un problème avec le format de pixel. glTexImage2D n'a pas d'option pour ARGB, mais la classe Java Bitmap n'a pas d'option pour créer un tampon en RGBA. Donc, je me retrouve avec des canaux de couleur foiré. J'ai besoin du canal alpha en passant. La question est: comment puis-je produire le plus efficacement un tampon de pixels au format RGBA8888 à partir de la classe bitmap Java, ou comment charger une texture GL au format ARGB8888?

Il existe sûrement un moyen autre que d'échanger manuellement des octets pixel par pixel?

Je suis en train de faire ceci:

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

Ou peut-être il y a une autre erreur? Pas vraiment sûr des options glTexImage2D pour être honnête.

Merci!

+0

Avez-vous besoin de faire l'appel glTexImage2D sur le côté JNI? Alternativement, vous pouvez le télécharger sur le côté Java en utilisant GLUtils.texImage2D et simplement passer l'ID de texture comme un int sur JNI. – samgak

+0

merci, mais oui j'essaie de garder toutes les choses GL en C++. Cela fonctionne pour moi avec l'échange manuel, était juste curieux s'il y a une solution plus élégante. – spinalwrap

+0

Je suis curieux aussi, parce que le [code source pour GLUtils] (https://github.com/android/platform_frameworks_base/blob/master/core/jni/android/opengl/util.cpp) ne fait aucun échange mais ça marche. Cela fonctionne en passant l'objet Bitmap à JNI en tant que jobject et en appelant getPixels(). Vérifiez la fonction util_texImage2D. – samgak

Répondre

1

Je pense qu'il n'y a pas de méthode pour le faire, mais vous pouvez optimiser votre algorithme avec ce

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

}