StupidBeauty
Read times:1245Posted at:Tue Feb 28 18:21:44 2012
- no title specified

ClanLib维基翻译:主文档:定时,MainDocs:Timing

刷新率

刷新率(某些时候叫做垂直同步)指的是显示设备在一秒内绘制数据的次数。

历史上,在米国,电视的刷新率是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);

}

Your opinions
Your name:Email:Website url:Opinion content: