Picking

Does anyone have a demo of picking working in Jogl? I had it working under c++ (SDL/win32) but I can’t get it working in Jogl - I think perhaps due to a threading issue, I’m not sure…

If anyone has example code, I’d really appreciate it - thanks!

Peter.

Seriously!? Noone anywhere has any examples of picking in Jogl???

Depends on what you mean by picking…

If you want to do picking with the mouse from camera view against geometry objects, you can use gluUnProject to convert a screen space point to virtual world space and then use that to make a ray for ray testing on geometry - all of this except the gluUnProject call is OpenGL independent.

If you want to use the readPixel techniques where you use the pixel color to ID an object, that should work as well although I have never both because this would not normally be an in-game technique.

And then there’s the “selection buffer” technique.

All of these are well documented in OGL books, on the web and at www.OpenGL.org. :slight_smile:
Try
http://www.opengl.org/developers/faqs/technical/selection.htm
and the NeHe picking tutorial
http://nehe.gamedev.net/lesson.asp?index=07
for starters.

Good luck

It was picking using the selection buffer that I was asking about.

I don’t need to know how it works - as I said in my first post, I had it working fine in C++, I just can’t get the same code running in Jogl.

This might work.

wz

/*

  • Created on Jul 7, 2003
  • To change the template for this generated file go to
  • Window>Preferences>Java>Code Generation>Code and Comments
    */

/**

  • @author w0zhang
  • To change the template for this generated type comment go to
  • Window>Preferences>Java>Code Generation>Code and Comments
    */

import java.awt.;
import java.awt.event.
;

import net.java.games.jogl.;
import net.java.games.jogl.util.
;

