Selection problem

Well I have the following code in my camera class


      public void viewFrom(){
      
            
            GLU.gluLookAt(_position._x,_position._y,_position._z,_view._x,_view._y,_view._z,_top.getX(),_top.getY(),_top.getZ());
            
            //GL.glViewport(0,0,800,600);
            
            GL.glMatrixMode(GL.GL_PROJECTION);
            GL.glLoadIdentity();
            GLU.gluPerspective(90,1.25,this._minDepth,this._maxDepth);
            GL.glMatrixMode(GL.GL_MODELVIEW);
      
      }

This makes me look at my system from above, now I want todo a selction so I have a selction method.


public void selection(){
            // The Size Of The Viewport. [0] Is <x>, [1] Is <y>, [2] Is <width>, [3] Is <height>
            IntBuffer viewPort = ByteBuffer.allocateDirect(4*8).order(ByteOrder.nativeOrder()).asIntBuffer();
            // This Sets The Array <viewport> To The Size And Location Of The Screen Relative To The Window
            GL.glGetInteger(GL.GL_VIEWPORT, viewPort);      
            System.out.println("view x,y,z" + viewPort.get(1) +","+ viewPort.get(2) +","+ viewPort.get(3) +","+ viewPort.get(4));
            
            GL.glSelectBuffer(ibuf);
            
            GL.glRenderMode(GL.GL_SELECT);
            
            GL.glInitNames();
            GL.glPushName(-1);
            
                  
            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.dx,  (double)(viewPort.get(3)-Mouse.dy), 5.0f, 5.0f, viewPort);
            //GLU.gluPerspective(_camera.get_fow(), _camera.get_aspect(), _camera.get_minDepth(), _camera.get_maxDepth());
      
            GL.glMatrixMode(GL.GL_MODELVIEW);
            GL.glLoadIdentity();
            //GLU.gluOrtho2D (0.0, 3.0, 0.0, 3.0);
            drawSystem();
            
            GL.glMatrixMode(GL.GL_PROJECTION);                                                // Select The Projection Matrix
            GL.glPopMatrix();// Pop The Projection Matrix
                                                                  
            GL.glMatrixMode(GL.GL_MODELVIEW);
            int hits =GL.glRenderMode(GL.GL_RENDER);

my problem is that the world rendered in GL_SELECT is NOT the same as my world seen from the camera class… How the hell do I do that???

From the red book:
“You use the utility routine gluPickMatrix() to multiply a special projection matrix onto the current matrix. This routine should be called prior to multiplying a projection matrix onto the stack.”

So you still need to call GLU.gluPerspective(). It is commented out in your code. Also I guess it needs to be exactly the same as the one used in rendering mode.

Mouse.dx and Mouse.dy returns the differance in mouse movement since last poll, not absolute mouse pos. You have to keep track of the mouse position yourself by adding Mouse.dx and Mouse.dy after each poll. With this setup you will only be picking around the corner of the window :slight_smile:

I did a little picking test:


// game loop
int pickx = 320;
int picky = 240;
Vector3f eye = new Vector3f(0, 5, -5);
Vector3f center = new Vector3f();
boolean finished = false;
while (!finished && !Window.isCloseRequested()) {
      // keyboard input; esc-exit arrows-move cursor
      Keyboard.poll();
      finished = Keyboard.isKeyDown(Keyboard.KEY_ESCAPE);
      pickx += (Keyboard.isKeyDown(Keyboard.KEY_LEFT)  ? -5 : 0);
      pickx += (Keyboard.isKeyDown(Keyboard.KEY_RIGHT) ?  5 : 0);
      picky += (Keyboard.isKeyDown(Keyboard.KEY_UP)   ?  5 : 0);
      picky += (Keyboard.isKeyDown(Keyboard.KEY_DOWN) ? -5 : 0);
      
      // clear background
      GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
      
      // Draw a torus
      GL.glMatrixMode(GL.GL_PROJECTION);        
      GL.glLoadIdentity();
      float aspect = (float) Display.getWidth() / (float) Display.getHeight();
      GLU.gluPerspective(45.0f, aspect, 0.1f, 1000.0f);
      GL.glMatrixMode(GL.GL_MODELVIEW);
      GL.glLoadIdentity();
      GLU.gluLookAt(eye.x, eye.y, eye.z, center.x, center.y, center.z, 0, 1, 0);
      GL.glRotatef(rotateAngle, 0, 1, 0);
      renderTorus();

      // picking. same projection setup as drawing, except gluPickMatrix
      GL.glPushMatrix();
      GL.glMatrixMode(GL.GL_PROJECTION);
      GL.glLoadIdentity();
      // restrict pick area to around the cursor
      GLU.gluPickMatrix(pickx-2, picky-2, 4.0, 4.0, viewBuf);      
      GLU.gluPerspective(45.0f, aspect, 0.1f, 1000.0f);
      GL.glMatrixMode(GL.GL_MODELVIEW);
      // same modelview setup as drawing
      GL.glLoadIdentity();
      GLU.gluLookAt(eye.x, eye.y, eye.z, center.x, center.y, center.z, 0, 1, 0);
      GL.glRotatef(rotateAngle, 0, 1, 0);
      final int BUF_SIZE = 16;
      IntBuffer selectBuf = ByteBuffer.allocateDirect(4*BUF_SIZE).order(ByteOrder.nativeOrder()).asIntBuffer(); 
      GL.glSelectBuffer(selectBuf);
      GL.glRenderMode(GL.GL_SELECT);
      GL.glInitNames();
      GL.glPushName(-1);
      GL.glLoadName(13);
      renderTorus();
      GL.glPopMatrix();
      GL.glFlush();
      int hits = GL.glRenderMode(GL.GL_RENDER);
      processHits(hits, selectBuf);

      // Draw mouse cursor
      GL.glDisable(GL.GL_TEXTURE_2D);
      GL.glMatrixMode(GL.GL_PROJECTION);
      GL.glLoadIdentity();
      GLU.gluOrtho2D(0, viewWidth, viewHeight, 0);
      GL.glMatrixMode(GL.GL_MODELVIEW);
      GL.glLoadIdentity();
      GL.glBegin(GL.GL_QUADS);
      GL.glColor3f(1,1,1);
      GL.glVertex2f(pickx-2, viewHeight-picky-2);
      GL.glVertex2f(pickx+2, viewHeight-picky-2);
      GL.glVertex2f(pickx+2, viewHeight-picky+2);
      GL.glVertex2f(pickx-2, viewHeight-picky+2);
      GL.glEnd();

      Window.update();
      Window.paint();
      Thread.yield();
      
      rotateAngle += (float)Math.PI/5;      // animation
}

