这一篇基本上是从Nehe的第7课改编而来的,我将他的Win32代码改写为MFC框架下来实现。
第一个遇到的问题就是MFC窗口中如何响应键盘消息,搜索了下资料,发现只需要重载PreTranslateMessage函数就可以让窗口监听按键消息了。
BOOLCOpenGLDemoView::PreTranslateMessage(MSG
*
pMsg)

{
//TODO:Addyourspecializedcodehereand/orcallthebaseclass
if(pMsg->message==WM_KEYDOWN)


{
SendMessage(pMsg->message,pMsg->wParam,pMsg->lParam);
returntrue;
}
else


{
returnCView::PreTranslateMessage(pMsg);
}
}

为了监视按键的情况,增设了下面几个变量来负责按键的控制:
GLbooleanbLighting;
//
是否启用光照
bool
lPressed;
//
’L’键是否按下
bool
fPressed;
//
’F’键是否按下
目的是防止用户长时间按住一个键不动(例如‘L’不动,从而导致光照持续地开关)这种情况。
GLfloatxspeed;
//
X旋转速度
GLfloatyspeed;
//
Y旋转速度
GLfloatz;
//
深入屏幕的距离
这几个变量是让用户用来增减旋转速度和Z轴深度用的。
void
COpenGLDemoView::OnKeyDown(UINTnChar,UINTnRepCnt,UINTnFlags)

{
//TODO:Addyourmessagehandlercodehereand/orcalldefault
switch(nChar)


{
caseVK_LEFT:


{//左键
yspeed-=0.01f;
break;
}
caseVK_RIGHT:


{//右键
yspeed+=0.01f;
break;
}
caseVK_NEXT:


{//Page_Down键按下
z+=0.05f;
break;
}
caseVK_PRIOR:


{//Page_Up键按下
z-=0.05f;
break;
}
caseVK_UP:


{//Page_Up键按下
xspeed-=0.01f;
break;
}
caseVK_DOWN:


{//Page_Up键按下
xspeed+=0.01f;
break;
}
case'F':


{
fPressed=TRUE;
break;
}
case'L':


{
lPressed=TRUE;
break;
}

default:
break;
}

CView::OnKeyDown(nChar,nRepCnt,nFlags);
}

void
COpenGLDemoView::OnKeyUp(UINTnChar,UINTnRepCnt,UINTnFlags)

{
//TODO:Addyourmessagehandlercodehereand/orcalldefault
switch(nChar)


{
case'F':


{
if(fPressed==TRUE)


{
filter=(filter+1)%3;
}
fPressed=FALSE;
break;
}
case'L':


{
if(lPressed==TRUE)


{//防止长时间按着'L'键而导致光照持续变化
bLighting=!bLighting;
if(bLighting)


{
glEnable(GL_LIGHTING);
}
else


{
glDisable(GL_LIGHTING);
}
}
lPressed=FALSE;
break;
}
default:
break;
}
CView::OnKeyUp(nChar,nRepCnt,nFlags);
}
具体的绘制代码如下:
int
COpenGLDemoView::DrawGLScene()

{//Here'sWhereWeDoAllTheDrawing
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);//ClearScreenAndDepthBuffer
glPushAttrib(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_CURRENT_BIT);
glPushMatrix();
glLoadIdentity();
glTranslatef(0.0f,0.0f,z);
glRotatef(xrot,1.0f,0.0f,0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f);
//纹理模式切换,这里提供三种纹理模式
glBindTexture(GL_TEXTURE_2D,texture[this->filter]);//绑定到选定的纹理上
glBegin(GL_QUADS);//绘制正方形
//FrontFace
glNormal3f(0.0f,0.0f,1.0f);//法线指向观察者
glTexCoord2f(0.0f,0.0f);glVertex3f(-1.0f,-1.0f,1.0f);
glTexCoord2f(1.0f,0.0f);glVertex3f(1.0f,-1.0f,1.0f);
glTexCoord2f(1.0f,1.0f);glVertex3f(1.0f,1.0f,1.0f);
glTexCoord2f(0.0f,1.0f);glVertex3f(-1.0f,1.0f,1.0f);
//BackFace
glNormal3f(0.0f,0.0f,-1.0f);//法线背向观察者
glTexCoord2f(1.0f,0.0f);glVertex3f(-1.0f,-1.0f,-1.0f);
glTexCoord2f(1.0f,1.0f);glVertex3f(-1.0f,1.0f,-1.0f);
glTexCoord2f(0.0f,1.0f);glVertex3f(1.0f,1.0f,-1.0f);
glTexCoord2f(0.0f,0.0f);glVertex3f(1.0f,-1.0f,-1.0f);
//TopFace
glNormal3f(0.0f,1.0f,0.0f);//法线向上
glTexCoord2f(0.0f,1.0f);glVertex3f(-1.0f,1.0f,-1.0f);
glTexCoord2f(0.0f,0.0f);glVertex3f(-1.0f,1.0f,1.0f);
glTexCoord2f(1.0f,0.0f);glVertex3f(1.0f,1.0f,1.0f);
glTexCoord2f(1.0f,1.0f);glVertex3f(1.0f,1.0f,-1.0f);
//BottomFace
glNormal3f(0.0f,-1.0f,0.0f);//法线朝下
glTexCoord2f(1.0f,1.0f);glVertex3f(-1.0f,-1.0f,-1.0f);
glTexCoord2f(0.0f,1.0f);glVertex3f(1.0f,-1.0f,-1.0f);
glTexCoord2f(0.0f,0.0f);glVertex3f(1.0f,-1.0f,1.0f);
glTexCoord2f(1.0f,0.0f);glVertex3f(-1.0f,-1.0f,1.0f);
//Rightface
glNormal3f(1.0f,0.0f,0.0f);//法线朝右
glTexCoord2f(1.0f,0.0f);glVertex3f(1.0f,-1.0f,-1.0f);
glTexCoord2f(1.0f,1.0f);glVertex3f(1.0f,1.0f,-1.0f);
glTexCoord2f(0.0f,1.0f);glVertex3f(1.0f,1.0f,1.0f);
glTexCoord2f(0.0f,0.0f);glVertex3f(1.0f,-1.0f,1.0f);
//LeftFace
glNormal3f(-1.0f,0.0f,0.0f);//法线朝左
glTexCoord2f(0.0f,0.0f);glVertex3f(-1.0f,-1.0f,-1.0f);
glTexCoord2f(1.0f,0.0f);glVertex3f(-1.0f,-1.0f,1.0f);
glTexCoord2f(1.0f,1.0f);glVertex3f(-1.0f,1.0f,1.0f);
glTexCoord2f(0.0f,1.0f);glVertex3f(-1.0f,1.0f,-1.0f);
glEnd();//正方形绘制结束
glPopMatrix();
glPopAttrib();
glFlush();
xrot+=xspeed;
yrot+=yspeed;
returnTRUE;//EverythingWentOK
}
最后效果图如下:
