Вход Glutkeyboard не регистрируется без лишнего цикла, чтобы выручить
Я работаю над тем, чтобы заставить ввод с клавиатуры работать в GLUT, у меня достаточно времени. В основном моя проблема заключается в том, что операции, которые я установил для связи с определенными клавишами, не работают должным образом.
Это мое объявление и определение glutKeyboardFunc и glutKeyboardUpFunc:
glutKeyboardFunc(keyPressed);
glutKeyboardUpFunc(keyUp);
void keyPressed (unsigned char key, int x, int y) {
keyStates[key] = true;
}
void keyUp (unsigned char key, int x, int y) {
keyStates[key] = false;
}
Цель этого состоит в том, чтобы просто установить клавишу на true, когда она нажата, и на false, когда она отпущена.
Затем я определяю некоторые вещи на основе нажатия клавиш:
void keyOperations (void) {
if (keyStates[int('w')] || keyStates[int('W')]){
xspeed-=0.001f;
}
if (keyStates[int('s')] || keyStates[int('S')]){
xspeed+=0.001f;
}
if (keyStates[int('a')] || keyStates[int('A')]){
yspeed+=0.001f;
}
if (keyStates[int('d')] || keyStates[int('D')]){
yspeed-=0.001f;
}
if (keyStates[' ']){
yspeed=0.0f;
xspeed=0.0f;
}
}
Затем keyOperations вызывается в моем glutDisplayFunc.
void display(void) {
keyOperations();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f,-1.0f,z);
glRotatef(xrot,1.0f,0.0f,0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f);
glBegin(GL_QUADS);
glNormal3f( 0.0f, 1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f);glVertex3f(-100.0f, -0.0001f, -100.0f);
glTexCoord2f(0.0f, 1.0f);glVertex3f( 100.0f, -0.0001f, -100.0f);
glTexCoord2f(0.0f, 0.0f);glVertex3f( 100.0f, -0.0001f, 100.0f);
glTexCoord2f(1.0f, 0.0f);glVertex3f(-100.0f, -0.0001f, 100.0f);
glEnd();
xrot+=xspeed;
yrot+=yspeed;
glutSwapBuffers();
}
Если вы все еще со мной, моя основная функция вместе с некоторыми переменными выглядит так:
GLfloat xrot;
GLfloat yrot;
GLfloat xspeed;
GLfloat yspeed;
GLfloat z=-50.0f;
bool* keyStates = new bool[256];
int main (int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("Test");
for(int i=0; i<=255; i++){ //this is the odd loop I'm referring to
keyStates[i]=0;
}
glEnable (GL_DEPTH_TEST);
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
glutDisplayFunc(display);
glutIdleFunc (display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyPressed);
glutKeyboardUpFunc(keyUp);
glutMainLoop();
}
Цикл for, который я включил в функцию main, сбрасывает весь массив keyStates в 0. Что в конечном итоге должно иметь тот же эффект, что и glutKeyboardUpFunc, но по некоторым причинам операции keyOperations не выполняются должным образом без этого для цикла for.
Я искал несколько примеров кода, похожих на мой, используя glutKeyboardUpFunc, но это не помогло найти что-то значительно похожее. Я знаю, что операции внутри glutKeyboardUpFunc и glutKeyboardFunc выполняются просто путем вставки какой-либо команды выхода, когда она попадает в этот фрагмент кода.
Этот код должен скомпилироваться в его текущей форме, если вы удалите glutReshapeFunc(reshape);
Мой вопрос, в частности: как насчет этого цикла for вызывает желаемый эффект вращения, который, кажется, не происходит без него? И если вы знаете, как я могу исправить это?
Кроме того, вращение в пустой плоскости при нажатии клавиш a и d не заметно, но нажатие w и s должно дать некоторое вращение. Возможно, вам придется изменить значения, которые есть у xspeed и yspeed, чтобы он вращался быстрее / медленнее в зависимости от скорости вашего компьютера.
1 ответ
Как насчет этого цикла for вызывает желаемый эффект вращения, который, кажется, не происходит без него?
Это называется "инициализация ваших данных". Любая выделенная память неинициализирована (и, следовательно, содержит случайный мусор), если у типа нет конструктора. А также bool
не. Вы по умолчанию инициализируете этот массив bool
, который даст им все значения мусора.
Ваш цикл дает им всем явное значение. А именно ложно.
Правильный способ сделать то, что вы делаете, это:
bool keyStates[256] = {false};
C++ не является Java; Вам не нужно динамически распределять все. Это создает статический массив из 256 bool
элементы. {false}
часть инициализирует первый false
; по правилам C++ все остальные члены инициализируются значением (отличается от инициализированного по умолчанию). Инициализированное значение bool
содержит false
, Так что это инициализирует все наши bool
s.
Нет необходимости в петле.
Кстати, вы можете рассмотреть возможность отказа от FreeGLUT для GLFW. Он хранит правильный список ключевых состояний для вас, поэтому вам не нужно управлять им самостоятельно. Если вы делаете что-то подобное, вы, вероятно, создаете приложение, для которого вы столкнетесь с другими проблемами, используя FreeGLUT.