Libgdx: Finish LWJGL 3 backend and request for testing

Created on 28 Dec 2015  Â·  104Comments  Â·  Source: libgdx/libgdx

LWJGL 3 backend

I just committed the first iteration of the new LWJGL 3 backend. Going forward, i hope this can largely replace the old LWJGL 2 backend, especially on Mac OS X where we have a lot of problems with LWJGL 2. The new backend is also prepared for multi-window environments, altough respective methods in Lwjgl3Application haven't been exposed yet.

The LWJGL 3 backend is structure the same way as the LWJGL 2 backend, including the main module in backends/gdx-backend-lwjgl3 and a test module in tests/gdx-tests-lwjgl3. Everything is wired up with Maven and Eclipse projects so you can test things. I also wired it up with our Ant build, haven't tested that one at all.

It would be amazing if you guys could help test this. I already build snapshots for the new backend, and all the code is merged with master. You can easily switch out the LWJGL 2 backend for the LWJGL 3 backend in Gradle. In your core projects dependencies, change:

compile "com.badlogicgames.gdx:gdx-backend-lwjgl:$gdxVersion"

to

compile "com.badlogicgames.gdx:gdx-backend-lwjgl3:$gdxVersion"

Make sure gdxVersion is set to the latest snapshot version 1.7.3-SNAPSHOT. In your desktop launcher, simply replace LwjglApplicationConfiguration and LwjglApplication with Lwjgl3ApplicationConfiguration and Lwjgl3Application. That's it.

