You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为游戏进程实现固定帧率限制功能(类Rivatuner)

无源码实现游戏进程固定帧率限制方案

要实现无源码的游戏帧率限制,核心是Hook游戏的图形渲染API交换缓冲区函数,在每帧渲染完成后插入精准延迟,通过控制帧间隔来固定帧率。常见的目标函数是DirectX的Present/Present1或OpenGL的SwapBuffers,这些函数是每帧画面输出的最后一步,是控制帧率的关键节点。

1. 注入Hook DLL到目标进程

你当前的代码已经能找到目标进程并打开句柄,接下来需要将包含Hook逻辑的DLL注入到目标进程中。可以通过CreateRemoteThread调用目标进程的LoadLibraryA来加载你的DLL:

// 替换你代码中的// Do stuff..部分
if (hProcess != NULL) {
    // 你的Hook DLL绝对路径
    const char* dllPath = "C:\\Path\\To\\Your\\FrameLimitHook.dll";
    LPVOID remoteMem = VirtualAllocEx(hProcess, NULL, strlen(dllPath) + 1, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    
    if (remoteMem != NULL) {
        // 将DLL路径写入目标进程内存
        WriteProcessMemory(hProcess, remoteMem, dllPath, strlen(dllPath) + 1, NULL);
        // 创建远程线程加载DLL
        HANDLE hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibraryA, remoteMem, 0, NULL);
        
        if (hRemoteThread != NULL) {
            WaitForSingleObject(hRemoteThread, INFINITE);
            CloseHandle(hRemoteThread);
        }
        VirtualFreeEx(hProcess, remoteMem, 0, MEM_RELEASE);
    }
}

注意:OpenProcess无需PROCESS_ALL_ACCESS,仅需PROCESS_CREATE_THREAD、PROCESS_QUERY_INFORMATION、PROCESS_VM_OPERATION、PROCESS_VM_WRITE、PROCESS_VM_READ这些权限即可,更安全。

2. 在Hook DLL中实现帧率控制逻辑

以下以Direct3D 9的Present函数为例,使用微软Detours库简化Hook实现(也可自行编写inline hook):

2.1 定义函数指针与全局变量

#include <d3d9.h>
#include <detours.h>
#include <windows.h>
#include <chrono>

// 原始Present函数指针
typedef HRESULT(WINAPI* pPresent)(LPDIRECT3DDEVICE9, CONST RECT*, CONST RECT*, HWND, CONST RGNDATA*);
pPresent OriginalPresent = NULL;

// 目标帧率(可根据需求修改)
const float targetFPS = 60.0f;
// 目标帧间隔(毫秒)
const float targetFrameTime = 1000.0f / targetFPS;
// 上一帧时间戳
std::chrono::steady_clock::time_point lastFrameTime;

2.2 实现Hook的Present函数

HRESULT WINAPI HookedPresent(LPDIRECT3DDEVICE9 pDevice, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion) {
    // 计算当前帧与上一帧的时间差
    auto currentTime = std::chrono::steady_clock::now();
    auto elapsedTime = std::chrono::duration<float, std::milli>(currentTime - lastFrameTime).count();
    
    // 补全帧间隔延迟
    if (elapsedTime < targetFrameTime) {
        // 粗略Sleep减少CPU占用
        if (targetFrameTime - elapsedTime > 1.0f) {
            Sleep((DWORD)(targetFrameTime - elapsedTime - 0.5f));
        }
        // 高精度循环等待补全剩余时间
        while (std::chrono::duration<float, std::milli>(std::chrono::steady_clock::now() - lastFrameTime).count() < targetFrameTime) {
            YieldProcessor();
        }
    }
    
    // 更新上一帧时间戳
    lastFrameTime = std::chrono::steady_clock::now();
    
    // 调用原始Present函数
    return OriginalPresent(pDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
}

2.3 DLL入口函数初始化Hook

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
        case DLL_PROCESS_ATTACH:
            // 初始化时间戳
            lastFrameTime = std::chrono::steady_clock::now();
            // 启动Hook
            DetourTransactionBegin();
            DetourUpdateThread(GetCurrentThread());
            OriginalPresent = (pPresent)DetourFindFunction("d3d9.dll", "Present");
            DetourAttach(&(PVOID&)OriginalPresent, HookedPresent);
            DetourTransactionCommit();
            break;
        case DLL_PROCESS_DETACH:
            // 卸载Hook
            DetourTransactionBegin();
            DetourUpdateThread(GetCurrentThread());
            DetourDetach(&(PVOID&)OriginalPresent, HookedPresent);
            DetourTransactionCommit();
            break;
    }
    return TRUE;
}

3. 关键注意事项

  • 多API兼容:不同游戏可能使用D3D11、D3D12或OpenGL,需针对对应API实现Hook(如D3D11的Present1、OpenGL的SwapBuffers)。
  • 位数匹配:Hook DLL需与目标进程位数一致(32位游戏用32位DLL,64位游戏用64位DLL)。
  • 权限要求:程序需以管理员权限运行,否则无法注入受保护的游戏进程。
  • 精度优化:Sleep精度约1ms,高帧率场景(如144FPS)需依赖高精度计时循环保证帧率稳定。

内容的提问来源于stack exchange,提问作者szefitoo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 22:45:53