2010-10-13 24 views
5

Estoy generando con éxito mis texturas usando GLUtils.texImage2D, pero cuando uso las texturas generadas obtengo problemas con mi alfa: son más oscuras de lo deseado.Problemas con GLUtils.texImage2D y Alpha en Texturas

después de haber verificado varias cosas, finalmente obtuve la conclusión de que el problema proviene de GLUtils.texImage2D (GL10.GL_TEXTURE_2D, level, bmp, 0);

Creé una segunda función que utiliza gl.glTexImage2D (GL10.GL_TEXTURE_2D, nivel, GL10.GL_RGBA, ancho, alto, 0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, pixels2);

pero es costoso en el proceso crear pixels2 que es un bytebuffer en el que tengo que volver a copiar los bytes mientras cambio los valores del mapa de bits ARGB a la textura RGBA.

¿Alguien ha notado eso? y si es así ¿cómo resolver este ...

Jason


Gracias por su respuesta, ya estoy usando

gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); 

y me estoy poniendo este problema

mi problema es que el alfa generado por GLUtils no es el de la textura, es más oscuro.

la diferencia es como mirar un color en el sol y en la sombra (si eso hace cualquier sentido).

ya he intentado gl.gltextimage2d pero la creación de la memoria intermedia de toma demasiado tiempo, a menos que exista una herramienta para convertir un mapa de bits en una memoria intermedia de bytes que no conozco ...

Respuesta

3

El canal alfa es el hijastro pobremente maltratado de un gran número de programadores es todo lo que puedo decir ...pero la carga funciona bastante eficiente si se hace eso:

  • Estimación su textura más grande (como 1024x1024) y crear una matriz int de ese tamaño (1024 * 1024) que almacena en una variable estática o en algún lugar donde se se puede acceder a ella de manera que no es necesario para recrear esa matriz (la asignación del tiempo es muy valioso aquí)

  • continuación, haga lo siguiente:

    bitmap.getPixels(pixels, 0, width, 0, 0, width, height); 
    gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, width, height, 
        0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, IntBuffer.wrap(pixels)); 
    

lo siento no tener encontró una solución diferente ... el problema original es que el implementador de la función GLUtils.texImage2D ha maltratado el canal alfa de alguna manera, dando como resultado bordes negros cuando la imagen se muestra más grande de lo que es (el filtro bilineal calcula el color entre cuatro píxeles y cuando los valores de rgb de los píxeles con alfas transparentes han sido mutilados (como en negro), el resultado es que ocurre una especie de "sangrado de color" sobre el borde transparente que se está formando allí. Muy feo. Tal vez se hizo para mejorar la relación de compresión ya que los valores RGB en áreas alfa transparente en PSD contienen una gran cantidad de basura que cuando se eliminan producen mucho margen de mejora para los algoritmos de compresión)

Editar: Lamentablemente, este enfoque fue solo trabajando correctamente para las imágenes grises, ya que el canal rojo y azul se intercambian cuando se buscan los píxeles del mapa de bits. Al menos en MI dispositivo. No estoy seguro de cómo correctamente esto es para otros dispositivos, pero en mi caso, esto aquí hice el truco:

for (int i=0;i<pixels.length;i+=1) { 
    int argb = pixels[i]; 
    pixels[i] = argb&0xff00ff00 | ((argb&0xff)<<16) | ((argb>>16)&0xff); 
} 
0

hay un temas en GLUtils con alpha premultiplicado La única solución que puedo proponer es utilizar:

gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA) 

En caso de que necesite otras funciones de mezcla que tendrá que utilizar gl.glTexImage2D.

5

GLUtils.texImage2D genera una textura alfa premultiplicada. En esta textura generada, todos los píxeles se multiplican por el valor alfa, por lo que no es necesario multiplicar el valor alfa una vez más. Probemos

gl.glBlendFunc (GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);

1

Android Bitmap almacena las imágenes cargadas desde PNG con colores premultiplicados. GLUtils.texImage2D también usa colores premultiplicados por alfa, por lo que no puede obtener los colores originales de esta manera.

el fin de cargar las imágenes PNG sin RGB canales que se están premultiplicados utilizo tercera parte PNGDecoder y la textura de carga con glTexImage2D. Puede obtener PNGDecoder biblioteca para decodificar PNG desde aquí: http://twl.l33tlabs.org/#downloads

3

solución se encuentra here. Se relaciona como lo afirman otros con alfa premultiplicado.

En el SurfaceView Constructor

setEGLConfigChooser(8, 8, 8, 8, 0, 0); 
    getHolder().setFormat(PixelFormat.RGBA_8888); 

En el View.Renderer onSurfaceCreated

gl.glEnable(GL10.GL_BLEND); 
    gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);