OpenGL gluUnProject and gluLookAt trying to understand dependence of each other

I am using gluUnProject function from OpenGL to transform mouse 2D coordinates to world space 3D coordinates , by doing this i am retrieving a ray start and end points accordingly to the near and far plane which configured in the glFrustumf inside onSurfaceChanged function .

I created 3d world space with surface size 20*20 and painted the x,y,z axis :

[ATTACH=CONFIG]1228[/ATTACH]

I am using to move the camera with gluLookAt function , When the camera Eye is set to x=0,y=0,z=98 and look at x=0,y=0,z=0 whice is the far plane (gl.glFrustumf(-ratio, ratio, -1, 1, 1f, 100)) I am getting right 3D world space coordinates from mouse .

[ATTACH=CONFIG]1229[/ATTACH]

Unfortunately whenever i move the camera to other position whice cuz camera rotatation The coordinates i am getting are wrong. I understand that i have to do some mathematic calculation to normalize the coordinates to 3D world space depending on the camera position, But how please help?

The ray class :


import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLU;
import android.opengl.Matrix;

public class Ray {

float[] P0;
float[] P1;

public Ray(GL10 gl, int width, int height, float xTouch, float yTouch) {
    MatrixGrabber matrixGrabber = new MatrixGrabber();
    matrixGrabber.getCurrentState(gl);

    int[] viewport = {0, 0, width, height};

    float[] nearCoOrds = new float[3];
    float[] farCoOrds = new float[3];
    float[] temp = new float[4];
    float[] temp2 = new float[4];
    // get the near and far ords for the click

    float winx = xTouch, winy =(float)viewport[3] - yTouch;

    int result = GLU.gluUnProject(winx, winy, 1.0f, matrixGrabber.mModelView, 0, matrixGrabber.mProjection, 0, viewport, 0, temp, 0);        Matrix.multiplyMV(temp2, 0, matrixGrabber.mModelView, 0, temp, 0);
    if(result == GL10.GL_TRUE){
        nearCoOrds[0] = temp2[0] / temp2[3];
        nearCoOrds[1] = temp2[1] / temp2[3];
        nearCoOrds[2] = temp2[2] / temp2[3];
    }

    result = GLU.gluUnProject(winx, winy, 0, matrixGrabber.mModelView, 0, matrixGrabber.mProjection, 0, viewport, 0, temp, 0);
    Matrix.multiplyMV(temp2,0,matrixGrabber.mModelView, 0, temp, 0);
    if(result == GL10.GL_TRUE){
        farCoOrds[0] = temp2[0] / temp2[3];
        farCoOrds[1] = temp2[1] / temp2[3];
        farCoOrds[2] = temp2[2] / temp2[3];
    }
    this.P0 = farCoOrds;
    this.P1 = nearCoOrds;
}   
}

The Render class :


  import java.util.Arrays;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLU;
import android.opengl.GLSurfaceView.Renderer;

public class ExampleGLRenderer implements Renderer {

    private float ratio;
    private int width;
    private int height;
    private int prevPressX = -999;
    private int prevPressY = -999;

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glShadeModel(GL10.GL_SMOOTH);
        gl.glClearDepthf(1.0f);
        gl.glEnable(GL10.GL_DEPTH_TEST);
        gl.glDepthRangef(0,1);
        gl.glDepthFunc(GL10.GL_LEQUAL);
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
        gl.glDisable(GL10.GL_DITHER);      // Disable dithering for better performance
    }

    public void onDrawFrame(GL10 gl) {

        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);        
        gl.glLoadIdentity();
        gl.glMatrixMode(GL10.GL_MODELVIEW);

        double camHight=98f;
        double camX=0.1f;
        double camZ=0;
        GLU.gluLookAt(gl, (float)camX,(float)camHight,(float)camZ, 0, 0, 0, 0, 1, 0);

        Ray ray = null;
        if (prevPressX != -999) {
            ray = new Ray(gl, width, height, prevPressX, prevPressY);
            System.out.println(Arrays.toString(ray.P1));
        }

        paintXYZ(gl);
        paintSurface(gl,null);

        prevPressX = -999;

    }

    public void onSurfaceChanged(GL10 gl, int width, int height) {

        gl.glViewport(0, 0, width, height);
        if (height == 0) height = 1;   // To prevent divide by zero

        this.width = width;
        this.height = height;

        ratio = (float)width / height;

        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();

        gl.glFrustumf(-ratio, ratio, -1, 1, 1f, 100);

        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
    }   

public void paintSurface(GL10 gl,Ray ray){

        //Surface
          gl.glPushMatrix();
          gl.glRotatef(90f, 1, 0, 0);
          Mesh floor = new Mesh();
          floor.setColor("gray");
          floor.setSize(20);
          floor.setup();
          floor.draw(gl,ray);                                
          gl.glPopMatrix();

        Line line;
          for(int i=-20; i<20; i++){
              line = new Line();         
              if(i!=0){
              line.setLineCord(-20f,0,i, 20f,0.0f,i);
              line.setColor("black");
              line.setup();
              line.draw(gl);
              }
          }

          for(int i=-20; i<20; i++){
              if(i!=0){
              line = new Line();         
              line.setLineCord(i, 0, -20f, i, 0.0f, 20f);
              line.setColor("black");
              line.setup();
              line.draw(gl);
              }
           }
    }
    public void paintXYZ(GL10 gl){      
         // paint x axis
          Line linex = new Line();         
          linex.setLineCord(-20f,0.0f,-0.0f,20f,0.0f,-0.0f);
          linex.setColor("yellow");
          linex.setup();
          linex.draw(gl);       


          // paint y axis
          Line lineY = new Line();         
          lineY.setLineCord(0.0f, -20f, -0.0f, 0.0f, 20f, -0.0f);
          lineY.setColor("red");
          lineY.setup();
          lineY.draw(gl);    

       // paint Z axis
          Line lineZ = new Line();         
          lineZ.setLineCord(0.0f, 0, -20f, 0.0f, 0.0f, 20f);
          lineZ.setColor("green");
          lineZ.setup();
          lineZ.draw(gl);

    }
    public void onPress(int x, int y) {
        prevPressX=x;
        prevPressY=y;
    }
}

This shouldn’t be here. It’s transforming the un-projected coordinates from world space to eye space.

If you want eye-space coordinates, pass an identity matrix to gluUnProject() in place of the model-view matrix.

Thanks for answere , can you please be more speciefic ? i need to transform screen space (mouse position) coordinates to camera/view coordinates system and then to my world space coordinates system . as i understand right now the ray i have is in camera/view space coordinates with depth of far/near plane and my problem is to find out where this ray intersect surface in world coordinates accordenly to mouse position and camera position ?

Thanks i finaly solved it !!!

GLU.gluUnProject(winx, winy, 0, matrixGrabber.mModelView, 0, matrixGrabber.mProjection, 0, viewport, 0, temp2, 0);
//Matrix.multiplyMV(temp2, 0, matrixGrabber.mModelView, 0, temp, 0); // if we need the coordinatws in camera world coordinates system

now i know where exactly ray intersect with my surface ^^