SWT and OpenGL context attributes

Started by Kai, November 03, 2014, 17:21:52

Previous topic - Next topic

Kai

Hello,

I evaluated several window toolkits, where I want to have a simple GL-enabled component embedded into another SWT component (like an Eclipse IDE view).

There are certain requirements that must be met by that toolkit:
1. It should allow to create OpenGL > 3.0 contexts with glXCreateContextAttribsARB (and the like)
2. It should be able to create multiple windows/components, each having their own (and/or shared OpenGL context)
3. It should not flicker when refreshing OpenGL renderings
4. It should not consume much memory/create much garbage when any events happening
5. It should allow for fast animated redrawing of the GL component

Naturally, I selected the SWT GLCanvas for that task, but it most notably fell short of point 1. SWT (as of the current version 4.5) is not able to create a core >3.0 context with the context attributes call... On Mac OS X, a test application crashed because OS X falls back to OpenGL 2.1 core profile when no explicit GL version is set in the context attributes.

Then, I came to using lwjgl Display. That works very nice, especially on Windows and on Mac OS X. But it does not support 2, and I guess cannot easily be embedded into another SWT container. I must add to this the remark that I do not want to create a fullscreen game, but a data visualization application.

Next came AWT with lwjgl AWTGLCanvas. It does support 1 and 2 but it kind of has issues with 3 and 4 and 5.

Ultimately, what would be the best option (in my opinion) is to have still SWT but with the included support of 1.

The question therefore in my opinion is: Is it possible, with lwjgl3 and its use of glfw, to create such an SWT Canvas? I would do it myself, but first off want to have some advice first on whether that is achievable.

Best regards,
Kai

spasi

GLFW is an independent windowing toolkit, you can easily have multiple windows (each with its own OpenGL 3.0+ context), but you cannot embed it to another windowing toolkit (e.g. SWT). It has its own event loop, etc. It's the Display replacement in LWJGL 3.0 (for now at least).

LWJGL 3.0 also exposes platform-specific functionality that could be used to create your own SWT canvas. Assuming SWT is designed to allow that (I've never used it, so don't know what's possible). All of the OpenGL context management APIs are available, as well as OS-specific functionality like X11 on Linux. Any bindings missing could easily be added. See tests/org/lwjgl/system/windows and tests/org/lwjgl/demo/windows for examples of what's possible.

Cornix

Quote from: Kai on November 03, 2014, 17:21:52Next came AWT with lwjgl AWTGLCanvas. It does support 1 and 2 but it kind of has issues with 3 and 4 and 5.
Although I am not a fan of AWT I must say in its defense, that I never encountered any flickering or performance problems with an embedded LWJGL Display in an AWT application. Runs smooth as silk for me.
Only problem is mixing lightweight and heavyweight components and the problems connected with Z-fighting of these.

How exactly did you try to use it?

Kai

@Cornix: I too like AWT for its superior GL capabilities compared to SWT but when I created a simple test application with a simple Frame and added a lwjgl AWTGLCanvas to it, it drew the grayish background of the frame and/or the canvas and that interfered with the swapbuffer from GL. You have to go to quite some OS-specifc pain to disable AWT background rendering or do it the global system property way using "-Dsun.awt.noerasebackground=true", but then again it would interfere with your other AWT stuff in your app.

SWT on the other hand, being more closer to the metal, allows to set the window manager properties, like SWT.NO_BACKGROUND to do that per window.

This is of course only what I know and experienced.

Kai

@spasi: Thanks for the info. Wow, WindowsGLContext is exactly what I was looking for! :-) Just created a SWT Canvas in no time with it. SWT allows you to get a hold of the HDC very easily. If you want, we could have it integrated in lwjgl3 after some more tests.

Kai

spasi, is it somehow possible to call wglCreateContextAttribsARB, wglGetPixelFormatAttribiARB and wglChoosePixelFormatARB without having a "dummy" context and a dummy window/hDC current?
Without a current context, those functions report an exception from GL.getCapabilities.
I guess it is somehow related to LWJGL's context state tracking?

