LWJGL 3/ GLFW - glGetKey un glGetMouseButton - Polling oder Cache ?

Hallo,

LWJGL 3 ist nun schon eine Weile verfügbar und so habe ich nun auch begonnen mich damit zu beschäftigen und meine Projekte zu updaten.
Allerdings ist mir teilweise der richtige Umgang mit den Input Callbacks und den glfwGet… Methoden nicht ganz klar.
Callbacks sind die Events und werden aufgerufen, falls sich etwas ändert. Meistens nur wenn glfwPollEvents() aufgerufen wird, teilweise kann es aber auch jederzeit passieren.
Mit den Get/Polling-Methoden kann jederzeit der aktuelle Status, z.B. eines Keys abgefragt werden.

In dem offizielen GLFW-Guide wird empfohlen immer falls verfügbar die Callbacks und nicht die Polling Methoden zu verwenden.

Where a callback is provided, that is the recommended way to receive that kind of input. The more you can use callbacks the less time your users’ machines will need to spend polling.

Vor allem für kontinuierliche Aktion, wie z.B. nach vorne laufen solange „W“ gedrückt bleibt ist es jedoch etwas umständlich nur mit den Callbacks/Events zu arbeiten.
Nun steht in der GLFW-Input-Guide glfwGetMouseButton und glfwGetKey, dass nur gepeicherte Zustände zurückgegeben werden würden und keine neue Anfrage an das System gestellt wird. Danach wird aber von der Funktion als „Polling“ gesprochen.

This function only returns cached key event state. It does not poll the system for the current state of the key.
Whenever you poll state, you risk missing the state change you are looking for. …

Daher frage ich mich ob diese beiden Funktionen jetzt zu dem langsamen Polling gehören, dass man meiden sollte, oder ob der Gebrauch doch OK ist.

MfG,
~Oneric

das verstehe ich nicht.
ein keycallback bekommt immer die action übergeben. 1 für pressed, 0 für released und 2 für „wird gehalten“.
pressed und released reicht doch schon aus, um eine aktion zu starten beziehungsweise abzubrechen?..

*** Edit ***

achso und die methoden die du ansprichst, ich kenne mich da zwar nicht genug aus,
aber ich würde mal stark vermuten dass die auf information des letzten glfwPollEvents() zurückgreifen.

Auch wenn ich mich (im Gegensatz zu @Fancy räusper :smiley: ) noch nicht mit LWJGL 3 beschäftigt habe, ging es vermutlich darum, dass bei solchen Kontinuierlichen Aktionen ja ein flag gesetzt werden muss. Es ist ja nicht so

void keyPressed() {
    moveABit();
}

sondern

boolean moving = false;
void keyPressed() {
    moving = true;
}
void keyReleased() {
    moving = true;
}
void gameLoop() {
    double dt = computeDelta();
    if (moving) moveABit(dt);
}

Warum callbacks dafür „umständlich“ sein sollen, erschließt sich mir aber nicht. Genau das will man ja: Egal wann, egal, wie, egal wo: Beim Drücken wird ein flag gesetzt…

Moin,

im Detail hab ich mir das auch noch nicht angesehen, sondern einfach den GLFWKeyCallback genutzt. Letztendlich so wie Marco das angedeutet hat (nur, dass der GLFWKeyCallback eine andere Methodensignatur hat).

Mit den Callbacks scheint mir das in LWJGL/GLFW jetzt auch der bevorzugte Weg zu sein. Nicht nur beim Input Handling, sondern z.B. auch um auf Größenänderungen des Fensters zu reagieren.

Gruß
Fancy

Hallo,

erstmal danke für die Antworten :slight_smile:

Eben :smiley: , im Vergleich zu glfwGetKey ist es umständlicher für jede Aktion Flags zu setzen, wenn auch nicht besonders kompliziert. Jeder Aktion eine eigene flag-Variable zuzuweisen wäre aber wohl etwas unflexible für spätere Ergänzungen, auch in Form von Mods/Plugins. Man könnte natürlich selbst Informationen über den Zustand der Keys speichern, aber wenn GLFW das schon selbst machen sollte und kein Performanceverlust damit einhergeht, wäre es ja nicht nötig es noch ein weiteres Mal zu speichern.
Das könnte so aussehen:

private HashMap<Integer, Boolean> keyStates = new HashMap<>(); //Für kontinuierliche Aktionen

void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    //Evtl. vorher filtern um ungenutze KeyStates nicht unnötig zu speichern
    keyStates.put(key, action != GLFW_RELEASE);

    //Anschließend einmalige Event-Aktionen
}

public boolean isKeyPressed(int key) {
   return keyStates.get(key) == true; //Bei Bedarf könnte man es auch so ändern, dass zwischen PRESS und REPEAT unterschieden wird
}

Ob dabei auch der Zustand der Shift, ALt und Strg/Ctrl Tasten gespeichert wird weiß ich nicht.
Aber, falls GLFW das sowieso schon tun würde und es keinen Performanceverlust bringt, wäre es wie gesagt unnötig noch zusätzlich selbst keyStates zu speichern.

Ja, es wird in der Guide empfohlen die Callbacks zu nutzen, da das Polling langsamere wäre. Allerdings findet sich bei glfwGetKey und glfwGetMouse der oben zitierte Hinweis der unklar lässt ob diese Methoden jetzt zu dem langsamen Polling gehören, oder nicht. Das ist es was mich verunsichert

This function only returns cached key event state. It does not poll the system for the current state of the key.
Whenever you poll state, you risk missing the state change you are looking for. …

MfG,
~Oneric

ähm… ich verstehe dein problem immer noch nicht ganz, aber alt strg und shift
informationen sind in “mods” versteckt. habs mal ausprobiert weiß aber nicht mehr
welche zahl für was stand… irgendetwas in die richtung shift = 0 strg = 1 und so weiter
aber probier einfach aus um herauszufinden welche zahlen da für was stehen.

Huch…
Bisher dachte ich GLFW_REPEAT würde für mehrfaches runterdrücken der Teaste sthene und nicht fürs Halten einer gedrückten Taste.
Den Teil deiner Antwort

1 für pressed, 0 für released und 2 für „wird gehalten“.

muss ich das letzte mal wohl überlesen haben, war wohl noch nicht ganz wach :smiley:

Aber dann ist es natürlich überhaupt kein Problem mehr, danke für den Hinweis :slight_smile:

MfG,
~Oneric