public class JoglTest
implements GLEventListener, MouseListener, MouseMotionListener, KeyListener {

  private Frame frame;

  private Animator animator;

  private GLCanvas canvas;

  private float prevMouseX, prevMouseY;
  private float mouseX, mouseY;
  private float transX = 0f, transY = 0f, transZ = -10.0f;
  private boolean picked;
  private int pickedName;

  private float view_rotX_1 = 0.0f, view_rotY_1 = 0.0f, view_rotZ = 0.0f;
  private float view_rotX_2 = 0.0f, view_rotY_2 = 0.0f;
  private final int test = 1;

  private float fAspect;

  float lambr = 0.0f;
  float lambg = 0.0f;
  float lambb = 0.0f;
  float ldifr = 1.0f;
  float ldifg = 1.0f;
  float ldifb = 1.0f;
  float lsper = 1.0f;
  float lspeg = 1.0f;
  float lspeb = 1.0f;
  float lposx = 0.8f;
  float lposy = 0.8f;
  float lposz = 0.8f;

  float light_ambient[] = { lambr, lambg, lambb, 1.0f };
  float light_diffuse[] = { ldifr, ldifg, ldifb, 1.0f };
  float light_specular[] = { lsper, lspeg, lspeb, 1.0f };
  float light_position[] = { lposx, lposy, lposz };
  float global_ambient[] = { 0.75f, 0.75f, 0.75f, 1.0f };
  float mambr = 0.25f;
  float mambg = 0.2f;
  float mambb = 0.074f;
  float mdifr = 0.57f;
  float mdifg = 0.14f;
  float mdifb = 0.17f;
  float msper = 0.8f;
  float mspeg = 0.65f;
  float mspeb = 0.25f;
  float ambient[] = { mambr, mambg, mambb, 1.0f };
  float diffuse[] = { mdifr, mdifg, mdifb, 1.0f };
  float specular[] = { msper, mspeg, mspeb, 1.0f };
  float shininess = 20.0f;

  private JoglTest() {
        System.out.println("JoglTest instance created");

        // Canvas setup
        GLCapabilities caps = new GLCapabilities();
        caps.setDoubleBuffered(true);
        caps.setAlphaBits(8);
        caps.setStencilBits(8);
        canvas = GLDrawableFactory.getFactory().createGLCanvas(caps);

        
        canvas.addGLEventListener(this);
        canvas.setGL(new DebugGL(canvas.getGL()));
        canvas.addMouseListener(this);
        canvas.addMouseMotionListener(this);
        canvas.addKeyListener(this);

        // Frame setup
        frame = new Frame("Vectrix");
        frame.add(canvas);
        frame.setSize(800, 600);

        frame.addWindowListener(new WindowAdapter() {
              public void windowClosing(WindowEvent e) {
                    animator.stop();
                    System.exit(0);
              }
        });

        // Event handlers
        animator = new Animator(canvas);
  }

  public void initialiseDisplay() {
        frame.show();
  }

  public void run() {
        animator.start();
  }

  public static void main(String[] args) {
        System.out.println("Vectrix starting...");

        JoglTest app = new JoglTest();
        app.initialiseDisplay();

        // Other loading/initialisation
        // ..

        // Start main game loop
        app.run();
  }

  // GL Event Listener methods

  // Called when GL has been initialised for the first time.
  public void init(GLDrawable drawable) {
        System.out.println("Vectrix.init(): GL init event");

        GL gl = drawable.getGL();

        // light properties
        gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, light_ambient);
        gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, light_diffuse);
        gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, light_specular);
        gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, light_position);
        gl.glLightModelfv(GL.GL_LIGHT_MODEL_AMBIENT, global_ambient);
        
        // material properties
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, ambient);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, diffuse);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, specular);
        gl.glMaterialf(GL.GL_FRONT, GL.GL_SHININESS, shininess);

        // various OpenGL states
        gl.glFrontFace(GL.GL_CW);
        gl.glEnable(GL.GL_LIGHTING);
        gl.glEnable(GL.GL_LIGHT0);
        gl.glEnable(GL.GL_AUTO_NORMAL);
        gl.glEnable(GL.GL_NORMALIZE);
        gl.glDepthFunc(GL.GL_LESS);
        gl.glEnable(GL.GL_DEPTH_TEST);

        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glMatrixMode(GL.GL_TEXTURE);
        gl.glLoadIdentity();
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glLoadIdentity();

  }

  public void display(GLDrawable drawable) {

        //System.err.println("DISPLAY THREAD: " + Thread.currentThread());
        draw(drawable);

        if (picked)
              processSelection(drawable, mouseX, mouseY);
  }

  public void draw(GLDrawable drawable) {

        //System.err.println("DISPLAY THREAD: " + Thread.currentThread());
        GL gl = drawable.getGL();
        GLU glu = drawable.getGLU();
        //setLightmat(gl);

        gl.glClearColor(0.2f, 0.2f, 0.2f, 0.0f);
        gl.glClear(
              GL.GL_COLOR_BUFFER_BIT
                    | GL.GL_DEPTH_BUFFER_BIT
                    | GL.GL_STENCIL_BUFFER_BIT);

        //gl.glColor3f(1f, 0f, 0f);
        float ambient[] = { 0.4f, 0.4f, 0.4f, 1.0f };
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, ambient);

        GLUT glut = new GLUT();

        gl.glPushMatrix();
        gl.glTranslatef(transX, transY, transZ);
        gl.glRotatef(view_rotX_1, 1.0f, 0.0f, 0.0f);
        gl.glRotatef(view_rotY_1, 0.0f, 1.0f, 0.0f);
        gl.glRotatef(view_rotZ, 0.0f, 0.0f, 1.0f);

        //gl.glPushMatrix();

        //gl.glTranslatef(0f, 0f, -3f);
        //gl.glRotatef(30f, 0f, 1f, 0f);
        gl.glInitNames();
        gl.glPushName(0);
        gl.glLoadName(1);
        glut.glutWireSphere(glu, 0.5, 100, 100);

        //gl.glPopMatrix();
        //gl.glPopName();
        gl.glPopMatrix();

        gl.glPushMatrix();
        gl.glTranslatef(transX - 2, transY, transZ);
        gl.glRotatef(view_rotX_2, 1.0f, 0.0f, 0.0f);
        gl.glRotatef(view_rotY_2, 0.0f, 1.0f, 0.0f);
        gl.glRotatef(view_rotZ, 0.0f, 0.0f, 1.0f);

        //gl.glPushMatrix();

        //gl.glTranslatef(0f, 0f, -3f);
        //gl.glRotatef(30f, 0f, 1f, 0f);

        gl.glLoadName(2);

        glut.glutSolidTetrahedron(gl);

        //gl.glPopMatrix();
        //gl.glPopName();
        gl.glPopMatrix();
        gl.glFlush();

  }

  public void reshape(
        GLDrawable drawable,
        int x,
        int y,
        int width,
        int height) {
        //System.err.println("RESHAPE THREAD: " + Thread.currentThread());
        GL gl = drawable.getGL();
        GLU glu = drawable.getGLU();
        fAspect = (float) width / (float) height;

        //   l/r  b/t  near/far
        //gl.glMatrixMode(GL.GL_PROJECTION);
        //gl.glOrtho(0, 4, 0, 3, -8, 8);

        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();
        glu.gluPerspective(30.0, (float) width / (float) height, 1.0, 50);
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glLoadIdentity();
        //glu.gluLookAt(0.0, 0, 10, 0, 0, 0, 0, 1, 0);

  }

  public void displayChanged(GLDrawable arg0, boolean arg1, boolean arg2) {
  }

  public void processSelection(GLDrawable drawable, float x, float y) {
        GL gl = drawable.getGL();
        GLU glu = drawable.getGLU();
        int[] selectBuff = new int[64];
        int hits = 0;
        int[] viewport = new int[4];

        gl.glSelectBuffer(64, selectBuff);
        gl.glGetIntegerv(GL.GL_VIEWPORT, viewport);
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glPushMatrix();

        gl.glRenderMode(GL.GL_SELECT);
        gl.glLoadIdentity();
        glu.gluPickMatrix(x, viewport[3] - y, 5, 5, viewport);
        glu.gluPerspective(30.0f, fAspect, 1.0, 50);
        draw(drawable);
        hits = gl.glRenderMode(GL.GL_RENDER);
        if (hits > 0) {
              int count = selectBuff[0];
              pickedName = selectBuff[3];
              System.out.println(count + " " + pickedName);

        } else {
              System.out.println("no hit");
              pickedName = 0;
        }

        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glPopMatrix();
        gl.glMatrixMode(GL.GL_MODELVIEW);
        picked = false;

  }

  public void processKey(KeyEvent event) {
        int key = event.getKeyCode();

        if (event.isControlDown() && key == KeyEvent.VK_DOWN) {
              transY -= 0.1f;
        } else if (event.isControlDown() && key == KeyEvent.VK_UP) {
              transY += 0.1f;
        } else if (key == KeyEvent.VK_DOWN) {
              transZ += 0.1f;
        } else if (key == KeyEvent.VK_UP) {
              transZ -= 0.1f;
        } else if (key == KeyEvent.VK_LEFT) {
              transX -= 0.1f;
        } else if (key == KeyEvent.VK_RIGHT) {
              transX += 0.1f;
        }
  }

  public void mouseEntered(MouseEvent e) {
  }
  public void mouseExited(MouseEvent e) {
  }

  public void mousePressed(MouseEvent e) {
        prevMouseX = e.getX();
        prevMouseY = e.getY();
        mouseX = e.getX();
                    mouseY = e.getY();
                    picked = true;
  }

  public void mouseReleased(MouseEvent e) {
  }
  public void mouseClicked(MouseEvent e) {

  }

  public void mouseDragged(MouseEvent e) {
        int x = e.getX();
        int y = e.getY();

        Dimension size = e.getComponent().getSize();
        //System.out.println(size.width + " " + size.height);

        float thetaY = 360.0f * (float) (x - prevMouseX) / (float) size.width;
        float thetaX = 360.0f * (float) (prevMouseY - y) / (float) size.height;

        prevMouseX = x;
        prevMouseY = y;

        switch(pickedName){
              case 1:
                    view_rotX_1 += thetaX;
                    view_rotY_1 += thetaY;
                    break;
              case 2:
                    view_rotX_2 += thetaX;
                    view_rotY_2 += thetaY;
                    break;
        }
  }

  public void mouseMoved(MouseEvent e) {
  }

  public void keyPressed(KeyEvent e) {
        processKey(e);
  }

  public void keyReleased(KeyEvent e) {

  }

  public void keyTyped(KeyEvent e) {

  }

}

[quote]/*

  • Created on Jul 7, 2003
  • To change the template for this generated file go to
  • Window>Preferences>Java>Code Generation>Code and Comments
    */

/**

  • @author w0zhang
  • To change the template for this generated type comment go to
  • Window>Preferences>Java>Code Generation>Code and Comments
    */
    [/quote]
    Someone needs to edit their Eclipse preferences. :slight_smile:

[quote]This might work.
[/quote]
Cheers! That does indeed work.

Thanks, I now have a working version to compare to my… not-so working version :o).

Peter.