在标题中,我在Android(7.0)上使用OpenGL ES(2)。 显然,在尝试从资产文件夹加载纹理时遇到一些问题。 这是我使用
的代码public static int loadTexture(final AssetManager assetManager, final String img)
{
final int[] textureHandle = new int[1];
glGenTextures(1, textureHandle, 0);
if(textureHandle[0] == 0)
throw new RuntimeException("Error loading texture");
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false;
try
{
final Bitmap bitmap = BitmapFactory.decodeStream(assetManager.open(img));
glBindTexture(GL_TEXTURE_2D, textureHandle[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
GLUtils.texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
}
catch (IOException e)
{
e.printStackTrace();
}
textures.put(img, textureHandle[0]);
return textureHandle[0];
}
这是从onSurfaceCreated
调用的,因为我知道我需要一个正在运行的OpenGL上下文
大部分时间这都有效并给我这个结果
但其他相当多的时间我得到了这个
没有抛出异常。
我知道问题不依赖于3D模型和纹理,因为我已尝试过其他问题。发生这种情况时我唯一能做的就是重启我的应用程序几次。
我试过谷歌搜索但没有结果。我知道我可以尝试实现另一个加载功能,但首先我想了解为什么这不好,以及它无法正常工作。
如果你认为这可能取决于我用来渲染场景的代码,那就是(没有VAO,因为我需要支持旧设备和OpenGL ES 2):
glBindBuffer(GL_ARRAY_BUFFER, model.getCoordsVBO());
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, model.getTextureVBO());
glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, 0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, model.getNormalsVBO());
glVertexAttribPointer(2, 3, GL_FLOAT, false, 0, 0);
glEnableVertexAttribArray(2);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, entity.getTexture());
loadFloat(loc_textureSampler, 0);
if(model.getIndicesBuffer() != null)
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model.getIndicesVBO());
glDrawElements(GL_TRIANGLES, model.getVertexCount(), GL_UNSIGNED_INT, 0);
}
else
glDrawArrays(GL_TRIANGLES, 0, model.getVertexCount());
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
答案 0 :(得分:1)
我没有说(因为我认为这是无关紧要的)是我在功能的顶部添加了一些代码......
if(textures.containsKey(img))
return textures.get(img);
并在底部
textures.put(img, textureHandle[0]);
我认为跟踪纹理是很聪明的,所以我可以随时调用这个加载函数,如果我已经加载它,它会返回它而不再加载。
这可能适用于桌面应用程序,但我还没有考虑到在Android上垃圾收集器可以在退出应用程序时从OpenGL中删除纹理,以便当活动重新启动时它不会在那里了。
删除HashMap
解决了问题,证明实际的读取和加载代码与黑色事物无关。