I've spent more time than I should trying to get my ray picking program working. I'm pretty convinced my math is solid with respect to line plane intersection, but I believe the problem lies with the changing of the mouse screen touch into 3D world space.

Heres my code:

    public void passTouchEvents(MotionEvent e){

        int[] viewport = {0,0,viewportWidth,viewportHeight};
        float x = e.getX(), y = viewportHeight - e.getY();

        float[] pos1 = new float[4];
        float[] pos2 = new float[4];
        GLU.gluUnProject(   x, y, 0.0f,
                            mViewMatrix, 0,
                            mProjectionMatrix, 0,
                            viewport, 0,
                            pos1, 0);

        GLU.gluUnProject(   x, y, 1.0f,
                            mViewMatrix, 0,
                            mProjectionMatrix, 0,
                            viewport, 0,
                            pos2, 0);

Just as a reference I've tried transforming the coordinates 0,0,0 and got an offset. It would be appreciated if you would answer using OpenGL ES 2.0 code.

  • 1
    \$\begingroup\$ Since GLU isn't part of OpenGLES, is this GLU implementation a port? Is gluUnProject implemented in it? \$\endgroup\$
    – kaoD
    Commented Mar 28, 2012 at 2:33
  • \$\begingroup\$ i'm using the android GLU library and what evers in that. You'll have to forgive my ignorance I'm still new to opengl on android. \$\endgroup\$
    – secheung
    Commented Mar 28, 2012 at 3:26
  • 2
    \$\begingroup\$ You don't mention what the problem is... \$\endgroup\$
    – House
    Commented Mar 28, 2012 at 20:59
  • \$\begingroup\$ Sorry about that. My problem is the converted coordinates don't seem to be "unprojecting" the coordinates into world space. Is there anything wrong with my code or is there something i'm not getting? \$\endgroup\$
    – secheung
    Commented Mar 28, 2012 at 23:38
  • \$\begingroup\$ The code looks about right... I suspect the matrices are off. Are you using the MODELVIEW_MATRIX for mViewMatrix? Here is a working piece of code using JOGL if it helps: pastebin.com/8a3mKkAq \$\endgroup\$
    – Danik
    Commented May 23, 2012 at 19:29

1 Answer 1


The GLU library was made with 1.1, but the gluUnProject can still be used in 2.0 as long as you have the correct values. The 4th parameter should be the multiplied model view matrix, not just the model matrix or just the view matrix. Also, the calculated pos1 and pos2 values have to be converted from 4D vectors to 3D vectors by dividing them by their w component. According to this: http://forums.create.msdn.com/forums/p/10940/70238.aspx.
Here's how I did it for Android:

public void singleTouch(float x, float y)
    float[] nearPos = new float[4];
    float[] farPos = new float[4];
    PointF touchPoint;

    boolean unprojectedNear = (GLU.gluUnProject(x, y, 0,
        floorViewDrawable.getMvMatrix(), 0, projectionMatrix, 0,
        viewport, 0, nearPos, 0) == GLES10.GL_TRUE);
    boolean unprojectedFar = (GLU.gluUnProject(x, y, 1,
        floorViewDrawable.getMvMatrix(), 0, projectionMatrix, 0,
        viewport, 0, farPos, 0) == GLES10.GL_TRUE);

    if (unprojectedNear && unprojectedFar)
        // To convert the transformed 4D vector to 3D, you must divide
        // it by the W component
        nearPos = convertTo3d(nearPos);
        farPos = convertTo3d(farPos);

        // Use the near and far instead of the assumed camera position
        float floorViewX = (((farPos[0] - nearPos[0]) / (perspectiveFar - perspectiveNear)) * nearPos[2]) + nearPos[0];
        float floorViewY = ((((farPos[1] - nearPos[1]) / (perspectiveFar - perspectiveNear)) * nearPos[2])  + nearPos[1]) + (2f * positionY);

        touchPoint = new PointF(floorViewX, floorViewY);

        if (floorViewDrawable.getArea()
            .contains(touchPoint.x, touchPoint.y))
            floorViewPoint = new PointF(nearPos[0], nearPos[1]);
            Log.e(HostessMobileApp.TAG, "floorViewTouched");

private float[] convertTo3d(float[] vector) {
    float[] result = new float[4];

    for (int index = 0; index < vector.length; index++) {
        result[index] = vector[index] / vector[3];

    return result;

Here's a resource for explaining gluUnproject if anybody needs it. http://myweb.lmu.edu/dondi/share/cg/unproject-explained.pdf


You must log in to answer this question.

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