A Torus is rendered. The cursor is controlled by the keyboard. If the cursor intersects the torus the hits are printed.

Thanks I’ll let you know in a few days when I digested and tested the info I just got :slight_smile:

Well I tried rendering my code (eg outcommenting GL_SELECT, it seems like I do zoom in, or rather I enlarge, cause suddenly the coord system seems Bigger. To move left and right i must go 10K left. So I must have done something to translate that.

So where should I look for a solution to my problem?

Sounds like you are doing it right. If you try to render your select code you should only see the area that you specified in gluPickMatrix(…). Of course it will be zoomed in and rendered in the whole view port. In selection mode, nothing is actually rendered. Polygons is only clipped to the frustum to find out what is visible.

[quote]To move left and right i must go 10K left. So I must have done something to translate that.
[/quote]
Can you explain a little more. I don’t understand. Can you also explain a little more about you problem. Sounds like it’s working.

sorry it wasent clear.

It do not zoom in on other objects on my screen, only the center one, when I feed it with screen coords. To hit a object away from teh center one I have to multiply my screen cords witha HUGE constant.

So I am thinking, I am doing something wrong, either with the screen cords or with the zooming.

Ok, I understand now.

Lets first find where the problem is.

  1. Try uncommenting “GLU.gluPickMatrix(…)”. The scene rendered should look exactly like the one you use for GL_RENDER. If not, make the necessary changes so that it do.

  2. Make sure that you call GLU.gluPickMatrix() just before GLU.gluPerspective().

  3. Make sure your viewPort IntBuffer contains the rigth values, and that the buffer is rewinded. Do this by printing the content of the buffer right before calling GLU.gluPickMatrix(), like this:


viewBuf.rewind(); // make sure int buffer is rewinded
System.out.println("viewPort="+viewBuf.get(0)+" "+viewBuf.get(1)+" "+viewBuf.get(2)+" "+viewBuf.get(3));
GLU.gluPickMatrix(mousex, mousey, cursorSize, cursorSize, viewBuf);
GLU.gluPerspective(45.0f, aspect, 0.1f, 1000.0f);

  1. Experiment with some hardcoded paremeters to GLU.gluPickMatrix(). Here are some examples, assuming the following viewport bounds: (0, 0, width, height)

GLU.gluPickMatrix(width/2, height/2, width, height, viewBuf);      // Does no change. Scene is rendered as this line was commented out.
GLU.gluPickMatrix(width*3/4, height/2, width/2, height, viewBuf); // The right hand side of original scene is rendered
GLU.gluPickMatrix(width/4, height/4, width/2, height/2, viewBuf); // A corner of the original scene is rendered

Hope this helps!

Hey Tom

  1. I did that already, I may be a daftv newbie but nor THAT daft :slight_smile:

2.DOUGH!.. THAT HELPED A BIT!!!

3.yep yep its correct

  1. YES IT WORKS WEEEHAAAA
    This is what worked… I must find out why my mouse is distorted

Thankyou very much Tom if you are ever around in Denmark i’ll buy you a BIG beer.

Yep it did work :slight_smile:

http://www.extorris.com/screenshots/selectionPlanet.png

Nice ;D