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;
}