Динамически изменять параметры gluPerspective()?

Чтобы понять, как работает gluPerspective(), я хотел бы динамически изменять его параметры (первый — угол) с помощью стрелок клавиатуры.

Как я могу заставить его работать, и это проблема, когда матричный режим установлен в функции обратного вызова?

Вот код, который у меня есть до сих пор, но ничего не происходит при нажатии стрелки влево или вправо:

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

person yooo123    schedule 12.11.2017    source источник


Ответы (2)


Функция, переданная glutReshapeFunc, вызывается только при изменении размера окна. Таким образом, новые параметры для gluPerspective используются только после этого. Вы можете, например, вызвать функцию вручную после того, как отрегулировали угол:

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));
}
person BDL    schedule 12.11.2017

Вы не сообщили функции обратного вызова дисплея обновить новый угол.
Вызовите функцию glutPostRedisplay() в последней функции клавиатуры, чтобы увидеть обновленный угол.

person Utkarsha Khanal    schedule 07.03.2019