OpenGL中的光照和键盘控制

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

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

None.gif BOOL COpenGLDemoView::PreTranslateMessage(MSG *  pMsg) 
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
// TODO: Add your specialized code here and/or call the base class
InBlock.gif
    if(pMsg->message == WM_KEYDOWN)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{       
InBlock.gif        SendMessage(pMsg
->message, pMsg->wParam, pMsg->lParam);
InBlock.gif        
return true;
ExpandedSubBlockEnd.gif    }

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

ExpandedBlockEnd.gif}

None.gif
None.gif

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

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

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

None.gif     GLfloat xspeed;                                     //  X 旋转速度
None.gif
    GLfloat yspeed;                                     //  Y 旋转速度
None.gif
    GLfloat    z;                                 //  深入屏幕的距离
None.gif

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

None.gif void  COpenGLDemoView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
// TODO: Add your message handler code here and/or call default
InBlock.gif
    switch(nChar)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif    
case VK_LEFT:
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{//左键
InBlock.gif
            yspeed-=0.01f;
InBlock.gif            
break;
ExpandedSubBlockEnd.gif        }

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

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

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

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

InBlock.gif    
case VK_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.gif            fPressed 
= TRUE    ;
InBlock.gif            
break;
ExpandedSubBlockEnd.gif        }

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

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

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

None.gif
None.gif
void  COpenGLDemoView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
// TODO: Add your message handler code here and/or call default
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.gif                filter
=(filter+1)%3;
ExpandedSubBlockEnd.gif            }

InBlock.gif            fPressed 
= 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.gif                    glEnable(GL_LIGHTING);
ExpandedSubBlockEnd.gif                }

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

ExpandedSubBlockEnd.gif            }

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

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

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

None.gif

具体的绘制代码如下:

None.gif int  COpenGLDemoView::DrawGLScene()                                   
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {// Here's Where We Do All The Drawing
InBlock.gif
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    // Clear Screen And Depth Buffer
InBlock.gif
    glPushAttrib(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_CURRENT_BIT);
InBlock.gif    glPushMatrix();
InBlock.gif    glLoadIdentity();
InBlock.gif    glTranslatef(
0.0f,0.0f,z);
InBlock.gif    glRotatef(xrot,
1.0f,0.0f,0.0f);
InBlock.gif    glRotatef(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        
// Front Face
InBlock.gif
        glNormal3f( 0.0f0.0f1.0f);                    // 法线指向观察者
InBlock.gif
        glTexCoord2f(0.0f0.0f); glVertex3f(-1.0f-1.0f,  1.0f);
InBlock.gif        glTexCoord2f(
1.0f0.0f); glVertex3f( 1.0f-1.0f,  1.0f);
InBlock.gif        glTexCoord2f(
1.0f1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
InBlock.gif        glTexCoord2f(
0.0f1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
InBlock.gif        
// Back Face
InBlock.gif
        glNormal3f( 0.0f0.0f,-1.0f);                    // 法线背向观察者
InBlock.gif
        glTexCoord2f(1.0f0.0f); glVertex3f(-1.0f-1.0f-1.0f);
InBlock.gif        glTexCoord2f(
1.0f1.0f); glVertex3f(-1.0f,  1.0f-1.0f);
InBlock.gif        glTexCoord2f(
0.0f1.0f); glVertex3f( 1.0f,  1.0f-1.0f);
InBlock.gif        glTexCoord2f(
0.0f0.0f); glVertex3f( 1.0f-1.0f-1.0f);
InBlock.gif        
// Top Face
InBlock.gif
        glNormal3f( 0.0f1.0f0.0f);                    // 法线向上
InBlock.gif
        glTexCoord2f(0.0f1.0f); glVertex3f(-1.0f,  1.0f-1.0f);
InBlock.gif        glTexCoord2f(
0.0f0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
InBlock.gif        glTexCoord2f(
1.0f0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
InBlock.gif        glTexCoord2f(
1.0f1.0f); glVertex3f( 1.0f,  1.0f-1.0f);
InBlock.gif        
// Bottom Face
InBlock.gif
        glNormal3f( 0.0f,-1.0f0.0f);                    // 法线朝下
InBlock.gif
        glTexCoord2f(1.0f1.0f); glVertex3f(-1.0f-1.0f-1.0f);
InBlock.gif        glTexCoord2f(
0.0f1.0f); glVertex3f( 1.0f-1.0f-1.0f);
InBlock.gif        glTexCoord2f(
0.0f0.0f); glVertex3f( 1.0f-1.0f,  1.0f);
InBlock.gif        glTexCoord2f(
1.0f0.0f); glVertex3f(-1.0f-1.0f,  1.0f);
InBlock.gif        
// Right face
InBlock.gif
        glNormal3f( 1.0f0.0f0.0f);                    // 法线朝右
InBlock.gif
        glTexCoord2f(1.0f0.0f); glVertex3f( 1.0f-1.0f-1.0f);
InBlock.gif        glTexCoord2f(
1.0f1.0f); glVertex3f( 1.0f,  1.0f-1.0f);
InBlock.gif        glTexCoord2f(
0.0f1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
InBlock.gif        glTexCoord2f(
0.0f0.0f); glVertex3f( 1.0f-1.0f,  1.0f);
InBlock.gif        
// Left Face
InBlock.gif
        glNormal3f(-1.0f0.0f0.0f);                    // 法线朝左
InBlock.gif
        glTexCoord2f(0.0f0.0f); glVertex3f(-1.0f-1.0f-1.0f);
InBlock.gif        glTexCoord2f(
1.0f0.0f); glVertex3f(-1.0f-1.0f,  1.0f);
InBlock.gif        glTexCoord2f(
1.0f1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
InBlock.gif        glTexCoord2f(
0.0f1.0f); glVertex3f(-1.0f,  1.0f-1.0f);
InBlock.gif    glEnd();                                
// 正方形绘制结束
InBlock.gif
    glPopMatrix();
InBlock.gif    glPopAttrib();
InBlock.gif    glFlush();
InBlock.gif    xrot
+=xspeed;
InBlock.gif    yrot
+=yspeed;
InBlock.gif    
return TRUE;                                        // Everything Went OK
ExpandedBlockEnd.gif
}

None.gif

最后效果图如下:

200780903.jpg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值