恒定游戏速度独立于OpenGL与GLUT中的可变FPS?

时间:2011-03-18 19:50:58

标签: c opengl glut game-loop

3 个答案:

答案 0 :(得分:1)

过剩是为了 游戏循环而设计的。当你调用glutMainLoop()时,它执行'for循环',除了exit()信号之外没有终止条件。您可以像现在一样实现您的程序,但是您需要进行一些小的更改。首先,如果您想知道FPS是什么,您应该将该跟踪放入renderScene()函数中,而不是放在更新函数中。当然,您的更新函数的调用速度与计时器指定的一样快,您将elapsedTime视为帧之间时间的度量。一般来说,这是真的,因为你正在调用glutPostRedisplay而且如果不需要则不会尝试更新屏幕(如果场景没有改变则不需要重绘)。但是,还有其他时候会调用renderScene。例如,如果您在窗口中拖动某些内容。如果你这样做,你会看到更高的FPS(如果你在渲染功能中正确跟踪FPS)。

答案 1 :(得分:0)

您可以使用glutIdleFunc,尽可能连续调用它 - 类似于while(game_is_running)循环。也就是说,无论你在while循环中输入什么逻辑,你都可以放入glutIdleFunc的回调。您可以通过跟踪自己的刻度来避免使用glutTimerFunc,就像您链接的文章一样(使用glutGet(GLUT_ELAPSED_TIME))。

答案 2 :(得分:0)

作为示例,具有鼠标驱动的旋转矩阵,其以固定的帧速率更新,与渲染帧速率无关。在我的程序中,空格键切换基准测试模式,并确定布尔值fxFPS。

拖动时松开鼠标按钮,你就可以扔掉'由这个矩阵转换的对象。

如果fxFPS为真,则渲染帧速率被限制为动画帧速率;否则,重复绘制相同的帧以进行基准测试,即使没有足够的毫秒时间来触发任何动画。

如果您正考虑放慢速度并加快帧速度,那么您必须仔细考虑在每种情况下是否表示渲染或动画帧。在此示例中,简单动画的渲染限制与动画加速相结合,适用于在潜在的慢动画中丢帧的任何情况。

为了加速动画,循环中重复执行旋转。与使用自适应旋转角度进行触发的选项相比,这样的循环不会太慢;只要小心你放入任何实际需要更长时间执行的循环,FPS越低。对于它所考虑的每个帧丢失,这个循环所需的额外帧要少得多,所以它相当安全。

int xSt, ySt, xCr, yCr, msM = 0, msOld = 0;
bool dragging = false, spin = false, moving = false;
glm::mat4 mouseRot(1.0f), continRot(1.0f);
float twoOvHght; // Set in reshape()
glm::mat4 mouseRotate(bool slow) {
    glm::vec3 axis(twoOvHght * (yCr - ySt), twoOvHght * (xCr - xSt), 0); // Perpendicular to mouse motion
    float len = glm::length(axis);
    if (slow) { // Slow rotation; divide angle by mouse-delay in milliseconds; it is multiplied by frame delay to speed it up later
        int msP = msM - msOld;
        len /= (msP != 0 ? msP : 1);
    }
    if (len != 0) axis = glm::normalize(axis); else axis = glm::vec3(0.0f, 0.0f, 1.0f);
    return rotate(axis, cosf(len), sinf(len));
}
void mouseMotion(int x, int y) {
    moving = (xCr != x) | (yCr != y);
    if (dragging & moving) {
        xSt = xCr; xCr = x; ySt = yCr; yCr = y; msOld = msM; msM = glutGet(GLUT_ELAPSED_TIME);
        mouseRot = mouseRotate(false) * mouseRot;
    }
}
void mouseButton(int button, int state, int x, int y) {
    if (button == 0) {
        if (state == 0) {
            dragging = true; moving = false; spin = false;
            xCr = x; yCr = y; msM = glutGet(GLUT_ELAPSED_TIME);
            glutPostRedisplay();
        } else {
            dragging = false; spin = moving;
            if (spin) continRot = mouseRotate(true);
        }
    }
}

然后......

bool fxFPS = false;
int T = 0, ms = 0;
const int fDel = 20;
void display() {
    ms = glutGet(GLUT_ELAPSED_TIME);
    if (T <= ms) { T = ms + fDel;
        for (int lp = 0; lp < fDel; lp++) {
            orient = rotY * orient; orientCu = rotX * rotY * orientCu; // Auto-rotate two orientation quaternions
            if (spin) mouseRot = continRot * mouseRot; // Track rotation from thowing action by mouse
        }
        orient1 = glm::mat4_cast(orient); orient2 = glm::mat4_cast(orientCu);
    }
    // Top secret animation code that will make me rich goes here
    glutSwapBuffers();
    if (spin | dragging) { if (fxFPS) while (glutGet(GLUT_ELAPSED_TIME) < T); glutPostRedisplay(); } // Fast, repeated updates of the screen
}

喜欢在轴上扔东西;我发现大多数人都这样做。请注意,fps在界面或渲染中不会影响任何内容。我已经最大限度地减少了划分的使用,因此比较应该是美观和准确的,并且时钟中的任何不准确性都不会不必要地累积。

多人游戏的同步是另外18个对话,我会判断。