2013-04-24 13 views
8

Tôi đang sử dụng LibGDX để tạo trò chơi. Tôi muốn đồng thời tải/dỡ tài sản khi đang cần thiết. Tuy nhiên, chờ đợi cho các tài sản để tải trong thread chính gây lag. Để khắc phục điều này, tôi đã tạo chủ đề nền giám sát nội dung nào cần được tải (họa tiết, âm thanh, v.v.) và tải/giải phóng chúng một cách thích hợp.Không tìm thấy ngữ cảnh OpenGL trong chủ đề hiện tại

Thật không may, tôi gặp lỗi sau khi gọi số AssetManager.update() từ chuỗi đó.

com.badlogic.gdx.utils.GdxRuntimeException: java.lang.RuntimeException: No OpenGL context found in the current thread. 

Tôi đã thử run ing thread nền trong các chủ đề chính trong đầu và chỉ đối phó với vài màn hình đầu tiên, và tất cả mọi thứ hoạt động tốt. Tôi cũng có thể thay đổi thuật toán để chỉ tải mọi thứ vào bộ nhớ từ đầu trong cùng một chuỗi và cũng hoạt động. Tuy nhiên, không hoạt động trong chuỗi nền.

Khi tôi chạy ứng dụng này trên Android với OpenGL ES 2.0 (linh hoạt theo cách kỳ lạ) thay vì trên Windows, mọi thứ đều chạy tốt và thậm chí tôi có thể lấy kích thước pixel của hình ảnh - nhưng kết cấu hiển thị màu đen .

Tìm kiếm của tôi đã cho tôi biết rằng đây là vấn đề của ngữ cảnh OpenGL OpenGL bị ràng buộc vào một chuỗi duy nhất, nhưng không được nhiều thứ khác. Điều này giải thích lý do tại sao tất cả mọi thứ hoạt động khi tôi xô nó trong chủ đề chính, và không phải khi tôi đặt nó trong một chủ đề khác. Làm cách nào để khắc phục sự cố ngữ cảnh này?

Trả lời

9

Trước tiên, bạn không nên truy cập ngữ cảnh OpenGL bên ngoài chuỗi hiển thị.

Tôi giả sử bạn đã xem xét những điều này, nhưng chỉ để đảm bảo đọc trên số AssetManager wiki article, cuộc trò chuyện này nói một chút về cách sử dụng AssetManager để quản lý tài sản không đồng bộ. Ngoài bài viết trên wiki, hãy xem AssetManagerTest để hiểu rõ hơn cách sử dụng nó. Kiểm tra trình quản lý nội dung có lẽ là cách tốt nhất để bạn tải vào cách tải động nội dung.

Nếu bạn đang tải hàng tấn nội dung, bạn có thể muốn xem xét việc tạo thanh tải để tải bất kỳ thứ gì lớn lên trước. Nó có thể làm việc để kiểm tra tài sản và như vậy từ một chủ đề khác (và đặt cờ để cập nhật cuộc gọi), nhưng vào cuối ngày bạn sẽ cần phải gọi update() trên chuỗi hiển thị.

Lưu ý rằng bạn phải gọi cập nhật() từ một chuỗi khác, tôi không thấy lý do bạn muốn một chuỗi khác kiểm tra điều kiện và đặt cờ. Có thể có nhiều chi phí hơn bằng cách sử dụng một luồng khác và đồng bộ hóa cuộc gọi update() hơn là chỉ làm tất cả trên chuỗi kết xuất. Ngoài ra, phương thức update() chỉ tạm dừng trong vài mili giây tại một thời điểm vì nó tăng dần các tệp. Thông thường, bạn chỉ cần gọi load() cho nội dung của mình, sau đó kiểm tra isLoaded() trên nội dung của bạn. Nếu nó không được nạp thì bạn sẽ gọi update() một lần cho mỗi frame cho đến khi isLoaded() trả về true. Khi nó trả về true, bạn có thể gọi get() và nhận bất kỳ nội dung nào bạn đang tải. Điều này tất cả có thể được thực hiện thông qua các chủ đề rendering chính mà không có sự chậm trễ ứng dụng trong khi tải của nó.

Nếu bạn thực sự muốn chủ đề khác gọi cập nhật(), bạn cần tạo đối tượng Runnable và gọi postRunnable() chẳng hạn như cách chúng được mô tả trong wiki article trên đa luồng với libGDX. Tuy nhiên, điều này đánh bại toàn bộ các điểm của việc sử dụng các chủ đề khác bởi vì bất cứ điều gì bạn sử dụng với postRunnable chạy đồng bộ trên chuỗi kết xuất.

+0

-1 cho các ngữ cảnh OpenGL không chính xác nêu rõ không thể được sử dụng từ nhiều luồng. Hoàn toàn có thể tách ra một bối cảnh OpenGL từ một sợi chỉ và đính kèm nó vào một luồng khác. – datenwolf

+0

Cách tách và đính kèm ngữ cảnh vào một luồng khác bằng cách sử dụng nó theo nghĩa đa luồng? Bản thân bối cảnh chỉ có thể được truy cập bởi một luồng đơn tại một thời điểm trừ khi bạn muốn thử và sử dụng khóa để đạt được nó. Tuy nhiên, điều đó đánh bại toàn bộ vấn đề. – Jyro117

+0

Bạn đã xác nhận rằng ngữ cảnh OpenGL chỉ có thể được sử dụng từ chuỗi chỉ hiển thị, ngụ ý rằng chỉ chuỗi đã tạo ngữ cảnh mới có thể sử dụng nó. BTW: bạn có thể tạo một số bối cảnh OpenGL trên cùng một drawable với các không gian tên đối tượng được chia sẻ và đính kèm từng chủ đề riêng. Điều này cho phép bạn đa luồng. – datenwolf