在上篇教程中,我們實作了在D3D11中畫一個簡單的三角形,但是,當我們改變視窗大小時候,三角形形狀卻随着視窗高寬比例改變而改變,如下圖所示:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcuIjZ5EmYlJmZxIDZ2cDO3UGN3QjZhlzMyUWYykzNkN2MfdWbp9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.png)
這是因為我們改變了視窗大小,但後緩沖大小在程式初始化時候,已經被指定,不随着視窗改變而改變,這樣在視口映射下,我們所渲染的三角形就改變了形狀。
下面我們将對程式進行一些小的改動,進而實作改變視窗大小,而渲染的圖形形狀不變。
首先是SystemClass.cpp,主要是增加了WM_SIZE消息的處理,當視窗大小改變時候,我們重新調用GraphicsClass的初始化函數,該函數中将會重新生成建立D3DClass,進而從新産生swapchain等等。主要改動代碼如下:
LRESULT CALLBACK SystemClass::MessageHandler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam)
{
…
case WM_KEYUP:
{
m_Input->KeyUp((unsigned int)wparam);
return 0;
}
//任何其它消息發送到windows預設處理.
case WM_SIZE:
int screenWidth = 0, screenHeight = 0;
screenWidth = LOWORD(lparam);
screenHeight = HIWORD(lparam);
// 視窗大小改變時,重新初始化圖形對象
if(m_Graphics)
{
bool result = m_Graphics->Initialize(screenWidth, screenHeight, m_hwnd);
if(!result)
{
return false;
}
}
default:
return DefWindowProc(hwnd, umsg, wparam, lparam);
}
GraphicsClass.cpp的初始化函數也進行了小小的改動,就是在函數的開始,先調用Shutdown()函數。
bool GraphicsClass:: Initialize(int screenWidth, int screenHeight, HWND hwnd)
bool result;
//如果對象已經存在,先釋放掉它們
Shutdown();
// 建立一個D3DClass對象.
…
第三個小改動是在D3CClass的初始化函數中,定義numerator和denominator這兩個重新整理率相關變量時候,要賦初值。如果不賦初值的話,當改變視窗大小時候,可能超找不到合适的重新整理率,引起程式異常。
代碼如下:
//Initialize函數包含完成D3D設定的所有代碼。
bool D3DClass::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen,
float screenDepth, float screenNear)
HRESULT result;
IDXGIFactory* factory;
IDXGIAdapter* adapter;
IDXGIOutput* adapterOutput;
unsigned int numModes, i, numerator=0, denominator=1, stringLength;
DXGI_MODE_DESC* displayModeList;
DXGI_ADAPTER_DESC adapterDesc;
int error;
}
程式運作後,現在我們再更變視窗大小,則三角形的形狀不會改變。
完整的代碼請參考:
工程檔案myTutorialD3D11_5
代碼下載下傳:
<a href="http://files.cnblogs.com/mikewolf2002/myTutorialD3D11.zip">http://files.cnblogs.com/mikewolf2002/myTutorialD3D11.zip</a>