我想在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