OpenGL中的光照和键盘控制

这一篇基本上是从Nehe的第7课改编而来的,我将他的Win32代码改写为MFC框架下来实现。

第一个遇到的问题就是MFC窗口中如何响应键盘消息,搜索了下资料,发现只需要重载PreTranslateMessage函数就可以让窗口监听按键消息了。

None.gif BOOLCOpenGLDemoView::PreTranslateMessage(MSG * pMsg)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
//TODO:Addyourspecializedcodehereand/orcallthebaseclass
InBlock.gif
if(pMsg->message==WM_KEYDOWN)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifSendMessage(pMsg
->message,pMsg->wParam,pMsg->lParam);
InBlock.gif
returntrue;
ExpandedSubBlockEnd.gif}

InBlock.gif
else
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
returnCView::PreTranslateMessage(pMsg);
ExpandedSubBlockEnd.gif}

ExpandedBlockEnd.gif}

None.gif
None.gif

为了监视按键的情况,增设了下面几个变量来负责按键的控制:

None.gif GLbooleanbLighting; // 是否启用光照
None.gif
bool lPressed; // ’L’键是否按下
None.gif
bool fPressed; // ’F’键是否按下
None.gif

目的是防止用户长时间按住一个键不动(例如‘L’不动,从而导致光照持续地开关)这种情况。

None.gif GLfloatxspeed; // X旋转速度
None.gif
GLfloatyspeed; // Y旋转速度
None.gif
GLfloatz; // 深入屏幕的距离
None.gif

这几个变量是让用户用来增减旋转速度和Z轴深度用的。

None.gif void COpenGLDemoView::OnKeyDown(UINTnChar,UINTnRepCnt,UINTnFlags)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
//TODO:Addyourmessagehandlercodehereand/orcalldefault
InBlock.gif
switch(nChar)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
caseVK_LEFT:
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//左键
InBlock.gif
yspeed-=0.01f;
InBlock.gif
break;
ExpandedSubBlockEnd.gif}

InBlock.gif
caseVK_RIGHT:
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//右键
InBlock.gif
yspeed+=0.01f;
InBlock.gif
break;
ExpandedSubBlockEnd.gif}

InBlock.gif
caseVK_NEXT:
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//Page_Down键按下
InBlock.gif
z+=0.05f;
InBlock.gif
break;
ExpandedSubBlockEnd.gif}

InBlock.gif
caseVK_PRIOR:
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//Page_Up键按下
InBlock.gif
z-=0.05f;
InBlock.gif
break;
ExpandedSubBlockEnd.gif}

InBlock.gif
caseVK_UP:
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//Page_Up键按下
InBlock.gif
xspeed-=0.01f;
InBlock.gif
break;
ExpandedSubBlockEnd.gif}

InBlock.gif
caseVK_DOWN:
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//Page_Up键按下
InBlock.gif
xspeed+=0.01f;
InBlock.gif
break;
ExpandedSubBlockEnd.gif}

InBlock.gif
case'F':
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.giffPressed
=TRUE;
InBlock.gif
break;
ExpandedSubBlockEnd.gif}

InBlock.gif
case'L':
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.giflPressed
=TRUE;
InBlock.gif
break;
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
default:
InBlock.gif
break;
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gifCView::OnKeyDown(nChar,nRepCnt,nFlags);
ExpandedBlockEnd.gif}

None.gif
None.gif
void COpenGLDemoView::OnKeyUp(UINTnChar,UINTnRepCnt,UINTnFlags)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
//TODO:Addyourmessagehandlercodehereand/orcalldefault
InBlock.gif
switch(nChar)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
case'F':
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
if(fPressed==TRUE)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.giffilter
=(filter+1)%3;
ExpandedSubBlockEnd.gif}

InBlock.giffPressed
=FALSE;
InBlock.gif
break;
ExpandedSubBlockEnd.gif}

InBlock.gif
case'L':
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
if(lPressed==TRUE)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//防止长时间按着'L'键而导致光照持续变化
InBlock.gif
bLighting=!bLighting;
InBlock.gif
if(bLighting)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifglEnable(GL_LIGHTING);
ExpandedSubBlockEnd.gif}

InBlock.gif
else
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifglDisable(GL_LIGHTING);
ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}

InBlock.giflPressed
=FALSE;
InBlock.gif
break;
ExpandedSubBlockEnd.gif}

InBlock.gif
default:
InBlock.gif
break;
ExpandedSubBlockEnd.gif}

InBlock.gifCView::OnKeyUp(nChar,nRepCnt,nFlags);
ExpandedBlockEnd.gif}

None.gif

具体的绘制代码如下:

