Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MacOS Support #1

Closed
tbotting opened this issue Nov 20, 2017 · 12 comments

Comments

@tbotting
Copy link

commented Nov 20, 2017

Hello,

First off, I'd like to thank you for your work!

I'm currently working on a game engine and want to integrate an OpenGL canvas inside a Swing frame. I see that you have done a lot to get this to work with LWJGL 3. Sadly though, you don't have MacOS support it seems. I was not able to find the MacOS counterpart of Win32SurfaceInfo and X11SurfaceInfo myself either. Do you have any idea if it's possible, and if so, how to get a GL canvas on MacOS to work?

Thanks in advance!

@httpdigest

This comment has been minimized.

Copy link
Member

commented Nov 20, 2017

Hi,
it's unlikely that Mac OS support will ever going to be added, since I do not own a Mac, and generally people do not volunteer on such small projects to do it themselves.
You would have to get really into details of the windowing framework Cocoa and the OpenGL device context implementation for Mac OS, which is CGL. All of that would have to be interfaced with using LWJGL3's native OS and JAWT bindings, as was done for the Windows version.
So, if you know anything about this or are willing to learn it, you are of course encouraged to add it and I will of course merge it in.

@tbotting

This comment has been minimized.

Copy link
Author

commented Nov 21, 2017

Hello,

Thank you for your reply.
I've now found the LWJGL CGL class and from here everything seems pretty straightforward. I'll give it an attempt today and if I get anything to work on MacOS I'll let you know!

@httpdigest

This comment has been minimized.

Copy link
Member

commented Nov 21, 2017

Sounds great! I wish you good luck with that.

@httpdigest

This comment has been minimized.

Copy link
Member

commented Nov 21, 2017

I think it would definitely help having a look at how LWJGL 2 handles its AWT integration: https://github.com/LWJGL/lwjgl/blob/master/src/native/macosx/org_lwjgl_opengl_MacOSXCanvasPeerInfo.m

@kappaOne

This comment has been minimized.

Copy link

commented Nov 22, 2017

Just a quick summary of how the above MacOSXCanvasPeerInfo from LWJGL2 works (its been a few years when i last looked at the code so mostly just writing from memory).

It should be noted that LWJGL2 had to support Java 5+ on OSX (at one point) therefore there are actually two different ways of embedding into AWT in MacOSXCanvasPeerInfo. One uses the legacy NSView method (no longer available in Java 7+) and the second uses CoreAnimation Layers implemented through Apple JVM specific API's (which carried over into the Oracle JVM on macOS).

Firstly, the old way of doing stuff was pretty simple (and similar to Windows/Linux). You simply grabbed a window handle from a NSView (as AWT Canvas's used to be NSView's) and drew into its context. This method (IIRC) was removed in Java 7 as Apple implemented their own new method using CoreAnimation and is the only way to implement in Java AWT now. Therefore you will notice the NSView method is used only as a fallback in the above code, i.e. if the CoreAnimation method fails or is not available (i.e. only for Java 5 and Java 6).

In Java 6 the CoreAnimation method was introduced and made mandatory for the Java applet plugin2 and later for all AWT usage (in fact even AWT Canvas's are now CoreAnimation Layers and no longer NSView's as before).

CoreAnimation Layer's have some limitations which need to be overcome to make this work:

  1. They are not windows, therefore have no window handle, so you can't attach another window to them and are essentially just offscreen buffers. You can only attach other types of CALayer's to them.
  2. A CALayer does not control directly when it is drawn, its parent the CoreAnimation system does that. As LWJGL applications usually specify when they want to draw this was a big limitation for LWJGL2.

Therefore its was pretty difficult to work with these limitations and required lots of tweaks to get this working.

There is a layer type called CAOpenGLLayer which allows drawing OpenGL on CoreAnimation and has its own OpenGL context and this layer type is used by LWJGL2. A CAOpenGLLayer is created and attached onto the Java AWT Canvas layer. Since this layer type creates its own context LWJGL2 has little control over its creation parameters. Therefore to work with this LWJGL creates its own shared context (to share resources, textures, VBO's, etc with this context) and redirects all LWJGL rendering to a FBO.

When the CALayer is drawn (i.e. its draw method called) we basically do a blit (glBlitFramebufferEXT) from the LWJGL FBO to the CALayer context. So whatever we drew to our LWJGL FBO gets drawn on the CALayer.

You will note from the code that there are various settings and things that need to be done to make this all work together. Such as the LWJGL FBO having to match the size of the CALayer and when the CALayer is resized the LWJGL FBO has to be recreated with that size.

Hope that helps clarify the above code a little.

@httpdigest

This comment has been minimized.

Copy link
Member

commented Nov 22, 2017

LWJGL creates its own shared context (to share resources, textures, VBO's, etc with this context) and redirects all LWJGL rendering to a FBO.

When the CALayer is drawn (i.e. its draw method called) we basically do a blit (glBlitFramebufferEXT) from the LWJGL FBO to the CALayer context. So whatever we drew to our LWJGL FBO gets drawn on the CALayer.

Does this basically mean that client code cannot assume FBO 0 to be the default window framebuffer, since binding to FBO 0 will not redirect any rendering to the actual LWJGL FBO anymore? So client code must know that it is inside an AWT/LWJGL layer emulated by an FBO controlled by LWJGL?

@kappaOne

This comment has been minimized.

Copy link

commented Nov 22, 2017

Yes, nice catch, this was a limitation of the implementation but ultimately a compromise needed to get it working without too much more hacks.

I vaguely recall there being some discussion between the LWJGL devs at the time, including exploring the option of catching any reference to framebuffer 0 and redirecting it to the internal fbo id but was dropped as it would be too much hassle to implement for something that can easily be avoided in client code.

@tbotting

This comment has been minimized.

Copy link
Author

commented Nov 22, 2017

I'm a little bit confused, isn't it possible to just use JAWT + this;
https://javadoc.lwjgl.org/org/lwjgl/opengl/CGL.html

@tbotting

This comment has been minimized.

Copy link
Author

commented Nov 22, 2017

Also, it might be worth looking at JOGL, they have canvas support for MacOS: https://github.com/sgothel/jogl/blob/master/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java

@httpdigest

This comment has been minimized.

Copy link
Member

commented Nov 22, 2017

Well then, go ahead and try it. I won't do it, because I do not have a Mac to test/develop it on.

@tbotting

This comment has been minimized.

Copy link
Author

commented Nov 22, 2017

Hello,

You might have mistaken my intent. I did not mean to imply that you would write it. I'll write it myself but just threw a few things for discussion. I'm grateful for your time and help. 😄

@httpdigest

This comment has been minimized.

Copy link
Member

commented Jan 5, 2018

@tbotting Just asking: Have you made any progress on the Mac OS implementation?

@httpdigest httpdigest closed this Jan 12, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.