Jogl and JavaFX

classic Classic list List threaded Threaded
40 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Jogl and JavaFX

Sweck
I heared its possible to integrate Jogl into JavaFX with the NewtCanvasJFX but I can't get it to work.
I tried something like that.

  @Override
   public void start(Stage primaryStage) throws Exception{
       Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
       primaryStage.setTitle("JavaFX Jogl");
       primaryStage.setScene(new Scene(root, 300, 275));
       primaryStage.show();
     
       //init Canvas
       final GLProfile glProfile = GLProfile.getDefault();
       final GLCapabilities capabilities = new GLCapabilities(glProfile);

       GLWindow glWindow = GLWindow.create(capabilities);

       NewtCanvasJFX glPanel = new NewtCanvasJFX(glWindow);
       glPanel.setWidth(300);
       glPanel.setHeight(300);
     
       StackPane openGLPane = new StackPane();
       openGLPane.getChildren().add(glPanel);

       glWindow.addGLEventListener(this);
  }

I just need to get jogl and Javafx working together for a university project so if anyone has other solutions I would really appreciate them.
Reply | Threaded
Open this post in threaded view
|

Re: Jogl and JavaFX

gouessej
Administrator
This post was updated on .
Hello

Where is your animator? Do you get an error message? Have you followed the instructions in our wiki to add the necessary libraries into your classpath?
https://jogamp.org/wiki/index.php/Setting_up_a_JogAmp_project_in_your_favorite_IDE

Look at this example:
https://github.com/sgothel/jogl/blob/master/src/test/com/jogamp/opengl/test/junit/jogl/javafx/TestNewtCanvasJFXGLn.java

Reminder: You need the latest RC of JOGL 2.4.0 to make it work. It obviously doesn't work with JOGL 2.3.2.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Jogl and JavaFX

Sven Gothel
Administrator
In reply to this post by Sweck
On 3/31/20 8:50 PM, Sweck [via jogamp] wrote:
> I heared its possible to integrate Jogl into JavaFX with the NewtCanvasJFX but
> I can't get it to work.
> I tried something like that.
>

This is our unit test

<https://jogamp.org/cgit/jogl.git/tree/src/test/com/jogamp/opengl/test/junit/jogl/javafx/TestNewtCanvasJFXGLn.java>

It works using either some Java8 + combinded [Open]JFX
or OpenJDK 10 + OpenJFX.

As Julien suggested, please provide a small test case
and also state platform and other details etc.

~Sven


signature.asc (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Jogl and JavaFX

Sweck
In reply to this post by gouessej
I get no errors. All I get is an empty window. It doesnt run the init or display functions either. Here is the full code:

package Testing;

import com.jogamp.newt.javafx.NewtCanvasJFX;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.util.FPSAnimator;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Main extends Application implements GLEventListener{

         
        public static void main(String[] args) {
          launch(args);
        }
       
       
        @Override
        public void start(Stage primaryStage) throws Exception{
            final GLProfile glProfile = GLProfile.getDefault();
            final GLCapabilities capabilities = new GLCapabilities(glProfile);
           
            GLWindow glWindow = GLWindow.create(capabilities);

            NewtCanvasJFX glPanel = new NewtCanvasJFX(glWindow);

            glWindow.addGLEventListener(this);

            final FPSAnimator animator = new FPSAnimator(glWindow, 60);
            animator.start();
           
           
            StackPane root = new StackPane();
           
            root.getChildren().add(glPanel);
           
            primaryStage.setTitle("JavaFX OpenGL");
            primaryStage.setScene(new Scene(root, 300, 275));
            primaryStage.show();
        }


        @Override
        public void display(GLAutoDrawable arg0) {
               
        }

        @Override
        public void dispose(GLAutoDrawable arg0) {
               
        }

        @Override
        public void init(GLAutoDrawable arg0) {
               
        }

        @Override
        public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4) {
               
        }
       
}
Reply | Threaded
Open this post in threaded view
|

Re: Jogl and JavaFX

DamagedTiberius
I'm not sure if you're married to using NewtCanvasJFX; however, I actually have JOGL 2.1.5 integrated into JavaFX. I'm stuck at that version for the moment since I'm incorporating NASA World Wind in my application. My class looks something like the following. I couldn't post the exact class since it actually derives from other classes that would muddy the waters here at best, so I apologize if I made a typo or overlooked something when making this quick example.

