yellowstonegames / SquidLib

Useful tools for roguelike, role-playing, strategy, and other grid-based games in Java. Feedback is welcome!
Other
454 stars 46 forks source link

SquidLayers stops rendering after losing focus #178

Closed gotoss08 closed 7 years ago

gotoss08 commented 7 years ago

This is almost the same error as this, with the exception that I'm not trying to manipulate any static classes or resources or whatever. The error lies in the fact that when the window loses focus, the SquidLayers stops rendering anything. Here is very basic example

private SpriteBatch batch;
private SquidLayers layers;

public RenderingSystem() {
   batch = new SpriteBatch();
   layers = new SquidLayers(40, 25);
}

public void render(float delta) {
   layers.put(10, 10, '@');

   batch.begin();
   layers.draw(batch, delta);
   batch.end();
}

And now, if i minimize window or switch to other application, '@' char stops rendering.

tommyettinger commented 7 years ago

Does the @ stop rendering permanently, or just while the window is out of focus? I'll try to reproduce.

tommyettinger commented 7 years ago

I have a complete example in the latest commit, and it doesn't reproduce this issue at all when it's set up correctly and completely. I suspect part of the issue may be with how you're calling SquidLayers.draw(); the second parameter is not delta time, it is the parent alpha transparency of anything containing the SquidLayers, which is almost always supposed to be 1f. If you called it with delta, that could have a completely different value than what is allowed for alpha. It looks like this was meant to be some kind of Screen, since that's the only place I know in libGDX that has a render(float delta) method to be implemented. Also, normal code using libGDX clears the screen at the start of each frame to avoid transparent things overwriting old frames. This code is pretty consistently the same across most games, although it's strange and obtuse considering how libGDX code is usually cleaner. If you have a Color (either the libGDX class or SquidLib's SColor) that you want to use for a background called bgColor, the clear code looks like this at the start of each call to your ApplicationAdapter's, ApplicationListener's, or Game's render() method:

        Gdx.gl.glClearColor(bgColor.r / 255.0f, bgColor.g / 255.0f, bgColor.b / 255.0f, 1.0f);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

If you just want to clear to black easily, it looks like:

        Gdx.gl.glClearColor(0f, 0f, 0f, 1.0f);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

If you don't have an ApplicationListener, ApplicationAdapter, or Game, you may be using an extremely old version of SquidLib that uses Swing, or your project may have become configured in an invalid way. I think the current best way to get started for an example project layout and setup might be to copy one of the SquidLib-Demos projects, available here: https://github.com/tommyettinger/SquidLib-Demos . BasicDemo and TheTsar3 (which may just become the only TheTsar demo, since it's the most up-to-date) are probably the best places to start for now.

gotoss08 commented 7 years ago

Oops, that was my mistake. The code I attached to last comment, was simply example code without lines that do not relate to the problem, as I think. In my real code, I of course clearing screen, and I am not passing delta time to second parameter of SquidLayers.draw(). That was mistake. And of course, I am extending Game class, and implementing Screen interface, and etc. I am doing all right, because I am familiar with SquidLib and LibGDX, and this is not my first project. Fortunately, when I found this error, I was at an early stage of development, and after after several unsuccessful attempts to identify the problem in my code, I decided to rewrite all the code. But the issue does not disappear. I wrote very simple test application that just prints '@' symbol, but even then the error did not disappear.

tommyettinger commented 7 years ago

OK, I wasn't sure what the code was like that had the bug where it was found, thanks for catching me up. I'm guessing this is being run on a desktop platform, probably not LWJGL3 but maybe, though I'm not sure what OS it is (which may matter for replicating if there's some different window foreground/background behavior relative to my OS, Windows 7). I did push a commit about 11 hours ago, which can be obtained from JitPack here https://jitpack.io/#SquidPony/SquidLib/47fbfc35a6 , and it is meant to address a similar issue with a font resource being mistakenly disposed by SquidLib. I'll ask hawk66 what OS/platform he is or was experiencing issues on using his Scala code.

gotoss08 commented 7 years ago

I am on windows 10. To make more clarity, I'll post my source code and gif of how it works. Here is my test project source code. DesktopLauncher.java Project1.java PlayScreen.java And here is gif of how it works.

tommyettinger commented 7 years ago

I'm not sure what is causing the problem, and it seems to work without issues here; here's a similar screen recording of two windows. I'm on Windows 7 and it might be tricky for me to test this on Windows 10, though it should be possible. I wonder if the build of Java I use, Zulu OpenJDK 8, has some bugfix that applies here but not to some versions of Oracle Java. Normally it would be the other way around, but Zulu is pretty good about fixing things quickly. There's also a strong possibility that Windows 10 treats foreground and background windows differently than Windows 7, but I don't know any specifics. I'll make some small JAR and test it on a nearby Windows 10 machine.

gotoss08 commented 7 years ago

I tested the application with Zulu but the error remained

gotoss08 commented 7 years ago

I tested the application on Ubuntu 17.04 with openjdk version 1.8.0_131 and oddly enough the error has not gone anywhere. But app what i've been testing was a build on Windows. Now I'm going to rebuild app from sources on Linux.

UPD: Yep. Even when i fully rebuilded source code on linux, SquidLayers still stops rendering after losing focus.

tommyettinger commented 7 years ago

This is going to drive me nuts... I'm somewhat short on ideas for what could cause this if you're on the current commit. I have your code for demonstrating the error in SquidLib's tests currently, since it is something that should get tested. While it isn't super-easy to run the tests (it needs Maven, but Maven is integrated into IntelliJ IDEA and Eclipse... I think), that might be the best way to debug the path being taken through the code, and check if the font is getting disposed when the window loses focus. If you're using JitPack to get dependencies, which is the recommended way of the three ways to get the current version of code (the others being running mvn install from source to depend on a local Maven version, and the alternative way of just copying all of SquidLib's source into your project), then the current commit hash to depend on is 8608c8b2e3, with further info at https://jitpack.io/#SquidPony/SquidLib/8608c8b2e3 .

gotoss08 commented 7 years ago

I do not know what happened but now everything is working again.

tommyettinger commented 7 years ago

I think it's possible that the issue was fixed at some point in the wave of commits relating to DefaultResources and the disposal of BitmapFonts, but due to a frequent issue in IDE-to-Gradle integration that has affected me several times, your dependency on SquidLib may have not been updated in the IDE even though your Gradle config was correct and telling it to update. This hasn't happened to me with Maven, only Gradle, but Maven doesn't apparently handle Android projects very well so libGDX uses Gradle almost exclusively... I'll close this now, but please re-open if you encounter it again, since it may be some symptom of a deeper problem that only surfaces in rare cases. One possibility is that the font's image is being removed from RAM due to a shortage of available memory on the GPU or the system RAM (if using integrated graphics), and isn't being re-added because SquidLib and/or libGDX don't do that. That would only explain part of the issue; it would require there to be a RAM shortage on both Windows 10 and Ubuntu when the application was run the first many times, but not the latest times. I don't know if there is a way to detect that an image has been replaced by the OS or GPU driver with an invalid state, and that might be completely irrelevant since the issue may have been the dependency being stuck on an older version.