1. 新建单文档类型的MFC应用程序
2. 添加三个lib文件:d3d9.lib d3dx9.lib winmm.lib
3. 在D3D9MFCView.h文件中添加如下代码:
包含头文件:#include <d3dx9.h> //88888
添加成员函数和成员变量:
- //88888
- private:
- HRESULT initD3D(
- HWND hwnd,
- int width,
- int height,
- bool windowed,
- D3DDEVTYPE deviceType);
- HRESULT setup(int width, int height);
- HRESULT cleanup();
- public:
- HRESULT update(float timeDelta);
- HRESULT render();
- private:
- IDirect3DDevice9* _device;
- D3DPRESENT_PARAMETERS _d3dpp;
- ID3DXMesh* _teapot;
- public:
- virtual void OnInitialUpdate();
- afx_msg void OnSize(UINT nType, int cx, int cy);
- afx_msg BOOL OnEraseBkgnd(CDC* pDC);
- //88888
对应函数实现:
- CD3D9MFCView::CD3D9MFCView():_device(0),_teapot(0)
- {
- // TODO: add construction code here
- ::ZeroMemory(&_d3dpp,sizeof(_d3dpp));//88888
- }
- CD3D9MFCView::~CD3D9MFCView()
- {
- if (_teapot)
- _teapot->Release();
- if(_device)
- _device->Release();
- }
- HRESULT CD3D9MFCView::initD3D(HWND hwnd,
- int width,
- int height,
- bool windowed,
- D3DDEVTYPE deviceType)
- {
- HRESULT hr = 0;
- // Step 1: Create the IDirect3D9 object.
- IDirect3D9* d3d9 = 0;
- d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
- if( !d3d9 )
- {
- ::MessageBox(0, "Direct3DCreate9() - FAILED", 0, 0);
- return E_FAIL;
- }
- // Step 2: Check for hardware vp.
- D3DCAPS9 caps;
- d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, deviceType, &caps);
- int vp = 0;
- if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
- vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
- else
- vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
- // Step 3: Fill out the D3DPRESENT_PARAMETERS structure.
- _d3dpp.BackBufferWidth = width;
- _d3dpp.BackBufferHeight = height;
- _d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
- _d3dpp.BackBufferCount = 1;
- _d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
- _d3dpp.MultiSampleQuality = 0;
- _d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
- _d3dpp.hDeviceWindow = hwnd;
- _d3dpp.Windowed = windowed;
- _d3dpp.EnableAutoDepthStencil = true;
- _d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
- _d3dpp.Flags = 0;
- _d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
- _d3dpp.PresentationInterval =
- D3DPRESENT_INTERVAL_IMMEDIATE;
- // Step 4: Create the device.
- hr = d3d9->CreateDevice(
- D3DADAPTER_DEFAULT, // primary adapter
- deviceType, // device type
- hwnd, // window associated with device
- vp, // vertex processing
- &_d3dpp, // present parameters
- &_device); // return created device
- if( FAILED(hr) )
- {
- // try again using a safer configuration.
- _d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
- hr = d3d9->CreateDevice(
- D3DADAPTER_DEFAULT,
- deviceType,
- hwnd,
- D3DCREATE_SOFTWARE_VERTEXPROCESSING,
- &_d3dpp,
- &_device);
- if( FAILED(hr) )
- {
- d3d9->Release(); // done with d3d9 object
- ::MessageBox(0, "CreateDevice() - FAILED", 0, 0);
- return hr;
- }
- }
- d3d9->Release(); // done with d3d9 object
- return S_OK;
- }
- HRESULT CD3D9MFCView::setup(int width, int height)
- {
- if( _device )
- {
- // Set view matrix.
- D3DXMATRIX V;
- D3DXVECTOR3 pos (0.0f, 0.0f, -6.0f);
- D3DXVECTOR3 target (0.0f, 0.0f, 0.0f);
- D3DXVECTOR3 up (0.0f, 1.0f, 0.0f);
- D3DXMatrixLookAtLH(&V, &pos, &target, &up);
- _device->SetTransform(D3DTS_VIEW, &V);
- // Create the teapot.
- if( !_teapot)
- D3DXCreateTeapot(_device, &_teapot, 0);
- // Use wireframe mode and turn off lighting.
- _device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
- _device->SetRenderState(D3DRS_LIGHTING, false);
- // Size the viewport based on window dimensions.
- D3DVIEWPORT9 vp = {0, 0, width, height, 0.0f, 1.0f};
- _device->SetViewport( &vp );
- // Set the projection matrix based on the
- // window dimensions.
- D3DXMATRIX P;
- D3DXMatrixPerspectiveFovLH(
- &P,
- D3DX_PI * 0.25f,//45-degree field of view
- (float)width / (float)height,
- 1.0f,
- 1000.0f);
- _device->SetTransform(D3DTS_PROJECTION, &P);
- }
- return S_OK;
- }
- HRESULT CD3D9MFCView::cleanup()
- {
- // Nothing to Destroy.
- return S_OK;
- }
- HRESULT CD3D9MFCView::update(float timeDelta)
- {
- if( _device )
- {
- //
- // Spin the teapot around the y-axis.
- //
- static float angle = 0.0f;
- D3DXMATRIX yRotationMatrix;
- D3DXMatrixRotationY(&yRotationMatrix, angle);
- _device->SetTransform(D3DTS_WORLD, &yRotationMatrix);
- angle += timeDelta;
- if(angle >= D3DX_PI * 2.0f)
- angle = 0.0f;
- }
- return S_OK;
- }
- HRESULT CD3D9MFCView::render()
- {
- if( _device )
- {
- //
- // Draw the scene.
- //
- _device->Clear(0, 0,
- D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
- 0x00000000, 1.0f, 0);
- _device->BeginScene();
- // Draw the teapot.
- _teapot->DrawSubset(0);
- _device->EndScene();
- _device->Present(0, 0, 0, 0);
- }
- return S_OK;
- }
- void CD3D9MFCView::OnInitialUpdate()
- {
- CView::OnInitialUpdate();
- // TODO: Add your specialized code here and/or call the base class
- CRect rect;
- GetClientRect(&rect);
- // Initialize Direct3D (e.g. acquire a IDirect3DDevice9 poniter).
- HRESULT hr = initD3D(
- GetSafeHwnd(),
- rect.right,
- rect.bottom,
- true,
- D3DDEVTYPE_HAL);
- if(FAILED(hr))
- {
- MessageBox("initD3D() - Failed", "Error");
- ::PostQuitMessage(0);
- }
- // Setup the application.
- hr = setup(rect.right, rect.bottom);
- if(FAILED(hr))
- {
- MessageBox("setup() - Failed", "Error");
- ::PostQuitMessage(0);
- }
- }
- void CD3D9MFCView::OnSize(UINT nType, int cx, int cy)
- {
- CView::OnSize(nType, cx, cy);
- // TODO: Add your message handler code here
- if( _device )
- {
- HRESULT hr = 0;
- // On a resize we must change the dimensions of the
- // back buffers to match the new window size.
- _d3dpp.BackBufferWidth = cx;
- _d3dpp.BackBufferHeight = cy;
- // We are about to call Reset, free any resources
- // that need to be freed prior to a Reset.
- hr = cleanup();
- if(FAILED(hr))
- {
- MessageBox("destroy() - Failed", "Error");
- ::PostQuitMessage(0);
- }
- // Reset the flipping chain with the new window dimensions.
- // Note that all device states are reset to the default
- // after this call.
- hr = _device->Reset(&_d3dpp);
- if(FAILED(hr))
- {
- MessageBox("Reset() - Failed", "Error");
- ::PostQuitMessage(0);
- }
- // Reinitialize resource and device states since we
- // Reset everything.
- hr = setup(cx, cy);
- if(FAILED(hr))
- {
- MessageBox("setup() - Failed", "Error");
- ::PostQuitMessage(0);
- }
- }
- }
- BOOL CD3D9MFCView::OnEraseBkgnd(CDC* pDC)
- {
- // TODO: Add your message handler code here and/or call default
- return FALSE;
- //return CView::OnEraseBkgnd(pDC);
- }
3. 在类CD3D9MFCApp中添加如下代码。
包含头文件:#include "mmsystem.h"//88888
添加重载函数:
- BOOL CD3D9MFCApp::OnIdle(LONG lCount)
- {
- // TODO: Add your specialized code here and/or call the base class
- CWinApp::OnIdle(lCount);
- CWnd* mainFrame = AfxGetMainWnd();
- CD3D9MFCView* cview =
- (CD3D9MFCView*)mainFrame->GetWindow(GW_CHILD);
- // Save last time.
- 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;
- cview->update(deltaTime);
- cview->render();
- return TRUE;
- //return CWinApp::OnIdle(lCount);
- }
效果如下: