OpenGL中的光照和键盘控制

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

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

BOOL COpenGLDemoView::PreTranslateMessage(MSG* pMsg) 
{
    
// TODO: Add your specialized code here and/or call the base class
    if(pMsg->message == WM_KEYDOWN)
    
{       
        SendMessage(pMsg
->message, pMsg->wParam, pMsg->lParam);
        
return true;
    }

    
else
    
{
        
return CView::PreTranslateMessage(pMsg);
    }

}


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

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

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

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

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

void COpenGLDemoView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
    
// TODO: Add your message handler code here and/or call default
    switch(nChar)
    
{
    
case VK_LEFT:
        
{//左键
            yspeed-=0.01f;
            
break;
        }

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

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

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

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

    
case VK_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(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
    
// TODO: Add your message handler code here and/or call default
    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's Where We Do All The Drawing
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    // Clear Screen And Depth Buffer
    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);                            //  绘制正方形
        
// Front Face
        glNormal3f( 0.0f0.0f1.0f);                    // 法线指向观察者
        glTexCoord2f(0.0f0.0f); glVertex3f(-1.0f-1.0f,  1.0f);
        glTexCoord2f(
1.0f0.0f); glVertex3f( 1.0f-1.0f,  1.0f);
        glTexCoord2f(
1.0f1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
        glTexCoord2f(
0.0f1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
        
// Back Face
        glNormal3f( 0.0f0.0f,-1.0f);                    // 法线背向观察者
        glTexCoord2f(1.0f0.0f); glVertex3f(-1.0f-1.0f-1.0f);
        glTexCoord2f(
1.0f1.0f); glVertex3f(-1.0f,  1.0f-1.0f);
        glTexCoord2f(
0.0f1.0f); glVertex3f( 1.0f,  1.0f-1.0f);
        glTexCoord2f(
0.0f0.0f); glVertex3f( 1.0f-1.0f-1.0f);
        
// Top Face
        glNormal3f( 0.0f1.0f0.0f);                    // 法线向上
        glTexCoord2f(0.0f1.0f); glVertex3f(-1.0f,  1.0f-1.0f);
        glTexCoord2f(
0.0f0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
        glTexCoord2f(
1.0f0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
        glTexCoord2f(
1.0f1.0f); glVertex3f( 1.0f,  1.0f-1.0f);
        
// Bottom Face
        glNormal3f( 0.0f,-1.0f0.0f);                    // 法线朝下
        glTexCoord2f(1.0f1.0f); glVertex3f(-1.0f-1.0f-1.0f);
        glTexCoord2f(
0.0f1.0f); glVertex3f( 1.0f-1.0f-1.0f);
        glTexCoord2f(
0.0f0.0f); glVertex3f( 1.0f-1.0f,  1.0f);
        glTexCoord2f(
1.0f0.0f); glVertex3f(-1.0f-1.0f,  1.0f);
        
// Right face
        glNormal3f( 1.0f0.0f0.0f);                    // 法线朝右
        glTexCoord2f(1.0f0.0f); glVertex3f( 1.0f-1.0f-1.0f);
        glTexCoord2f(
1.0f1.0f); glVertex3f( 1.0f,  1.0f-1.0f);
        glTexCoord2f(
0.0f1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
        glTexCoord2f(
0.0f0.0f); glVertex3f( 1.0f-1.0f,  1.0f);
        
// Left Face
        glNormal3f(-1.0f0.0f0.0f);                    // 法线朝左
        glTexCoord2f(0.0f0.0f); glVertex3f(-1.0f-1.0f-1.0f);
        glTexCoord2f(
1.0f0.0f); glVertex3f(-1.0f-1.0f,  1.0f);
        glTexCoord2f(
1.0f1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
        glTexCoord2f(
0.0f1.0f); glVertex3f(-1.0f,  1.0f-1.0f);
    glEnd();                                
// 正方形绘制结束
    glPopMatrix();
    glPopAttrib();
    glFlush();
    xrot
+=xspeed;
    yrot
+=yspeed;
    
return TRUE;                                        // Everything Went OK
}

最后效果图如下:

200780903.jpg

posted on 2007-08-09 21:19  Phinecos(洞庭散人)  阅读(2271)  评论(1编辑  收藏  举报

导航