need more examples of picking

While I have received an example of how to do picking in JOGL (thank you very much Ken), I am still unable to get it working properly and if anyone knows of other examples that I can look at, it would be greatly appreciated.

This is the only example I have …
http://www.sm.luth.se/~david/classes/smm009/TestPrograms/Picking.java

Here is a revised version of Thomas Bladh’s example that works with the NIO-only glSelectBuffer API.

If you are interested in clicking and dragging objects I would suggest you look at the gleem APIs in the jogl-demos workspace, which implement a few Open Inventor-style 3D manipulators.


//=================================================================================
// 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();
                  }                  
            }
      }
}

I think that glSelectBuffer effectively works by assigning names to pixels actually rasterized, so if you’re drawing just lines you’re probably not going to be able to find any information about them. You might be able to get this information in your setup by drawing the polygons (appropriately named) in solid black but with different individual names and then using glPolygonOffset to redraw the lines in your model. That would allow you to pick the faces but see the outlines.