亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》
  • 首頁 > 
  • 教程 > 
  • 開發技術 > 
  • 【 Visual C++】游戲開發筆記之二——最簡單的DirectX,vc窗口的編寫

【 Visual C++】游戲開發筆記之二——最簡單的DirectX,vc窗口的編寫

發布時間:2020-04-03 08:54:30 來源:網絡 閱讀:2565 作者:zhmxy555 欄目:開發技術

筆記一中我們介紹了如何用代碼創建空的win32窗口,然而創建空的win32窗口只完成了一半的工作,接下來要做的工作是設置Direct3D,從而可以在屏幕上渲染圖形。

Direct3D要調用很多函數才能成功設置API。一旦完成設置,并且設置成功,就可以向屏幕上渲染圖形。

下面是函數中設置Direct3D所需的最少代碼。

  1. bool InitializeD3D(HWND hWnd, bool fullscreen)  
  2. {  
  3. D3DDISPLAYMODE displayMode;  
  4. // Create the D3D object.  
  5. g_D3D = Direct3DCreate9(D3D_SDK_VERSION);  
  6. if(g_D3D == NULL) return false;  
  7. // Get the desktop display mode.  
  8. if(FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode)))  
  9. return false;  
  10. // Set up the structure used to create the D3DDevice  
  11. D3DPRESENT_PARAMETERS d3dpp;  
  12. ZeroMemory(&d3dpp, sizeof(d3dpp));  
  13. if(fullscreen)  
  14. {  
  15. d3dpp.Windowed = FALSE;  
  16. d3dpp.BackBufferWidth = 640;  
  17. d3dpp.BackBufferHeight = 480;  
  18. }  
  19. else 
  20. d3dpp.Windowed = TRUE;  
  21. d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;  
  22. d3dpp.BackBufferFormat = displayMode.Format;  
  23. // Create the D3DDevice  
  24. if(FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,  
  25. D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_D3DDevice)))  
  26. {  
  27. return false;  
  28. }  
  29. return true;  

上段代碼中的InitializeD3D函數的參數有窗口句柄hWnd,標識窗口是否全屏的標識符fullscreen。窗口句柄是在調用CreateWindows()函數創建窗口句柄時,返回給WinMain()函數的數值。InitializeD3D()函數開始先調用Direct3DCreat9()函數。Direct3DCreat9()函數將創建一個Direct3D接口對象,并返回該對象。該函數所帶的參數值為D3D_SDK_VERSION。如果從該函數創建的接口不為NULL(空),那么接口創建成功。如果是NULL,那么創建接口時就會出錯。其他步驟很大程度上取決于是否成功調用Direct3DCreat9()函數,所以一旦出現錯誤,就會立刻退出Direct3D初始化程序。

接下來調用的是GetAdapterDisplayMode()
函數。該函數將返回當前的顯示信息,如桌面分辨率(寬度和高度),顯示格式,顯示器的刷新頻率等。該函數的參數包括正在查詢的適配器以及保存信息的顯示模式對象。將D3DADAPTER_DEFAULT發送給函數,詳細說明代碼,通過這些代碼可以獲取想要的主顯卡信息。

檢索顯卡信息之后,函數接下來會創建D3DPRESENT_PARAMETERS對象。D3DPRESENT_PARAMETERS結構用于定義Direct3D窗口的顯示信息。這樣可以設置正在創建窗口的期望寬度和高度,刷新率,顯示模式為全屏或窗口,后天緩存數目等。

D3DPRESENT_PARAMETERS結構體的定義:

  1. typedef struct _D3DPRESENT_PARAMETERS_ {  
  2. UINT BackBufferWidth; //窗口寬度  
  3. UINT BackBufferHeight; //窗口高度  
  4. D3DFORMAT BackBufferFormat; //渲染后臺緩存的格式  
  5. UINT BackBufferCount; //想要用于渲染的后臺緩存總數  
  6. D3DMULTISAMPLE_TYPE MultiSampleType;  
  7. D3DSWAPEFFECT SwapEffect;  
  8. HWND hDeviceWindow;  
  9. BOOL Windowed;  
  10. BOOL EnableAutoDepthStencil;  
  11. D3DFORMAT AutoDepthStencilFormat;  
  12. DWORD Flags;  
  13. UINT FullScreen_RefreshRateInHz;  
  14. UINT FullScreen_PresentationInterval;  
  15. } D3DPRESENT_PARAMETERS; 

