Problems with loading screen

I’ve made using GUINode a simple, static loading screen. So people would know that level is loading. Unfortunately it somehow doesn’t get displayed. It is done like that:

[java]guiNode.attachChild(this.app.loading);

this.app.loading.setQueueBucket(Bucket.Gui);

this.app.loading.setPosition(0, 0);

levelNode = levelLoader.LoadLevel(level);// This freezes game even for 4 seconds in case of biggest levels

guiNode.detachChild(this.app.loading);[/java]



“loading” is Picture object and is referred via this.app, because it is inside of appstate. I know positions, etc. are correct, because when I remove detaching part, image is displayed forever.

Look in the wiki, theres examples of non-blockingloading screens. As your load method blocks the update loop the display isn’t updated. Basic update loop logic.

Simply explained, your scene with the laoding screen is never rendered, since you load the scene, and detach it before the next rendering is made.



Rough solution(singe threaded, dirty)

→ Attach loading screen

→ Wait until scene is rendered at least once

→ Load

->detach

Problem here is that the rendering is halt while loading, This leads to window not responding on windows 7 for example, grafic artifacts if other windows are moved over and in case of android even to application termination.



Cleaner solution(yet not perfect)

→ Attach loading scene

→ Preoload all stuff in a background thread, do any modifications with to a detached node

→ attach with enque in rendering thread said node

→ detach loading screen as well when doing so

While being more complex here is only a very small delay in the render thread, after attaching when it first uploads textures , shaders & models (that are already decoded in the background thread) to the gpu, this will only be a matter of a few ms.

1 Like

As said, the wiki contains a full example with code:

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:loading_screen

1 Like

Well, it involves NiftyGui, which I don’t want to learn yet (though it will be needed for my next project). I’d probably go with first Phoenix’s solution. Also I got it working.

What it explains doesn’t have anything to do with nifty, you can use any ui for that :roll:

How would I be able to create a loading screen using an AppState? I assume I have to make an AppState for the Loading Screen, and another for Loading the Models etc…?

If you want to incorporate an AppState then I would suggest doing something like this (adapted from the LoadingScreen tutorial in the wiki), which is mainly useful for accessing to the update(float tpf) loop:



[java]

public class LoadingScreen extends AbstractAppState implements ScreenController {



private boolean load = false;

private int frameCount = 0;



public void update(float tpf) {



if(load) {



if (frameCount == 1) {

setProgress(0.1f, "Attaching sky");

attachSky();

} else if (frameCount == 2) {

setProgress(0.4f, "Loading scene");

loadScene();

}







} else if (frameCount > 30) {

load = false;

nifty.gotoScreen("end");

getStateManager().detach(this);

getStateManager().attach(new LevelManagerAppState());

}



frameCount++;

}



}



}

[/java]

I won’t be using Nifty, but I will test it out later, by attaching pictures to the guiNode instead of setProgress…



One question I have though - does loading a scene only take one frame?

One frame isn’t a constant amount of time…

Generally, the whole idea behind a loading screen is that you are doing something on a background thread and just want to show progress to the player. So the “take one frame” bit doesn’t matter and it’s a sign that you are thinking about this incorrectly.

1 Like

It’s not that I’m thinking about it incorrectly, but isn’t that which is being done in wezrule’s code? In the first frame, the sky is attached; in the second, the scene is loaded. Correct me if I’m wrong though. I know that a frame isn’t constant in terms of time, but why are ‘frames’ used in the code?

Think of a frame as one update() loop. The time this takes is different on every machine, but that’s what a frame is.

Yeah I understand that well. I read this in the Wiki link normen provided: “If you do all of this in a single frame, then it is sent to the graphics card only after the whole code block has executed. By this time the bar has reached 100% and the game has already begun – for the user, the progressbar on the screen would not have visibly changed.”



So that means that a model/scene/whatever I load is loaded in one frame - one update loop?

@memonick said:
So that means that a model/scene/whatever I load is loaded in one frame - one update loop?


From what I understand of your question, essentially yes.
@memonick said:
Yeah I understand that well. I read this in the Wiki link normen provided: "If you do all of this in a single frame, then it is sent to the graphics card only after the whole code block has executed. By this time the bar has reached 100% and the game has already begun – for the user, the progressbar on the screen would not have visibly changed."

So that means that a model/scene/whatever I load is loaded in one frame - one update loop?


Yeah, wezrule's code was the simple hacky way. The load takes one frame because the frame waits for the load. So, yeah. The scene gets loaded in one frame but that one frame could take 20 minutes. (shrug)

If you want the progress to change while loading then you have to load in a separate thread.

@pspeed said:
If you want the progress to change while loading then you have to load in a separate thread.

...for which there is an example on the same page
@normen said:
...for which there is an example on the same page


Heheh. Yeah. I assumed that their mouse click button was broken so I offered more information here. ;)
@pspeed said:
Heheh. Yeah. I assumed that their mouse click button was broken so I offered more information here. ;)

...we need a Siri extension for this site, seriously ;)