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.
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.
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.
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.
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.
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.
Thanks! Somebody already did the hard work of tracking it down, so there wasn’t much then
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…
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.