glutPassiveMotionFunc und glutWarpMousePointer

8

Ich möchte meinen eigenen Cursor in einem OpenGL / GLUT-Fenster implementieren. Die übliche Methode besteht darin, den Cursor einzufrieren (damit er nicht auf die Ränder des Bildschirms trifft) und die Position selbst zu verfolgen. Ich kann den Bildschirmcursor mit

unsichtbar machen %Vor%

und dann innerhalb meines glutPassiveMotionFunc Callbacks den Zeiger mit

in die Mitte des Fensters bewegen %Vor%

Das funktioniert so, dass der Zeiger in der Mitte des Fensters bleibt. Das Problem ist, dass, wenn ich die 'OpenGL' Maus zeichne (innerhalb des glutDisplayFunc () Callback) es extrem ruckelt.

Ich habe online gesucht und festgestellt, dass es ein Problem geben kann, bei dem glutWarpPointer () den glutPassiveMotionFunc-Callback erneut aufruft, was zu einer Schleife führt, aber das scheint hier nicht zu passieren.

Ich bin auf Mac OS X und habe einen Post gefunden, der besagt, dass CGDisplayMoveCursorToPoint dafür besser geeignet ist. Der Aufruf von CGDisplayMoveCursorToPoint funktioniert, aber die Bewegung ist immer noch sehr ruckelig (und ich bekomme anscheinend viele Ereignisse, bei denen x und y beide 0 sind). Auf jeden Fall möchte ich, dass dies auch unter Linux funktioniert, daher ist eine Mac-Only-Lösung nicht ideal (aber ich bin in Ordnung, wenn ich verschiedene Dinge auf den verschiedenen Systemen machen muss).

Ich habe das auf einen Testfall reduziert.

%Vor%     
Steven Canfield 08.04.2009, 00:01
quelle

6 Antworten

6

Danke aib für die Tipps. Du hast mich in die Zerlegung von glutWarpPointer eingeweiht und es wurde offensichtlich, was vor sich ging. Das Aufrufen von glutWarpPointer CGPostMouseEvent führt zu einer Reihe von unsinnigen Ereignissen (und es gibt keine Möglichkeit, sie zu überspringen, da Sie nur Mausereignisse einmal pro Frame erhalten, die neuen "echten" Ereignisse werden verspätet sein). Die Lösung, die ich gefunden habe, besteht darin, sich nur zu verzerren, wenn sich der Zeiger am Rand des Bildschirms befindet (der Punkt besteht ja darin, so zu tun, als ob der Punkt niemals den Rand des Bildschirms erreichen könnte). In jedem Fall ist hier der Code.

%Vor%     
Steven Canfield 08.04.2009, 15:55
quelle
5

Ich habe einen besseren Ansatz gefunden. Was passiert, ist, dass das Betriebssystem die Ereignisse für etwa 0,25 Sekunden unterdrückt, nachdem Sie die Maus verzerrt haben. Rufen Sie stattdessen einfach an:

%Vor%

Dann wird alles glatt ohne Stottern.

Sie müssen möglicherweise Folgendes einschließen:

%Vor%

und fügen Sie dieses Framework Ihrem Projekt oder Ihren Compiler-Optionen hinzu.

Beachten Sie, dass Sie möglicherweise ein Ereignis erhalten, wenn sich die Maus in die Mitte des Bildschirms bewegt. Daher ignoriere ich ein Ereignis, wenn es sich in der Mitte des Bildschirms befindet.

    
Nathan S. 16.03.2011 21:13
quelle
0

Ich habe nicht viel Erfahrung mit Überangebot, außer für Rotbuch-Beispiele, aber ist es ruckelnd wegen dem, was Sie für den Cursor zeichnen, oder wie oft Sie es zeichnen? Wenn Sie nur einen Punkt zeichnen, wo der Cursor OpenGL-Aufrufe verwenden soll, ist es immer noch ruckelnd? Könnte Ihr Timing-Code ein Problem sein?

