Question

I am working on getting keyboard input to work in GLUT, I am having quite the time. Basically my problem is the operations I've set to be associated with certain keys do not work properly.

These are my declaration and definition of the glutKeyboardFunc and 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; 
}

The goal with these is simply to set the key to true when it's pressed and false when it is released.

I then define some things to do based on which keys are pressed:

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 is then called in my 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();
}

If you're still with me, my main function along with some variables look like this:

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

The for loop I've included in the main function resets the entire keyStates array to 0. Which ultimately should have the same effect as glutKeyboardUpFunc but for some reason the keyOperations aren't performed properly without this for loop.

I have searched for some code examples similar to mine using glutKeyboardUpFunc but it hasn't gone well in terms of finding something significantly similar. I know that operations inside glutKeyboardUpFunc and glutKeyboardFunc are performed just by inserting some sort of exit command when it gets to that piece of code.

This code should compile in its current form if you remove glutReshapeFunc(reshape);

My question specifically is: What about this for loop causes the desired rotation effect that doesn't seem to happen without it? And if you know, how can I remedy this?

Also, the rotation on a blank plane by pressing a and d keys is not noticeable but pressing w and s should give some rotation. You may need to change the amounts that xspeed and yspeed have in order to make it rotate faster/slower depending on your computer's speed.

Was it helpful?

Solution

What about this for loop causes the desired rotation effect that doesn't seem to happen without it?

It's called "initializing your data". Any allocated memory is uninitialized (and therefore contains random garbage), unless the type has a constructor. And bool does not. You're default-initializing this array of bool, which will give them all garbage values.

Your loop gives them all an explicit value. Namely, false.

The correct way to do what you're doing is this:

bool keyStates[256] = {false};

C++ is not Java; you don't have to dynamically allocate everything. This creates a static array of 256 bool elements. The {false} part initializes the first one to false; by C++ rules, all of the rest of the members are value-initialized (different from default-initialized). A value-initialized bool contains false. So this initializes all of our bools.

No need for a loop.

BTW, you may want to consider ditching FreeGLUT for GLFW. It stores a proper list of key states for you, so you don't have to manage it yourself. If you're doing something like this, you're probably making an application that you'll run into other problems using FreeGLUT for.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top