spasi

Not related to state tracking (there's none in LWJGL 3). These are all extensions, so they might not be available. Creating a dummy context to figure out the OpenGL driver's capabilities is standard practice.

With that said, anything you can do with pure native code is also possible with LWJGL 3. All the alternative versions of a particular function go through a single JNI method, with an 'n' prefix and primitive-only arguments. On the native side there is no additional processing, only type casts and the native function call (this applies to ALL bindings, no exceptions). For optional functions (like in OpenGL extensions), there's an additional final argument, which is the function address in the native library. You can use it like so:

FunctionProvider provider = GL.getFunctionProvider();
long wglCreateContextAttribsARB = provider.getFunctionAddress("wglCreateContextAttribsARB");
long context = nwglCreateContextAttribsARB(hdc, shareContext, attribList, wglCreateContextAttribsARB);


Note that GL.getFunctionProvider() returns an implementation of org.lwjgl.system.DynamicLinkLibrary which, on Windows, basically uses LoadLibrary and GetProcAddress to retrieve function pointers from opengl32.dll. Also note that attribList is a long, use org.lwjgl.system.MemoryUtil.memAddress(buffer) to get a pointer to your Byte/IntBuffer.

You can use the same trick to call wglGetExtensionsStringARB, so that you can also manually check driver capabilities without creating a context. Though, technically, WGL_ARB_extensions_string might also not be available if you run your code on an ancient driver, that's why creating a dummy default context is useful.

Kai

Thanks, spasi, for the clarifications about using the default context to obtain general capabilities of the GL first. I am doing it this way then with my custom SWT Canvas.

I sneaked over glfw and its issue tracker on github and found the very interesting issue https://github.com/glfw/glfw/issues/25 which proposes to decouple window management from GL context management in glfw.

This would be the ultimate solution for most people, I guess, since that would allow all kinds of language bindings and different windowing toolkits to work together with glfw's capability to create GL contexts, like in saying: "If you want glfw to take care of window management, fine. If you want to create your windows yourself and just provide glfw with the handle to create the GL context, that's fine, too."

I hope that it will receive enough attention to be attended to by someone familiar with glfw's internals.

spasi

Yeah, I'm aware of that issue and I'm also hoping that it will be implemented. But for a different reason. LWJGL does not need GLFW's context management, in fact, it currently gets in the way. LWJGL can do a much better job with context management, even LWJGL 2 supports more features with ContextAttribs. LWJGL 3 does not currently have a ContextAttribs equivalent and cross-platform context management is incomplete, mainly because of GLFW's window/context coupling.

The ideal would be to use LWJGL for anything OpenGL related and GLFW only for its windowing capabilities. OpenGL contexts would be created and managed by LWJGL and GLFW would use the context handles that LWJGL provides. With issue #25 fixed, we could have that. GLFW would then simply be a windowing backend. One of many hopefully, e.g. SWT could be another backend.


Kai

Okay, I see. That kind of makes more sense, provided that LWJGL's GL context creation works equally well for all three major platforms and stays up to date as well as compatible with older and newer OS versions. But you LWJGL devs have always been so super-actively supporting LWJGL that the answer to "up-to-date-ness" is quite in favor of LWJGL compared to glfw, I guess. :-)

Also, could you make an estimate on how long it would take to support GL context management in lwjgl3 for all three platforms? Just want to know when there would be a good moment to switch from lwjgl2.9 to lwjgl3, as the only thing missing for me in lwjgl3 is GL context management for Mac and Linux.

spasi

Well, technically, LWJGL 3 has full support for OpenGL context management, there's just no cross-platform abstraction over it at the moment (other than GLFW's API). So, if you want to hack something custom, you're better off using the platform-specific APIs directly. WGL and GLX are fully supported, including all extensions. On OSX there's support for CGL, but not for NSGL. What is missing is the ability to generate ObjC code in the LWJGL binding generator. This is not a priority right now, the current situation with GLFW will work just fine for the first beta.