husker-dev / openglfx

OpenGL implementation for JavaFX
Apache License 2.0
80 stars 10 forks source link

How do I run the program on a mac #5

Closed lqyaos closed 2 years ago

lqyaos commented 2 years ago

How do I run the program on a mac, I found that my window keeps getting stuck in OpenGLCanvas.create() this method and Internally, he is stuck on this method: Class.forName(JAWTUtilClassName, true, NativeWindowFactory.class.getClassLoader());

husker-dev commented 2 years ago

Not sure if this error is related to OpenGLFX. More like to JOGL.

I don't have a MacOS device, so I can't give you an exact solution. But...

You can test the node creation with true/false requireDirectDraw arguments. Most likely, if true, it will work

Node glNode = OpenGLCanvas.create(/* GLCapabilities */, /* FPS */, /* requireDirectDraw */);

Also try to push node creation into the main thread, using:

// Java
Platform.runLater(() -> {
    // your code here
})
// Kotlin
Platform.runLater {
    // your code here
}
lqyaos commented 2 years ago

I have already made such a call Platform.runLater {my code} and still get stuck in GLProfile.getDefault()

now I found out where I got stuck:

sun.lwawt.macosx.LWCToolkit#getMultiClickTime This is a native method of jdk. I don’t know why it is stuck.

But in the final analysis, it is caused by the call of jogl jogamp.nativewindow.jawt430 line. Is it because the jogl of mac has a bug?

Do you have an idea? Windows can run because it will not run to this line of code.

next I tried Thread{ GLProfile.getDefault()}.start() He won't get stuck. sun.lwawt.macosx.LWCToolkit#getMultiClickTime return 500 succeeded, but in the end it crashed:

Apple AWT Internal Exception: NSWindow drag regions should only be invalidated on the Main Thread!

So I feel very conflicted

husker-dev commented 2 years ago

Here is code of sun.lwawt.macosx.LWCToolkit#getMultiClickTime:

JNIEXPORT jint JNICALL Java_sun_lwawt_macosx_LWCToolkit_getMultiClickTime(JNIEnv *env, jclass klass) {
    __block jint multiClickTime = 0;
    JNF_COCOA_ENTER(env);
    [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
        multiClickTime = (jint)([NSEvent doubleClickInterval] * 1000);
    }];
    JNF_COCOA_EXIT(env);
    return multiClickTime;
}

This code waits for execution on the main thread. So, if you call GLProfile.getDefault() from Platform.runLater, then the thread will wait for itself to complete, and as a result stuck.

On MacOS a large number of UI-related functions must be executed in the main thread. This is why there are no errors on Windows.

In general, it is strange that JOGL uses the AWT libraries in this case. You can try using LWJGL instead of JOGL. It definitely doesn't use AWT.

husker-dev commented 2 years ago

There are already existing implementations of LWJGL. Maybe I will implement this in the future

lqyaos commented 2 years ago

thank you very much It seems that this solution won’t work. I’ll try lwjgl.

Of course, I’m also looking forward to your realization. Haha

lqyaos commented 2 years ago

After two days of research, I found the problem:

For example, the corresponding native function on jdk16

JNIEXPORT jint JNICALL Java_sun_lwawt_macosx_LWCToolkit_getMultiClickTime(JNIEnv *env, jclass klass) {
    __block jint multiClickTime = 0;
    JNF_COCOA_ENTER(env);
    [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
        multiClickTime = (jint)([NSEvent doubleClickInterval] * 1000);
    }];
    JNF_COCOA_EXIT(env);
    return multiClickTime;
}

This code is waiting to be executed on the main thread. Therefore, if you call GLProfile.getDefault() from a javafx thread, the thread will wait for itself to complete and it will get stuck For example, this project https://github.com/defold/defold He uses jogl and requires the developer to use the jdk version 11.

Now I use jdk11 to run in the jogl+javafx+macos environment, but the interface still does not display. Then I went to see the source code of the https://github.com/defold/defold project. He turned out to be using Java to call Clojure. I feel very drunk and drunk. NS

husker-dev commented 2 years ago

LWJGL only requires the main thread to create a window using native GLFW library, not SWT. In this situation, you do not need to do this.

The main point of LWJGL is to simply call OpenGL functions from Java, as JavaFX does by the native code.

Therefore, I don't think there should be any problems with it.

lqyaos commented 2 years ago

As mentioned earlier, I used jdk11 version on the mac to run, but using my FXGLEventListener just simply output a line segment, DirectGLRenderer can’t display it.

UniversalRenderer can be displayed using the same listener What is the problem, how can I debug it

husker-dev commented 2 years ago

I completely rewrote the library and added LWJGL support. You can try it!

husker-dev commented 2 years ago

For people, who interested in this issue

DON’T use JOGL if you want to launch your application on MacOS without any troubles.

Please, use LWJGL :)