Are you doing all of your GL calls within your GLEventListener’s init(), display(), and other callbacks?
Picking and selection via the OpenGL selection buffer definitely work in JOGL. Here’s an example from our JavaOne 2004 talk, originally authored by Thomas Bladh.
//=================================================================================
// Picking 0.2 (Thomas Bladh)
//=================================================================================
// A simple picking example using java/jogl. This is far from a complete solution
// but it should give you an idea of how to include picking in your assigment
// solutions.
//
// Notes: * Based on example 13-3 (p 542) in the "OpenGL Programming Guide"
// * This version should handle overlapping objects correctly.
//---------------------------------------------------------------------------------
import java.awt.*;
import java.awt.event.*;
import java.awt.Canvas.*;
import java.nio.*;
import java.util.*;
import net.java.games.jogl.*;
import net.java.games.jogl.util.*;
class Picking
{
public static void main(String[] args)
{
new Picking();
}
Picking()
{
Frame frame = new Frame("Picking Example");
GLDrawableFactory factory = GLDrawableFactory.getFactory();
GLCapabilities capabilities = new GLCapabilities();
GLCanvas drawable = factory.createGLCanvas(capabilities);
drawable.addGLEventListener(new Renderer());
frame.add(drawable);
frame.setSize(400, 400);
final Animator animator = new Animator(drawable);
frame.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
animator.stop();
System.exit(0);
}
});
frame.show();
animator.start();
}
static class Renderer implements GLEventListener, MouseListener, MouseMotionListener
{
static final int NOTHING = 0, UPDATE = 1, SELECT = 2;
int cmd = UPDATE;
int mouse_x, mouse_y;
private GL gl;
private GLU glu;
private GLDrawable gldrawable;
public void init(GLDrawable drawable)
{
gl = drawable.getGL();
glu = drawable.getGLU();
this.gldrawable = drawable;
gl.glEnable(GL.GL_CULL_FACE);
gl.glEnable(GL.GL_DEPTH_TEST);
gl.glEnable(GL.GL_NORMALIZE);
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
drawable.addMouseListener(this);
drawable.addMouseMotionListener(this);
}
public void reshape(GLDrawable drawable, int x, int y, int width, int height)
{
float h = (float) height / (float) width;
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluOrtho2D(0.0f,1.0f,0.0f,1.0f);
}
public void display(GLDrawable drawable)
{
switch(cmd)
{
case UPDATE:
drawScene();
break;
case SELECT:
int buffsize = 512;
double x = (double) mouse_x, y = (double) mouse_y;
int[] viewPort = new int[4];
IntBuffer selectBuffer = BufferUtils.newIntBuffer(buffsize);
int hits = 0;
gl.glGetIntegerv(GL.GL_VIEWPORT, viewPort);
gl.glSelectBuffer(buffsize, selectBuffer);
gl.glRenderMode(GL.GL_SELECT);
gl.glInitNames();
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glPushMatrix();
gl.glLoadIdentity();
glu.gluPickMatrix(x, (double) viewPort[3] - y, 5.0d, 5.0d, viewPort);
glu.gluOrtho2D(0.0d, 1.0d, 0.0d, 1.0d);
drawScene();
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glPopMatrix();
gl.glFlush();
hits = gl.glRenderMode(GL.GL_RENDER);
processHits(hits, selectBuffer);
cmd = UPDATE;
break;
}
}
public void processHits(int hits, IntBuffer buffer)
{
System.out.println("---------------------------------");
System.out.println(" HITS: " + hits);
int offset = 0;
int names;
float z1, z2;
for (int i=0;i<hits;i++)
{
System.out.println("- - - - - - - - - - - -");
System.out.println(" hit: " + (i + 1));
names = buffer.get(offset); offset++;
z1 = (float) buffer.get(offset) / 0x7fffffff; offset++;
z2 = (float) buffer.get(offset) / 0x7fffffff; offset++;
System.out.println(" number of names: " + names);
System.out.println(" z1: " + z1);
System.out.println(" z2: " + z2);
System.out.println(" names: ");
for (int j=0;j<names;j++)
{
System.out.print(" " + buffer.get(offset));
if (j==(names-1))
System.out.println("<-");
else
System.out.println();
offset++;
}
System.out.println("- - - - - - - - - - - -");
}
System.out.println("---------------------------------");
}
public int viewPortWidth()
{
int[] viewPort = new int[4];
gl.glGetIntegerv(GL.GL_VIEWPORT, viewPort);
return viewPort[2];
}
public int viewPortHeight()
{
int[] viewPort = new int[4];
gl.glGetIntegerv(GL.GL_VIEWPORT, viewPort);
return viewPort[3];
}
public void drawScene()
{
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
// Colors
float red[] = {1.0f,0.0f,0.0f,1.0f};
float green[] = {0.0f,1.0f,0.0f,1.0f};
float blue[] = {0.0f,0.0f,1.0f,1.0f};
// Red rectangle
GLRectangleEntity r1 = new GLRectangleEntity(gl, glu);
r1.x = 0.15f;
r1.y = 0.25f;
r1.w = 0.4f;
r1.h = 0.4f;
r1.c = red;
r1.id = 10;
r1.draw();
// Green rectangle
GLRectangleEntity r2 = new GLRectangleEntity(gl, glu);
r2.x = 0.35f;
r2.y = 0.45f;
r2.w = 0.4f;
r2.h = 0.4f;
r2.c = green;
r2.id = 20;
r2.draw();
// Blue rectangle
GLRectangleEntity r3 = new GLRectangleEntity(gl, glu);
r3.x = 0.45f;
r3.y = 0.15f;
r3.w = 0.4f;
r3.h = 0.4f;
r3.c = blue;
r3.id = 30;
r3.draw();
gl.glFlush();
}
public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {}
public void mousePressed(MouseEvent e)
{
cmd = SELECT;
mouse_x = e.getX();
mouse_y = e.getY();
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mouseDragged(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {}
public abstract class GLEntity
{
float x, y, z;
float[] c;
int id = 0;
boolean outline = false;
GL gl;
GLU glu;
public GLEntity(GL gl, GLU glu)
{
this.gl = gl;
this.glu = glu;
}
public void draw()
{
gl.glPushName(id);
_draw();
}
public abstract void _draw();
}
public class GLRectangleEntity extends GLEntity
{
float w = 0.1f;
float h = 0.1f;
public GLRectangleEntity(GL gl, GLU glu)
{
super(gl, glu);
}
public void _draw()
{
if (outline)
gl.glPolygonMode(GL.GL_FRONT, GL.GL_LINE);
else
gl.glPolygonMode(GL.GL_FRONT, GL.GL_FILL);
gl.glColor4fv(c);
gl.glBegin(GL.GL_POLYGON);
gl.glVertex3f(x, y, z);
gl.glVertex3f(x + w, y, z);
gl.glVertex3f(x + w, y + h, z);
gl.glVertex3f(x, y + h, z);
gl.glEnd();
}
}
}
}