Input
OkInput reads the keyboard and mouse each frame and exposes both an edge/level query API and a digested OkInputState. You usually reach it through OkCore::getInput() inside the step callback. Keys are referenced through the platform-independent OkKey enum (see input/keys.hpp).
OkInput methods
| Method | Purpose |
|---|---|
bool isKeyJustPressed(OkKey key) const |
True only on the frame the key goes down. |
bool isKeyHeld(OkKey key) const |
True while the key is held. |
bool isKeyJustReleased(OkKey key) const |
True only on the frame the key is released. |
OkInputState getState() const |
The digested per-frame input state. |
void injectKey(OkKey key, double durationSeconds) |
Synthesize a key press (used to drive the app programmatically). |
void setPhysicalInputEnabled(bool enabled) |
Enable/disable physical keyboard/mouse input. |
void setCursorCaptured(bool captured) |
Capture (hide + lock for mouse-look) or release the OS cursor. |
void setPointerLockOnClick(bool enabled) |
Whether a click may take the pointer at all (default on). |
bool isCursorCaptured() const |
Whether the cursor is currently captured. |
void setTextCapture(bool captured) |
Text capture (the console): the normal accessors and getState() report nothing while set, so typing cannot trigger gameplay keys. |
bool isKeyJustPressedRaw/isKeyHeldRaw(OkKey) |
Variants that ignore the text-capture flag (console internals). |
void onChar(unsigned int codepoint) |
Queue a typed character (fed by the GLFW char callback; printable injected keys also land here while captured). |
std::string drainChars() |
Return and clear the characters typed since the last call. |
Mouse cursor (pointer lock)
Mouse-look uses a pointer-lock model rather than holding the cursor captured for the whole session:
- The app starts with a normal OS cursor, so the window can be moved (title bar), sent to another desktop, and the OS chrome used normally.
- Clicking inside the render area captures the cursor (hidden + locked) and enables mouse-look. Clicks on the title bar / OS chrome are not delivered to the engine, so they keep working.
- ESC releases the cursor (browser style). When the cursor is already released, ESC sets
exitinstead (the app's quit request). - Losing window focus releases the cursor automatically (frees the OS pointer and, on macOS, restores system-wide mouse acceleration); the user clicks back into the view to resume mouse-look.
- With physical input disabled (
setPhysicalInputEnabled(false), e.g.--no-input) the cursor is never captured; drive the view through the MCPviewtool instead.
Applications that are pointed at rather than steered
The model above is what a game wants. An application whose cursor is the
instrument -- one where clicking is how things are chosen -- wants the
opposite, and setPointerLockOnClick(false) gives it: no click ever
takes the pointer, and the cursor stays on screen for good.
It has to be a deliberate choice, because it is a trade. Mouse-look reads the locked pointer's motion, so switching pointer lock off switches mouse-look off with it; a tool that does this drives its camera from keys, or from a drag it interprets itself.
Without it the first click is the last one the user can aim: the cursor disappears on the way in, and every click after that is made blind at a window that no longer shows where the pointer is.
OkCore::getInput()->setPointerLockOnClick(false);
The frame's mouse pan delta (panX / panY) follows the same rule from
the other side. It is fed while the cursor is captured — or, in an
application that has switched capture off altogether, always. Otherwise
a delta that waited for a capture which never comes would never arrive,
and every pan-style controller would sit still in exactly the kind of
application that most wants one. Applications that leave capture on are
unaffected: for them the condition is still "captured", so a mouse
crossing the window before any click moves nothing.
Mouse-look keeps needing the capture either way. A free cursor aimed at a menu would be swinging the view along behind it.
OkInputState fields
getState() returns a struct with ready-to-use flags. Movement: forward, backward, strafeLeft, strafeRight, plus the vertical nudge moveUp / moveDown (E / Q held). Rotation: turnLeft, turnRight, turnUp, turnDown. Mouse pan: panX / panY, the frame's raw mouse pixel delta (accumulated by the cursor callback while the cursor is captured, or always when the application has switched capture off; consumed by pan-style controllers). Edge-triggered actions (true only on the frame first pressed): action1, action2, action3, action4. Camera selection: changeCamera (-1 if none). And exit, set when the user asks to quit (ESC while the cursor is already released; a captured cursor consumes ESC to release first).
Example
void stepCallback(float deltaTime) {
OkInput *input = OkCore::getInput();
OkInputState state = input->getState();
if (state.exit) {
OkCore::askForExit();
return;
}
OkCamera *camera = OkCore::getCamera();
OkPoint forward = camera->getRotation().getForwardVector();
if (state.forward) {
camera->move(forward.x() * deltaTime,
forward.y() * deltaTime,
forward.z() * deltaTime);
}
}