retrieving mouse 3d coordinates

Hi, i have a simple terrain engine built on a 1024x1024 triangle strip. I’d like, when i move the mouse on a vertex, to get the x,y,z coordinates. So i coded the following mousemove routine:

xPos = LOWORD(lParam); // horizontal position of cursor
yPos = HIWORD(lParam); // vertical position of cursor
glGetIntegerv (GL_VIEWPORT, viewport);
glGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix);
glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);
realy = viewport[3] - (GLint) yPos - 1;
glReadPixels(xPos,viewport[3]-yPos-19,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,(void *)pixel_depth_cp);
gluUnProject ((GLdouble) xPos, (GLdouble) realy, pixel_depth_cp[0], mvmatrix, projmatrix, viewport, &wx, &wy, &wz);

Is this code correct ? I.e. wx, wy, wz really hold the vertex coordinates ? If i want to draw a simple 3d point exactly where i click the mouse, do i have to glTranslatef to wx,wy,wz. I’m trying to say that i’d like to draw a point on the vertex where the mouse currently on.

My turn to help with this subject…I just went through it myself .

You need to call glUnProject after your camera transformation and after you draw the terrain. The resulting point is the position in world space which is where you’re terrain is…well I’m assuming that’s where it’s at.

To clearly answer your last question, you would have to draw the resulting point wx, wy and wz using the same matrix state as your terrain.

thx for help but i dont understand: shall i call glunproject in the main draw routine and not every time i move the mouse ?

Yep. For example:

void main()
{
…a bunch of game code…

PushCameraMatrix();

DrawYourTerrain();

//Do your UnProject thing here

PopCameraMatrix();
}

Just store the x and y position of the mouse globaly so you can use them to call glUnProject between your camera matrix calls.

[This message has been edited by WhatEver (edited 01-28-2003).]

Here’s what I came up with a few days ago. I just call this after I push the camera matrix:

[source]
/*
This function takes a pixel from the framebuffer and transforms it into world space.
*/

S3Dvoid s3d_camera::ScreenToWorld(S3Ddouble xin, S3Ddouble yin, S3Dfloat* xout, S3Dfloat* yout, S3Dfloat* zout)
{
S3Dmat16d Projection, Modelview;
S3Dint ViewPort[4];
S3Ddouble dxout, dyout, dzout;
S3Dfloat fz;

glGetIntegerv(GL_VIEWPORT, ViewPort);
glGetDoublev(GL_PROJECTION_MATRIX, Projection);
glGetDoublev(GL_MODELVIEW_MATRIX, Modelview);

yin=ViewPort[3]-yin;

glReadPixels((S3Dint)xin, (S3Dint)yin, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &fz);

gluUnProject(xin, yin, (S3Ddouble)fz, Modelview, Projection, ViewPort, &dxout, &dyout, &dzout);

*xout=(S3Dfloat)dxout;
*yout=(S3Dfloat)dyout;
*zout=(S3Dfloat)dzout;

}
[/source]