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.