https://github.com/zytc2009/BigTeam_learning
分类: C/C++
2012-07-10 15:10:59
在opengl下从鼠标坐标转换到三维坐标的方法
转载 http://general.blog.51cto.com/927298/562641
一般用来拾取物体:
fPoint CMy3D_SurfaceView::Get_3D_pos(CPoint Tpoint)
{
CMy3D_SurfaceDoc *pDoc=(CMy3D_SurfaceDoc*)GetDocument();
fPoint Rp;
GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
GLfloat winX,winY,winZ;
GLdouble posX,posY,posZ;
glPushMatrix();
glTranslatef(TransVect[0],TransVect[1],TransVect[2]);
if(pDoc->Init)roty=0.0f;
glRotatef(roty+20.0f,0.0f,1.0f,0.0f);
glScalef(scalx,scaly,scalz);
glGetIntegerv(GL_VIEWPORT,viewport);
glGetDoublev(GL_MODELVIEW_MATRIX,modelview);
glGetDoublev(GL_PROJECTION_MATRIX,projection);
glPopMatrix();
winX=(float)Tpoint.x;
winY=viewport[3]-(float)Tpoint.y;
glReadPixels((int)winX,(int)winY,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,&winZ);//获取鼠标屏幕坐标处像素的深度Z
gluUnProject(winX,winY,winZ,modelview,projection,viewport,&posX,&posY,&posZ);
Rp.x=posX;
Rp.y=posY;
Rp.z=posZ;
return Rp;
}
遇到需要将3D坐标转换到屏幕坐标的问题,在网上很多朋友也在寻找答案,下面是glu中gluProject函数的实现。
矩阵按行优先存储
GLint gluProject(GLdouble objx, GLdouble objy, GLdouble objz,
const GLdouble model[16], const GLdouble proj[16],
const GLint viewport[4],
GLdouble * winx, GLdouble * winy, GLdouble * winz)
{
GLdouble in[4], out[4];
in[0] = objx;
in[1] = objy;
in[2] = objz;
in[3] = 1.0;
transform_point(out, model, in);
transform_point(in, proj, out);
if (in[3] == 0.0)
return GL_FALSE;
in[0] /= in[3];
in[1] /= in[3];
in[2] /= in[3];
*winx = viewport[0] + (1 + in[0]) * viewport[2] / 2;
*winy = viewport[1] + (1 + in[1]) * viewport[3] / 2;
*winz = (1 + in[2]) / 2;
return GL_TRUE;
}
static void
transform_point(GLdouble out[4], const GLdouble m[16], const GLdouble in[4])
{
#define M(row,col) m[col*4+row]
out[0] =
M(0, 0) * in[0] + M(0, 1) * in[1] + M(0, 2) * in[2] + M(0, 3) * in[3];
out[1] =
M(1, 0) * in[0] + M(1, 1) * in[1] + M(1, 2) * in[2] + M(1, 3) * in[3];
out[2] =
M(2, 0) * in[0] + M(2, 1) * in[1] + M(2, 2) * in[2] + M(2, 3) * in[3];
out[3] =
M(3, 0) * in[0] + M(3, 1) * in[1] + M(3, 2) * in[2] + M(3, 3) * in[3];
#undef M
}
----------------------------------------------------------------------------------------
GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
GLfloat winX,winY,winZ;
GLdouble posX,posY,posZ;
glPushMatrix();
glTranslatef(TransVect[0],TransVect[1],TransVect[2]);
if(pDoc->Init)roty=0.0f;
glRotatef(roty+20.0f,0.0f,1.0f,0.0f);
glScalef(scalx,scaly,scalz);
glGetIntegerv(GL_VIEWPORT,viewport);
glGetDoublev(GL_MODELVIEW_MATRIX,modelview);
glGetDoublev(GL_PROJECTION_MATRIX,projection);
glPopMatrix();