La textura transparente de Android OpenGL dibuja negro

Estoy tratando de dibujar texturas transparentes (texto) en mi aplicación. Curiosamente, funciona en el nuevo Nexus 7 y en mi segunda generación de Moto X, pero en el Nexus 7 original las texturas son sólo negras. Tengo la mezcla habilitada y la textura es 512×512 por lo que no es un problema de poder-de-dos. También estoy usando GL10 que debe ser apoyado en todo, ¿verdad? Cualquier razón las texturas no funcionaría en sólo este dispositivo?

gl.glEnable(GL10.GL_BLEND); gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); gl.glEnable(GL10.GL_TEXTURE_2D); // text drawn here gl.glDisable(GL10.GL_TEXTURE_2D); gl.glDisable(GL10.GL_BLEND); 

Y aquí está la inicialización de la textura, donde carga el atlas de texturas:

 public void loadGlyphs(GL10 gl, Context context) { Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.text_bitmap); gl.glGenTextures(1, textures, 0); gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); bitmap.recycle(); } 

Top muestra lo que sucede en el viejo Nexus 7. La imagen de abajo es un Moto X.

Malo

Bueno

Edit: He aquí un ejemplo completo. No hay transparencia, no dibuja nada en el viejo Nexus 7. Si me deshago de la materia de textura que dibuja el cuadrado en blanco como debería.

MainActivity.java

 import android.app.Activity; import android.opengl.GLSurfaceView; import android.os.Bundle; public class MainActivity extends Activity { private GLSurfaceView glView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); glView = new TestView(this); setContentView(glView); } @Override protected void onPause() { super.onPause(); glView.onPause(); } @Override protected void onResume() { super.onResume(); glView.onResume(); } } 

TestView.java

 import android.content.Context; import android.opengl.GLSurfaceView; public class TestView extends GLSurfaceView { private TestRenderer renderer; public TestView(Context context) { super(context); renderer = new TestRenderer(context); setRenderer(renderer); } } 

TestRenderer.java

 import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.opengl.GLSurfaceView; import android.opengl.GLU; import android.opengl.GLUtils; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; public class TestRenderer implements GLSurfaceView.Renderer { private FloatBuffer floatBuffer; private FloatBuffer textureBuffer; private Context context; private int[] textures; public TestRenderer(Context context) { this.context = context; textures = new int[1]; } public void onSurfaceCreated(GL10 gl, EGLConfig config) { floatBuffer = ByteBuffer.allocateDirect(4 * 2 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); floatBuffer.put(-0.5f); floatBuffer.put(-0.5f); floatBuffer.put(-0.5f); floatBuffer.put(0.5f); floatBuffer.put(0.5f); floatBuffer.put(-0.5f); floatBuffer.put(0.5f); floatBuffer.put(0.5f); floatBuffer.rewind(); textureBuffer = ByteBuffer.allocateDirect(4*2*4).order(ByteOrder.nativeOrder()).asFloatBuffer(); textureBuffer.put(0); textureBuffer.put(1); textureBuffer.put(0); textureBuffer.put(0); textureBuffer.put(1); textureBuffer.put(1); textureBuffer.put(1); textureBuffer.put(0); textureBuffer.rewind(); Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.test); gl.glGenTextures(1, textures, 0); gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); bitmap.recycle(); } public void onSurfaceChanged(GL10 gl, int w, int h) { gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); GLU.gluPerspective(gl, 45.0f, (float) w / (float) h, 0.1f, 100.0f); gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); } public void onDrawFrame(GL10 gl) { gl.glLoadIdentity(); gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.glClear(GL10.GL_COLOR_BUFFER_BIT); gl.glTranslatef(0.0f, 0.0f, -5.0f); gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); gl.glEnable(GL10.GL_TEXTURE_2D); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); gl.glFrontFace(GL10.GL_CW); gl.glVertexPointer(2, GL10.GL_FLOAT, 0, floatBuffer); gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer); gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); gl.glDisable(GL10.GL_TEXTURE_2D); } } 

Edit: He aquí un ejemplo que encontré en línea. Si desactivo GL_TEXTURE_2D obtengo un cuadrado blanco. Si habilito GL_TEXTURE_2D no obtengo nada.

MainActivity clase pública MainActivity extends Actividad {

  private GLSurfaceView glSurfaceView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); glSurfaceView = new GLSurfaceView(this); glSurfaceView.setRenderer(new GlRenderer(this)); setContentView(glSurfaceView); } @Override protected void onResume() { super.onResume(); glSurfaceView.onResume(); } @Override protected void onPause() { super.onPause(); glSurfaceView.onPause(); } } 

Glander

 public class GlRenderer implements Renderer { private Square square; private Context context; public GlRenderer(Context context) { this.context = context; this.square = new Square(); } @Override public void onDrawFrame(GL10 gl) { gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); gl.glLoadIdentity(); gl.glTranslatef(0.0f, 0.0f, -5.0f); square.draw(gl); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { if(height == 0) { height = 1; } gl.glViewport(0, 0, width, height); gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 0.1f, 100.0f); gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { square.loadGLTexture(gl, this.context); gl.glEnable(GL10.GL_TEXTURE_2D); gl.glShadeModel(GL10.GL_SMOOTH); gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); gl.glClearDepthf(1.0f); gl.glEnable(GL10.GL_DEPTH_TEST); gl.glDepthFunc(GL10.GL_LEQUAL); gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); } } 

Cuadrado

 public class Square { private FloatBuffer vertexBuffer; private float vertices[] = { -1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f }; private FloatBuffer textureBuffer; private float texture[] = { 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f }; private int[] textures = new int[1]; public Square() { ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4); byteBuffer.order(ByteOrder.nativeOrder()); vertexBuffer = byteBuffer.asFloatBuffer(); vertexBuffer.put(vertices); vertexBuffer.position(0); byteBuffer = ByteBuffer.allocateDirect(texture.length * 4); byteBuffer.order(ByteOrder.nativeOrder()); textureBuffer = byteBuffer.asFloatBuffer(); textureBuffer.put(texture); textureBuffer.position(0); } public void loadGLTexture(GL10 gl, Context context) { Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.test); gl.glGenTextures(1, textures, 0); gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); bitmap.recycle(); } public void draw(GL10 gl) { gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); gl.glFrontFace(GL10.GL_CW); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer); gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer); gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3); gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); } } 

¿Qué formato de color es su textura está usando? ¿Concuerda con el formato de color que espera su shader?

Si su formato de color es RGBA8888 y el shader espera RGB256 puede obtener problemas como este. (Se buscará la información del canal alfa en el lugar equivocado)

Después de mucha solución de problemas, pude resolver el problema en ambos dispositivos (y presumiblemente todos los dispositivos) agregando la textura que envuelve como si:

 gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE); 

No estoy seguro de por qué esto era necesario para dos dispositivos, pero no los otros dos, sin embargo.

  • Vista superficial en capas en un FrameLayout en Android
  • Cómo hacer un fondo 20% transparente en Android
  • ¿Cómo hacer que el botón no sea transparente?
  • Superposición transparente GLSurfaceview en la vista existente en android?
  • ImageButton no se resalta en hacer clic con fondo transparente
  • Imagen de png que aparece con fondo gris en android
  • Descripción de los colores en Android (seis caracteres)
  • Transparencia hexagonal en colores
  • Cambiar la opacidad del color int en java / android
  • El tema translúcido no funciona cuando se programa mediante programación en Android 2.3.3 o 4.2
  • Android AlertDialog con fondo transparente
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.