Hello everybody,
I am pretty new to OpenGL so please try to understand me :).
I have that beautiful function
void key(unsigned char k, int x, int y)
which is posted to OpenGL in :
glutKeyboardFunc(key);
but with this function I can only detect one key being pressed at a time. How can I do it to detect multiple key presses ?
How to detect multiple key presses in OpenGL?
Quote:Original post by lordmonkeyNote that this is actually a question about Glut, which is only tangentially related to OpenGL. Regardless:
I am pretty new to OpenGL so please try to understand me :).
I have that beautiful function
void key(unsigned char k, int x, int y)
which is posted to OpenGL in :
glutKeyboardFunc(key);
Quote:but with this function I can only detect one key being pressed at a time. How can I do it to detect multiple key presses ?It will be called once each time a key is pressed. If you want to track multiple key presses, then each time the function is called, record which key was just pressed in an array (do the same with a keyup function to clear them). Then you can check the array to see all the keys which are pressed at the current time...
And just to add on be sure you read them in individual ifs and not a set of else if's otherwise it will find one key and return.
Ok, I have it working but i have 2 problems with this, but first i will explain what I implemented:
I have something like this to atore info about pressed keys :
enum key_state {NOTPUSHED, PUSHED} keyarr[127];
for my array of pushed or notpushed values for every key, then i will initialized them all with notpushed value
then:
this is my : glutKeyboardFunc(key);
void key(unsigned char k, int x, int y)
{
if(k == 'd')
keyarr[int('d')] = PUSHED;
if(k == 'w')
keyarr[int('w')] = PUSHED;
if(k == 'r')
keyarr[int('r')] = PUSHED;
glutPostRedisplay();
}
this is my : glutKeyboardUpFunc(keyup);
void keyup(unsigned char k, int x, int y)
{
if(k == 'd')
keyarr['d'] = NOTPUSHED;
if(k == 'w')
keyarr['w'] = NOTPUSHED;
if(k == 'r')
keyarr['r'] = NOTPUSHED;
glutPostRedisplay();
}
and in the main draw() function (for now i don't have any other place to put it in) I put :
if( keyarr['d'] )
tankTurretAngle--;
if( keyarr['w'] )
wheelAngle += 5;
if( keyarr['r'] )
yRot++;
and it works :) but...
1)when I press any key of defined ones there is this small 'lag' like in windows when you push and hold key while typing how can I omit that ?
2) when I release one of e.g. 3 held keys whole animation which is running thanks to that stops. how can I handle this so that the animation won't stop but only the part responsible for the released key ?
I have something like this to atore info about pressed keys :
enum key_state {NOTPUSHED, PUSHED} keyarr[127];
for my array of pushed or notpushed values for every key, then i will initialized them all with notpushed value
then:
this is my : glutKeyboardFunc(key);
void key(unsigned char k, int x, int y)
{
if(k == 'd')
keyarr[int('d')] = PUSHED;
if(k == 'w')
keyarr[int('w')] = PUSHED;
if(k == 'r')
keyarr[int('r')] = PUSHED;
glutPostRedisplay();
}
this is my : glutKeyboardUpFunc(keyup);
void keyup(unsigned char k, int x, int y)
{
if(k == 'd')
keyarr['d'] = NOTPUSHED;
if(k == 'w')
keyarr['w'] = NOTPUSHED;
if(k == 'r')
keyarr['r'] = NOTPUSHED;
glutPostRedisplay();
}
and in the main draw() function (for now i don't have any other place to put it in) I put :
if( keyarr['d'] )
tankTurretAngle--;
if( keyarr['w'] )
wheelAngle += 5;
if( keyarr['r'] )
yRot++;
and it works :) but...
1)when I press any key of defined ones there is this small 'lag' like in windows when you push and hold key while typing how can I omit that ?
2) when I release one of e.g. 3 held keys whole animation which is running thanks to that stops. how can I handle this so that the animation won't stop but only the part responsible for the released key ?
They keyboard functions are only called when you actually press or release a key, and consequently, glutPostRedisplay is only called when you actually press or release a key. You can actually get multiple key presses by holding the key down, but that is only because GLUT issues multiple callbacks if you hold it down, just like you can do in, say, notepad by holding down a key to "type" repeated keystrokes.
What you need instead is to only record the keys in the callback functions, and then use the idle callback to redisplay your scene. Thus, remove glutPostRedisplay from your keyboard callbacks, and set the idle callback like this:
The idle function is called as soon as there's nothing else to do (like handling keyboard messages), which you use to update your game logics and redisplaying the scene.
What you need instead is to only record the keys in the callback functions, and then use the idle callback to redisplay your scene. Thus, remove glutPostRedisplay from your keyboard callbacks, and set the idle callback like this:
void idle(){ glutPostRedisplay();}int main(){ ... glutIdleFunc(idle); ...}
The idle function is called as soon as there's nothing else to do (like handling keyboard messages), which you use to update your game logics and redisplaying the scene.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement