【问题标题】:OpenGL Keyboard Camera ControlsOpenGL 键盘相机控制
【发布时间】:2009-11-15 20:02:20
【问题描述】:

我一直在关注OpenGLGLUT:的这个系列教程:

http://www.lighthouse3d.com/opengl/glut/

我已经到了使用键盘实现相机控制的阶段:

http://www.lighthouse3d.com/opengl/glut/index.php?8

在学习高级教程时,它会停止工作。我几乎只是复制并粘贴了它。当我运行它的代码版本时,它可以工作。我的似乎不起作用。左右移动时应旋转相机视图,使用上下键时应前后移动。

我的代码在这里分解:

我的这部分代码使用 init() 渲染场景中的组件,它会初始化值等:

void display(void)
{
 if (deltaMove)
  moveMeFlat(deltaMove);
 if (deltaAngle) {
  angle += deltaAngle;
  orientMe(angle);
 }

 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 glBindTexture(GL_TEXTURE_2D, texture[0]);
 RenderSkyDome();
 glBindTexture(GL_TEXTURE_2D, NULL);

 glutSwapBuffers();

}

void init(void)
{
 glClearColor(0.0, 0.0, 0.0, 0.0);
 glClearDepth(1.0f);
 glColor3f(0.0, 0.0, 1.0);
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 glEnable(GL_TEXTURE_2D);
 glEnable(GL_DEPTH_TEST);
 glDepthFunc(GL_LEQUAL);
 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

 LoadTextures("clouds2.bmp", 0);
 GenerateDome(600.0f, 5.0f, 5.0f, 1.0f, 1.0f);

 snowman_display_list = createDL();
}

这是我的主循环函数:

int main ()
{
 glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
 glutInitWindowSize(800, 600);
 glutInitWindowPosition(0, 0);
 glutCreateWindow("Captain Ed's Adventures: Great Wall of China");
 init();

 //Glut Input Commands
 glutIgnoreKeyRepeat(1);
 glutSpecialFunc(pressKey);
 glutSpecialUpFunc(releaseKey);
 glutKeyboardFunc(processNormalKeys);

 glutDisplayFunc(display);
 glutIdleFunc(display);
 glutReshapeFunc(reshape);  // This redraws everything on screen when window size is changed.               
 glutMainLoop();
 return 0;
}

这是我调用的输入函数:

void pressKey(int key, int x, int y) {

 switch (key) {
  case GLUT_KEY_LEFT : deltaAngle = -0.10f;break;
  case GLUT_KEY_RIGHT : deltaAngle = 0.10f;break;
  case GLUT_KEY_UP : deltaMove = 50;break;
  case GLUT_KEY_DOWN : deltaMove = -50;break;
 }
}

void releaseKey(int key, int x, int y) {

 switch (key) {
  case GLUT_KEY_LEFT : if (deltaAngle < 0.0f) 
         deltaAngle = 0.0f;
        break;
  case GLUT_KEY_RIGHT : if (deltaAngle > 0.0f) 
         deltaAngle = 0.0f;
        break;
  case GLUT_KEY_UP :  if (deltaMove > 0) 
         deltaMove = 0;
        break;
  case GLUT_KEY_DOWN : if (deltaMove < 0) 
         deltaMove = 0;
        break;
 }
}

void processNormalKeys(unsigned char key, int x, int y) {

 if (key == 27) 
  exit(0);
}

相机使用的变量和应该改变它的函数:

static float angle=0.0,deltaAngle = 0.0,ratio;
static float x=0.0f,y=1.75f,z=5.0f;
static float lx=0.0f,ly=0.0f,lz=-1.0f;
static int deltaMove=0;

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);
}

我相信这几乎就是我正在使用的所有东西,所以基本上应该发生的是,当我按下 UP 键时 deltaMove 应该 = 50 并且当这种情况发生时,void display(void) 中的 if 语句应该执行 moveMeFlat(deltaMove);不知道是我做错了还是有更好的结果....

我可以在相关的开关盒中移动“moveMeFlat(deltaMove)”,但这不允许我进行我想要的移动。它似乎可以使用上面教程中的源代码并具有正确的功能,但在我的情况下不是这样,所以我的假设是它与显示中的 if 语句有关。

我正在寻找的最终结果是能够通过左右旋转相机进行前后工作。我希望能够按前进和左键并像在赛车游戏中一样看到相机swerve左...

【问题讨论】:

标签: c++ opengl input keyboard glut


【解决方案1】:

尝试在所有全局变量声明前去掉静态。

静态的最后一次使用是作为代码文件中的全局变量。在这种情况下,使用 static 表示作为项目一部分的其他文件中的源代码无法访问该变量。只有单个文件中的代码才能看到该变量。 (它的范围 - 或可见性 - 仅限于文件。)这种技术可用于模拟面向对象的代码,因为它限制了变量的可见性,从而有助于避免命名冲突。这种对静态的使用是对 C 的保留。

-http://www.cprogramming.com/tutorial/statickeyword.html

另外,不要这样:

if (deltaMove)
  moveMeFlat(deltaMove);
 if (deltaAngle) {
  angle += deltaAngle;
  orientMe(angle);
 }

试试这个:

if (deltaMove != 0)
  moveMeFlat(deltaMove);
 if (deltaAngle != 0.0) {
  angle += deltaAngle;
  orientMe(angle);
 }

【讨论】:

【解决方案2】:

当按键发生时,GLUT 是否空闲?我觉得不是闲的。您的 display() 函数仅在创建窗口和 GLUT 空闲时调用,这不允许更改您的位置。

我建议添加:

glutTimerFunc(40, display, 1);

到你的显示函数的末尾。这将导致每 40 毫秒调用一次显示。

另外,不要将 display 注册为空闲功能,否则您将让空闲功能启动许多系列的计时器功能。

附:我会打电话给 glFlush();就在交换显示函数中的缓冲区之前。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-26
  • 1970-01-01
  • 2017-01-25
  • 2017-09-22
  • 1970-01-01
  • 2011-10-10
  • 1970-01-01
相关资源
最近更新 更多