D3DPRESENT_PARAMETERS結構體是的前兩個變量是BackBufferWidth( 窗口寬度 ),BackBufferHeight(窗口高度)。接下來的變量BackBufferFormat代表渲染后臺緩存的格式。將D3DFMT_DEFAULT發送給該參數,就會得到所要用到的桌面格式。該參數可以接收的其他參數值分別是D3DFMT_A2R10G10B10(紅、綠、藍各10位,Alpha通道2位,總計32位),D3DFMT_A8R8G8B8(紅、綠、藍Alpha各8位,總計32位)、D3DFMT_X8R8G8B8、D3DFMT_AIR5G5B5、D3DFMT_XIR5G5B5和D3DFMT_R5G5B5。


BcakBufferCount是想要用于渲染的后臺緩存總數。通常,使用一個后臺緩存和一個主緩存,使用多個緩存會使動畫更流暢,因為后臺緩存上繪制內容,然后將結果復制到主緩存,主緩存將其顯示在屏幕上。如果所有的事情都在主緩存處理,那么游戲玩家在玩游戲時,會看到正在刷新的屏幕,從而會產生視覺假象,破壞游
戲的視覺效果。成員變量MultiSampleType、MultiSampleQuality和SwapEffect處理交換效果。hDeviceWindow是調用WinMain()中的CreateWindow()函數創建的窗口句柄。Windowed標識符用于指定創建的窗口是否是全屏窗口。
 

EnableAutoDepthStencil標識符用于設置是否用Direct3D管理緩存深度以及模板緩存。AutoDepthStencilFormat將深度和模板緩存設置為BackBufferFormat可以使用的相同值之一。

結構中的最后三個變量分別是Flags、FullScreen_RefreshRateInHz和PresentationInterval。Flags標識符可以是D3DPRESENTFLAG_DEVICECLIP、D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL和D3DPRESENTFLAG_LOCKABLE_ BUFFER或D3DPRESENTFLAG_VIDEO的任意組合。變量FullScreen_RefreshRateInHz存儲顯示器的刷新率。對窗口模式程序而言,該值必須為0,但對全屏模式而言,該值取決于顯示器。對此,可以調用GetDisplayAdapter()函數獲取顯示模式。最后一個變量PresentationInterval處理可以顯示的交換鏈的后臺緩存的最大次數。交換鏈主要讓程序有多個窗口在桌面上同時顯示(每個渲染自己的窗口)本書不涉及交換鏈的討論,所以這里將不使用該變量。程序清單1.3 InitializeD3D()函數中調用的最后一個函數是CreateDevice()。該函數主要負責創建Direct3D設備對象,該對象用于向屏幕渲染圖形。如果函數失敗,最后一個參數(對象被發送給ppReturnedDeviceInterface)將為NULL(空)。測試函數是否失敗的另一種方法是判斷函數的返回值是否是D3D_OK以外的其他值。如果不是D3D_OK,則意味著創建過程中出現了問題,而且不會按照給定的規格創建設備。下面的代碼給出了CreateDevice()的函數原型。

CreateDevice()函數原型代碼如下:

  1. HRESULT CreateDevice( UINT Adapter,  
  2. D3DDEVTYPE DeviceType,  
  3. HWND hFocusWindow,  
  4. DWORD BehaviorFlags,  
  5. D3DPRESENT_PARAMETERS *pPresentationParameters,  
  6. IDirect3DDevice9 **ppReturnedDeviceInterface  
  7. ); 

CreateDevice()函數中的第一個參數是Adapter。該參數用于指定正在使用的顯卡。第二個參數DeviceType是一個標識符,用于指定Direct3D中的渲染方式。該參數的參數值可以是采用硬件渲染的D3DDEVTYPE_HAL、采用軟件渲染的D3DDEVTYPE_REF、不需要軟硬件支持的D3DDEVTYPE_NULLREF,或是采用要進行渲染工作的可插拔軟件的D3DDEVTYPE_SW。軟件渲染標識符允許運行Direct3D程序,它可以使用硬件不支持的特性。軟件渲染存在的問題是渲染速度慢,尤其是在開發游戲時。

下一參數hFocusWindow也是一個窗口句柄。參數BehaviorFlags是標識符組合,用于指定設備的運行方式。

pPresentationParameter是一個指針,它指向該函數前面創建的D3DPRESENT_PARAMTERS結構。ppReturnedDeviceInterface是一個指針,它指向新創建的Direct3D設備對象。如果該對象為NULL(空),或是函數返回除D3D_OK以外的值,那么Direct3D設備的創建失敗。

一旦完成Direct3D的設置和創建,就可以隨意渲染屏幕。初始化階段的CreateDevice()函數中創建的設備對象可以完成Direct3D中的渲染工作。渲染屏幕開始先要清屏為指定的顏色,告知Direct3D將要開始繪制新場景,渲染想要渲染的物體,完成屏幕渲染,在屏幕上顯示渲染結果。代碼1.6給出了驗證這個過程的例子代碼。例子代碼創建簡單的顯示空白黑屏的函數。

