I saw a lot of picking code opengl-es, but nothing worked. Can someone give me what am I missing?

My code is (from tutorials/forums)

Vec3 far  = Camera.getPosition();
Vec3 near = Shared.opengl().getPickingRay(ev.getX(), ev.getY(), 0);

Vec3 direction = far.sub(near);

Log.e("direction", direction.x+" "+direction.y+" "+direction.z);

Ray mouseRay = new Ray(near, direction);

for (int n=0; n<ObjectFactory.objects.size(); n++) {
    if (ObjectFactory.objects.get(n)!=null) {
        IObject obj = ObjectFactory.objects.get(n);

         float discriminant, b;
         float radius=0.1f;

         b = -mouseRay.getOrigin().dot(mouseRay.getDirection());
         discriminant = b * b - mouseRay.getOrigin().dot(mouseRay.getOrigin()) + radius*radius;

         discriminant = FloatMath.sqrt(discriminant);

         double x1 = b - discriminant;
         double x2 = b + discriminant;

         Log.e("asd", obj.getName() + " "+discriminant+"   "+x1+" "+x2);

my camera vectors:

Vec3 position   =new Vec3(-obj.getPosX()+x, obj.getPosZ()-0.3f, obj.getPosY()+z);
Vec3 direction  =new Vec3(-obj.getPosX(),   obj.getPosZ(), obj.getPosY());
Vec3 up         =new Vec3(0.0f, -1.0f, 0.0f);
Camera.set(position, direction, up);

and my picking code:

public Vec3 getPickingRay(float mouseX, float mouseY, float mouseZ) {

    int[] viewport      = getViewport();
    float[] modelview   = getModelView();
    float[] projection  = getProjection();

    float winX, winY;
    float[] position    = new float[4];

    winX = (float)mouseX;
    winY = (float)Shared.screen.width - (float)mouseY;

    GLU.gluUnProject(winX, winY, mouseZ, modelview, 0, projection, 0, viewport, 0, position, 0);

    return new Vec3(position[0], position[1], position[2]);

My camera moving all the time in 3d space. and my actors/modells moving too. my camera is following one actor/modell and the user can move the camera on a circle on this model.

How can I change the above code to working?

  • 1
    \$\begingroup\$ You'll have to try and explain exactly what is going wrong. \$\endgroup\$
    – House
    Jan 4, 2012 at 19:41
  • \$\begingroup\$ As Sean said in a comment below, I would say abandon this approach and use ray-polygon intersections instead. \$\endgroup\$
    – bobobobo
    Mar 8, 2013 at 13:13
  • \$\begingroup\$ Here's an excellent tutorial that helped me extract the picking ray: antongerdelan.net/opengl/raycasting.html The above approach is even better than the commonly used one. \$\endgroup\$
    – Tara
    Sep 13, 2013 at 7:55

1 Answer 1


There is a much easier way of picking which requires much less processing power. You simply give each model a specific color, render it without updating the screen, check if the mouse cursor is hovering over the color in question by calling glReadPixels (use PBOs if you want more performance), and then clear the screen and render normally. The non-pickable objects should be black.

  • 9
    \$\begingroup\$ While this is a technique that works, it's gone out of style in a big way. It eats into the GPU fillrate budget. It can also potentially stall the GPU while you wait for the read pixel to be returned, depending on implementation, driver, and hardware. \$\endgroup\$ Aug 9, 2012 at 21:31
  • \$\begingroup\$ Thanks for comment. Could you tell us what the most modern way of doing picking is? \$\endgroup\$
    – Oskar
    Aug 10, 2012 at 5:59
  • 10
    \$\begingroup\$ Plain ol' ray testing. \$\endgroup\$ Aug 10, 2012 at 15:15
  • 3
    \$\begingroup\$ Color picking is much easier, you can even do per-polygon picking by first picking the object then re-rendering it in the background while giving each polygon a unique colour, based on it's index (which is a feature in newer OpenGL's, otherwise do it manually with an extra attribute). This would be useful for a 3D editor for example). The only downside is it's possible that a platform is set to 'force' anti-aliasing even if you disable it in which case you can get broken results on edges, you could detect this and popup a warning though \$\endgroup\$ Nov 7, 2012 at 22:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .