Проблемы с вводом с клавиатуры OpenGL / Glut - PullRequest
1 голос
/ 19 февраля 2020

У меня есть задание нарисовать пирамиду на экране, а затем повернуть ее после нажатия клавиши «k» на клавиатуре. Все работает нормально, кроме вращающейся части, так как программа, кажется, не замечает, что я нажимаю клавишу. Код выглядит следующим образом:

void changeSize(int w, int h) {

    if(h == 0)
        h = 1;

    float ratio = w * 1.0 / h;

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    glViewport(0, 0, w, h);

    // Set perspective
    gluPerspective(45.0f ,ratio, 1.0f ,1000.0f);

    // return to the model view matrix mode
    glMatrixMode(GL_MODELVIEW);
}

void renderScene(void) {

    // clear buffers
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // set the camera
    glLoadIdentity();
    gluLookAt(5.0,5.0,5.0,
              0.0,0.0,0.0,
              0.0f,2.0f,0.0f);

    // put the geometric transformations here

    // put drawing instructions here

    glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);

    glBegin(GL_LINES);
        glColor3f(1.0f, 0.0f, 0.0f);
        glVertex3f(-100.0f, 0.0f, 0.0f);
        glVertex3f( 100.0f, 0.0f, 0.0f);

        glColor3f(0.0f, 1.0f, 0.0f);
        glVertex3f(0.0f, -100.0f, 0.0f);
        glVertex3f(0.0f, 100.0f, 0.0f);

        glColor3f(0.0f, 0.0f, 1.0f);
        glVertex3f(0.0f, 0.0f, -100.0f);
        glVertex3f(0.0f, 0.0f, 100.0f);
    glEnd();

    //triangulos da base
    glBegin(GL_TRIANGLES);
        glColor3f(255.0f,255.0f,255.0f);
        glVertex3f(1.0f,0.0f,1.0f);
        glVertex3f(-1.0f,0.0f,-1.0f);
        glVertex3f(-1.0f,0.0f,1.0f);
    glEnd();

    glBegin(GL_TRIANGLES);
        glVertex3f(1.0f,0.0f,1.0f);
        glVertex3f(1.0f,0.0f,-1.0f);
        glVertex3f(-1.0f,0.0f,-1.0f);
    glEnd();

    //triangulos das faces

    glBegin(GL_TRIANGLES);
        glVertex3f(1.0f,0.0f,1.0f);
        glVertex3f(0.0f,2.0f,0.0f);
        glVertex3f(-1.0f,0.0f,1.0f);
    glEnd();

    glBegin(GL_TRIANGLES);
        glVertex3f(1.0f,0.0f,-1.0f);
        glVertex3f(0.0f,2.0f,0.0f);
        glVertex3f(1.0f,0.0f,1.0f);
    glEnd();

    glBegin(GL_TRIANGLES);
        glVertex3f(1.0f,0.0f,-1.0f);
        glVertex3f(0.0f,2.0f,0.0f);
        glVertex3f(-1.0f,0.0f,-1.0f);
    glEnd();

    glBegin(GL_TRIANGLES);
        glVertex3f(-1.0f,0.0f,-1.0f);
        glVertex3f(0.0f,2.0f,0.0f);
        glVertex3f(-1.0f,0.0f,1.0f);
    glEnd();

    // End of frame
    glutSwapBuffers();
}

// write function to process keyboard events

void rotate (unsigned char key, int x, int y) {
    if (key == 'k') 
        glRotatef(45,1.0,1.0,0.0);

        glutPostRedisplay();
}

int main(int argc, char **argv) {

    // init GLUT and the window
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH|GLUT_DOUBLE|GLUT_RGBA);
    glutInitWindowPosition(100,100);
    glutInitWindowSize(1200,1200);
    glutCreateWindow("CG@DI-UM");

    // Required callback registry 
        glutDisplayFunc(renderScene);
        glutReshapeFunc(changeSize);


    // put here the registration of the keyboard callbacks
        glutKeyboardFunc(rotate);

    //  OpenGL settings
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);

    // enter GLUT's main cycle
    glutMainLoop();

    return 0;
}

Кажется, что моя программа не замечает, что я нажимаю клавишу, даже если я. Я пробовал печатать только те клавиши, которые нажимаются, и это работает, поэтому я действительно потерян здесь.

1 Ответ

0 голосов
/ 19 февраля 2020

glRotatef, кажется, не имеет никакого эффекта в rotate, потому что glLoadIdentity() вызывается в начале renderScene. На самом деле glRotatef изменяет текущую матрицу, но когда сцена визуализируется (renderScene), тогда glLoadIdentity() загружает матрицу идентификации в текущую matrix.
В любом случае, вносить изменения в текущую матрицу в обратных вызовах событий ввода - это плохой стиль. Измените состояния и значения переменных во входных событиях и используйте эти переменные, чтобы установить текущую матрицу представления модели до визуализации сцены в renderScene.

Добавить глобальную переменную angle:

float angle = 0.0f;

Изменить значение переменной в renderScene. Например:

void rotate (unsigned char key, int x, int y) {
    if (key == 'k') {
        angle += 45.0f;
        glutPostRedisplay();
    }
}

И применить вращение к текущей матрице в renderScene:

void renderScene(void) {

    // clear buffers
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // set the camera
    glLoadIdentity();
    gluLookAt(5.0,5.0,5.0,
              0.0,0.0,0.0,
              0.0f,2.0f,0.0f);

    // apply rotation
    glRotatef(angle, 1.0f, 1.0f, 0.0f);

    // [...]

}
...