public class OpenGlPanel extends VBox
                         implements GLEventListener, KeyListener, MouseListener, MouseMotionListener
{
    private final GLJPanel gljPanel;
    private final SwingNode swingNode;
   
    private final Camera camera;
   
    public OpenGlPanel()
    {
        super();

        // Getting the capabilities object of GL2 profile
        // Stuck at GL2 for simultaneous support of World Wind
        final GLProfile profile = GLProfile.get(GLProfile.GL2);
        GLCapabilities capabilities = new GLCapabilities(profile);

        gljPanel = new GLJPanel(capabilities);
        gljPanel.setBackground(Color.BLACK);
       
        camera = new Camera();
        camera.installTrackball(gljPanel);
       
        addGLEventListener(this);
        addKeyListener(this);
        addMouseListener(this);
        addMouseListener(this);

        swingNode = new SwingNode();
        getChildren().add(swingNode);

        VBox.setVgrow(swingNode, Priority.ALWAYS);
               
        SwingUtilities.invokeLater(this::setContent);
    }

    @Override
    public void init(GLAutoDrawable glDrawable)
    {
        final GL2 gl = glDrawable.getGL().getGL2();
        glu = GLU.createGLU(gl);
       
        gl.glEnable(GL2.GL_BLEND);
        gl.glBlendFunc(GL2.GL_SRC_ALPHA, GL2.GL_ONE_MINUS_SRC_ALPHA);

        gl.glEnable(GL.GL_DEPTH_TEST);
        gl.glDepthMask(true);        
        gl.glDepthFunc(GL.GL_LEQUAL);      
       
        gl.glViewport(0, 0, glDrawable.getWidth(), glDrawable.getHeight());
       
        camera = view.getCamera();
        camera.apply(gl);
    }

    @Override
    public void dispose(GLAutoDrawable glad)
    {
        // Cleanup
    }

    @Override
    public void display(GLAutoDrawable glDrawable)
    {        
        final GL2 gl = glDrawable.getGL().getGL2();
       
        clearScreen(gl);
       
        camera.apply(gl);
       
        // Make your drawing calls
    }

    public void clearScreen(GL2 gl)
    {
        gl.glClearColor(0f, 0f, 0f, 1f);
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // clear the window
    }

    @Override
    public void reshape(GLAutoDrawable glDrawable, int i, int i1, int i2, int i3)
    {
        final GL gl = glDrawable.getGL();
        gl.glViewport(i, i1, i2, i3);
    }

    @Override
    public void keyTyped(KeyEvent e)
    {
    }

    @Override
    public void keyPressed(KeyEvent e)
    {
    }

    @Override
    public void keyReleased(KeyEvent e)
    {
    }

    @Override
    public void mouseClicked(MouseEvent e)
    {
    }

    @Override
    public void mousePressed(MouseEvent e)
    {
    }

    @Override
    public void mouseReleased(MouseEvent e)
    {
    }

    @Override
    public void mouseEntered(MouseEvent e)
    {
    }

    @Override
    public void mouseExited(MouseEvent e)
    {
    }

    @Override
    public void mouseDragged(MouseEvent e)
    {
    }

    @Override
    public void mouseMoved(MouseEvent e)
    {
    }

    private void setContent()
    {
        swingNode.setContent(gljPanel);
    }
}
Reply | Threaded
Open this post in threaded view
|

Re: Jogl and JavaFX

Sweck
Thank you for this answer this is exactly what I was looking for.
I would still like to try out this new NewtCanvasJFX so if anyone has an idea how to fix my previous code let me know.

I came up with these lines of code to integrate a gljpanel into a jfx scene:

public void initCanvas() {
                final GLProfile glProfile = GLProfile.getDefault();
                final GLCapabilities capabilities = new GLCapabilities(glProfile);
                   
                canvas = new GLJPanel(capabilities);    
                canvas.addGLEventListener(this);
           
                final SwingNode swingNode = new SwingNode();
                swingNode.setContent(canvas);
           
                root.getChildren().add(swingNode);
           
            animator = new FPSAnimator(canvas, 20);
          animator.start();
}

