首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

自製 3D 圖形引擎 (三):WuguiEngine 基礎迴圈與視窗類別實作

     編輯:關於C++

可重用視窗類別 (WEWindow)

採單例模式封裝 Windows 程式進入點難點:OnIdle 處理、HInstance 保存、HWND 保存。

class WEWindow {
public:
    static WEWindow* GetInstance();
    void SetHInstance(HINSTANCE hInst);
    HINSTANCE GetHInstance();
    void SetWEWindow(LPCWSTR szTitle, int iWidth, int iHeight, DWORD iStyle);
    void CreateMainWindow();
    int GetWidth(); int GetHeight();
    HWND GetHWnd();
protected:
    HINSTANCE hInst; HWND hWnd;
    LPCWSTR szTitle; int iWidth, iHeight; DWORD iStyle;
    void CreateWEWindow(LPCWSTR szTitle, int iWidth, int iHeight, DWORD iStyle);
    void EnterMessageLoop();
private:
    static WEWindow* weInstance; WEWindow();
};

WinMain 使用範例

INT WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR, int) {
    WEWindow* weWindow = WEWindow::GetInstance();
    weWindow->SetHInstance(hInstance);
    weWindow->SetWEWindow(L"Hello World", 640, 480, WS_OVERLAPPEDWINDOW | WS_VISIBLE);
    weWindow->CreateMainWindow();
    // ...
}

基礎遊戲類別 (BaseGame)

繼承介面 IDisposed, IRenderable, IUpdatable (純虛函數)。

class BaseGame : virtual public IDisposed, virtual public IRenderable, virtual public IUpdatable {
public:
    BaseGame(string name);
    GraphicsDevice* GetGraphicsDevice();
    void Tick(); // 一幀完整流程
    virtual void Run() = 0; // 進入訊息迴圈
    virtual void Dispose();
    virtual void Update(DWORD dt);
    virtual void Render(DWORD dt);
    virtual void Initialize();
    void RegisterCamera(BaseCamera* camera);
    BaseCamera* GetCamera();
protected:
    void SetTimeUsed(); void ShowFPS(); void UpdateCamera(DWORD dt);
    GraphicsDevice* pDevice; bool isInitialized; BaseCamera* pCamera;
};

Tick 幀流程

void BaseGame::Tick() {
    SetTimeUsed();           // 計算幀時間
    Update(TimeUsed::LastTickTimeUsed);
    Render(TimeUsed::LastTickTimeUsed);
}

TimeUsed 靜態類別保存幀時間、總運行時間等。

完整流程範例:TestGame

  1. WinMain:建立視窗 (WEWindow)。
  2. WinMain:建立 TestGame 實例,呼叫 Run()。
  3. TestGame::Run():Initialize() → EnterMessageLoop()。
  4. TestGame::Initialize():呼叫基底 Initialize(),初始化幾何體、渲染狀態。
  5. TestGame::EnterMessageLoop():標準訊息迴圈,PeekMessage 處理訊息,無訊息時呼叫 Tick()。
void TestGame::EnterMessageLoop() {
    MSG kMessage; HWND hWnd = WEWindow::GetInstance()->GetHWnd();
    while (1) {
        if (PeekMessage(&kMessage, hWnd, 0, 0, PM_REMOVE)) {
            if (WM_QUIT == kMessage.message) { Dispose(); return; }
            TranslateMessage(&kMessage); DispatchMessage(&kMessage);
        } else { Tick(); }
    }
}

下集預告

下篇將介紹渲染核心:Model、Effect、Texture、Transformation、Camera 類別組織。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved