Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 5 of 5

Thread: Get world coordinate

  1. #1
    Junior Member Newbie
    Join Date
    Jul 2009
    Posts
    22

    Angry Get world coordinate

    Hi guys,
    I create my point cloud viewer and now i'm trying to implement mouse points picking. I find a lot of tutorials about this issue but i have some problems.
    i draw on the screen my point cloud by:



    GLsizei vx, vy;
    vx = glutGet( GLUT_WINDOW_WIDTH );
    vy = glutGet( GLUT_WINDOW_HEIGHT );
    double aspect = double(vx)/double(vy);


    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective( 45*zoomFactor, aspect, 1, 100. );


    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
    gluLookAt ( 0, 0, 10., 0., 0., 0., 0., 1., 0. );
    glMultMatrixf(matrix);
    glPointSize(3.0);
    glBegin(GL_POINTS);
    for(int i = 0; i < content->nvertex; i++){
    glVertex3f(content->vertexes[i].x, content->vertexes[i].y, content->vertexes[i].z);
    }
    glEnd();
    glutSwapBuffers();
    glFlush();

    where matrix is a rotation matrix calculate by trackball.
    When I click on the screen I'm able to get (x,y) screen coordinate and then i want get 3D world-coordinate by:

    GLdouble sx, sy, sz; GLdouble ex, ey, ez;


    GLint viewport[4];
    GLdouble modelview[16];
    GLdouble projection[16];


    GLsizei vx, vy;
    vx = glutGet( GLUT_WINDOW_WIDTH );
    vy = glutGet( GLUT_WINDOW_HEIGHT );
    double aspect = double(vx)/double(vy);


    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45*zoomFactor, aspect, 1, 100. );


    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
    gluLookAt ( 0, 0, 10., 0., 0., 0., 0., 1., 0. );


    glMultMatrixf(matrix);
    GLint realy;
    glGetIntegerv(GL_VIEWPORT,viewport);
    glGetDoublev(GL_MODELVIEW_MATRIX,modelview);
    glGetDoublev(GL_PROJECTION_MATRIX,projection);


    realy = viewport[3] - y;//viewport[3] - y;
    gluUnProject( (double) x, realy, 0.0, // Near
    modelview, projection, viewport,
    &sx, &sy, &sz );


    cout << sx << ", " << sy<< ", " << sz<< ", " << endl;
    gluUnProject( (double) x, realy, 1.0f, // Far
    modelview, projection, viewport,
    &ex, &ey, &ez );

    and I pick a point by ray tracing.
    I create a simple example where a set of points (1,0,0) (2,0,0) (3,0,0) (4,0,0) ... (10,0,0) are drawn on the screen but i can pick the point only if i move the mouse between first point and second one. If I rotate this points by trackball i have similar problem. I'm not to be able to find a solution. I search on google for long times but nothing help me to solve this problem.
    Please help me!!

    bye

    G.

  2. #2
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,101
    This is just a personal opinion but when I got serious about picking a point on the screen and needing to know the exact world coordinate I abandoned gluUnProject and created an extra render buffer that records the world coordinate in the fragment shader.
    Now I don't have any trouble (and it is super fast) for the cost of a little graphics memory.

  3. #3
    Junior Member Newbie
    Join Date
    Jul 2009
    Posts
    22
    Quote Originally Posted by tonyo_au View Post
    This is just a personal opinion but when I got serious about picking a point on the screen and needing to know the exact world coordinate I abandoned gluUnProject and created an extra render buffer that records the world coordinate in the fragment shader.
    Now I don't have any trouble (and it is super fast) for the cost of a little graphics memory.
    can you post an example? I have problem to get 3D coordinate from 2D screen coordinate. How can extra buffer solve my problem?

    Cheers

    G.

  4. #4
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,101
    First, so I don't make too many assumptions. Do you know how to create a frame buffer object (FBO) with multi-rendering?

    If you do, then something like this code in the fragment shader will record the world corrdinate to the render buffer. (Please note this is not necessarily
    the most efficient code).

    Code :
      float near = u_NearFar.x;
      float far  = u_NearFar.y;
      float diff = far - near;
      float sum  = far + near;
      float q   = -sum/diff;
      float qn   = -2*near*far/diff;
     
      // convert window to ndc
      vec3  ndc = vec3(gl_FragCoord.xy / u_Screen.xy,gl_FragCoord.z);
      ndc = ndc * 2.0f - 1.0f;
      // convert window Z to clip z
      // NOTE frag.w = 1/w clip
      vec3 clip = ndc / gl_FragCoord.w;   
      // convert clip z to eye z
      float ze    = gl_FragCoord.z / gl_FragCoord.w;
      // convert clip x,y to eye x,y
      vec2 xye = clip.xy / vec2(u_CameraProjection[0].x,u_CameraProjection[1].y);
      // convert from eye space to world
      vec4 worldSpace = u_CameraViewInvert * vec4(xye,-ze,1.0f);
      worldSpace.w = ze;
     Fragout_location = worldSpace;

    The main advantage of recording something in the fragment shader is that the value z is still in 32-bit precision whereas the depth buffer is often 24-bit.
    Just recording the z value in a float texture buffer and doing the screen to world logic in the pick code on the cpu will also work and is probably faster.

  5. #5
    Junior Member Newbie
    Join Date
    Jul 2009
    Posts
    22
    hi tonyo,
    thank you for your help.
    I haven't used FBO yet. I don't understand your code and what the variables represent (e.g.
    u_NearFar, gl_FragCoord,
    u_Screen etc....)!
    can you explaine your code??

    thanks!

    G.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •