View Full Version : JOGL Selection

06-26-2010, 12:00 AM
Hi guys, i need some help in JOGL selection, i tried to select an sphere, but when i click anywhere in the screen i get the selection of the sphere (it only should happen when i click in the sphere), Please, i just tried many things and i can't figure out the mistake. I'm leaving my code, any answer is well received.
Thanks in advance

package org.yourorghere;

import com.sun.opengl.util.Animator;
import com.sun.opengl.util.BufferUtil;
import java.awt.Frame;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.nio.IntBuffer;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;
import javax.media.opengl.glu.GLUquadric;
import java.awt.event.MouseListener;

* Pick.java <BR>
* author: Brian Paul (converted to Java by Ron Cemer and Sven Goethel) <P>
* This version is equal to Brian Paul's version 1.2 1999/10/21

public class Pick implements GLEventListener, MouseListener {

private GLU glu;
private GL gl;
private float taxaDeAspecto;
// picking
private boolean inSelectionMode = false;
private int xCursor, yCursor;
private IntBuffer selectBuffer;
private boolean isClicked = false;
private static final int BUFSIZE = 512; // size of selection buffer

public static void main(String[] args) {
Frame frame = new Frame("Simple JOGL Application");
GLCanvas canvas = new GLCanvas();
Pick pa = new Pick();

frame.setSize(640, 480);
final Animator animator = new Animator(canvas);
frame.addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e) {
// Run this on another thread than the AWT event queue to
// make sure the call to Animator.stop() completes before
// exiting
new Thread(new Runnable() {

public void run() {
// Center frame


public void init(GLAutoDrawable drawable) {
// Use debug pipeline
// drawable.setGL(new DebugGL(drawable.getGL()));

gl = drawable.getGL();
glu = new GLU();
System.err.println("INIT GL IS: " + gl.getClass().getName());

// Enable VSync

// Setup the drawing area and shading mode
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
//gl.glShadeModel(GL.GL_SMOOTH); // try setting this to GL_FLAT and see what happens.


public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
gl = drawable.getGL();

if (height <= 0) { // avoid a divide by zero error!

height = 1;
taxaDeAspecto = (float) width / (float) height;
gl.glViewport(0, 0, width, height);
glu.gluPerspective(45, taxaDeAspecto, 0.5f, 1600f);


public void display(GLAutoDrawable drawable) {
gl = drawable.getGL();

// Clear the drawing area
// Reset the current matrix to the "identity"


GLUquadric quadric = glu.gluNewQuadric();
glu.gluSphere(quadric, 10f, 16, 16);
drawable.swapBuffers(); // put the scene onto the canvas
// swap front and back buffers, making the new rendering visible
/* This call was moved here from renderLoop() so it's only called
when the 'real' scene needs to be shown; the 'pick' scene is
never swapped. If it is then there's a very distinct flicker as
rendering switches between the two scenes.
if (isClicked){

// Flush all drawing operations to the graphics card


public void ajustarCamara(){


double localizacao[] = new double[3];
double alvo[] = new double[3];
double direcao[] = new double[3];

localizacao[0] = 100.0d;
localizacao[1] = 100.0d;
localizacao[2] = 100.0d;

alvo[0] = 0.0d;
alvo[1] = 0.0d;
alvo[2] = 0.0d;

direcao[0] = 0.0d;
direcao[1] = 1.0d;
direcao[2] = 0.0d;

glu.gluPerspective(45, taxaDeAspecto, 0.5f, 1600f);

glu.gluLookAt(localizacao[0], localizacao[1], localizacao[2],
alvo[0], alvo[1], alvo[2],
direcao[0], direcao[1], direcao[2]);


public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {

// ------------------ picking methods --------------------------

/* Trata eventos de clique do mouse */
public void mouseClicked(MouseEvent evento) {
int botaoClicado = evento.getButton();
/* BUTTON1 = Botão Esquerdo */
if (botaoClicado == MouseEvent.BUTTON1) {
Point posicao = evento.getPoint();
System.out.printf("Posicao do mouse: (%f, %f)\n",
posicao.getX(), posicao.getY());

/* Passa as coordenadas do mouse para o OpenGL*/
xCursor = evento.getX();
yCursor = evento.getY();
isClicked = true;


private void seleciona()
/* Switch to selection mode, initialize necessary data structures
and create a 'picking' area using the viewport. */
// initialize the selection buffer
int selectBuf[] = new int[BUFSIZE];
selectBuffer = BufferUtil.newIntBuffer(BUFSIZE);
gl.glSelectBuffer(BUFSIZE, selectBuffer);

gl.glRenderMode(GL.GL_SELECT); // switch to selection mode

gl.glInitNames(); // make an empty name stack
// gl.glPushName(-1); // not needed

/* redefine the viewing volume so it only renders a
small area around the place where the mouse was clicked */

// save the original projection matrix

// get the current viewport
int viewport[] = new int[4];
gl.glGetIntegerv(GL.GL_VIEWPORT, viewport, 0);

// create a 5x5 pixel picking area near the cursor location
glu.gluPickMatrix((double) xCursor,
(double) (viewport[3] - yCursor),
5.0, 5.0, viewport, 0);

/* The y-value uses an 'inverted' yCursor to transform the y-coordinates
origin from the upper left corner into the bottom left corner. */

/* set projection (perspective or orthogonal) exactly as it is in
normal rendering (i.e. duplicate the gluPerspective() call
in resizeView()) */
glu.gluPerspective(45, taxaDeAspecto, 0.5f, 1600f);

gl.glMatrixMode(GL.GL_MODELVIEW); // restore model view
} // end of startPicking()

private void pararseleciona()
/* Switch back to normal rendering, and extract 'hit information
generated because of picking. */
// restore original projection matrix

// return to normal rendering mode, and process hits
int numHits = gl.glRenderMode(GL.GL_RENDER);

isClicked = false;
} // end of endPicking()

private float getDepth(int offset)
/* A depth is in the range 0 to 1, but is stored
after being multiplied by 2^32 -1 and rounded to
the nearest integer. The number will be negative due to
the multiplication and being stored as an integer.
long depth = (long) selectBuffer.get(offset); // large -ve number
return (1.0f + ((float) depth / 0x7fffffff));
// return as a float between 0 and 1
} // end of getDepth()

public void mousePressed(MouseEvent e) {

public void mouseReleased(MouseEvent e) {

public void mouseEntered(MouseEvent e) {

public void mouseExited(MouseEvent e) {