[RFE] LWJGL 3.0

Started by spasi, November 08, 2012, 13:23:54

Previous topic - Next topic

spasi

I updated the post on JGO with a new build and more info. I'll be trying AWT integration next. I could really use more test results though, especially on nvidia GPUs.

kappa

Another thing we might want to consider for LWJGL3 is using two threads for the native Display, one for only rendering and the other for window events, input, etc. This would be transparent to the library users as its an internal change and would allow for smoother rendering (i.e. no time spent on input polling, window events, etc on the rendering thread) and would allow for rendering/game loop to continue without being blocked when doing stuff like moving and resizing the Display window.

spasi

Progress update:

I just created the first window using the API that's generated through the new code generator. And it's all Java code!

public void testCreateWindow() {
	final ByteBuffer wndClassEx = WNDCLASSEX.malloc();

	WNDCLASSEX.cbSize(wndClassEx, WNDCLASSEX.SIZEOF);
	WNDCLASSEX.style(wndClassEx, CS_OWNDC);
	WNDCLASSEX.lpfnWndProc(wndClassEx, WindowsPlatform.getDefWindowProc());
	WNDCLASSEX.cbClsExtra(wndClassEx, 0);
	WNDCLASSEX.cbWndExtra(wndClassEx, 0);
	WNDCLASSEX.hInstance(wndClassEx, WindowsPlatform.getHINSTANCE());
	WNDCLASSEX.hIcon(wndClassEx, nLoadIcon(0, IDI_APPLICATION));
	WNDCLASSEX.hCursor(wndClassEx, nLoadCursor(0, IDC_ARROW));
	WNDCLASSEX.hbrBackground(wndClassEx, 0);
	WNDCLASSEX.lpszMenuName(wndClassEx, 0);
	WNDCLASSEX.lpszClassName(wndClassEx, memAddress(memEncodeUTF16("LWJGL")));
	WNDCLASSEX.hIconSm(wndClassEx, 0);

	final short classAtom = RegisterClassEx(wndClassEx);
	assertTrue(classAtom != 0);

	final long hwnd = CreateWindowEx(
		WS_EX_APPWINDOW,
		memEncodeUTF16("LWJGL"),
		memEncodeUTF16("LWJGL Test"),
		WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
		0, 0, 640, 480,
		0, 0, WindowsPlatform.getHINSTANCE(), 0
	);
	assertTrue(hwnd != 0);

	ShowWindow(hwnd, SW_SHOWDEFAULT);

	DestroyWindow(hwnd);
}


So, the first milestone is complete, we can now create bindings to arbitrary OS-specific APIs. We also generate "struct classes" that take care of setting up ByteBuffer in a way that the system call understands (WNDCLASSEX in the above example). It supports any primitive value, pointer values (automatically cast to 32 or 64 bits at runtime) and also nested structs. All the struct member offsets are discovered at runtime from auto-generated native code.

The Generator Kotlin-based DSL looks like this:

// A simple type
val DWORD = PrimitiveType("DWORD", PrimitiveMapping.INT)

// A struct type definition
val LPGLYPHMETRICSFLOAT = StructType(
	name = "LPGLYPHMETRICSFLOAT",
	includesPointer = true,
	definition = struct(WINDOWS_PACKAGE, "GLYPHMETRICSFLOAT") {
		nativeImport ("WindowsLWJGL.h")
		FLOAT _ "gmfBlackBoxX"
		FLOAT _ "gmfBlackBoxY"
		POINTFLOAT _ "gmfptGlyphOrigin" // Nested struct
		FLOAT _ "gmfCellIncX"
		FLOAT _ "gmfCellIncY"
	}
)

// A Windows function
HWND.func("CreateWindowEx") {
	DWORD IN "exStyle"
	LPCTSTR IN "className"
	LPCTSTR IN "windowName"
	DWORD IN "style"
	int IN "x"
	int IN "y"
	int IN "width"
	int IN "height"
	HWND IN "parent"
	HMENU IN "menu"
	HINSTANCE IN "instance"
	LPVOID IN "param"
}

// A WGL function
BOOL.func("wglMakeCurrent") {
	HDC IN "device"
	HGLRC IN "context"
	javaDoc {
		"""
		Makes a specified OpenGL rendering context the calling thread's current rendering context.
		All subsequent OpenGL calls made by the thread are drawn on the device identified by device.
		You can also use wglMakeCurrent to change the calling thread's current rendering context so it's no longer current.
		"""
	}
}


The next milestone will be adding support for context/device specific functions. Once that's done, I'll create the 3.0 branch and start accepting contributions.

NateS

