在建立好基本的OpenGL编程框架后,可以做一些更复杂的操作,如控制图像运动:移动、旋转、拉伸、加减速、变换、点选等。
相关阅读
1、按键控制图像运行
添加消息如下:ON_WM_KEYDOWN, ON_WM_LBUTTONDOWN,ON_WM_SIZE, ON_TIMER, ON_WM_CREATE, ON_WM_DESTROY。
编写代码如下:
void CGLTestView::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
Invalidate(FALSE);
CView::OnTimer(nIDEvent);
}
void CGLTestView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
xPos = point.x; // horizontal position of cursor
yPos = point.y; // vertical position of cursor
ProcessSelection(xPos, yPos); // 点选
CView::OnLButtonDown(nFlags, point);
}
void CGLTestView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
switch(nChar)
{
case 'A':
{
// nextstate=ViewEye::Leftrote;
x_motion--;
break;
}
case 'D':
{
// nextstate=ViewEye::rightrote;
x_motion++;
break;
}
case 'W':
{
// nextstate=ViewEye::Eyeup;
y_motion++;
break;
}
case 'X':
{
// nextstate=ViewEye::Eyedown;
y_motion--;
break;
}
case VK_UP:
{
// VHRCt.viewEye.viewy+=0.1f;
// VHRCt.viewEye.eye.z+=0.1f;
// VHRCt.viewEye.at.z+=0.1f;
z_motion++;
break;
}
case VK_DOWN:
{
// VHRCt.viewEye.viewy-=0.1f;
// VHRCt.viewEye.eye.z-=0.1f;
// VHRCt.viewEye.at.z-=0.1f;
z_motion--;
break;
}
case VK_LEFT:
{ //每当按下LEFT,rotate数值 +1,以下函数都类似
rotate++;
break;
}
case VK_RIGHT:
{
rotate--;
break;
}
}
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
2、图像的点选反馈
void CGLTestView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
xPos = point.x; // horizontal position of cursor
yPos = point.y; // vertical position of cursor
ProcessSelection(xPos, yPos);
CView::OnLButtonDown(nFlags, point);
}
BOOL CGLTestView::RenderScene(void)
{
// 见 基础篇
}
// 处理选取
void CGLTestView::ProcessSelection(int xPos, int yPos)
{
CString Sh;
GLint hits;
// 选择缓冲区
// 单击与视口保存
GLint viewport[4];
// 设置选择缓冲区
glSelectBuffer(512, SelectBuff);
// 获得视口
glGetIntegerv(GL_VIEWPORT, viewport);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glRenderMode(GL_SELECT);
glLoadIdentity();
gluPickMatrix(xPos, viewport[3]-yPos+viewport[1] , 2,2, viewport);
// 应用透视投影矩阵
fAspect =(float)viewport[2]/(float)viewport[3];
gluPerspective(45.0f, fAspect, 1.0, 425.0); // 投影变换, 好象默认是45度视角
// 绘制场景
RenderScene();
// 收集点击记录
hits=glRenderMode(GL_RENDER);
CString str;
str.Format("hits:%d",hits);
// AfxMessageBox(str);
Sh="Error: Nothing was Selected!";
if(hits >= 1)
Sh=ProcessPlanet(SelectBuff);
// 恢复投影矩阵
glMatrixMode(GL_PROJECTION);
glPopMatrix();
// 恢复到模型视图,以便进行正常的渲染
glMatrixMode(GL_MODELVIEW);
MessageBox(Sh,MB_OK);
}
// 处理选取细节
CString CGLTestView::ProcessPlanet(GLuint *pSelectBuff)
{
int id,count;
char cMessage[64];
// 名称堆栈中名称的数目
count = pSelectBuff[0];
// 名称堆栈的栈底
id = pSelectBuff[3];
// 选择发生
// 当前的视点在物体内部
CString str;
str.Format("ID:%d",id);
// AfxMessageBox(str);
switch(id)
{
case 1:
strcpy(cMessage,"You clicked Earth.");
if(count == 2)
strcat(cMessage,"\nSpecifically the moon.");
break;
case 2:
strcpy(cMessage,"You clicked Teapot.");
// if(count == 2)
// {
// if(pSelectBuff[4] == MOON1)
// strcat(cMessage,"\nSpecifically Moon #1.");
// else
// strcat(cMessage,"\nSpecifically Moon #2.");
// }
break;
default:
strcpy(cMessage,"Error - Nothing was clicked on!");
break;
}
// MessageBox(cMessage,"Selection Message",MB_OK);
return cMessage;
}