gluLookAt()无法按预期工作

时间:2013-07-08 08:26:28

标签: c++ eclipse opengl glut

我使用Eclipse在OpenGL中创建了一个保龄球游戏。

现在我想在按下按键时更改相机的视图。

但是当我按下x按钮时,一切都消失了。

这里是我们的代码: -

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

在代码案例'i'中:

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

相机视图应该像我猜的那样改变,但我知道我做错了。请告诉我怎么做?

1 个答案:

答案 0 :(得分:4)

永远不要从输入事件处理程序调用OpenGL函数。只有痛苦和绝望才会出现。

在输入事件处理程序中,从用户输入数据中设置变量并触发重绘。在绘图功能中,从这些变量中参数化渲染过程。

您可以完全删除调整大小处理程序。在显示功能中设置视口和投影

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