c++openglglutglu

Change parameters of gluPerspective() dynamically?


In order to understand how gluPerspective() works, I would like to change its parameters(the first one which is the angle) dynamically with the arrows of the keyboard.

How can I make it work and is it a problem when matrix mode is set in a callback function?

Here is the code I have so far, but nothing happens when left or right arrow is pressed:

double angle = 45;

void renderScene(void) {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0, 1, 1, 1);

    glBegin(GL_TRIANGLES);
    glVertex3f(-2, -2, -5.0);
    glVertex3f(2, 0.0, -5.0);
    glVertex3f(0.0, 2, -5.0);
    glEnd();

    glutSwapBuffers();
}

void keyboard(int c, int x, int y) {

    switch (c) {
    case GLUT_KEY_LEFT:
        angle -= 15;
        break;

    case GLUT_KEY_RIGHT:
        angle += 15;
        break;
    }
}

void changeSize(int w, int h) {

    // Prevent a divide by zero, when window is too short
    // (you cant make a window of zero width).
    if (h == 0)
        h = 1;
    float ratio = 1.0* w / h;

    // Use the Projection Matrix
    glMatrixMode(GL_PROJECTION);

    // Reset Matrix
    glLoadIdentity();

    // Set the viewport to be the entire window
    glViewport(0, 0, w, h);

    // Set the correct perspective.
    gluPerspective(angle, ratio, 1, 1000);

    // Get Back to the Modelview
    glMatrixMode(GL_MODELVIEW);
}

int main(int argc, char **argv) {
    glutInit(&argc, argv);

    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowPosition(200, 300);//optional
    glutInitWindowSize(800, 600); //optional
    glutCreateWindow("OpenGL First Window");
    glutDisplayFunc(renderScene);

    glutSpecialFunc(keyboard);
    glutReshapeFunc(changeSize);

    glutMainLoop();

    return 0;
}

Solution

  • The function passed to glutReshapeFunc is only called when the window gets resized. Thus the new parameters for gluPerspective are only used after that. You can, for example, call the function manually after you have adjusted the angle:

    void keyboard(int c, int x, int y) {
    
        switch (c) {
        case GLUT_KEY_LEFT:
            angle -= 15;
            break;
    
        case GLUT_KEY_RIGHT:
            angle += 15;
            break;
        }
    
        changeSize(glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));
    }