OpenGL MFC单文档 实现轨迹球
前言:我是一个怀揣着伟大梦想的普通男生!结果就是,一有时间就幻想着自己的伟大梦想,忘了自己下一步该迈出左脚还是右脚。这不,只顾做梦了,时光可不管我,独自一个人走远了。
建议:目标,计划,实施。我认为的三大步骤!好比今天学习MFC单文档下的轨迹球实现,首先拿起纸,Write:
目标:实现轨迹球
计划:1.学习MFC鼠标和键盘事件
2.学习二维的鼠标点映射到三维的轨迹球映射关系
3.结合
实施:不能只想不做,Begin
1.MFC单文档鼠标响应
通过MFC 类向导,添加鼠标的消息响应,如下图:
关于每个消息,我就不解释了,大家可以问问度娘。
1.首先在类的头文件中添加成员变量:
2.再在构造函数中初始化:
CPoint m_mousePoint; //记录鼠标信息
GLfloat m_xAngle,m_yAngle; //控制旋转
GLfloat m_Scale; //用于缩放
GLfloat m_xPos;
GLfloat m_yPos;
m_xAngle = 0.0f;
m_yAngle = 0.0f;
m_Scale = 1.f;
m_xPos = 0.0f;
m_yPos = 0.0f;
3.编辑消息响应
鼠标左键按下:
void CStepinGLView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
m_mousePoint = point;
SetCapture(); //设置鼠标按下捕获
CView::OnLButtonDown(nFlags, point);
}
鼠标左键释放:
void CStepinGLView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
m_mousePoint = point;
ReleaseCapture();
CView::OnLButtonUp(nFlags, point);
}
鼠标移动:
void CStepinGLView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (GetCapture() == this)
{
m_xAngle+=(point.y-m_mousePoint.y)/3.6;
m_yAngle+=(point.x-m_mousePoint.x)/3.6;
InvalidateRect(NULL,FALSE);
//Set the mouse point
m_mousePoint = point;
}
CView::OnMouseMove(nFlags, point);
}
鼠标中间滑轮:
BOOL CStepinGLView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
m_Scale += 0.1 *zDelta /120;
InvalidateRect(NULL,FALSE);
return CView::OnMouseWheel(nFlags, zDelta, pt);
}
4.点击编译,运行,是不是可以实现鼠标控制了?!
2.键盘响应
因为我们已近添加过键盘的消息响应,只需编辑即可:
void CStepinGLView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
switch (nChar)
{
case VK_UP: m_yPos = m_yPos + 0.1f;
break;
case VK_DOWN: m_yPos = m_yPos - 0.1f;
break;
case VK_LEFT: m_xPos = m_xPos - 0.1f;
break;
case VK_RIGHT: m_xPos = m_xPos + 0.1f;
break;
default: MessageBox(L"请按 ↑ ↓ ← → 键!");
break;
}
Invalidate(FALSE);
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
3.附上我修改后程序:
void CStepinGLView::DrawScene(void)
{
//移动物体到显示区
glTranslatef(0.f,0.f,-7.0f);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
//视角变换
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0,3.0,7.0, 0.0,0.0,0.0, 0.0,1.0,0.0);/*前三个参数是眼睛的位置,中间三个参数是物体所在的位置,后面三个参数表示向量,头顶朝上的方向*/
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glPushMatrix();
LightM();
glPopMatrix();
glPushMatrix();
glColor3f(0.5f, 0.25f, 0.0f);
glTranslatef(m_xPos,m_yPos,0.0f);
glRotatef(rtri,0.0f,0.1f,0.0f); //旋转
glRotatef(m_xAngle, 1.0f,0.0f,0.0f);
glRotatef(m_yAngle, 0.0f,1.0f,0.0f);
glScalef(m_Scale,m_Scale,m_Scale); //缩放
glutSolidTeapot(0.5f);
glPopMatrix();
glPushMatrix();
glRotated(-65,1.0,0.0,0.0);
DrawWater();
glPopMatrix();
glDisable(GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL);
}
4.编译完成,运行程序:
后记:大家运行程序时,可能会出现界面不显示问题,那就好好看看你程序使用的是透视投影还是平行投影,最后再检查一下你的glTranslatef()函数,看看是否把图形移动到视区内。