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