C++ 相机的旋转方向在一段时间后会反转

C++ 相机的旋转方向在一段时间后会反转,c++,opengl,C++,Opengl,我正在尝试创建一个微型应用程序,通过鼠标的移动使相机围绕一个立方体旋转。它在绕Y轴旋转时工作得很好,但我在绕X轴旋转时遇到了一个问题。当我不断向上移动鼠标时,立方体开始沿正X方向旋转。一段时间后,它反转旋转方向,开始在负X方向旋转,然后在一段时间后,再次在正X方向旋转。我想让它围绕正X旋转,直到我向上移动鼠标为止。这里有什么问题 立方体位于坐标系的中心。投影是透视图: 编辑:以下是与问题相关的视频: vec4眼; VEC4AT; vec4上升; GLfloat mouseX=-1; GLfloa

我正在尝试创建一个微型应用程序,通过鼠标的移动使相机围绕一个立方体旋转。它在绕Y轴旋转时工作得很好,但我在绕X轴旋转时遇到了一个问题。当我不断向上移动鼠标时,立方体开始沿正X方向旋转。一段时间后,它反转旋转方向,开始在负X方向旋转,然后在一段时间后,再次在正X方向旋转。我想让它围绕正X旋转,直到我向上移动鼠标为止。这里有什么问题

立方体位于坐标系的中心。投影是透视图:

编辑:以下是与问题相关的视频:

vec4眼;
VEC4AT;
vec4上升;
GLfloat mouseX=-1;
GLfloat mouseY=-1;
//绑定到glutemotionfunc
无效鼠标(整数x,整数y){
//这种旋转效果非常好,只要我向左或向右移动鼠标,立方体就会沿着同一方向连续旋转
GLfloat加速度_x=mouseX-x;
眼=旋转(加速度×10.f)*眼;
mouseX=x;
//此旋转无法正常工作,一段时间后,立方体的旋转方向会反转
GLfloat加速度_y=mouseY-y;
眼=旋转(加速度y/10.f)*眼;
mouseY=y;
//这部分在到达窗口边界后将指针传送到窗口的另一侧
如果(x>=1364){
指针(1,y);
mouseX=1;
} 
否则如果(x=751){
指针(x,3);
mouseY=3;
}

否则,如果(y是因为相机被翻转了。像这样使用你的手:食指指向
方向,拇指向上(拇指=(0,1,0))。将食指向前,拇指向上。现在,开始绕X旋转你的手:食指开始指向下,拇指向前(在此期间,thumb.y为正)。当您将手旋转90度时,食指指向下方,拇指指向前方(thumb.y为0)。当您继续旋转时,拇指开始指向前方+下方(thumb.y为负)

此时,LookAt函数将不会计算您想要的矩阵,因为您希望
up
向量指向下方(正如我们所说,thumb.y是负数),但在代码中,
up
向量是一个常量(0,1,0),因此LookAt将计算一个矩阵,该矩阵具有正的
向上。y
相机翻转

一个解决方案是注册所需的旋转角度,并用这些角度旋转相机矩阵(而不是
dir

vec4 eye;
vec4 at;
vec4 up;
GLfloat mouseX = -1;
GLfloat mouseY = -1;

// Bound to glutPassiveMotionFunc
void mouse(int x, int y) {
    // This rotation works perfect, cube rotates on same direction continuously as far as I move the mouse left or right 
    GLfloat acceleration_x = mouseX - x;
    eye = RotateY(acceleration_x / 10.f) * eye;
    mouseX = x;


    // This rotation doesn't work properly, after some time, cube's rotation direction inverses
    GLfloat acceleration_y = mouseY - y;
    eye = RotateX(acceleration_y / 10.f) * eye;
    mouseY = y;


    // This part teleports pointer to opposite side of window after reaching window bounds
    if (x >= 1364) {
        glutWarpPointer(1, y);
        mouseX = 1;
    } 
    else if (x <= 0) {
        glutWarpPointer(1363, y);
        mouseX = 1363;
    }

    if (y >= 751) {
        glutWarpPointer(x, 3);
        mouseY = 3;
    }
    else if (y <= 2) {
        glutWarpPointer(x, 750);
        mouseY = 750;
    }
}


void display( void )
{
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    vec4   up( 0.0, 1.0, 0.0, 0.0 );

    mat4 model_view = LookAt( eye, at, up );
    glUniformMatrix4fv( ModelView, 1, GL_TRUE, model_view );

    glDrawArrays( GL_TRIANGLES, 0, NumVertices );
    glutSwapBuffers();
}

// Bound to glutTimerFunc
void timer( int id )
{    
    glutPostRedisplay();
    glutTimerFunc(1000.f/60.f, timer, 0);
}

int main( int argc, char **argv )
{
    ......
    ......

    eye = vec4(0, 0, 2, 0);
    at = vec4(0, 0, 0, 0);
    up = vec4(0.0, 1.0, 0.0, 0.0);

    .....
    .....
}