这一篇基本上是从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;//是否启用光照
boollPressed;//’L’键是否按下
boolfPressed;//’F’键是否按下
目的是防止用户长时间按住一个键不动(例如‘L’不动,从而导致光照持续地开关)这种情况。
GLfloatxspeed;//X旋转速度
GLfloatyspeed;//Y旋转速度
GLfloatz;//深入屏幕的距离
这几个变量是让用户用来增减旋转速度和Z轴深度用的。
voidCOpenGLDemoView::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);
}
voidCOpenGLDemoView::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);
}
具体的绘制代码如下:
intCOpenGLDemoView::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
}
最后效果图如下:

本文介绍如何在MFC框架下使用OpenGL进行绘图,包括键盘消息响应、旋转速度及Z轴深度控制等,并提供了具体绘制代码示例。
2792

被折叠的 条评论
为什么被折叠?



