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.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);
        // Back Face
        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);
        // Top Face
        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);
        // Bottom Face
        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);
        // Right face
        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);
        // Left Face
        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;
    return TRUE;                                        // Everything Went OK
}

最后效果图如下:
OpenGL中的光照和键盘控制


本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2007/08/09/849887.htm,如需转载请自行联系原作者
上一篇:k8s源码分析之kubelet


下一篇:专访Dan Kohn:阡陌交迭,云原生布局开源生态构建及深度应用