Android OpenGL透明纹理绘制黑色

我正试图在我的应用程序中绘制透明纹理(文本)。 奇怪的是,它适用于最新的Nexus 7和我的第二代Moto X,但在最初的Nexus 7上,纹理只是黑色。 我已启用混合,纹理为512×512,因此它不是二次幂的问题。 我也只是使用GL10,应该支持所有东西,对吗? 纹理不能仅仅在这个设备上工作的任何原因?

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

这是纹理初始化,我加载纹理图集:

 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显示旧Nexus 7上发生的情况。底部图片是Moto X.

坏

好

编辑:这是一个完整的例子。 没有透明度,不会在旧的Nexus 7上绘制任何东西。如果我摆脱纹理的东西,它就像它应该的那样绘制白色的正方形。

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

编辑:这是我在网上find的一个例子。 如果我禁用GL_TEXTURE_2D,我会得到一个白色方块。 如果我启用GL_TEXTURE_2D,我什么也得不到。

MainActivity公共类MainActivity扩展Activity {

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

GlRenderer

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

广场

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

你的纹理使用什么颜色格式? 它是否与着色器所期望的颜色格式相匹配?

如果您的颜色格式是RGBA8888并且着色器需要RGB256,您可能会遇到这样的问题。 (它会在错误的地方查找alpha通道信息)

经过多次故障排除后,我能够通过添加纹理包装来解决这两个设备(可能是所有设备)的问题:

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

我不确定为什么这对于两个设备是必要的,但不是另外两个设备。