Я хочу реализовать свой собственный курсор в окне OpenGL / GLUT. Обычный способ сделать это - заморозить курсор (чтобы он не ударялся о края экрана) и самостоятельно отслеживать его положение. Я могу сделать экранный курсор невидимым, используя
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;
}