Quote from: kappa on November 12, 2012, 17:31:19
@princec - replacing all input with JInput sounds like a cool idea (especially as it reduces the native code), however is JInput workable and good enough to replace input from the windowing system? does stuff like Keyboard localisation work? are there limitations of using JInput over input from the windowing system?.

If we do go with JInput for input I'd prefer the binaries be merged into the lwjgl ones rather than having to carrying around yet another jar and native for each platform, quite like the idea of the core being one jar, one native (for each platform). Might even be easier to just absorb JInput into lwjgl to allow consistent package names and allowing bugs to be fixed directly.
The JInput source scares the hell out of me. I would vote to not use it, or to do a rewrite as a real part of LWJGL.

kappa

Quote from: NateS on November 27, 2012, 10:35:27
The JInput source scares the hell out of me. I would vote to not use it, or to do a rewrite as a real part of LWJGL.
I also evaluated it and came to the same conclusion, a major point being that there is no way to get the mouse location using JInput, which can only be done by implementing native windowing code for the mouse which would again bring us back to the current situation.

jakj

Another limitation is lack of hot-plug support of controllers, as far as I've been able to determine.

MattCa

The one thing I would definitely not like to see go would be the utility package, from what I can tell from LWJGL's name, it's not a graphics library but a game library. For me, one of the greatest benefits of LWJGL was its inclusion of simple vector, matrix, etc, classes, which are necessary parts of game development.

I understand that there are plenty of other Math libraries out there, but the convenience of having one included in the library and not having to find java bindings for another makes a massive difference. It's the same thing with other game libraries such as XNA, it's very easy to create a new project and have something rendered on the screen in a matter of minutes, rather than having to spend a few hours finding a math library that does everything you need and then finding/making java bindings for it.

Just my two cents, but I think removing the utility package would move LWJGL closer to JOGL, and I chose LWJGL for the very reason that it was focused on game development, not just an OpenGL java binding.

NateS

It depends on what LWJGL wants to be. I personally would prefer if LWJGL didn't try to solve too many problems. Including a utils package makes it a bit of a junk drawer. There are all kinds of things it *could* have that aren't related to the core problems it solves.

I use libgdx, which uses LWJGL on the desktop, and I delete the entire LWJGL util package from the JAR because I don't use any of it. libgdx has vector, matrix, quaternion, collections classes, and more.

jakj

Knowing the util library is deprecated, and having some other things missing that full game libraries have, has actually forced me to write better code, as well as understanding what that code really does. OpenGL's simplification has done the same thing: Being forced to use VBOs/VAOs for everything, and having no client-side matrix transformation whatsoever, has taken entire layers off of my code and streamlined it immensely, simply because I was forced to think about what I was doing instead of simply using function calls as I felt like.

LWJGL is mirroring OpenGL in the sense that it wants to be a facilitation, not a solution: LWJGL is not like a transit system, but more like a road: It doesn't simply take you from A to B, but rather provides a way for you to get from A to B yourself, and though that leads to fewer people using it due to lack of all-around utility (the same reason many use DX instead of GL, because DX is like a Swiss-army knife), in the end, it leads to better things.

MattCa

Quote from: jakj on November 29, 2012, 00:21:34
Knowing the util library is deprecated, and having some other things missing that full game libraries have, has actually forced me to write better code, as well as understanding what that code really does. OpenGL's simplification has done the same thing: Being forced to use VBOs/VAOs for everything, and having no client-side matrix transformation whatsoever, has taken entire layers off of my code and streamlined it immensely, simply because I was forced to think about what I was doing instead of simply using function calls as I felt like.

LWJGL is mirroring OpenGL in the sense that it wants to be a facilitation, not a solution: LWJGL is not like a transit system, but more like a road: It doesn't simply take you from A to B, but rather provides a way for you to get from A to B yourself, and though that leads to fewer people using it due to lack of all-around utility (the same reason many use DX instead of GL, because DX is like a Swiss-army knife), in the end, it leads to better things.

I suppose you have a point there, but LWJGL is (for me) a way to develop games without having to worry about different Math implementations, similar to Unity (albeit with a lower-level feature set) or XNA. I first started Java programming just over a year ago, and I used LWJGL as a way to apply what I learnt. I didn't have to install Math libraries, I didn't have to worry about handling input, and all of this definitely helped me making small and relatively big games.

If it were to lose its utility package (including Maths, Input, etc), then it would be nothing more than a clone of JOGL, which is not a game library, and I'm finding it hard to believe that such a change would attract newcomers, and if anything we want to be encouraging a growing user base.

