OpenGL如何使用gluUnProject函数得到线解集?
浏览:432672 回答:2
我才接触OpenGL编程没多久,我想得到鼠标点击窗口后对应2D点的3D射线,大家都说用gluUnProjectint函数,但是没有如何使用的例子,MSDN上也只是简单的参数说明,也没有例子,望哪位知晓的讲解一下,万分感谢
原型:
gluUnProject(
GLdouble winx,
GLdouble winy,
GLdouble winz, // 这个Z不知道做什么用的,2D窗口坐标的Z坐标?
const GLdouble modelMatrix[16],
const GLdouble projMatrix[16],
const GLint viewport[4],
GLdouble *objx,
GLdouble *objy,
GLdouble *objz
);
出来后得到了objx,objy,objz,其中objz好象是近剪裁的大小,而这三个值是视点坐标系里的,问题是:
1、如何转换到世界坐标系呢?
2、只有一个点怎么确定一条线呀?
---------------------------------------------------------------
// 获取光标位置的模型坐标。 2002.11.18.
CVector3 WINAPI GetMouseModelCoordinate(CVRRoomView* pView, CPoint point)
{
GLfloat fdepth;
GLdouble ObjectX, ObjectY, ObjectZ;
GLint iViewPort[4];
GLdouble dProjMatrix[16];
GLdouble dModelMatrix[16];
POINT iScreen;
int iScrToWinX, iScrToWinY;
long iError;
CVector3 pp;
CClientDC ClientDC(pView);
wglMakeCurrent(ClientDC.m_hDC, pView->m_hGLContext); //使 RC 与当前 DC 相关联
glGetIntegerv(GL_VIEWPORT, iViewPort);
glPushMatrix();
glGetDoublev(GL_MODELVIEW_MATRIX, dModelMatrix);
glGetDoublev(GL_PROJECTION_MATRIX, dProjMatrix);
::GetCursorPos(&iScreen);
iScrToWinX = iScreen.x-point.x;
iScrToWinY = iScreen.y-point.y;
glReadPixels(point.x, iViewPort[3]-point.y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &fdepth);
gluUnProject((GLdouble)point.x, (GLdouble)(iViewPort[3]-point.y), (GLdouble)fdepth, dModelMatrix, dProjMatrix, iViewPort, &ObjectX, &ObjectY, &ObjectZ);
if(ObjectX>=pView->m_pDoc->m_dModelMinX&&ObjectX<=pView->m_pDoc->m_dModelMaxX&&
ObjectY>=pView->m_pDoc->m_dModelMinY&&ObjectY<=pView->m_pDoc->m_dModelMaxY&&
ObjectZ>=pView->m_pDoc->m_dModelMinZ&&ObjectZ<=pView->m_pDoc->m_dModelMaxZ)
{
pp.x = ObjectX;
pp.y = ObjectY;
pp.z = ObjectZ;
}
else
{
pp.x = pView->m_pDoc->m_pRoamParameter->dMouseModelX;
pp.y = pView->m_pDoc->m_pRoamParameter->dMouseModelY;
pp.z = pView->m_pDoc->m_pRoamParameter->dMouseModelZ;
}
// pView->m_pDoc->m_pRoamParameter->dMouseModelX = (double)ObjectX;
// pView->m_pDoc->m_pRoamParameter->dMouseModelX = (double)ObjectY;
// pView->m_pDoc->m_pRoamParameter->dMouseModelX = (double)ObjectZ;
glPopMatrix();
iError = glGetError();
if(iError!=GL_NO_ERROR)
{
// Errinfo = gluErrorString(iResultCode);
::MessageBox(NULL, (LPCTSTR)gluErrorString(iError), "提示13:", MB_OK);
}
wglMakeCurrent(ClientDC.m_hDC, NULL);//释放 RC,以便其它 DC 进行绘图
return pp;
}
原型:
gluUnProject(
GLdouble winx,
GLdouble winy,
GLdouble winz, // 这个Z不知道做什么用的,2D窗口坐标的Z坐标?
const GLdouble modelMatrix[16],
const GLdouble projMatrix[16],
const GLint viewport[4],
GLdouble *objx,
GLdouble *objy,
GLdouble *objz
);
出来后得到了objx,objy,objz,其中objz好象是近剪裁的大小,而这三个值是视点坐标系里的,问题是:
1、如何转换到世界坐标系呢?
2、只有一个点怎么确定一条线呀?
---------------------------------------------------------------
// 获取光标位置的模型坐标。 2002.11.18.
CVector3 WINAPI GetMouseModelCoordinate(CVRRoomView* pView, CPoint point)
{
GLfloat fdepth;
GLdouble ObjectX, ObjectY, ObjectZ;
GLint iViewPort[4];
GLdouble dProjMatrix[16];
GLdouble dModelMatrix[16];
POINT iScreen;
int iScrToWinX, iScrToWinY;
long iError;
CVector3 pp;
CClientDC ClientDC(pView);
wglMakeCurrent(ClientDC.m_hDC, pView->m_hGLContext); //使 RC 与当前 DC 相关联
glGetIntegerv(GL_VIEWPORT, iViewPort);
glPushMatrix();
glGetDoublev(GL_MODELVIEW_MATRIX, dModelMatrix);
glGetDoublev(GL_PROJECTION_MATRIX, dProjMatrix);
::GetCursorPos(&iScreen);
iScrToWinX = iScreen.x-point.x;
iScrToWinY = iScreen.y-point.y;
glReadPixels(point.x, iViewPort[3]-point.y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &fdepth);
gluUnProject((GLdouble)point.x, (GLdouble)(iViewPort[3]-point.y), (GLdouble)fdepth, dModelMatrix, dProjMatrix, iViewPort, &ObjectX, &ObjectY, &ObjectZ);
if(ObjectX>=pView->m_pDoc->m_dModelMinX&&ObjectX<=pView->m_pDoc->m_dModelMaxX&&
ObjectY>=pView->m_pDoc->m_dModelMinY&&ObjectY<=pView->m_pDoc->m_dModelMaxY&&
ObjectZ>=pView->m_pDoc->m_dModelMinZ&&ObjectZ<=pView->m_pDoc->m_dModelMaxZ)
{
pp.x = ObjectX;
pp.y = ObjectY;
pp.z = ObjectZ;
}
else
{
pp.x = pView->m_pDoc->m_pRoamParameter->dMouseModelX;
pp.y = pView->m_pDoc->m_pRoamParameter->dMouseModelY;
pp.z = pView->m_pDoc->m_pRoamParameter->dMouseModelZ;
}
// pView->m_pDoc->m_pRoamParameter->dMouseModelX = (double)ObjectX;
// pView->m_pDoc->m_pRoamParameter->dMouseModelX = (double)ObjectY;
// pView->m_pDoc->m_pRoamParameter->dMouseModelX = (double)ObjectZ;
glPopMatrix();
iError = glGetError();
if(iError!=GL_NO_ERROR)
{
// Errinfo = gluErrorString(iResultCode);
::MessageBox(NULL, (LPCTSTR)gluErrorString(iError), "提示13:", MB_OK);
}
wglMakeCurrent(ClientDC.m_hDC, NULL);//释放 RC,以便其它 DC 进行绘图
return pp;
}
iScrToWinX = iScreen.x-point.x;
iScrToWinY = iScreen.y-point.y;
这三句怎么没有见到你在程序中用上呀:
if(ObjectX>=pView->m_pDoc->m_dModelMinX&&ObjectX<=pView->m_pDoc->m_dModelMaxX&&
ObjectY>=pView->m_pDoc->m_dModelMinY&&ObjectY<=pView->m_pDoc->m_dModelMaxY&&
ObjectZ>=pView->m_pDoc->m_dModelMinZ&&ObjectZ<=pView->m_pDoc->m_dModelMaxZ)
{
pp.x = ObjectX;
pp.y = ObjectY;
pp.z = ObjectZ;
}
else
{
pp.x = pView->m_pDoc->m_pRoamParameter->dMouseModelX;
pp.y = pView->m_pDoc->m_pRoamParameter->dMouseModelY;
pp.z = pView->m_pDoc->m_pRoamParameter->dMouseModelZ;
}
这个ifelse语句说明意思?