加载屏幕中的非连续渲染无法正常工作 - 多线程LIBGDX [英] Non-continuous Rendering in Loading screen not working as it supposed to work - Multithreading LIBGDX

查看:236
本文介绍了加载屏幕中的非连续渲染无法正常工作 - 多线程LIBGDX的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在加载屏幕中使用非连续渲染,因此我可以更新它,因为我在辅助线程中输入了我的代码的不同部分。这样我可以手动增加我用来绘制一个Sprite的动画计数器,该Sprite显示与我的资产加载一致的填充沙漏。

I'm using Non-continuous Rendering in my loading screen so I can update it as I INIT different parts of my code in a secondary thread. That way I can manually increase the Animation counter that I use to draw a Sprite which shows a filling hourglass in tune with the loading of my assets.

所以,我加载我的在另一个线程的帮助下的游戏画面(地图集,纹理,初始化变量等):

So, I load my game screen with the help of another thread (atlases, textures, init variables,etc) :

Runnable load_game_screen = new Runnable(){
    public void run(){
        new_game_screen.load_all();
    }
}};
Thread thread_load_game = new Thread(load_game_screen);
thread_load_game.start();

在我的游戏画面 load_all 功能中我使用 Gdx.app .postRunnable 在主UI线程的下一个渲染上运行这些初始化,这样我就不会出现任何上下文错误:

In my game screen load_all function I use Gdx.app.postRunnable to run those initializations on the next render of the main UI thread so I don't get any context errors:

public void load_all(){
    Gdx.app.postRunnable(new Runnable(){
    @Override
    public void run(){
       ...load stuff
       loading_screen.loading_counter += 0.025f;
       loading_screen.loadingTimerSprite.setRegion(loading_screen.animation.getKeyFrame(loading_screen.loading_counter, true));
    }
    Gdx.graphics.requestRendering();
    Thread.sleep(25);

    Gdx.app.postRunnable(new Runnable(){
    @Override
    public void run(){
       ...load stuff part2
       loading_screen.loading_counter += 0.025f;
       loading_screen.loadingTimerSprite.setRegion(loading_screen.animation.getKeyFrame(loading_screen.loading_counter, true));
    }
    Gdx.graphics.requestRendering();
    Thread.sleep(25);

    ... etc ... 
}

问题是 requestRendering 不会立即行动,有时 postRunnables 会一个接一个地运行,而不会立即进入主UI渲染功能,因此用户无法看到完整的加载精灵的动画;它发生在跳跃中。我如何在主要UI线程中强制渲染来自正在加载代表主线程的资产和变量的辅助线程?

The problem is that requestRendering doesn't act immediately and sometimes the postRunnables are run one after another without immediately going into the main UI render function so the user can't see the complete animation of the loading sprite; it happens with jumps. HOW can I force Rendering in the main UI thread from the secondary thread that is loading the assets and variables of behalf of the main thread?

推荐答案

如果您的加载速度比帧时间快(例如,如果加载步骤的速度超过每秒60步),用户将无法看到所有动画步骤。这对我来说听起来不错!

If your loading happens faster than the frame time (e.g., if you're loading steps are faster than 60 steps per second) a user won't see all the animation steps. This sounds like a good thing to me!

但是,如果你想确保显示动画的所有步骤,我认为你的后台线程应该只设置一个目标动画帧,渲染线程应该将实际帧提前一直到目标被击中。它可以像这样运行:

If however, you want to make sure all the steps of the animation are shown, I think your background thread should just set a "target" animation frame, and the render thread should advance the actual frame by one until the target is hit. It could operate something like this:


  • 后台线程集 target = 10 (和请求渲染)

  • 渲染线程为0,看到目标10,绘制0,颠倒计数为1,设置请求渲染标记。

  • 渲染线程为1,目标为10,绘制1,凸起数为2,设置请求渲染标志

  • 后台线程集 target = 11 (并请求渲染)。

  • 等等。

  • Background thread sets target = 10 (and requests a render)
  • Render thread is at 0, sees target 10, draws 0, bumps count to 1, sets the request render flag.
  • Render thread is at 1, sees target of 10, draws 1, bumps count to 2, sets request render flag
  • Background thread sets target = 11 (and requests a render).
  • etc, etc.

这种方式这两个人可以按自己的节奏进行。如果你想快速加载,渲染线程只能绘制目标帧。如果你想显示每一帧,它可以加1。

This way the two can proceed at their own pace. If you want the loading to go quickly the render thread can just draw the target frame. If you want to show every frame, it can bump by 1.

一个注意事项:发布一个runnable会隐式请求一个渲染。

One note: posting a runnable will implicitly request a render.

其次,它看起来像所有你的后台线程中的工作都是在发布的runnables中完成的(这可能是真的,因为大多数加载需要OpenGL上下文),但也许只是因为你简化了发布问题的代码。无论如何,如果这是真的,那么它只是在渲染线程上运行所有内容的一种尴尬方式。你可能最好设置一个简单的状态机,并让你的渲染线程一步一步地直接运行你的加载过程:

Secondly, it also looks like all of the work in your "background" thread is being done inside posted runnables (which is probably true, since most loading requires OpenGL context), but maybe its just because you simplified the code for posting your question. Anyway, if that is true, then it is just an awkward way of running everything on the render thread. You might be better off setting up a simple state machine, and having your render thread step through it to run your loading process directly:

if (! done) {
    switch(loadingStep) {
       case 0:
         // step 0 code
         break;
       case 1:
         // step 1 code 
         break;
       case 2:
         ...
       case 10:
         done = true;
         break;
    }

    loadingStep++;
}

这样做的好处是每次渲染只运行一步。

This has the side benefit of running exactly one step per render.

这篇关于加载屏幕中的非连续渲染无法正常工作 - 多线程LIBGDX的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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