Winapi Windows应用程序(游戏)使用大量资源

Winapi Windows应用程序(游戏)使用大量资源,winapi,opengl,windows,Winapi,Opengl,Windows,我目前正在开发一款使用WindowsAPI创建窗口的游戏。然而,目前这个进程占用了我50%的CPU。我所做的就是创建窗口并使用下面的代码循环: int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { MSG message = {0}; WNDCLASSEX wcl = {0}; wcl.cbSize = sizeof(wcl);

我目前正在开发一款使用WindowsAPI创建窗口的游戏。然而,目前这个进程占用了我50%的CPU。我所做的就是创建窗口并使用下面的代码循环:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    MSG message = {0};
    WNDCLASSEX wcl = {0};

    wcl.cbSize = sizeof(wcl);
    wcl.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
    wcl.lpfnWndProc = WindowProc;
    wcl.cbClsExtra = 0;
    wcl.cbWndExtra = 0;
    wcl.hInstance = hInstance = hInstance;
    wcl.hIcon = LoadIcon(0, IDI_APPLICATION);
    wcl.hCursor = LoadCursor(0, IDC_ARROW);
    wcl.hbrBackground = 0;
    wcl.lpszMenuName = 0;
    wcl.lpszClassName = "GL2WindowClass";
    wcl.hIconSm = 0;

    if (!RegisterClassEx(&wcl))
        return 0;

    hWnd = CreateAppWindow(wcl, "Application");

    if (hWnd)
    {
        if (Init())
        {
            ShowWindow(hWnd, nShowCmd);
            UpdateWindow(hWnd);         

            while (true)
            {
                while (PeekMessage(&message, 0, 0, 0, PM_REMOVE))
                {
                    if (message.message == WM_QUIT)
                        break;

                    TranslateMessage(&message);
                    DispatchMessage(&message);
                }

                if (message.message == WM_QUIT)
                    break;

                if (hasFocus)
            {
                elapsedTime = GetElapsedTimeInSeconds();
                lastEarth += elapsedTime;
                lastUpdate += elapsedTime;
                lastFrame += elapsedTime;
                lastParticle += elapsedTime;

                if(lastUpdate >= (1.0f / 100.0f))
                {
                    Update(lastUpdate);        
                    lastUpdate = 0;
                }
                if(lastFrame >= (1.0f / 60.0f))
                {
                    UpdateFrameRate(lastFrame);
                    lastFrame = 0;
                    Render();
                    SwapBuffers(hDC);
                }
                if(lastEarth >= (1.0f / 10.0f))
                {
                    UpdateEarthAnimation();
                    lastEarth = 0;
                }
                if(lastParticle >= (1.0f / 30.0f))
                {
                    particleManager->rightBooster->Update();
                    particleManager->rightBoosterSmoke->Update();
                    particleManager->leftBooster->Update();
                    particleManager->leftBoosterSmoke->Update();

                    particleManager->breakUp->Update();
                    lastParticle = 0;
                }
            }
            else
            {
                WaitMessage();
            }
            }
        }

        Cleanup();
        UnregisterClass(wcl.lpszClassName, hInstance);
    }

    return static_cast<int>(message.wParam);
}
int-WINAPI-WinMain(HINSTANCE-HINSTANCE、HINSTANCE-hPrevInstance、LPSTR-lpCmdLine、int-nShowCmd)
{
MSG message={0};
WNDCLASSEX wcl={0};
wcl.cbSize=sizeof(wcl);
wcl.style=CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
wcl.lpfnWndProc=WindowProc;
wcl.cbClsExtra=0;
wcl.cbWndExtra=0;
wcl.hInstance=hInstance=hInstance;
wcl.hIcon=加载图标(0,IDI_应用程序);
wcl.hCursor=加载光标(0,IDC_箭头);
wcl.hbrBackground=0;
wcl.lpszMenuName=0;
wcl.lpszClassName=“GL2WindowClass”;
wcl.hIconSm=0;
如果(!RegisterClass(&wcl))
返回0;
hWnd=CreateAppWindow(wcl,“应用程序”);
如果(hWnd)
{
if(Init())
{
显示窗口(hWnd、nShowCmd);
更新窗口(hWnd);
while(true)
{
while(peek消息(&消息,0,0,0,PM_移除))
{
如果(message.message==WM\u退出)
打破
翻译消息(和消息);
DispatchMessage(&message);
}
如果(message.message==WM\u退出)
打破
如果(hasFocus)
{
elapsedTime=GetElapsedTimeInSeconds();
lastEarth+=延迟时间;
lastUpdate+=elapsedTime;
lastFrame+=延迟时间;
lastParticle+=延迟时间;
如果(最新更新>=(1.0f/100.0f))
{
更新(最新更新);
lastUpdate=0;
}
如果(最后一帧>=(1.0f/60.0f))
{
UpdateFrameRate(最后一帧);
lastFrame=0;
Render();
SwapBuffers(hDC);
}
如果(lastEarth>=(1.0f/10.0f))
{
UpdateEarthAnimation();
lastEarth=0;
}
如果(lastParticle>=(1.0f/30.0f))
{
particleManager->rightBooster->Update();
particleManager->rightBoosterSmoke->Update();
particleManager->leftBooster->Update();
particleManager->leftBoosterSmoke->Update();
particleManager->breakUp->Update();
粒子数=0;
}
}
其他的
{
WaitMessage();
}
}
}
清理();
取消注册类(wcl.lpszClassName,hInstance);
}
返回静态_cast(message.wParam);
}
其中GetElapsedTimeInSeconds:

