# T4.2 Keyboard Interaction

We are preparing to use arrow keys and + - to control the pan, pitch and zoom of our camera.

(You can also use other keys, such as WASD)

## Outline

We are going to use GLFW to bind keyboard event handling functions.

1. First we are going to write our keyboard event handling call back function.
2. Second, we are going to register that function to GLFW.

## GLFW key\_callback

We are going to write the GLFW key\_call back function which takes four parameters as follows:

* `GLFWwindow* window`: A pointer to the GLFW window that received the event. This allows you to differentiate between keyboard events in multiple windows if your application uses more than one.
* `int key`: The keyboard key that was pressed or released. This is a GLFW key token (e.g., `GLFW_KEY_E`, `GLFW_KEY_ESCAPE`). If GLFW lacks a token for a specific key, this value will be `GLFW_KEY_UNKNOWN`.
* `int scancode`: The system-specific scancode of the key. Scancodes are unique for each key, regardless of whether it has a key token, and are consistent over time on a given platform.
* `int action`: The action that occurred with the key. This will be one of `GLFW_PRESS` (key was pressed), `GLFW_RELEASE` (key was released), or `GLFW_REPEAT` (key is being held down and repeating).
* `int modes`: A bit field describing which modifier keys (e.g., Shift, Ctrl, Alt) were held down during the event. You can check for specific modifiers using bitwise operations with constants like `GLFW_MOD_SHIFT`, `GLFW_MOD_CONTROL`, etc.

In this example, what we need is only the "key".

Try to check <https://www.glfw.org/docs/3.3/group__keys.html> for key names.

To deal with the "+" key which shares a key with "=", we need to check if  the shift key is pressed ( the GLFW\_MOD\_SHIFT bit is set). The key name is GLFW\_KEY\_EQUAL.

```cpp

void key_callback(GLFWwindow* window, int key, int scancode, int action, int modes)
{
    if (action == GLFW_PRESS) {
    
        if (GLFW_KEY_LEFT == key) {
            // TODO: pan left, rotate around Y, CCW
        } else if (GLFW_KEY_RIGHT == key ) {
            // TODO: pan right, rotate around Y, CW
        } else if (GLFW_KEY_UP == key) {
            // TODO: tilt up, rotate around X, CCW
        } if (GLFW_KEY_DOWN == key) {
            // TODO: tilt down, rotate around X, CW
        } else if ( (GLFW_KEY_KP_ADD == key) || 
            (GLFW_KEY_EQUAL == key) && (modes & GLFW_MOD_SHIFT) ) {
            // TODO: zoom in, move along -Z
        } else if ( (GLFW_KEY_KP_SUBTRACT == key ) || (GLFW_KEY_MINUS == key) ) {
            // TODO: zoom out, move along -Z
        } else if (GLFW_KEY_R == key) {
            // TODO: reset
        }
}
```

## Registr key\_callback

In main(), add glfwSetKeyCallback()  after glfw window creation to register the key event callback function.

```cpp
    // create a GLFW window
    window = glfwCreateWindow(640, 640, "Hello OpenGL 2", NULL, NULL);
    glfwMakeContextCurrent(window);

    // register the key event callback function
    glfwSetKeyCallback(window, key_callback);
```
