2012-06-21 48 views
0

我想學習一些DirectX API,現在,我只有一個WINAPI窗口和一個簡單的渲染函數,在整個屏幕上顯示一個位圖。我的WinMain函數:DirectX小應用程序消耗資源喜歡地獄

LPDIRECT3D9 pD3D; // the Direct3D object 
LPDIRECT3DDEVICE9 pd3dDevice; // the Direct3D device 

// This is winmain, the main entry point for Windows applications 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, 
        int nCmdShow) { 
    hInst = hInstance; 
    // Initialize the window 
    if (!initWindow(hInstance)) return false; 
    // called after creating the window 
    if (!initDirect3D()) return false; 
    // main message loop: 
    MSG msg; 
    ZeroMemory(&msg, sizeof(msg)); 
    while(msg.message != WM_QUIT) { 
     if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) { 
      TranslateMessage (&msg); 
      DispatchMessage (&msg); 
     } else { 
      render(); 
     } 
    } 
    // Release the device and the Direct3D object 
    if(pd3dDevice != NULL) pd3dDevice->Release(); 
    if(pD3D != NULL) pD3D->Release(); 
    return (int) msg.wParam; 
} 

,這是我的渲染功能:

void render(void) { 
    IDirect3DSurface9* surface; 
    pd3dDevice->CreateOffscreenPlainSurface(640, // the width of the surface to create 
     480, // the height of the surface to create 
     D3DFMT_X8R8G8B8, // the surface format 
     D3DPOOL_DEFAULT, // the memory pool to use 
     &surface, // holds the resulting surface 
     NULL); // reserved 
    D3DXLoadSurfaceFromFile(surface, NULL, NULL, L"test.bmp", NULL, D3DX_DEFAULT, 0, NULL); 
    // This will hold the back buffer 
    IDirect3DSurface9* backbuffer = NULL; 
    // Check to make sure you have a valid Direct3D device 
    if(NULL == pd3dDevice) return;// Clear the back buffer to a blue color 
    pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0); 
    // Get the back buffer 
    pd3dDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); 
    // Copy the offscreen surface to the back buffer 
    // Note the use of NULL values for the source and destination RECTs 
    // This ensures a copy of the entire surface to the back buffer 
    pd3dDevice->StretchRect(surface, NULL, backbuffer, NULL, D3DTEXF_NONE); 
    // Present the back buffer contents to the display 
    pd3dDevice->Present(NULL, NULL, NULL, NULL); 
} 

所以,主要的問題是,當渲染功能啓用(取消註釋)應用程序所使用的內存去400 - 每秒600 Mb。現在,如果我禁用(評論)來自WinMain的行,內存將保留在5 Mb內,但處理器變得瘋狂,應用程序佔用了大約50%的內存。所以,它看起來像WinMain()使用了大量的處理器和render()大量的內存。爲什麼?我忘了什麼?

謝謝!

回答

3
pd3dDevice->CreateOffscreenPlainSurface(640, // the width of the surface to create 
     480, // the height of the surface to create 
     D3DFMT_X8R8G8B8, // the surface format 
     D3DPOOL_DEFAULT, // the memory pool to use 
     &surface, // holds the resulting surface 
     NULL); // reserved 
    D3DXLoadSurfaceFromFile(surface, NULL, NULL, L"test.bmp", NULL, D3DX_DEFAULT, 0, NULL); 

你在調用這麼多的代碼,創建資源的次數超過了bazillion次,但是你並沒有釋放它。它在渲染函數中必須至少每秒調用60次(如果缺少與垂直回掃同步,則可以每秒調用數千次,這對您造成了很大的問題)。這意味着你將指針轉換爲表面到具有相同圖像的新表面存儲器塊,並丟失舊地址(未發佈)。因此,它會導致內存泄漏。

將該代碼切換到應用程序的初始化函數中,而不是在渲染函數中。 (並確保您管理它!當您停止使用它時,請調用釋放功能以降低COM對象的參考計數,以便系統可以聲明內存(可再次提供給您))

編輯:這還需要移動到應用程序的初始化,它只需一次點擊這裏

IDirect3DSurface9* backbuffer = NULL; 
    // Check to make sure you have a valid Direct3D device 
    if(NULL == pd3dDevice) return;// Clear the back buffer to a blue color 
    pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0); 
    // Get the back buffer 
    pd3dDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); 
    // Copy the offscreen surface to the back buffer 
    // Note the use of NULL values for the source and destination RECTs 
    // This ensures a copy of the entire surface to the back buffer 
    pd3dDevice->StretchRect(surface, NULL, backbuffer, NULL, D3DTEXF_NONE); 
    // Present the back buffer contents to the display 
+0

謝謝!現在,使用的內存是50 Mb(它只加載一個900 Kb位圖),處理器總是50%。 – ali

+0

@ali閱讀我在答案上的編輯,還有一件事需要完成。 – 2012-06-21 11:38:33

+0

@ali,'PeekMessage'不會引入空閒時間。爲什麼你想要一個遊戲(這是一個遊戲循環,你有)閒置? – chris

1

處理器使用率是50%,主要是由於while循環無限次頻繁調用。

前,

while(TRUE) 
{ 
} 

這將經常檢查,因爲你是指令集中以此爲條件爲真處理器。如果您使用的是4核心處理器,其中一個處理器將完全專注於此過程,在我的情況下,我使用了4核心,因此我的CPU使用率爲25%。我認爲你正在使用2核心處理器。

while(TRUE) 
{ 
Sleep(1); 
} 

這將解決您的處理器問題。