Not implemented yet

  • [ ] Window refresh callback for nicer resize
  • [x] HDPI support. Works out of the box on mac os x, but need to scale mouse coords accordingly. They are reported in logical coords, whereas Graphics reports framebuffer size now.
  • [x] Screen mode change related functions in Lwjgl3Graphics. Just haven't gotten around implementing those. Note that when changing the screen mode (e.g. window -> fullscreen), GLFW returns a new window handle. Lwjgl3Input and Lwjgl3Graphics need to re-register all the GLFW callbacks in that case with the new window handle.
  • [x] Clipboard support without AWT on Mac OS X
  • [x] Fix fullscreen toggling. On Mac OS X, the first windowed -> fullscreen switch fails in weird ways, e.g. clearColor has an effect, but rendering doesn't. Subsequent fullscreen -> fullscreen switches work as intended (but those use glfwSetWindowSize instead of creating a new window). On Window (10) fullscreen switching doesn't work at all on HDPI monitors, need to test on normal monitors. Bug for Windows, Bug for Mac OS X. Should be resolved in GLFW, libGDX side does the proper thing.
  • [x] Custom cursors in Lwjgl3Graphics. Haven't checked how to do that yet.
  • [x] Application icon support. This needs to be covered via tools like PackR
  • [x] Platform-specific multi-window API (Lwjgl3Application#newWindow(ApplicationListener, int width, int height)/newWindow(ApplicationListener, DisplayMode)).
  • [x] Controller support. GLFW comes with its own controller API, should be simply to add that to the controllers extension. There's a bug on Windows in GLFW, where all gamepads are reported by the same name. This makes mapping controller types impossible.
  • [x] OpenGL 3.0 support. We should only need to add that to Lwjgl3Application#createGlfwWindow. The Lwjgl3GL30 implementation is prepared, except for Lwjgl3GL30#glGetBufferPointerv
  • [ ] Mac OS X (potentially Windows and Linux too): glfwSwapBuffers doesn't block in windowed mode if app window is fully behind other window or minimized. Bug with GLFW. Could "fix" it in our own code.
  • [ ] [Lwjgl3Input#getTextInput()](https://github.com/libgdx/libgdx/blob/master/backends/gdx-backend-lwjgl3/src/com/badlogic/gdx/backends/lwjgl3/Lwjgl3Input.java#L240), can't call into Swing/AWT
  • [x] Non-continuous rendering in Lwjgl3Graphics. It's a bit of a bitch. Lwjgl3Input will already call Graphics#requestRendering() in case new input events arrive
  • [ ] Make OpenALAudio thread-safe, put the update on a separate thread

    Known Issues

  • LWJGL 3 is based on GLFW. GLFW and AWT don't play nice with each other. Calling Swing/AWT stuff is thus not possible at the moment.

  • On Mac OS X, you need to pass the JVM argument -XstartOnFirstThread when starting your app. We may be able to fix both things to some extend.
  • If you use the multi-window API, understand that any Runnable you post via Gdx.app.postRunnable() may be executed in such a way that the statics in Gdx, like Gdx.graphics may point to a window other than the one for which the runnable was posted.

Most helpful comment

@badlogic: I understand your argumentation on the limitFPS/vsync but I think you miss something. What if I don't want to enable v-sync because of the one-frame lag but still don't want my CPU or GPU to run at 100%? There is no need for 300 FPS on a 60 HZ monitor. As far as I can see this is currently not possible with the new API.

All 104 comments

We should ensure that this bug is fixed or we should try to fix it.
https://github.com/glfw/glfw/issues/608

We can fix that on our end by checking if the reported position has changed since the last time.

I've had a go at it, besides documented things:

  • no fps options in config
  • resize never gets called, related to screen mode stuff probably
  • no way to get Display.getPixelScaleFactor() ie if hdmi is in effect

Seems to be working fine on Win10

Resize isn't supposed to get called on startup. Does it get called when you resize the window?

The fps options in config are a very bad idea imo. It's either vsync or not. Limiting fps by sleeping the main thread is a terrible thing and results in jank.

I can see what i can do about exposing whether you are running in HDPI mode or not.

Regarding HDPI: we actually now report the real resolution of the framebuffer instead of the logical resolution via Gdx.graphics.getWidth()/getHeight(). A specific flag that says "This is 2x retina" doesn't make a lot of sense imo. You have to accomodate a lot of different screen sizes anyways, which will just work for the 2x retina case as well.

Does Clipboard work? It shouldn't work on mac, because it uses AWT.

Will PRs that implement missing features be merged or will you implement the features anyway?

After some more investigation, resize is called for each frame while window is being resized. Viewports dont like this for whatever reason and stuff is all kinds of broken.
Yeah sleeping to reduce fps is jank, but some way to throttle would be nice if possible.
If real resolution is reported, a flag is not needed indeed.

Regarding HDPI: we actually now report the real resolution of the framebuffer instead of the logical resolution via Gdx.graphics.getWidth()/getHeight(). A specific flag that says "This is 2x retina" doesn't make a lot of sense imo. You have to accomodate a lot of different screen sizes anyways, which will just work for the 2x retina case as well.

Please reconsider, I'd very much like to know in my app whether the hi-dpi mode is active and if it is - what the pixel/point ratio is (to use Apple terminology). For example, I have a 100% UI app. With lwjgl2 backend I launch it on my retina primary monitor and set up the viewport to be in "points", not in pixels (I just divide it by two for now), because otherwise, all UI would be ridiculously small. This works and everything is crisp. But when I drag the window to my secondary, non-retina, monitor, everything is huge, because I can't tell whether or not is the hi-dpi mode active. Graphics already has some Ppi and Density methods, but these don't help much in this case. Something like getLogicalPixelScale() (with less terrible name), which would return 1f on non-retina, 2f on retina, etc. would be very useful and appreciated.

But I may have misunderstood or overlooked something.

I am testing on Linux; getting this exception:

LwjglApplication: Couldn't initialize audio, disabling audio
java.lang.NoSuchMethodError: org.lwjgl.openal.AL.create()V
    at com.badlogic.gdx.backends.lwjgl.audio.OpenALAudio.<init>(OpenALAudio.java:72)
    at com.badlogic.gdx.backends.lwjgl.LwjglApplication.<init>(LwjglApplication.java:85)
    at com.badlogic.gdx.backends.lwjgl.LwjglApplication.<init>(LwjglApplication.java:66)
    at xxxxxxxx.desktop.DesktopLauncher.main(DesktopLauncher.java:38)
Exception in thread "main" java.lang.ExceptionInInitializerError
    at com.badlogic.gdx.backends.lwjgl.LwjglInput.<init>(LwjglInput.java:93)
    at com.badlogic.gdx.backends.lwjgl.LwjglApplication.<init>(LwjglApplication.java:93)
    at com.badlogic.gdx.backends.lwjgl.LwjglApplication.<init>(LwjglApplication.java:66)
    at xxxxxxxx.desktop.DesktopLauncher.main(DesktopLauncher.java:38)
Caused by: java.lang.SecurityException: sealing violation: package org.lwjgl is sealed
    at java.net.URLClassLoader.getAndVerifyPackage(URLClassLoader.java:388)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:417)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    at org.lwjgl.input.Keyboard.<clinit>(Keyboard.java:265)
    ... 4 more

not getting as far as rendering :(

billy1380, that's likely because you didn't replace LwjglApplicationConfiguration and LwjglApplication with Lwjgl3ApplicationConfiguration and Lwjgl3Application everywhere in your desktop launcher.

Thanks @Osaris31

Nice work @badlogic ;) I tested in my game (I edited Lwjgl3Graphics to add OpenGL3).
It works pretty well, no FPS change from the previous backend, no crash.
A couple issues: my InputAdapter doesn't seem to receive mouseMoved anymore, as well as a few keys (Tab, /, ...), but for exemple WASD and touchDown are still received.

Works very nicely... seems to have sorted #3527 too!

@Osaris31 i can confirm this (on Linux). The middle button of the mouse is also not working...but polling via Gdx.input.isButtonPressed works fine.

Everything else works great so far.

Awesome feedback everyone. I'll try tl stabilize it over the next few days! Please keep the feedback coming. I'll think about a solution for HDPI reporting as well.

Oh, and if you report further issues, please always state what OS you are on!

@mbrlabs what flavor of Linux are you on using which window manager?

@Osaris31 what operating system and version? Fullscreen or windowed?

@badlogic Win10, windowed

@Darkyenus here's how i fixed HDPI support. Pending minor changes.

  1. Added Graphics#getBackBufferWidthand Graphics#getBackBufferHeight. These report the physical dimension in pixels of the back buffer we render to in OpenGL. These are the sizes you need to use with glViewport and glScissor, as they expect back buffer coordinates. I added a class called HdpiUtils that you can use to keep working in logical coordinates, even when calling glViewport and glScissor.
  2. Graphics#getWidth and Graphics#getHeight as well as all mouse coordinates are always reported in logical screen coordinates, just like the operating system would report them to you. You can check if you are in HDPI mode by comparing the logical width/height to the back buffer width/height.
  3. ScissorStack and viewports of stage2d have been modified to use HdpiUtils instead of directly calling glViewport and glScissor. Your scenario of dragging a window from a HDPI to a normal DPI monitor and back now works flawlessly without any manual scaling or orther stupid stuff.
  4. If you dislike the impedance mismatch between logical and back buffer coordinates, you can enable HDPI reporting via Lwjgl3ApplicationConfiguration#useHDPI. Everything will then be reported in back buffer coordinates, e.g. Graphics#getWidth() and mouse coords, no logical coordinates to be found.

LwjglGraphics.GetWidth() doesn't return the logical size (as stated in the javadocs), it returns the frame buffer size, or did I miss something?

@badlogic Arch Linux with Cinnamon and windowed

@badlogic alright, i guess i figured it out. I am using the touchDragged of the InputProcessor. I tought it's not called because my camera was not moving (but actually it is). It's simply that screenX and screenY are always 0. In the update method of the Lwjgl3Input you are setting the delta values always to zero. Is that intened? Because if i remove these two lines, it works again

@badlogic it's actually just Gdx.input.getDeltaX() and Gdx.input.getDeltaY() which are not working correctly...screenX and screenY of the InputProcessor callbacks are fine

@badlogic Perfect thanks! So now the "hi-dpi" mode is active by default? i.e. with default settings, when running on retina display, getWidth and getBackBufferWidth will differ? That might break some applications as this behavior (or what we have now) is opt-in in in lwjgl2 backend. Also, the useHDPI for using "most pixels available" is IMO a bit misleading name, because it is not really hi-dpi anymore, it is just making things "small".

What about solving both of these problems with enum setting:

enum HDPIModes {
    NO_HDPI, //Current default lwjgl2 behavior, default and simple, UI is never small, but not crisp on retina
    HDPI, //Your solution, getWidth differs from getBackBufferWidth on retina, for apps that know how to handle it
    FORCE_HDPI; //(or better name), similar to HDPI but getWidth always returns getBackBufferWidth. I am not sure what would it be good for, but somebody will probably find a good use.
}

That way, with NO_HDPI as default, non retina-aware games won't break down when launched on retina display, but others can still use it. Maybe I am overthinking it though.

@mbrlabs thanks for figuring it out. DeltaX/Y should work, i'll look into it!

@Darkyenus i think we need to educate users on HDPI. As such, i prefer the correct way of doing it, that is separate logical resolution from physical resolution, which is option 2 in your enum. GLFW introduced this, and i think it's a good way to go about things. The not crispyness of option 1 needs to die. And again, the only thing people need to watch out for in option 2 is glViewport, glScissor and glReadPixels. Something pretty much no libGDX user uses manually anyways. Any usage inside of the core libs will be Hdpi aware.

@mbrlabs thanks for reporting, this is fixed now (together with other polling methods).

great! i will keep an eye on this backend.
The multi-window support looks very interesting.

@badlogic Ok, that will lead to (hopefully) better applications, but has steeper learning curve. In that case, do we need the useHDPI flag at all? Hi-DPI is always enabled, so the name is a bit confusing and I am not sure if it is worth having, same effect can be achieved by just calling different methods, so it only adds internal complexity for no real benefit. At least I can't see any use case.

  • In Lwjgl3Application#loop: It is probably better to reuse the closedWindows array instead of creating it inside the loop every frame.
  • The callbacks should be release()d once they are not used any more and GLFW should be glfwTerminate()d. You can run the program with -Dorg.lwjgl.util.DebugAllocator=true to have the location of memory leaks reported.
  • In Lwjgl3Application#createGlfwWindow: Instead of parsing the GL_VERSION and using glfwExtensionSupported you can use the GLCapabilities instance returned by GL.createCapabilities() to check for supported versions or extensions.
  • In Lwjgl3Application#initializeGlfw: You create a glfw error callback but don't ever set it with glfwSetErrorCallback. This should be done before glfwInit so initialization errors are reported as well.

@FortressBuilder fantastic feedback, thanks a ton! Fixing!

Ok folks, i added the last missing bits and pieces. This should be mostly functional for most apps out there. See the initial issue for minor features that still need to be implemented. Happy to receive PRs for some of them (e.g. GL30 support).

I'll implement the windowing API and the other missing features tomorrow night (controller support).

@badlogic, I just tested on Win10 and it works well.
I then turned on GL30 by adding _this.gl30 = new Lwjgl3GL30();_ in _public Lwjgl3Graphics(Lwjgl3Window window)_ and all my GL30 shaders work well so everything seems fine!
Thanks

@badlogic actually there is a small issue: keyDown and keyUp of InputAdapter receive Qwerty code with my Azerty keyboard. This is strange because for example TextInput works well.

Keycodes are scan codes in GLFW. I see the same issue on my German
keyboards. We'll see if we can fix this somehow.
On Jan 3, 2016 12:06 AM, "Osaris31" [email protected] wrote:

@badlogic https://github.com/badlogic actually there is a small issue:
keyDown and keyUp of InputAdapter receive Qwerty code with my Azerty
keyboard. This is strange because for example TextInput works well.

—
Reply to this email directly or view it on GitHub
https://github.com/libgdx/libgdx/issues/3673#issuecomment-168437560.

Some more things:

  • User-created cursors should also be destroyed with glfwDestroyCursor in Cursor.dispose, not only the standard cursors.
  • The error callback is still not correctly set. It should be done like this:

errorCallback = GLFWErrorCallback.createPrint(System.err); GLFW.glfwSetErrorCallback(errorCallback);

  • It is good form to call glfwTerminate in Lwjgl3Application.dispose because this will make sure that all resources used by GLFW are properly cleaned up.

Running the Lwjgl3DebugStarter with the error callback correctly set up gives a GLFW_NO_CURRENT_CONTEXT error at the glfwSwapInterval call in Lwjgl3Application, line 382. The docs say this occurs when the function is called without a current context, so I suggest moving the call after the glfwMakeContextCurrent.

@FortressBuilder amazing feedback. I believe i fixed everything up. Please keep it coming!

All other windows freeze, when one window is moved/dragged, is this intended behavior?

@intrigus this has been fixed, thanks for reporting!

@badlogic Lwjgl3ApplicationConfiguration#setBackbufferConfig doesn't set the samples. Probably an oversight?

@FortressBuilder Yes, because i suck. Fixed!

LWJGL3 fails to launch on my laptop (Windows 10) and throws this error instead:

Can't load IA 32-bit .dll on a AMD 64-bit platform

Looks like 64-bit natives fail to load/don't exist and so it tries 32-bit dlls instead.

DesktopLauncher:

final Lwjgl3ApplicationConfiguration configuration = new Lwjgl3ApplicationConfiguration(); configuration.setTitle("Fallen"); new Lwjgl3Application(new Application(), configuration);

The resize method isn't being called when going to fullscreen mode at runtime. I do get resize events when resizing the window and when alt-tabbing in/out of the fullscreen window, just not when going from windowed to fullscreen.

(gdxVersion 1.8.0, Windows 10, java 1.6.0_45 64-bit)

I also suffer from the "Can't load IA 32-bit .dll on a AMD 64-bit platform" error on Win 7, x64.

Adding the debug, I am now getting a null pointer:

java.lang.NullPointerException
at org.lwjgl.Version.getVersionImpl(Version.java:48)
at org.lwjgl.Version.getVersion(Version.java:35)
at org.lwjgl.system.Library.(Library.java:39)
at org.lwjgl.system.MemoryUtil.(MemoryUtil.java:56)
at org.lwjgl.system.libffi.Closure.(Closure.java:57)
at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.initializeGlfw(Lwjgl3Application.java:64)
at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.(Lwjgl3Application.java:73)
at com.ruin4x.desktop.DesktopLauncher.main(DesktopLauncher.java:10)
[LWJGL] Version: 3.0.0b SNAPSHOT
[LWJGL] OS: Windows 7 v6.1
[LWJGL] JRE: 1.8.0_66 amd64
[LWJGL] JVM: Java HotSpot(TM) 64-Bit Server VM v25.66-b18 by Oracle Corporation

@DorthLous @Ocordu please file an issue for this, specifying what JVM you use (32-, 64-bit) and what Windows version.

@anonl this has been fixed!

If you don't mind, I won't open the issue, as the issue seems resolved since my last Gradle dependency update. If you're still interested in the JVM and Win, the info are in the trace above. Thank you for your great work.

@DorthLous @Ocordu @badlogic
This is likely not a bug (in libGDX).

I tripped upon exactly this error ([email protected](Version.java:48)) and message Can't load IA 32-bit .dll on a AMD 64-bit platform on Windows 7 x64, regardless of JVM.

This happens if some dependencies get included twice, or if both the LWJGL and LWJGL 3 backend get included, or if you somehow end up with incompatible versions in your gradle cache.

For my case, I was stupid and included gdx-tools in my root gradles :core, gdx-tools having the old LWJGL backend as a dependency leading to both backend's dependencies being included in the build.

Cleaning the Gradle cache may also help in other cases.

Note: If you run into this, you can enable additional debug output with System.setProperty("org.lwjgl.util.Debug", "true");.
Note: If in doubt, look into the JAR generated by building and see if e.g. the LWJGL native .dlls are included twice.

The LWJGL 3 backend seems to run quite nicely for my smallish (10-20KLOC) projects so far.

Thanks a ton, I had real difficulty figuring this one out. gdx-tools
depending on the old LWJGL backend is a bit of a bummer. I need to find a
solution for that.
On Jan 13, 2016 1:18 PM, "mhilbrunner" [email protected] wrote:

@DorthLous https://github.com/DorthLous @Ocordu
https://github.com/Ocordu @badlogic https://github.com/badlogic
This is likely not a bug (in libGDX).

I tripped upon exactly this error ([email protected](Version.java:48))
and message Can't load IA 32-bit .dll on a AMD 64-bit platform on Windows
7 x64, regardless of JVM.

This happens if some dependencies get included twice, or if both the LWJGL
and LWJGL 3 backend get included, or if you somehow end up with
incompatible versions in your gradle cache.

For my case, I was stupid and included gdx-tools in my root gradles :core,
gdx-tools having the old LWJGL backend as a dependency leading to both
backend's dependencies being included in the build.

Cleaning the Gradle cache may also help in other cases.

Note: If you run into this, you can enable additional debug output with System.setProperty("org.lwjgl.util.Debug",
"true");.
Note: If in doubt, look into the JAR generated by building and see if e.g.
the LWJGL native .dlls are included twice.

The LWJGL 3 backend seems to run quite nicely for my smallish (10-20KLOC)
projects so far.

—
Reply to this email directly or view it on GitHub
https://github.com/libgdx/libgdx/issues/3673#issuecomment-171274904.

@badlogic Correct me if I'm wrong:
The SharedLibraryLoader probably extracts the dlls to the same folder. Both (lwjgl-backends) have a lwjgl.dll as a dependency. Since they are exported to the same folder it doesn't work. The solution may be to rename lwjgl.dll to lwjgl3.dll. The 32bit on 64bit windows errors are thrown, because in lwjgl 2 there was a lwjgl.dll (32bit) and a lwjgl64.dll . Lwjgl 3 has a lwjgl.dll (64bit) and a lwjgl32.dll.

That is correct. The problem is, that the file names are not under our
control. I'll hack up our loader for the LWJGL3 backend.
On Jan 13, 2016 1:40 PM, "intrigus" [email protected] wrote:

@badlogic https://github.com/badlogic Correct me if I'm wrong:
The SharedLibraryLoader probably extracts the dlls to the same folder.
Both (lwjgl-backends) have a lwjgl.dll as a dependency. Since they are
exported to the same folder it doesn't work. The solution may be to rename
lwjgl.dll to lwjgl3.dll. The 32bit on 64bit windows errors are thrown,
because in lwjgl 2 there was a lwjgl.dll (32bit) and a lwjgl64.dll . Lwjgl
3 has a lwjgl.dll (64bit) and a lwjgl32.dll.

—
Reply to this email directly or view it on GitHub
https://github.com/libgdx/libgdx/issues/3673#issuecomment-171279663.

I'm having an issue where mouse moves are happening faster than they can be processed in the GDXInputProcessor. I've updated my processor to do nothing (thinking it was my code causing the backlog), but it's still happening. I think the way the LWJGL events are being processed is causing fast moving mouse events to drag it down and long after I stop moving the mouse I continue to receive events. This is on Linux with 1.8.0.

What specific Linux distri and version? How long is "long"?
On Jan 14, 2016 8:22 PM, "Matt Hicks" [email protected] wrote:

I'm having an issue where mouse moves are happening faster than they can
be processed in the GDXInputProcessor. I've updated my processor to do
nothing (thinking it was my code causing the backlog), but it's still
happening. I think the way the LWJGL events are being processed is causing
fast moving mouse events to drag it down and long after I stop moving the
mouse I continue to receive events. This is on Linux with 1.8.0.

—
Reply to this email directly or view it on GitHub
https://github.com/libgdx/libgdx/issues/3673#issuecomment-171750422.

It was happening on i3 in openSUSE 64-bit. I switched to GNOME 3 and everything seems to be working fine. I'll do some additional testing when I switch back to i3 and let you know if it persists.

Another issue,
it seems that the LifecycleListeners are not implemented at all in LWJGL3 backend. Gdx.app.addLifecycleListener is correct, but removeLifecycleListener is not and added listeners are never called, for anything.

I've got an issue on my app where the drawing area is confined to a 1/4 size of the window at the bottom left when the app opens, but if I move the window, it updates itself to be the full-size of the window. I'm on a retina display MacBook Pro. I can't reproduce the problem on a fresh new Gdx app, so I think it's related to my use of the OrthographicCamera.

I just wanted to post this now in case anyone had any ideas before I started to investigate myself.

If you use glViewport or glScissor, make sure you use the values returned
by Gdx.graphics.getBackBufferWidth()/Height(). The reasons are explained in
the last release blog post.

On Mon, Jan 18, 2016 at 9:06 AM, Thomas Leese [email protected]
wrote:

I've got an issue on my app where the drawing area is confined to a 1/4
size of the window at the bottom left when the app opens, but if I move the
window, it updates itself to be the full-size of the window. I'm on a
retina display MacBook Pro. I can't reproduce the problem on a fresh new
Gdx app, so I think it's related to my use of the OrthographicCamera.

I just wanted to post this now in case anyone had any ideas before I
started to investigate myself.

—
Reply to this email directly or view it on GitHub
https://github.com/libgdx/libgdx/issues/3673#issuecomment-172457359.

@badlogic Thanks. After some investigation I've discovered that the issue happens when I call begin()/end() on a FrameBuffer. I'm not too familiar with how frame buffer objects work underneath, could they be calling that, and then I need to reset it at the end?

Yes, framebuffers will set the viewport. Once you are done, the viewport
needs to be reset to the windows backbuffer size. This should already
happen. Please file an issue with a reproduction case so we can verify and
fix this.
On Jan 18, 2016 12:42 PM, "Thomas Leese" [email protected] wrote:

@badlogic https://github.com/badlogic Thanks. After some investigation
I've discovered that the issue happens when I call begin()/end() on a
FrameBuffer. I'm not too familiar with how frame buffer objects work
underneath, could they be calling that, and then I need to reset it at the
end?

—
Reply to this email directly or view it on GitHub
https://github.com/libgdx/libgdx/issues/3673#issuecomment-172505353.

@badlogic Great, thanks. Yep, I had to add HdpiUtils.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); after fbo.end(). I'll create a reproduction case then open a new issue.

