Sort of, you wouldn't want to call your keyboard handler with glutKeyboardFunc(..) though.
Here is a more complete example.
cpp
int keyState[119]; // 119 keys, 0 = up, 1 = down
...
const int KEY_UPPER_A = 21;
const int KEY_UPPER_B = 22;
...
void keyDown(unsigned char key, int x, int y)
{
switch (key)
{
case 65:
keyState[KEY_UPPER_A] = 1;
break;
case 66:
keyState[KEY_UPPER_B] = 1;
break;
...
}
void keyUp(unsigned char key, int x, int y)
{
switch (key)
{
case 65:
keyState[KEY_UPPER_A] = 0;
break;
case 66:
keyState[KEY_UPPER_B] = 0;
break;
...
}
void keyInit()
{
glutKeyboardFunc(keyDown);
glutKeyboardUpFunc(keyUp);
}
// Call me from within your game/render/logic loop.
void keyHandler()
{
if (keyState[KEY_UPPER_A])
{
// Do something.
}
if (keyState(KEY_UPPER_B)
{
// Do something else.
}
}
They keyUp/keyDown functions are callbacks, you register them with GLUT (ie. the code in keyInit(..)) and it calls them for your whenever a key is pressed or released.
You want to keep the code that updates the table (ie. which keys are currently pressed down) separate from the code that performs actions based upon which keys are pressed down.
On a side note, GLUT considers keys like the arrow keys to be "special" and you need to use the glutSpecialFunc(..)/glutSpecialUpFunc(..) functions to listen for them.