c++ - DirectX 小应用程序像 hell 一样消耗资源

标签 c++ winapi resources directx-9 consumption

我正在尝试学习一些 DirectX API,目前,我只有一个 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 );
}

因此,主要问题是当启用渲染功能(取消注释)时,应用程序使用的内存在一秒钟内达到 400 - 600 Mb。现在,如果我禁用(注释)来自 WinMain 的行,内存将保留 5 Mb,但处理器会变得疯狂,应用程序会使用大约 50% 的内存。因此,看起来 WinMain() 使用了大量处理器,而 render() 使用了大量内存。为什么?我忘记了什么?

谢谢!

最佳答案

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

您正在调用这段创建资源无数次的代码,但您没有释放它。它位于必须每秒至少调用 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

关于c++ - DirectX 小应用程序像 hell 一样消耗资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11137116/

相关文章:

c# - 以管理员身份运行 : requireAdministrator & ClickOnce + emulating system time

java - 为什么要使用字符串标识符来访问资源数据?

javascript - 将多个对象传递给 angularjs $resource.save()

c++ - GetVersionEx 弃用 - 如何从较新的 API 获取产品类型 (VER_NT_DOMAIN_CONTROLLER)

c++ - 偶数秒的 WinAPI 事件

c++ - 将 OCX 控件添加到资源对话框(我如何控制它)

c++ - 在 C++17 中没有从 std::string 到 std::string_view 的隐式转换(在 std::experimental::basic_string_view 中)

c++ - 超声波传感器HC-SR04 + Arduino计算?

c++ - 用C++读取文本文件

c++ - dll 的环境变量与 exe 不同