0

私はいくつかのDirectXAPIを学習しようとしていますが、今のところ、WINAPIウィンドウと、画面全体にビットマップを表示する単純なレンダリング関数しかありません。私のWINMAIN機能:

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 );
}

したがって、主な問題は、レンダリング機能が有効になっている(コメントされていない)場合、アプリケーションが使用するメモリが1秒間に400〜600Mbになることです。ここで、WinMainからの回線を無効(コメント)にすると、メモリは5 Mbのままになりますが、プロセッサがおかしくなり、アプリケーションはその約50%を使用します。WinMain()したがって、多くのプロセッサとrender()多くのメモリを使用しているように見えます。なんで?何を忘れているの?

ありがとう!

4

2 に答える 2

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);

リソースを何億回も作成するこのコードを呼び出していますが、リリースしていません。これはレンダリング関数にあり、少なくとも1秒間に60回呼び出す必要があります(垂直リトレースとの同期がない場合は、1秒間に数千回呼び出すことができるため、大きな問題が発生します)。つまり、サーフェスへのポインタを同じイメージのサーフェスメモリの新しいブロックに変更し、古い(リリースされていない)アドレスを失うことを意味します。したがって、メモリリークが発生します。

そのコードを、レンダリング関数ではなく、アプリケーションの初期化関数にシフトします。(そして、それを管理することを確認してください!それを使用するのをやめるときは、リリース関数を呼び出して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
于 2012-06-21T11:29:32.707 に答える
1

プロセッサの使用率が50%であるのは、主にwhileループの無限回が頻繁に呼び出されるためです。

元。、

while(TRUE)
{
}

条件が真であるため、これを集中するようにプロセッサに指示しているため、これは頻繁にチェックされます。4コアプロセッサを使用している場合、プロセッサの1つがこのプロセスに完全に集中します。私の場合、4コアを使用したため、CPU使用率は25%です。2コアプロセッサを使用していると思います。

while(TRUE)
{
Sleep(1);
}

これにより、プロセッサの問題が解決します。

于 2016-03-04T05:53:05.460 に答える