Regarding moving the utility package over to a separate project, I have no arguments against this, but what I would at least like to see is some form of integration (e.g. LWJGL and util in one distribution), so new users can get started quickly.

spasi

Quote from: MattCa on November 29, 2012, 21:34:33Regarding moving the utility package over to a separate project, I have no arguments against this, but what I would at least like to see is some form of integration (e.g. LWJGL and util in one distribution), so new users can get started quickly.

This is what will most likely happen in 3.0.

CodeBunny

What's going to happen to the Display class in 3.0?

As I've said before, an Object-Oriented Display API would be really, really nice (http://lwjgl.org/forum/index.php/topic,4511.msg24269.html#msg24269).

spasi

The LWJGL 3 repo is up, here. There's nothing usable in there yet, but the generator is almost feature complete for the OpenGL API. Everything in GL11 has been implemented and there's API parity with 2.x, minus a few signature fixes and cleanups.

The most important new feature since my last post is support for Javadoc generation. Currently the generator requires that every function/parameter template comes with a description and I did my best to document everything in GL11, including enum lists and links from one function to another. Most of it is simple descriptions from the GL spec, but I tried to add extra info for the more important/often-used functions. I'm hoping that this will make LWJGL easier to use and we won't have to leave our IDEs as often to go look for info in the GL/extension specs. This is what it currently looks like in my IDE:



For contributors: To get a glimpse of what the new generator provides and what the internals of 3.0 might look like, see the following two classes:

- org.lwjgl.system.windows.WindowsDisplay in src/core/
- org.lwjgl.demo.windows.WGLDemo in src/tests/

Matzon

awesome!
I don't have much time right now - but at a cursory glance, I like what I see :)

The kotlin stuff and the native handling looks a lot better.
Are you confident that we can handle al and cl, as easily too?

compiling:
compile:
[Core java compilation] Compiling 45 source files to J:\Work\programming\Personal\lwjgl3\bin\Core
[Core java compilation] J:\Work\programming\Personal\lwjgl3\src\core\org\lwjgl\system\MathUtil.java:7: cannot find symbol
[Core java compilation] symbol  : class ThreadLocalRandom
[Core java compilation] location: package java.util.concurrent
[Core java compilation] import java.util.concurrent.ThreadLocalRandom;
[Core java compilation]                            ^
[Core java compilation] J:\Work\programming\Personal\lwjgl3\src\core\org\lwjgl\system\MathUtil.java:27: cannot find symbol
[Core java compilation] symbol  : variable ThreadLocalRandom
[Core java compilation] location: class org.lwjgl.system.MathUtil
[Core java compilation]                 return ThreadLocalRandom.current().nextInt(range + 1);
[Core java compilation]                        ^
[Core java compilation] 2 errors

Do we require Java 7 now?

compile-templates also seemed kinda slow?
QuoteTotal time: 19 seconds
- on a pretty fast machine

Although I am a big fan of 'use-the-source-luke', I think that we need to also spend some time documenting the templates processing so that it is easier to work with, unlike the old apt.

Also, I assume the WGLDemo is just a display of raw windows usage, more so than the expected API for creating a window?
That is, we will add the current'ish API on top of the raw platform api.

Anyhow, I'll look more at this later - just wanted to shoot some comments on your work.

spasi

Quote from: Matzon on December 24, 2012, 10:01:05Are you confident that we can handle al and cl, as easily too?
Very.

Quote from: Matzon on December 24, 2012, 10:01:05Do we require Java 7 now?
No, we don't. It's a leftover from some tests I'd been doing, not used anymore.

Quote from: Matzon on December 24, 2012, 10:01:05compile-templates also seemed kinda slow?
QuoteTotal time: 19 seconds
- on a pretty fast machine
That's because of kotlinc. Kotlin is still a work in progress and compilation performance is pretty bad at this time. Their goal is to match javac performance for the final version, so I'm hoping that the situation will improve rapidly (JetBrains has started using it in production since the last milestone). The code generation itself takes ~1 second with a clean cache.

Quote from: Matzon on December 24, 2012, 10:01:05Although I am a big fan of 'use-the-source-luke', I think that we need to also spend some time documenting the templates processing so that it is easier to work with, unlike the old apt.
Yes, I'll try to fully document it once it's stable.

Quote from: Matzon on December 24, 2012, 10:01:05Also, I assume the WGLDemo is just a display of raw windows usage, more so than the expected API for creating a window?
That is, we will add the current'ish API on top of the raw platform api.
Exactly. So, for example, the WindowsDisplay class would be an implementation of the cross-platform Display in the public API layer. It also showcases how one could circumvent all LWJGL code and go straight to the native APIs, for custom solutions, etc.