DirectX 創建一個窗口

#include <d3d9.h>

#pragma comment(lib, "d3d9.lib")

PDIRECT3D9 g_D3D = nullptr; // D3D對象
PDIRECT3DDEVICE9 g_D3DDevice = nullptr; // D3D設備對象

bool InitializeD3D(HWND hWnd); // 初始化D3D
void ShutdownD3D(); // 退出窗口之前釋放D3D對象和D3D設備對象
void RenderScene(); // 渲染場景


// windows的消息處理函數
LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
        break;
    default:
        break;
    }

    // windows消息的默認處理函數
    return DefWindowProc(hWnd, msg, wParam, lParam);
}


void MyCreateWindow(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
{
    // 聲明一個窗口類 包含創建一個窗口所需要的相關數據信息
    WNDCLASSEX wc = {
        sizeof(WNDCLASSEX), // 窗口類的內存空間大小(字節)
        CS_CLASSDC, // 窗口風格
        MsgProc, // 處理消息的函數指針
        0, // 類額外信息
        0, // 窗口額外信息
        hInstance, // 句柄,可以看作是窗口的身份標識
        nullptr, // 圖標樣式
        nullptr, // 鼠標樣式
        nullptr, // 背景畫刷 也可以設置爲一個顏色值 調用UnregisterClass後由系統刪除
        nullptr, // 菜單
        "AppClass", // 窗口類名 
        nullptr // 窗口小圖標
    };

    // 註冊窗口類
    RegisterClassEx(&wc);

    // 創建窗口
    HWND hWnd = CreateWindow(
        "AppClass", // 窗口類名
        "Window Title", // 窗口標題
        WS_OVERLAPPEDWINDOW, // 窗口風格 (可重疊)
        100, // 窗口左上角在屏幕座標中的X值
        100, // 窗口左上角在屏幕座標中的Y值
        640, // 窗口寬度
        480, // 窗口高度
        GetDesktopWindow(), // 窗口父類
        nullptr, // 菜單
        hInstance, // 句柄
        nullptr
        );

    if (InitializeD3D(hWnd))
    {
        // 設置指定窗口爲顯示狀態
        ShowWindow(hWnd, SW_SHOWDEFAULT);

        // 發送繪製消息給窗口
        UpdateWindow(hWnd);


        MSG msg;

        ZeroMemory(&msg, sizeof(msg));

        while (msg.message != WM_QUIT)
        {
            if (PeekMessage(
                &msg, // 存儲消息的結構體指針
                nullptr, // 窗口消息和線程消息都會被處理 
                0, // 消息過濾最小值; 爲0時返回所有可用信息
                0, // 消息過濾最大值; 爲0時返回所有可用信息
                PM_REMOVE // 指定消息如何處理; 消息在處理完後從隊列中移除
                ))
            {
                TranslateMessage(&msg); // 變換虛擬鍵消息到字符消息,字符消息被髮送到調用線程的消息隊列
                DispatchMessage(&msg); // 派發消息到窗口過程
            }
            else
            {
                // 渲染場景
                RenderScene();
            }    
        }
    }

    // 釋放D3D對象和D3D設備對象資源
    ShutdownD3D();

    // 註銷窗口類,釋放窗口所佔用資源
    UnregisterClass("AppClass", wc.hInstance); 
}

int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
{
    
    MyCreateWindow(hInstance, hPrevInstance, lpCmdLine, nShowCmd);
    
    return 0;
}

bool InitializeD3D(HWND hWnd)
{
    // 顯示模式 (以像素爲單位的屏幕寬高,刷新頻率,surface formt)
    D3DDISPLAYMODE displayMode;

    // 創建D3D對象 獲取主顯卡硬件信息  最先被創建,最後被釋放
    g_D3D = Direct3DCreate9(D3D_SDK_VERSION);
    if (g_D3D == nullptr)
    {
        return false;
    }

    // 獲取顯示模式
    if (FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT/*查詢主顯卡*/, &displayMode)))
    {
        return false;
    }

    // D3D 顯示參數
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory(&d3dpp, sizeof(d3dpp));

    d3dpp.Windowed = true; // 是否窗口化
    d3dpp.BackBufferFormat = displayMode.Format;  // D3DFMT_X8R8G8B8  表示爲32位RGB像素格式 每種顏色用一個字節表示
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // 幀緩衝區交換方式; 可能是COPY可能是FLIP,由設備來確定適合當前情況的方式
    // 創建D3D設備對象 ---- 代表顯卡
    if (FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_D3DDevice)))
    {
        return false;
    }

    return true;
}

void ShutdownD3D()
{
    if (g_D3DDevice != nullptr)
    {
        g_D3DDevice->Release();
    }

    if (g_D3D != nullptr)
    {
        g_D3D->Release(); // 最行創建, 最後釋放
    }
}

void RenderScene()
{

    g_D3DDevice->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
    g_D3DDevice->BeginScene();
    // 3D圖形數據
    g_D3DDevice->EndScene();

    // 顯示backbuffer內容到屏幕
    g_D3DDevice->Present(nullptr, nullptr, nullptr, nullptr);
}



發佈了98 篇原創文章 · 獲贊 37 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章