Tôi có kiến thức cơ bản về việc sử dụng OpenGL, đặc biệt là trên Android. Tôi đang phát triển một ứng dụng sử dụng OpenGL để chuyển đổi giữa các hình ảnh toàn màn hình một cách nhanh chóng (vì nó quá chậm bằng cách sử dụng khung Android bình thường).Cách tải họa tiết trong OpenGL ES hiệu quả
Những gì tôi đã tìm thấy là để load texture, tôi cần phải làm một cái gì đó như:
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuffer.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
textureBuffer = byteBuffer.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
_gl = gl;
final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), _imageResourceId);
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_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
Bây giờ, kể từ khi những hình ảnh có nghĩa là để được toàn màn hình (và họ là khá lớn - 1024x1024), điều này mất một thời gian, đặc biệt là kể từ khi tôi cần phải tải 5 trong số họ cùng một lúc.
Vì vậy, tôi cần phải hỏi một số câu hỏi liên quan đến lời khuyên của việc cải thiện mã, đặc biệt là về tải hiệu quả (nhưng cũng sử dụng ít bộ nhớ nếu có thể):
nếu tôi giải mã bitmap không có pixel minh bạch, bằng cách sử dụng định dạng RGB_565, nó sẽ tăng tốc độ tải hình ảnh lên OpenGL (hay giai đoạn giải mã)?
bitmap đầu vào phải có chiều rộng và chiều cao là 2 hoặc tôi có thể để OpenGL chỉ lấy phần mà nó muốn, có quy tắc này không? Ý tôi là, có lẽ tôi có thể thực hiện lệnh
texImage2D
để chỉ lấy một phần của bitmap?có lẽ tôi thậm chí chỉ có thể giải mã phần này ngay từ đầu (vì vậy nếu tôi có hình ảnh cực lớn 10000x10000, tôi chỉ có thể giải mã một phần 1024x1024 của nó và đưa nó cho OpenGL)?
có thể tải và chỉ hiển thị hình ảnh đầu tiên và trong nền tải phần còn lại không? Tôi đã nghe nói rằng bạn không thể gửi bitmap cho OpenGL trong một chủ đề mà không phải là một trong đó xử lý nó. Liệu có ý nghĩa khi tải chúng theo phương pháp của số
GlRenderer
, nói lần thứ hai nó được gọi? Tôi nhớ tôi đã nghe nói về một mẹo về sáp nhập nhiều hình ảnh vào một hình ảnh duy nhất (cái khác, từ trái sang phải), để nó có thể có một số tăng tốc độ cho giai đoạn giải mã. Không chắc tên của kỹ thuật này là gì. Vẫn có thể sử dụng OpenGL ES trên Android?là có thể tránh tạo ra một thể hiện Bitmap và để giải mã được thực hiện theo cách bản địa hơn (NDK, có lẽ)? Theo các thử nghiệm của tôi, việc giải mã một tệp PNG có kích thước 1024x1024 trên trình mô phỏng mất khoảng 400ms-700ms, nhưng việc gửi nó tới OpenGL mất khoảng 50ms-70ms.
sử dụng Procrank, tôi đã phát hiện ra rằng OpenGL có thể chiếm nhiều bộ nhớ. Có thể làm cho nó sử dụng ít bộ nhớ hơn? Có thể sử dụng các loại kết cấu tốt hơn?
vì Android có thể hoạt động trên nhiều loại thiết bị, có thể đưa vào tệp kê khai yêu cầu cần bao nhiêu bộ nhớ để ứng dụng chạy, để những người có quá ít bộ nhớ sẽ không thể cài đặt nó?
@Majid Max:
do đó, nó đủ để giải mã theo cách này và gửi nó đến OpenGL, hoặc nên tôi cũng đặt một cái gì đó đặc biệt khi gửi đến OpenGL?
không có lệnh như vậy để tham gia một phần của bitmap?
Ý tôi là, tôi có thể giải mã chỉ một phần của tệp được lưu trữ trong bitmap không, thay vì tất cả bitmap?
vì vậy điều duy nhất tôi có thể làm để tải mọi thứ ngay từ đầu và sau đó sử dụng tất cả? Lam thê nao điêu đo co thể? Trò chơi xử lý nó như thế nào? Ý tôi là, họ thể hiện một giai đoạn khác, ngay cả với một cái gì đó trông giống như một thanh tiến trình OpenGL tạo ra. Điều này rất có vấn đề.
nội dung tôi mô tả cũng khả dụng trên web. Ví dụ: thay vì tải nhiều hình ảnh nhỏ, trang web chứa một hình ảnh duy nhất và ánh xạ phần nào của nó sẽ được hiển thị ở đâu. Một tên khác cho nó là sprites. Ví dụ here.
Tôi hiểu. Tôi đoán tôi cũng nên gọi glDeleteTextures khi tôi thấy không được sử dụng nữa, phải không?
làm cách nào để làm điều đó? Tôi nên thay đổi gì trong mã?
điều gì xảy ra khi tôi sử dụng nhiều bộ nhớ? Có một thứ như RAM ảo (sử dụng bộ nhớ trong có lẽ) khi không có RAM miễn phí? Tôi đã nghe về nó trên Google IO video, nhưng có vẻ như họ không chắc chắn về câu trả lời là tốt. Liên kết here. Họ chỉ nói để mong đợi nhiều sự cố hơn khi một điều như vậy xảy ra.
@Majid Max:
1 + 2 + 3. ?
điều này có thể hiệu quả. Bạn có nghĩa là tôi thực hiện một chủ đề mới sẽ tải các bitmap, và sau đó gửi kết quả trở lại chủ đề OpenGL mà sẽ ràng buộc các kết cấu với bitmap? Có lẽ tôi có thể sử dụng cách tiếp cận tương tự như asyncTask và sử dụng publishprogress.
đó cũng là một điều tốt. Bạn có bất kỳ liên kết tôi nên đọc về nó? Hoặc có thể một đoạn mã để thay đổi trong mã của tôi?
cảm ơn.
vì vậy tôi nghĩ đó là điều dễ nhất để sử dụng ETC1. Tuy nhiên nó không hỗ trợ minh bạch, vì vậy theo this link, tôi cần phải sử dụng một kết cấu khác chỉ cho điều đó, nhưng tôi không thể tìm thấy một mẫu cho việc này.
Tôi có thể giả định gì về bộ nhớ khả dụng mà tôi có thể sử dụng? Ví dụ: tôi có thể giả định rằng tất cả các thiết bị Android có thể cung cấp cho tôi 200MB bộ nhớ video mà tôi có thể sử dụng cho OpenGL không?
thật đáng tiếc là tôi không thể sử dụng vì tôi cần làm việc với cả API Android và OpenGL. tôi biết về giải pháp này (và libGDX). Tôi chỉ không được phép sử dụng chúng, đặc biệt là kể từ khi tôi cần phải đặt các quan điểm trong một viewPager. –