LWJGL3 moves to GLFW?

Why? :slight_smile:

GLFW is a very stable library and supports all the stuff old LWJGL windowing system tried to accomplish. It will open the door to some nice features like multi-monitor and multi-window support.

The library is getting stripped down quite a lot. No more utility functions (like vecmath, color), will just be the bare minimum.

The plan for 3.0 is that GLFW will be just one of the possible window & context management back-ends. Like davedes said, it’s stable, has a clean API and more features than the native display in LWJGL 2.x, has a very active developer and a relatively big community around it. Also, if we ignore Java-specific features (applet integration etc), it perfectly matches LWJGL’s requirements.

There are some minor issues though. Its OpenGL context management is not as rich as LWJGL’s, but it’s good enough for most use cases and getting better over time. The MacOSX implementation is also problematic, it assumes that all API calls will be made on the main thread (would require -XstartOnFirstThread). I have implemented a workaround for that, but I’m not sure if it will be robust enough. Not that it’s GLFW’s fault, all cross-platform windowing systems do the same thing because of how OSX is designed. Anyway, the point is that GLFW support is fully functional in 3.0 now, but it might not be good enough for everyone.

There hasn’t been much work on an alternative back-end so far, except for JGLFW, which is a GLFW* implementation in “pure” Java. This is not to be confused with this JGLFW, which is another GLFW wrapper. Our JGLFW uses 3.0’s new binding capabilities to call into any system APIs required to implement GLFW, in 100% Java code, without having to write a single line of C. For example here are parts of the Windows and Linux implementations. Having a different implementation that does the same thing might seem pointless, except maybe for the natural event callbacks (native -> Java callbacks are really awkward in JNI) and slightly better performance, but it does prove a few things:

  • We could just as easily implement a different back-end. Even LWJGL 2.x could be implemented in terms of 3.0 in a matter of days.
  • Anyone that doesn’t like how LWJGL does things could implement their own back-end. Note that all OS-specific APIs (including OpenGL context management ones) are publicly available in 3.0, under the new org.lwjgl.system package.
  • The 3.0 code generator is powerful** and doing everything in Java is a huge productivity boost. Even if the code looks like shit. Though it can be much better using a different JVM language (Scala, Kotlin etc), especially pointer arithmetic and struct interactions.
  • Using pure Java code significantly lowers the bar for contributions. Unless a new API call is involved, a patch could be implemented, tested and submitted without the contributor having to set up a native build system.

When 3.0 is released there will be of course an “official” windowing API like 2.x has. With obvious changes, like going to an instanced Display vs the static in 2.x. There might also be static APIs that match 2.x to reduce the porting effort. It’s too early to make promises, but hopefully the back-end will be pluggable and you will certainly be able to use a concrete back-end directly (e.g. GLFW), if you choose so.

* based on a beta snapshot of GLFW 3.0.0, has not been updated to the latest version yet
** currently missing ObjC support, but it’s coming


OT: If you liked any of the above and want it done sooner, feel free to contribute! I mostly need help with porting the OpenGL extension templates. It’s too much grunt work for one person; they are so many and I’ve also made it a requirement that all API bindings be fully documented. Here’s an example of the generated javadoc and here’s the source template. The template DSL supports many shortcuts and layout is done automatically by the generator, but it’s still tons of work that needs to be done.

Btw, javadoc in bindings happens to be my favorite 3.0 feature so far. Nothing beats having inline GL/CL function documentation one shortcut away, within your IDE.

The amount of work, porting, potential problems later on and all that outweigh the benefits of doing this, as I see it

but hey, who am I to question the lwjgl devs.

I like GLFW, it is very lightweight. Eg, you can see its whole API here.

With -XstartOnFirstThread GLFW works fine on OSX, but fails catastrophically if anything (anything) is done with AWT. I fixed this for JGLFW using TLS and some small changes to GLFW. I did a PR and they merged some of it into GLFW, but not all. Unfortunately the discussion is gone now that the elmindreda/glfw repo has been changed to glfw/glfw.

I ran into a similar issue with AWT on Linux, but I couldn’t fix it as easily. In the end I gave up and for Spine I use LWJGL for Windows and Linux and JGLFW for OSX.

An API that abstracts multiple backends is neat, but I am not sure anyone has really needed the choice of backend. People want the LWJGL API to work, nothing more. What it does under the covers is not important, unless something goes wrong and needs fixing or new features. In that case, the stuff under the covers (which includes building, Java and natives) should be as simple as possible so people can contribute easily. I have not looked at 3.0 closely, but in the past I have not been able to contribute to LWJGL.

Personally I would rather see fewer layers and less complexity under the covers. Using GLFW is a good way to get that. Not only is GLFW nice, simple, and easy to trace through, using it pushes a lot of the effort down the line. LWJGL could then focus on proper AWT integration and the rest of what it wants to add. GLFW can merge PRs.

Has LWJGL considered gdx-jnigen? It’s pretty amazing to be able to do a native build so easily. Also it is extremely convenient to have native code inline in your Java code (though this is optional).

Will LWJGL3 break compability with previous versions?

I for one welcome the change.But as Nate stated, GLFW has it’s issues too, so testing will be needed. Also not sold on the code generator yet. Maybe the GL header parserwehave in JGLFW can help with the extensions?

Yes, its a clean rewrite of the API to better support new features instead of trying to shoehorn them into the existing API which wasn’t designed to support things like multiple windows, monitors, keyboards & mice, etc.

