OpenGL中的光照和键盘控制
2007-08-09 21:56
375 查看
这一篇基本上是从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
}
最后效果图如下:
第一个遇到的问题就是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
}
最后效果图如下:
相关文章推荐
- 【Qt OpenGL教程】07:光照和键盘控制
- OpenGL之路(八)加入�光照效果和键盘控制
- 为OpenGL考试而准备的代码——鼠标控制视角变换+简单纹理映射+键盘的光照控制+Bezier曲线
- OpenGL小探4——光照和键盘控制
- NeHe+OpenGL教程 第七课 纹理过滤器、光照和键盘控制
- OpenGL中的光照和键盘控制
- OpenGL学习笔记 (7) —— 三种不同的纹理滤波方式,光照和键盘控制
- OpenGL(二十) glutSpecialFunc响应键盘方向控制键
- OpenGL键盘控制图形移动
- OpenGL3D图形、旋转、纹理、键盘移动、光照、滤波、透明(完整)
- opengl键盘控制一
- Andriod OpenGL 教程 07 - 光照和输入控制
- OpenGL光照、键盘
- OpenGL_8 光照和键盘
- OpenGL之路(八)添加光照效果和键盘控制
- OpenGL 键盘控制和灯光
- OpenGL---GLUT键盘控制 .
- OpenGL3D图形、旋转、纹理、键盘移动、光照、滤波、透明(完整)
- 计算机图形学OpenGL——键盘控制三维汽车
- OpenGL 键盘控制