在屏幕上繪制一個空白屏的代碼:

  1. void RenderScene()  
  2. {  
  3. // Clear the backbuffer.  
  4. g_D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET,  
  5. D3DCOLOR_XRGB(0,0,0), 1.0f, 0);  
  6. // Begin the scene. Start rendering.  
  7. g_D3DDevice->BeginScene();  
  8. // End the scene. Stop rendering.  
  9. g_D3DDevice->EndScene();  
  10. // Display the scene.  
  11. g_D3DDevice->Present(NULL, NULL, NULL, NULL);  

RenderScene()函數開始先清除后臺緩存。調用Direct3D設備對象的Clear()函數可以完成該工作。Clear()函數的參數包括:要清除的矩形數目(0代表清除整個屏幕)、定義想要清除的屏幕區域矩形鏈表(NULL代表整個屏幕)、標識要清除內容的標識符、清除后的顏色、要設定的深度值、設定模板緩存值。對標識符參數而言,D3DCLEAR_DEFAULT清除所有的渲染目標,D3DCLEAR_STENCIL清除模板緩存,而D3DCLEAR_ZBUFFER清除深度緩存。后面將會更多地介紹深度緩存。


一旦完成清除工作,渲染函數將調用設備對象的BeginScene()函數,在Direct3D中啟動一個新場景。在Direct3D中渲染任何圖形前,都必須先調用BeginScene()函數。一旦渲染完要渲染的物體,就調用設備對象的EndScene()函數結束渲染。記住:每個BeginScene()函數必須有一個與之對應的EndScene()函數。由于這里只是繪制了一個空白窗口,所以在BeginScene()和EndScene()之間不需要添加任何代碼。


最后一步是在屏幕上顯示渲染結果。調用設備對象的Present()函數可以完成顯示。就目前的學習而言,Present()函數的參數可以全部設為NULL(空)。第一個參數是正在顯示的原始矩形,如果不使用交換鏈,那么該值必須為NULL(空)。第二個參數是一個指針,它指向要渲染的最終矩形。第三個參數是正在顯示的窗口的窗口句柄。另外,由于沒有用到交換鏈,所以對正在使用的窗口句柄而言,該值設為NULL(空)。這個正在使用的窗口句柄是在Direct3D初始化過程中為D3DPRESENT_PARAMETERS對象設置的窗口句柄。Present()函數中的最后一個參數是緩存區域,它代表需要更新的最小區域。同樣,該參數涉及到交換鏈,也可以設為NULL(空)。

既然可以使用Direct3D初始化和渲染屏幕,那么剩下要做的工作是在退出程序時,釋放對象。在Direct3D中,會發現通常要在退出程序前釋放系統使用的內存,從而避免內存泄漏。所有要釋放的內存都可以通過調用對象的Release()函數釋放。Release()函數會減少對象的引用計數。如果引用計數降為0,那么系統就可以安全地從內存中刪除對象。如果對單個對象有多個引用,那么必須牢記對所有的對象都要調用Release()函數,否則將不會釋放內存。要牢記的規則就是:如果創建了對象,那么最終就要釋放該對象。下述代碼給出了在一個名為Shutdown()的函數中釋放兩個Direct3D對象的方法。