@badlogic I've submitted an issue. https://github.com/libgdx/libgdx/issues/3746

Note: it looks like LwjglInput reported some keys as "key typed" events, which Lwjgl3Input does not anymore. In my case, the Return key. Adjusting my code has been easy, I just wonder if that's intended/tolerated behaviour.

On Win7 when minimizing app window resize method is called with width and height equal 0. Might be some issue with GLFW because the wrong size is set here.

Lwjgl3Input does not implement getCurrentEventTime(), it always returns 0. This breaks gesture detectors; for example flinging in ScrollPane does not work.

Using openjdk-7-jdk Version: 7u95-2.6.4-0ubuntu0.15.10.1 with Lwjgl3 results in

# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007fceef766031, pid=13461, tid=140527389366016
#
# JRE version: OpenJDK Runtime Environment (7.0_95) (build 1.7.0_95-b00)
# Java VM: OpenJDK 64-Bit Server VM (24.95-b01 mixed mode linux-amd64 compressed oops)
# Derivative: IcedTea 2.6.4
# Distribution: Ubuntu 15.10, package 7u95-2.6.4-0ubuntu0.15.10.1
# Problematic frame:
# C  [libGL.so.1+0xa6031]

Works fine with oracle-jdk.
I can provide the full log if needed.

@badlogic
Gdx.input.getCurrentEventTime() returns always zero.

