SceneProcessor reshape() not called in 3.7.0-beta1.2

Hi,

Some context: I was working on a future version of my game and implementing a settings menu to change resolution.
I based it off a code I already had and was proved to work, however my GUI based on Nifty would broke after the resolution change.
The difference was I was using the latest beta jme 3.7.0 so I tested with 3.6.1 and it started working.

After some debugging I found a suspect, although I haven’t tracked it back to this.

Regression: If I add a SceneProcessor to the view port the beta jme does not call reshape() anymore.
So I suspect this is important for Nifty.

Example: Here’s an example showing the issue, I used Lemur’s input system here but I can produce an example without it if needed.

Is this a known issue?

package jc.workbench;

import com.jme3.app.SimpleApplication;
import com.jme3.font.BitmapText;
import com.jme3.input.KeyInput;
import com.jme3.post.SceneProcessor;
import com.jme3.profile.AppProfiler;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.texture.FrameBuffer;
import com.simsilica.lemur.GuiGlobals;
import com.simsilica.lemur.input.FunctionId;
import com.simsilica.lemur.input.InputState;
import com.simsilica.lemur.input.StateFunctionListener;

public class ReshapeBugDemo extends SimpleApplication implements StateFunctionListener {

  private static final String RES1 = "Res1";
  private static final String RES2 = "Res2";
  private BitmapText text;

  public static void main(String[] args) {
    new ReshapeBugDemo().start();
  }

  @Override
  public void simpleInitApp() {
    // Setup some keys
    GuiGlobals.initialize(this);
    var inputMapper = GuiGlobals.getInstance().getInputMapper();
    var functionRes1 = new FunctionId(RES1);
    var functionRes2 = new FunctionId(RES2);
    inputMapper.map(functionRes1, KeyInput.KEY_1);
    inputMapper.map(functionRes2, KeyInput.KEY_2);
    inputMapper.addStateListener(this, functionRes1);
    inputMapper.addStateListener(this, functionRes2);

    // Register the processor
    getGuiViewPort().addProcessor(new ReshapeProcessor());

    // Display a message
    var font = assetManager.loadFont("Interface/Fonts/Default.fnt");
    text = new BitmapText(font);
    text.setText("Press 1 or 2 to change resolution.");
    text.setLocalTranslation(50, 10 * text.getLineHeight(), 0);

    guiNode.attachChild(text);
  }

  @Override
  public void valueChanged(FunctionId func, InputState value, double tpf) {
    if (func.getId().equals(RES1)) {
      settings.setResolution(1024, 768);
    } else if (func.getId().equals(RES2)) {
      settings.setResolution(1280, 1024);
    }
    restart();
  }

  @Override
  public void reshape(int w, int h) {
    System.out.println("App reshape");
    super.reshape(w, h);
  }

  class ReshapeProcessor implements SceneProcessor {

    @Override
    public void reshape(ViewPort vp, int w, int h) {
      var message = String.format("New resolution: %dx%d", w, h);
      System.out.println(message);
      text.setText(message);
    }

    @Override
    public void initialize(RenderManager rm, ViewPort vp) {
    }

    @Override
    public boolean isInitialized() {
      return true;
    }

    @Override
    public void preFrame(float tpf) {
    }

    @Override
    public void postQueue(RenderQueue rq) {
    }

    @Override
    public void postFrame(FrameBuffer out) {
    }

    @Override
    public void cleanup() {
    }

    @Override
    public void setProfiler(AppProfiler profiler) {
    }
  }
}

The screen message is not updated after resizing the view port.

2 Likes

It’s important for any UI or screen-size related code. In JME, this is the only way to know if the window size or screen size has changed.

1 Like

I can try to take a look at this. I think this or something similar was reported at the JME 3.7 thread. Was there already a Github issue about this? Although it is going to be next week at the earliest. I have previously messed with this also.

Does this happen on LWJGL 2 or 3? Or both?

1 Like

The problem only happens with 3.

2 Likes

I think this or something similar was reported at the JME 3.7 thread. Was there already a Github issue about this?

Perhaps you’re thinking of issue 1793 ?

1 Like

Hmm, that I don’t remember but good to know. Reminds me how fiddly it was, no wonder it broke.

This I was referring to. I think here also the problem might be that we never initialize the size. And the bisect seems to be my commit… I think these are all related… I’ll try to roll my sleeves up next week.

1 Like

And if the bisect is 100% correct, these are the only lines as far as I know that are related to this:

Edit: hmm, the link does not highlight the lines? Anyway jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java:298-299

The PR is probably squashed, but I believe this commit message was related to that change “Fix offscreen rendering by not triggering unnecessary resize”. That fix is probably the wrong approach anyway. Offscreen rendering should probably just handle it better. Besides, I’m not sure if it really is an issue anymore as the Canvas rendering for LWJGL 3 was reworked after that.

3 Likes

Here we go: Setting the resolution to match the old prevents calling reshape by tonihele · Pull Request #2290 · jMonkeyEngine/jmonkeyengine · GitHub

I tested with code pasted here in the original post. Couple of observations:

  • We still suffer from Nifty GUI doesn't display correctly after context restart · Issue #1013 · jMonkeyEngine/jmonkeyengine · GitHub. Yes, Nifty is not used here but that problem is not just a Nifty problem. Also BitmapFont and what have you. So this sample code can be used to troubleshoot that too if Nifty feels unsanitary for people’s liking
  • On LWJGL 2 I could go crazy switching the resolution, as fast as my fingers could do it. On LWJGL 3 being too fast crashes. On LWJGL 3 side. Everything is synced as far as I can see so it should not be a race condition. Not really that big of an issue, who would change resolutions so rapidly.
3 Likes

Awesome @tonihele, glad it was a quick fix!

hmm interesting, I wasn’t aware of that issue.
By the dates it should still be present in 3.6 however I haven’t experienced in my “display settings” made with nifty, so far it’s been working fine.
I will test a bit more and see if I can reproduce it.

1 Like

Thanks! Somebody already did the hard work of tracking it down, so there wasn’t much then :slight_smile:

Yep, I mean, it should be broken in your test case as well. The BitmapFont. It should be broken. Perhaps all the way to the first LWJGL 3 implementations. Not a huge issue of course but very mysterious.

For Nifty this can be worked around by reloading Nifty. Should not be all that difficult. BitmapFont I guess needs to be recreated. I’d rather have it fixed than any of these workarounds. If someone would understand what is wrong there…

Now I’m confused. This is the result of the test with jme 3.6.1 and lwjgl 3.3.2:
Initial state and pressing 1 and 2:

Imgur
Imgur
Imgur

I can’t see anything wrong with the BitmapFont

Hmm, that is odd. Is this another NVIDIA specialty. I should try my Intel also.

Here is my experience (no audio), first LWJGL 2 and then 3. Using the code supplied, running against master branch:

Oh, I see now.
Never had that issue, I also tried spamming 1 and 2 and it didn’t crash.
My test was with Intel and Linux, unfortunately I don’t have access to any Nvidia card.