在当前线程中找不到 OpenGL 上下文 [英] No OpenGL context found in the current thread

查看:53
本文介绍了在当前线程中找不到 OpenGL 上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using LibGDX to make a game. I want to simultaneously load/unload assets on the fly as needed. However, waiting for assets to load in the main thread causes lag. In order to remedy this, I've created a background thread that monitors which assets need to be loaded (textures, sounds, etc.) and loads/unloads them appropriately.

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

Unfortunately, I get the following error when calling AssetManager.update() from that thread.

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

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

I've tried runing the background thread in the main thread in the beginning and just dealing with the first few screens, and everything works fine. I can also change the algorithm to just load everything into memory from the start in the same thread, and that works as well. However, neither works in the background thread.

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

When I run this on Android with OpenGL ES 2.0 (which is flexible in odd ways) instead of on Windows, everything runs fine, and I can even get the pixel dimensions of the images - but the textures render black.

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

My searches have told me that this is an issue of the OpenGL context being bound to a single thread, but not much else. This explains why everything works when I shove it in the main thread, and not when I put it in a different one. How do I fix this context problem?

推荐答案

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

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

I assume you have looked at these already, but just to make sure read up on the AssetManager wiki article, which talks a bit about how to use the AssetManager for asynchronous managing of assets. In addition to the wiki article, check out the AssetManagerTest to better understand how to use it. The asset manager test is probably your best bet into loading at how to dynamically load assets.

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

If you are loading a ton of stuff, you may want to look into creating a loading bar to load anything large upfront. It might work to check assets and such from another thread (and set a flag to call update), but at the end of the day you will need to call update() on the rendering thread.

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

Keeping in mind you have to call update() it from a different thread, I don't see why you would want another thread to check conditions and set a flag. There is probably more overhead using another thread and synchronizing the update() call than to just do it all on the rendering thread. Also, the update() method only pauses for a couple milliseconds at a time as it incrementally loads files. Typically, you would simply call load() for your asset, then check isLoaded() on your asset. If it isn't loaded you would then call update() once per frame until isLoaded() returns true. Once it returns true, you can then call get() and get whatever asset you were loading. This can all be done via the main rendering thread without having the app lag while its loading.

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

If you really want your other thread to call update(), you need to create a Runnable object and call postRunnable() such as how they have it described in the wiki article on multi-threading with libGDX. However, this defeats the whole point of using other threads because anything you use with postRunnable runs synchronously on the rendering thread.

这篇关于在当前线程中找不到 OpenGL 上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