我使用Open GL ES(1.1)为Android做了一个非常漂亮的测试游戏。为了简单和方便处理纹理,我使用包含以下方法的类来封装必要的gl-operations(在代码中我使用了一些自己的附加类):
public void load() {
GL10 gl = glGraphics.getGL();
int[] textureIds = new int[1];
gl.glGenTextures(1, textureIds, 0);
textureId = textureIds[0];
InputStream in = null;
try {
in = fileIO.readAsset(fileName);
Bitmap bitmap = BitmapFactory.decodeStream(in);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);
bitmap.recycle();
}
catch(IOException e) {
throw new RuntimeException("Couldn't load texture '" + fileName + "'", e);
}
finally
{
if(in != null)
{
try {
in.close();
}
catch (IOException e) { }
}
}
}
public void reload() {
load();
setFilters(minFilter, magFilter);
glGraphics.getGL().glBindTexture(GL10.GL_TEXTURE_2D, 0);
}
public void setFilters(int minFilter, int magFilter) {
this.minFilter = minFilter;
this.magFilter = magFilter;
}
public void bind() {
GL10 gl = glGraphics.getGL();
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, minFilter);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, magFilter);
}
public void dispose() {
GL10 gl = glGraphics.getGL();
gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);
int[] textureIds = { textureId };
gl.glDeleteTextures(1, textureIds, 0);
}
开始使用一些纹理我加载()它。当我想绘制一个精灵时,我使用方法bind()作为纹理。当上下文可能丢失时,我使用方法reload()。当我对纹理说再见时,我称之为dispose()。
我同时使用两个纹理图集1136 x 640(其中一个包含播放元素,另一个包含背景)。为了避免无聊,当用户离开开始游戏菜单并再次进入游戏本身时,地图集会切换到两个类似的地图集以其他方式着色。
问题在于,如果用户经常这样做,那么每次游戏加载越来越慢,并且几次(5-7)崩溃。处理方法及时工作,整个类的方法finalize()及时工作。
你有什么想法吗?
答案 0 :(得分:0)
很难说你给出的信息,但你可能已经没有记忆了。你在这个过程中是否正在调用reload()方法?我注意到的一件事是你的reload()方法将创建一个全新的纹理副本,而不会删除以前的副本。
总结:确保对glGenTextures
的每次通话与对glDeleteTextures
的通话配对。对重载方法的一个简单但缓慢的修复方法是:
public void reload() {
// call dispose() before load()
dispose();
load();
// ...
}
但更安全的解决方法是,如果再次调用load(),只需替换先前分配的纹理的内容。在load()方法中,如果已分配纹理Id,则跳过对glGenTextures
的调用。像这样:
// initialize texture id
private int textureId = 0;
public void load() {
// ...
// only allocate texture if needed
if (textureId == 0) {
int[] textureIds = new int[1];
gl.glGenTextures(1, textureIds, 0);
textureId = textureIds[0];
}
// ...
}
public void dispose() {
// ...
// delete texture if allocated, and
// set the id to zero
if (textureId != 0) {
int[] textureIds = { textureId };
gl.glDeleteTextures(1, textureIds, 0);
textureId = 0;
}
// ...
}
我还建议尝试使用两种纹理(即1024x512而不是1136x640)。我已经看到一些芯片/驱动程序存在非POT纹理的无证问题。