private long currentEventTime
in Lwjgl3Input
is never set.

As a result, GestureListener#fling does not report correct velocities.

Am I missing something?

I'm having an issue with multi window support, closing a window sometimes results in native crash:

Stack: [0x00007fff4feb8000,0x00007fff506b8000],  sp=0x00007fff506b2e38,  free space=8171k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [libobjc.A.dylib+0x14d7]  objc_msgSend+0x17
J 1184  org.lwjgl.system.JNI.invokePV(JJ)V (0 bytes) @ 0x00000001125d1c76 [0x00000001125d1bc0+0xb6]
j  org.lwjgl.glfw.GLFW.glfwDestroyCursor(J)V+20
j  com.badlogic.gdx.backends.lwjgl3.Lwjgl3Cursor.disposeAll()V+62
j  com.badlogic.gdx.backends.lwjgl3.Lwjgl3Graphics.dispose()V+7
j  com.badlogic.gdx.backends.lwjgl3.Lwjgl3Window.dispose()V+22
j  com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.loop()V+305
j  com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.<init>(Lcom/badlogic/gdx/ApplicationListener;Lcom/badlogic/gdx/backends/lwjgl3/Lwjgl3ApplicationConfiguration;)V+246
j  io.piotrjastrzebski.aitest.desktop.DesktopLauncher.main([Ljava/lang/String;)V+36

I have hard time creating a repro case, but Im quite sure that stuff gets disposed twice for some reason. Perhaps clearing the static arrays after dispose would help with the symptoms. Or maybe Im just doing something stupid.

@badlogic

When I click a scene2d Button using the mouse, I receive the TouchDown event immediately, and my button is drawn using the "Down" drawable as expected.

However, when I touch the touch-screen of my laptop, the TouchDown event is not triggered, and I still see the "Up" drawable.

If I touch a button, and then slightly drag my finger on the button, I will get the TouchDown event (I think this is triggered when I leave the Tap square). This happens most of the times, not every time.

Happens in Windows 10.

Any ideas?

On some computers (windows with certains Intel HD), calling GLFW.glfwGetVideoMode() before GL.createCapabilities(), like it is done in createGlfwWindow, will cause a crash.
Removing the call made it work, it might also work if you make the call after GL.createCapabilities() but I didn't try.

I just switched from lwjgl 1.5.3 to lwjgl3 1.9.1 (linux) and I noticed the gl viewport is no longer updated on resize.

Is window width/height supposed to be 0 when app is minimized ? logicalWidth and logicalHeight is being set to 0 and crashing with a NaN when I use methods like Camera#getPickRay(..)

A simple fix is to ignore callback when size is 0

private GLFWFramebufferSizeCallback resizeCallback = new GLFWFramebufferSizeCallback() {
        @Override
        public void invoke(long windowHandle, final int width, final int height) {
            if(width == 0 || height == 0)
                return;

LifecycleListener.dispose() method is never called. I guess it should be called in the cleanup() method or just after it.

@Osaris31 could you please create a separate issue for your problem?
A SSCCE would be good.

Values reported by Gdx.input.getX/Y() are 0, 0 until first mouse move/touch. While it is not very likely it would cause bugs, it works as expected on Lwjgl backend.

Has there been any success with solving the following:

Can't load IA 32-bit .dll on a AMD 64-bit platform

Unfortunately my project depends on gdx.tools and LWJGL3. Combining the two doesn't seem to mesh as mentioned earlier:

The SharedLibraryLoader probably extracts the dlls to the same folder. Both (lwjgl-backends) have a lwjgl.dll as a dependency. Since they are exported to the same folder it doesn't work. The solution may be to rename lwjgl.dll to lwjgl3.dll. The 32bit on 64bit windows errors are thrown, because in lwjgl 2 there was a lwjgl.dll (32bit) and a lwjgl64.dll . Lwjgl 3 has a lwjgl.dll (64bit) and a lwjgl32.dll.

Refreshing the gradle cache seems to have no effect on this issue.

For the checklist, will we be picking this (native file dialogs)up? I suspect it's what you were referring to on the LibGDX blog as something to add to LWJGL3Window.

@cypherdare this should be available, when https://github.com/libgdx/libgdx/pull/4104 has been merged.

Since 1.9.3 window resizing doesn't work on osx. Minimising or attempting to change the size of the window causes resize(0, 0) to be called immediately. 1.9.2 works fine.

@piotr-j Are you using window size limits? I just discovered a couple days ago that on OSX only, if you set any of the four limits to something besides "don't care" it will do what you described. Leaving all of them as "don't care" did not trigger the issue. Setting them all to some value (even 0 or 9999) fixed it so there's a work around we could put in.

@cypherdare i have no idea what those are, so probably not. Where are the settings for that?

@piotr-j It's in the Lwjgl3ApplicationConfiguration. Try setting config.setWindowSizeLimits(0, 0, 9999, 9999) and see if it affects the issue.

@piotr-j I reported the same thing here https://github.com/libgdx/libgdx/issues/3673#issuecomment-177606278 but on Windows it's only called with 0 when window is being minimized.
I've used if (width == 0 && height == 0) return; in resize(...) as simple workaround.

@cypherdare @kotcrab setting the window size limits to non default values fixes the problem. Perhaps it helps on windows as well? Looks like its a bug in GLFW.

@piotr-j config.setWindowSizeLimits(0, 0, 9999, 9999) doesn't help on Windows.

@piotr-j @kotrab I think we might be talking about two different issues. One where an unnecessary resize(0, 0) call is made when minimizing in Windows, and one where the window is actually physically resized to 0, 0 when manually resizing a window on OSX. The second issue is the one where config.setWindowSizeLimits(0, 0, 9999, 9999) seems to help.

@badlogic I've found 2 small issues:

1) Lwjgl3ApplicationConfiguration has no addIcon function.

2) When I start Hiero (from GDX-tools) I get this (it works with LWJGL 2):

Exception in thread "AWT-EventQueue-0" java.lang.SecurityException: sealing violation: package org.lwjgl.opengl is sealed
    at java.net.URLClassLoader.getAndVerifyPackage(URLClassLoader.java:399)
    at java.net.URLClassLoader.definePackageInternal(URLClassLoader.java:419)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:451)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at com.badlogic.gdx.backends.lwjgl.LwjglGraphics.setVSync(LwjglGraphics.java:557)
    at com.badlogic.gdx.backends.lwjgl.LwjglCanvas.initialize(LwjglCanvas.java:123)
    at com.badlogic.gdx.backends.lwjgl.LwjglCanvas.<init>(LwjglCanvas.java:68)
    at com.badlogic.gdx.tools.hiero.Hiero.<init>(Hiero.java:182)
    at com.badlogic.gdx.tools.hiero.Hiero$21.run(Hiero.java:1579)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)


