与键盘听众的游戏循环

时间:2014-02-26 15:19:59

标签: c++ opengl glut

对于C ++ / OpenGL游戏,我正在制作我想要一个键盘输入处理程序和一个恒定的屏幕更新,因为游戏中有不断变化的部分。 现在我已经读过我可以使用glutKeyboardFunc()作为键盘监听器,并使用简单的while循环来进行常量屏幕更新(而gameRunning {...})。

但是如何将两者结合起来,因为如果我使用while循环,则关键监听器永远不会被调用,因为游戏仍在运行while循环。

3 个答案:

答案 0 :(得分:1)

This tutorial at Lighthouse3d.com涵盖了你所谈论的一切。

关键观察:您不使用自己的'while'循环来创建动画。循环内置于函数glutMainLoop()中,一旦设置了所有内容,就可以调用它。

答案 1 :(得分:0)

您似乎正在寻找glutIdleFunc,您将获得不断更新的屏幕(请记得最后调用glutPostRedisplay)。虽然你没有固定的时间步长(不能保证以恒定的间隔调用)。必须阅读fix your timestep

恕我直言,你需要一起抛弃GLUT并获得更好的库,如SDL或GLFW。

答案 2 :(得分:0)

您可以使用多个线程,一个用于显示,一个用于键盘捕获,一个用于物理更新。如果物理需要以固定频率运行,这里有一段代码,用于Windows XP或更高版本,使用高频计数器并在有足够的“备用”时间时休眠:

typedef unsigned long long UI64;    /* unsigned 64 bit int */
#define FREQ 400                    /* 400 hz */
static LARGE_INTEGER liPerfFreq;    /* 64 bit frequency */
LARGE_INTEGER liPerfTemp;           /* used for query */
UI64 uFreq = FREQ;                  /* process frequency */
UI64 uOrig;                         /* original tick */
UI64 uWait;                         /* tick rate / freq */
UI64 uRem = 0;                      /* tick rate % freq */
UI64 uPrev;                         /* previous tick based on original tick */
UI64 uDelta;                        /* current tick - previous */
UI64 u2ms;                          /* 2ms of ticks */
UI64 i;                          
    timeBeginPeriod(1);             /* set period to 1ms */
    Sleep(128);                     /* wait for it to stabilize */
    u2ms = ((UI64)(liPerfFreq.QuadPart)+499) / ((UI64)500);
    QueryPerformanceCounter(&liPerfTemp);
    uOrig = uPrev = liPerfTemp.QuadPart;
    for(i = 0; i < (uFreq*30); i++){
        /* physics step code goes here */
        /* update uWait and uRem based on uRem */
        uWait = ((UI64)(liPerfFreq.QuadPart) + uRem) / uFreq;
        uRem  = ((UI64)(liPerfFreq.QuadPart) + uRem) % uFreq;
        /* wait for uWait ticks */
        while(1){
            QueryPerformanceCounter(&liPerfTemp);
            uDelta = (UI64)(liPerfTemp.QuadPart - uPrev);
            if(uDelta >= uWait)
                break;
            if((uWait - uDelta) > u2ms)
                Sleep(1);   /* up to 2ms on win xp */
        }
    }