PDA

View Full Version : JOGL Selection



Empty
06-25-2010, 11:00 PM
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();

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

@Override
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() {
animator.stop();
System.exit(0);
}
}).start();
}
});
// Center frame
frame.setLocationRelativeTo(null);
frame.setVisible(true);
animator.start();

}

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
gl.setSwapInterval(1);

// 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);
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(45, taxaDeAspecto, 0.5f, 1600f);
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();

ajustarCamara();
}

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

// Clear the drawing area
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
// Reset the current matrix to the "identity"

if(isClicked){
seleciona();
}

gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
GLUquadric quadric = glu.gluNewQuadric();
gl.glPushMatrix();
glu.gluSphere(quadric, 10f, 16, 16);
gl.glPopMatrix();
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){
pararseleciona();
}

ajustarCamara();
// Flush all drawing operations to the graphics card
gl.glFlush();

}

public void ajustarCamara(){
gl.glMatrixMode(GL.GL_PROJECTION);

gl.glLoadIdentity();

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
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glPushMatrix();
gl.glLoadIdentity();

// 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);

System.out.println(xCursor);
System.out.println(yCursor);
/* 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
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glPopMatrix();
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glFlush();

// return to normal rendering mode, and process hits
int numHits = gl.glRenderMode(GL.GL_RENDER);
System.out.println(numHits+"wtf");

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) {
}
}