【问题标题】:direct3d initialization failure / c++direct3d初始化失败/ C++
【发布时间】:2012-01-25 18:13:33
【问题描述】:

这是创建简单窗口并初始化简单 direct3d 设备的代码。但每次程序到达render() 函数应用程序都会终止。我不知道为什么会这样。有人可以解释一下这种奇怪的行为吗?谢谢!!

//====================================================================================================

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

//====================================================================================================

HINSTANCE hInst;
HWND wndHandle;

//====================================================================================================

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

//====================================================================================================

bool initWindow(HINSTANCE hInstance);
bool initDirect3D(void);
void cleanUp (void);
void render(void);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

//====================================================================================================

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    if (!initWindow(hInstance)) return false;

    if (!initDirect3D()) return false;

    MSG msg;
    ZeroMemory(&msg, sizeof(msg));

    if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
    {
        TranslateMessage (&msg);
        DispatchMessage (&msg);
    } else {
        render();  // i think this is the problem ...
    }

    return static_cast<int>(msg.wParam);
}

bool initWindow(HINSTANCE hInstance )
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(0, IDI_APPLICATION);
    wcex.hCursor = LoadCursor(0, IDC_ARROW);
    wcex.hbrBackground = static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
    wcex.lpszMenuName = 0L;
    wcex.lpszClassName = L"DirectXTemplate";
    wcex.hIconSm = 0;
    RegisterClassEx(&wcex);

    wndHandle = CreateWindow(L"DirectXTemplate", L"DirectX Template", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, hInstance, NULL);

    if (!wndHandle) return false;

    ShowWindow(wndHandle, SW_SHOW);
    UpdateWindow(wndHandle);

    return true;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            break;

        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }   
}

bool initDirect3D(void)
{
    pD3D = NULL;
    pd3dDevice = NULL;

    // create the DirectX object
    if(NULL == (pD3D = Direct3DCreate9(D3D_SDK_VERSION))) return false;

    // fill the presentation parameters structure
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory(&d3dpp, sizeof(d3dpp));

    d3dpp.Windowed          = TRUE;
    d3dpp.SwapEffect        = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat  = D3DFMT_UNKNOWN;
    d3dpp.BackBufferCount   = 1;
    d3dpp.BackBufferHeight  = 480;
    d3dpp.BackBufferWidth   = 640;
    d3dpp.hDeviceWindow     = wndHandle;

    // create a default DirectX device
    if (FAILED(pD3D -> CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, wndHandle, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pd3dDevice))) return false;

    return true;
}

void render(void)
{
    // 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);

    // Present the back buffer contents to the display
    pd3dDevice -> Present(NULL, NULL, NULL, NULL);
}

void cleanUp (void)
{
    // Release the device and the Direct3D object
    if (pd3dDevice != NULL) pd3dDevice -> Release();
    if (pD3D != NULL) pD3D -> Release();
}

【问题讨论】:

    标签: c++ winapi directx


    【解决方案1】:

    @DuckMaestro 是对的。您的程序正在经历一次 msg/render 过程,然后结束。仅当msg 退出程序时才应结束。尝试像这样输入一个循环:

    while(msg.message!=WM_QUIT){
      if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
      {
          TranslateMessage (&msg);
          DispatchMessage (&msg);
      } else {
          render();  // i think this is the problem ...
      }
    }
    

    【讨论】:

      【解决方案2】:

      你的……

      if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) 
      { 
          TranslateMessage (&msg); 
          DispatchMessage (&msg); 
      } else { 
          render();  // i think this is the problem ... 
      } 
      

      ...需要在while 循环中,不是吗?使用调试器逐句逐句执行您的代码。 Win32 应用程序需要一个 while 循环来维持生命,可以这么说。

      【讨论】:

      • 我试过了——为了测试它,我把render() 函数放在WM_PAINT 中。程序仍然终止。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-25
      • 2012-11-17
      • 2017-12-10
      相关资源
      最近更新 更多