2013-07-08 2 views
1

Eclipse를 사용하여 OpenGL에서 볼링 게임을 만들었습니다.gluLookAt()가 예상대로 작동하지 않습니다.

이제 키를 누를 때 카메라의 화면을 변경하고 싶습니다.

하지만 x 버튼을 누르면 모든 것이 사라집니다.

여기에 우리 코드 - 코드의 경우 'i'를에서

#include <GL/glut.h> 
#include <stdlib.h> 
int refreshMillis = 30; // Refresh period in milliseconds 
int windowWidth = 640; // Windowed mode's width 
int windowHeight = 480; // Windowed mode's height 
int windowPosX = 50; // Windowed mode's top-left corner x 
int windowPosY = 50; // Windowed mode's top-left corner y 
bool fullScreenMode = false; // Full-screen or windowed mode? 
GLfloat ballTSpeed = 0.15f; // Ball's speed in y directions 
GLfloat x = 1.0f, y = 10.0f, z = 10.0f, i = 0.0f, j = 0.0f, k = 0.0f, a = 0.0f, 
     b = 0.0f, c = -1.0f; 
bool moveBallUp = false, moveBallDown = false, isCollision = false, resetCall = 
     false; 
// 
GLfloat cone1[] = { 0.0f, 2.5f, -11.0f, /*rotated*/30.0f, -1.5, 0.0, 0.0 }; 
GLfloat cone2[] = { 2.0f, 2.5f, -11.0f, /*rotated*/30.0f, -1.5, 0.0, 0.0 }; 
GLfloat cone3[] = { -2.0f, 2.5f, -11.0f, /*rotated*/30.0f, -1.5, 0.0, 0.0 }; 

GLfloat ball[] = {/* X */0.0f, /* Y */-2.0f, /* Z */-6.0f, /*sphere*/1.0f, 50.0, 
     50.0 }; 
// 

void resetGame() { 

    resetCall = true; 
    cone1[0] = 0.0f; 
    cone1[1] = 2.5f; 
    cone1[2] = -11.0f; 
    /*rotated*/ 
    cone1[3] = 30.0f; 
    cone1[4] = -1.5; 
    cone1[5] = 0.0; 
    cone1[6] = 0.0; 

    cone2[0] = 2.0f; 
    cone2[1] = 2.5f; 
    cone2[2] = -11.0f; 
    /*rotated*/ 
    cone2[3] = 30.0f; 
    cone2[4] = -1.5; 
    cone2[5] = 0.0; 
    cone2[6] = 0.0; 

    cone3[0] = -2.0f; 
    cone3[1] = 2.5f; 
    cone3[2] = -11.0f; 
    /*rotated*/ 
    cone3[3] = 30.0f; 
    cone3[4] = -1.5; 
    cone3[5] = 0.0; 
    cone3[6] = 0.0; 

} 

const GLfloat light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f }; 
const GLfloat light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f }; 
const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; 
const GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f }; 

const GLfloat mat_ambient[] = { 0.7f, 0.7f, 0.7f, 1.0f }; 
const GLfloat mat_diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f }; 
const GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; 
const GLfloat high_shininess[] = { 100.0f }; 
static void resize(int width, int height) { 
    const float ar = (float) width/(float) height; 

    glViewport(0, 0, width, height); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glFrustum(-ar, ar, -1.0, 1.0, 1.0, 100.0); 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    gluLookAt(x, y, z, i, j, k, a, b, c); 
    // eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz 
} 
/* Called back when the timer expired */ 
void Timer(int value) { 
    glutPostRedisplay(); // Post a paint request to activate display() 
    glutTimerFunc(refreshMillis, Timer, 0); // subsequent timer call at milliseconds 
} 
void keyboard(unsigned char key, int x, int y) { 
    switch (key) { 
    case 27: // ESC key 
     exit(0); 
     break; 
    case 'r': 
     resetGame(); 
     break; 
    case 'i': 
     x += 0.5; 
     gluLookAt(x, y, z, i, j, k, a, b, c); 
     // eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz 

    } 
} 