I'm using gdxVersion = '1.9.4-SNAPSHOT' on Ubuntu 16.04
Java is /usr/lib/jvm/java-8-openjdk-amd64/bin/java

btw. Thanks for your work! :+1:

I may be a total ass for reporting this here, but I just tried the gdx-tests-lwjgl3 starter app on a new libgdx cloned repo (latest & greatest version) and got the below. Are these not changed or implemented just yet?

[LWJGL] GLFW_INVALID_VALUE error
Description : Invalid window size limits
Stacktrace :
org.lwjgl.glfw.GLFW.glfwSetWindowSizeLimits(GLFW.java:1968)
com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.createGlfwWindow(Lwjgl3Application.java:415)
com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.createWindow(Lwjgl3Application.java:366)
com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.(Lwjgl3Application.java:107)
com.badlogic.gdx.tests.lwjgl3.Lwjgl3TestStarter.main(Lwjgl3TestStarter.java:45)

@xGnoSiSx Try setting applicationConfig.setWindowSizeLimits(0, 0, 9999, 9999);.

There is a GLFW bug (fixed here) that has not trickled down to an LWJGL release yet.

regarding useHDPI:

How do I get real screen density? The Gdx.app.graphics.density is the same value regardless of useHDPI value.

Also, contrary to https://github.com/libgdx/libgdx/issues/3673#issuecomment-167869299, I get doubled pixels when useHDPI is false. (running on a rMBP with OS X 10.11.6)

