-- 作者:卷积内核
-- 发布时间:1/16/2008 5:25:00 PM
-- 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 }
|