[quote=“Nate,post:5,topic:44251”]
There have been some fixes to AWT lately to enable better interop with JavaFX, which might help with GLFW too. I haven’t had time to test this yet, but it’s in Java 8 (not sure if it’s been back-ported to 7u40 too). But in any case, requiring both a JVM start-up flag and a specific JRE is unfortunate for a supposedly cross-platform library, that’s why I don’t feel comfortable committing to GLFW yet. I do like everything else about it though.

[quote=“Spasi,post:3,topic:44251”]
I am inclined to agree with you. The LWJGL API might just end being a simple and more user friendly wrapper around a specific implementation. With just enough room for the LWJGL devs to change it without breaking user apps. I’m really open to suggestions and contributions on this specific matter and will work on what most people think is right/better. Personally, I will probably be using the lower level bindings directly in my own projects (mostly because those are/will be available much earlier than the 3.0 release).

[quote=“Spasi,post:3,topic:44251”]
Writing native code is not a problem, simply because there’s no native code to write. The only hand written parts in 3.0 are callbacks from C to Java and a few macros and utility functions. Everything else (and I really mean everything) is a simple as: cast the JNI method arguments to the proper C type, then call the native function. All the complexity has been moved to Java code. Even for as complicated methods as glShaderSource(int shader, CharSequence… strings), there’s no reason to do anything in C. For example, why use JNI’s GetStringChars or NewStringUTF, when you can do your own encoding/decoding to/from ByteBuffers, in Java, and just pass pointers around. Another benefit is simplified/quicker debugging, when something breaks you know the problem is in Java code when the native binding is so simple. It will also be very simple to convert if we get foreign function interface (FFI) support in Java 9.

[quote=“badlogicgames,post:7,topic:44251”]
I’ve already hacked the 2.x generator to spit out the 3.0 template format. There’s also a tool in 3.0 that converts #define blocks and function definitions from C code to the template syntax. That’s the easy part, you only have to fill in some modifiers where necessary (which have been simplified considerably compared to the annotations we used in 2.x). The real pain is filling in the documentation (but as I said, totally worth it!).

[quote=“Mac70,post:6,topic:44251”]
What kappa said, but I would also like to add that the majority of user code goes into calling AL/CL/GL methods. Those will remain compatible with 2.x, except for a few bug fixes or additions here and there.

PS. Sorry for the late reply, but my daughter was born yesterday. ;D

[quote=“badlogicgames,post:7,topic:44251”]
This is off-topic, but there’s another thing I’d like to say about the generator. It does many things better than the old one, but the primary motivation behind the new implementation was compile-time “type-safety”. For example, you can write:

// C function
int XConvertSelection(Display *display, Atom selection, Atom target, Atom property, Window requestor, Time time);

// LWJGL definition
int.func(
	"XConvertSelection",
	"Requests that the specified selection be converted to the specified target type.",

	Display_p.IN("display", "the connection to the X server"),
	Atom.IN("selection", "the selection atom"),
	Atom.IN("target", "the target atom"),
	Atom.IN("property", "the property name or $None"),
	Window.IN("requestor", "the requestor window"),
	Time.IN("time", "the time. You can pass either a timestamp or ${"X".link("CurrentTime")}")
)

If you ignore the alien syntax (this is Kotlin code, the “int.func” is a method call on a variable called “int”, not the Java type int), this is more or less just like the C definition. I had only to define the data types (Atom, Window, etc) once, then I can reuse them as much as I want and the right thing happens every time. There’s no room for typos or the nasty (mostly pointer-related) bugs we frequently had in 2.x.

The “typedefs” are equally simple, yet powerful:

val Window_p = PointerType(Window) // pointer to Window, which is an
val Window = PrimitiveType("Window", XID) // alias to XID, which is an
val XID = PrimitiveType("XID", unsigned_long) // alias to unsigned_long, which is a
val unsigned_long = IntegerType("unsigned long", PrimitiveMapping.PTR, unsigned = true) // pointer-sized integer primitive

[quote=“Spasi,post:9,topic:44251”]
What the?

That’s a valid excuse! :smiley:

Happy birthday, I guess? :wink:

Now what I actually wanted to say:
I would like you to keep posting some more information about LWJGL 3.0, because I’m really interested in seeing how it turns out. I really want to use it too.

The lack of updates made me almost forget that project! :confused:

[quote=“matheus23,post:11,topic:44251”]
I’ll try, but make sure you watch the project on GitHub. You can also watch the generated code, sometimes a cryptic commit on the main repo will result in some interesting changes in the generated stuff.

Congratulations Spasi :slight_smile: Kiss bye-bye to all that free time though :o

Very much looking forward to LWJGL 3.0 and its hopefully considerably increased reliability! I couldn’t care less about backward compatibility myself as the amount of actual callsites into LWJGL in a typical game is actually very small.

Cas :slight_smile:

Also theoretically it would probably be pretty easy to create a small wrapper library that clones the LWJGL 2.x API on top of LWJGL 3. Therefore allowing code using LWJGL 2 to work without any change or recompilation. However as princec mentioned above the LWJGL specific api usage is usually really small and wouldn’t take long to update.

[quote=“Spasi,post:12,topic:44251”]

I do already! :slight_smile:

But this might actually be important information for other visitors :slight_smile:

Holy shit congrats man! What the hell are you doing on LWJGL 3.0 with a newborn! :o

I am about to encounter a ton of free time in a few days, so I will contribute whatever I can :slight_smile:

I knew you would end up by doing this kind of change.