I'm testing it with libgdx 1.9.5-SNAPSHOT

There is a bug with controller support. It doesn't exist(I think)

Exception in thread "main" com.badlogic.gdx.utils.GdxRuntimeException: Error creating controller manager: com.badlogic.gdx.controllers.lwjgl3.Lwjgl3ControllerManager
    at com.badlogic.gdx.controllers.Controllers.initialize(Controllers.java:105)
    at com.badlogic.gdx.controllers.Controllers.addListener(Controllers.java:52)
    at com.qookie.ludumdare.LDMain.create(LDMain.java:74)
    at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Window.initializeListener(Lwjgl3Window.java:275)
    at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Window.update(Lwjgl3Window.java:242)
    at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.loop(Lwjgl3Application.java:138)
    at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.<init>(Lwjgl3Application.java:107)
    at com.qookie.ludumdare.desktop.DesktopLauncher.main(DesktopLauncher.java:13)
Caused by: com.badlogic.gdx.utils.reflect.ReflectionException: Class not found: com.badlogic.gdx.controllers.lwjgl3.Lwjgl3ControllerManager
    at com.badlogic.gdx.utils.reflect.ClassReflection.forName(ClassReflection.java:30)
    at com.badlogic.gdx.controllers.Controllers.initialize(Controllers.java:102)
    ... 7 more
