Mit GLUT die Maus im Fenster in OpenGL einfangen?


8

Ich verstehe vollkommen, dass GLUT begrenzt ist und das folgende Problem wahrscheinlich nicht mit OpenGL / GLUT gelöst werden kann, aber da ich nicht genau weiß, ob es kann oder nicht, frage ich besser einfach. Vielleicht mache ich etwas falsch oder vergesse etwas Wichtiges. Oder wahrscheinlich auch nicht und GLUT wird nicht besser.

Mein Problem ist, dass ich die Maus nicht im Fenster einfangen kann. Nun, eigentlich kann ich, der folgende Code macht genau das. Ich fange die Maus im Fenster ein und kann die Welt mit der Maus frei drehen. Das Problem? Wenn ich die Maus zu schnell bewege, komme ich aus dem Fenstergefängnis.

Gibt es einen Weg, dies mit OpenGL / GLUT zu umgehen, oder ist die einzige Option eine andere Bibliothek oder ein direkter Aufruf der Windows-API? Genug Worte, hier ist mein aktueller Code:

void processPassiveMouseMotion(int x, int y) {
    static int centerX = glutGet(GLUT_WINDOW_WIDTH) / 2;
    static int centerY = glutGet(GLUT_WINDOW_HEIGHT) / 2;

    CameraAngle.x = -1.0f * (y - centerY);
    CameraAngle.y = -1.0f * (x - centerX);

    if(CameraAngle.x != 0.0f || CameraAngle.y != 0.0f) {
        SceneCamera.Rotate(CameraAngle);
        glutPostRedisplay();

        glutWarpPointer(centerX, centerY);
    }
}

glutPassiveMotionFunc(processPassiveMouseMotion);

Antworten:


7

Nach meinem besten Wissen ist dies Windows-API-spezifisch - diese Funktionalität ist nicht einmal auf allen Plattformen vorhanden. Wenn Sie meinen Code durchsuchen möchten, finden Sie eine funktionierende Windows-Implementierung (LockMouseCursor ist der Einstiegspunkt in das Betriebssystemmodul, ClipCursor ist die eigentliche Windows-Funktion, die das Überfüllen ausführt, aber es gibt einige Besonderheiten, die diese Funktion umgeben - sollte es nicht sein zu schwer zu entziffern.)

Ich habe auch eine Linux-Implementierung in reinem X (wieder mit LockMouseCursor beginnen), aber ich habe nie eine verwendbare OSX-API dafür gefunden. Wenn Sie am Ende einen benötigen oder einen finden, überprüfen Sie meine Stackoverflow-Frage zu diesem Thema :)


Vielen Dank, ich werde diesen Beitrag als Referenz berücksichtigen. Sie haben es mit Windows-APIs zu tun, da ich vermutete, dass dies der einzig gute Weg ist, dies zu erreichen, aber ich wollte diesen Weg nicht gehen. Nicht, dass ich nicht weiß wie, denn ich mache das, was ich vorher gemacht habe, aber für das, was ich tun möchte, ist es keinen Ärger wert und es hat keine Priorität.
Rfgamaral

2

Bei einer schnellen Suche durch die GLUT-Spezifikation scheint GLUT keine Mauserfassungsfunktionen zu haben. Das Beste, was Sie tun können (wie Sie es anscheinend tun), ist, den Cursor in die Mitte zu bewegen und zu hoffen, dass der Benutzer nicht schnell genug ist (oder kein Tablet verwendet) =)

Sie können auch zu SDL oder SFML wechseln , da GLUT nur zum Testen und nicht für "echte" Software entwickelt wurde.


Obwohl ich Ihrem Kommentar im Allgemeinen zustimme, möchte ich dringend gegen SDL drängen, da oh man SDL große Probleme hat. SFML ist großartig, benutze das!
ZorbaTHut

Sie haben beide ihre Seiten, und ich mag SDL, also .. =)
Jari Komppa

1
Bitte verstehe das nicht falsch, aber dies ist das zweite Mal, dass du mir sagst, ich soll wechseln. Obwohl ich die Antwort von jedem schätze, habe ich vielleicht einen guten Grund dafür und kann nicht wechseln, wenn ich darauf bestehe, GLUT-spezifische Fragen zu stellen? Ich habe bereits gemerkt, wie GLUT saugt, aber ich muss es ertragen, es ist nicht meine Wahl. Es tut mir leid, wenn ich hart klinge, aber ich hasse es, wenn Leute darauf bestehen, ich habe dich das erste Mal "gehört".
Rfgamaral

Ich stimme Ihrer Antwort zu, weil ich diesen letzten Absatz ignoriere. :)
rfgamaral

2
Nazgulled, tut mir leid, wenn ich Dinge zu wiederholen scheine, ich verfolge nicht wirklich, wessen Fragen ich beantworte =). Außerdem werden die Leute diese Frage durch Suchen finden, und ich möchte ihnen auch antworten, nicht nur Ihnen.
Jari Komppa

2

Probieren Sie eine neuere Version von Freeglut aus. Mein v2.6 fängt den Cursor mit glutWarpPointer ab, ohne dass die Möglichkeit besteht, mit der Maus zu entkommen.


1

In meinem Fall ändern

glutWarpPointer(centerX, centerY);

zu so etwas wie

if (x != centerX || y != centerY) glutWarpPointer(centerX, centerY);

perfekt gelöst das Problem.

Das Problem wird dadurch verursacht, dass glutWarpPointer ein anderes passives Bewegungsereignis auf (centerX, centerY) auslöst, was zu einer Schleife führt und / oder die Ereigniswarteschlange überflutet. Um dies zu vermeiden, überprüfen Sie einfach, ob sich die Maus auf (centerX, centerY) befindet. Wenn ja, verziehen Sie sich nicht.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.