I actualy get a window with the canvas inside it and all the functions like init, display etc work and I can also change the clear color using glClearColor but it doesnt draw anything. I used some previous code that loads an obj model into a scene and it doesnt show anything. When I use the exact same jogl code with a GLCanvas inside a JFrame it works perfectly so its not a problem of the rendering part. It has to be a problem with the canvas setup I assume. Does anyone have an idea why there is nothing drawn to the screen ?
Reply | Threaded
Open this post in threaded view
|

Re: Jogl and JavaFX

Sven Gothel
Administrator
On 4/2/20 2:42 PM, Sweck [via jogamp] wrote:
> I would still like to try out this new NewtCanvasJFX so if anyone has an idea
> how to fix my previous code let me know.

Have you read my other email and tested or reviewed our unit test?

> This is our unit test
>
> <https://jogamp.org/cgit/jogl.git/tree/src/test/com/jogamp/opengl/test/junit/jogl/javafx/TestNewtCanvasJFXGLn.java>
>
> It works using either some Java8 + combinded [Open]JFX
> or OpenJDK 10 + OpenJFX.

~Sven
Reply | Threaded
Open this post in threaded view
|

Re: Jogl and JavaFX

DamagedTiberius
In reply to this post by Sweck
You can't set the content of the SwingNode in the FX thread. In my original post, there is a line:
   
    SwingUtilities.invokeLater(this::setContent);

This is critical since it queues the task of setting the SwingNode content on the AWT thread.
Reply | Threaded
Open this post in threaded view
|

Re: Jogl and JavaFX

DamagedTiberius
As a general statement, you need to be careful about what is running on which thread in my approach. You must make certain that anything affecting the JPanel or OpenGL is queued onto the AWT thread using SwingUtilities. I don't use animators in my work; however, I suspect that you will need to launch that from the AWT thread as well.
Reply | Threaded
Open this post in threaded view
|

Re: Jogl and JavaFX

Sweck
In reply to this post by Sven Gothel
@Sven Gothel

Yes, I did see that but the code is a complete mess and I can't figure out whats even going on there.
All I need are those 4 lines of code to work properly and I can't even finde similar lines in that test case.

Reply | Threaded
Open this post in threaded view
|

Re: Jogl and JavaFX

Sweck
In reply to this post by DamagedTiberius
Ah thats what I thought too.
I will try it later thanks a lot.
Reply | Threaded
Open this post in threaded view
|

Re: Jogl and JavaFX

Sven Gothel
Administrator
In reply to this post by Sweck
On 4/2/20 5:51 PM, Sweck [via jogamp] wrote:
> @Sven Gothel
>
> Yes, I did see that but the code is a complete mess and I can't figure out
> whats even going on there.
> All I need are those 4 lines of code to work properly and I can't even finde
> similar lines in that test case.

I wish you good luck then resolving _your_ mess ;-)

Hint: Ignorance and avoiding reading 'the book' is not always helping.
Here that would be unit tests and the source code, all available.
Before expecting others to dive into your problems,
maybe read what has been written first.

~Sven
Reply | Threaded
Open this post in threaded view
|

Re: Jogl and JavaFX

Sweck
You are acting really childish here.

I already read the source code many times before I even asked the question. I asked this question here because I can't figure out this code at all. By mess I mean I'ts way to complicated for me I just need those 4 lines that do the job.

I expected answers like those from @DamagedTiberius which actualy help solve my problem and not just references to sources I already know.

I respect you for taking your time and trying to help me but until now all you did is just referencing and not answering my question.  I think the answer to my question is really simple like @DamagedTiberius showed. I just need it for NewtCanvasJFX now.

Reply | Threaded
Open this post in threaded view
|

Re: Jogl and JavaFX

Sven Gothel
Administrator
On 4/2/20 8:19 PM, Sweck [via jogamp] wrote:
> You are acting really childish here.

;-)

>
> I already read the source code many times before I even asked the question. I
> asked this question here because I can't figure out this code at all. By mess
> I mean I'ts way to complicated for me I just need those 4 lines that do the job.
>
> I expected answers like those from @DamagedTiberius which actualy help solve
> my problem and not just references to sources I already know.
>
> I respect you for taking your time and trying to help me but until now all you
> did is just referencing and not answering my question.  I think the answer to
> my question is really simple like @DamagedTiberius showed. I just need it for
> NewtCanvasJFX now.

Truly an interesting point of view.

Whatever, good riddance then.

~Sven
Reply | Threaded
Open this post in threaded view
|

Re: Jogl and JavaFX

