Chinaunix首页 | 论坛 | 博客
  • 博客访问: 523052
  • 博文数量: 197
  • 博客积分: 2071
  • 博客等级: 上尉
  • 技术积分: 1307
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-02 09:49
个人简介

prothes 专注嵌入式的ARM linux

文章分类

全部博文(197)

文章存档

2014年(3)

2013年(16)

2012年(108)

2011年(70)

分类: C/C++

2011-09-06 12:04:41

 
这一节里,我们再来看看上次的例子,这次我们讲使用高级的键盘控制。
 
在初始化那部分,我们有两个变量:deltaAngle和deltaMode。这些变量控制旋转和移动照相机。当为非0时,照相机执行一些动作,当为0时,照相机就不动,这两个变量的初始值是0,也就是说,照相机初始状态是不动的。
 

#include

#include  

float angle=0.0,deltaAngle = 0.0,ratio;

float x=0.0f,y=1.75f,z=5.0f;

float lx=0.0f,ly=0.0f,lz=-1.0f;

GLint snowman_display_list;int deltaMove = 0;  

void changeSize(int w, int h)        

{        

// Prevent a divide by zero, when window is too short        

// (you cant make a window of zero width).

         if(h == 0)

                 h = 1;

          ratio = 1.0f * w / h;

         // 重置投影矩阵

         glMatrixMode(GL_PROJECTION);

         glLoadIdentity();

                 // 设置视口大小

         glViewport(0, 0, w, h);

          // 设置可视空间

         gluPerspective(45,ratio,1,1000); 

        glMatrixMode(GL_MODELVIEW);

         glLoadIdentity();

         gluLookAt(x, y, z,

                       x + lx,y + ly,z + lz,

                           0.0f,1.0f,0.0f);

}

  void drawSnowMan()

{

         glColor3f(1.0f, 1.0f, 1.0f);

// Draw Body

             glTranslatef(0.0f ,0.75f, 0.0f);

         glutSolidSphere(0.75f,20,20);

 // Draw Head

         glTranslatef(0.0f, 1.0f, 0.0f);

         glutSolidSphere(0.25f,20,20); 

// Draw Eyes

         glPushMatrix();

         glColor3f(0.0f,0.0f,0.0f);

         glTranslatef(0.05f, 0.10f, 0.18f);

         glutSolidSphere(0.05f,10,10);

         glTranslatef(-0.1f, 0.0f, 0.0f);

         glutSolidSphere(0.05f,10,10); 

        glPopMatrix(); 

// Draw Nose 

        glColor3f(1.0f, 0.5f , 0.5f);

         glRotatef(0.0f,1.0f, 0.0f, 0.0f);

         glutSolidCone(0.08f,0.5f,10,2);

}

 GLuint createDL()

{                         

//返回一个显示列表

         GLuint snowManDL;

          // Create the id for the list 

        snowManDL = glGenLists(1);

          // start list

         glNewList(snowManDL,GL_COMPILE);

          // call the function that contains 

        // the rendering commands 

                drawSnowMan(); 

         // endList 

        glEndList(); 

         return(snowManDL);

}

 void initScene()

{

          glEnable(GL_DEPTH_TEST);

         snowman_display_list = createDL(); 

}

 void orientMe(float ang)

{

         lx = sin(ang);

         lz = -cos(ang); 

        glLoadIdentity();

         gluLookAt(x, y, z,

                       x + lx,y + ly,z + lz,

                           0.0f,1.0f,0.0f);

} 

void moveMeFlat(int i)

{

         x = x + i*(lx)*0.1;

         z = z + i*(lz)*0.1;

         glLoadIdentity();

         gluLookAt(x, y, z,

                       x + lx,y + ly,z + lz,

                           0.0f,1.0f,0.0f);

}

下面的代码和以前的有些不同了。下面这个函数最开始,检查我们定义的那两个变量是否为0,如果不为0就调用相应的函数,来控制照相机的移动,和旋转。
void renderScene(void) {          if (deltaMove)                 moveMeFlat(deltaMove);         if (deltaAngle) {                 angle += deltaAngle;                 orientMe(angle);         }         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Draw ground         glColor3f(0.9f, 0.9f, 0.9f);         glBegin(GL_QUADS);                 glVertex3f(-100.0f, 0.0f, -100.0f);                 glVertex3f(-100.0f, 0.0f, 100.0f);                 glVertex3f( 100.0f, 0.0f, 100.0f);                 glVertex3f( 100.0f, 0.0f, -100.0f);         glEnd();// Draw 36 SnowMen         for(int i = -3; i < 3; i++)                 for(int j=-3; j < 3; j++) {                          glPushMatrix();                          glTranslatef(i*10.0,0,j * 10.0);                          glCallList(snowman_display_list);;                          glPopMatrix();                 }         glutSwapBuffers();}
下面的函数,分别是我们注册的特殊键控制的回调函数,和键的释放(键的松开)。
void pressKey(int key, int x, int y) {          switch (key) {                 case GLUT_KEY_LEFT :                          deltaAngle = -0.01f;break;                 case GLUT_KEY_RIGHT :                          deltaAngle = 0.01f;break;                 case GLUT_KEY_UP :                          deltaMove = 1;break;                 case GLUT_KEY_DOWN :                          deltaMove = -1;break;         }} void releaseKey(int key, int x, int y) {          switch (key) {                 case GLUT_KEY_LEFT :                 case GLUT_KEY_RIGHT :                          deltaAngle = 0.0f;break;                 case GLUT_KEY_UP :                 case GLUT_KEY_DOWN :                          deltaMove = 0;break;         }
}
Main函数里,有三行新的代码行。 
glutIgnoreKeyRepeat函数,传递了一个非0值告诉GLUT不发送keyborad repeat消息,然后,glutSpecialUpFunc和glutKeyboardUpFunc调用注册的回调函数。
  int main(int argc, char **argv){         glutInit(&argc, argv);         glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);         glutInitWindowPosition(100,100);         glutInitWindowSize(640,360);         glutCreateWindow("SnowMen from 3D-Tech");          initScene();          glutIgnoreKeyRepeat(1);         glutSpecialFunc(pressKey);         glutSpecialUpFunc(releaseKey);          glutDisplayFunc(renderScene);         glutIdleFunc(renderScene);          glutReshapeFunc(changeSize);          glutMainLoop();          return(0);
}
还可以自己改下照相机设置的函数。 (原文地址:
阅读(722) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~