Caused by: java.lang.ClassNotFoundException: com.badlogic.gdx.controllers.lwjgl3.Lwjgl3ControllerManager
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at com.badlogic.gdx.utils.reflect.ClassReflection.forName(ClassReflection.java:28)
    ... 8 more

@badlogic: I understand your argumentation on the limitFPS/vsync but I think you miss something. What if I don't want to enable v-sync because of the one-frame lag but still don't want my CPU or GPU to run at 100%? There is no need for 300 FPS on a 60 HZ monitor. As far as I can see this is currently not possible with the new API.

There seems to be really bad input lag for text fields with the lwjgl3 backend only when vsync is enabled. I created a small test and it demonstrates the issue on my machine (ubuntu 16.04). The key typed callback is really slow - key up and down are normal. Also, the lwjgl backend is fine, just lwjgl3.

  • video demo: the output to the screen is just tied to an input processor, you can see how the key typed one lags behind the others if you type fast. Once I disable vsync it is fixed.
  • source

@thekeenant That looks pretty severe. Does this still happen when you turn off vsync but "simulate it" by putting Thread.sleep(1000/60) (or more) into render()?

@Darkyenus I get the same effect with vsync off and Thread.sleep(1000/60) . Hard to say if the effect is compounded with both vsync on and thread sleep on. updated this gist

