【发布时间】:2012-09-04 19:55:24
【问题描述】:
我在 Android 模拟器上遇到纹理损坏问题(它在大多数 Android 设备上运行良好)。
上图是运行Android 4.1 Jelly Bean的模拟器生成的参考渲染图,一切正常。
第二张图片是在运行 Android 1.6 的模拟器中捕获的。注意一些被禁用的工具栏按钮的损坏(它们以颜色 1f,1f,1f,0.5f 呈现)
第三张图片是在同一个模拟器中拍摄的。不同的是,现在分数是在右上角呈现的。 Score 是一种位图字体,它的纹理是一个 alpha 蒙版。得分后渲染的所有内容都失去了它的纹理。请注意,之前的屏幕截图还包含以相同方式渲染的位图字体(但使用不同的纹理)。
其中一台三星设备存在类似问题(我不记得型号)。渲染地板纹理时,在丢失纹理之后渲染的所有内容。当我 a) 没有绑定纹理 b) 确实绑定了纹理,但没有使用它绘制三角形 c) 从头开始重新创建 png 资源时,问题并没有表现出来。
Opengl 设置:
gl.glDisable(GL10.GL_LIGHTING);
gl.glDisable(GL10.GL_CULL_FACE);
gl.glDisable(GL10.GL_DEPTH_TEST);
gl.glDisable(GL10.GL_DITHER);
gl.glDepthMask(false);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glBlendFunc(GL10.GL_ONE,GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glShadeModel(GL10.GL_FLAT);
gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_MODULATE);
如何加载纹理:
public void doGLLoading(Engine renderer) {
GL10 gl=renderer.getGl();
int[] ids=new int[1];
gl.glGenTextures(1, ids,0);
id=ids[0];
gl.glBindTexture(GL10.GL_TEXTURE_2D, id);
Log.d("SpriteDraw", String.format("Texture %s has format %s",getPath(),bitmap.getConfig().toString()));
buildMipmap(gl, bitmap);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER, minFilter);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER, magFilter);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_S, textureWrapS);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_T, textureWrapT);
}
private void buildMipmap(GL10 gl, Bitmap bitmap) {
int level = 0;
int height = bitmap.getHeight();
int width = bitmap.getWidth();
while (height >= 1 || width >= 1) {
// First of all, generate the texture from our bitmap and set it to
// the according level
//TextureUtils.texImage2D(gl, GL10.GL_TEXTURE_2D, level, -1, bitmap, -1, 0);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, level, bitmap, 0);
if (height == 1 || width == 1) {
break;
}
// Increase the mipmap level
level++;
height /= 2;
width /= 2;
Bitmap bitmap2 = Bitmap.createScaledBitmap(bitmap, width, height,
true);
// Clean up
bitmap.recycle();
bitmap = bitmap2;
}
}
注意:字体使用gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); 和GL10.glDrawArrays 渲染。损坏不仅影响 1.6 模拟器,还影响 android 的 2.x 系列,尽管它没有那么突出(alpha 掩码仍然呈现不正确)。所有资源都正确加载为两个位图的幂。
【问题讨论】:
-
纹理维度是二的幂吗?你用的是superPng还是Png?正常的 png 文件不会正确地将 alpha 保留为掩码。但 superPng 可以保留它。存在用于导出为 superPng 的 Photoshop 插件
-
是的,它们都是二的力量(在帖子末尾提到)。位图存储为灰度位图,由 android 加载为 ARGB_8888,并由我的代码转换为 alpha 掩码。
标签: android opengl-es android-emulator