最近一直接觸的都是C#的東東,好久沒寫C++代碼了,怕手生忘記了,打算寫寫C++的代碼。寫什麼好呢?想來想去,以前的工作學過接觸了些OpenGL,那我就學習一下D3D吧。原以為D3D的中文入門資料會很多的,結果找了半天也沒找到合適的。哎,隨便將就著學吧。
既然是來興趣學一下,我可不想去下個超大的DirectX安裝包,所以首先,當然得找到lib庫和標頭檔啦,我在GameRes遊戲開發資源網上找到了,只有3.2M,呵呵,夠小吧。地址如下:
DirectX9.0C SDK library
下載下來解壓後,假設解壓到d:/codelib/dx9csdk下吧, 首先得把INC和lib目錄加到VC的搜尋路徑上去。
我用VS2005, 選擇菜單Tools - Option - Projects and Solutions - VC++ Directories
然後,接下來就可以開始寫代碼了。
我們採用Win32API來建立視窗,為了重用代碼,建立視窗使用了我部落格裡介紹的一個類KWindow,請見:
一個基於Win32的完全物件導向的視窗類別
我們建立一個類,叫做KD3DWindow把,從KWindow繼承。
其UML圖如下所示:
KWindow的內容請看我部落格上的前一篇文章吧。
KD3DWindow.h的內容如下所示:
- #include "KWindow.h"
- #include <D3D8.H>
- #pragma comment(lib, "D3d8.lib") //連結庫
- class KD3DWindow : public KWindow
- {
- private:
- void OnKeyDown(WPARAM wParam, LPARAM lParam);
- void OnDraw(HDC hDC);
- void GetWndClassEx(WNDCLASSEX & wc);
-
- //D3D相關
- void Render();
- void Cleanup();
- HRESULT InitD3D( HWND hWnd );
- public:
- KD3DWindow();
- ~KD3DWindow();
- virtual bool CreateEx(DWORD dwExStyle,
- LPCTSTR lpszClass, LPCTSTR lpszName, DWORD dwStyle,
- int x, int y, int nWidth, int nHeight, HWND hParent,
- HMENU hMenu, HINSTANCE hInst);
- private:
- LPDIRECT3D8 g_pD3D ; // 用來建立D3D裝置
- LPDIRECT3DDEVICE8 g_pd3dDevice ; // D3D裝置
- };
KD3DWindow.cpp內容如下:
- // KD3DWindow.cpp: implementation of the KD3DWindow class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "KD3DWindow.h"
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- #include <windows.h>
- #include <assert.h>
- #include <tchar.h>
- #include "KWindow.h"
- const TCHAR szHint[] = _T("Press ESC to quit.");
- void KD3DWindow::GetWndClassEx( WNDCLASSEX & wc )
- {
- memset(& wc, 0, sizeof(wc));
-
- wc.cbSize = sizeof(WNDCLASSEX);
- wc.style = 0;
- wc.lpfnWndProc = WindowProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = NULL;
- wc.hIcon = NULL;
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
- wc.lpszMenuName = NULL;
- wc.lpszClassName = NULL;
- wc.hIconSm = NULL;
- }
- void KD3DWindow::OnDraw( HDC hDC )
- {
- //先用D3D裝置渲染
- Render();
- //用Windows API在螢幕上繪圖
- TextOut(hDC, 0, 0, szHint, lstrlen(szHint));
- }
- void KD3DWindow::OnKeyDown( WPARAM wParam, LPARAM lParam )
- {
- if (wParam==VK_ESCAPE )
- {
- PostMessage(m_hWnd, WM_CLOSE, 0, 0);
- }
- }
- // 初始化D3D
- HRESULT KD3DWindow::InitD3D( HWND hWnd )
- {
- //如果還沒有視窗,返回失敗啦
- if( m_hWnd == NULL)
- return E_FAIL;
- // 建立D3D對象
- if( NULL == ( g_pD3D = Direct3DCreate8( D3D_SDK_VERSION ) ) )
- return E_FAIL;
- // 擷取當前的顯示模式
- D3DDISPLAYMODE d3ddm;
- if( FAILED( g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )
- return E_FAIL;
- D3DPRESENT_PARAMETERS d3dpp;
- ZeroMemory( &d3dpp, sizeof(d3dpp) );
- d3dpp.Windowed = TRUE; // 視窗模式
- d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // 設定交換模式
- d3dpp.BackBufferFormat = d3ddm.Format; // 設定背景緩衝區格式為當前左面格式
- // 建立D3D裝置
- // 第一個參數:使用預設的顯卡
- // 第二個參數:請求使用硬體抽象層(HAL)
- // 第三個參數:視窗控制代碼
- // 第四個參數:使用軟體處理頂點
- // 第五個參數:建立的參數
- // 第六個參數:建立的D3D裝置指標
- if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT,
- D3DDEVTYPE_HAL,
- hWnd,
- D3DCREATE_SOFTWARE_VERTEXPROCESSING,
- &d3dpp,
- &g_pd3dDevice ) ) )
- {
- return E_FAIL;
- }
- return S_OK;
- }
- // 釋放D3D
- void KD3DWindow::Cleanup()
- {
- if( g_pd3dDevice != NULL)
- g_pd3dDevice->Release();
- if( g_pD3D != NULL)
- g_pD3D->Release();
- }
- // 渲染
- void KD3DWindow::Render()
- {
- if( NULL == g_pd3dDevice )
- return;
- // 清除背景為蘭色
- g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );
- // 繪製情境
- g_pd3dDevice->BeginScene();
- // 這裡繪製你需要的東西
- // 結束繪製
- g_pd3dDevice->EndScene();
- // 顯示到螢幕上
- g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
- }
- KD3DWindow::KD3DWindow()
- {
- }
- KD3DWindow::~KD3DWindow()
- {
- Cleanup();
- }
- bool KD3DWindow::CreateEx(DWORD dwExStyle,
- LPCTSTR lpszClass, LPCTSTR lpszName, DWORD dwStyle,
- int x, int y, int nWidth, int nHeight, HWND hParent,
- HMENU hMenu, HINSTANCE hInst)
- {
- //建立視窗
- bool bRet = KWindow::CreateEx(dwExStyle,lpszClass,lpszName,dwStyle,x,y,nWidth,nHeight,hParent,hMenu,hInst);
- //初始化D3D裝置
- if( InitD3D(m_hWnd) != S_OK)
- bRet = false;
- return bRet;
- }
代碼關鍵地方都有注釋,也很好理解的。
然後就是主函數如何調用了,請看:
- int APIENTRY WinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nCmdShow)
- {
- // TODO: Place code here.
- KD3DWindow win;
- //KHelloWindow win;
- win.CreateEx(0, _T("Hello"), _T("Hello"), WS_OVERLAPPEDWINDOW, GetSystemMetrics(SM_CXSCREEN)/4, GetSystemMetrics(SM_CYSCREEN)/4,
- GetSystemMetrics(SM_CXSCREEN)/2,
- GetSystemMetrics(SM_CYSCREEN)/2,
- NULL, NULL, hInstance);
- win.ShowWindow(nCmdShow);
- win.UpdateWindow();
- return win.MessageLoop();
- }
編譯運行後,可以看到程式既有D3D渲染的背景情境,也有Win32 GDI繪製的文字。如下所示:
本文來自
http://blog.csdn.net/zxcred