9

我正在使用 LibGDX 制作游戏。我想根据需要同时加载/卸载资产。但是,等待资产在主线程中加载会导致延迟。为了解决这个问题,我创建了一个后台线程来监控需要加载哪些资产(纹理、声音等)并适当地加载/卸载它们。

AssetManager.update()不幸的是,从该线程调用时出现以下错误。

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

我一run开始就尝试在主线程中设置后台线程,只处理前几个屏幕,一切正常。我还可以将算法更改为在同一个线程中从一开始就将所有内容加载到内存中,这也可以。但是,两者都不能在后台线程中工作。

当我在 Android 上使用 OpenGL ES 2.0(以奇怪的方式灵活)而不是在 Windows 上运行它时,一切运行良好,我什至可以获得图像的像素尺寸 -但纹理呈现黑色

我的搜索告诉我,这是OpenGL 上下文绑定到单个线程的问题,但仅此而已。这就解释了为什么当我把它推到主线程时一切正常,而不是当我把它放在另一个线程中时。如何解决此上下文问题?

4

1 回答 1

9

首先,您不应该在渲染线程之外访问 OpenGL 上下文。

我假设您已经看过这些,但只是为了确保阅读AssetManager wiki 文章,该文章谈到了如何使用 AssetManager 进行资产的异步管理。除了 wiki 文章,查看AssetManagerTest以更好地了解如何使用它。资产管理器测试可能是您了解如何动态加载资产的最佳选择。

如果您要加载大量内容,您可能需要考虑创建一个加载栏来预先加载任何大型内容。从另一个线程检查资产等可能会起作用(并设置一个标志来调用更新),但最终您需要在渲染线程上调用update() 。

请记住,您必须从不同的线程调用 update() 它,我不明白为什么您希望另一个线程检查条件并设置标志。使用另一个线程和同步 update() 调用可能比仅在渲染线程上完成所有开销更多。此外,update() 方法在增量加载文件时每次只暂停几毫秒。通常,您只需为您的资产调用load(),然后在您的资产上检查isLoaded()。如果未加载,您将每帧调用一次 update(),直到 isLoaded() 返回 true。一旦它返回 true,您就可以调用get()并获取您正在加载的任何资产。这一切都可以通过主渲染线程完成,而不会在加载时出现应用程序延迟。

如果您真的希望您的其他线程调用 update(),则需要创建一个Runnable对象并调用postRunnable(),例如他们在关于 libGDX 多线程的wiki 文章中如何描述它。但是,这违背了使用其他线程的全部意义,因为您使用 postRunnable 的任何内容都会在渲染线程上同步运行。

于 2013-04-24T23:02:52.720 回答