¿Atrapando el mouse dentro de la ventana en OpenGL con GLUT?

8

Entiendo perfectamente que GLUT es limitado y el siguiente problema probablemente no se pueda resolver con OpenGL / GLUT, pero como no sé exactamente si puede o no, es mejor que pregunte. Tal vez estoy haciendo algo mal u olvidando algo importante. O probablemente no, y GLUT no se pone mejor que esto.

Mi problema es que no puedo atrapar el mouse dentro de la ventana. Bueno, en realidad puedo, el código a continuación hace exactamente eso. Atrapo el mouse dentro de la ventana y puedo usar el mouse libremente para girar el mundo. ¿El problema? Si muevo el mouse demasiado rápido puedo salir de la prisión de la ventana.

¿Hay alguna forma de evitar esto con OpenGL / GLUT o la única opción es otra biblioteca o hacer algunas llamadas directamente a la API de Windows? Palabras suficientes, aquí está mi código actual:

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
fuente

Respuestas:

7

Que yo sepa, esto es específico de Windows-API: esta funcionalidad ni siquiera existe en todas las plataformas. Si desea profundizar en mi código , puede encontrar una implementación de Windows que funcione (LockMouseCursor es el punto de entrada al módulo del sistema operativo, ClipCursor es la función real de Windows que hace la captura, pero hay algunas sutilezas que rodean esa función; no debería ser demasiado difícil de descifrar)

También tengo una implementación de Linux en X puro (nuevamente, comience con LockMouseCursor) pero nunca he encontrado una API OSX utilizable para ello. Si terminas necesitando uno o tienes uno, revisa mi pregunta de Stackoverflow al respecto :)

ZorbaTHut
fuente
Gracias, tendré esta publicación en mente como referencia. Estás lidiando con las API de Windows, ya que sospechaba que era la única buena manera de lograr esto, pero no quería seguir esa ruta. No es que no sepa cómo, porque hago lo que hice antes, pero por lo que estoy tratando de hacer, no vale la pena y no es una prioridad.
rfgamaral
2

Con una búsqueda rápida a través de la especificación GLUT , GLUT no parece tener capacidades de captura de mouse. Lo mejor que puede hacer (como parece estar haciendo) es deformar el cursor hacia el centro y esperar que el usuario no sea lo suficientemente rápido (o no esté usando una tableta) =)

O bien, puede cambiar a SDL o SFML , ya que GLUT solo está diseñado para pruebas, no para software "real".

Jari Komppa
fuente
Si bien estoy de acuerdo con su comentario en general, quiero instar firmemente a SDL porque oh hombre SDL tiene problemas importantes. SFML es genial, ¡úsalo!
ZorbaTHut
Ambos tienen su lado, y me gusta SDL, así que ... =)
Jari Komppa
1
Por favor, no entiendas esto mal, pero esta es la segunda vez que me estás diciendo que cambie. Si bien agradezco la respuesta de alguien, si insisto en publicar preguntas específicas de GLUT, ¿tal vez tengo una buena razón para esto y no puedo cambiar? Ya me di cuenta de cómo GLUT apesta, pero tengo que soportarlo, no es mi elección. Lo siento si sueno duro, pero odio cuando la gente insiste así, te "escuché" la primera vez.
rfgamaral
Estoy votando su respuesta porque estoy ignorando ese último párrafo. :)
rfgamaral 23/03/11
2
Nazgulled, perdón si parece que estoy repitiendo cosas, realmente no hago un seguimiento de las preguntas de las que estoy respondiendo =). Además, las personas terminarán encontrando esta pregunta a través de búsquedas, y también quiero responderlas, no solo a usted.
Jari Komppa
2

Pruebe una versión más nueva de freeglut; Mi v2.6, atrapa el cursor con glutWarpPointer sin ninguna posibilidad de escapar con el mouse.

Palax
fuente
1

En mi caso, modificar

glutWarpPointer(centerX, centerY);

a algo como

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

Resuelto perfectamente el problema.

El problema es causado por glutWarpPointer que dispara otro evento de movimiento pasivo a (centerX, centerY), lo que resulta en un bucle y / o inunda la cola de eventos. Para evitarlo, simplemente verifique si el mouse está en (centerX, centerY), si es así, no se deforme.

Giumo
fuente