#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 просто заставит вас повторить это поведение самостоятельно.