Sweck
In reply to this post by DamagedTiberius
@DamagedTiberius

I tried running it in SwingUtilities.invokeLater but still nothing rendered. Got any idea ?

public void initCanvas() {
                canvas = new GLJPanel(capabilities);
            canvas.addGLEventListener(this);
            swingNode = new SwingNode();
           
            root.getChildren().add(swingNode);
   
            SwingUtilities.invokeLater(new Runnable() {
            public void run() {

            swingNode.setContent(canvas);

            animator = new FPSAnimator(canvas, 20);
              animator.start();
            }
            });
}
Reply | Threaded
Open this post in threaded view
|

Re: Jogl and JavaFX

DamagedTiberius
In reply to this post by Sweck
I took a quick look at your code and the unit test. The unit test is definitely complicated. It's really an integration test which allows a number of variations to be tested with some configuration parameters rather than having to rewrite almost the same unit test repeatedly.

I've never used Newt before, so I really had no basis of what to look for other than differences between the code I'm troubleshooting and an example of working code. I usually find that a good start when you're approaching something like this is to find the top and start skimming through the chain of methods to find the types of operations you're looking for, so you can start comparing against how you did it. An alternative approach could be to take this unit test and see if you can make it work on your system. You can then whittle it down to the pieces that are important to your case.

In this example, the top of the chain are the methods annotated with @Test. Each of those call runTestAGL with a different set of parameters.  Taking a quick look at runTestAGL, you can see that these parameters set the OpenGL profile used and the drawing code that will be used. If you get to a point where you think that your window creation is correct, you might look at the GearsES2 code to look for additional ideas.

As you trace down through runTestAGL, you can see where the test does many of the same things you do. The first thing I noticed was that the unit test creates a Screen object which is then passed to the factory method to create the GLWindow. Your code does not have this, so I went to the documentation to see how the Screen is used. I found that the method documentation includes "The lifecycle of this Window's Screen and Display is handled via Screen.addReference() and Screen.removeReference()." This brings to mind potential garbage collection issues, so I continued on to Screen to see what it is and what references do. That refers you directly to Display which tells you that the "1st call will initiate native creation, since we follow the lazy creation pattern."

My guess is that this is your first issue. It sounds like you need to create a Screen instance as is done in the test case in order to access the graphics device. If it's still not working, you should try applying this approach to the rest of your code - look for differences in how things are created in the test vs. how you do it. Check the documentation to see what might happen due to those differences.
Reply | Threaded
Open this post in threaded view
|

Re: Jogl and JavaFX

DamagedTiberius
In reply to this post by Sweck
Nothing leaps out at me in that method. Can you post your full code?
Reply | Threaded
Open this post in threaded view
|

Re: Jogl and JavaFX

Sweck
Important are just start() and initCanvas() the rest is just opengl stuff and as I said works perfectly when I use GLCanvas inside a JFrame.


package Testing;

import javax.swing.SwingUtilities;

import com.jogamp.newt.javafx.NewtCanvasJFX;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.GL4;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLContext;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.awt.GLJPanel;
import com.jogamp.opengl.util.FPSAnimator;

