Intrappolare il mouse all'interno della finestra in OpenGL con GLUT?


8

Capisco perfettamente che GLUT è limitato e il seguente problema probabilmente non può essere risolto con OpenGL / GLUT, ma poiché non so esattamente se può o meno, è meglio che lo chieda. Forse sto facendo qualcosa di sbagliato o dimentico qualcosa di importante. O probabilmente no e GLUT non migliora di così.

Il mio problema è che non riesco a intrappolare il mouse all'interno della finestra. Bene, in realtà, posso, il codice qui sotto fa proprio questo. Intrappolo il mouse all'interno della finestra e posso usare il mouse liberamente per ruotare il mondo. Il problema? Se muovo il mouse troppo velocemente, riesco ad allontanarmi dal carcere di finestra.

Esiste un modo per aggirare questo problema con OpenGL / GLUT o l'unica opzione è un'altra libreria o effettuare direttamente alcune chiamate all'API di Windows? Basta parole, ecco il mio codice attuale:

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);

Risposte:


7

Per quanto ne so, questo è specifico dell'API di Windows: questa funzionalità non esiste nemmeno su tutte le piattaforme. Se vuoi scavare nel mio codice puoi trovare un'implementazione di Windows funzionante (LockMouseCursor è il punto di ingresso nel modulo del sistema operativo, ClipCursor è l'effettiva funzione di Windows che esegue il trapping, ma ci sono alcune bellezze che circondano quella funzione - non dovrebbe essere troppo difficile da decifrare.)

Ho anche un'implementazione Linux in puro X (di nuovo, inizia con LockMouseCursor) ma non ho mai trovato un'API OSX utilizzabile per questo. Se finisci per averne bisogno o ne trovi uno, controlla la mia domanda StackOverflow sull'argomento :)


Grazie, terrò presente questo post come riferimento. Hai a che fare con le API di Windows come sospettavo essere l'unico buon modo per raggiungere questo obiettivo, ma non ho voglia di seguire questa strada. Non che non sappia come, perché faccio come ho fatto prima, ma per quello che sto facendo, non vale la pena creare problemi e non è una priorità.
rfgamaral,

2

Con una rapida ricerca attraverso le specifiche GLUT , GLUT non sembra avere capacità di acquisizione del mouse. Il meglio che puoi fare (come sembra che tu stia facendo) è deformare il cursore al centro e sperare che l'utente non sia abbastanza veloce (o non stia utilizzando un tablet) =)

In alternativa, è possibile passare a SDL o SFML , poiché GLUT è progettato solo per i test, non per il software "reale".


Sebbene io sia d'accordo con il tuo commento in generale, voglio fortemente esortare contro SDL perché oh uomo SDL ha grossi problemi. SFML è fantastico, usalo!
ZorbaTHut

Entrambi hanno i loro lati, e mi piace SDL, quindi .. =)
Jari Komppa

1
Per favore, non sbagliare, ma questa è la seconda volta che mi stai dicendo di cambiare. Anche se apprezzo la risposta di qualcuno, se insisto a pubblicare domande specifiche su GLUT, forse ho una buona ragione per questo e non posso cambiare? Ho già capito come fa schifo GLUT, ma devo sopportarlo, non è una mia scelta. Scusate se sembro duro, ma odio quando le persone insistono in questo modo, "ti ho sentito" la prima volta.
rfgamaral,

Sto votando la tua risposta perché sto ignorando l'ultimo paragrafo. :)
rfgamaral

2
Nazgulled, scusa se mi sembra di ripetere le cose, in realtà non tengo traccia delle domande a cui rispondo =). Inoltre, le persone finiranno per trovare questa domanda attraverso le ricerche e voglio anche rispondere a loro, non solo a te.
Jari Komppa,

2

Prova una versione più recente di freeglut; La mia v2.6, intrappola il cursore con glutWarpPointer senza alcuna possibilità di fuga con il mouse.


1

Nel mio caso, modifica

glutWarpPointer(centerX, centerY);

a qualcosa del genere

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

risolto perfettamente il problema.

Il problema è causato da glutWarpPointer che attiva un altro evento di movimento passivo su (centerX, centerY), che si traduce in un loop e / o inonda la coda degli eventi. Per evitarlo, controlla semplicemente se il mouse è su (centerX, centerY), in tal caso, non deformare.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.