Piéger la souris à l'intérieur d'une fenêtre dans OpenGL avec GLUT?

8

Je comprends parfaitement que GLUT est limité et le problème suivant ne peut probablement pas être résolu avec OpenGL / GLUT, mais comme je ne sais pas exactement si cela peut ou non, je ferais mieux de demander. Peut-être que je fais quelque chose de mal ou que j'oublie quelque chose d'important. Ou probablement pas et GLUT ne va pas mieux que ça.

Mon problème est que je ne peux pas piéger la souris à l'intérieur de la fenêtre. Eh bien, en fait, je peux, le code ci-dessous fait exactement cela. Je piège la souris à l'intérieur de la fenêtre et je peux utiliser la souris librement pour faire tourner le monde. Le problème? Si je déplace la souris trop vite, je peux m'éloigner de la prison de fenêtre.

Existe-t-il un moyen de contourner cela avec OpenGL / GLUT ou la seule option est une autre bibliothèque ou de passer directement des appels à l'API Windows? Assez de mots, voici mon code actuel:

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);
rfgamaral
la source

Réponses:

7

À ma connaissance, cela est spécifique à l'API Windows - cette fonctionnalité n'existe même pas sur toutes les plateformes. Si vous voulez fouiller dans mon code, vous pouvez trouver une implémentation Windows fonctionnelle (LockMouseCursor est le point d'entrée dans le module OS, ClipCursor est la fonction Windows réelle qui fait le piégeage, mais il y a quelques subtilités autour de cette fonction - elle ne devrait pas être trop difficile à déchiffrer.)

J'ai également une implémentation Linux en pur X (encore une fois, commencez par LockMouseCursor) mais je n'ai jamais trouvé d'API OSX utilisable pour cela. Si vous finissez par en avoir besoin ou en proposer un, consultez ma question Stackoverflow à ce sujet :)

ZorbaTHut
la source
Merci, je garderai ce post à l'esprit comme référence. Vous avez affaire à des API Windows car je soupçonnais être le seul bon moyen d'y parvenir, mais je ne voulais pas emprunter cette voie. Non pas que je ne sache pas comment, parce que je fais comme je l'ai fait auparavant, mais pour ce que je veux faire, ça ne vaut pas la peine et ce n'est pas une priorité.
rfgamaral
2

Avec une recherche rapide dans la spécification GLUT , GLUT ne semble pas avoir de capacités de capture de souris. Le mieux que vous puissiez faire (comme vous semblez le faire) est de déformer le curseur vers le centre et d'espérer que l'utilisateur n'est pas assez rapide (ou n'utilise pas de tablette) =)

Vous pouvez également basculer vers SDL ou SFML , car GLUT est uniquement conçu pour les tests, pas pour les "vrais" logiciels.

Jari Komppa
la source
Bien que je sois d'accord avec votre commentaire en général, je veux vivement déconseiller SDL car oh man SDL a des problèmes majeurs. SFML est génial, utilisez ça!
ZorbaTHut
Ils ont tous les deux leurs côtés, et j'aime SDL, donc .. =)
Jari Komppa
1
Veuillez ne pas vous tromper mais c'est la deuxième fois que vous me dites de changer. Bien que j'apprécie la réponse de quiconque, si j'insiste pour publier des questions spécifiques à GLUT, j'ai peut-être une bonne raison à cela et je ne peux pas changer? J'ai déjà réalisé à quel point GLUT était nul, mais je dois le supporter, ce n'est pas mon choix. Désolé si j'ai l'air dur, mais je déteste quand les gens insistent comme ça, je vous ai "entendu" la première fois.
rfgamaral
Je vote votre réponse parce que j'ignore ce dernier paragraphe. :)
rfgamaral
2
Nazgulled, désolé si je semble répéter des choses, je ne fais pas vraiment le suivi des questions auxquelles je réponds =). De plus, les gens finiront par trouver cette question par le biais de recherches, et je veux également y répondre, pas seulement à vous.
Jari Komppa
2

Essayez une nouvelle version de freeglut; Ma v2.6, piège le curseur avec glutWarpPointer sans aucune possibilité d'évasion par la souris.

Palax
la source
1

Dans mon cas, modifiez

glutWarpPointer(centerX, centerY);

à quelque chose comme

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

parfaitement résolu le problème.

Le problème est dû au fait que glutWarpPointer déclenche un autre événement de mouvement passif vers (centerX, centerY), ce qui entraîne une boucle et / ou inonde la file d'attente des événements. Pour l'éviter, vérifiez simplement si la souris est à (centerX, centerY), si c'est le cas, ne vous déformez pas.

Giumo
la source