轉載請注明出處http://www.cnblogs.com/CAION/p/3192111.html
(程序運行時是和其他程序挺像 = =,但我保證這是原創的)
1.將D3D的初始化,渲染等等一些行為封裝為圖形(Graph)類
代碼如下(這里使用繪制旋轉的茶壺作為例子),頭文件
#pragma once #include <d3d9.h> #include <d3dx9.h> class Graphi { public: Graphi(void); ~Graphi(void); bool Initialize(int,int,HWND); void Shutdown(); bool Setup(); bool Update(); bool Render(); private: float GetDeltaTime(); private: LPDIRECT3D9 m_pD3d; //Direct3D對象 LPDIRECT3DDEVICE9 m_pd3dDevice; //Direct3D設備對象 ID3DXMesh* m_Teapot; // private: int m_Width,m_Height; D3DXMATRIX m_world; };
CPP文件
#include "StdAfx.h" #include "Graphi.h" #include "MMSystem.h" Graphi::Graphi(void) { m_pD3d = NULL; //Direct3D對象 m_pd3dDevice = NULL; m_Teapot = NULL; // m_Width = 0; m_Height = 0; } Graphi::~Graphi(void) { Shutdown(); } bool Graphi::Initialize(int Width,int Height,HWND hWnd) { //創建Direct3D對象, 該對象用來創建Direct3D設備對象 if( NULL == ( m_pD3d = Direct3DCreate9( D3D_SDK_VERSION ) ) ) return false; //設置D3DPRESENT_PARAMETERS結構, 准備創建Direct3D設備對象 D3DPRESENT_PARAMETERS d3dpp; ZeroMemory( &d3dpp, sizeof(d3dpp) ); d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; //創建Direct3D設備對象 m_pD3d->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &m_pd3dDevice ) ; // m_Width = Width; m_Height = Height; return true; } bool Graphi::Setup() { D3DXCreateTeapot(m_pd3dDevice,&m_Teapot,0); D3DXVECTOR3 position(0.0f, 0.0f, -3.0f); D3DXVECTOR3 target(0.0f, 0.0f, 0.0f); D3DXVECTOR3 up(0.0f, 1.0f, 0.0f); D3DXMATRIX V; D3DXMatrixLookAtLH(&V, &position, &target, &up); m_pd3dDevice->SetTransform(D3DTS_VIEW, &V); D3DXMATRIX proj; D3DXMatrixPerspectiveFovLH( &proj, D3DX_PI * 0.5f, // 90 - degree (float)m_Width / (float)m_Height, 1.0f, 1000.0f); m_pd3dDevice->SetTransform(D3DTS_PROJECTION, &proj); m_pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); return true; } void Graphi::Shutdown() { //釋放Direct3D設備對象 if( m_pd3dDevice != NULL) m_pd3dDevice->Release(); //釋放Direct3D對象 if( m_pD3d != NULL) m_pD3d->Release(); //釋放mesh對象 if( m_Teapot != NULL) m_Teapot->Release(); } float Graphi::GetDeltaTime() { static float lastTime = (float)timeGetTime(); // Compute time now. float currentTime = (float)timeGetTime(); // Compute the difference: time elapsed in seconds. float deltaTime = (currentTime - lastTime) * 0.001f; // Last time is now current time. lastTime = currentTime; return deltaTime; } bool Graphi::Render() { //清空后台緩沖區 m_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(45, 50, 170), 1.0f, 0 ); m_pd3dDevice->BeginScene(); //在此在后台緩沖區繪制圖形 m_Teapot->DrawSubset(0); m_pd3dDevice->EndScene(); //將在后台緩沖區繪制的圖形提交到前台緩沖區顯示 m_pd3dDevice->Present( NULL, NULL, NULL, NULL ); return true; } bool Graphi::Update() { D3DXMATRIX Ry; static float y = 0.0f; D3DXMatrixRotationY(&Ry, y); m_world = Ry; float deltaTime = GetDeltaTime(); y += deltaTime; if(y >= 6.28f) y = 0.0f; m_pd3dDevice->SetTransform(D3DTS_WORLD, &m_world); return true; }
2.在VS2010中新建MFC工程,選擇基於對話框創建
3.為對話框添加一個Static控件,並把控件ID改成IDC_3DVIEW。添加控件變量m_3dview
4.重載WM_KICKIDLE消息。(關於WM_KICKIDLE消息了解更多,http://hi.baidu.com/cherven23/item/ac0d59f539a137793c198b00)
5.完成回調函數WM_KICKIDLE的回調函數OnKickIdle()。
LRESULT CD3D_MFCDlg::OnKickIdle(WPARAM wParam,LPARAM lParam) { m_d3dGraphi->Update(); m_d3dGraphi->Render(); return 1; }
6.在初始化對話框的函數中,添加初始化D3D代碼
BOOL CD3D_MFCDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // 設置此對話框的圖標。當應用程序主窗口不是對話框時,框架將自動 // 執行此操作 SetIcon(m_hIcon, TRUE); // 設置大圖標 SetIcon(m_hIcon, FALSE); // 設置小圖標 // TODO: 在此添加額外的初始化代碼 CRect rect; GetWindowRect(&rect); m_3dview.GetWindowRect( &rect ); //初始化圖形代碼 HWND hWnd; hWnd = m_3dview.m_hWnd; m_d3dGraphi = new Graphi(); m_d3dGraphi->Initialize(rect.Width(),rect.Height(),hWnd); m_d3dGraphi->Setup(); return TRUE; // 除非將焦點設置到控件,否則返回 TRUE }
7.編譯運行