2012-03-13 30 views
5

Tôi hiện đang triển khai trình xem 3D cơ bản hiển thị một tập hợp con của tất cả hình ảnh mà người dùng có trên Thẻ SD của mình. Các sản phẩm phù hợp nhất Tôi sẽ nghĩ đến sẽ là Cooliris:Kết cấu OpenGL trên Android: tạo và xóa chúng khi đang bay

enter image description here

Nó chỉ đơn giản hiển thị một bảng cuộn của N gạch trên màn hình, mỗi hiển thị hình ảnh khác nhau, với gạch mới vào màn hình và hiển thị hình ảnh mới.

Bây giờ cho vấn đề của tôi: Tôi có chương trình làm việc và hiển thị độc đáo các quad. Khi một quad đi ra khỏi màn hình, nó được tái chế/phát hành. Và quads mới tiếp tục được thêm vào bảng gạch trước khi họ nhập vào màn hình.

Vì có thể có hàng trăm hình ảnh, kết cấu cần phải được tạo và xóa khi đang di chuyển (để chúng tôi không hết bộ nhớ). Vấn đề tôi có là sau khi tôi xóa kết cấu, các hoạ tiết mới tạo dường như nhận được một số ID của các hoạ tiết khác hiện đang được sử dụng.

loop vẽ của tôi trông như thế này:

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) 

} 

Để cung cấp cho một ý tưởng tốt hơn về dữ liệu được tổ chức như thế nào, đây là một tổng quan về các lớp:

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

Tile { 
    Image image; 
} 

Image { 
    String path; 
    int textureId; 
    int referenceCount; 
} 

mã tạo Texture:

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]); 
} 

Mã xóa kết cấu:

// 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(); 
} 
+0

Đã thử gọi glGetError ở bất kỳ đâu? – Tim

Trả lời

5

Tôi đã giải quyết được sự cố: vấn đề là bạn phải giữ mảng kết cấu được chuyển tới glGenTextures và sử dụng lại nó.

Dưới đây là tổng quan về sửa đổi cho những người sẽ có cùng một vấn đề: Mã tạo

Image { 
    String path; 
    int[] textureIds; 
    int referenceCount; 
} 

Texture:

// 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(); 
} 

Texture đang xóa:

foreach Image img { 
    gl.glDeleteTextures(img.textureIds.length, img.textureIds, 0); 
} 
gl.glFlush(); 
+0

Sẽ thật tuyệt nếu ai đó biết cách làm việc này chi tiết và lý do tại sao cùng một mảng phải được sử dụng trong trường hợp này. Tôi đã nhìn thấy nhiều ví dụ khác khi các kết cấu được tạo ra bằng cách sử dụng nhiều mảng 1-dim. Ngoài ra, bạn không bắt đầu mảng trước khi gọi glGenTextures? –

4

tôi biết bạn đã nói rằng bạn đã giải quyết được vấn đề của mình, nhưng tôi nghĩ rằng tôi đã nhận thấy lỗi của bạn trong bit đầu tiên của mã. Nhìn vào vòng lặp while trong mã xóa kết cấu của bạn, bạn không tăng chỉ mục i cho mảng của bạn, vì vậy bạn sẽ liên tục gán chỉ mục đầu tiên cho đến khi bạn đạt được mục nhập cuối cùng trong pendingTextureUnloads, phần còn lại của chỉ mục sẽ là 0 (null) . Đó có thể là vấn đề.

Và nhân tiện, tôi đã tạo ra kết cấu bằng cách không sử dụng lại mảng, chỉ trả lại chỉ mục được tạo bởi glGenTextures. Mã của tôi là dòng bằng với của bạn, ngoại trừ việc tạo một mảng int mới trong phần đầu của phương thức và trả về int tại chỉ mục đầu tiên ở cuối. Mã của bạn để tạo kết cấu sẽ hoạt động, lỗi chỉ là trong quá trình xóa kết cấu.

+0

Bắt tốt. +1 :) –

Các vấn đề liên quan