Android OpenGL纹理:动态创建和删除它们

Vin*_*rat 5 android textures opengl-es loading

我目前正在实现一个3D查看器,它基本上呈现用户在SD卡上的所有图像的子集.我想到的最接近的匹配产品是CoolIris:

在此输入图像描述

它只是在屏幕上显示N个图块的滚动板,每个图块显示不同的图像,新的图块进入屏幕并显示新图像.

现在我的问题是:我让程序工作并且很好地渲染了四边形.当四边形离开屏幕时,它会被回收/释放.并且新的四边形在进入屏幕之前不断添加到瓷砖板.

因为可能有数百个图像,所以需要动态创建和删除纹理(这样我们就不会耗尽内存).我遇到的问题是,在删除纹理后,新创建的纹理似乎会获得当前正在使用的其他纹理的ID.

我的渲染循环如下所示:

void render(GL10 gl) {
  0. Move the camera

  // Tile board maintenance
  1. Remove tiles out of screen
  2. Add new tiles which are about to enter screen

  // Texture handling
  3. glDeleteTextures on all unused textures followed by glFlush
  4. For newly used images
     - Create corresponding Bitmap
     - Create the OpenGL texture, followed by glFlush
     - Release the Bitmap

  // Rendering
  5. Render the tile (using a textured quad)

}
Run Code Online (Sandbox Code Playgroud)

为了更好地了解数据的组织方式,以下是类的概述:

TileBoard {
  Image[] allImages;
  Tile[] board;
}

Tile {
  Image image;
}

Image {
  String path;
  int textureId;
  int referenceCount;
}
Run Code Online (Sandbox Code Playgroud)

纹理创建代码:

protected void loadSingleTexture(GL10 gl, long objectId, Bitmap bmp) {
    int[] textures = new int[1];
    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_LINEAR);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
    gl.glFlush();

    if (bmp != null) bmp.recycle();

    if (listener != null) listener.onTextureLoaded(gl, objectId, textures[0]);
}
Run Code Online (Sandbox Code Playgroud)

纹理删除代码:

// pendingTextureUnloads is a Set<Integer>
if (pendingTextureUnloads.size() > 0) {
  int[] textureIds = new int[pendingTextureUnloads.size()];
  int i = 0;
  Iterator<Integer> it = pendingTextureUnloads.iterator();
  while (it.hasNext()) {
    textureIds[i] = it.next();
  }

  gl.glDeleteTextures(textureIds.length, textureIds, 0);
  gl.glFlush();
}
Run Code Online (Sandbox Code Playgroud)

Vin*_*rat 5

我已经解决了这个问题:问题是你必须将纹理数组传递给glGenTextures并重用它.

以下是具有相同问题的修改后的概述:

Image {
  String path;
  int[] textureIds;
  int referenceCount;
}
Run Code Online (Sandbox Code Playgroud)

纹理创建代码:

// Notice that I don't allocate the int[] at the beginning but use the one of the image
protected void loadSingleTexture(GL10 gl, Image img, Bitmap bmp) {
    gl.glGenTextures(1, img.textureIds, 0);
    gl.glBindTexture(GL10.GL_TEXTURE_2D, img.textureIds[0]);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
    gl.glFlush();

    if (bmp != null) bmp.recycle();
}
Run Code Online (Sandbox Code Playgroud)

纹理删除代码:

foreach Image img {
  gl.glDeleteTextures(img.textureIds.length, img.textureIds, 0);
}
gl.glFlush();
Run Code Online (Sandbox Code Playgroud)