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
}

最后效果图如下:
200780903.jpg


本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2007/08/09/849887.htm,如需转载请自行联系原作者
目录
相关文章
|
8月前
|
算法
QT+OpenGL高级光照 Blinn-Phong和Gamma校正
冯氏光照:视线与反射方向之间的夹角不小于90度,镜面光分量会变成0.0(不是很合理,会有清晰的分界线) Blinn-Phone模型采用了半程向量,即光线与视线夹角一般方向上的一个单位向量。当半程向量与法线向量越接近,镜面光分量就越大。
61 0
|
8月前
QT+OpenGL光照2
在现实世界中,每个物体会对光照产生不同的反应
25 0
|
8月前
QT+OpenGL光照
现实生活中看到的物体的颜色并不是这个物体真正拥有的颜色,而是它所反射的颜色 太阳光能被看见的白光是多找演的的组合
32 0
|
API Android开发 C++
Android OpenGL添加光照和材料属性
Android OpenGL添加光照和材料属性
Android OpenGL添加光照和材料属性
OpenGL ES 关于光照计算
有关光照的代码公式, 在此用CC老师已经写好的代码做一个记录, 方便以后使用的时候查询.
84 0
|
Windows
【OpenGL】二十三、OpenGL 光照中的法线原理
【OpenGL】二十三、OpenGL 光照中的法线原理
177 0
【OpenGL】二十三、OpenGL 光照中的法线原理
|
Windows
【OpenGL】二十二、OpenGL 光照效果 ( 模型准备 | 光照设置 | 启用光照 | 启用光源 | 设置光源位置 | 设置光照参数 | 设置环境光 | 设置反射材质 | 设置法线 )(二)
【OpenGL】二十二、OpenGL 光照效果 ( 模型准备 | 光照设置 | 启用光照 | 启用光源 | 设置光源位置 | 设置光照参数 | 设置环境光 | 设置反射材质 | 设置法线 )(二)
198 0
【OpenGL】二十二、OpenGL 光照效果 ( 模型准备 | 光照设置 | 启用光照 | 启用光源 | 设置光源位置 | 设置光照参数 | 设置环境光 | 设置反射材质 | 设置法线 )(二)
【OpenGL】二十二、OpenGL 光照效果 ( 模型准备 | 光照设置 | 启用光照 | 启用光源 | 设置光源位置 | 设置光照参数 | 设置环境光 | 设置反射材质 | 设置法线 )(一)
【OpenGL】二十二、OpenGL 光照效果 ( 模型准备 | 光照设置 | 启用光照 | 启用光源 | 设置光源位置 | 设置光照参数 | 设置环境光 | 设置反射材质 | 设置法线 )(一)
180 0
【OpenGL】二十二、OpenGL 光照效果 ( 模型准备 | 光照设置 | 启用光照 | 启用光源 | 设置光源位置 | 设置光照参数 | 设置环境光 | 设置反射材质 | 设置法线 )(一)