glutKeyboardUpFunc get вызывается без освобождения ключа

#c #opengl #glut

#c #opengl #перенасыщение

Вопрос:

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

Вот краткий пример, который я привел:

 #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <float.h>
#include <time.h>
#include <GL/glut.h>


#define DEBUG 1

/* VARI�VEIS GLOBAIS */

typedef struct {
    GLboolean doubleBuffer;
    GLint delay;
} Estado;

typedef struct {
    GLfloat x;
    GLfloat y;
    GLfloat height;
    GLfloat width;
    GLfloat y_accelaration;
} Plataforma;


//save stage coordinates
typedef struct {
    GLfloat top;
    GLfloat bottom;
    GLfloat right;
    GLfloat left;
} Screen;

Estado estado;
Screen ecra;
Plataforma plataforma;


GLfloat tab_speed = 2.0 / 20.0;
GLfloat y_accelaration = 0.001;

void Init(void) {

    struct tm *current_time;
    time_t timer = time(0);

    estado.delay = 42;
    estado.doubleBuffer = GL_TRUE;

    plataforma.height = 0.3;
    plataforma.width = 0.05;

    plataforma.y_accelaration = 0;

    plataforma.y = 0;


    // L� hora do Sistema
    current_time = localtime(amp;timer);

    glClearColor(0.3, 0.3, 0.3, 0.0);

    glEnable(GL_POINT_SMOOTH);
    glEnable(GL_LINE_SMOOTH);
    glEnable(GL_POLYGON_SMOOTH);

}

void Reshape(int width, int height) {
    GLint size;
    GLfloat ratio = (GLfloat) width / height;
    GLfloat ratio1 = (GLfloat) height / width;

    if (width < height)
        size = width;
    else
        size = height;


    glViewport(0, 0, width, height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    if (width < height) {
        ecra.left = -1;
        ecra.right = 1;
        ecra.bottom = -1 * ratio1;
        ecra.top = 1 * ratio1;
        gluOrtho2D(-1, 1, -1 * ratio1, 1 * ratio1);
    } else {
        ecra.left = -1 * ratio;
        ecra.right = 1 * ratio;
        ecra.bottom = -1;
        ecra.top = 1;
        gluOrtho2D(-1 * ratio, 1 * ratio, -1, 1);
    }

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void desenhar_plataforma(Plataforma pf) {
    glColor3f(1.0f, 0.0f, 0.0f);
    glBegin(GL_POLYGON);



    glVertex2f(pf.x - pf.width / 2, pf.y - pf.height / 2);
    glVertex2f(pf.x   pf.width / 2, pf.y - pf.height / 2);
    glVertex2f(pf.x   pf.width / 2, pf.y   pf.height / 2);
    glVertex2f(pf.x - pf.width / 2, pf.y   pf.height / 2);
    glEnd();
}


void Draw(void) {
    glClear(GL_COLOR_BUFFER_BIT);
    plataforma.x = ecra.left   0.1;
    desenhar_plataforma(plataforma);
    glFlush();
    if (estado.doubleBuffer)
        glutSwapBuffers();
}


void Key(unsigned char key, int x, int y) {
    switch (key) {

        case 'a':
            plataforma.y  = tab_speed;
            glutPostRedisplay();
            break;
        case 's':
            plataforma.y -= tab_speed;
            glutPostRedisplay();
            break;
    }
}

void KeyUp(unsigned char key, int x, int y) {

    if (DEBUG)
        printf("Key Up %cn", key);
}

int main(int argc, char **argv) {
    estado.doubleBuffer = GL_TRUE; 

    glutInit(amp;argc, argv);
    glutInitWindowPosition(0, 0);
    glutInitWindowSize(800, 600);
    glutInitDisplayMode(((estado.doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE) | GLUT_RGB);
    if (glutCreateWindow("No Man's Pong") == GL_FALSE)
        exit(1);

    Init();

    glutReshapeFunc(Reshape);
    glutDisplayFunc(Draw);

    // Callbacks de teclado
    glutKeyboardFunc(Key);
    glutKeyboardUpFunc(KeyUp);

    glutMainLoop();
    return 0;
}
  

Вот вывод при нажатии «a»:

 Key Up a             
Key Up a
Key Up a
Key Up a
Key Up a
Key Up a
Key Up a
......
  

Излишне говорить, что я не выпускаю ‘a’.

Я использую linux mint 17.3 и g , отключая повтор клавиш или устанавливая glutIgnoreKeyRepeat (true), останавливает эту проблему, но также заставляет glutKeyboardFunc выполняться только один раз за нажатие клавиши, и я действительно этого не хочу.

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

Я также скомпилировал тот же код под Windows 8.1, и нажатие клавиши срабатывает только при фактическом освобождении ключа.

Комментарии:

1. Я не понимаю вашего вопроса. Вы говорите, что ваш обратный вызов вызывается несколько раз, пока у вас нажата клавиша, но говорите, что вы не хотите, чтобы поведение glutIgnoreKeyRepeat(true) поведения вызывало обратный вызов один раз для каждого ключа. Чего ты хочешь?

2. Проблема здесь в том, что обратный вызов keyUp выполняется без фактического освобождения ключа. В Windows этого не происходит, glutKeyboardFunc вызывается несколько раз, пока клавиша нажата, но glutKeyboardUpFunc вызывается только при освобождении ключа.

3. эй, такое же поведение здесь прямо сейчас, вы нашли какое-то решение для этого? Что ж, перечитывая ваш пост, я чувствую, что что-то ужасно не так с перенасыщением, например: » чтобы иметь новый ключ, я должен иметь ключ раньше», и поэтому перенасыщение запускает keyup (что может изменить какое-то внутреннее состояние перенасыщения), а затем снова вниз (благодаря состоянию, которое теперь позволяет это), я чувствуюнапример, IgnoreKeyRepeat просто заставит вас повторить это поведение самостоятельно.