我不确定这在 stackexchange 中是否更合适,但是 steam(游戏覆盖)和 FRAPS 等程序如何在窗口上覆盖数据?我注意到覆盖/fraps 只能在由 opengl/directx 驱动的窗口上工作,还是覆盖只是 Windows API 中的一个功能?此外,fraps 如何获取窗口的 fps?
答案1
FRAPS 和类似程序通过挂钩用于显示渲染帧的 API 调用来工作(例如IDirect3DDevice9::Present方法或 OpenGL交换缓冲区())
本质上,当游戏即将显示新帧时,程序执行将转移到 FRAPS 安装的钩子。该代码可以以任何方式修改帧,在其上绘制 FPS 计数器、更改颜色或截取屏幕截图以进行视频录制。完成后,FRAPS 会调用原始 API 来显示帧。
不同的图形 API 需要不同的钩子,因此 FRAPS 必须为 OpenGL 和 Direct3D 8/9/10 等提供单独的实现。这也意味着当新技术(如 Direct2D)发布时,FRAPS 需要更新来处理这些技术。
安装和删除钩子的实际过程相当复杂;你可以在这个 StackOverflow 问题中找到更多信息:
或者这里:案例研究:Fraps
计算 FPS 很简单;程序只需要帧之间的时间间隔。例如:帧时间 = 20 毫秒;FPS = 1000 毫秒/20 毫秒 = 50;
如果帧时间变化很大,FPS 值就会大幅波动。更好的方法是计算最后 10 帧的平均值或计算最后一秒绘制的帧数。尽管 FRAPS 中的数字似乎变化太快了。