void specialKeys(int key, int x, int y) { 
    switch (key) { 
    case GLUT_KEY_F1: // F1: Toggle between full-screen and windowed mode 
     fullScreenMode = !fullScreenMode; // Toggle state 
     if (fullScreenMode) { // Full-screen mode 
      windowPosX = glutGet(GLUT_WINDOW_X); // Save parameters for restoring later 
      windowPosY = glutGet(GLUT_WINDOW_Y); 
      windowWidth = glutGet(GLUT_WINDOW_WIDTH); 
      windowHeight = glutGet(GLUT_WINDOW_HEIGHT); 
      glutFullScreen(); // Switch into full screen 
     } else { // Windowed mode 
      glutReshapeWindow(windowWidth, windowHeight); // Switch into windowed mode 
      glutPositionWindow(windowPosX, windowPosX); // Position top-left corner 
     } 
     break; 

    case GLUT_KEY_UP: 
     if (!isCollision) 
      moveBallUp = true; 
     break; 
    case GLUT_KEY_PAGE_UP: 
     ballTSpeed *= 1.2f; 
     break; 

    } 

} 

static void display(void) { 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    if (moveBallUp) { 
     ball[1] += ballTSpeed; 
     ball[2] -= 0.02 + ballTSpeed; 
    } 

    if (ball[1] >= (cone1[1] - 0.4) && ball[1] <= cone1[1]) { 

     if (!isCollision) 

     { 
      cone1[0] -= 0.5; 
      cone1[4] -= 10.0; 
      cone1[5] += 10.0; 
      cone1[2] += -0.3; 

      cone2[0] += 0.5; 
      cone2[4] -= 10.0; 
      cone2[5] -= 10.0; 
      cone2[2] += -0.4; 

      cone3[0] += 0.5; 
      cone3[4] -= 10.0; 
      cone3[5] -= 10.0; 
      cone3[2] += -0.4; 
     } 

     isCollision = true; 
     moveBallUp = false; // stop moving the ball 

    } 

    if (resetCall) { 

     if ((ball[1] >= -2.0f && ball[1] <= -1.6f) 
       && (ball[2] >= -6.0f && ball[2] <= -5.6f)) { 
      resetCall = false; 
      isCollision = false; 

     } 

     else { 

      ball[1] -= ballTSpeed; 
      ball[2] += 0.02 + ballTSpeed; 

     } 

    } 

    glColor3d(1, 1, 0); 
    glPushMatrix(); 
    glTranslated(cone1[0], cone1[1], cone1[2]); 
    glRotated(cone1[3], cone1[4], cone1[5], cone1[6]); 
    glutSolidCone(1, 2, 50, 50); 
    glPopMatrix(); 

    glColor3d(1, 0, 1); 
    glPushMatrix(); 
    glTranslated(cone2[0], cone2[1], cone2[2]); 
    glRotated(cone2[3], cone2[4], cone2[5], cone2[6]); 
    glutSolidCone(1, 2, 50, 50); 
    glPopMatrix(); 

    glColor3d(0, 0, 1); 
    glPushMatrix(); 
    glTranslated(cone3[0], cone3[1], cone3[2]); 
    glRotated(cone3[3], cone3[4], cone3[5], cone3[6]); 
    glutSolidCone(1, 2, 50, 50); 
    glPopMatrix(); 

    glColor3d(1, 0, 0); 
    glPushMatrix(); 
    glTranslated(ball[0], ball[1], ball[2]); 
    glutSolidSphere(ball[3], ball[4], ball[5]); 
    glPopMatrix(); 
    glPushMatrix(); 
    glColor3d(0.6, 1, 0.20); 

    glBegin(GL_QUADS); 
    glVertex3f(16.0, 5.0, -25.0); 
    glVertex3f(-16.0, 5.0, -25.0); 
    glVertex3f(-6.0, -4.0, -5.0); 
    glVertex3f(6.0, -4.0, -5.0); 
    glEnd(); 
    glColor3d(1, 1, 0); 
    glBegin(GL_QUADS); 
    glVertex3f(16.0, 15.0, -25.0); 
    glVertex3f(-16.0, 15.0, -25.0); 
    glVertex3f(-16.0, -4.0, -25.0); 
    glVertex3f(16.0, -4.0, -25.0); 
    glEnd(); 

    glutSwapBuffers(); 
} 

