Hello,
I have a little problem with picking.
1-
First, I use the GLCanvas component, and I don’t animate it. When I want to refresh the image, I explicitly call glCanvas.display().
To do picking, I detect the mousePressed event on my glCanvas, and I call my picking method (pickRay) .
public void mousePressed(MouseEvent evt)
{
if ( evt.getButton() == MouseEvent.BUTTON1)
{
mousePos.x = evt.getX();
mousePos.y = evt.getY();
if(glcanvas.isVisible())
pickRay(glcanvas.getGL(), glcanvas.getGLU(), mousePos.x, mousePos.y);
//bSelection = true;
//glCanvas.display();
}
}
private boolean pickRay(GL gl, GLU glu, double mouse_x, double mouse_y) //--- problème avec le IntBuffer -> class abstraite
{ // This Is Where Selection Is Done
System.out.println("debut picking");
IntBuffer buffer = BufferUtils.newIntBuffer(512);
int hits; // The Number Of Objects That We Selected
// The Size Of The Viewport. [0] Is <x>, [1] Is <y>, [2] Is <width>, [3] Is <height>
int[] viewport = new int[4];
// This Sets The Array <viewport> To The Size And Location Of The Screen Relative To The Window
gl.glGetIntegerv(GL.GL_VIEWPORT, viewport);
gl.glSelectBuffer(512, buffer); // Tell OpenGL To Use Our Array For Selection
// Puts OpenGL In Selection Mode. Nothing Will Be Drawn. Object ID's and Extents Are Stored In The Buffer.
gl.glRenderMode(GL.GL_SELECT);
gl.glInitNames(); // Initializes The Name Stack
gl.glPushName(0); // Push 0 (At Least One Entry) Onto The Stack
gl.glMatrixMode(GL.GL_PROJECTION); // Selects The Projection Matrix
gl.glPushMatrix(); // Push The Projection Matrix
gl.glLoadIdentity(); // Resets The Matrix
// This Creates A Matrix That Will Zoom Up To A Small Portion Of The Screen, Where The Mouse Is.
glu.gluPickMatrix( (double)mouse_x, (double)(viewport[3]-mouse_y), 2.0f, 10.0f, viewport);
// Apply The Perspective Matrix
glu.gluPerspective(45.0f, (float) viewport[2] / (float)viewport[3], 0.1f, 100.0f); // Calculate The Aspect Ratio Of The Window
gl.glMatrixMode(GL.GL_MODELVIEW); // Select The Modelview Matrix
drawScene(gl); // Render The Targets To The Selection Buffer
gl.glMatrixMode(GL.GL_PROJECTION); // Select The Projection Matrix
gl.glPopMatrix(); // Pop The Projection Matrix
gl.glMatrixMode(GL.GL_MODELVIEW); // Select The Modelview Matrix
int cont[] = new int[1];
gl.glGetIntegerv(GL.GL_NAME_STACK_DEPTH, cont);
hits = gl.glRenderMode(GL.GL_RENDER); // Switch To Render Mode, Find Out How Many
if (hits > 0)
{
System.out.println("un objet trouvé");
int choose = buffer.get(3); // Make Our Selection The First Object
int depth = buffer.get(1); // Store How Far Away It Is
int last = 0;
for (int loop = 0; loop < hits; loop++)
{ // Loop Through All The Detected Hits
// If This Object Is Closer To Us Than The One We Have Selected
if (buffer.get(last+1) < (int)depth)
{
choose = buffer.get(last+3); // Select The Closer Object
depth = buffer.get(last+1); // Store How Far Away It Is
}
last += buffer.get(last) + 3;
}
try
{
String s = "" + choose;
//my treatments ........
}
catch(NullPointerException e)
{
/*e.printStackTrace();*/
{
System.out.println("PickRay: No Object Selected !");
}
}
}
return false;
}
Could anyone tell me if this code is ok?
Then, calling pickRay from the moussePressed event doesn’t work, the method pickRay is well called, but there isn’t any object picked detected (and all my objects are correctly identified with glLoadName…).
But if I put a boolean variable (bSelection) to true when the mousePressed event is called, then I call glCanvas.display(), and then, in my display() method, I call the pickRay method when bSelection is true, my objects are correctly picked.
So, why DO we have to call pickRay from the display method ???
2-
Then, I have another problem. It seems that I have an “intermediate” image where my scene is drawn two times.
When I press down the mouse, the image present on my glCanvas is the scene drawn two times, at different places…
And I have to call glCanvas.display in the mouseReleased method in order to have a good image. (Or to call two times the glCanvas.display() method in the mousePressed event).
This problem doesn’t appear visually if I launch the animator, because I think we don’t have the time to see this image when the frame rate is over 20 or 100…
So if someone could help me… It is probably an error on the pickRay method, or a problem with my buffers (perhaps I should use swapBuffer somewhere? or desactivate autoSwapBuffer? )
Thank you.