转载请注明出处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.编译运行
附:源代码下载http://download.youkuaiyun.com/detail/ok123zxx/5759675