None.gif int COpenGLDemoView::DrawGLScene()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {//Here'sWhereWeDoAllTheDrawing
InBlock.gif
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);//ClearScreenAndDepthBuffer
InBlock.gif
glPushAttrib(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_CURRENT_BIT);
InBlock.gifglPushMatrix();
InBlock.gifglLoadIdentity();
InBlock.gifglTranslatef(
0.0f,0.0f,z);
InBlock.gifglRotatef(xrot,
1.0f,0.0f,0.0f);
InBlock.gifglRotatef(yrot,
0.0f,1.0f,0.0f);
InBlock.gif
//纹理模式切换,这里提供三种纹理模式
InBlock.gif
glBindTexture(GL_TEXTURE_2D,texture[this->filter]);//绑定到选定的纹理上
InBlock.gif
glBegin(GL_QUADS);//绘制正方形
InBlock.gif
//FrontFace
InBlock.gif
glNormal3f(0.0f,0.0f,1.0f);//法线指向观察者
InBlock.gif
glTexCoord2f(0.0f,0.0f);glVertex3f(-1.0f,-1.0f,1.0f);
InBlock.gifglTexCoord2f(
1.0f,0.0f);glVertex3f(1.0f,-1.0f,1.0f);
InBlock.gifglTexCoord2f(
1.0f,1.0f);glVertex3f(1.0f,1.0f,1.0f);
InBlock.gifglTexCoord2f(
0.0f,1.0f);glVertex3f(-1.0f,1.0f,1.0f);
InBlock.gif
//BackFace
InBlock.gif
glNormal3f(0.0f,0.0f,-1.0f);//法线背向观察者
InBlock.gif
glTexCoord2f(1.0f,0.0f);glVertex3f(-1.0f,-1.0f,-1.0f);
InBlock.gifglTexCoord2f(
1.0f,1.0f);glVertex3f(-1.0f,1.0f,-1.0f);
InBlock.gifglTexCoord2f(
0.0f,1.0f);glVertex3f(1.0f,1.0f,-1.0f);
InBlock.gifglTexCoord2f(
0.0f,0.0f);glVertex3f(1.0f,-1.0f,-1.0f);
InBlock.gif
//TopFace
InBlock.gif
glNormal3f(0.0f,1.0f,0.0f);//法线向上
InBlock.gif
glTexCoord2f(0.0f,1.0f);glVertex3f(-1.0f,1.0f,-1.0f);
InBlock.gifglTexCoord2f(
0.0f,0.0f);glVertex3f(-1.0f,1.0f,1.0f);
InBlock.gifglTexCoord2f(
1.0f,0.0f);glVertex3f(1.0f,1.0f,1.0f);
InBlock.gifglTexCoord2f(
1.0f,1.0f);glVertex3f(1.0f,1.0f,-1.0f);
InBlock.gif
//BottomFace
InBlock.gif
glNormal3f(0.0f,-1.0f,0.0f);//法线朝下
InBlock.gif
glTexCoord2f(1.0f,1.0f);glVertex3f(-1.0f,-1.0f,-1.0f);
InBlock.gifglTexCoord2f(
0.0f,1.0f);glVertex3f(1.0f,-1.0f,-1.0f);
InBlock.gifglTexCoord2f(
0.0f,0.0f);glVertex3f(1.0f,-1.0f,1.0f);
InBlock.gifglTexCoord2f(
1.0f,0.0f);glVertex3f(-1.0f,-1.0f,1.0f);
InBlock.gif
//Rightface
InBlock.gif
glNormal3f(1.0f,0.0f,0.0f);//法线朝右
InBlock.gif
glTexCoord2f(1.0f,0.0f);glVertex3f(1.0f,-1.0f,-1.0f);
InBlock.gifglTexCoord2f(
1.0f,1.0f);glVertex3f(1.0f,1.0f,-1.0f);
InBlock.gifglTexCoord2f(
0.0f,1.0f);glVertex3f(1.0f,1.0f,1.0f);
InBlock.gifglTexCoord2f(
0.0f,0.0f);glVertex3f(1.0f,-1.0f,1.0f);
InBlock.gif
//LeftFace
InBlock.gif
glNormal3f(-1.0f,0.0f,0.0f);//法线朝左
InBlock.gif
glTexCoord2f(0.0f,0.0f);glVertex3f(-1.0f,-1.0f,-1.0f);
InBlock.gifglTexCoord2f(
1.0f,0.0f);glVertex3f(-1.0f,-1.0f,1.0f);
InBlock.gifglTexCoord2f(
1.0f,1.0f);glVertex3f(-1.0f,1.0f,1.0f);
InBlock.gifglTexCoord2f(
0.0f,1.0f);glVertex3f(-1.0f,1.0f,-1.0f);
InBlock.gifglEnd();
//正方形绘制结束
InBlock.gif
glPopMatrix();
InBlock.gifglPopAttrib();
InBlock.gifglFlush();
InBlock.gifxrot
+=xspeed;
InBlock.gifyrot
+=yspeed;
InBlock.gif
returnTRUE;//EverythingWentOK
ExpandedBlockEnd.gif
}

None.gif

最后效果图如下:

200780903.jpg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值