我想在OpenGL/GLUT窗口中实现自己的光标。通常的做法是冻结光标(使其不能触及屏幕边缘)并自己跟踪其位置。我可以用glutPassiveMotionFunc和glutWarpMousePointer
glutSetCursor(GLUT_CURSOR_NONE);
,然后我glutPassiveMotionFunc回调的内屏幕上的光标不可见使用
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);
这工作,因为它使指针粘在鼠标指针移到窗口的中间窗户的中间。问题是,当我绘制'OpenGL'鼠标(在glutDisplayFunc()回调中)时,它非常生涩。
我在网上看了一遍,发现glutWarpPointer()会导致glutPassiveMotionFunc回调再次被调用,导致循环,但这似乎并没有发生在这里。
我在Mac OS X上,发现一篇文章说CGDisplayMoveCursorToPoint更适合这个。调用CGDisplayMoveCursorToPoint的作品,但运动仍然非常生涩(我似乎得到很多事件,其中x和y都是0)。在任何情况下,我都希望这也适用于Linux,因此仅Mac的解决方案并不理想(但我可以在不同的系统上做不同的事情)。
我减少了这个测试用例。
#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;
}
很高兴你能工作。 +1发布您的解决方案和一个很好的解释。看起来我还没有接近! :) – 2009-04-10 03:32:59
我解决了这个问题,先调用glutWarpPointer并忽略鼠标事件,直到下一行为止。 – 2011-01-01 09:15:14