import Engine.Core.Config;
import Engine.Core.Camera.Camera;
import Engine.Core.Lights.AmbientLight;
import Engine.Core.Lights.DirectionalLight;
import Engine.Core.Math.Matrix4f;
import Engine.Core.Math.Vector3f;
import Engine.Core.Models.Model;
import Engine.Core.Renderer.Renderer;
import Engine.Core.Shaders.Core.BasicShader;
import Engine.Core.Shaders.Core.Material;
import javafx.application.Application;
import javafx.embed.swing.SwingNode;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Main extends Application implements GLEventListener{

        private boolean experimental = false;
        private GLJPanel canvas;
        private StackPane root;
        private SwingNode swingNode;
       
        private FPSAnimator animator;
        private Renderer renderer;
        private BasicShader shader;
        private Camera camera;
        private Matrix4f projectionMatrix;
        private Model teapot;
         
        public static void main(String[] args) {
          launch(args);
        }
       
       
        @Override
        public void start(Stage primaryStage) throws Exception{
                root = new StackPane();
               
                primaryStage.setTitle("JavaFX OpenGL");
                primaryStage.setScene(new Scene(root, 1920, 1080));
                primaryStage.show();
                initCanvas();
                 
        }
       
        public void initCanvas() {
                final GLProfile glProfile = GLProfile.getDefault();
                final GLCapabilities capabilities = new GLCapabilities(glProfile);
               
               
                if(experimental) {
                        //trying NewtCanvasJFX
                       
            GLWindow glWindow = GLWindow.create(capabilities);
             glWindow.addGLEventListener(this);
           
             NewtCanvasJFX glPanel = new NewtCanvasJFX(glWindow);    
             root.getChildren().add(glPanel);
             
             final FPSAnimator animator = new FPSAnimator(glWindow, 20);
             animator.start();
             
            }else {
            //Using Swing
           
            canvas = new GLJPanel(capabilities);
           
            canvas.addGLEventListener(this);
            swingNode = new SwingNode();
           
            root.getChildren().add(swingNode);
   
            SwingUtilities.invokeLater(new Runnable() {
            public void run() {

            swingNode.setContent(canvas);

            animator = new FPSAnimator(canvas, 20);
              animator.start();
            }
            });
           
                }
        }
       
        @Override
        public void stop() {
                animator.stop();
        }

        @Override
        public void display(GLAutoDrawable arg0) {
               
                renderer.clear();
               
                //teapot.increaseRotation(0,0.5f,0);
               
                renderer.render(teapot, shader);
               
        }

        @Override
        public void dispose(GLAutoDrawable arg0) {

        }

        @SuppressWarnings("unused")
        @Override
        public void init(GLAutoDrawable arg0) {
                Config.BACKGROUND_COLOR = new Vector3f(0.4f,0.5f,0.4f);
               
                projectionMatrix=new Matrix4f();
                projectionMatrix.changeToPerspecitveMatrix(Config.FIELD_OF_VIEW, Config.NEAR_PLANE, Config.FAR_PLANE,canvas.getHeight(),canvas.getWidth());
               
                camera= new Camera(canvas,0,1,5,0,0,0);
               
                renderer = new Renderer(camera,projectionMatrix);
               
                shader=new BasicShader("Phong");
       
            @SuppressWarnings("unused")
                AmbientLight ambientLight = new AmbientLight(1);    
               
                @SuppressWarnings("unused") //new DirectionalLight(lightDirection,        diffuseColor,          speculaColor)
                DirectionalLight directionalLight=new DirectionalLight(new Vector3f(0, 0, -1), new Vector3f(1, 1, 1), new Vector3f(1, 1, 1));
               
                    //new Material(emissionColor,         ambientColor,                 diffuseColor,                 specularColor,                shininess)
                Material basicMaterial = new Material(new Vector3f(0, 0, 0), new Vector3f(0.2f,0.2f,0.2f), new Vector3f(0.5f,0.5f,0.5f), new Vector3f(1.f, 1.f, 1.f), 16);
               
                teapot = new Model("teapot",basicMaterial);
                teapot.setScale(0.8f);
       
        }

        @Override
        public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
                GL4 gl=(GL4)GLContext.getCurrentGL();
                gl.glViewport(0, 0, width, height);
                Config.CANVAS_HEIGHT=height;
                Config.CANVAS_WIDTH=width;
                renderer.getProjectionMatrix().changeToPerspecitveMatrix(Config.FIELD_OF_VIEW, Config.NEAR_PLANE, Config.FAR_PLANE,canvas.getHeight(),canvas.getWidth());
                canvas.setSize(width, height);
        }
       
}
Reply | Threaded
Open this post in threaded view
|

Re: Jogl and JavaFX

Sweck
In reply to this post by DamagedTiberius
" I've never used Newt before, so I really had no basis of what to look for other than differences between the code I'm troubleshooting and an example of working code. I usually find that a good start when you're approaching something like this is to find the top and start skimming through the chain of methods to find the types of operations you're looking for, so you can start comparing against how you did it. "

Thats exactly what I tried too when I saw someone referencing the unit test in a forum. I saw some stuff I needed in there but I didnt get the whole picture and expecially dont know how to integrate this all thats why I asked the main question in this forum. I started programming 1 1/2 years ago and have like 0 experience with all of this.

But your explanations help me a lot thank you very much.
Reply | Threaded
Open this post in threaded view
|

Re: Jogl and JavaFX

DamagedTiberius
In reply to this post by Sweck
I think you need to call initCanvas() before showing the window. I didn't really look at your other methods based on your statement though.
12