java - OpenGL ES Android - 未加载纹理(呈现黑色)

标签 java android opengl-es textures

如标题所示,我在 Android (7.0) 上使用 OpenGL ES (2)。 不过,显然,我在尝试从 Assets 文件夹加载纹理时遇到了一些问题。 这是我正在使用的代码

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 上下文

大多数时候这是有效的并给我这个结果

working texture

但是很多时候我都得到了这个

enter image description here

没有抛出异常。

我知道问题不在于 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);

最佳答案

我没有说的(因为我认为这是无关紧要的)是我在函数顶部添加了一些代码...

if(textures.containsKey(img))
    return textures.get(img);

在底部

textures.put(img, textureHandle[0]);

我认为跟踪纹理是明智的,所以我可以在需要纹理的任何时候调用这个加载函数,如果我已经加载它,它会返回它而不会再次加载。

这可以在桌面应用程序上工作,但我没有考虑过在 Android 上垃圾收集器可以在我退出应用程序时从 OpenGL 中删除纹理,这样当 Activity 重新启动时它就不会再存在了。

去掉那个HashMap就解决了问题,说明实际的读取和加载代码与那个黑东西无关。

关于java - OpenGL ES Android - 未加载纹理(呈现黑色),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49706709/

相关文章:

c++ - GLSL 着色器正在编译,但程序未链接

java - 在eclipse中将简单的java项目转换为maven项目后出现NoClassDefFoundError

java - 删除用户输入的信息

java - Axis2 文件分块上传

android - 如何获得专辑封面? ALBUM_ART 列索引为 -1

ios - 渲染到纹理 : always black texture

java - 当使用大量引用(如 PIXELS_PER_INCH = 72)时,如何使用函数减少我的代码?

android - 如何在 ListView 中制作一个始终位于顶部的部分标题?

android - UnsatisfiedLinkError for libopencv_core.so while .apk holds this library

android - Android 上的颜色选择 - glReadPixels 舍入错误