Login  Register

JOGL - without GLEventListener (GLCanvas or GLJPanel)

Posted by Andrzej on Apr 23, 2018; 5:16pm
URL: https://forum.jogamp.org/JOGL-without-GLEventListener-GLCanvas-or-GLJPanel-tp4038837.html

Hi,

So I have a need to NOT use GLEventListener (native c++ dll doing the rendering, asynchronously on demand, and requires it to be on the same calling thread - all I need it a context, make it current on the same thread, and the native C++ code does the rest, there is no option to rewrite this code in Java)

I was able to get it to work with GLWindow, but I need to be able to have the OpenGL embeded in a JPanel (I couldn't get it to work with NewtCanvasAWT as some people here suggested), and I can't get the same code to work with GLCanvas or GLJpanel (when I set everything up the getContext() method always returns null).

Here is the working GLWindow code, just a proof of concept (I have it working also with my native c++ renderer), rendering a triangle:

package test;


import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.*;

public final class RenderJOGL
{  
   private GLContext glContext;
   private GLWindow glWindow;
   private GL gl;
   public RenderJOGL() throws Throwable
   {
          GLProfile glProfile = GLProfile.get("GL2");
      GLCapabilities glCaps = new GLCapabilities(glProfile);  
      glCaps.setDoubleBuffered(false);
      glCaps.setHardwareAccelerated(true);

      glWindow = GLWindow.create(glCaps);
      glWindow.setSize(800, 600);
      glWindow.setVisible(true);
     
      glContext = glWindow.getContext();
      this.gl = glContext.getGL();
   }
   
   public GLWindow getWindow() {
           return glWindow;
   }
   
   public void setSize(int viewPixelWidth,int viewPixelHeight)//,int maxAntialias)
   {
      glWindow.setSize(viewPixelWidth,viewPixelHeight);
   }      
   
   public void render()
   {  
      this.makeContentCurrent();

      GL2 gl2 = gl.getGL2();
     
      gl2.glDisable(GL.GL_DEPTH_TEST);
      gl2.glClearColor(0.0f,1.0f,1.0f,0.0f);   //Background blue
      gl2.glClear(GL.GL_COLOR_BUFFER_BIT);
      gl2.glLoadIdentity();  
      gl2.glColor3f(1.0f, 0.0f, 0.0f);   //Color red
      gl2.glBegin(GL.GL_TRIANGLES);
      gl2.glVertex3f(0,0,0.0f);
      gl2.glVertex3f(1,0,0.0f);
      gl2.glVertex3f(0,1,0.0f);        
      gl2.glEnd();
     
      glWindow.display();
   }
   
   private void makeContentCurrent()
   {  
      try
      {
         while (glContext.makeCurrent() == GLContext.CONTEXT_NOT_CURRENT)
         {
            System.out.println("Context not yet current...");
            Thread.sleep(100);
         }
      }
      catch (InterruptedException e)
      {
          e.printStackTrace();
      }
   }          
}

and a simple runner for it:


public class RenderJOGLRunner {
       
   public static void main(String[] args) {
           try {
                RenderJOGL render = new RenderJOGL();
               
                while(true) {
                        render.render();
                }
        } catch (Throwable e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
        }  
   }
}

But when I try something similar with GLJPanel, when I want to render the GLContext is null, this is my GLJPanel implementation:

package test;

import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLContext;
import com.jogamp.opengl.awt.GLJPanel;

public class OpenGLPanel extends GLJPanel {

    public OpenGLPanel(GLCapabilities caps) {
                super(caps);
    }

    public void render() {

                this.setSize(800, 600);
               
        this.setVisible(true);
        this.display();
   
//THIS IS ALWAYS NULL
        while (this.getContext() == null)
        {
           System.out.println("Context null...");
                   try {
                                Thread.sleep(1000);
                        } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                        }
        }
   
        while (this.getContext().makeCurrent() == GLContext.CONTEXT_NOT_CURRENT)
        {
           System.out.println("Context not yet current...");
                   try {
                                Thread.sleep(100);
                        } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                        }
        }
   
        GL2 gl2 = this.getContext().getGL().getGL2();
   
        gl2.glDisable(GL.GL_DEPTH_TEST);
        gl2.glClearColor(0.0f,1.0f,1.0f,0.0f);   //Background blue
        gl2.glClear(GL.GL_COLOR_BUFFER_BIT);
        gl2.glLoadIdentity();  
        gl2.glColor3f(1.0f, 0.0f, 0.0f);   //Color red
        gl2.glBegin(GL.GL_TRIANGLES);
        gl2.glVertex3f(0,0,0.0f);
        gl2.glVertex3f(1,0,0.0f);
        gl2.glVertex3f(0,1,0.0f);        
        gl2.glEnd();
       
        this.display();
}
}

and how I use it:

private void createUI() {
        getContentPane().setBackground(Color.white);

        setMinimumSize(new Dimension(640, 480));

        topBar_ = new JToolBar("Top Bar");
        topBar_.setMinimumSize(new Dimension(100, 30));
        topBar_.setFloatable(false);

        bottomBar_ = new JToolBar("Bottom Bar");
        bottomBar_.setMinimumSize(new Dimension(100, 30));
        bottomBar_.setFloatable(false);
               
        Container pane = getContentPane();
        pane.setLayout(new BorderLayout());

        middlePanel_ = new JPanel(new BorderLayout(), false);
        middlePanel_.setBackground(Color.lightGray);
        middlePanel_.setPreferredSize(new Dimension(800, 600));

        OpenGLPanel panel = this.getTestGLJPanel();
        middlePanel_.add(panel, BorderLayout.CENTER);

        getRootPane().addComponentListener(new ComponentAdapter() {
            public void componentResized(ComponentEvent e) {
                openGLPanel_.setPreferredSize(openGLPanel_.getSize());
            }
        });

        pane.add(topBar_, BorderLayout.NORTH);
        pane.add(middlePanel_, BorderLayout.CENTER);
        pane.add(bottomBar_, BorderLayout.SOUTH);
               
        pack();
        setLocationRelativeTo(null);
               
        panel.render();
}


I'm not sure what I can be doing wrong. I tried with GLCanvas as well, but basically same thing as in GLJPanel. I just don't know how to use it without using the GLEventListener.