1.绘图前初始化Camera矩阵
2.程序运行时,根据用户动作实时更新Camera矩阵
3.绘图时先取得Camera矩阵,然后应用该矩阵绘图
4.在消息处理过程中调用Camera的消息处理函数
只有这样才能实时得到变化的Sence
下面看一下核心代码
1. 在InitD3D函数中初始化三种矩阵,world matrix, view matrix, porjection matrix,对应步骤1
Code
1 // Set world matrix
2 D3DXMATRIXA16 matWorld ;
3 D3DXMatrixTranslation( &matWorld, 0.0f, 0.0f, 0.0f) ;
4 g_Camera.SetWorldMatrix(&matWorld) ;
5
6 // Set view matrix
7 D3DXVECTOR3 vEyePt( 0.0f, 0.0f,-5.0f );
8 D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
9 D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
10 g_Camera.SetViewParams(&vEyePt, &vLookatPt, &vUpVec) ;
11
12 // Set projection matrix
13 g_Camera.SetProjParams(D3DX_PI/4, 1.0f, 1.0f, 320.0f) ;
14
1 // Set world matrix
2 D3DXMATRIXA16 matWorld ;
3 D3DXMatrixTranslation( &matWorld, 0.0f, 0.0f, 0.0f) ;
4 g_Camera.SetWorldMatrix(&matWorld) ;
5
6 // Set view matrix
7 D3DXVECTOR3 vEyePt( 0.0f, 0.0f,-5.0f );
8 D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
9 D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
10 g_Camera.SetViewParams(&vEyePt, &vLookatPt, &vUpVec) ;
11
12 // Set projection matrix
13 g_Camera.SetProjParams(D3DX_PI/4, 1.0f, 1.0f, 320.0f) ;
14
2. 定义函数SetupMatrix用来设置当前矩阵,定义函数OnFrameMove,用来更新每一帧
Code
1 VOID SetupMatrix()
2 {
3 // Wrold
4 D3DXMATRIX matWorld = *g_Camera.GetWorldMatrix() ;
5 g_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld) ;
6
7 // View
8 D3DXMATRIX matView = *g_Camera.GetViewMatrix() ;
9 g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView) ;
10
11 // Projection
12 D3DXMATRIX matProj = *g_Camera.GetProjMatrix() ;
13 g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
14
15 }
16
1 VOID SetupMatrix()
2 {
3 // Wrold
4 D3DXMATRIX matWorld = *g_Camera.GetWorldMatrix() ;
5 g_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld) ;
6
7 // View
8 D3DXMATRIX matView = *g_Camera.GetViewMatrix() ;
9 g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView) ;
10
11 // Projection
12 D3DXMATRIX matProj = *g_Camera.GetProjMatrix() ;
13 g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
14
15 }
16
1 void OnFrameMove()
2 {
3 // update every frame
4 g_Camera.OnFrameMove() ;
5 }
6
2 {
3 // update every frame
4 g_Camera.OnFrameMove() ;
5 }
6
3. 在Render()函数中,首先调用OnFrameMove(), 更新Frame,对应步骤2, 然后调用SetupMatrix(),取得当前矩阵并应用,对应步骤3
1 // Update frame
2 OnFrameMove() ;
3
4 // update matrix
5 SetupMatrix() ;
6
7
2 OnFrameMove() ;
3
4 // update matrix
5 SetupMatrix() ;
6
7
4. 在WinProc函数的最后调用camera的消息处理函数
1 g_Camera.HandleMessages(hWnd, msg, wParam, lParam) ;
完整代码
Code
1 #include <d3dx9.h>
2 #include "Camera.h"
3
4 LPDIRECT3D9 g_pD3D = NULL;
5 LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
6 ID3DXMesh* mesh = 0; // hold sphere
7
8 Camera g_Camera ;
9
10 HRESULT InitD3D( HWND hWnd )
11 {
12 if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
13 return E_FAIL;
14
15 D3DPRESENT_PARAMETERS d3dpp;
16 ZeroMemory( &d3dpp, sizeof(d3dpp) );
17 d3dpp.hDeviceWindow = hWnd ;
18 d3dpp.Windowed = TRUE;
19 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
20 d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
21
22 // Create device
23 if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
24 D3DCREATE_SOFTWARE_VERTEXPROCESSING,
25 &d3dpp, &g_pd3dDevice ) ) )
26 {
27 return E_FAIL;
28 }
29
30 g_pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
31
32 HRESULT r = D3DXCreateSphere(g_pd3dDevice, 0.5f, 20, 20, &mesh, NULL) ;
33 if(r != D3D_OK)
34 MessageBox(hWnd, L"Create Shpere failed!", L"error!", 0);
35
36 // Set world matrix
37 D3DXMATRIXA16 matWorld ;
38 D3DXMatrixTranslation( &matWorld, 0.0f, 0.0f, 0.0f) ;
39 g_Camera.SetWorldMatrix(&matWorld) ;
40
41 // Set view matrix
42 D3DXVECTOR3 vEyePt( 0.0f, 0.0f,-5.0f );
43 D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
44 D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
45 g_Camera.SetViewParams(&vEyePt, &vLookatPt, &vUpVec) ;
46
47 // Set projection matrix
48 g_Camera.SetProjParams(D3DX_PI/4, 1.0f, 1.0f, 320.0f) ;
49
50 return S_OK;
51 }
52
53 VOID Cleanup()
54 {
55 if( g_pd3dDevice != NULL)
56 g_pd3dDevice->Release();
57
58 if( g_pD3D != NULL)
59 g_pD3D->Release();
60
61 if(mesh != NULL)
62 mesh->Release() ;
63 }
64
65 VOID SetupMatrix()
66 {
67 // Wrold
68 D3DXMATRIX matWorld = *g_Camera.GetWorldMatrix() ;
69 g_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld) ;
70
71 // View
72 D3DXMATRIX matView = *g_Camera.GetViewMatrix() ;
73 g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView) ;
74
75 // Projection
76 D3DXMATRIX matProj = *g_Camera.GetProjMatrix() ;
77 g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
78
79 }
80
81 void OnFrameMove()
82 {
83 // update every frame
84 g_Camera.OnFrameMove() ;
85 }
86
87 VOID Render()
88 {
89 // Update frame
90 OnFrameMove() ;
91
92 // update matrix
93 SetupMatrix() ;
94
95 // Clear the backbuffer to a RED color
96 g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255,255,255), 1.0f, 0 );
97
98 // Begin the scene
99 if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
100 {
101 // Draw a shpere
102 mesh->DrawSubset(0) ;
103
104 // End the scene
105 g_pd3dDevice->EndScene();
106 }
107
108 // Present the backbuffer contents to the display
109 g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
110 }
111
112 LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
113 {
114 switch( msg )
115 {
116 case WM_KEYDOWN:
117 {
118 switch( wParam )
119 {
120 case VK_ESCAPE:
121 SendMessage( hWnd, WM_CLOSE, 0, 0 );
122 break ;
123 default:
124 break ;
125 }
126 }
127 return 0 ;
128
129 case WM_DESTROY:
130 Cleanup();
131 PostQuitMessage( 0 );
132 return 0;
133 }
134
135 // handle camera message
136 g_Camera.HandleMessages(hWnd, msg, wParam, lParam) ;
137
138 return DefWindowProc( hWnd, msg, wParam, lParam );
139 }
140
141 INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT )
142 {
143 // Register the window class
144 WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
145 GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
146 L"D3D Tutorial", NULL };
147 RegisterClassEx( &wc );
148
149 // Create the application's window
150 HWND hWnd = CreateWindow( L"D3D Tutorial", L"D3D Tutorial 01: CreateDevice",
151 WS_OVERLAPPEDWINDOW , 0, 0, 800, 600,
152 NULL, NULL, wc.hInstance, NULL );
153
154 // Initialize Direct3D
155 if( SUCCEEDED( InitD3D( hWnd ) ) )
156 {
157 // Show the window
158 ShowWindow( hWnd, SW_SHOWDEFAULT );
159 UpdateWindow( hWnd );
160
161 MSG msg ;
162 ZeroMemory( &msg, sizeof(msg) );
163 PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE );
164
165 while (msg.message != WM_QUIT)
166 {
167 if( PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE) != 0)
168 {
169 TranslateMessage (&msg) ;
170 DispatchMessage (&msg) ;
171 }
172 else // Render when there is no message to process
173 {
174 Render() ;
175 }
176 }
177
178 UnregisterClass( L"D3D Tutorial", wc.hInstance );
179 return 0;
180 }
181 }
1 #include <d3dx9.h>
2 #include "Camera.h"
3
4 LPDIRECT3D9 g_pD3D = NULL;
5 LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
6 ID3DXMesh* mesh = 0; // hold sphere
7
8 Camera g_Camera ;
9
10 HRESULT InitD3D( HWND hWnd )
11 {
12 if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
13 return E_FAIL;
14
15 D3DPRESENT_PARAMETERS d3dpp;
16 ZeroMemory( &d3dpp, sizeof(d3dpp) );
17 d3dpp.hDeviceWindow = hWnd ;
18 d3dpp.Windowed = TRUE;
19 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
20 d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
21
22 // Create device
23 if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
24 D3DCREATE_SOFTWARE_VERTEXPROCESSING,
25 &d3dpp, &g_pd3dDevice ) ) )
26 {
27 return E_FAIL;
28 }
29
30 g_pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
31
32 HRESULT r = D3DXCreateSphere(g_pd3dDevice, 0.5f, 20, 20, &mesh, NULL) ;
33 if(r != D3D_OK)
34 MessageBox(hWnd, L"Create Shpere failed!", L"error!", 0);
35
36 // Set world matrix
37 D3DXMATRIXA16 matWorld ;
38 D3DXMatrixTranslation( &matWorld, 0.0f, 0.0f, 0.0f) ;
39 g_Camera.SetWorldMatrix(&matWorld) ;
40
41 // Set view matrix
42 D3DXVECTOR3 vEyePt( 0.0f, 0.0f,-5.0f );
43 D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
44 D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
45 g_Camera.SetViewParams(&vEyePt, &vLookatPt, &vUpVec) ;
46
47 // Set projection matrix
48 g_Camera.SetProjParams(D3DX_PI/4, 1.0f, 1.0f, 320.0f) ;
49
50 return S_OK;
51 }
52
53 VOID Cleanup()
54 {
55 if( g_pd3dDevice != NULL)
56 g_pd3dDevice->Release();
57
58 if( g_pD3D != NULL)
59 g_pD3D->Release();
60
61 if(mesh != NULL)
62 mesh->Release() ;
63 }
64
65 VOID SetupMatrix()
66 {
67 // Wrold
68 D3DXMATRIX matWorld = *g_Camera.GetWorldMatrix() ;
69 g_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld) ;
70
71 // View
72 D3DXMATRIX matView = *g_Camera.GetViewMatrix() ;
73 g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView) ;
74
75 // Projection
76 D3DXMATRIX matProj = *g_Camera.GetProjMatrix() ;
77 g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
78
79 }
80
81 void OnFrameMove()
82 {
83 // update every frame
84 g_Camera.OnFrameMove() ;
85 }
86
87 VOID Render()
88 {
89 // Update frame
90 OnFrameMove() ;
91
92 // update matrix
93 SetupMatrix() ;
94
95 // Clear the backbuffer to a RED color
96 g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255,255,255), 1.0f, 0 );
97
98 // Begin the scene
99 if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
100 {
101 // Draw a shpere
102 mesh->DrawSubset(0) ;
103
104 // End the scene
105 g_pd3dDevice->EndScene();
106 }
107
108 // Present the backbuffer contents to the display
109 g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
110 }
111
112 LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
113 {
114 switch( msg )
115 {
116 case WM_KEYDOWN:
117 {
118 switch( wParam )
119 {
120 case VK_ESCAPE:
121 SendMessage( hWnd, WM_CLOSE, 0, 0 );
122 break ;
123 default:
124 break ;
125 }
126 }
127 return 0 ;
128
129 case WM_DESTROY:
130 Cleanup();
131 PostQuitMessage( 0 );
132 return 0;
133 }
134
135 // handle camera message
136 g_Camera.HandleMessages(hWnd, msg, wParam, lParam) ;
137
138 return DefWindowProc( hWnd, msg, wParam, lParam );
139 }
140
141 INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT )
142 {
143 // Register the window class
144 WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
145 GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
146 L"D3D Tutorial", NULL };
147 RegisterClassEx( &wc );
148
149 // Create the application's window
150 HWND hWnd = CreateWindow( L"D3D Tutorial", L"D3D Tutorial 01: CreateDevice",
151 WS_OVERLAPPEDWINDOW , 0, 0, 800, 600,
152 NULL, NULL, wc.hInstance, NULL );
153
154 // Initialize Direct3D
155 if( SUCCEEDED( InitD3D( hWnd ) ) )
156 {
157 // Show the window
158 ShowWindow( hWnd, SW_SHOWDEFAULT );
159 UpdateWindow( hWnd );
160
161 MSG msg ;
162 ZeroMemory( &msg, sizeof(msg) );
163 PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE );
164
165 while (msg.message != WM_QUIT)
166 {
167 if( PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE) != 0)
168 {
169 TranslateMessage (&msg) ;
170 DispatchMessage (&msg) ;
171 }
172 else // Render when there is no message to process
173 {
174 Render() ;
175 }
176 }
177
178 UnregisterClass( L"D3D Tutorial", wc.hInstance );
179 return 0;
180 }
181 }