OpenGL相机旋转怪异

Posted

技术标签:

【中文标题】OpenGL相机旋转怪异【英文标题】:OpenGL Camera rotation weirdness 【发布时间】:2013-03-23 19:42:00 【问题描述】:

我一直在使用 FreeGlut 和 Glew 开展一个小项目。现在我正在编写一个摄像头系统,但有些事情很奇怪:

在全屏模式下,如果鼠标在屏幕下方移动,相机的移动速度会比在屏幕上方移动时快。

相机做出奇怪的运动,总是在同一个方向,一个小的 8 位数移动。

代码:

void MouseOps(int x, int y)

    // Changes in mousepositions.  Always same direction and 
    // in lower right corner of monitor faster, for some reason.
    deltaX = x - MousePreviousX;
    deltaY = y - MousePreviousY;

    // Also I didn't bother to put * 360 in next equations, 
    // because it would make the camera  jump for crazy. 
    // resx and resy are screen resolutions. 
    // Endresult should be that camera can 
    // rotate once when mouse moves over screen
    yaw = yaw + (((deltaX / resx)) * deginrad);
    pitch = pitch + (((deltaY / resy)) * deginrad);

    //Check clippings (eg. camera wont end upside down etc.)
    if(yaw >= (2 * pi) || yaw <= (-2 * pi)  )
        yaw = 0;
    if(pitch >= (pi / 2))
        pitch = pi / 2;
    if(pitch <= (pi / -2))
        pitch = pi / -2;

    //Calculate x, y, and z coordinates of unit sphere to look at (r = 1)
    cam_normX = cos(yaw) * sin(pitch); 
    cam_normY = sin(yaw) * sin(pitch);
    cam_normZ = cos(yaw);

    // Current x and y to previous
    int MousePreviousX = x;
    int MousePreviousY = y; 

我试过用这个 http://en.wikipedia.org/wiki/Spherical_coordinate_system#Cartesian_coordinates 系统来计算要查看的点。然后我将所有“cam_norm”变量传递给

gluLookAt(cam_posX, cam_posY, cam_posZ,
        cam_posX+cam_normX, cam_posY+cam_normY, cam_posZ + cam_normZ,
        cam_upX, cam_upY, cam_upZ); 

【问题讨论】:

为什么要在函数末尾声明MousePreviousX/Y?它们需要是静态或全局变量才能在函数调用之间保持其值。 我的错,我实际上已经宣布了两次。我删除了那些,但奇怪的事情并没有消失。实际上,相机似乎根本不动。 好的,它移动了,但又奇怪了。 您需要更具体。 it moves, but weirdly 是什么意思?它有什么奇怪的?它会移动到快/慢,仅以粗略的步骤,在随机方向上移动到无穷大甚至更远吗? 【参考方案1】:

我不知道为什么会这样,但它解决了所有问题:

bool isCursorWarping = false;

void MouseOps(int x, int y)


    if(isCursorWarping == false)
        // Changes in mousepositions. Always same direction and in lower right corner of monitor faster, for some reason.
        deltaX = x - MousePreviousX;
        deltaY = y - MousePreviousY;

        yaw = yaw + ((((deltaX / resx)) * deginrad) * 360);
        pitch = pitch + ((((deltaY / resy)) * deginrad) * 360);


        //Check clippings (eg. camera wont end upside down etc.)

        if(x >= resx - 1 || y >= resy - 1 || x == 0 || y == 0)
        
            warpCursor();
            MousePreviousX = resx / 2;
            MousePreviousY = resy / 2; 
        else
            MousePreviousX = x;
            MousePreviousY = y; 
        

        if(yaw >= (2 * pi) || yaw <= (-2 * pi)  )
            yaw = 0;
        if(pitch >= (pi / 2))
            pitch = pi / 2;
        if(pitch <= (pi / -2))
            pitch = pi / -2;


        //Calculate x, y, and z coordinates of unit sphere to look at (r = 1)

        cam_normX = cos(pitch) * cos(yaw); 
        cam_normY = sin(pitch) * sin(yaw);
        cam_normZ = cos(pitch) * sin(yaw);



    
        // Current x and y to previous and cleanup



        isCursorWarping = false;




void warpCursor()

    isCursorWarping = true;
    glutWarpPointer(resx / 2, resy / 2);



然后我将“cam_norm”值传递给:

gluLookAt(0.0f, 1.0f, 2.0f, 0.0f + cam_normX, 1.0f + cam_normY, 2.0f+ cam_normZ, 0.0f, 0.1f, 0.0f);

【讨论】:

以上是关于OpenGL相机旋转怪异的主要内容,如果未能解决你的问题,请参考以下文章

在OpenGL中沿对象后面的方向旋转相机

Java OpenGL - 如何使对象随相机旋转?

使用 OpenGL 2.0 API 在 GLSurfaceView 上将 Android 相机预览旋转 90 度

OpenGL在2个键上旋转相机

从相机旋转中隔离“指南针”openGL

OpenGL:相机和对象