釋放所有的Direct3D對象的代碼

  1. void Shutdown()  
  2. {  
  3. if(g_D3DDevice != NULL) g_D3DDevice->Release();  
  4. if(g_D3D != NULL) g_D3D->Release();  
  5. g_D3DDevice = NULL;  
  6. g_D3D = NULL;  

到這里,基本的模塊都已經一目了然了,下面我們把他串聯起來,構成一個整體。

完整的Blank Window演示程序代碼如下:

  1. #include<d3d9.h>  
  2. #pragma comment(lib, "d3d9.lib")  
  3. #pragma comment(lib, "d3dx9.lib")  
  4. #define WINDOW_CLASS "UGPDX"  
  5. #define WINDOW_NAME "Blank D3D Window"  
  6. // Function Prototypes...  
  7. bool InitializeD3D(HWND hWnd, bool fullscreen);  
  8. void RenderScene();  
  9. void Shutdown();  
  10. // Direct3D object and device.  
  11. LPDIRECT3D9 g_D3D = NULL;  
  12. LPDIRECT3DDEVICE9 g_D3DDevice = NULL;  
  13. LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)  
  14. {  
  15. switch(msg)  
  16. {  
  17. case WM_DESTROY:  
  18. PostQuitMessage(0);  
  19. return 0;  
  20. break;  
  21. case WM_KEYUP:  
  22. if(wParam == VK_ESCAPE) PostQuitMessage(0);  
  23. break;  
  24. }  
  25. return DefWindowProc(hWnd, msg, wParam, lParam);  
  26. }  
  27. int WINAPI WinMain(HINSTANCE hInst, HINSTANCE prevhInst, LPSTR cmdLine, int show)  
  28. {  
  29. // Register the window class  
  30. WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,  
  31. GetModuleHandle(NULL), NULL, NULL, NULL, NULL,  
  32. WINDOW_CLASS, NULL };  
  33. RegisterClassEx(&wc);  
  34. // Create the application's window  
  35. HWND hWnd = CreateWindow(WINDOW_CLASS, WINDOW_NAME, WS_OVERLAPPEDWINDOW,  
  36. 100, 100, 640, 480, GetDesktopWindow(), NULL,  
  37. wc.hInstance, NULL);  
  38. // Initialize Direct3D  
  39. if(InitializeD3D(hWnd, false))  
  40. {  
  41. // Show the window  
  42. ShowWindow(hWnd, SW_SHOWDEFAULT);  
  43. UpdateWindow(hWnd);  
  44. // Enter the message loop  
  45. MSG msg;  
  46. ZeroMemory(&msg, sizeof(msg));  
  47. while(msg.message != WM_QUIT)  
  48. {  
  49. if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))  
  50. {  
  51. TranslateMessage(&msg);  
  52. DispatchMessage(&msg);  
  53. }  
  54. else 
  55. RenderScene();  
  56. }  
  57. }  
  58. // Release any and all resources.  
  59. Shutdown();  
  60. // Unregister our window.  
  61. UnregisterClass(WINDOW_CLASS, wc.hInstance);  
  62. return 0;  
  63. }  
  64. bool InitializeD3D(HWND hWnd, bool fullscreen)  
  65. {  
  66. D3DDISPLAYMODE displayMode;  
  67. // Create the D3D object.  
  68. g_D3D = Direct3DCreate9(D3D_SDK_VERSION);  
  69. if(g_D3D == NULL) return false;  
  70. // Get the desktop display mode.  
  71. if(FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode)))  
  72. return false;  
  73. // Set up the structure used to create the D3DDevice  
  74. D3DPRESENT_PARAMETERS d3dpp;  
  75. ZeroMemory(&d3dpp, sizeof(d3dpp));  
  76. if(fullscreen)  
  77. {  
  78. d3dpp.Windowed = FALSE;  
  79. d3dpp.BackBufferWidth = 640;  
  80. d3dpp.BackBufferHeight = 480;  
  81. }  
  82. else 
  83. d3dpp.Windowed = TRUE;  
  84. d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;  
  85. d3dpp.BackBufferFormat = displayMode.Format;  
  86. // Create the D3DDevice  
  87. if(FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,  
  88. D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_D3DDevice)))  
  89. {  
  90. return false;  
  91. }  
  92. return true;  
  93. }  
  94. void RenderScene()  
  95. {  
  96. // Clear the backbuffer.  
  97. g_D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);  
  98. // Begin the scene. Start rendering.  
  99. g_D3DDevice->BeginScene();  
  100. // End the scene. Stop rendering.  
  101. g_D3DDevice->EndScene();  
  102. // Display the scene.  
  103. g_D3DDevice->Present(NULL, NULL, NULL, NULL);  
  104. }  
  105. void Shutdown()  
  106. {  
  107. if(g_D3DDevice != NULL) g_D3DDevice->Release();  
  108. if(g_D3D != NULL) g_D3D->Release();  

只要成功安裝了DirectX SDK,并配置好DirectX的開發環境,則萬事俱備。

我們先編譯該程序,然后運行它。我們可以看到一個640×480分辨率的空白窗口。

下面給出了運行后的窗口截圖:

【 Visual C++】游戲開發筆記之二——最簡單的DirectX,vc窗口的編寫

以上就是本節筆記的全部內容。

本節源代碼請點擊這里下載:【Visual C++】Code_Note_2


請大家繼續關注【 Visual C++】游戲開發筆記系列,謝謝大家一直的支持~~~


 

The end

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

罗城| 紫阳县| 林州市| 莆田市| 长治县| 西平县| 商都县| 盐源县| 睢宁县| 峨山| 武冈市| 翼城县| 波密县| 南平市| 西盟| 莱阳市| 阳江市| 曲麻莱县| 泗洪县| 耒阳市| 宕昌县| 吴忠市| 宽城| 清水河县| 鞍山市| 右玉县| 辽源市| 土默特右旗| 重庆市| 子洲县| 金阳县| 南通市| 米泉市| 贺州市| 肥西县| 玛沁县| 明水县| 视频| 津市市| 尼勒克县| 德州市|