/* Program entry point */ 

int main(int argc, char *argv[]) { 
    glutInit(&argc, argv); 
    glutInitWindowSize(windowWidth, windowHeight); // Initial window width and height 
    glutInitWindowPosition(windowPosX, windowPosY); // Initial window top-left corner (x, y) 
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); 

    glutCreateWindow("Balling Game 3d"); 

    glutReshapeFunc(resize); 
    glutDisplayFunc(display); 

    glClearColor(1, 1, 1, 1); 
    glEnable(GL_CULL_FACE); 
    glCullFace(GL_BACK); 

    glEnable(GL_DEPTH_TEST); 
    glDepthFunc(GL_LESS); 

    glEnable(GL_LIGHT0); 
    glEnable(GL_NORMALIZE); 
    glEnable(GL_COLOR_MATERIAL); 
    glEnable(GL_LIGHTING); 

    glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); 
    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); 
    glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); 
    glLightfv(GL_LIGHT0, GL_POSITION, light_position); 

    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); 
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); 
    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); 
    glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess); 
    glutTimerFunc(0, Timer, 0); // First timer call immediately 

    glutSpecialFunc(specialKeys); // Register callback handler for special-key event 
    glutKeyboardFunc(keyboard); // Register callback handler for special-key event 
    glutMainLoop(); 

    return EXIT_SUCCESS; 
} 

: 내 생각으로

x += 0.5; 
    gluLookAt(x, y, z, i, j, k, a, b, c); 
    // eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz 

카메라 뷰를 변경해야하지만 난 내가 잘못하고있는 중이 야 것을 알고있다. 어떻게하는지 말해줘?

답변

4

입력 이벤트 핸들러에서 OpenGL 함수를 호출하지 마십시오. 불행과 처형 만이 나온다.

입력 이벤트 핸들러에서 사용자 입력 데이터의 변수를 설정하고 다시 그리기를 트리거합니다. drawing 함수에서 렌더링 프로세스를 변수에서 매개 변수화하십시오.

크기 조정 핸들러를 완전히 제거 할 수 있습니다. 키보드 핸들러에서 표시 기능

static void display(void) { 
    int const width = glutGet(GLUT_WINDOW_WIDTH); 
    int const height = glutGet(GLUT_WINDOW_HEIGHT); 
    float const ar = (float) width/(float) height; 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glViewport(0, 0, width, height); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glFrustum(-ar, ar, -1.0, 1.0, 1.0, 100.0); 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    gluLookAt(view_x, view_y, view_z, target_x, target_y, target_z, up_x, up_y, up_z); 
    // eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz 

    /* ... */ 

에서 설정 뷰포트 및 프로젝션는 변수를 설정하고 당신이 말한대로 내가했던 다시 표시

void keyboard(unsigned char key, int mouse_x, int mouse_y) { 
    switch (key) { 
    case 27: // ESC key 
     exit(0); 
     break; 
    case 'r': 
     resetGame(); 
     break; 
    case 'i': 
     view_x += 0.5; 
     /* don't call gluLookAt here! */ 
    } 

    glutPostRedisplay(); 
} 
+0

을 유발하지만 작동하지 않습니다. 카메라가 변경 사항을 표시하지 않습니다. – Umair

+1

@UmairAyub : 원래 변수 이름'x'가 키보드 함수'x' 매개 변수에 의해 가려 졌기 때문입니다. 마스크를 얻지 못하도록 변수의 이름을 바꾸거나 (예 :'x :'네임 스페이스 한정자 사용) 작동합니다. – datenwolf

+1

@UmairAyub : BTW : 그리기 코드에 불필요한 glPushMatrix가있어 OpenGL 행렬 스택 오버플로가 발생합니다. – datenwolf

관련 문제