2009-11-15 131 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