Edit: Can't reproduce on Windows 10 with the same hardware.

I can't reproduce it on OSX 10.11.6, even with high sleep times, so this is probably not libGDX but GLFW related. The closest thing I found on their issue tracker to this is this issue, but I'm not sure if it is the same problem.

@Darkyenus Yeah I noticed that after I posted and it definitely looks related... Might try plain GLFW and see what happens. For now I can stick with good old lwjgl - thanks for the help!

I've opened the following PR libgdx/libgdx#5443 . This is a fix for mouses with "continuous" wheels or osx touch pads. These devices can report scroll events that are lower than one. They also support acceleration and report scroll events greater than one. Without the PR the scroll is ultra fast, because small movements (e.g. a scroll of 0.1) are rounded up to scroll events of 1 unit.

This only fixes vertical scrolling. Horizontal could be better propagated from lwjgl to libgdx, but this would require some API changes.

Could anybody review this PR ?

I can report that running default template project (generated without any extensions or other things) on macos with this backend causes crash:

java.lang.ExceptionInInitializerError
  at org.lwjgl.glfw.GLFW.glfwCreateWindow(GLFW.java:1647)
  at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.createGlfwWindow(Lwjgl3Application.java:442)
  at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.createWindow(Lwjgl3Application.java:391)
  at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.createWindow(Lwjgl3Application.java:379)
  at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.<init>(Lwjgl3Application.java:108)
  at org.rexcellentgames.burningknight.desktop.DesktopLauncher.main(DesktopLauncher.java:134)
Caused by: java.lang.IllegalStateException: GLFW windows may only be created on the main thread and that thread must be the first thread in the process. Please run the JVM with -XstartOnFirstThread. For offscreen rendering, make sure another window toolkit (e.g. AWT or JavaFX) is initialized before GLFW.

Tried running with -XstartOnFirstThread, getting the same result. Tried every possible fix found on web - no result.

Tried running with -XstartOnFirstThread, getting the same result. Tried every possible fix found on web - no result.

I've never seen _this_ fail. Make sure you set this as a VM parameter, not as a command line argument.

@code-disaster I'm not sure what in lwjgl3 backend causes it, but anyway, I tried every single possible way to fix it suggested online and dug up the source, yet did not find a fix. Had to roll my huge codebase back to lwjgl2 backed to get mac support working. It's not too bad, but I really miss some features :x

@egordorichev If you are adding -XstartOnFirstThread to the launch options in IntelliJ it does not work. You have to add it to the run task.

task run(dependsOn: classes, type: JavaExec) {
    main = project.mainClassName
    classpath = sourceSets.main.runtimeClasspath
    standardInput = System.in
    workingDir = project.assetsDir
    ignoreExitValue = true
    jvmArgs '-XstartOnFirstThread'
}

From "Not implemented yet":
"Mac OS X (potentially Windows and Linux too): glfwSwapBuffers doesn't block in windowed mode if app window is fully behind other window or minimized. Bug with GLFW. Could "fix" it in our own code."
https://github.com/glfw/glfw/issues/680 closed, its mean that gdx-backend-lwjgl3 was fixed?

As the issue was closed as part of glfw 3.3 and lwjgl 3.2.1 is using it, this should be fixed (at least in 1.9.10+).

Given this appears to be completed, I'll close this. We can re-open as needed or create a new issue/PR later. Thanks everyone for the hard work & comments :)

Was this page helpful?
0 / 5 - 0 ratings