2012-04-20 7 views
6

Tôi hiện đang phát triển một ứng dụng iOS (iPad và iPhone) sử dụng OpenGL ES 1.0 để hiển thị một số hoạ tiết cơ bản. Tôi sử dụng atlases để lưu trữ và trình bày kết cấu của tôi.OpenGL ES sẽ không xóa kết cấu của tôi trong bộ nhớ

Bản đồ chính của tôi tương đối lớn (2000x2000) nhưng thuật toán nội bộ của tôi tải và định lại kích thước thành 2048x2048 vì OpenGL ES chỉ chấp nhận sức mạnh của 2 họa tiết có kích thước. Tôi có thể vẽ các viên gạch, mọi thứ đều tốt đẹp ở phía bên này.

Tôi đang gặp phải rò rỉ bộ nhớ nghiêm trọng mỗi khi tôi cố gắng tải và dỡ (hủy) kết cấu. Điều này sẽ xảy ra trong phiên bản cuối cùng nhưng tôi cần phải chắc chắn rằng tải và dỡ hàng của tôi là tốt. Trong bộ nhớ, kết cấu chiếm 2048x2048x4 (RGBA) byte = 16MB. Đây là một số lượng lớn các byte để bạn hiểu rằng vấn đề là khá khó chịu đối với tôi (iOS sẽ giết ứng dụng sau một vài phút ..)

Khi tôi tải một kết cấu, Dụng cụ cho biết bộ nhớ tổng thể được sử dụng bởi ứng dụng tăng 16MB này là chính xác (tôi sử dụng cột "Bộ nhớ thực"). Vấn đề xảy ra khi tôi cần hủy kết cấu để giải phóng tất cả các byte có thể được sử dụng bởi nó: nó không bao giờ mất 16MB ... và kể từ khi tôi tải và dỡ bỏ trong một vòng lặp, bộ nhớ tiếp tục được sử dụng và không bao giờ giải phóng.

Đây là cách tôi tải các kết cấu:

GLubyte *outData = malloc((_dataWidth * _dataHeight * 4) * sizeof(*outData)); 
GLuint _texture; // declared as un instance variable so its address never changes 
glGenTextures(1, &_texture); 
glBindTexture(GL_TEXTURE_2D, _texture); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _dataWidth, _dataHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, outData); 
free(outData); 

Dưới đây là làm thế nào tôi dỡ bỏ các kết cấu (điều này được gọi, tôi đã kiểm tra)

glDeleteTextures(1, &_texture); 

tôi đã sử dụng glGetError() ở khắp mọi nơi để kiểm tra nếu một lỗi xảy ra nhưng nó luôn trả về 0 (ngay cả sau glDeleteTexture).

Có ai có ý tưởng không? Cảm ơn bạn!

+0

Như một lưu ý phụ, mọi thiết bị iOS từ iPhone 3G S và mới hơn sẽ hỗ trợ họa tiết không có điện hai trong OpenGL ES 1.1: http://stackoverflow.com/a/4761453/19679. Ngoài ra, bạn có nghĩ về việc chuyển đổi bản đồ của bạn để sử dụng PowerVR Texture Compression (PVRTC) không? Các họa tiết được nén theo cách đó thực sự được lưu trữ trong bộ nhớ dưới dạng nén của chúng, có thể làm cho dấu chân của chúng nhiều hơn, nhỏ hơn nhiều so với kết cấu không nén. Nó sẽ không giải quyết rò rỉ của bạn, nhưng nó có thể là một ý tưởng tốt nói chung. –

Trả lời

14

Đảm bảo rằng bạn hủy kết cấu của mình trên cùng một chuỗi, nơi bạn đã tạo ngữ cảnh của mình. Nếu bạn đang thực hiện bất kỳ cuộc gọi GL nào mà không có ngữ cảnh thì sẽ không có lỗi.

+0

Cảm ơn bạn !! Nó đã làm việc. –

+1

Max, câu trả lời này đã giúp tôi theo dõi một rò rỉ kết cấu thực sự khó chịu trong Core Image (vì một CIContext đã được chia sẻ trên một ranh giới thread.) Cảm ơn rất nhiều cho bài viết ngắn, nhưng rất hữu ích! – chockenberry

1

Bạn đã thử tiện ích mở rộng GL_APPLE_client_storage chưa? Nó có nghĩa là thay vì có OpenGL có một bản sao của bộ nhớ kết cấu bạn hứa sẽ giữ cho khối dữ liệu được chuyển đến glTexImage2D còn sống cho đến khi glDeleteTextures được gọi.

+0

Ứng dụng có được bật trên iOS không? Tôi có cảm giác rằng đây không phải là tài liệu cho iOS .. –

+0

Vâng, tôi nghĩ rằng phần mở rộng chỉ dành cho Mac. Trên iOS 5.0, chúng tôi có thể sử dụng một cái gì đó tương tự trong bộ đệm kết cấu, nhưng đó không phải là những gì dường như là trường hợp ở đây. –