Je veux implémenter mon propre curseur dans une fenêtre OpenGL/GLUT. La manière habituelle de faire ceci est de geler le curseur (de sorte qu'il ne peut pas frapper les bords de l'écran) et de garder une trace de sa position vous-même. Je peux faire le curseur à l'écran invisible à l'aideglutPassiveMotionFunc et glutWarpMousePointer
glutSetCursor(GLUT_CURSOR_NONE);
puis à l'intérieur de mon rappel glutPassiveMotionFunc déplacer le pointeur vers le milieu de la fenêtre à l'aide
int centerX = (float)kWindowWidth/2.0;
int centerY = (float)kWindowHeight/2.0;
int deltaX = (x - centerX);
int deltaY = (y - centerY);
mouseX += deltaX/(float)kWindowWidth;
mouseY -= deltaY/(float)kWindowHeight;
glutWarpPointer(centerX, centerY);
Cela fonctionne en ce qu'il garde le pointeur collé à la milieu de la fenêtre. Le problème est que lorsque je dessine la souris 'OpenGL' (à l'intérieur du callback glutDisplayFunc()), elle est extrêmement saccadée. J'ai regardé en ligne et j'ai constaté qu'il peut y avoir un problème où glutWarpPointer() provoque le rappel de glutPassiveMotionFunc à nouveau, ce qui entraîne une boucle, mais cela ne semble pas se produire ici. Je suis sur Mac OS X et j'ai trouvé un post disant que CGDisplayMoveCursorToPoint convenait mieux à cela. L'appel de CGDisplayMoveCursorToPoint fonctionne mais le mouvement est toujours très saccadé (et il semble que j'obtiens beaucoup d'événements où x et y sont tous deux à 0). Dans tous les cas, je voudrais que cela fonctionne également sur Linux, donc une solution uniquement pour Mac n'est pas idéale (mais je suis d'accord pour faire différentes choses sur les différents systèmes). J'ai réduit cela à un test de cas.
#include <stdio.h>
#include <OpenGL/OpenGL.h>
#include <GLUT/GLUT.h>
int curX = 0;
int curY = 0;
void display() {
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
float vx = (float)curX/300.0 + 0.5;
float vy = (float)curY/300.0 + 0.5;
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POINTS);
glVertex3f(vx, vy, 0.0);
glEnd();
glutSwapBuffers();
}
void passivemotion(int x, int y) {
int centerX = 150;
int centerY = 150;
int deltaX = x - centerX;
int deltaY = y - centerY;
curX += deltaX;
curY -= deltaY;
glutWarpPointer(centerX, centerY);
}
void timer(int val) {
glutTimerFunc(16, &timer, 0);
glutPostRedisplay();
}
int main (int argc, char * argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB);
glutInitWindowSize(300,300);
glutCreateWindow("FPS Mouse Sample");
glutDisplayFunc(&display);
glutPassiveMotionFunc(&passivemotion);
glutSetCursor(GLUT_CURSOR_NONE);
glutTimerFunc(16, &timer, 0);
glutMainLoop();
return 0;
}
Je suis content que vous ayez réussi. +1 pour poster votre solution et une bonne explication. On dirait que je n'étais même pas proche! :) –
J'ai corrigé cela en retournant un peu avant d'appeler glutWarpPointer et ignorer les événements de souris jusqu'à la ligne suivante. –