2009-11-15 133 views
-1

我一直跟着教程系​​列OpenGLGLUTOpenGL的键盘摄像头控制

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

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

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

在做先进教程停止工作。我几乎只是复制并粘贴它。当我运行它的代码版本时,它的工作。我的工作似乎不起作用。使用向上和向下键时,它应该在左右移动时旋转摄像机视图并向前和向后移动。

我的代码如下分解:

我的这部分代码使组件在现场使用init(),它initilizes值等:

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就像在赛车游戏中一样...

+0

这个问题已经有很多点看着http://www.gamedev.net/community/forums/topic.asp?topic_id=553415仍然没有解决办法让我知道,如果你能帮助感谢。 – Anicho 2009-11-16 00:24:15

+0

你可以下载我的源代码这个@ http://www.anicho.com/downloads/StageTwo.zip – Anicho 2009-11-16 04:07:37

回答

2

尝试摆脱所有全局变量声明前面的静态。

最后一次使用静态是作为代码文件中的全局变量。在这种情况下,使用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); 
}
+0

http://www.gamedev.net/community/forums/topic.asp?topic_id=553415解决方案可以在这里找到 – Anicho 2010-02-10 14:15:03

0

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

我建议增加:

glutTimerFunc(40, display, 1); 

你的显示功能的结束。这将导致显示每40毫秒被调用一次。

此外,不要将显示器注册为空闲功能,或者您将有空闲功能启动许多系列定时器功能。

P.S.我会打电话glFlush();就在交换显示功能中的缓冲区之前。

+0

http://www.gamedev.net/community/forums/topic.asp?topic_id=553415感谢glFlush提示解决方案可以在这个论坛发现 – Anicho 2010-02-10 14:18:22