
刷新率
刷新率(某些时候叫做垂直同步)指的是显示设备在一秒内绘制数据的次数。
历史上,在米国,电视的刷新率是60赫兹。在欧洲是50赫兹。这使得游戏容易判断定时情况。
然而,电脑显示器和现代的电视机的刷新率却不统一。通常是在60赫兹到80赫兹之间,但是也有些产品的刷新率达到120赫兹。
CL_Display::flip()
妳只會在完成绘图过程之后再将内容真正绘制到屏幕上,否则将會显示一個只画到一半的图像(这叫做花屏(screen tearing))
显示设备在内在中包含2 個屏幕。一個正在被写入,另一個正在被显示。为咯便于参考,在OpenGL 中叫做GL_DRAW_FRAMEBUFFER 和CL_READ_FRAMEBUFFER。
要交换这两个屏幕,妳需要调用flip()
这叫做“双缓冲”或“换页”("page switching")
在1 次显示器刷新过程中绘制2 次屏幕是一种浪费。理想情况下,妳应当在第一次屏幕交换之后等待,直到下次显示刷新。
幸运的是,OpenGL帮助妳做到这一点。(多年以前,妳只能等待垂直空白中断(vertical blanking interrupt))
flip()函数有一個整数参数
"-1" (默认値)。屏幕按照显卡的默认设置来绘制,可能是“不要等待下次显示刷新”或“等待下次显示刷新”。
"0" 。绘制屏幕的过程中不等待下次显示刷新
"1" 。绘制屏幕的过程中會等待下次显示刷新
"n" 。屏幕會在第n次显示刷新之后绘制
即使妳要求程序等待下次显示刷新,也不能假设它會这样。某些显卡驱动允许用户覆盖掉程序的设置。例如NVidia 就提供“垂直同步”("Vertical Sync")选项。
如果妳想测试程序的速度,则使用flip(0)。正常情况下,则使用flip(1)
不要使用flip()来控制游戏的时间周期
CL_DisplayWindowDescription
它包含:set_refresh_rate()
OpenGL 目标不會使用这個参数。曾几何时,它使用过,但是由于引起咯一系列的问题,所以去掉咯。
它是在SWRender 目标中使用的,以让程序猿可以更容易地在不同的ClanLib 显示目标之间切换。它调用CL_System::sleep(),以让程序以为自己是与显示刷新率同步的。如果没有定义,则默认为60赫兹。
再说一遍,它只在使用flip(1)时用于clanSWRender。
这個类还包含:set_swap_interval()
这個函数控制的是初始的flip()交换时间周期,改变flip()的默认状态
也就是说,只會在妳调用flip(-1)或flip()时才使用。
这個函数被用来在使用clanGUI 时控制显示刷新率
CL_System::sleep()
这個函数會睡眠若干毫秒,以减少妳的程序的cpu 占用率。
在内部实现中,这個函数會导致一個线程放弃(relinquish)它的时间片的剩下部分。系统时钟以一個固定的频率动作("ticks")。如果设置的时间比系统时钟的精度还要小,那么这個线程的睡眠时间可能會比指定的时间还要短。如果设置的时间比一個滴答(tick)要长又比二個滴答要短,那么睡眠时间可能會是1到2個滴答之间的任何时间,依此类推
如果妳指定0 毫秒,则这個线程會放弃时间片的剩余部分,因此不會立即返回。
CL_System::pause()
这与CL_System::sleep()类似,但是它可能會产生一個自旋锁来使程序暂停。
避免使用这個,除非妳需要更精确的时间控制。电脑上其它程序的运行可能會变慢。
CL_KeepAlive::process
这個函数會处理操作系统的消息(键盘、鼠标……)
参数是超时时间(毫秒)
对于游戏来说,妳永远會将这個参数写成0 的。
如果妳将它设置成-1(一直等到消息来临),则妳的游戏的主循环只會在鼠标移动的时候才工作(有趣,但是没用)。
主循环时间控制
理想的代码是这样的:
代码: (参考 示例/显示/定时 )
unsigned int last_time = CL_System::get_time();
while (!quit)
{
unsigned int current_time = CL_System::get_time();
int time_difference = current_time - last_time;
if (time_difference > 1000)
time_difference = 1000; // 如果程序被暂停,则限制时间差
float time_delta_ms = static_cast<float> (time_difference);
last_time = current_time;
*** 游戏代码写在这里
gc.clear(CL_Colorf(0.0f,0.0f,0.2f));
sprite_position += speed * time_delta_ms;
*** 游戏代码结束
window.flip(1);
CL_KeepAlive::process(0);
current_time = CL_System::get_time();
const int main_loop_rate = 10; // 10 毫秒 (100 赫兹)
int time_to_sleep_for = main_loop_rate - (current_time - last_time);
if (time_to_sleep_for > 0)
CL_System::sleep(time_to_sleep_for);
}
HxLauncher: Launch Android applications by voice commands