游戏开发论坛

 找回密码
 立即注册
搜索
查看: 6735|回复: 7

[求助]游戏帧率好难控制...

[复制链接]

50

主题

236

帖子

454

积分

中级会员

Rank: 3Rank: 3

积分
454
发表于 2012-9-18 21:46:00 | 显示全部楼层 |阅读模式
我用ddraw和gdi滚动一张地图,帧率控制到60FPS,但怎么控制,画面都有撕裂感,要么就是一行一行的像素波动.
但是用DX9,开启垂直同步(D3DPRESENT_INTERVAL_ONE),滚动这张地图就不会有任何的撕裂感和波动,非常的平滑,不知道人家是怎么实现的.

这是我使用的限制FPS的函数:

  1. void LimitFps(int fps)
  2. {
  3.         const double const_timePerFrame = 1000.0/fps;
  4.         static double timePerFrame = const_timePerFrame;

  5.         LARGE_INTEGER Freq;
  6.         if (!QueryPerformanceFrequency(&Freq))
  7.                 return;

  8.         static LARGE_INTEGER startTime = { 0 };
  9.         static LARGE_INTEGER endTime;

  10.         if (startTime.QuadPart == 0)
  11.         {
  12.                 QueryPerformanceCounter(&startTime);
  13.                 return;
  14.         }

  15.         QueryPerformanceCounter(&endTime);
  16.         double time = (endTime.QuadPart-startTime.QuadPart)*1000.0/Freq.QuadPart;
  17.         if (time < timePerFrame)
  18.         {
  19.                 double timeToWait = (Freq.QuadPart*(timePerFrame-time)/1000.0);
  20.                 LARGE_INTEGER curTime = endTime;
  21.                 while (curTime.QuadPart-endTime.QuadPart < timeToWait)
  22.                         QueryPerformanceCounter(&curTime);
  23.         }

  24.         QueryPerformanceCounter(&startTime);
  25. }
复制代码

34

主题

844

帖子

1755

积分

金牌会员

Rank: 6Rank: 6

积分
1755
发表于 2012-9-19 08:55:00 | 显示全部楼层

Re:[求助]游戏帧率好难控制...

如果能“同步”,那么这段代码就不需要了。

50

主题

236

帖子

454

积分

中级会员

Rank: 3Rank: 3

积分
454
 楼主| 发表于 2012-9-19 11:03:00 | 显示全部楼层

Re: Re:[求助]游戏帧率好难控制...

snghun: Re:[求助]游戏帧率好难控制...

如果能“同步”,那么这段代码就不需要了。


dx9都能处理非常好,我想我也可以,因为好像窗口化程序是无法开启垂直同步的,是吧?
而且,我开始是用GetTickCount() + Sleep()进行的限制,效果非常差,但自从用了QueryPerformanceCounter()后,基本上平滑了,但是仍每隔一段时间,就有一行行的波纹.
所以,我感觉这是fps限制代码写的不够好.

34

主题

844

帖子

1755

积分

金牌会员

Rank: 6Rank: 6

积分
1755
发表于 2012-9-19 11:53:00 | 显示全部楼层

Re:[求助]游戏帧率好难控制...

你错了。

限制是限制,同步是同步。
就算帧数完美限制为60.00000fps,屏幕的刷新率为60.00000Hz,那也不能得到你想要的结果。
因为“光是限制,却不去同步,画面仍然会撕裂”。

同步是必须调用显卡的“Vertical Blank”的。
不知道GDI有没有这样的功能。

DDraw有 WaitForVerticalBlank 函数可以捕捉垂直回归瞬间。

50

主题

236

帖子

454

积分

中级会员

Rank: 3Rank: 3

积分
454
 楼主| 发表于 2012-9-19 13:28:00 | 显示全部楼层

Re: Re:[求助]游戏帧率好难控制...

snghun: Re:[求助]游戏帧率好难控制...

你错了。

限制是限制,同步是同步。
就算帧数完美限制为60.00000fps,屏幕的刷新率为60.00000Hz,那也不...


查了一下,WaitForVerticalBlank()的确可以用来解决画面撕裂感,
非常感谢,

但是经测试,效果不太好,画面还会波动,不知道这函数应该怎么用?
我是这样用的:

  1. void MainLoop()
  2. {
  3.         1:绘制图像

  4.         2:将后台表表面blt到前台

  5.         3:m_pDDraw7->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL);
  6. }
复制代码

34

主题

844

帖子

1755

积分

金牌会员

Rank: 6Rank: 6

积分
1755
发表于 2012-9-19 13:47:00 | 显示全部楼层

Re:[求助]游戏帧率好难控制...

我的妈妈呀

垂直同步,就是为了“等到垂直回归的那一瞬间,交换两个缓存”。

你先“将后台表表面blt到前台”,然后再“WaitForVerticalBlank”,这是干神马?

1,在后缓存上渲染游戏画面
2,等待垂直回归 WaitForVerticalBlank
3,替换两个缓存

这样才正确的嘛。

34

主题

844

帖子

1755

积分

金牌会员

Rank: 6Rank: 6

积分
1755
发表于 2012-9-19 13:53:00 | 显示全部楼层

Re:[求助]游戏帧率好难控制...

如果硬件的渲染能力非常出色的话,你甚至可以这么整:

1,等待垂直回归 WaitForVerticalBlank
2,在后缓存上渲染游戏画面(大概只需要1ms)
3,替换两个缓存

这样的话,连双缓存的通病-“画面延迟于操作1帧”也能给解决掉了。
但前提是,硬件渲染速度要非常非常快。在垂直回归的过程当中就把整张画面完整地渲染完。
要不然的话,呵呵,屏幕的上方还是会出现撕裂的。大概在屏幕上方5%处吧(取决于渲染速度)。

50

主题

236

帖子

454

积分

中级会员

Rank: 3Rank: 3

积分
454
 楼主| 发表于 2012-9-19 14:20:00 | 显示全部楼层

Re: Re:[求助]游戏帧率好难控制...

snghun: Re:[求助]游戏帧率好难控制...

我的妈妈呀

垂直同步,就是为了“等到垂直回归的那一瞬间,交换两个缓存”。

你先“将后台表表面blt到...


嘿嘿.....
这样子,试了,效果好多了,不再有波纹了,
只是反复比较后发现,总是感觉晃动的频率比DX9高一些,而且偶尔会忽快忽慢,不过总体上差不多.
不知道是不是ddraw太旧了,对硬件的支持不如DX9好?

还有,听说需要和GetVerticalBlankStatus()配合使用??
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-2-27 16:46

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表