float GetElapsedTimeInSeconds()
{
    static const int MAX_SAMPLE_COUNT = 50;

    static float frameTimes[MAX_SAMPLE_COUNT];
    static float timeScale = 0.0f;
    static float actualElapsedTimeSec = 0.0f;
    static INT64 freq = 0;
    static INT64 lastTime = 0;
    static int sampleCount = 0;
    static bool initialized = false;

    INT64 time = 0;
    float elapsedTimeSec = 0.0f;

    if (!initialized)
    {
        initialized = true;
        QueryPerformanceFrequency(reinterpret_cast<LARGE_INTEGER*>(&freq));
        QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(&lastTime));
        timeScale = 1.0f / freq;
    }

    QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(&time));
    elapsedTimeSec = (time - lastTime) * timeScale;
    lastTime = time;

    if (fabsf(elapsedTimeSec - actualElapsedTimeSec) < 1.0f)
    {
        memmove(&frameTimes[1], frameTimes, sizeof(frameTimes) - sizeof(frameTimes[0]));
        frameTimes[0] = elapsedTimeSec;

        if (sampleCount < MAX_SAMPLE_COUNT)
            ++sampleCount;
    }

    actualElapsedTimeSec = 0.0f;

    for (int i = 0; i < sampleCount; ++i)
        actualElapsedTimeSec += frameTimes[i];

    if (sampleCount > 0)
        actualElapsedTimeSec /= sampleCount;

    return actualElapsedTimeSec;
}
float GetElapsedTimeInSeconds()
{
静态常数int MAX_SAMPLE_COUNT=50;
静态浮点帧时间[最大采样计数];
静态浮动时间刻度=0.0f;
静态浮动实际浮动时间=0.0f;
静态INT64频率=0;
静态INT64 lastTime=0;
静态整数采样计数=0;
静态布尔初始化=假;
INT64时间=0;
浮动时间间隔=0.0f;
如果(!已初始化)
{
初始化=真;
QueryPerformanceFrequency(重新解释强制转换(&freq));
QueryPerformanceCounter(重新解释强制转换(&lastTime));
时间刻度=1.0f/频率;
}
QueryPerformanceCounter(重新解释强制转换(&T));
elapsedTimeSec=(时间-上次时间)*时间刻度;
lastTime=时间;
如果(fabsf(elapsedTimeSec-实际LapsedTimesec)<1.0f)
{
memmove(&frameTimes[1]、frameTimes、sizeof(frameTimes)-sizeof(frameTimes[0]);
帧时间[0]=elapsedTimeSec;
if(样本数<最大样本数)
++样本数;
}
实际LapsedTimesec=0.0f;
对于(int i=0;i0)
ActualLapsedTimesec/=样本计数;
返回ActualLapsedTimesec;
}
所以,即使我没有画任何东西,当窗口有焦点时,它仍然占50%。我不明白这怎么会占用这么多系统资源

我做错什么了吗


任何帮助都将不胜感激,谢谢

hasfocus从天而降。当它为真时,您将烧掉100%的内核,if()语句中没有任何东西会让您的程序等待任何东西。睡眠(1)可以解决这个问题,但你的意图并不明显。

hasfocus从天上掉下来。当它为真时,您将烧掉100%的内核,if()语句中没有任何东西会让您的程序等待任何东西。睡眠(1)可以解决这一问题,但你的意图并不明显。

你的应用程序运行在一个紧密的循环中,没有做任何有用的事情会消耗CPU。您必须在循环中添加类似于
Sleep(1)
的内容

您提供的这个示例是一个退化的情况,它实际上不需要修复。如果你打算用它来制作一个游戏,那么你将把帧更新和渲染功能放到循环中,它将做一些有用的“东西”。在这种情况下,您不想“睡眠”任何周期


如果我是你,我就不会从头开始制作游戏,而是寻找一些游戏引擎。市场上有很多高质量的开源和开源免费游戏引擎。或者至少寻找一些简单的游戏框架,它们提供了一些基本功能,如消息循环和双缓冲窗口绘图设置。

您的应用程序运行在一个紧密的循环中,没有做任何有用的事情,从而消耗了CPU。您必须在循环中添加类似于
Sleep(1)
的内容

这个例子