Welchen Code rufen Sie auf, um den Zeiger bei jedem Tick zu aktualisieren? Ich nehme an, es ist nicht der Code aufgeführt, da Sie den Mittelpunkt jedes Mal berechnen würden, anstatt auf ein Größenänderungs-Ereignis.

Ich entschuldige mich dafür, hier blind zu antworten (d. h. mit eingeschränkter Erfahrung im Bereich der Überschwemung).

    
Bernard 08.04.2009 01:29
quelle
0

Ich vermute hier, aber ich vermute, dass die Bewegung ruckelt, weil der Cursor in der Zeichenfunktion Ihrer Anwendung (display ()) gezeichnet wird, anstatt vom Betriebssystem behandelt zu werden.

Ein normaler Mauszeiger wird auf der Treiberebene gehandhabt, indem das Cursorbild mit dem Bildpufferinhalt XOR-verarbeitet wird - also blitzschnell und vom OS in einer Interrupt-Serviceroutine mit sehr hoher Priorität gehandhabt wird (um die Illusion der Reaktionsfähigkeit aufrechtzuerhalten) ).

Wenn Sie es selbst zeichnen, unterliegen Sie dem regulären Zeitplanungsmechanismus Ihres Betriebssystems. gehe durch den regulären Clear & Amp; zeichne das ganze Fenster rigamarole neu. In diesem Fall ist es schnell, aber nicht so schnell wie wir es mit dem Mauszeiger gewohnt sind.

Kurz gesagt, ich bin mir nicht sicher, ob Sie jemals erreichen werden, dass es so schnell ist, wie Sie es erwarten (besonders, da Ihre Display-Funktion und App-Logik komplexer wird).

Viel Glück!

    
Drew Hall 08.04.2009 02:21
quelle
0

Berechnen Sie die Bewegung der Maus über ein paar Frames? Ich kann meinen Code für mein vorheriges Projekt nicht finden, weil ich bei der Arbeit bin. Aber ich denke, ich habe die Mausbewegungen über ein paar Frames zuvor gemittelt Ich tat, dass die Bewegung sehr ruckartig war.

    
Craig 08.04.2009 03:08
quelle
0

Könnte es sein, dass Sie Puffer in einem nicht doppelt gepufferten Fenster austauschen?

Ihr Beispiel funktioniert nicht auf meinem Win32-System, wenn ich GLUT_DOUBLE nicht zu glutInitDisplayMode () hinzufüge.

Bearbeiten:

Sie haben Recht. Der Aufruf von glutWarpPointer () aus der Bewegungsfunktion scheint eine Schleife auf meinem [win32] -System zu verursachen. Der Timer bekommt nicht einmal eine Chance zu schießen, außer ich klicke auf einen Knopf oder etwas. Ich wette, dass die Nachrichtenwarteschlange mit Bewegungsereignissen überflutet wird.

Der Aufruf der Anzeige () rechts von der Bewegungsfunktion scheint ebenfalls nicht zu funktionieren - diesmal kann keine Bewegung registriert werden.

Die einzige Möglichkeit, Ihr Beispiel zum Laufen zu bringen, bestand darin, den passiven Bewegungsrückruf zu einem aktiven Bewegungsrückruf zu ändern und display () direkt von dieser Funktion aus aufzurufen. Ich weiß, das ist weit entfernt von dem, was du ursprünglich beabsichtigt hast, aber zumindest habe ich auf diese Weise eine sanfte Bewegung bekommen.

Haben Sie versucht, Ihre display updates mit einem glutIdleFunc () auszulösen? Es funktioniert möglicherweise immer noch nicht mit einer überfluteten Nachrichtenwarteschlange, aber es kann einen Versuch wert sein. Sie könnten auch untersuchen, ob Sie die Maus mit einem API-Aufruf erfassen, anstatt den Cursor bei jeder Bewegung manuell in die Mitte des Fensters zu bewegen.

    
aib 08.04.2009 12:57
quelle

Tags und Links