PDA

View Full Version : need to process both normal and special keys for keyUp status



technologist
12-28-2017, 09:33 AM
How do I use if (key==number){do stuff;} instead of


switch (key) {
case GLUT_KEY_LEFT : pGv->deltaAngle = 0.0f; break;//pGv->strafe_left = false; break;
case GLUT_KEY_RIGHT : pGv->deltaAngle = 0.0f;break;//pGv->strafe_right = false; break;
case GLUT_KEY_UP : pGv->deltaMove = 0.0f;break; //was deltaAngle CHANGE to DeltaAngle constantly move forward
case GLUT_KEY_DOWN : pGv->deltaMove = 0.0f;break;
case (97): std::cout<<".."; break;
}


the reason is that I want to process keyUp with both normal keys and special and they are already a mixture of if (key==) and case(key) statements. Of course if you know the better way I'm all ears. I know that if(key==) is supposed to be equivalent to case(key) switch but I can't detect the up arrow with the key==arrow number.

Thanks in advance

GClements
12-28-2017, 10:43 AM
Note that some of the GLUT_KEY_* constants used for "special" keys overlap the range of ASCII codes used for normal keys, so you can't handle both sets of keys with a single switch statement or group of if/else statements without transforming one or both types of code.

technologist
12-28-2017, 11:45 AM
Note that some of the GLUT_KEY_* constants used for "special" keys overlap the range of ASCII codes used for normal keys, so you can't handle both sets of keys with a single switch statement or group of if/else statements without transforming one or both types of code.

I want to transform all of my switch statements to, example: if (key==var) because how can keyUp take in both Ascii & GLUT_KEY_* constants.

from switch (key) {case GLUT_KEY_LEFT : pGv->deltaAngle = 0.0f; break;//pGv->strafe_left = false; break;}
I've tried to sub GLUT_KEY_LEFT with ascii, but didn't work.

Back to basics:

My "big" question is how to handle both types (Ascii values & GLUT_KEY_* constants in glutkeyUp(keyUp)). Can I call keyUp both from normal keys as well as special keys, or do the normal and special keys need there own methods -- keyUpNorm, keyUpspec?

Below, I have to decide on one or the other ascii or GLUT_KEY_constants. Or is there a better way to organize.


void keyPressed (unsigned char key, int x, int y)
{
if (key == 27)
{ delete pGv;
exit(0);}
if (key == 'a') { std::cout<<"strafe left on"<<std::endl; pGv->strafe_left = true; pGv->strafe_right = false;}
if (key == 'd') {std::cout<<"strafe right on"<<std::endl; pGv->strafe_left = false; pGv->strafe_right = true;}
if (key==37) {std::cout<<"arrow down"<<std::endl;}
}


void keyUp (unsigned char key, int x, int y)
{
if (key == 'a') { std::cout<<"strafe left off"<<std::endl; pGv->strafe_left = false; pGv->strafe_right = false;}
if (key == 'd') { std::cout<<"strafe right off"<<std::endl; pGv->strafe_left = false; pGv->strafe_right = false;}

}


Thx in advance

technologist
12-29-2017, 10:07 AM
I've got four callbacks to handle ASCII & special function keys.
AscII->detect a normal keypress (keyPressed) and (keyUp) to detect release of the ASCII key.
Keyboard ARROWs pressed are (specialkeyPress) and their release (specialkeyUp).
The four:


glutKeyboardFunc(keyPressed);
glutKeyboardUpFunc(keyUp);
glutSpecialFunc(specialkeyPress);
glutKeyboardUpFunc(specialkeyUp);

The problem is that when I depress a "normal" key I am getting a special key call back. I am trying to keep the ASCII and special key actions separate. And I don't understand the behavior described.


keyPressed ASCII called
strafe left on
keyPressed ASCII called
specialkeyUp GLUT_KEY_* constants called
specialkeyUp GLUT_KEY_* constants called
keyPressed ASCII called
strafe left on
specialkeyUp GLUT_KEY_* constants called

Another example: get special key up function after pressing ASCII:


keyPressed ASCII called
strafe right on
specialkeyUp GLUT_KEY_* constants called

A small amount of understanding will take me a long way here.

Expanded code od the 4 methodologies(keypress & release methods):



void keyPressed (unsigned char key, int x, int y)
{
std::cout<<"keyPressed ASCII called"<<std::endl;
if (key == 27)
{ delete pGv;
exit(0);}
if (key == 'a') { std::cout<<"\tstrafe left on"<<std::endl; pGv->strafe_left = true; pGv->strafe_right = false;}
if (key == 'd') {std::cout<<"\tstrafe right on"<<std::endl; pGv->strafe_left = false; pGv->strafe_right = true;}

}


void keyUp (unsigned char key, int x, int y)
{
std::cout<<"keyUp ASCII called"<<std::endl;
if (key == 'a') { std::cout<<"strafe left off"; pGv->strafe_left = false; pGv->strafe_right = false;}
if (key == 'd') { std::cout<<"strafe right off"; pGv->strafe_left = false; pGv->strafe_right = false;}

}

void specialkeyPress(int key, int xx, int yy) {
std::cout<<"specialkeyPress GLUT_KEY_* constants called"<<std::endl;
switch (key)
{
case GLUT_KEY_LEFT :
case GLUT_KEY_RIGHT :
case GLUT_KEY_UP :
case GLUT_KEY_DOWN : break;

}
}

void specialkeyUp (unsigned char key, int x, int y)
{
std::cout<<"\tspecialkeyUp GLUT_KEY_* constants called"<<std::endl;
switch (key) {
case GLUT_KEY_LEFT : pGv->deltaAngle = 0.0f; break;//pGv->strafe_left = false; break;
case GLUT_KEY_RIGHT : pGv->deltaAngle = 0.0f; break;//pGv->strafe_right = false; break;
case GLUT_KEY_UP : pGv->deltaMove = 0.0f; pGv->angle = 9000; break; //was deltaAngle CHANGE to DeltaAngle constantly move forward
case GLUT_KEY_DOWN : pGv->deltaMove = 0.0f; break;

}

}


Why are my callbacks being called in this manner?

single switch statement or group of if/else statements without transforming one or both types of code.
I think it was answered here to an extent; just need further understanding.

Alfonse Reinheart
12-29-2017, 11:47 AM
glutKeyboardUpFunc(keyUp);
glutKeyboardUpFunc(specialkeyUp);


You can only have one function registered for each callback. This replaces your `keyUp` function.

You probably meant `glutSpecialUpFunc`.

Lastly, it should be noted that FreeGLUT's input system is pretty terrible overall. If you're doing anything that requires something more than the simplest kinds of inputs, GLFW is a far better tool than FreeGLUT. FreeGLUT is designed for basic tech-demo kinds of things; GLFW is designed for more serious applications.

technologist
12-31-2017, 04:09 PM
You can only have one function registered for each callback. This replaces your `keyUp` function. Got it fixed with your help, thanks.



Lastly, it should be noted that FreeGLUT's input system is pretty terrible overall. If you're doing anything that requires something more than the simplest kinds of inputs, GLFW is a far better tool than FreeGLUT. FreeGLUT is designed for basic tech-demo kinds of things; GLFW is designed for more serious applications.

For now , you hit it on the head. I'm using the GLUT FPS for learning. I'm going to migrate towards contemporary OpenGL once I cross some topics issues off my list. I'll look at GLFW/Glew for sure.



You probably meant `glutSpecialUpFunc`

Thanks, the glutSpecialUpFunc got everything working/included correctly.
I was then able to organize the keys effectively. Key presses and release all working normally.